Statistics
| Branch: | Tag: | Revision:

root / test / testutils.py @ eea3b572

History | View | Annotate | Download (6.3 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 0d20cc42 Bernardo Dal Seno
  def assertFileUid(self, file_name, expected_uid):
140 0d20cc42 Bernardo Dal Seno
    """Checks that the user id of a file is what we expect.
141 0d20cc42 Bernardo Dal Seno

142 0d20cc42 Bernardo Dal Seno
    @type file_name: str
143 0d20cc42 Bernardo Dal Seno
    @param file_name: the file whose contents we should check
144 0d20cc42 Bernardo Dal Seno
    @type expected_uid: int
145 0d20cc42 Bernardo Dal Seno
    @param expected_uid: the user id we expect
146 0d20cc42 Bernardo Dal Seno

147 0d20cc42 Bernardo Dal Seno
    """
148 0d20cc42 Bernardo Dal Seno
    st = os.stat(file_name)
149 0d20cc42 Bernardo Dal Seno
    actual_uid = st.st_uid
150 0d20cc42 Bernardo Dal Seno
    self.assertEqual(actual_uid, expected_uid)
151 0d20cc42 Bernardo Dal Seno
152 0d20cc42 Bernardo Dal Seno
  def assertFileGid(self, file_name, expected_gid):
153 0d20cc42 Bernardo Dal Seno
    """Checks that the group id of a file is what we expect.
154 0d20cc42 Bernardo Dal Seno

155 0d20cc42 Bernardo Dal Seno
    @type file_name: str
156 0d20cc42 Bernardo Dal Seno
    @param file_name: the file whose contents we should check
157 0d20cc42 Bernardo Dal Seno
    @type expected_gid: int
158 0d20cc42 Bernardo Dal Seno
    @param expected_gid: the group id we expect
159 0d20cc42 Bernardo Dal Seno

160 0d20cc42 Bernardo Dal Seno
    """
161 0d20cc42 Bernardo Dal Seno
    st = os.stat(file_name)
162 0d20cc42 Bernardo Dal Seno
    actual_gid = st.st_gid
163 0d20cc42 Bernardo Dal Seno
    self.assertEqual(actual_gid, expected_gid)
164 0d20cc42 Bernardo Dal Seno
165 d357f531 Michael Hanselmann
  def assertEqualValues(self, first, second, msg=None):
166 d357f531 Michael Hanselmann
    """Compares two values whether they're equal.
167 d357f531 Michael Hanselmann

168 d357f531 Michael Hanselmann
    Tuples are automatically converted to lists before comparing.
169 d357f531 Michael Hanselmann

170 d357f531 Michael Hanselmann
    """
171 d357f531 Michael Hanselmann
    return self.assertEqual(UnifyValueType(first),
172 d357f531 Michael Hanselmann
                            UnifyValueType(second),
173 d357f531 Michael Hanselmann
                            msg=msg)
174 d357f531 Michael Hanselmann
175 149a5439 Iustin Pop
  @staticmethod
176 149a5439 Iustin Pop
  def _TestDataFilename(name):
177 149a5439 Iustin Pop
    """Returns the filename of a given test data file.
178 149a5439 Iustin Pop

179 149a5439 Iustin Pop
    @type name: str
180 149a5439 Iustin Pop
    @param name: the 'base' of the file name, as present in
181 149a5439 Iustin Pop
        the test/data directory
182 149a5439 Iustin Pop
    @rtype: str
183 149a5439 Iustin Pop
    @return: the full path to the filename, such that it can
184 149a5439 Iustin Pop
        be used in 'make distcheck' rules
185 c9c4f19e Michael Hanselmann

186 c9c4f19e Michael Hanselmann
    """
187 3f991867 Michael Hanselmann
    return "%s/test/data/%s" % (GetSourceDir(), name)
188 149a5439 Iustin Pop
189 149a5439 Iustin Pop
  @classmethod
190 149a5439 Iustin Pop
  def _ReadTestData(cls, name):
191 149a5439 Iustin Pop
    """Returns the contents of a test data file.
192 149a5439 Iustin Pop

193 149a5439 Iustin Pop
    This is just a very simple wrapper over utils.ReadFile with the
194 149a5439 Iustin Pop
    proper test file name.
195 149a5439 Iustin Pop

196 149a5439 Iustin Pop
    """
197 149a5439 Iustin Pop
    return utils.ReadFile(cls._TestDataFilename(name))
198 51596eb2 Iustin Pop
199 51596eb2 Iustin Pop
  def _CreateTempFile(self):
200 51596eb2 Iustin Pop
    """Creates a temporary file and adds it to the internal cleanup list.
201 51596eb2 Iustin Pop

202 51596eb2 Iustin Pop
    This method simplifies the creation and cleanup of temporary files
203 51596eb2 Iustin Pop
    during tests.
204 51596eb2 Iustin Pop

205 51596eb2 Iustin Pop
    """
206 51596eb2 Iustin Pop
    fh, fname = tempfile.mkstemp(prefix="ganeti-test", suffix=".tmp")
207 51596eb2 Iustin Pop
    os.close(fh)
208 51596eb2 Iustin Pop
    self._temp_files.append(fname)
209 51596eb2 Iustin Pop
    return fname
210 d357f531 Michael Hanselmann
211 d357f531 Michael Hanselmann
212 d357f531 Michael Hanselmann
def UnifyValueType(data):
213 d357f531 Michael Hanselmann
  """Converts all tuples into lists.
214 d357f531 Michael Hanselmann

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

217 d357f531 Michael Hanselmann
  """
218 d357f531 Michael Hanselmann
  if isinstance(data, (tuple, list)):
219 d357f531 Michael Hanselmann
    return [UnifyValueType(i) for i in data]
220 d357f531 Michael Hanselmann
221 d357f531 Michael Hanselmann
  elif isinstance(data, dict):
222 d357f531 Michael Hanselmann
    return dict([(UnifyValueType(key), UnifyValueType(value))
223 d357f531 Michael Hanselmann
                 for (key, value) in data.iteritems()])
224 d357f531 Michael Hanselmann
225 d357f531 Michael Hanselmann
  return data