New version.
[pykickstart.git] / tests / baseclass.py
blobbbc901e413f72742bfb3d776535d2ae58ec4b9ce
1 import os
2 import sys
3 import unittest
4 import shlex
5 import imputil
6 import glob
7 import warnings
8 import re
9 import tempfile
10 import shutil
12 from pykickstart.errors import *
13 from pykickstart.parser import preprocessFromString, KickstartParser
14 from pykickstart.version import *
15 import gettext
16 gettext.textdomain("pykickstart")
17 _ = lambda x: gettext.ldgettext("pykickstart", x)
19 class ParserTest(unittest.TestCase):
20 version = DEVEL
22 def __init__(self, *args, **kwargs):
23 unittest.TestCase.__init__(self, *args, **kwargs)
25 def setUp(self):
26 self._handler = None
27 self._parser = None
28 unittest.TestCase.setUp(self)
30 def tearDown(self):
31 """Undo anything performed by setUp"""
32 unittest.TestCase.tearDown(self)
34 def get_parser(self):
35 """This function can be overriden by subclasses,
36 for example if the subclass wants to use a fresh
37 parser for every test
38 """
39 if self._parser is None:
40 self._parser = KickstartParser(self.handler)
41 return self._parser
43 @property
44 def parser(self):
45 return self.get_parser()
47 @property
48 def handler(self):
49 if self._handler is None:
50 self._handler = makeVersion(self.version)
51 return self._handler
53 def assert_parse_error(self, ks_string, exception=KickstartParseError, regex=r".*"):
54 """Parsing of this command sequence is expected to raise an exception,
55 exception type can be set by the exception keyword argument.
57 By default the KickstartParseError is expected.
58 """
60 with self.assertRaisesRegexp(exception, regex):
61 self.parser.readKickstartFromString(ks_string)
63 def assert_parse(self, ks_string):
64 """Parsing of his command sequence is expected to finish without
65 raising an exception; if it raises an exception, the test failed
66 """
67 try:
68 self.parser.readKickstartFromString(ks_string)
69 except Exception, e:
70 self.fail("Failed while parsing commands %s: %s" % (ks_string, e))
73 class CommandSequenceTest(ParserTest):
74 """Kickstart command sequence testing
76 Enables testing kickstart indepdent command sequences
77 and checking if their parsing raises or doesn't raise
78 a parsing exception.
79 """
81 def get_parser(self):
82 """Command sequence tests need a fresh parser
83 for each test"""
84 handler = makeVersion(self.version)
85 return KickstartParser(handler)
88 # Base class for any command test case
89 class CommandTest(unittest.TestCase):
90 def setUp(self):
91 '''Perform any command setup'''
92 unittest.TestCase.setUp(self)
94 # ignore DeprecationWarning
95 warnings.simplefilter("error", category=UserWarning)
96 warnings.simplefilter("ignore", category=DeprecationWarning, append=0)
98 def tearDown(self):
99 '''Undo anything performed by setUp(self)'''
100 # reset warnings
101 warnings.resetwarnings()
103 unittest.TestCase.tearDown(self)
105 def __init__(self, *args, **kwargs):
106 unittest.TestCase.__init__(self, *args, **kwargs)
107 self._options = []
109 @property
110 def handler(self):
111 version = self.__class__.__name__.split("_")[0]
112 return returnClassForVersion(version)
114 @property
115 def optionList(self):
116 if self._options:
117 return self._options
119 parser = self.getParser(self.command)._getParser()
121 for opt in filter(lambda o: not o.deprecated, parser.option_list):
122 self._options.append(opt.get_opt_string())
124 return self._options
126 def getParser(self, inputStr):
127 '''Find a handler using the class name. Return the requested command
128 object.'''
129 args = shlex.split(inputStr)
130 cmd = args[0]
132 parser = self.handler().commands[cmd]
133 parser.currentLine = inputStr
134 parser.currentCmd = args[0]
135 parser.seen = True
137 return parser
139 def assert_parse(self, inputStr, expectedStr=None, ignoreComments=True):
140 '''KickstartParseError is not raised and the resulting string matches
141 supplied value'''
142 parser = self.getParser(inputStr)
143 args = shlex.split(inputStr)
145 # If expectedStr supplied, we want to ensure the parsed result matches
146 if expectedStr is not None:
147 obj = parser.parse(args[1:])
148 result = str(obj)
150 # Strip any comment lines ... we only match on non-comments
151 if ignoreComments:
152 result = re.sub("^#[^\n]*\n", "", result)
154 # Ensure we parsed as expected
155 self.assertEqual(result, expectedStr)
156 # No expectedStr supplied, just make sure it does not raise an
157 # exception
158 else:
159 try:
160 obj = parser.parse(args[1:])
161 except Exception, e:
162 self.fail("Failed while parsing: %s" % e)
163 return obj
165 def assert_parse_error(self, inputStr, exception=KickstartParseError, regex=r".*"):
166 '''Assert that parsing the supplied string raises a
167 KickstartParseError'''
168 parser = self.getParser(inputStr)
169 args = shlex.split(inputStr)
171 with self.assertRaisesRegexp(exception, regex):
172 parser.parse(args[1:])
174 def assert_deprecated(self, cmd, opt):
175 '''Ensure that the provided option is listed as deprecated'''
176 parser = self.getParser(cmd)
178 for op in parser.op.option_list:
179 if op.get_opt_string() == opt:
180 self.assert_(op.deprecated)
182 def assert_removed(self, cmd, opt):
183 '''Ensure that the provided option is not present in option_list'''
184 parser = self.getParser(cmd)
185 for op in parser.op.option_list:
186 self.assertNotEqual(op.dest, opt)
188 def assert_required(self, cmd, opt):
189 '''Ensure that the provided option is labelled as required in
190 option_list'''
191 parser = self.getParser(cmd)
192 for op in parser.op.option_list:
193 if op.get_opt_string() == opt:
194 self.assert_(op.required)
196 def assert_type(self, cmd, opt, opt_type):
197 '''Ensure that the provided option is of the requested type'''
198 parser = self.getParser(cmd)
199 for op in parser.op.option_list:
200 if op.get_opt_string() == opt:
201 self.assertEqual(op.type, opt_type)
204 def loadModules(moduleDir, cls_pattern="_TestCase", skip_list=["__init__", "baseclass"]):
205 '''taken from firstboot/loader.py'''
207 # Guaruntee that __init__ is skipped
208 if skip_list.count("__init__") == 0:
209 skip_list.append("__init__")
211 tstList = list()
213 # Make sure moduleDir is in the system path so imputil works.
214 if not moduleDir in sys.path:
215 sys.path.insert(0, moduleDir)
217 # Get a list of all *.py files in moduleDir
218 moduleList = []
219 lst = map(lambda x: os.path.splitext(os.path.basename(x))[0],
220 glob.glob(moduleDir + "/*.py"))
222 # Inspect each .py file found
223 for module in lst:
224 if module in skip_list:
225 continue
227 # Attempt to load the found module.
228 try:
229 found = imputil.imp.find_module(module)
230 loaded = imputil.imp.load_module(module, found[0], found[1], found[2])
231 except ImportError, e:
232 print(_("Error loading module %s: %s") % (module, e))
233 continue
235 # Find class names that match the supplied pattern (default: "_TestCase")
236 beforeCount = len(tstList)
237 for obj in loaded.__dict__.keys():
238 if obj.endswith(cls_pattern):
239 tstList.append(loaded.__dict__[obj])
240 afterCount = len(tstList)
242 # Warn if no tests found
243 if beforeCount == afterCount:
244 print(_("Module %s does not contain any test cases; skipping.") % module)
245 continue
247 return tstList
249 # Run the tests
250 if __name__ == "__main__":
251 # Make sure PWD is in the path before the eggs, system paths, etc.
252 sys.path.insert(0, os.environ.get("PWD"))
254 # Create a test suite
255 PyKickstartTestSuite = unittest.TestSuite()
257 # Find tests to add
258 tstList = loadModules(os.path.join(os.environ.get("PWD"), "tests/"))
259 tstList.extend(loadModules(os.path.join(os.environ.get("PWD"), "tests/commands")))
260 tstList.extend(loadModules(os.path.join(os.environ.get("PWD"), "tests/parser")))
261 for tst in tstList:
262 PyKickstartTestSuite.addTest(tst())
264 # Run tests
265 unittest.main(defaultTest="PyKickstartTestSuite")