Package TestON :: Package core :: Module teston
[hide private]
[frames] | no frames]

Source Code for Module TestON.core.teston

  1  #!/usr/bin/env python 
  2  ''' 
  3  Created on 22-Oct-2012 
  4       
  5  @author: Anil Kumar (anilkumar.s@paxterrasolutions.com) 
  6   
  7  teston is the main module. 
  8   
  9  ''' 
 10   
 11  import sys 
 12  import getpass 
 13  import os 
 14  import re 
 15  import __builtin__ 
 16  import new 
 17  import xmldict 
 18  module = new.module("test") 
 19  import openspeak 
 20  global path, drivers_path, core_path, tests_path,logs_path 
 21  path = re.sub("(core|bin)$", "", os.getcwd()) 
 22  drivers_path = path+"drivers/" 
 23  core_path = path+"core" 
 24  tests_path = path+"tests" 
 25  logs_path = path+"logs/" 
 26  config_path = path + "config/" 
 27  sys.path.append(path) 
 28  sys.path.append( drivers_path) 
 29  sys.path.append(core_path ) 
 30  sys.path.append(tests_path) 
 31   
 32  from core.utilities import Utilities 
 33   
 34  import logging  
 35  import datetime 
 36  from optparse import OptionParser 
 37   
38 -class TestON:
39 ''' 40 41 TestON will initiate the specified test. 42 The main tasks are : 43 * Initiate the required Component handles for the test. 44 * Create Log file Handles. 45 46 '''
47 - def __init__(self,options):
48 ''' 49 Initialise the component handles specified in the topology file of the specified test. 50 51 ''' 52 # Initialization of the variables. 53 __builtin__.main = self 54 55 __builtin__.path = path 56 __builtin__.utilities = Utilities() 57 self.TRUE = 1 58 self.FALSE = 0 59 self.ERROR = -1 60 self.FAIL = False 61 self.PASS = True 62 self.CASERESULT = self.TRUE 63 self.init_result = self.TRUE 64 self.testResult = "Summary" 65 self.stepName ="" 66 self.EXPERIMENTAL_MODE = False 67 self.test_target = None 68 self.lastcommand = None 69 self.testDir = tests_path 70 self.configFile = config_path + "ofa.cfg" 71 self.parsingClass = "xmlparser" 72 self.parserPath = core_path + "/xmlparser" 73 self.loggerPath = core_path + "/logger" 74 self.loggerClass = "Logger" 75 self.logs_path = logs_path 76 self.driver = '' 77 78 self.configparser() 79 verifyOptions(options) 80 load_logger() 81 self.componentDictionary = {} 82 self.componentDictionary = self.topology ['COMPONENT'] 83 self.driversList=[] 84 if type(self.componentDictionary) == str : 85 self.componentDictionary = dict(self.componentDictionary) 86 87 for component in self.componentDictionary : 88 self.driversList.append(self.componentDictionary[component]['type']) 89 90 self.driversList = list(set(self.driversList)) # Removing duplicates. 91 # Checking the test_target option set for the component or not 92 if type(self.componentDictionary) == dict: 93 for component in self.componentDictionary.keys(): 94 if 'test_target' in self.componentDictionary[component].keys(): 95 self.test_target = component 96 97 # Checking for the openspeak file and test script 98 self.logger.initlog(self) 99 100 # Creating Drivers Handles 101 initString = "\n"+"*" * 30+"\n CASE INIT \n"+"*" * 30+"\n" 102 self.log.exact(initString) 103 self.driverObject = {} 104 if type(self.componentDictionary) == dict: 105 for component in self.componentDictionary.keys(): 106 self.componentInit(component)
107
108 - def configparser(self):
109 ''' 110 It will parse the config file (ofa.cfg) and return as dictionary 111 ''' 112 matchFileName = re.match(r'(.*)\.cfg', self.configFile, re.M | re.I) 113 if matchFileName: 114 xml = open(self.configFile).read() 115 try : 116 self.configDict = xmldict.xml_to_dict(xml) 117 return self.configDict 118 except : 119 print "There is no such file to parse " + self.configFile
120
121 - def componentInit(self,component):
122 ''' 123 This method will initialize specified component 124 ''' 125 global driver_options 126 self.log.info("Creating component Handle: "+component) 127 driver_options = {} 128 if 'COMPONENTS' in self.componentDictionary[component].keys(): 129 driver_options =dict(self.componentDictionary[component]['COMPONENTS']) 130 131 driver_options['name']=component 132 driverName = self.componentDictionary[component]['type'] 133 driver_options ['type'] = driverName 134 135 classPath = self.getDriverPath(driverName.lower()) 136 driverModule = __import__(classPath, globals(), locals(), [driverName.lower()], -1) 137 driverClass = getattr(driverModule, driverName) 138 driverObject = driverClass() 139 connect_result = driverObject.connect(user_name = self.componentDictionary[component]['user'] if ('user' in self.componentDictionary[component].keys()) else getpass.getuser(), 140 ip_address= self.componentDictionary[component]['host'] if ('host' in self.componentDictionary[component].keys()) else 'localhost', 141 pwd = self.componentDictionary[component]['password'] if ('password' in self.componentDictionary[component].keys()) else 'changeme', 142 port = self.componentDictionary[component]['port'] if ('port' in self.componentDictionary[component].keys()) else None, 143 options = driver_options) 144 if not connect_result: 145 self.log.error("Exiting form the test execution because the connecting to the "+component+" component failed.") 146 self.exit() 147 148 vars(self)[component] = driverObject
149
150 - def run(self):
151 ''' 152 The Execution of the test script's cases listed in the Test params file will be done here. 153 And Update each test case result. 154 This method will return TRUE if it executed all the test cases successfully, 155 else will retun FALSE 156 ''' 157 158 self.testCaseResult = {} 159 self.TOTAL_TC_RUN = 0 160 self.TOTAL_TC_NORESULT = 0 161 self.TOTAL_TC_FAIL = 0 162 self.TOTAL_TC_PASS = 0 163 self.stepCount = 0 164 self.CASERESULT = self.TRUE 165 166 import testparser 167 testFile = self.tests_path + "/"+self.TEST + "/"+self.TEST + ".py" 168 test = testparser.TestParser(testFile) 169 self.testscript = test.testscript 170 self.code = test.getStepCode() 171 172 result = self.TRUE 173 for self.CurrentTestCaseNumber in self.testcases_list: 174 result = self.runCase(self.CurrentTestCaseNumber) 175 return result
176
177 - def runCase(self,testCaseNumber):
178 self.CurrentTestCaseNumber = testCaseNumber 179 result = self.TRUE 180 self.stepCount = 0 181 self.EXPERIMENTAL_MODE = self.FALSE 182 self.addCaseHeader() 183 self.testCaseNumber = str(testCaseNumber) 184 stopped = False 185 try : 186 self.stepList = self.code[self.testCaseNumber].keys() 187 except KeyError,e: 188 main.log.error("There is no Test-Case "+ self.testCaseNumber) 189 return main.FALSE 190 191 self.stepCount = 0 192 while self.stepCount < len(self.code[self.testCaseNumber].keys()): 193 result = self.runStep(self.stepList,self.code,self.testCaseNumber) 194 if result == main.FALSE: 195 break 196 elif result == main.TRUE : 197 continue 198 199 if not stopped : 200 self.testCaseResult[str(self.CurrentTestCaseNumber)] = self.CASERESULT 201 self.logger.updateCaseResults(self) 202 return result
203
204 - def runStep(self,stepList,code,testCaseNumber):
205 if not cli.pause: 206 try : 207 step = stepList[self.stepCount] 208 exec code[testCaseNumber][step] in module.__dict__ 209 self.stepCount = self.stepCount + 1 210 except TypeError,e: 211 self.stepCount = self.stepCount + 1 212 self.log.error(e) 213 return main.TRUE 214 215 if cli.stop: 216 cli.stop = False 217 stopped = True 218 self.TOTAL_TC_NORESULT = self.TOTAL_TC_NORESULT + 1 219 self.testCaseResult[str(self.CurrentTestCaseNumber)] = "Stopped" 220 self.logger.updateCaseResults(self) 221 result = self.cleanup() 222 return main.FALSE
223
224 - def addCaseHeader(self):
225 caseHeader = "\n"+"*" * 30+"\n Result summary for Testcase"+str(self.CurrentTestCaseNumber)+"\n"+"*" * 30+"\n" 226 self.log.exact(caseHeader) 227 caseHeader = "\n"+"*" * 40 +"\nStart of Test Case"+str(self.CurrentTestCaseNumber)+" : " 228 for driver in self.componentDictionary.keys(): 229 vars(self)[driver+'log'].info(caseHeader)
230
231 - def addCaseFooter(self):
232 if self.stepCount-1 > 0 : 233 previousStep = " "+str(self.CurrentTestCaseNumber)+"."+str(self.stepCount-1)+": "+ str(self.stepName) + "" 234 stepHeader = "\n"+"*" * 40+"\nEnd of Step "+previousStep+"\n"+"*" * 40+"\n" 235 236 caseFooter = "\n"+"*" * 40+"\nEnd of Test case "+str(self.CurrentTestCaseNumber)+"\n"+"*" * 40+"\n" 237 238 for driver in self.driversList: 239 vars(self)[driver].write(stepHeader+"\n"+caseFooter)
240
241 - def cleanup(self):
242 ''' 243 Release all the component handles and the close opened file handles. 244 This will return TRUE if all the component handles and log handles closed properly, 245 else return FALSE 246 247 ''' 248 result = self.TRUE 249 self.logger.testSummary(self) 250 251 #self.reportFile.close() 252 # Closing all the driver's session files 253 for driver in self.componentDictionary.keys(): 254 vars(self)[driver].close_log_handles() 255 256 utilities.send_mail() 257 try : 258 for component in self.componentDictionary.keys(): 259 print "Disconnecting "+str(tempObject) 260 tempObject = vars(self)[component] 261 print "Disconnecting "+str(tempObject) 262 tempObject.disconnect() 263 #tempObject.execute(cmd="exit",prompt="(.*)",timeout=120) 264 265 except(Exception): 266 #print " There is an error with closing hanldes" 267 result = self.FALSE 268 269 return result
270
271 - def pause(self):
272 ''' 273 This function will pause the test's execution, and will continue after user provide 'resume' command. 274 ''' 275 __builtin__.testthread.pause()
276
277 - def onfail(self,*components):
278 ''' 279 When test step failed, calling all the components onfail. 280 ''' 281 282 if not components: 283 try : 284 for component in self.componentDictionary.keys(): 285 tempObject = vars(self)[component] 286 result = tempObject.onfail() 287 except(Exception),e: 288 print str(e) 289 result = self.FALSE 290 291 else: 292 try : 293 for component in components: 294 tempObject = vars(self)[component] 295 result = tempObject.onfail() 296 except(Exception),e: 297 print str(e) 298 result = self.FALSE
299 300
301 - def getDriverPath(self,driverName):
302 ''' 303 Based on the component 'type' specified in the params , this method will find the absolute path , 304 by recursively searching the name of the component. 305 ''' 306 import commands 307 308 cmd = "find "+drivers_path+" -name "+driverName+".py" 309 result = commands.getoutput(cmd) 310 311 result_array = str(result).split('\n') 312 result_count = 0 313 314 for drivers_list in result_array: 315 result_count = result_count+1 316 if result_count > 1 : 317 print "found "+driverName+" "+ str(result_count) + " times"+str(result_array) 318 self.exit() 319 320 result = re.sub("(.*)drivers","",result) 321 result = re.sub("\.py","",result) 322 result = re.sub("\.pyc","",result) 323 result = re.sub("\/",".",result) 324 result = "drivers"+result 325 return result
326 327
328 - def step(self,stepDesc):
329 ''' 330 The step information of the test-case will append to the logs. 331 ''' 332 previousStep = " "+str(self.CurrentTestCaseNumber)+"."+str(self.stepCount-1)+": "+ str(self.stepName) + "" 333 self.stepName = stepDesc 334 335 stepName = " "+str(self.CurrentTestCaseNumber)+"."+str(self.stepCount)+": "+ str(stepDesc) + "" 336 if self.stepCount == 0: 337 stepName = " INIT : Initializing the test case :"+self.CurrentTestCase 338 339 self.log.step(stepName) 340 stepHeader = "" 341 if self.stepCount > 1 : 342 stepHeader = "\n"+"-"*45+"\nEnd of Step "+previousStep+"\n"+"-"*45+"\n" 343 344 stepHeader += "\n"+"-"*45+"\nStart of Step"+stepName+"\n"+"-"*45+"\n" 345 for driver in self.componentDictionary.keys(): 346 vars(self)[driver+'log'].info(stepHeader)
347
348 - def case(self,testCaseName):
349 ''' 350 Test's each test-case information will append to the logs. 351 ''' 352 self.CurrentTestCase = testCaseName 353 testCaseName = " " + str(testCaseName) + "" 354 self.log.case(testCaseName) 355 caseHeader = testCaseName+"\n"+"*" * 40+"\n" 356 for driver in self.componentDictionary.keys(): 357 vars(self)[driver+'log'].info(caseHeader)
358
359 - def testDesc(self,description):
360 ''' 361 Test description will append to the logs. 362 ''' 363 description = "Test Description : " + str (description) + "" 364 self.log.info(description)
365
366 - def _getTest(self):
367 ''' 368 This method will parse the test script to find required test information. 369 ''' 370 testFile = self.tests_path + "/"+self.TEST + "/"+self.TEST + ".py" 371 testFileHandler = open(testFile, 'r') 372 testFileList = testFileHandler.readlines() 373 testFileHandler.close() 374 #self.TOTAL_TC_PLANNED = 0 375 counter = 0 376 for index in range(len(testFileList)): 377 lineMatch = re.match('\s+def CASE(\d+)(.*):',testFileList[index],0) 378 if lineMatch: 379 counter = counter + 1 380 self.TOTAL_TC_PLANNED = counter
381
382 - def exit(self):
383 __builtin__.testthread = None 384 sys.exit()
385
386 -def verifyOptions(options):
387 ''' 388 This will verify the command line options and set to default values, if any option not given in command line. 389 ''' 390 import pprint 391 pp = pprint.PrettyPrinter(indent=4) 392 393 #pp.pprint(options) 394 verifyTest(options) 395 verifyExample(options) 396 verifyTestScript(options) 397 verifyParams() 398 verifyLogdir(options) 399 verifyMail(options) 400 verifyTestCases(options)
401
402 -def verifyTest(options):
403 if options.testname: 404 main.TEST = options.testname 405 main.classPath = "tests."+main.TEST+"."+main.TEST 406 main.tests_path = tests_path 407 elif options.example : 408 main.TEST = options.example 409 main.tests_path = path+"/examples/" 410 main.classPath = "examples."+main.TEST+"."+main.TEST 411 else : 412 print "Test or Example not specified please specify the --test <test name > or --example <example name>" 413 self.exit()
414
415 -def verifyExample(options):
416 if options.example: 417 main.testDir = path+'/examples/' 418 main.tests_path = path+"/examples/" 419 main.classPath = "examples."+main.TEST+"."+main.TEST
420
421 -def verifyLogdir(options):
422 #Verifying Log directory option 423 if options.logdir: 424 main.logdir = options.logdir 425 else : 426 main.logdir = main.FALSE
427
428 -def verifyMail(options):
429 # Checking the mailing list 430 if options.mail: 431 main.mail = options.mail 432 elif main.params.has_key('mail'): 433 main.mail = main.params['mail'] 434 else : 435 main.mail = 'paxweb@paxterrasolutions.com'
436
437 -def verifyTestCases(options):
438 #Getting Test cases list 439 if options.testcases: 440 testcases_list = re.sub("(\[|\])", "", options.testcases) 441 main.testcases_list = eval(testcases_list+",") 442 else : 443 if 'testcases' in main.params.keys(): 444 main.params['testcases'] = re.sub("(\[|\])", "", main.params['testcases']) 445 if re.search('\d+', main.params['testcases'], 0): 446 main.testcases_list = eval(main.params['testcases']+",") 447 else : 448 print "Please provide the testcases list in Params file" 449 sys.exit() 450 else : 451 print "testcases not specifed in params, please provide in params file or 'testcases' commandline argument" 452 sys.exit()
453
454 -def verifyTestScript(options):
455 ''' 456 Verifyies test script. 457 ''' 458 main.openspeak = openspeak.OpenSpeak() 459 openspeakfile = main.testDir+"/" + main.TEST + "/" + main.TEST + ".ospk" 460 testfile = main.testDir+"/" + main.TEST + "/" + main.TEST + ".py" 461 if os.path.exists(openspeakfile) : 462 main.openspeak.compiler(openspeakfile=openspeakfile,writetofile=1) 463 elif os.path.exists(testfile): 464 print '' 465 else: 466 print "\nThere is no :\""+main.TEST+"\" test, Please Provide OpenSpeak Script/ test script" 467 __builtin__.testthread = None 468 main.exit() 469 470 try : 471 testModule = __import__(main.classPath, globals(), locals(), [main.TEST], -1) 472 except(ImportError): 473 print "There is no test like "+main.TEST 474 main.exit() 475 476 testClass = getattr(testModule, main.TEST) 477 main.testObject = testClass() 478 load_parser() 479 main.params = main.parser.parseParams(main.classPath) 480 main.topology = main.parser.parseTopology(main.classPath)
481
482 -def verifyParams():
483 try : 484 main.params = main.params['PARAMS'] 485 except(KeyError): 486 print "Error with the params file: Either the file not specified or the format is not correct" 487 main.exit() 488 489 try : 490 main.topology = main.topology['TOPOLOGY'] 491 except(KeyError): 492 print "Error with the Topology file: Either the file not specified or the format is not correct" 493 main.exit()
494
495 -def load_parser() :
496 ''' 497 It facilitates the loading customised parser for topology and params file. 498 It loads parser mentioned in tab named parser of ofa.cfg file. 499 It also loads default xmlparser if no parser have specified in ofa.cfg file. 500 501 ''' 502 confighash = main.configDict 503 if 'file' in confighash['config']['parser'] and 'class' in confighash['config']['parser']: 504 if confighash['config']['parser']['file'] != None or confighash['config']['parser']['class']!= None : 505 if os.path.exists(confighash['config']['parser']['file']) : 506 module = re.sub(r".py\s*$","",confighash['config']['parser']['file']) 507 moduleList = module.split("/") 508 newModule = ".".join([moduleList[len(moduleList) - 2],moduleList[len(moduleList) - 1]]) 509 try : 510 parsingClass = confighash['config']['parser']['class'] 511 parsingModule = __import__(newModule, globals(), locals(), [parsingClass], -1) 512 parsingClass = getattr(parsingModule, parsingClass) 513 main.parser = parsingClass() 514 #hashobj = main.parser.parseParams(main.classPath) 515 if hasattr(main.parser,"parseParams") and hasattr(main.parser,"parseTopology") and hasattr(main.parser,"parse") : 516 517 pass 518 else: 519 main.exit() 520 521 except ImportError: 522 print sys.exc_info()[1] 523 main.exit() 524 else : 525 print "No Such File Exists !!"+ confighash['config']['parser']['file'] +"using default parser" 526 load_defaultParser() 527 elif confighash['config']['parser']['file'] == None or confighash['config']['parser']['class'] == None : 528 load_defaultParser() 529 else: 530 load_defaultParser()
531
532 -def load_defaultParser():
533 ''' 534 It will load the default parser which is xml parser to parse the params and topology file. 535 ''' 536 moduleList = main.parserPath.split("/") 537 newModule = ".".join([moduleList[len(moduleList) - 2],moduleList[len(moduleList) - 1]]) 538 try : 539 parsingClass = main.parsingClass 540 parsingModule = __import__(newModule, globals(), locals(), [parsingClass], -1) 541 parsingClass = getattr(parsingModule, parsingClass) 542 main.parser = parsingClass() 543 if hasattr(main.parser,"parseParams") and hasattr(main.parser,"parseTopology") and hasattr(main.parser,"parse") : 544 pass 545 else: 546 main.exit() 547 548 except ImportError: 549 print sys.exc_info()[1]
550 551
552 -def load_logger() :
553 ''' 554 It facilitates the loading customised parser for topology and params file. 555 It loads parser mentioned in tab named parser of ofa.cfg file. 556 It also loads default xmlparser if no parser have specified in ofa.cfg file. 557 558 ''' 559 confighash = main.configDict 560 if 'file' in confighash['config']['logger'] and 'class' in confighash['config']['logger']: 561 if confighash['config']['logger']['file'] != None or confighash['config']['logger']['class']!= None : 562 if os.path.exists(confighash['config']['logger']['file']) : 563 module = re.sub(r".py\s*$","",confighash['config']['logger']['file']) 564 moduleList = module.split("/") 565 newModule = ".".join([moduleList[len(moduleList) - 2],moduleList[len(moduleList) - 1]]) 566 try : 567 loggerClass = confighash['config']['logger']['class'] 568 loggerModule = __import__(newModule, globals(), locals(), [loggerClass], -1) 569 loggerClass = getattr(loggerModule, loggerClass) 570 main.logger = loggerClass() 571 #hashobj = main.parser.parseParams(main.classPath) 572 573 except ImportError: 574 print sys.exc_info()[1] 575 else : 576 print "No Such File Exists !!"+confighash['config']['logger']['file']+ "Using default logger" 577 load_defaultlogger() 578 elif confighash['config']['parser']['file'] == None or confighash['config']['parser']['class'] == None : 579 load_defaultlogger() 580 else: 581 load_defaultlogger()
582
583 -def load_defaultlogger():
584 ''' 585 It will load the default parser which is xml parser to parse the params and topology file. 586 ''' 587 moduleList = main.loggerPath.split("/") 588 newModule = ".".join([moduleList[len(moduleList) - 2],moduleList[len(moduleList) - 1]]) 589 try : 590 loggerClass = main.loggerClass 591 loggerModule = __import__(newModule, globals(), locals(), [loggerClass], -1) 592 loggerClass = getattr(loggerModule, loggerClass) 593 main.logger = loggerClass() 594 595 except ImportError: 596 print sys.exc_info()[1] 597 main.exit()
598
599 -def _echo(self):
600 print "THIS IS ECHO"
601