root / test / py / ganeti.utils.log_unittest.py @ 7bc2c097
History | View | Annotate | Download (8.3 kB)
1 | b6fa9a44 | Michael Hanselmann | #!/usr/bin/python
|
---|---|---|---|
2 | b6fa9a44 | Michael Hanselmann | #
|
3 | b6fa9a44 | Michael Hanselmann | |
4 | b6fa9a44 | Michael Hanselmann | # Copyright (C) 2011 Google Inc.
|
5 | b6fa9a44 | Michael Hanselmann | #
|
6 | b6fa9a44 | Michael Hanselmann | # This program is free software; you can redistribute it and/or modify
|
7 | b6fa9a44 | Michael Hanselmann | # it under the terms of the GNU General Public License as published by
|
8 | b6fa9a44 | Michael Hanselmann | # the Free Software Foundation; either version 2 of the License, or
|
9 | b6fa9a44 | Michael Hanselmann | # (at your option) any later version.
|
10 | b6fa9a44 | Michael Hanselmann | #
|
11 | b6fa9a44 | Michael Hanselmann | # This program is distributed in the hope that it will be useful, but
|
12 | b6fa9a44 | Michael Hanselmann | # WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 | b6fa9a44 | Michael Hanselmann | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 | b6fa9a44 | Michael Hanselmann | # General Public License for more details.
|
15 | b6fa9a44 | Michael Hanselmann | #
|
16 | b6fa9a44 | Michael Hanselmann | # You should have received a copy of the GNU General Public License
|
17 | b6fa9a44 | Michael Hanselmann | # along with this program; if not, write to the Free Software
|
18 | b6fa9a44 | Michael Hanselmann | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
19 | b6fa9a44 | Michael Hanselmann | # 02110-1301, USA.
|
20 | b6fa9a44 | Michael Hanselmann | |
21 | b6fa9a44 | Michael Hanselmann | |
22 | b6fa9a44 | Michael Hanselmann | """Script for testing ganeti.utils.log"""
|
23 | b6fa9a44 | Michael Hanselmann | |
24 | b6fa9a44 | Michael Hanselmann | import os |
25 | b6fa9a44 | Michael Hanselmann | import unittest |
26 | b6fa9a44 | Michael Hanselmann | import logging |
27 | b6fa9a44 | Michael Hanselmann | import tempfile |
28 | 9a6813ac | Michael Hanselmann | import shutil |
29 | 796b5152 | Michael Hanselmann | import threading |
30 | 796b5152 | Michael Hanselmann | from cStringIO import StringIO |
31 | b6fa9a44 | Michael Hanselmann | |
32 | b6fa9a44 | Michael Hanselmann | from ganeti import constants |
33 | b6fa9a44 | Michael Hanselmann | from ganeti import errors |
34 | 796b5152 | Michael Hanselmann | from ganeti import compat |
35 | b6fa9a44 | Michael Hanselmann | from ganeti import utils |
36 | b6fa9a44 | Michael Hanselmann | |
37 | b6fa9a44 | Michael Hanselmann | import testutils |
38 | b6fa9a44 | Michael Hanselmann | |
39 | b6fa9a44 | Michael Hanselmann | |
40 | b6fa9a44 | Michael Hanselmann | class TestLogHandler(unittest.TestCase): |
41 | ad88650c | Michael Hanselmann | def testNormal(self): |
42 | b6fa9a44 | Michael Hanselmann | tmpfile = tempfile.NamedTemporaryFile() |
43 | b6fa9a44 | Michael Hanselmann | |
44 | b6fa9a44 | Michael Hanselmann | handler = utils.log._ReopenableLogHandler(tmpfile.name) |
45 | b6fa9a44 | Michael Hanselmann | handler.setFormatter(logging.Formatter("%(asctime)s: %(message)s"))
|
46 | b6fa9a44 | Michael Hanselmann | |
47 | b6fa9a44 | Michael Hanselmann | logger = logging.Logger("TestLogger")
|
48 | b6fa9a44 | Michael Hanselmann | logger.addHandler(handler) |
49 | b6fa9a44 | Michael Hanselmann | self.assertEqual(len(logger.handlers), 1) |
50 | b6fa9a44 | Michael Hanselmann | |
51 | b6fa9a44 | Michael Hanselmann | logger.error("Test message ERROR")
|
52 | b6fa9a44 | Michael Hanselmann | logger.info("Test message INFO")
|
53 | b6fa9a44 | Michael Hanselmann | |
54 | b6fa9a44 | Michael Hanselmann | logger.removeHandler(handler) |
55 | b6fa9a44 | Michael Hanselmann | self.assertFalse(logger.handlers)
|
56 | b6fa9a44 | Michael Hanselmann | handler.close() |
57 | b6fa9a44 | Michael Hanselmann | |
58 | b6fa9a44 | Michael Hanselmann | self.assertEqual(len(utils.ReadFile(tmpfile.name).splitlines()), 2) |
59 | b6fa9a44 | Michael Hanselmann | |
60 | b6fa9a44 | Michael Hanselmann | def testReopen(self): |
61 | b6fa9a44 | Michael Hanselmann | tmpfile = tempfile.NamedTemporaryFile() |
62 | b6fa9a44 | Michael Hanselmann | tmpfile2 = tempfile.NamedTemporaryFile() |
63 | b6fa9a44 | Michael Hanselmann | |
64 | b6fa9a44 | Michael Hanselmann | handler = utils.log._ReopenableLogHandler(tmpfile.name) |
65 | b6fa9a44 | Michael Hanselmann | |
66 | b6fa9a44 | Michael Hanselmann | self.assertFalse(utils.ReadFile(tmpfile.name))
|
67 | b6fa9a44 | Michael Hanselmann | self.assertFalse(utils.ReadFile(tmpfile2.name))
|
68 | b6fa9a44 | Michael Hanselmann | |
69 | b6fa9a44 | Michael Hanselmann | logger = logging.Logger("TestLoggerReopen")
|
70 | b6fa9a44 | Michael Hanselmann | logger.addHandler(handler) |
71 | b6fa9a44 | Michael Hanselmann | |
72 | b6fa9a44 | Michael Hanselmann | for _ in range(3): |
73 | b6fa9a44 | Michael Hanselmann | logger.error("Test message ERROR")
|
74 | b6fa9a44 | Michael Hanselmann | handler.flush() |
75 | b6fa9a44 | Michael Hanselmann | self.assertEqual(len(utils.ReadFile(tmpfile.name).splitlines()), 3) |
76 | b6fa9a44 | Michael Hanselmann | before_id = utils.GetFileID(tmpfile.name) |
77 | b6fa9a44 | Michael Hanselmann | |
78 | b6fa9a44 | Michael Hanselmann | handler.RequestReopen() |
79 | b6fa9a44 | Michael Hanselmann | self.assertTrue(handler._reopen)
|
80 | b6fa9a44 | Michael Hanselmann | self.assertTrue(utils.VerifyFileID(utils.GetFileID(tmpfile.name),
|
81 | b6fa9a44 | Michael Hanselmann | before_id)) |
82 | b6fa9a44 | Michael Hanselmann | |
83 | b6fa9a44 | Michael Hanselmann | # Rename only after requesting reopen
|
84 | b6fa9a44 | Michael Hanselmann | os.rename(tmpfile.name, tmpfile2.name) |
85 | b6fa9a44 | Michael Hanselmann | assert not os.path.exists(tmpfile.name) |
86 | b6fa9a44 | Michael Hanselmann | |
87 | b6fa9a44 | Michael Hanselmann | # Write another message, should reopen
|
88 | b6fa9a44 | Michael Hanselmann | for _ in range(4): |
89 | b6fa9a44 | Michael Hanselmann | logger.info("Test message INFO")
|
90 | ad88650c | Michael Hanselmann | |
91 | ad88650c | Michael Hanselmann | # Flag must be reset
|
92 | ad88650c | Michael Hanselmann | self.assertFalse(handler._reopen)
|
93 | ad88650c | Michael Hanselmann | |
94 | b6fa9a44 | Michael Hanselmann | self.assertFalse(utils.VerifyFileID(utils.GetFileID(tmpfile.name),
|
95 | b6fa9a44 | Michael Hanselmann | before_id)) |
96 | b6fa9a44 | Michael Hanselmann | |
97 | b6fa9a44 | Michael Hanselmann | logger.removeHandler(handler) |
98 | b6fa9a44 | Michael Hanselmann | self.assertFalse(logger.handlers)
|
99 | b6fa9a44 | Michael Hanselmann | handler.close() |
100 | b6fa9a44 | Michael Hanselmann | |
101 | b6fa9a44 | Michael Hanselmann | self.assertEqual(len(utils.ReadFile(tmpfile.name).splitlines()), 4) |
102 | b6fa9a44 | Michael Hanselmann | self.assertEqual(len(utils.ReadFile(tmpfile2.name).splitlines()), 3) |
103 | b6fa9a44 | Michael Hanselmann | |
104 | b6fa9a44 | Michael Hanselmann | def testConsole(self): |
105 | b6fa9a44 | Michael Hanselmann | for (console, check) in [(None, False), |
106 | b6fa9a44 | Michael Hanselmann | (tempfile.NamedTemporaryFile(), True),
|
107 | b6fa9a44 | Michael Hanselmann | (self._FailingFile(os.devnull), False)]: |
108 | b6fa9a44 | Michael Hanselmann | # Create a handler which will fail when handling errors
|
109 | b6fa9a44 | Michael Hanselmann | cls = utils.log._LogErrorsToConsole(self._FailingHandler)
|
110 | b6fa9a44 | Michael Hanselmann | |
111 | b6fa9a44 | Michael Hanselmann | # Instantiate handler with file which will fail when writing,
|
112 | b6fa9a44 | Michael Hanselmann | # provoking a write to the console
|
113 | b6fa9a44 | Michael Hanselmann | handler = cls(console, self._FailingFile(os.devnull))
|
114 | b6fa9a44 | Michael Hanselmann | |
115 | b6fa9a44 | Michael Hanselmann | logger = logging.Logger("TestLogger")
|
116 | b6fa9a44 | Michael Hanselmann | logger.addHandler(handler) |
117 | b6fa9a44 | Michael Hanselmann | self.assertEqual(len(logger.handlers), 1) |
118 | b6fa9a44 | Michael Hanselmann | |
119 | b6fa9a44 | Michael Hanselmann | # Provoke write
|
120 | b6fa9a44 | Michael Hanselmann | logger.error("Test message ERROR")
|
121 | b6fa9a44 | Michael Hanselmann | |
122 | b6fa9a44 | Michael Hanselmann | # Take everything apart
|
123 | b6fa9a44 | Michael Hanselmann | logger.removeHandler(handler) |
124 | b6fa9a44 | Michael Hanselmann | self.assertFalse(logger.handlers)
|
125 | b6fa9a44 | Michael Hanselmann | handler.close() |
126 | b6fa9a44 | Michael Hanselmann | |
127 | b6fa9a44 | Michael Hanselmann | if console and check: |
128 | b6fa9a44 | Michael Hanselmann | console.flush() |
129 | b6fa9a44 | Michael Hanselmann | |
130 | b6fa9a44 | Michael Hanselmann | # Check console output
|
131 | b6fa9a44 | Michael Hanselmann | consout = utils.ReadFile(console.name) |
132 | b6fa9a44 | Michael Hanselmann | self.assertTrue("Cannot log message" in consout) |
133 | b6fa9a44 | Michael Hanselmann | self.assertTrue("Test message ERROR" in consout) |
134 | b6fa9a44 | Michael Hanselmann | |
135 | b6fa9a44 | Michael Hanselmann | class _FailingFile(file): |
136 | b6fa9a44 | Michael Hanselmann | def write(self, _): |
137 | b6fa9a44 | Michael Hanselmann | raise Exception |
138 | b6fa9a44 | Michael Hanselmann | |
139 | b6fa9a44 | Michael Hanselmann | class _FailingHandler(logging.StreamHandler): |
140 | b6fa9a44 | Michael Hanselmann | def handleError(self, _): |
141 | b6fa9a44 | Michael Hanselmann | raise Exception |
142 | b6fa9a44 | Michael Hanselmann | |
143 | b6fa9a44 | Michael Hanselmann | |
144 | 9a6813ac | Michael Hanselmann | class TestSetupLogging(unittest.TestCase): |
145 | 9a6813ac | Michael Hanselmann | def setUp(self): |
146 | 9a6813ac | Michael Hanselmann | self.tmpdir = tempfile.mkdtemp()
|
147 | 9a6813ac | Michael Hanselmann | |
148 | 9a6813ac | Michael Hanselmann | def tearDown(self): |
149 | 9a6813ac | Michael Hanselmann | shutil.rmtree(self.tmpdir)
|
150 | 9a6813ac | Michael Hanselmann | |
151 | 9a6813ac | Michael Hanselmann | def testSimple(self): |
152 | 9a6813ac | Michael Hanselmann | logfile = utils.PathJoin(self.tmpdir, "basic.log") |
153 | 9a6813ac | Michael Hanselmann | logger = logging.Logger("TestLogger")
|
154 | 9a6813ac | Michael Hanselmann | self.assertTrue(callable(utils.SetupLogging(logfile, "test", |
155 | 9a6813ac | Michael Hanselmann | console_logging=False,
|
156 | 9a6813ac | Michael Hanselmann | syslog=constants.SYSLOG_NO, |
157 | 9a6813ac | Michael Hanselmann | stderr_logging=False,
|
158 | 9a6813ac | Michael Hanselmann | multithreaded=False,
|
159 | 9a6813ac | Michael Hanselmann | root_logger=logger))) |
160 | 9a6813ac | Michael Hanselmann | self.assertEqual(utils.ReadFile(logfile), "") |
161 | 9a6813ac | Michael Hanselmann | logger.error("This is a test")
|
162 | 9a6813ac | Michael Hanselmann | |
163 | 9a6813ac | Michael Hanselmann | # Ensure SetupLogging used custom logger
|
164 | 9a6813ac | Michael Hanselmann | logging.error("This message should not show up in the test log file")
|
165 | 9a6813ac | Michael Hanselmann | |
166 | 9a6813ac | Michael Hanselmann | self.assertTrue(utils.ReadFile(logfile).endswith("This is a test\n")) |
167 | 9a6813ac | Michael Hanselmann | |
168 | 9a6813ac | Michael Hanselmann | def testReopen(self): |
169 | 9a6813ac | Michael Hanselmann | logfile = utils.PathJoin(self.tmpdir, "reopen.log") |
170 | 9a6813ac | Michael Hanselmann | logfile2 = utils.PathJoin(self.tmpdir, "reopen.log.OLD") |
171 | 9a6813ac | Michael Hanselmann | logger = logging.Logger("TestLogger")
|
172 | 9a6813ac | Michael Hanselmann | reopen_fn = utils.SetupLogging(logfile, "test",
|
173 | 9a6813ac | Michael Hanselmann | console_logging=False,
|
174 | 9a6813ac | Michael Hanselmann | syslog=constants.SYSLOG_NO, |
175 | 9a6813ac | Michael Hanselmann | stderr_logging=False,
|
176 | 9a6813ac | Michael Hanselmann | multithreaded=False,
|
177 | 9a6813ac | Michael Hanselmann | root_logger=logger) |
178 | 9a6813ac | Michael Hanselmann | self.assertTrue(callable(reopen_fn)) |
179 | 9a6813ac | Michael Hanselmann | |
180 | 9a6813ac | Michael Hanselmann | self.assertEqual(utils.ReadFile(logfile), "") |
181 | 9a6813ac | Michael Hanselmann | logger.error("This is a test")
|
182 | 9a6813ac | Michael Hanselmann | self.assertTrue(utils.ReadFile(logfile).endswith("This is a test\n")) |
183 | 9a6813ac | Michael Hanselmann | |
184 | 9a6813ac | Michael Hanselmann | os.rename(logfile, logfile2) |
185 | 9a6813ac | Michael Hanselmann | assert not os.path.exists(logfile) |
186 | 9a6813ac | Michael Hanselmann | |
187 | 9a6813ac | Michael Hanselmann | # Notify logger to reopen on the next message
|
188 | 9a6813ac | Michael Hanselmann | reopen_fn() |
189 | 9a6813ac | Michael Hanselmann | assert not os.path.exists(logfile) |
190 | 9a6813ac | Michael Hanselmann | |
191 | 9a6813ac | Michael Hanselmann | # Provoke actual reopen
|
192 | 9a6813ac | Michael Hanselmann | logger.error("First message")
|
193 | 9a6813ac | Michael Hanselmann | |
194 | 9a6813ac | Michael Hanselmann | self.assertTrue(utils.ReadFile(logfile).endswith("First message\n")) |
195 | 9a6813ac | Michael Hanselmann | self.assertTrue(utils.ReadFile(logfile2).endswith("This is a test\n")) |
196 | 9a6813ac | Michael Hanselmann | |
197 | 9a6813ac | Michael Hanselmann | |
198 | 796b5152 | Michael Hanselmann | class TestSetupToolLogging(unittest.TestCase): |
199 | 796b5152 | Michael Hanselmann | def test(self): |
200 | 796b5152 | Michael Hanselmann | error_name = logging.getLevelName(logging.ERROR) |
201 | 796b5152 | Michael Hanselmann | warn_name = logging.getLevelName(logging.WARNING) |
202 | 796b5152 | Michael Hanselmann | info_name = logging.getLevelName(logging.INFO) |
203 | 796b5152 | Michael Hanselmann | debug_name = logging.getLevelName(logging.DEBUG) |
204 | 796b5152 | Michael Hanselmann | |
205 | 796b5152 | Michael Hanselmann | for debug in [False, True]: |
206 | 796b5152 | Michael Hanselmann | for verbose in [False, True]: |
207 | 796b5152 | Michael Hanselmann | logger = logging.Logger("TestLogger")
|
208 | 796b5152 | Michael Hanselmann | buf = StringIO() |
209 | 796b5152 | Michael Hanselmann | |
210 | 796b5152 | Michael Hanselmann | utils.SetupToolLogging(debug, verbose, _root_logger=logger, _stream=buf) |
211 | 796b5152 | Michael Hanselmann | |
212 | 796b5152 | Michael Hanselmann | logger.error("level=error")
|
213 | 796b5152 | Michael Hanselmann | logger.warning("level=warning")
|
214 | 796b5152 | Michael Hanselmann | logger.info("level=info")
|
215 | 796b5152 | Michael Hanselmann | logger.debug("level=debug")
|
216 | 796b5152 | Michael Hanselmann | |
217 | 796b5152 | Michael Hanselmann | lines = buf.getvalue().splitlines() |
218 | 796b5152 | Michael Hanselmann | |
219 | 796b5152 | Michael Hanselmann | self.assertTrue(compat.all(line.count(":") == 3 for line in lines)) |
220 | 796b5152 | Michael Hanselmann | |
221 | 796b5152 | Michael Hanselmann | messages = [line.split(":", 3)[-1].strip() for line in lines] |
222 | 796b5152 | Michael Hanselmann | |
223 | 796b5152 | Michael Hanselmann | if debug:
|
224 | 796b5152 | Michael Hanselmann | self.assertEqual(messages, [
|
225 | 796b5152 | Michael Hanselmann | "%s level=error" % error_name,
|
226 | 796b5152 | Michael Hanselmann | "%s level=warning" % warn_name,
|
227 | 796b5152 | Michael Hanselmann | "%s level=info" % info_name,
|
228 | 796b5152 | Michael Hanselmann | "%s level=debug" % debug_name,
|
229 | 796b5152 | Michael Hanselmann | ]) |
230 | 796b5152 | Michael Hanselmann | elif verbose:
|
231 | 796b5152 | Michael Hanselmann | self.assertEqual(messages, [
|
232 | 796b5152 | Michael Hanselmann | "%s level=error" % error_name,
|
233 | 796b5152 | Michael Hanselmann | "%s level=warning" % warn_name,
|
234 | 796b5152 | Michael Hanselmann | "%s level=info" % info_name,
|
235 | 796b5152 | Michael Hanselmann | ]) |
236 | 796b5152 | Michael Hanselmann | else:
|
237 | 796b5152 | Michael Hanselmann | self.assertEqual(messages, [
|
238 | 796b5152 | Michael Hanselmann | "level=error",
|
239 | 796b5152 | Michael Hanselmann | "level=warning",
|
240 | 796b5152 | Michael Hanselmann | ]) |
241 | 796b5152 | Michael Hanselmann | |
242 | 796b5152 | Michael Hanselmann | def testThreadName(self): |
243 | 796b5152 | Michael Hanselmann | thread_name = threading.currentThread().getName() |
244 | 796b5152 | Michael Hanselmann | |
245 | 796b5152 | Michael Hanselmann | for enable_threadname in [False, True]: |
246 | 796b5152 | Michael Hanselmann | logger = logging.Logger("TestLogger")
|
247 | 796b5152 | Michael Hanselmann | buf = StringIO() |
248 | 796b5152 | Michael Hanselmann | |
249 | 796b5152 | Michael Hanselmann | utils.SetupToolLogging(True, True, threadname=enable_threadname, |
250 | 796b5152 | Michael Hanselmann | _root_logger=logger, _stream=buf) |
251 | 796b5152 | Michael Hanselmann | |
252 | 796b5152 | Michael Hanselmann | logger.debug("test134042376")
|
253 | 796b5152 | Michael Hanselmann | |
254 | 796b5152 | Michael Hanselmann | lines = buf.getvalue().splitlines() |
255 | 796b5152 | Michael Hanselmann | self.assertEqual(len(lines), 1) |
256 | 796b5152 | Michael Hanselmann | |
257 | 796b5152 | Michael Hanselmann | if enable_threadname:
|
258 | 796b5152 | Michael Hanselmann | self.assertTrue((" %s " % thread_name) in lines[0]) |
259 | 796b5152 | Michael Hanselmann | else:
|
260 | 796b5152 | Michael Hanselmann | self.assertTrue(thread_name not in lines[0]) |
261 | 796b5152 | Michael Hanselmann | |
262 | 796b5152 | Michael Hanselmann | |
263 | b6fa9a44 | Michael Hanselmann | if __name__ == "__main__": |
264 | b6fa9a44 | Michael Hanselmann | testutils.GanetiTestProgram() |