Package pysys :: Package launcher :: Module console
[hide private]
[frames] | no frames]

Source Code for Module pysys.launcher.console

  1  # PySys System Test Framework, Copyright (C) 2006-2016  M.B.Grieve 
  2   
  3  # This library is free software; you can redistribute it and/or 
  4  # modify it under the terms of the GNU Lesser General Public 
  5  # License as published by the Free Software Foundation; either 
  6  # version 2.1 of the License, or (at your option) any later version. 
  7   
  8  # This library is distributed in the hope that it will be useful, 
  9  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 10  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
 11  # Lesser General Public License for more details. 
 12   
 13  # You should have received a copy of the GNU Lesser General Public 
 14  # License along with this library; if not, write to the Free Software 
 15  # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 
 16   
 17  # Contact: moraygrieve@users.sourceforge.net 
 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   
36 -class ConsoleCleanTestHelper:
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
47 - def printUsage(self, printXOptions):
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.upper() == "DEBUG": 74 stdoutHandler.setLevel(logging.DEBUG) 75 elif value.upper() == "INFO": 76 stdoutHandler.setLevel(logging.INFO) 77 elif value.upper() == "WARN": 78 stdoutHandler.setLevel(logging.WARN) 79 elif value.upper() == "CRIT": 80 stdoutHandler.setLevel(logging.CRITICAL) 81 82 elif option in ("-o", "--outdir"): 83 self.outsubdir = value
84 85
86 - def clean(self):
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
119 - def purgeDirectory(self, dir, delTop=False):
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
137 -class ConsolePrintHelper:
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
156 - def printUsage(self):
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
187 - def parseArgs(self, args):
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
229 - def printTests(self):
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
289 -class ConsoleMakeTestHelper:
290 - def __init__(self, name=""):
291 self.name = name 292 self.testId = None 293 self.type = "auto" 294 self.testdir = os.getcwd()
295 296
297 - def printUsage(self):
298 print "\nPySys System Test Framework (version %s): Console make test helper" % __version__ 299 print "\nUsage: %s %s [option]+ [testid]" % (os.path.basename(sys.argv[0]), self.name) 300 print " where [option] includes;" 301 print " -h | --help print this message" 302 print " -a | --type STRING set the test type (auto or manual, default is auto)" 303 print " -d | --dir STRING base path to testcase (default is current working dir)" 304 print "" 305 print " and where [testid] is the mandatory test identifier." 306 sys.exit()
307 308
309 - def parseArgs(self, args):
310 try: 311 optlist, arguments = getopt.getopt(args, 'ht:d:', ["help","type=","dir="] ) 312 except: 313 print "Error parsing command line arguments: %s" % (sys.exc_info()[1]) 314 self.printUsage() 315 316 for option, value in optlist: 317 if option in ("-h", "--help"): 318 self.printUsage() 319 320 elif option in ("-a", "--type"): 321 self.type = value 322 if self.type not in ["auto", "manual"]: 323 log.warn("Unsupported test type - valid types are auto and manual") 324 sys.exit(1) 325 326 elif option in ("-d", "--dir"): 327 self.testdir = value 328 329 if arguments == []: 330 print "A valid string test id must be supplied" 331 self.printUsage() 332 else: 333 self.testId = arguments[0] 334 335 return self.testId
336 337
338 - def makeTest(self, input=None, output=None, reference=None, descriptor=None, testclass=None, module=None, 339 group="", constantsImport=None, basetestImport=None, basetest=None, teststring=None):
340 if input==None: input = DEFAULT_INPUT 341 if output==None: output = DEFAULT_OUTPUT 342 if reference==None: reference = DEFAULT_REFERENCE 343 if descriptor==None: descriptor = DEFAULT_DESCRIPTOR[0] 344 if testclass==None: testclass = DEFAULT_TESTCLASS 345 if module==None: module = DEFAULT_MODULE 346 if constantsImport ==None: constantsImport = "from pysys.constants import *" 347 if basetestImport == None: basetestImport = "from pysys.basetest import BaseTest" 348 if basetest == None: basetest = "BaseTest" 349 350 log.info("Creating testcase %s ..." % self.testId) 351 try: 352 os.makedirs(os.path.join(self.testdir, self.testId)) 353 log.info("Created directory %s" % os.path.join(self.testdir, self.testId)) 354 except OSError: 355 log.info("Error creating testcase " + os.path.join(self.testdir, self.testId) + " - directory already exists") 356 return 357 else: 358 os.makedirs(os.path.join(self.testdir, self.testId, input)) 359 log.info("Created directory %s " % os.path.join(self.testdir, self.testId, input)) 360 os.makedirs(os.path.join(self.testdir, self.testId, output)) 361 log.info("Created directory %s " % os.path.join(self.testdir, self.testId, output)) 362 os.makedirs(os.path.join(self.testdir, self.testId, reference)) 363 log.info("Created directory %s " % os.path.join(self.testdir, self.testId, reference)) 364 descriptor_fp = open(os.path.join(self.testdir, self.testId, descriptor), "w") 365 descriptor_fp.write(DESCRIPTOR_TEMPLATE %(self.type, group, testclass, module)) 366 descriptor_fp.close() 367 log.info("Created descriptor %s " % os.path.join(self.testdir, self.testId, descriptor)) 368 testclass_fp = open(os.path.join(self.testdir, self.testId, "%s.py" % module), "w") 369 if teststring == None: 370 testclass_fp.write(TEST_TEMPLATE % (constantsImport, basetestImport, testclass, basetest)) 371 else: 372 testclass_fp.write(teststring) 373 testclass_fp.close() 374 log.info("Created test class module %s " % os.path.join(self.testdir, self.testId, "%s.py" % module))
375 376 377
378 -class ConsoleLaunchHelper:
379 - def __init__(self, workingDir, name=""):
380 self.workingDir = workingDir 381 self.arguments = [] 382 self.record = False 383 self.purge = False 384 self.type = None 385 self.trace = None 386 self.includes = [] 387 self.excludes = [] 388 self.cycle = 1 389 self.outsubdir = PLATFORM 390 self.mode = None 391 self.threads = 1 392 self.name=name 393 self.userOptions = {} 394 self.descriptors = [] 395 self.optionString = 'hrpyv:a:t:i:e:c:o:m:n:b:X:' 396 self.optionList = ["help","record","purge","verbosity=","type=","trace=","include=","exclude=","cycle=","outdir=","mode=","threads=", "abort=", 'validateOnly']
397 398
399 - def printUsage(self, printXOptions):
400 print "\nPySys System Test Framework (version %s): Console run test helper" % __version__ 401 print "\nUsage: %s %s [option]* [tests]*" % (os.path.basename(sys.argv[0]), self.name) 402 print " where [option] includes;" 403 print " -h | --help print this message" 404 print " -r | --record record the test results in the working directory" 405 print " -p | --purge purge the output subdirectory on test pass" 406 print " -v | --verbosity STRING set the verbosity level (CRIT, WARN, INFO, DEBUG)" 407 print " -a | --type STRING set the test type to run (auto or manual, default is both)" 408 print " -t | --trace STRING set the requirement id for the test run" 409 print " -i | --include STRING set the test groups to include (can be specified multiple times)" 410 print " -e | --exclude STRING set the test groups to exclude (can be specified multiple times)" 411 print " -c | --cycle INT set the the number of cycles to run the tests" 412 print " -o | --outdir STRING set the name of the test output subdirectory" 413 print " -m | --mode STRING set the user defined mode to run the tests" 414 print " -n | --threads INT set the number of worker threads to run the tests (defaults to 1). " 415 print " A value of 0 sets to the number of available CPUs" 416 print " -b | --abort STRING set the default abort on error property (true|false, overrides " 417 print " that specified in the project properties)" 418 print " -y | --validateOnly test the validate() method without re-running execute()" 419 print " -X KEY=VALUE set user defined options to be passed through to the test and " 420 print " runner classes. The left hand side string is the data attribute " 421 print " to set, the right hand side string the value (True of not specified) " 422 if printXOptions: printXOptions() 423 print "" 424 print " and where [tests] describes a set of tests to be run. Note that multiple test sets can be specified, " 425 print " where none are given all available tests will be run. If an include group is given, only tests that " 426 print " belong to that group will be run. If an exclude group is given, tests in the group will not be run. " 427 print " Tests should contain only alphanumeric and the underscore characters. The following syntax is used " 428 print " to select a test set;" 429 print "" 430 print " test1 - a single testcase with id test1" 431 print " :test2 - up to testcase with id test2" 432 print " test1: - from testcase with id test1 onwards" 433 print " test1:test2 - all tests between tests with ids test1 and test2" 434 print " test1 test 2 test5:test9 - test1, test2 and all tests between test5 and test9" 435 print " ^test* - all tests matching the regex ^test*" 436 print "" 437 print " e.g. " 438 print " %s -vDEBUG --include MYTESTS test1:test4 test7" % os.path.basename(sys.argv[0]) 439 print " %s -c2 -Xhost=localhost test1:" % os.path.basename(sys.argv[0]) 440 print "" 441 sys.exit()
442 443
444 - def parseArgs(self, args, printXOptions=None):
445 try: 446 optlist, self.arguments = getopt.getopt(args, self.optionString, self.optionList) 447 except: 448 log.warn("Error parsing command line arguments: %s" % (sys.exc_info()[1])) 449 sys.exit(1) 450 451 for option, value in optlist: 452 if option in ("-h", "--help"): 453 self.printUsage(printXOptions) 454 455 elif option in ("-r", "--record"): 456 self.record = True 457 458 elif option in ("-p", "--purge"): 459 self.purge = True 460 461 elif option in ("-v", "--verbosity"): 462 self.verbosity = value 463 if self.verbosity.upper() == "DEBUG": 464 stdoutHandler.setLevel(logging.DEBUG) 465 elif self.verbosity.upper() == "INFO": 466 stdoutHandler.setLevel(logging.INFO) 467 elif self.verbosity.upper() == "WARN": 468 stdoutHandler.setLevel(logging.WARN) 469 elif self.verbosity.upper() == "CRIT": 470 stdoutHandler.setLevel(logging.CRITICAL) 471 472 elif option in ("-a", "--type"): 473 self.type = value 474 if self.type not in ["auto", "manual"]: 475 log.warn("Unsupported test type - valid types are auto and manual") 476 sys.exit(1) 477 478 elif option in ("-t", "--trace"): 479 self.trace = value 480 481 elif option in ("-i", "--include"): 482 self.includes.append(value) 483 484 elif option in ("-e", "--exclude"): 485 self.excludes.append(value) 486 487 elif option in ("-c", "--cycle"): 488 try: 489 self.cycle = int(value) 490 except: 491 print "Error parsing command line arguments: A valid integer for the number of cycles must be supplied" 492 self.printUsage(printXOptions) 493 494 elif option in ("-o", "--outdir"): 495 self.outsubdir = value 496 497 elif option in ("-m", "--mode"): 498 self.mode = value 499 500 elif option in ("-n", "--threads"): 501 try: 502 self.threads = int(value) 503 except: 504 print "Error parsing command line arguments: A valid integer for the number of threads must be supplied" 505 self.printUsage(printXOptions) 506 507 elif option in ("-b", "--abort"): 508 setattr(PROJECT, 'defaultAbortOnError', str(value.lower()=='true')) 509 510 elif option in ["-X"]: 511 if EXPR1.search(value) is not None: 512 self.userOptions[value.split('=')[0]] = value.split('=')[1] 513 if EXPR2.search(value) is not None: 514 self.userOptions[value] = True 515 516 elif option in ("-y", "--validateOnly"): 517 self.userOptions['validateOnly'] = True 518 try: 519 descriptors = createDescriptors(self.arguments, self.type, self.includes, self.excludes, self.trace, self.workingDir) 520 except Exception, (strerror): 521 log.info(strerror) 522 descriptors = [] 523 return self.record, self.purge, self.cycle, self.mode, self.threads, self.outsubdir, descriptors, self.userOptions
524