Statistics
| Branch: | Tag: | Revision:

root / test / testutils.py @ 7578ab0a

History | View | Annotate | Download (5.5 kB)

1 c9c4f19e Michael Hanselmann
#
2 c9c4f19e Michael Hanselmann
#
3 c9c4f19e Michael Hanselmann
4 c9c4f19e Michael Hanselmann
# Copyright (C) 2006, 2007, 2008 Google Inc.
5 c9c4f19e Michael Hanselmann
#
6 c9c4f19e Michael Hanselmann
# This program is free software; you can redistribute it and/or modify
7 c9c4f19e Michael Hanselmann
# it under the terms of the GNU General Public License as published by
8 c9c4f19e Michael Hanselmann
# the Free Software Foundation; either version 2 of the License, or
9 c9c4f19e Michael Hanselmann
# (at your option) any later version.
10 c9c4f19e Michael Hanselmann
#
11 c9c4f19e Michael Hanselmann
# This program is distributed in the hope that it will be useful, but
12 c9c4f19e Michael Hanselmann
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 c9c4f19e Michael Hanselmann
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 c9c4f19e Michael Hanselmann
# General Public License for more details.
15 c9c4f19e Michael Hanselmann
#
16 c9c4f19e Michael Hanselmann
# You should have received a copy of the GNU General Public License
17 c9c4f19e Michael Hanselmann
# along with this program; if not, write to the Free Software
18 c9c4f19e Michael Hanselmann
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 c9c4f19e Michael Hanselmann
# 02110-1301, USA.
20 c9c4f19e Michael Hanselmann
21 c9c4f19e Michael Hanselmann
22 c9c4f19e Michael Hanselmann
"""Utilities for unit testing"""
23 c9c4f19e Michael Hanselmann
24 149a5439 Iustin Pop
import os
25 43983a88 Michael Hanselmann
import sys
26 9b977740 Guido Trotter
import stat
27 51596eb2 Iustin Pop
import tempfile
28 c9c4f19e Michael Hanselmann
import unittest
29 25231ec5 Michael Hanselmann
import logging
30 c6a65efb Michael Hanselmann
import types
31 c9c4f19e Michael Hanselmann
32 149a5439 Iustin Pop
from ganeti import utils
33 149a5439 Iustin Pop
34 c9c4f19e Michael Hanselmann
35 3f991867 Michael Hanselmann
def GetSourceDir():
36 3f991867 Michael Hanselmann
  return os.environ.get("TOP_SRCDIR", ".")
37 3f991867 Michael Hanselmann
38 3f991867 Michael Hanselmann
39 913138f4 Michael Hanselmann
def _SetupLogging(verbose):
40 913138f4 Michael Hanselmann
  """Setupup logging infrastructure.
41 913138f4 Michael Hanselmann

42 913138f4 Michael Hanselmann
  """
43 913138f4 Michael Hanselmann
  fmt = logging.Formatter("%(asctime)s: %(threadName)s"
44 913138f4 Michael Hanselmann
                          " %(levelname)s %(message)s")
45 913138f4 Michael Hanselmann
46 913138f4 Michael Hanselmann
  if verbose:
47 913138f4 Michael Hanselmann
    handler = logging.StreamHandler()
48 913138f4 Michael Hanselmann
  else:
49 913138f4 Michael Hanselmann
    handler = logging.FileHandler(os.devnull, "a")
50 913138f4 Michael Hanselmann
51 913138f4 Michael Hanselmann
  handler.setLevel(logging.NOTSET)
52 913138f4 Michael Hanselmann
  handler.setFormatter(fmt)
53 913138f4 Michael Hanselmann
54 913138f4 Michael Hanselmann
  root_logger = logging.getLogger("")
55 913138f4 Michael Hanselmann
  root_logger.setLevel(logging.NOTSET)
56 913138f4 Michael Hanselmann
  root_logger.addHandler(handler)
57 913138f4 Michael Hanselmann
58 913138f4 Michael Hanselmann
59 25231ec5 Michael Hanselmann
class GanetiTestProgram(unittest.TestProgram):
60 25231ec5 Michael Hanselmann
  def runTests(self):
61 913138f4 Michael Hanselmann
    """Runs all tests.
62 25231ec5 Michael Hanselmann

63 25231ec5 Michael Hanselmann
    """
64 913138f4 Michael Hanselmann
    _SetupLogging("LOGTOSTDERR" in os.environ)
65 43983a88 Michael Hanselmann
66 43983a88 Michael Hanselmann
    sys.stderr.write("Running %s\n" % self.progName)
67 43983a88 Michael Hanselmann
    sys.stderr.flush()
68 43983a88 Michael Hanselmann
69 a9b144cb Michael Hanselmann
    # Ensure assertions will be evaluated
70 a9b144cb Michael Hanselmann
    if not __debug__:
71 a9b144cb Michael Hanselmann
      raise Exception("Not running in debug mode, assertions would not be"
72 a9b144cb Michael Hanselmann
                      " evaluated")
73 a9b144cb Michael Hanselmann
74 a9b144cb Michael Hanselmann
    # Check again, this time with a real assertion
75 a9b144cb Michael Hanselmann
    try:
76 a9b144cb Michael Hanselmann
      assert False
77 a9b144cb Michael Hanselmann
    except AssertionError:
78 a9b144cb Michael Hanselmann
      pass
79 a9b144cb Michael Hanselmann
    else:
80 a9b144cb Michael Hanselmann
      raise Exception("Assertion not evaluated")
81 a9b144cb Michael Hanselmann
82 c6a65efb Michael Hanselmann
    # The following piece of code is a backport from Python 2.6. Python 2.4/2.5
83 c6a65efb Michael Hanselmann
    # only accept class instances as test runners. Being able to pass classes
84 c6a65efb Michael Hanselmann
    # reduces the amount of code necessary for using a custom test runner.
85 c6a65efb Michael Hanselmann
    # 2.6 and above should use their own code, however.
86 c6a65efb Michael Hanselmann
    if (self.testRunner and sys.hexversion < 0x2060000 and
87 c6a65efb Michael Hanselmann
        isinstance(self.testRunner, (type, types.ClassType))):
88 c6a65efb Michael Hanselmann
      try:
89 c6a65efb Michael Hanselmann
        self.testRunner = self.testRunner(verbosity=self.verbosity)
90 c6a65efb Michael Hanselmann
      except TypeError:
91 c6a65efb Michael Hanselmann
        # didn't accept the verbosity argument
92 c6a65efb Michael Hanselmann
        self.testRunner = self.testRunner()
93 c6a65efb Michael Hanselmann
94 25231ec5 Michael Hanselmann
    return unittest.TestProgram.runTests(self)
95 25231ec5 Michael Hanselmann
96 25231ec5 Michael Hanselmann
97 c9c4f19e Michael Hanselmann
class GanetiTestCase(unittest.TestCase):
98 51596eb2 Iustin Pop
  """Helper class for unittesting.
99 51596eb2 Iustin Pop

100 51596eb2 Iustin Pop
  This class defines a few utility functions that help in building
101 51596eb2 Iustin Pop
  unittests. Child classes must call the parent setup and cleanup.
102 51596eb2 Iustin Pop

103 51596eb2 Iustin Pop
  """
104 51596eb2 Iustin Pop
  def setUp(self):
105 51596eb2 Iustin Pop
    self._temp_files = []
106 51596eb2 Iustin Pop
107 51596eb2 Iustin Pop
  def tearDown(self):
108 51596eb2 Iustin Pop
    while self._temp_files:
109 51596eb2 Iustin Pop
      try:
110 51596eb2 Iustin Pop
        utils.RemoveFile(self._temp_files.pop())
111 51596eb2 Iustin Pop
      except EnvironmentError, err:
112 51596eb2 Iustin Pop
        pass
113 51596eb2 Iustin Pop
114 149a5439 Iustin Pop
  def assertFileContent(self, file_name, expected_content):
115 9b977740 Guido Trotter
    """Checks that the content of a file is what we expect.
116 149a5439 Iustin Pop

117 149a5439 Iustin Pop
    @type file_name: str
118 149a5439 Iustin Pop
    @param file_name: the file whose contents we should check
119 149a5439 Iustin Pop
    @type expected_content: str
120 149a5439 Iustin Pop
    @param expected_content: the content we expect
121 149a5439 Iustin Pop

122 149a5439 Iustin Pop
    """
123 149a5439 Iustin Pop
    actual_content = utils.ReadFile(file_name)
124 149a5439 Iustin Pop
    self.assertEqual(actual_content, expected_content)
125 149a5439 Iustin Pop
126 9b977740 Guido Trotter
  def assertFileMode(self, file_name, expected_mode):
127 9b977740 Guido Trotter
    """Checks that the mode of a file is what we expect.
128 9b977740 Guido Trotter

129 9b977740 Guido Trotter
    @type file_name: str
130 9b977740 Guido Trotter
    @param file_name: the file whose contents we should check
131 9b977740 Guido Trotter
    @type expected_mode: int
132 9b977740 Guido Trotter
    @param expected_mode: the mode we expect
133 9b977740 Guido Trotter

134 9b977740 Guido Trotter
    """
135 9b977740 Guido Trotter
    st = os.stat(file_name)
136 9b977740 Guido Trotter
    actual_mode = stat.S_IMODE(st.st_mode)
137 9b977740 Guido Trotter
    self.assertEqual(actual_mode, expected_mode)
138 9b977740 Guido Trotter
139 d357f531 Michael Hanselmann
  def assertEqualValues(self, first, second, msg=None):
140 d357f531 Michael Hanselmann
    """Compares two values whether they're equal.
141 d357f531 Michael Hanselmann

142 d357f531 Michael Hanselmann
    Tuples are automatically converted to lists before comparing.
143 d357f531 Michael Hanselmann

144 d357f531 Michael Hanselmann
    """
145 d357f531 Michael Hanselmann
    return self.assertEqual(UnifyValueType(first),
146 d357f531 Michael Hanselmann
                            UnifyValueType(second),
147 d357f531 Michael Hanselmann
                            msg=msg)
148 d357f531 Michael Hanselmann
149 149a5439 Iustin Pop
  @staticmethod
150 149a5439 Iustin Pop
  def _TestDataFilename(name):
151 149a5439 Iustin Pop
    """Returns the filename of a given test data file.
152 149a5439 Iustin Pop

153 149a5439 Iustin Pop
    @type name: str
154 149a5439 Iustin Pop
    @param name: the 'base' of the file name, as present in
155 149a5439 Iustin Pop
        the test/data directory
156 149a5439 Iustin Pop
    @rtype: str
157 149a5439 Iustin Pop
    @return: the full path to the filename, such that it can
158 149a5439 Iustin Pop
        be used in 'make distcheck' rules
159 c9c4f19e Michael Hanselmann

160 c9c4f19e Michael Hanselmann
    """
161 3f991867 Michael Hanselmann
    return "%s/test/data/%s" % (GetSourceDir(), name)
162 149a5439 Iustin Pop
163 149a5439 Iustin Pop
  @classmethod
164 149a5439 Iustin Pop
  def _ReadTestData(cls, name):
165 149a5439 Iustin Pop
    """Returns the contents of a test data file.
166 149a5439 Iustin Pop

167 149a5439 Iustin Pop
    This is just a very simple wrapper over utils.ReadFile with the
168 149a5439 Iustin Pop
    proper test file name.
169 149a5439 Iustin Pop

170 149a5439 Iustin Pop
    """
171 149a5439 Iustin Pop
    return utils.ReadFile(cls._TestDataFilename(name))
172 51596eb2 Iustin Pop
173 51596eb2 Iustin Pop
  def _CreateTempFile(self):
174 51596eb2 Iustin Pop
    """Creates a temporary file and adds it to the internal cleanup list.
175 51596eb2 Iustin Pop

176 51596eb2 Iustin Pop
    This method simplifies the creation and cleanup of temporary files
177 51596eb2 Iustin Pop
    during tests.
178 51596eb2 Iustin Pop

179 51596eb2 Iustin Pop
    """
180 51596eb2 Iustin Pop
    fh, fname = tempfile.mkstemp(prefix="ganeti-test", suffix=".tmp")
181 51596eb2 Iustin Pop
    os.close(fh)
182 51596eb2 Iustin Pop
    self._temp_files.append(fname)
183 51596eb2 Iustin Pop
    return fname
184 d357f531 Michael Hanselmann
185 d357f531 Michael Hanselmann
186 d357f531 Michael Hanselmann
def UnifyValueType(data):
187 d357f531 Michael Hanselmann
  """Converts all tuples into lists.
188 d357f531 Michael Hanselmann

189 d357f531 Michael Hanselmann
  This is useful for unittests where an external library doesn't keep types.
190 d357f531 Michael Hanselmann

191 d357f531 Michael Hanselmann
  """
192 d357f531 Michael Hanselmann
  if isinstance(data, (tuple, list)):
193 d357f531 Michael Hanselmann
    return [UnifyValueType(i) for i in data]
194 d357f531 Michael Hanselmann
195 d357f531 Michael Hanselmann
  elif isinstance(data, dict):
196 d357f531 Michael Hanselmann
    return dict([(UnifyValueType(key), UnifyValueType(value))
197 d357f531 Michael Hanselmann
                 for (key, value) in data.iteritems()])
198 d357f531 Michael Hanselmann
199 d357f531 Michael Hanselmann
  return data