-
Notifications
You must be signed in to change notification settings - Fork 67
/
Copy pathtest_logging_utils.py
180 lines (146 loc) · 5.9 KB
/
test_logging_utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
"""
Tests for SKLL logging utilities.
:author: Nitin Madnani (nmadnani@ets.org)
"""
import logging
import re
import sys
import unittest
import warnings
from tempfile import NamedTemporaryFile
from six import StringIO
from sklearn.metrics import roc_curve
from skll.utils.logging import (
MatplotlibCategoryFilter,
close_and_remove_logger_handlers,
get_skll_logger,
orig_showwarning,
)
from skll.utils.testing import unlink
TEMP_FILES = []
TEMP_FILE_PATHS = []
LOGGERS = []
class TestLoggingUtils(unittest.TestCase):
"""Test class for logging utility tests."""
def reset(self):
for i, temp_file in enumerate(TEMP_FILES):
temp_file.close()
del TEMP_FILES[i]
for i, temp_file_path in enumerate(TEMP_FILE_PATHS):
unlink(temp_file_path)
del TEMP_FILE_PATHS[i]
for i, logger in enumerate(LOGGERS):
close_and_remove_logger_handlers(logger)
del LOGGERS[i]
warnings.showwarning = orig_showwarning
def setUp(self):
self.reset()
def tearDown(self):
self.reset()
def trigger_sklearn_warning(self):
"""
Do something that will trigger an ``sklearn`` warning.
This should trigger an ``UndefinedMetricWarning``.
"""
roc_curve([1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [0, 1, 0, 1, 0, 1, 0, 1, 0, 1])
def test_get_skll_logger(self):
temp_file = NamedTemporaryFile("w", delete=False)
temp_file.close()
TEMP_FILES.append(temp_file)
TEMP_FILE_PATHS.append(temp_file.name)
logger = get_skll_logger("test_get_skll_logger", filepath=temp_file.name)
LOGGERS.append(logger)
# Send a regular log message
msg1 = "message 1"
logger.info(msg1)
# Send a regular log message
msg2 = "message 2"
logger.info(msg2)
with open(temp_file.name) as tempfh:
log_lines = tempfh.readlines()
assert log_lines[0].endswith(f"INFO - {msg1}\n")
assert log_lines[1].endswith(f"INFO - {msg2}\n")
close_and_remove_logger_handlers(logger)
def test_get_skll_logger_with_warning(self):
temp_file = NamedTemporaryFile("w", delete=False)
temp_file.close()
TEMP_FILES.append(temp_file)
TEMP_FILE_PATHS.append(temp_file.name)
logger = get_skll_logger("test_get_skll_logger_with_warning", filepath=temp_file.name)
LOGGERS.append(logger)
# Send a regular log message
msg1 = "message 1"
logger.info(msg1)
# Trigger an ``sklearn`` warning
self.trigger_sklearn_warning()
# Send a regular log message
msg2 = "message 2"
logger.info(msg2)
with open(temp_file.name) as temp_file:
log_lines = temp_file.readlines()
assert log_lines[0].endswith(f"INFO - {msg1}\n")
sklearn_warning_re = re.compile(
r"WARNING - [^\n]+sklearn.metrics._ranking.py:\d+: "
r"UndefinedMetricWarning:No negative samples in y_true, false "
r"positive value should be meaningless"
)
assert sklearn_warning_re.search("".join(log_lines[1]))
assert log_lines[-1].endswith(f"INFO - {msg2}\n")
# Now make sure that warnings.showwarning works the way
# it normally works (writes to STDERR) by issuing a warning,
# capturing it, and, finally, making sure the expected
# warning shows up correctly in the STDERR stream and,
# additionally, not in the log file.
old_stderr = sys.stderr
try:
msg3 = "message 3"
sys.stderr = mystderr = StringIO()
warnings.warn(msg3)
err = mystderr.getvalue()
assert f"UserWarning: {msg3}" in err
with open(temp_file.name) as log_file:
assert f"UserWarning:{msg3}" not in log_file.read()
finally:
sys.stderr = old_stderr
close_and_remove_logger_handlers(logger)
def test_close_and_remove_logger_handlers(self):
temp_file = NamedTemporaryFile("w", delete=False)
temp_file.close()
TEMP_FILES.append(temp_file)
TEMP_FILE_PATHS.append(temp_file.name)
logger = get_skll_logger("test_close_and_remove_logger_handlers", temp_file.name)
LOGGERS.append(logger)
close_and_remove_logger_handlers(logger)
assert not logger.handlers
class TestMatplotlibCategoryFilter(unittest.TestCase):
"""Test class for the MatplotlibCategoryFilter."""
def setUp(self):
# set up the logger and add the custom filter
self.logger = logging.getLogger("matplotlib.category")
self.logger.setLevel(logging.INFO)
self.filter = MatplotlibCategoryFilter()
self.logger.addFilter(self.filter)
# set up a logging handler to capture the logs
self.log_capture = logging.handlers.MemoryHandler(capacity=10, target=None)
self.logger.addHandler(self.log_capture)
def tearDown(self):
# remove the filter and handler
self.logger.removeFilter(self.filter)
self.logger.removeHandler(self.log_capture)
def test_filtered_message(self):
# log a message that should be filtered
self.logger.info(
"Using categorical units to plot a list of strings that are all "
"parsable as floats or dates."
)
# Check that the message was filtered and not captured
self.assertEqual(len(self.log_capture.buffer), 0)
def test_allowed_message(self):
# log a message that should not be filtered
self.logger.info("This is a test message that should not be filtered.")
# check that the message was not filtered and captured
self.assertEqual(len(self.log_capture.buffer), 1)
self.assertEqual(
self.log_capture.buffer[0].getMessage(),
"This is a test message that should not be filtered.",
)