Modify gnt-node add to call external script
[ganeti-local] / test / testutils.py
1 #
2 #
3
4 # Copyright (C) 2006, 2007, 2008 Google Inc.
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 # General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 # 02110-1301, USA.
20
21
22 """Utilities for unit testing"""
23
24 import os
25 import sys
26 import stat
27 import tempfile
28 import unittest
29 import logging
30
31 from ganeti import utils
32
33
34 def GetSourceDir():
35   return os.environ.get("TOP_SRCDIR", ".")
36
37
38 class GanetiTestProgram(unittest.TestProgram):
39   def runTests(self):
40     """
41
42     """
43     logging.basicConfig(filename=os.devnull)
44
45     sys.stderr.write("Running %s\n" % self.progName)
46     sys.stderr.flush()
47
48     # Ensure assertions will be evaluated
49     if not __debug__:
50       raise Exception("Not running in debug mode, assertions would not be"
51                       " evaluated")
52
53     # Check again, this time with a real assertion
54     try:
55       assert False
56     except AssertionError:
57       pass
58     else:
59       raise Exception("Assertion not evaluated")
60
61     return unittest.TestProgram.runTests(self)
62
63
64 class GanetiTestCase(unittest.TestCase):
65   """Helper class for unittesting.
66
67   This class defines a few utility functions that help in building
68   unittests. Child classes must call the parent setup and cleanup.
69
70   """
71   def setUp(self):
72     self._temp_files = []
73
74   def tearDown(self):
75     while self._temp_files:
76       try:
77         utils.RemoveFile(self._temp_files.pop())
78       except EnvironmentError, err:
79         pass
80
81   def assertFileContent(self, file_name, expected_content):
82     """Checks that the content of a file is what we expect.
83
84     @type file_name: str
85     @param file_name: the file whose contents we should check
86     @type expected_content: str
87     @param expected_content: the content we expect
88
89     """
90     actual_content = utils.ReadFile(file_name)
91     self.assertEqual(actual_content, expected_content)
92
93   def assertFileMode(self, file_name, expected_mode):
94     """Checks that the mode of a file is what we expect.
95
96     @type file_name: str
97     @param file_name: the file whose contents we should check
98     @type expected_mode: int
99     @param expected_mode: the mode we expect
100
101     """
102     st = os.stat(file_name)
103     actual_mode = stat.S_IMODE(st.st_mode)
104     self.assertEqual(actual_mode, expected_mode)
105
106   def assertEqualValues(self, first, second, msg=None):
107     """Compares two values whether they're equal.
108
109     Tuples are automatically converted to lists before comparing.
110
111     """
112     return self.assertEqual(UnifyValueType(first),
113                             UnifyValueType(second),
114                             msg=msg)
115
116   @staticmethod
117   def _TestDataFilename(name):
118     """Returns the filename of a given test data file.
119
120     @type name: str
121     @param name: the 'base' of the file name, as present in
122         the test/data directory
123     @rtype: str
124     @return: the full path to the filename, such that it can
125         be used in 'make distcheck' rules
126
127     """
128     return "%s/test/data/%s" % (GetSourceDir(), name)
129
130   @classmethod
131   def _ReadTestData(cls, name):
132     """Returns the contents of a test data file.
133
134     This is just a very simple wrapper over utils.ReadFile with the
135     proper test file name.
136
137     """
138     return utils.ReadFile(cls._TestDataFilename(name))
139
140   def _CreateTempFile(self):
141     """Creates a temporary file and adds it to the internal cleanup list.
142
143     This method simplifies the creation and cleanup of temporary files
144     during tests.
145
146     """
147     fh, fname = tempfile.mkstemp(prefix="ganeti-test", suffix=".tmp")
148     os.close(fh)
149     self._temp_files.append(fname)
150     return fname
151
152
153 def UnifyValueType(data):
154   """Converts all tuples into lists.
155
156   This is useful for unittests where an external library doesn't keep types.
157
158   """
159   if isinstance(data, (tuple, list)):
160     return [UnifyValueType(i) for i in data]
161
162   elif isinstance(data, dict):
163     return dict([(UnifyValueType(key), UnifyValueType(value))
164                  for (key, value) in data.iteritems()])
165
166   return data