blob: a15bb8c762283f543aabf06dcc2049f3320a955a [file] [log] [blame]
adminbae64d82013-08-01 10:50:15 -07001#!/usr/bin/env python
2'''
3Created on 22-Oct-2012
pingping-lin763ee042015-05-20 17:45:30 -07004
adminbae64d82013-08-01 10:50:15 -07005@author: Anil Kumar (anilkumar.s@paxterrasolutions.com)
6
7
8 TestON is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 2 of the License, or
11 (at your option) any later version.
12
13 TestON is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
pingping-lin763ee042015-05-20 17:45:30 -070019 along with TestON. If not, see <http://www.gnu.org/licenses/>.
adminbae64d82013-08-01 10:50:15 -070020
21
22
23teston is the main module.
24
25'''
26
27import sys
28import getpass
29import os
30import re
31import __builtin__
32import new
33import xmldict
pingping-lin763ee042015-05-20 17:45:30 -070034import importlib
adminbae64d82013-08-01 10:50:15 -070035module = new.module("test")
36import openspeak
37global path, drivers_path, core_path, tests_path,logs_path
38path = re.sub("(core|bin)$", "", os.getcwd())
39drivers_path = path+"drivers/"
40core_path = path+"core"
41tests_path = path+"tests"
42logs_path = path+"logs/"
43config_path = path + "config/"
44sys.path.append(path)
45sys.path.append( drivers_path)
46sys.path.append(core_path )
47sys.path.append(tests_path)
48
49from core.utilities import Utilities
pingping-lin763ee042015-05-20 17:45:30 -070050from core.Thread import Thread
adminbae64d82013-08-01 10:50:15 -070051
adminbae64d82013-08-01 10:50:15 -070052
53class TestON:
54 '''
pingping-lin763ee042015-05-20 17:45:30 -070055 TestON will initiate the specified test.
56 The main tasks are :
57 * Initiate the required Component handles for the test.
adminbae64d82013-08-01 10:50:15 -070058 * Create Log file Handles.
adminbae64d82013-08-01 10:50:15 -070059 '''
60 def __init__(self,options):
61 '''
62 Initialise the component handles specified in the topology file of the specified test.
adminbae64d82013-08-01 10:50:15 -070063 '''
64 # Initialization of the variables.
65 __builtin__.main = self
adminbae64d82013-08-01 10:50:15 -070066 __builtin__.path = path
67 __builtin__.utilities = Utilities()
68 self.TRUE = 1
69 self.FALSE = 0
70 self.ERROR = -1
pingping-lin763ee042015-05-20 17:45:30 -070071 self.NORESULT = 2
adminbae64d82013-08-01 10:50:15 -070072 self.FAIL = False
73 self.PASS = True
pingping-lin763ee042015-05-20 17:45:30 -070074 self.CASERESULT = self.ERROR
75 self.STEPRESULT = self.NORESULT
76 self.stepResults = []
adminbae64d82013-08-01 10:50:15 -070077 self.init_result = self.TRUE
78 self.testResult = "Summary"
pingping-lin763ee042015-05-20 17:45:30 -070079 self.stepName = ""
80 self.stepCache = ""
81 self.EXPERIMENTAL_MODE = False
adminbae64d82013-08-01 10:50:15 -070082 self.test_target = None
83 self.lastcommand = None
pingping-lin763ee042015-05-20 17:45:30 -070084 self.testDir = tests_path
85 self.configFile = config_path + "teston.cfg"
adminbae64d82013-08-01 10:50:15 -070086 self.parsingClass = "xmlparser"
87 self.parserPath = core_path + "/xmlparser"
88 self.loggerPath = core_path + "/logger"
89 self.loggerClass = "Logger"
90 self.logs_path = logs_path
91 self.driver = ''
pingping-lin763ee042015-05-20 17:45:30 -070092 self.Thread = Thread
93
adminbae64d82013-08-01 10:50:15 -070094 self.configparser()
95 verifyOptions(options)
96 load_logger()
97 self.componentDictionary = {}
98 self.componentDictionary = self.topology ['COMPONENT']
99 self.driversList=[]
100 if type(self.componentDictionary) == str :
101 self.componentDictionary = dict(self.componentDictionary)
pingping-lin763ee042015-05-20 17:45:30 -0700102
adminbae64d82013-08-01 10:50:15 -0700103 for component in self.componentDictionary :
104 self.driversList.append(self.componentDictionary[component]['type'])
pingping-lin763ee042015-05-20 17:45:30 -0700105
adminbae64d82013-08-01 10:50:15 -0700106 self.driversList = list(set(self.driversList)) # Removing duplicates.
107 # Checking the test_target option set for the component or not
108 if type(self.componentDictionary) == dict:
109 for component in self.componentDictionary.keys():
110 if 'test_target' in self.componentDictionary[component].keys():
111 self.test_target = component
pingping-lin763ee042015-05-20 17:45:30 -0700112
113 # Checking for the openspeak file and test script
adminbae64d82013-08-01 10:50:15 -0700114 self.logger.initlog(self)
115
116 # Creating Drivers Handles
117 initString = "\n"+"*" * 30+"\n CASE INIT \n"+"*" * 30+"\n"
118 self.log.exact(initString)
119 self.driverObject = {}
120 self.random_order = 111 # Random order id to connect the components
121 components_connect_order = {}
122 #component_list.append()
123 if type(self.componentDictionary) == dict:
124 for component in self.componentDictionary.keys():
125 self.componentDictionary[component]['connect_order'] = self.componentDictionary[component]['connect_order'] if ('connect_order' in self.componentDictionary[component].keys()) else str(self.get_random())
126 components_connect_order[component] = eval(self.componentDictionary[component]['connect_order'])
127 #Ordering components based on the connect order.
128 ordered_component_list =sorted(components_connect_order, key=lambda key: components_connect_order[key])
129 print ordered_component_list
adminbae64d82013-08-01 10:50:15 -0700130 for component in ordered_component_list:
131 self.componentInit(component)
132
133 def configparser(self):
134 '''
135 It will parse the config file (teston.cfg) and return as dictionary
136 '''
137 matchFileName = re.match(r'(.*)\.cfg', self.configFile, re.M | re.I)
138 if matchFileName:
139 xml = open(self.configFile).read()
140 try :
141 self.configDict = xmldict.xml_to_dict(xml)
142 return self.configDict
pingping-lin763ee042015-05-20 17:45:30 -0700143 except Exception:
adminbae64d82013-08-01 10:50:15 -0700144 print "There is no such file to parse " + self.configFile
pingping-lin763ee042015-05-20 17:45:30 -0700145
adminbae64d82013-08-01 10:50:15 -0700146 def componentInit(self,component):
147 '''
148 This method will initialize specified component
149 '''
150 global driver_options
151 self.log.info("Creating component Handle: "+component)
pingping-lin763ee042015-05-20 17:45:30 -0700152 driver_options = {}
adminbae64d82013-08-01 10:50:15 -0700153 if 'COMPONENTS' in self.componentDictionary[component].keys():
154 driver_options =dict(self.componentDictionary[component]['COMPONENTS'])
155
156 driver_options['name']=component
157 driverName = self.componentDictionary[component]['type']
158 driver_options ['type'] = driverName
pingping-lin763ee042015-05-20 17:45:30 -0700159
adminbae64d82013-08-01 10:50:15 -0700160 classPath = self.getDriverPath(driverName.lower())
pingping-lin763ee042015-05-20 17:45:30 -0700161 driverModule = importlib.import_module(classPath)
adminbae64d82013-08-01 10:50:15 -0700162 driverClass = getattr(driverModule, driverName)
163 driverObject = driverClass()
pingping-lin763ee042015-05-20 17:45:30 -0700164
adminbae64d82013-08-01 10:50:15 -0700165 connect_result = driverObject.connect(user_name = self.componentDictionary[component]['user'] if ('user' in self.componentDictionary[component].keys()) else getpass.getuser(),
166 ip_address= self.componentDictionary[component]['host'] if ('host' in self.componentDictionary[component].keys()) else 'localhost',
167 pwd = self.componentDictionary[component]['password'] if ('password' in self.componentDictionary[component].keys()) else 'changeme',
168 port = self.componentDictionary[component]['port'] if ('port' in self.componentDictionary[component].keys()) else None,
169 options = driver_options)
170 if not connect_result:
171 self.log.error("Exiting form the test execution because the connecting to the "+component+" component failed.")
pingping-lin763ee042015-05-20 17:45:30 -0700172 self.exit()
173
adminbae64d82013-08-01 10:50:15 -0700174 vars(self)[component] = driverObject
pingping-lin763ee042015-05-20 17:45:30 -0700175
adminbae64d82013-08-01 10:50:15 -0700176 def run(self):
177 '''
pingping-lin763ee042015-05-20 17:45:30 -0700178 The Execution of the test script's cases listed in the Test params file will be done here.
179 And Update each test case result.
180 This method will return TRUE if it executed all the test cases successfully,
adminbae64d82013-08-01 10:50:15 -0700181 else will retun FALSE
182 '''
adminbae64d82013-08-01 10:50:15 -0700183 self.testCaseResult = {}
Jon Halla1185982014-09-15 14:55:10 -0700184 self.TOTAL_TC = 0
adminbae64d82013-08-01 10:50:15 -0700185 self.TOTAL_TC_RUN = 0
pingping-lin763ee042015-05-20 17:45:30 -0700186 self.TOTAL_TC_PLANNED = 0
adminbae64d82013-08-01 10:50:15 -0700187 self.TOTAL_TC_NORESULT = 0
188 self.TOTAL_TC_FAIL = 0
189 self.TOTAL_TC_PASS = 0
Jon Halla1185982014-09-15 14:55:10 -0700190 self.TEST_ITERATION = 0
adminbae64d82013-08-01 10:50:15 -0700191 self.stepCount = 0
pingping-lin763ee042015-05-20 17:45:30 -0700192 self.CASERESULT = self.NORESULT
193
194 import testparser
adminbae64d82013-08-01 10:50:15 -0700195 testFile = self.tests_path + "/"+self.TEST + "/"+self.TEST + ".py"
196 test = testparser.TestParser(testFile)
197 self.testscript = test.testscript
198 self.code = test.getStepCode()
pingping-lin763ee042015-05-20 17:45:30 -0700199 repeat= int(self.params['repeat']) if ('repeat' in self.params) else 1
200 self.TOTAL_TC_PLANNED = len(self.testcases_list)*repeat
201
adminbae64d82013-08-01 10:50:15 -0700202 result = self.TRUE
pingping-lin763ee042015-05-20 17:45:30 -0700203 while(repeat):
Jon Halla1185982014-09-15 14:55:10 -0700204 for self.CurrentTestCaseNumber in self.testcases_list:
pingping-lin763ee042015-05-20 17:45:30 -0700205 result = self.runCase(self.CurrentTestCaseNumber)
206 repeat-=1
adminbae64d82013-08-01 10:50:15 -0700207 return result
pingping-lin763ee042015-05-20 17:45:30 -0700208
adminbae64d82013-08-01 10:50:15 -0700209 def runCase(self,testCaseNumber):
210 self.CurrentTestCaseNumber = testCaseNumber
pingping-lin763ee042015-05-20 17:45:30 -0700211 self.CurrentTestCase = ""
212 self.stepResults = []
213 self.stepName = ""
214 self.caseExplaination = ""
adminbae64d82013-08-01 10:50:15 -0700215 result = self.TRUE
216 self.stepCount = 0
217 self.EXPERIMENTAL_MODE = self.FALSE
218 self.addCaseHeader()
219 self.testCaseNumber = str(testCaseNumber)
220 stopped = False
221 try :
222 self.stepList = self.code[self.testCaseNumber].keys()
pingping-lin763ee042015-05-20 17:45:30 -0700223 except KeyError:
224 self.log.error("There is no Test-Case "+ self.testCaseNumber)
225 return self.FALSE
226
adminbae64d82013-08-01 10:50:15 -0700227 self.stepCount = 0
228 while self.stepCount < len(self.code[self.testCaseNumber].keys()):
229 result = self.runStep(self.stepList,self.code,self.testCaseNumber)
pingping-lin763ee042015-05-20 17:45:30 -0700230 if result == self.FALSE:
adminbae64d82013-08-01 10:50:15 -0700231 break
pingping-lin763ee042015-05-20 17:45:30 -0700232 elif result == self.TRUE:
adminbae64d82013-08-01 10:50:15 -0700233 continue
adminbae64d82013-08-01 10:50:15 -0700234 if not stopped :
pingping-lin763ee042015-05-20 17:45:30 -0700235 if all( self.TRUE == i for i in self.stepResults ):
236 # ALL PASSED
237 self.CASERESULT = self.TRUE
238 elif self.FALSE in self.stepResults:
239 # AT LEAST ONE FAILED
240 self.CASERESULT = self.FALSE
241 elif self.TRUE in self.stepResults:
242 # AT LEAST ONE PASSED
243 self.CASERESULT = self.TRUE
244 else:
245 self.CASERESULT = self.NORESULT
adminbae64d82013-08-01 10:50:15 -0700246 self.testCaseResult[str(self.CurrentTestCaseNumber)] = self.CASERESULT
247 self.logger.updateCaseResults(self)
pingping-lin763ee042015-05-20 17:45:30 -0700248 self.log.wiki( "<p>" + self.caseExplaination + "</p>" )
249 self.log.summary( self.caseExplaination )
250 self.log.wiki( "<ul>" )
251 for line in self.stepCache.splitlines():
252 if re.search( " - PASS$", line ):
253 self.log.wiki( "<li>" + line + " <ac:emoticon ac:name=\"tick\" /></li>\n" )
254 elif re.search( " - FAIL$", line ):
255 self.log.wiki( "<li>" + line + " <ac:emoticon ac:name=\"cross\" /></li>\n" )
256 elif re.search( " - No Result$", line ):
257 self.log.wiki( "<li>" + line + " <ac:emoticon ac:name=\"warning\" /></li>\n" )
258 self.log.wiki( "</ul>" )
259 self.log.summary( self.stepCache )
260 self.stepCache = ""
adminbae64d82013-08-01 10:50:15 -0700261 return result
pingping-lin763ee042015-05-20 17:45:30 -0700262
adminbae64d82013-08-01 10:50:15 -0700263 def runStep(self,stepList,code,testCaseNumber):
264 if not cli.pause:
265 try :
266 step = stepList[self.stepCount]
pingping-lin763ee042015-05-20 17:45:30 -0700267 self.STEPRESULT = self.NORESULT
adminbae64d82013-08-01 10:50:15 -0700268 exec code[testCaseNumber][step] in module.__dict__
269 self.stepCount = self.stepCount + 1
pingping-lin763ee042015-05-20 17:45:30 -0700270 if step > 0:
271 self.stepCache += "\t"+str(testCaseNumber)+"."+str(step)+" "+self.stepName+" - "
272 if self.STEPRESULT == self.TRUE:
273 self.stepCache += "PASS\n"
274 #self.stepCache += "PASS <ac:emoticon ac:name=\"tick\" /></li>\n"
275 elif self.STEPRESULT == self.FALSE:
276 self.stepCache += "FAIL\n"
277 #self.stepCache += "FAIL <ac:emoticon ac:name=\"cross\" /></li>\n"
278 else:
279 self.stepCache += "No Result\n"
280 #self.stepCache += "No Result <ac:emoticon ac:name=\"warning\" /></li>\n"
281 self.stepResults.append(self.STEPRESULT)
adminbae64d82013-08-01 10:50:15 -0700282 except TypeError,e:
pingping-lin763ee042015-05-20 17:45:30 -0700283 print "\nException in the following section of code: " +\
284 str(testCaseNumber) + "." + str(step) + ": " +\
285 self.stepName
286 #print code[testCaseNumber][step]
adminbae64d82013-08-01 10:50:15 -0700287 self.stepCount = self.stepCount + 1
pingping-lin763ee042015-05-20 17:45:30 -0700288 self.log.exception(e)
289 self.logger.updateCaseResults(self)
290 #WIKI results
291 self.log.wiki( "<ul>" )
292 for line in self.stepCache.splitlines():
293 if re.search( " - PASS$", line ):
294 self.log.wiki( "<li>" + line + " <ac:emoticon ac:name=\"tick\" /></li>\n" )
295 elif re.search( " - FAIL$", line ):
296 self.log.wiki( "<li>" + line + " <ac:emoticon ac:name=\"cross\" /></li>\n" )
297 elif re.search( " - No Result$", line ):
298 self.log.wiki( "<li>" + line + " <ac:emoticon ac:name=\"warning\" /></li>\n" )
299 self.log.wiki( "</ul>" )
300 #summary results
301 self.log.summary( self.stepCache )
302 self.stepCache = ""
303 self.cleanup()
304 self.exit()
adminbae64d82013-08-01 10:50:15 -0700305 return main.TRUE
adminbae64d82013-08-01 10:50:15 -0700306 if cli.stop:
307 cli.stop = False
308 stopped = True
309 self.TOTAL_TC_NORESULT = self.TOTAL_TC_NORESULT + 1
310 self.testCaseResult[str(self.CurrentTestCaseNumber)] = "Stopped"
311 self.logger.updateCaseResults(self)
312 result = self.cleanup()
313 return main.FALSE
pingping-lin763ee042015-05-20 17:45:30 -0700314
adminbae64d82013-08-01 10:50:15 -0700315 def addCaseHeader(self):
316 caseHeader = "\n"+"*" * 30+"\n Result summary for Testcase"+str(self.CurrentTestCaseNumber)+"\n"+"*" * 30+"\n"
pingping-lin763ee042015-05-20 17:45:30 -0700317 self.log.exact(caseHeader)
318 caseHeader = "\n"+"*" * 40 +"\nStart of Test Case"+str(self.CurrentTestCaseNumber)+" : "
adminbae64d82013-08-01 10:50:15 -0700319 for driver in self.componentDictionary.keys():
320 vars(self)[driver+'log'].info(caseHeader)
pingping-lin763ee042015-05-20 17:45:30 -0700321
adminbae64d82013-08-01 10:50:15 -0700322 def addCaseFooter(self):
323 if self.stepCount-1 > 0 :
324 previousStep = " "+str(self.CurrentTestCaseNumber)+"."+str(self.stepCount-1)+": "+ str(self.stepName) + ""
325 stepHeader = "\n"+"*" * 40+"\nEnd of Step "+previousStep+"\n"+"*" * 40+"\n"
pingping-lin763ee042015-05-20 17:45:30 -0700326
adminbae64d82013-08-01 10:50:15 -0700327 caseFooter = "\n"+"*" * 40+"\nEnd of Test case "+str(self.CurrentTestCaseNumber)+"\n"+"*" * 40+"\n"
pingping-lin763ee042015-05-20 17:45:30 -0700328
adminbae64d82013-08-01 10:50:15 -0700329 for driver in self.driversList:
330 vars(self)[driver].write(stepHeader+"\n"+caseFooter)
331
332 def cleanup(self):
333 '''
334 Release all the component handles and the close opened file handles.
335 This will return TRUE if all the component handles and log handles closed properly,
336 else return FALSE
337
338 '''
339 result = self.TRUE
340 self.logger.testSummary(self)
pingping-lin763ee042015-05-20 17:45:30 -0700341
adminbae64d82013-08-01 10:50:15 -0700342 #self.reportFile.close()
adminbae64d82013-08-01 10:50:15 -0700343
admin2c7034f2013-08-02 15:09:17 -0700344 #utilities.send_mail()
pingping-lin763ee042015-05-20 17:45:30 -0700345 for component in self.componentDictionary.keys():
346 try :
347 tempObject = vars(self)[component]
348 print "Disconnecting from " + str(tempObject.name) + ": " + \
349 str(tempObject)
adminbae64d82013-08-01 10:50:15 -0700350 tempObject.disconnect()
pingping-lin763ee042015-05-20 17:45:30 -0700351 #tempObject.execute(cmd="exit",prompt="(.*)",timeout=120)
adminbae64d82013-08-01 10:50:15 -0700352
pingping-lin763ee042015-05-20 17:45:30 -0700353 except (Exception):
354 self.log.exception( "Exception while disconnecting from " +
355 str( component ) )
356 result = self.FALSE
adminbae64d82013-08-01 10:50:15 -0700357 # Closing all the driver's session files
358 for driver in self.componentDictionary.keys():
359 vars(self)[driver].close_log_handles()
pingping-lin763ee042015-05-20 17:45:30 -0700360
adminbae64d82013-08-01 10:50:15 -0700361 return result
pingping-lin763ee042015-05-20 17:45:30 -0700362
adminbae64d82013-08-01 10:50:15 -0700363 def pause(self):
364 '''
365 This function will pause the test's execution, and will continue after user provide 'resume' command.
366 '''
367 __builtin__.testthread.pause()
pingping-lin763ee042015-05-20 17:45:30 -0700368
adminbae64d82013-08-01 10:50:15 -0700369 def onfail(self,*components):
370 '''
pingping-lin763ee042015-05-20 17:45:30 -0700371 When test step failed, calling all the components onfail.
adminbae64d82013-08-01 10:50:15 -0700372 '''
adminbae64d82013-08-01 10:50:15 -0700373 if not components:
374 try :
375 for component in self.componentDictionary.keys():
376 tempObject = vars(self)[component]
377 result = tempObject.onfail()
378 except(Exception),e:
379 print str(e)
380 result = self.FALSE
adminbae64d82013-08-01 10:50:15 -0700381 else:
382 try :
383 for component in components:
384 tempObject = vars(self)[component]
385 result = tempObject.onfail()
386 except(Exception),e:
387 print str(e)
388 result = self.FALSE
pingping-lin763ee042015-05-20 17:45:30 -0700389
adminbae64d82013-08-01 10:50:15 -0700390 def getDriverPath(self,driverName):
391 '''
392 Based on the component 'type' specified in the params , this method will find the absolute path ,
393 by recursively searching the name of the component.
394 '''
395 import commands
396
397 cmd = "find "+drivers_path+" -name "+driverName+".py"
398 result = commands.getoutput(cmd)
pingping-lin763ee042015-05-20 17:45:30 -0700399
adminbae64d82013-08-01 10:50:15 -0700400 result_array = str(result).split('\n')
401 result_count = 0
pingping-lin763ee042015-05-20 17:45:30 -0700402
adminbae64d82013-08-01 10:50:15 -0700403 for drivers_list in result_array:
404 result_count = result_count+1
405 if result_count > 1 :
406 print "found "+driverName+" "+ str(result_count) + " times"+str(result_array)
407 self.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700408
adminbae64d82013-08-01 10:50:15 -0700409 result = re.sub("(.*)drivers","",result)
410 result = re.sub("\.py","",result)
411 result = re.sub("\.pyc","",result)
412 result = re.sub("\/",".",result)
413 result = "drivers"+result
414 return result
adminbae64d82013-08-01 10:50:15 -0700415
416 def step(self,stepDesc):
417 '''
418 The step information of the test-case will append to the logs.
419 '''
420 previousStep = " "+str(self.CurrentTestCaseNumber)+"."+str(self.stepCount-1)+": "+ str(self.stepName) + ""
421 self.stepName = stepDesc
422
423 stepName = " "+str(self.CurrentTestCaseNumber)+"."+str(self.stepCount)+": "+ str(stepDesc) + ""
424 try :
425 if self.stepCount == 0:
426 stepName = " INIT : Initializing the test case :"+self.CurrentTestCase
427 except AttributeError:
428 stepName = " INIT : Initializing the test case :"+str(self.CurrentTestCaseNumber)
pingping-lin763ee042015-05-20 17:45:30 -0700429
adminbae64d82013-08-01 10:50:15 -0700430 self.log.step(stepName)
431 stepHeader = ""
432 if self.stepCount > 1 :
433 stepHeader = "\n"+"-"*45+"\nEnd of Step "+previousStep+"\n"+"-"*45+"\n"
pingping-lin763ee042015-05-20 17:45:30 -0700434
435 stepHeader += "\n"+"-"*45+"\nStart of Step"+stepName+"\n"+"-"*45+"\n"
adminbae64d82013-08-01 10:50:15 -0700436 for driver in self.componentDictionary.keys():
437 vars(self)[driver+'log'].info(stepHeader)
pingping-lin763ee042015-05-20 17:45:30 -0700438
adminbae64d82013-08-01 10:50:15 -0700439 def case(self,testCaseName):
440 '''
441 Test's each test-case information will append to the logs.
442 '''
pingping-lin763ee042015-05-20 17:45:30 -0700443 self.CurrentTestCase = testCaseName
adminbae64d82013-08-01 10:50:15 -0700444 testCaseName = " " + str(testCaseName) + ""
445 self.log.case(testCaseName)
pingping-lin763ee042015-05-20 17:45:30 -0700446 caseHeader = testCaseName+"\n"+"*" * 40+"\n"
adminbae64d82013-08-01 10:50:15 -0700447 for driver in self.componentDictionary.keys():
448 vars(self)[driver+'log'].info(caseHeader)
pingping-lin763ee042015-05-20 17:45:30 -0700449
adminbae64d82013-08-01 10:50:15 -0700450 def testDesc(self,description):
451 '''
452 Test description will append to the logs.
453 '''
454 description = "Test Description : " + str (description) + ""
455 self.log.info(description)
pingping-lin763ee042015-05-20 17:45:30 -0700456
adminbae64d82013-08-01 10:50:15 -0700457 def _getTest(self):
458 '''
459 This method will parse the test script to find required test information.
460 '''
461 testFile = self.tests_path + "/"+self.TEST + "/"+self.TEST + ".py"
462 testFileHandler = open(testFile, 'r')
463 testFileList = testFileHandler.readlines()
464 testFileHandler.close()
465 #self.TOTAL_TC_PLANNED = 0
466 counter = 0
467 for index in range(len(testFileList)):
468 lineMatch = re.match('\s+def CASE(\d+)(.*):',testFileList[index],0)
469 if lineMatch:
470 counter = counter + 1
Jon Halla1185982014-09-15 14:55:10 -0700471 self.TC_PLANNED = len(self.testcases_list)
pingping-lin763ee042015-05-20 17:45:30 -0700472
adminbae64d82013-08-01 10:50:15 -0700473 def response_parser(self,response, return_format):
474 ''' It will load the default response parser '''
475 response_dict = {}
476 response_dict = self.response_to_dict(response, return_format)
pingping-lin763ee042015-05-20 17:45:30 -0700477 return_format_string = self.dict_to_return_format(response,return_format,response_dict)
adminbae64d82013-08-01 10:50:15 -0700478 return return_format_string
pingping-lin763ee042015-05-20 17:45:30 -0700479
adminbae64d82013-08-01 10:50:15 -0700480 def response_to_dict(self,response,return_format):
adminbae64d82013-08-01 10:50:15 -0700481 response_dict = {}
482 json_match = re.search('^\s*{', response)
483 xml_match = re.search('^\s*\<', response)
484 ini_match = re.search('^\s*\[', response)
485 if json_match :
pingping-lin763ee042015-05-20 17:45:30 -0700486 self.log.info(" Response is in 'JSON' format and Converting to '"+return_format+"' format")
487 # Formatting the json string
adminbae64d82013-08-01 10:50:15 -0700488 response = re.sub(r"{\s*'?(\w)", r'{"\1', response)
489 response = re.sub(r",\s*'?(\w)", r',"\1', response)
490 response = re.sub(r"(\w)'?\s*:", r'\1":', response)
491 response = re.sub(r":\s*'(\w)'\s*([,}])", r':"\1"\2', response)
adminbae64d82013-08-01 10:50:15 -0700492 try :
493 import json
494 response_dict = json.loads(response)
pingping-lin763ee042015-05-20 17:45:30 -0700495 except Exception, e:
496 self.log.exception( e )
497 self.log.error("Json Parser is unable to parse the string")
adminbae64d82013-08-01 10:50:15 -0700498 return response_dict
adminbae64d82013-08-01 10:50:15 -0700499 elif ini_match :
pingping-lin763ee042015-05-20 17:45:30 -0700500 self.log.info(" Response is in 'INI' format and Converting to '"+return_format+"' format")
adminbae64d82013-08-01 10:50:15 -0700501 from configobj import ConfigObj
502 response_file = open("respnse_file.temp",'w')
503 response_file.write(response)
pingping-lin763ee042015-05-20 17:45:30 -0700504 response_file.close()
adminbae64d82013-08-01 10:50:15 -0700505 response_dict = ConfigObj("respnse_file.temp")
506 return response_dict
adminbae64d82013-08-01 10:50:15 -0700507 elif xml_match :
pingping-lin763ee042015-05-20 17:45:30 -0700508 self.log.info(" Response is in 'XML' format and Converting to '"+return_format+"' format")
adminbae64d82013-08-01 10:50:15 -0700509 try :
adminbae64d82013-08-01 10:50:15 -0700510 response_dict = xmldict.xml_to_dict("<response> "+str(response)+" </response>")
511 except Exception, e:
pingping-lin763ee042015-05-20 17:45:30 -0700512 self.log.exception( e )
adminbae64d82013-08-01 10:50:15 -0700513 return response_dict
pingping-lin763ee042015-05-20 17:45:30 -0700514
adminbae64d82013-08-01 10:50:15 -0700515 def dict_to_return_format(self,response,return_format,response_dict):
adminbae64d82013-08-01 10:50:15 -0700516 if return_format =='table' :
517 ''' Will return in table format'''
518 to_do = "Call the table output formatter"
519 global response_table
520 response_table = '\n'
521 response_table = response_table +'\t'.join(response_dict)+"\n"
pingping-lin763ee042015-05-20 17:45:30 -0700522
adminbae64d82013-08-01 10:50:15 -0700523 def get_table(value_to_convert):
524 ''' This will parse the dictionary recusrsively and print as table format'''
525 table_data = ""
526 if type(value_to_convert) == dict :
527 table_data = table_data +'\t'.join(value_to_convert)+"\n"
528 for temp_val in value_to_convert.values() :
529 table_data = table_data + get_table(temp_val)
530 else :
531 table_data = table_data + str(value_to_convert) +"\t"
pingping-lin763ee042015-05-20 17:45:30 -0700532 return table_data
533
adminbae64d82013-08-01 10:50:15 -0700534 for value in response_dict.values() :
535 response_table = response_table + get_table(value)
pingping-lin763ee042015-05-20 17:45:30 -0700536 # response_table = response_table + '\t'.join(response_dict.values())
adminbae64d82013-08-01 10:50:15 -0700537 return response_table
pingping-lin763ee042015-05-20 17:45:30 -0700538
adminbae64d82013-08-01 10:50:15 -0700539 elif return_format =='config':
540 ''' Will return in config format'''
541 to_do = 'Call dict to config coverter'
542 response_string = str(response_dict)
543 print response_string
544 response_config = re.sub(",", "\n\t", response_string)
545 response_config = re.sub("u\'", "\'", response_config)
546 response_config = re.sub("{", "", response_config)
547 response_config = re.sub("}", "\n", response_config)
548 response_config = re.sub(":", " =", response_config)
549 return "[response]\n\t "+response_config
adminbae64d82013-08-01 10:50:15 -0700550 elif return_format == 'xml':
551 ''' Will return in xml format'''
adminbae64d82013-08-01 10:50:15 -0700552 response_xml = xmldict.dict_to_xml(response_dict)
553 response_xml = re.sub(">\s*<", ">\n<", response_xml)
554 return "\n"+response_xml
adminbae64d82013-08-01 10:50:15 -0700555 elif return_format == 'json':
556 ''' Will return in json format'''
557 to_do = 'Call dict to xml coverter'
558 import json
559 response_json = json.dumps(response_dict)
560 return response_json
pingping-lin763ee042015-05-20 17:45:30 -0700561
adminbae64d82013-08-01 10:50:15 -0700562 def get_random(self):
563 self.random_order = self.random_order + 1
564 return self.random_order
pingping-lin763ee042015-05-20 17:45:30 -0700565
adminbae64d82013-08-01 10:50:15 -0700566 def exit(self):
567 __builtin__.testthread = None
568 sys.exit()
569
570def verifyOptions(options):
571 '''
572 This will verify the command line options and set to default values, if any option not given in command line.
573 '''
574 import pprint
575 pp = pprint.PrettyPrinter(indent=4)
576
pingping-lin763ee042015-05-20 17:45:30 -0700577 # pp.pprint(options)
adminbae64d82013-08-01 10:50:15 -0700578 verifyTest(options)
579 verifyExample(options)
580 verifyTestScript(options)
581 verifyParams()
582 verifyLogdir(options)
583 verifyMail(options)
584 verifyTestCases(options)
585
586def verifyTest(options):
587 if options.testname:
588 main.TEST = options.testname
589 main.classPath = "tests."+main.TEST+"."+main.TEST
590 main.tests_path = tests_path
591 elif options.example :
592 main.TEST = options.example
593 main.tests_path = path+"/examples/"
594 main.classPath = "examples."+main.TEST+"."+main.TEST
595 else :
596 print "Test or Example not specified please specify the --test <test name > or --example <example name>"
597 self.exit()
598
599def verifyExample(options):
600 if options.example:
601 main.testDir = path+'/examples/'
602 main.tests_path = path+"/examples/"
603 main.classPath = "examples."+main.TEST+"."+main.TEST
pingping-lin763ee042015-05-20 17:45:30 -0700604
adminbae64d82013-08-01 10:50:15 -0700605def verifyLogdir(options):
pingping-lin763ee042015-05-20 17:45:30 -0700606 # Verifying Log directory option
adminbae64d82013-08-01 10:50:15 -0700607 if options.logdir:
608 main.logdir = options.logdir
609 else :
pingping-lin763ee042015-05-20 17:45:30 -0700610 main.logdir = main.FALSE
611
adminbae64d82013-08-01 10:50:15 -0700612def verifyMail(options):
pingping-lin763ee042015-05-20 17:45:30 -0700613 # Checking the mailing list
adminbae64d82013-08-01 10:50:15 -0700614 if options.mail:
615 main.mail = options.mail
616 elif main.params.has_key('mail'):
617 main.mail = main.params['mail']
618 else :
619 main.mail = 'paxweb@paxterrasolutions.com'
620
621def verifyTestCases(options):
pingping-lin763ee042015-05-20 17:45:30 -0700622 # Getting Test cases list
adminbae64d82013-08-01 10:50:15 -0700623 if options.testcases:
pingping-lin763ee042015-05-20 17:45:30 -0700624 testcases_list = options.testcases
625 # sys.exit()
adminbae64d82013-08-01 10:50:15 -0700626 testcases_list = re.sub("(\[|\])", "", options.testcases)
627 main.testcases_list = eval(testcases_list+",")
628 else :
629 if 'testcases' in main.params.keys():
Jon Halla1185982014-09-15 14:55:10 -0700630 temp = eval(main.params['testcases']+",")
631 list1=[]
632 if type(temp[0])==list:
pingping-lin763ee042015-05-20 17:45:30 -0700633 for test in temp:
634 for testcase in test:
635 if type(testcase)==int:
636 testcase=[testcase]
637 list1.extend(testcase)
638 else :
639 temp=list(temp)
640 for testcase in temp:
641 if type(testcase)==int:
642 testcase=[testcase]
643 list1.extend(testcase)
644 main.testcases_list=list1
adminbae64d82013-08-01 10:50:15 -0700645 else :
646 print "testcases not specifed in params, please provide in params file or 'testcases' commandline argument"
pingping-lin763ee042015-05-20 17:45:30 -0700647 sys.exit()
648
adminbae64d82013-08-01 10:50:15 -0700649def verifyTestScript(options):
650 '''
651 Verifyies test script.
652 '''
pingping-lin763ee042015-05-20 17:45:30 -0700653 main.openspeak = openspeak.OpenSpeak()
adminbae64d82013-08-01 10:50:15 -0700654 openspeakfile = main.testDir+"/" + main.TEST + "/" + main.TEST + ".ospk"
655 testfile = main.testDir+"/" + main.TEST + "/" + main.TEST + ".py"
656 if os.path.exists(openspeakfile) :
657 main.openspeak.compiler(openspeakfile=openspeakfile,writetofile=1)
658 elif os.path.exists(testfile):
659 print ''
660 else:
661 print "\nThere is no :\""+main.TEST+"\" test, Please Provide OpenSpeak Script/ test script"
662 __builtin__.testthread = None
663 main.exit()
adminbae64d82013-08-01 10:50:15 -0700664 try :
adminbae64d82013-08-01 10:50:15 -0700665 testModule = __import__(main.classPath, globals(), locals(), [main.TEST], -1)
666 except(ImportError):
Jon Hallf8ecf732014-12-02 21:14:16 -0500667 print "There was an import error, it might mean that there is no test like "+main.TEST
pingping-lin763ee042015-05-20 17:45:30 -0700668 main.exit()
adminbae64d82013-08-01 10:50:15 -0700669
670 testClass = getattr(testModule, main.TEST)
671 main.testObject = testClass()
672 load_parser()
pingping-lin763ee042015-05-20 17:45:30 -0700673 main.params = main.parser.parseParams(main.classPath)
674 main.topology = main.parser.parseTopology(main.classPath)
675
adminbae64d82013-08-01 10:50:15 -0700676def verifyParams():
677 try :
678 main.params = main.params['PARAMS']
679 except(KeyError):
680 print "Error with the params file: Either the file not specified or the format is not correct"
pingping-lin763ee042015-05-20 17:45:30 -0700681 main.exit()
adminbae64d82013-08-01 10:50:15 -0700682 try :
683 main.topology = main.topology['TOPOLOGY']
684 except(KeyError):
685 print "Error with the Topology file: Either the file not specified or the format is not correct"
686 main.exit()
pingping-lin763ee042015-05-20 17:45:30 -0700687
adminbae64d82013-08-01 10:50:15 -0700688def load_parser() :
689 '''
690 It facilitates the loading customised parser for topology and params file.
691 It loads parser mentioned in tab named parser of teston.cfg file.
692 It also loads default xmlparser if no parser have specified in teston.cfg file.
693
694 '''
695 confighash = main.configDict
696 if 'file' in confighash['config']['parser'] and 'class' in confighash['config']['parser']:
697 if confighash['config']['parser']['file'] != None or confighash['config']['parser']['class']!= None :
698 if os.path.exists(confighash['config']['parser']['file']) :
699 module = re.sub(r".py\s*$","",confighash['config']['parser']['file'])
700 moduleList = module.split("/")
701 newModule = ".".join([moduleList[len(moduleList) - 2],moduleList[len(moduleList) - 1]])
702 try :
703 parsingClass = confighash['config']['parser']['class']
704 parsingModule = __import__(newModule, globals(), locals(), [parsingClass], -1)
705 parsingClass = getattr(parsingModule, parsingClass)
706 main.parser = parsingClass()
707 #hashobj = main.parser.parseParams(main.classPath)
708 if hasattr(main.parser,"parseParams") and hasattr(main.parser,"parseTopology") and hasattr(main.parser,"parse") :
adminbae64d82013-08-01 10:50:15 -0700709 pass
710 else:
711 main.exit()
adminbae64d82013-08-01 10:50:15 -0700712 except ImportError:
713 print sys.exc_info()[1]
714 main.exit()
715 else :
716 print "No Such File Exists !!"+ confighash['config']['parser']['file'] +"using default parser"
pingping-lin763ee042015-05-20 17:45:30 -0700717 load_defaultParser()
718 elif confighash['config']['parser']['file'] == None or confighash['config']['parser']['class'] == None :
719 load_defaultParser()
adminbae64d82013-08-01 10:50:15 -0700720 else:
721 load_defaultParser()
722
723def load_defaultParser():
724 '''
725 It will load the default parser which is xml parser to parse the params and topology file.
726 '''
727 moduleList = main.parserPath.split("/")
728 newModule = ".".join([moduleList[len(moduleList) - 2],moduleList[len(moduleList) - 1]])
729 try :
pingping-lin763ee042015-05-20 17:45:30 -0700730 parsingClass = main.parsingClass
adminbae64d82013-08-01 10:50:15 -0700731 parsingModule = __import__(newModule, globals(), locals(), [parsingClass], -1)
732 parsingClass = getattr(parsingModule, parsingClass)
733 main.parser = parsingClass()
734 if hasattr(main.parser,"parseParams") and hasattr(main.parser,"parseTopology") and hasattr(main.parser,"parse") :
735 pass
736 else:
737 main.exit()
738
739 except ImportError:
740 print sys.exc_info()[1]
741
adminbae64d82013-08-01 10:50:15 -0700742def load_logger() :
743 '''
744 It facilitates the loading customised parser for topology and params file.
745 It loads parser mentioned in tab named parser of teston.cfg file.
746 It also loads default xmlparser if no parser have specified in teston.cfg file.
747
748 '''
749 confighash = main.configDict
750 if 'file' in confighash['config']['logger'] and 'class' in confighash['config']['logger']:
751 if confighash['config']['logger']['file'] != None or confighash['config']['logger']['class']!= None :
752 if os.path.exists(confighash['config']['logger']['file']) :
753 module = re.sub(r".py\s*$","",confighash['config']['logger']['file'])
754 moduleList = module.split("/")
755 newModule = ".".join([moduleList[len(moduleList) - 2],moduleList[len(moduleList) - 1]])
756 try :
757 loggerClass = confighash['config']['logger']['class']
758 loggerModule = __import__(newModule, globals(), locals(), [loggerClass], -1)
759 loggerClass = getattr(loggerModule, loggerClass)
760 main.logger = loggerClass()
761 #hashobj = main.parser.parseParams(main.classPath)
762
763 except ImportError:
764 print sys.exc_info()[1]
765 else :
766 print "No Such File Exists !!"+confighash['config']['logger']['file']+ "Using default logger"
767 load_defaultlogger()
pingping-lin763ee042015-05-20 17:45:30 -0700768 elif confighash['config']['parser']['file'] == None or confighash['config']['parser']['class'] == None :
769 load_defaultlogger()
adminbae64d82013-08-01 10:50:15 -0700770 else:
771 load_defaultlogger()
772
773def load_defaultlogger():
774 '''
775 It will load the default parser which is xml parser to parse the params and topology file.
776 '''
777 moduleList = main.loggerPath.split("/")
778 newModule = ".".join([moduleList[len(moduleList) - 2],moduleList[len(moduleList) - 1]])
779 try :
pingping-lin763ee042015-05-20 17:45:30 -0700780 loggerClass = main.loggerClass
adminbae64d82013-08-01 10:50:15 -0700781 loggerModule = __import__(newModule, globals(), locals(), [loggerClass], -1)
782 loggerClass = getattr(loggerModule, loggerClass)
783 main.logger = loggerClass()
784
785 except ImportError:
786 print sys.exc_info()[1]
787 main.exit()
788
pingping-lin763ee042015-05-20 17:45:30 -0700789def load_defaultlogger():
790 '''
791 It will load the default parser which is xml parser to parse the params and topology file.
792 '''
793 moduleList = main.loggerPath.split("/")
794 newModule = ".".join([moduleList[len(moduleList) - 2],moduleList[len(moduleList) - 1]])
795 try :
796 loggerClass = main.loggerClass
797 loggerModule = __import__(newModule, globals(), locals(), [loggerClass], -1)
798 loggerClass = getattr(loggerModule, loggerClass)
799 main.logger = loggerClass()
adminbae64d82013-08-01 10:50:15 -0700800
pingping-lin763ee042015-05-20 17:45:30 -0700801 except ImportError:
802 print sys.exc_info()[1]
803 main.exit()
adminbae64d82013-08-01 10:50:15 -0700804
805def _echo(self):
806 print "THIS IS ECHO"