1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import sys, os, os.path, stat, glob, getopt, re, string, logging
20
21 from pysys import log
22 from pysys import stdoutHandler
23
24 from pysys import __version__
25 from pysys.constants import *
26 from pysys.exceptions import *
27 from pysys.launcher import createDescriptors
28 from pysys.xml.descriptor import DESCRIPTOR_TEMPLATE
29 from pysys.basetest import TEST_TEMPLATE
30
31 EXPR1 = re.compile("^[\w\.]*=.*$")
32 EXPR2 = re.compile("^[\w\.]*$")
33 EXPR3 = re.compile("^[\w]*_([0-9]+)$")
34
35
37 - def __init__(self, workingDir, name=""):
38 self.workingDir = workingDir
39 self.arguments = []
40 self.outsubdir = PLATFORM
41 self.all = False
42 self.name = name
43 self.optionString = 'hav:o:'
44 self.optionList = ["help","all", "verbosity=","outdir="]
45
46
48 print "\nPySys System Test Framework (version %s): Console clean test helper" % __version__
49 print "\nUsage: %s %s [option]* [tests]*" % (os.path.basename(sys.argv[0]), self.name)
50 print " where [option] includes;"
51 print " -h | --help print this message"
52 print " -a | --all clean all compiled testclass files"
53 print " -v | --verbosity STRING set the verbosity level (CRIT, WARN, INFO, DEBUG)"
54 print " -o | --outdir STRING set the name of the test output subdirectories to clean"
55 sys.exit()
56
57
58 - def parseArgs(self, args, printXOptions=None):
59 try:
60 optlist, self.arguments = getopt.getopt(args, self.optionString, self.optionList)
61 except:
62 log.warn("Error parsing command line arguments: %s" % (sys.exc_info()[1]))
63 sys.exit(1)
64
65 for option, value in optlist:
66 if option in ("-h", "--help"):
67 self.printUsage(printXOptions)
68
69 elif option in ("-a", "--all"):
70 self.all = True
71
72 elif option in ("-v", "--verbosity"):
73 if value == "DEBUG":
74 stdoutHandler.setLevel(logging.DEBUG)
75 elif value == "INFO":
76 stdoutHandler.setLevel(logging.INFO)
77 elif value == "WARN":
78 stdoutHandler.setLevel(logging.WARN)
79 elif value == "CRIT":
80 stdoutHandler.setLevel(logging.CRITICAL)
81
82 elif option in ("-o", "--outdir"):
83 self.outsubdir = value
84
85
87 try:
88 descriptors = createDescriptors(self.arguments, None, [], [], None, self.workingDir)
89 except Exception, (strerror):
90 log.info(strerror)
91 else:
92 for descriptor in descriptors:
93 if self.all:
94 if sys.version_info >= (3,):
95 cache=os.path.join(os.path.dirname(descriptor.module),"__pycache__")
96 if os.path.exists(cache):
97 log.info("Deleting pycache: " + cache)
98 self.purgeDirectory(cache, True)
99 else:
100 path = descriptor.module + ".pyc"
101 try:
102 mode = os.stat(path)[stat.ST_MODE]
103 if stat.S_ISLNK(mode):
104 os.unlink(path)
105 if stat.S_ISREG(mode):
106 os.remove(path)
107 log.info("Deleting compiled module: " + path)
108 except:
109 log.debug("Error deleting compiled module: " + path)
110
111 pathToDelete = os.path.join(descriptor.output, self.outsubdir)
112 if os.path.exists(pathToDelete):
113 log.info("Deleting output directory: " + pathToDelete)
114 self.purgeDirectory(pathToDelete, True)
115 else:
116 log.debug("Output directory does not exist: " + pathToDelete)
117
118
120 for file in os.listdir(dir):
121 path = os.path.join(dir, file)
122 if PLATFORM in ['sunos', 'linux']:
123 mode = os.lstat(path)[stat.ST_MODE]
124 else:
125 mode = os.stat(path)[stat.ST_MODE]
126
127 if stat.S_ISLNK(mode):
128 os.unlink(path)
129 if stat.S_ISREG(mode):
130 os.remove(path)
131 elif stat.S_ISDIR(mode):
132 self.purgeDirectory(path, delTop=True)
133
134 if delTop: os.rmdir(dir)
135
136
138 - def __init__(self, workingDir, name=""):
139 self.workingDir = workingDir
140 self.arguments = []
141 self.full = False
142 self.groups = False
143 self.modes = False
144 self.requirements = False
145 self.mode = None
146 self.type = None
147 self.trace = None
148 self.includes = []
149 self.excludes = []
150 self.tests = None
151 self.name = name
152 self.optionString = 'hfgdrm:a:t:i:e:'
153 self.optionList = ["help","full","groups","modes","requirements","mode=","type=","trace=","include=","exclude="]
154
155
157 print "\nPySys System Test Framework (version %s): Console print test helper" % __version__
158 print "\nUsage: %s %s [option]* [tests]*" % (os.path.basename(sys.argv[0]), self.name)
159 print " where options include;"
160 print " -h | --help print this message"
161 print " -f | --full print full information"
162 print " -g | --groups print test groups defined"
163 print " -d | --modes print test modes defined"
164 print " -r | --requirements print test requirements covered"
165 print " -m | --mode STRING print tests that run in user defined mode "
166 print " -a | --type STRING print tests of supplied type (auto or manual, default all)"
167 print " -t | --trace STRING print tests which cover requirement id "
168 print " -i | --include STRING print tests in included group (can be specified multiple times)"
169 print " -e | --exclude STRING do not print tests in excluded group (can be specified multiple times)"
170 print ""
171 print " and where [tests] describes a set of tests to be printed to the console. Note that multiple test "
172 print " sets can be specified, and where none are given all available tests will be run. If an include "
173 print " group is given, only tests that belong to that group will be printed. If an exclude group is given, "
174 print " tests in the group will not be run. The following syntax is used to select a test set;"
175 print ""
176 print " test1 - a single testcase with id test1"
177 print " :test2 - upto testcase with id test2"
178 print " test1: - from testcase with id test1 onwards"
179 print " id1:id2 - all tests between tests with ids test1 and test2"
180 print ""
181 print " e.g. "
182 print " %s -i group1 -e group2 --full test1:test3" % os.path.basename(sys.argv[0])
183 print ""
184 sys.exit()
185
186
188 try:
189 optlist, self.arguments = getopt.getopt(args, self.optionString, self.optionList)
190 except:
191 log.warn("Error parsing command line arguments: %s" % (sys.exc_info()[1]))
192 sys.exit(1)
193
194 for option, value in optlist:
195 if option in ("-h", "--help"):
196 self.printUsage()
197
198 elif option in ("-f", "--full"):
199 self.full = True
200
201 if option in ("-g", "--groups"):
202 self.groups = True
203
204 if option in ("-d", "--modes"):
205 self.modes = True
206
207 if option in ("-r", "--requirements"):
208 self.requirements = True
209
210 elif option in ("-m", "--mode"):
211 self.mode = value
212
213 elif option in ("-a", "--type"):
214 self.type = value
215 if self.type not in ["auto", "manual"]:
216 log.warn("Unsupported test type - valid types are auto and manual")
217 sys.exit(1)
218
219 elif option in ("-t", "--trace"):
220 self.trace = value
221
222 elif option in ("-i", "--include"):
223 self.includes.append(value)
224
225 elif option in ("-e", "--exclude"):
226 self.excludes.append(value)
227
228
230 try:
231 descriptors = createDescriptors(self.arguments, self.type, self.includes, self.excludes, self.trace, self.workingDir)
232 except Exception, (strerror):
233 log.info(strerror)
234 else:
235 exit = 0
236 if self.groups == True:
237 groups = []
238 for descriptor in descriptors:
239 for group in descriptor.groups:
240 if group not in groups:
241 groups.append(group)
242 print "\nGroups defined: "
243 for group in groups:
244 print " %s" % (group)
245 exit = 1
246
247 if self.modes == True:
248 modes = []
249 for descriptor in descriptors:
250 for mode in descriptor.modes:
251 if mode not in modes:
252 modes.append(mode)
253 print "\nModes defined: "
254 for mode in modes:
255 print " %s" % (mode)
256 exit = 1
257
258 if self.requirements == True:
259 requirements = []
260 for descriptor in descriptors:
261 for requirement in descriptor.traceability:
262 if requirement not in requirements:
263 requirements.append(requirement)
264 print "\nRequirements covered: "
265 for requirement in requirements:
266 print " %s" % (requirement)
267 exit = 1
268
269 if exit: return
270
271 maxsize = 0
272 for descriptor in descriptors:
273 if len(descriptor.id) > maxsize: maxsize = len(descriptor.id)
274 maxsize = maxsize + 2
275
276 for descriptor in descriptors:
277 if self.mode and not self.mode in descriptor.modes: continue
278 padding = " " * (maxsize - len(descriptor.id))
279 if not self.full:
280 print "%s:%s%s" % (descriptor.id, padding, descriptor.title)
281 else:
282 print "=========================================="
283 print " " + descriptor.id
284 print "=========================================="
285 print descriptor
286
287
288
290 - def __init__(self, workingDir, name=""):
291 self.workingDir = workingDir
292 self.testId = None
293 self.type = "auto"
294 self.name = name
295
297 print "\nPySys System Test Framework (version %s): Console make test helper" % __version__
298 print "\nUsage: %s %s [option]+ [testid]" % (os.path.basename(sys.argv[0]), self.name)
299 print " where [option] includes;"
300 print " -h | --help print this message"
301 print " -t | --type STRING set the test type (auto or manual, default is auto)"
302 print ""
303 print " and where [testid] is the mandatory test identifier."
304 sys.exit()
305
306
308 try:
309 optlist, arguments = getopt.getopt(args, 'ht:', ["help","type="] )
310 except:
311 print "Error parsing command line arguments: %s" % (sys.exc_info()[1])
312 self.printUsage()
313
314 for option, value in optlist:
315 if option in ("-h", "--help"):
316 self.printUsage()
317
318 elif option in ("-a", "--type"):
319 self.type = value
320 if self.type not in ["auto", "manual"]:
321 log.warn("Unsupported test type - valid types are auto and manual")
322 sys.exit(1)
323
324 if arguments == []:
325 print "A valid string test id must be supplied"
326 self.printUsage()
327 else:
328 self.testId = arguments[0]
329
330 return self.testId
331
332
333 - def makeTest(self, input=None, output=None, reference=None, descriptor=None, testclass=None, module=None,
334 group="", constantsImport=None, basetestImport=None, basetest=None, teststring=None):
335 if input==None: input = DEFAULT_INPUT
336 if output==None: output = DEFAULT_OUTPUT
337 if reference==None: reference = DEFAULT_REFERENCE
338 if descriptor==None: descriptor = DEFAULT_DESCRIPTOR[0]
339 if testclass==None: testclass = DEFAULT_TESTCLASS
340 if module==None: module = DEFAULT_MODULE
341 if constantsImport ==None: constantsImport = "from pysys.constants import *"
342 if basetestImport == None: basetestImport = "from pysys.basetest import BaseTest"
343 if basetest == None: basetest = "BaseTest"
344
345 log.info("Creating testcase %s ..." % self.testId)
346 try:
347 os.makedirs(self.testId)
348 log.info("Created directory %s" % self.testId)
349 except OSError:
350 log.info("Error creating testcase " + self.testId + " - directory already exists")
351 return
352 else:
353 os.makedirs(os.path.join(self.testId, input))
354 log.info("Created directory %s " % os.path.join(self.testId, input))
355 os.makedirs(os.path.join(self.testId, output))
356 log.info("Created directory %s " % os.path.join(self.testId, output))
357 os.makedirs(os.path.join(self.testId, reference))
358 log.info("Created directory %s " % os.path.join(self.testId, reference))
359 descriptor_fp = open(os.path.join(self.testId, descriptor), "w")
360 descriptor_fp.write(DESCRIPTOR_TEMPLATE %(self.type, group, testclass, module))
361 descriptor_fp.close()
362 log.info("Created descriptor %s " % os.path.join(self.testId, descriptor))
363 testclass_fp = open(os.path.join(self.testId, "%s.py" % module), "w")
364 if teststring == None:
365 testclass_fp.write(TEST_TEMPLATE % (constantsImport, basetestImport, testclass, basetest))
366 else:
367 testclass_fp.write(teststring)
368 testclass_fp.close()
369 log.info("Created test class module %s " % os.path.join(self.testId, "%s.py" % module))
370
371
372
374 - def __init__(self, workingDir, name=""):
375 self.workingDir = workingDir
376 self.arguments = []
377 self.record = False
378 self.purge = False
379 self.type = None
380 self.trace = None
381 self.includes = []
382 self.excludes = []
383 self.cycle = 1
384 self.outsubdir = PLATFORM
385 self.mode = None
386 self.threads = 1
387 self.name=name
388 self.userOptions = {}
389 self.descriptors = []
390 self.optionString = 'hrpv:a:t:i:e:c:o:m:n:X:'
391 self.optionList = ["help","record","purge","verbosity=","type=","trace=","include=","exclude=","cycle=","outdir=","mode=","threads="]
392
393
395 print "\nPySys System Test Framework (version %s): Console run test helper" % __version__
396 print "\nUsage: %s %s [option]* [tests]*" % (os.path.basename(sys.argv[0]), self.name)
397 print " where [option] includes;"
398 print " -h | --help print this message"
399 print " -r | --record record the test results in the working directory"
400 print " -p | --purge purge the output subdirectory on test pass"
401 print " -v | --verbosity STRING set the verbosity level (CRIT, WARN, INFO, DEBUG)"
402 print " -a | --type STRING set the test type to run (auto or manual, default is both)"
403 print " -t | --trace STRING set the requirement id for the test run"
404 print " -i | --include STRING set the test groups to include (can be specified multiple times)"
405 print " -e | --exclude STRING set the test groups to exclude (can be specified multiple times)"
406 print " -c | --cycle INT set the the number of cycles to run the tests"
407 print " -o | --outdir STRING set the name of the test output subdirectory"
408 print " -m | --mode STRING set the user defined mode to run the tests"
409 print " -n | --threads INT set the number of worker threads to run the tests (defaults to 1). "
410 print " A value of 0 sets to the number of available CPUs"
411 print " -X KEY=VALUE set user defined options to be passed through to the test and "
412 print " runner classes. The left hand side string is the data attribute "
413 print " to set, the right hand side string the value (True of not specified) "
414 if printXOptions: printXOptions()
415 print ""
416 print " and where [tests] describes a set of tests to be run. Note that multiple test sets can be specified, "
417 print " where none are given all available tests will be run. If an include group is given, only tests that "
418 print " belong to that group will be run. If an exclude group is given, tests in the group will not be run. "
419 print " The following syntax is used to select a test set;"
420 print ""
421 print " test1 - a single testcase with id test1"
422 print " :test2 - upto testcase with id test2"
423 print " test1: - from testcase with id test1 onwards"
424 print " id1:id2 - all tests between tests with ids test1 and test2"
425 print ""
426 print " e.g. "
427 print " %s -vDEBUG --include MYTESTS test1:test4 test7" % os.path.basename(sys.argv[0])
428 print " %s -c2 -Xhost=localhost test1:" % os.path.basename(sys.argv[0])
429 print ""
430 sys.exit()
431
432
433 - def parseArgs(self, args, printXOptions=None):
434 try:
435 optlist, self.arguments = getopt.getopt(args, self.optionString, self.optionList)
436 except:
437 log.warn("Error parsing command line arguments: %s" % (sys.exc_info()[1]))
438 sys.exit(1)
439
440 for option, value in optlist:
441 if option in ("-h", "--help"):
442 self.printUsage(printXOptions)
443
444 elif option in ("-r", "--record"):
445 self.record = True
446
447 elif option in ("-p", "--purge"):
448 self.purge = True
449
450 elif option in ("-v", "--verbosity"):
451 self.verbosity = value
452 if self.verbosity == "DEBUG":
453 stdoutHandler.setLevel(logging.DEBUG)
454 elif self.verbosity == "INFO":
455 stdoutHandler.setLevel(logging.INFO)
456 elif self.verbosity == "WARN":
457 stdoutHandler.setLevel(logging.WARN)
458 elif self.verbosity == "CRIT":
459 stdoutHandler.setLevel(logging.CRITICAL)
460
461 elif option in ("-a", "--type"):
462 self.type = value
463 if self.type not in ["auto", "manual"]:
464 log.warn("Unsupported test type - valid types are auto and manual")
465 sys.exit(1)
466
467 elif option in ("-t", "--trace"):
468 self.trace = value
469
470 elif option in ("-i", "--include"):
471 self.includes.append(value)
472
473 elif option in ("-e", "--exclude"):
474 self.excludes.append(value)
475
476 elif option in ("-c", "--cycle"):
477 try:
478 self.cycle = int(value)
479 except:
480 print "Error parsing command line arguments: A valid integer for the number of cycles must be supplied"
481 self.printUsage(printXOptions)
482
483 elif option in ("-o", "--outdir"):
484 self.outsubdir = value
485
486 elif option in ("-m", "--mode"):
487 self.mode = value
488
489 elif option in ("-n", "--threads"):
490 try:
491 self.threads = int(value)
492 except:
493 print "Error parsing command line arguments: A valid integer for the number of threads must be supplied"
494 self.printUsage(printXOptions)
495
496 elif option in ("-X"):
497 if EXPR1.search(value) is not None:
498 self.userOptions[value.split('=')[0]] = value.split('=')[1]
499 if EXPR2.search(value) is not None:
500 self.userOptions[value] = True
501
502 try:
503 descriptors = createDescriptors(self.arguments, self.type, self.includes, self.excludes, self.trace, self.workingDir)
504 except Exception, (strerror):
505 log.info(strerror)
506 descriptors = []
507 return self.record, self.purge, self.cycle, self.mode, self.threads, self.outsubdir, descriptors, self.userOptions
508