Statistics
| Branch: | Tag: | Revision:

root / test / py / ganeti.utils.log_unittest.py @ 7352d33b

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()