Reset method seen attrs when switching method (#1004889)
[pykickstart.git] / tests / baseclass.py
blob1589289409ed3c7ca50920a34aa82b2107cd04e4
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):
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 self.assertRaises(exception, self.parser.readKickstartFromString, ks_string)
62 def assert_parse(self, ks_string):
63 """Parsing of his command sequence is expected to finish without
64 raising an exception; if it raises an exception, the test failed
65 """
66 try:
67 self.parser.readKickstartFromString(ks_string)
68 except Exception, e:
69 self.fail("Failed while parsing commands %s: %s" % (ks_string, e))
72 class CommandSequenceTest(ParserTest):
73 """Kickstart command sequence testing
75 Enables testing kickstart indepdent command sequences
76 and checking if their parsing raises or doesn't raise
77 a parsing exception.
78 """
80 def get_parser(self):
81 """Command sequence tests need a fresh parser
82 for each test"""
83 handler = makeVersion(self.version)
84 return KickstartParser(handler)
87 # Base class for any command test case
88 class CommandTest(unittest.TestCase):
89 def setUp(self):
90 '''Perform any command setup'''
91 unittest.TestCase.setUp(self)
93 # ignore DeprecationWarning
94 warnings.simplefilter("error", category=UserWarning)
95 warnings.simplefilter("ignore", category=DeprecationWarning, append=0)
97 def tearDown(self):
98 '''Undo anything performed by setUp(self)'''
99 # reset warnings
100 warnings.resetwarnings()
102 unittest.TestCase.tearDown(self)
104 def __init__(self, *args, **kwargs):
105 unittest.TestCase.__init__(self, *args, **kwargs)
106 self._options = []
108 @property
109 def handler(self):
110 version = self.__class__.__name__.split("_")[0]
111 return returnClassForVersion(version)
113 @property
114 def optionList(self):
115 if self._options:
116 return self._options
118 parser = self.getParser(self.command)._getParser()
120 for opt in filter(lambda o: not o.deprecated, parser.option_list):
121 self._options.append(opt.get_opt_string())
123 return self._options
125 def getParser(self, inputStr):
126 '''Find a handler using the class name. Return the requested command
127 object.'''
128 args = shlex.split(inputStr)
129 cmd = args[0]
131 parser = self.handler().commands[cmd]
132 parser.currentLine = inputStr
133 parser.currentCmd = args[0]
134 parser.seen = True
136 return parser
138 def assert_parse(self, inputStr, expectedStr=None, ignoreComments=True):
139 '''KickstartParseError is not raised and the resulting string matches
140 supplied value'''
141 parser = self.getParser(inputStr)
142 args = shlex.split(inputStr)
144 # If expectedStr supplied, we want to ensure the parsed result matches
145 if expectedStr is not None:
146 obj = parser.parse(args[1:])
147 result = str(obj)
149 # Strip any comment lines ... we only match on non-comments
150 if ignoreComments:
151 result = re.sub("^#[^\n]*\n", "", result)
153 # Ensure we parsed as expected
154 self.assertEqual(result, expectedStr)
155 # No expectedStr supplied, just make sure it does not raise an
156 # exception
157 else:
158 try:
159 obj = parser.parse(args[1:])
160 except Exception, e:
161 self.fail("Failed while parsing: %s" % e)
162 return obj
164 def assert_parse_error(self, inputStr, exception=KickstartParseError):
165 '''Assert that parsing the supplied string raises a
166 KickstartParseError'''
167 parser = self.getParser(inputStr)
168 args = shlex.split(inputStr)
170 self.assertRaises(exception, parser.parse, args[1:])
172 def assert_deprecated(self, cmd, opt):
173 '''Ensure that the provided option is listed as deprecated'''
174 parser = self.getParser(cmd)
176 for op in parser.op.option_list:
177 if op.get_opt_string() == opt:
178 self.assert_(op.deprecated)
180 def assert_removed(self, cmd, opt):
181 '''Ensure that the provided option is not present in option_list'''
182 parser = self.getParser(cmd)
183 for op in parser.op.option_list:
184 self.assertNotEqual(op.dest, opt)
186 def assert_required(self, cmd, opt):
187 '''Ensure that the provided option is labelled as required in
188 option_list'''
189 parser = self.getParser(cmd)
190 for op in parser.op.option_list:
191 if op.get_opt_string() == opt:
192 self.assert_(op.required)
194 def assert_type(self, cmd, opt, opt_type):
195 '''Ensure that the provided option is of the requested type'''
196 parser = self.getParser(cmd)
197 for op in parser.op.option_list:
198 if op.get_opt_string() == opt:
199 self.assertEqual(op.type, opt_type)
202 def loadModules(moduleDir, cls_pattern="_TestCase", skip_list=["__init__", "baseclass"]):
203 '''taken from firstboot/loader.py'''
205 # Guaruntee that __init__ is skipped
206 if skip_list.count("__init__") == 0:
207 skip_list.append("__init__")
209 tstList = list()
211 # Make sure moduleDir is in the system path so imputil works.
212 if not moduleDir in sys.path:
213 sys.path.insert(0, moduleDir)
215 # Get a list of all *.py files in moduleDir
216 moduleList = []
217 lst = map(lambda x: os.path.splitext(os.path.basename(x))[0],
218 glob.glob(moduleDir + "/*.py"))
220 # Inspect each .py file found
221 for module in lst:
222 if module in skip_list:
223 continue
225 # Attempt to load the found module.
226 try:
227 found = imputil.imp.find_module(module)
228 loaded = imputil.imp.load_module(module, found[0], found[1], found[2])
229 except ImportError, e:
230 print(_("Error loading module %s: %s") % (module, e))
231 continue
233 # Find class names that match the supplied pattern (default: "_TestCase")
234 beforeCount = len(tstList)
235 for obj in loaded.__dict__.keys():
236 if obj.endswith(cls_pattern):
237 tstList.append(loaded.__dict__[obj])
238 afterCount = len(tstList)
240 # Warn if no tests found
241 if beforeCount == afterCount:
242 print(_("Module %s does not contain any test cases; skipping.") % module)
243 continue
245 return tstList
247 # Run the tests
248 if __name__ == "__main__":
249 # Make sure PWD is in the path before the eggs, system paths, etc.
250 sys.path.insert(0, os.environ.get("PWD"))
252 # Create a test suite
253 PyKickstartTestSuite = unittest.TestSuite()
255 # Find tests to add
256 tstList = loadModules(os.path.join(os.environ.get("PWD"), "tests/"))
257 tstList.extend(loadModules(os.path.join(os.environ.get("PWD"), "tests/commands")))
258 tstList.extend(loadModules(os.path.join(os.environ.get("PWD"), "tests/parser")))
259 for tst in tstList:
260 PyKickstartTestSuite.addTest(tst())
262 # Run tests
263 unittest.main(defaultTest="PyKickstartTestSuite")