blob: 0da4ceecad7225ba31b6bd8d387d2278bdf4df38 [file] [log] [blame]
adminbae64d82013-08-01 10:50:15 -07001#!/usr/bin/env python
2'''
3Created on 22-Oct-2012
Jon Hall65844a32015-03-09 19:09:37 -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
Jon Hall65844a32015-03-09 19:09:37 -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
Jon Hall30b82fa2015-03-04 17:15:43 -080034import 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
kelvin-onlabfb521662015-02-27 09:52:40 -080050from core.Thread import Thread
adminbae64d82013-08-01 10:50:15 -070051
adminbae64d82013-08-01 10:50:15 -070052
53class TestON:
54 '''
Jon Hall81d3d392015-04-24 14:40:35 -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
71 self.FAIL = False
72 self.PASS = True
73 self.CASERESULT = self.TRUE
74 self.init_result = self.TRUE
75 self.testResult = "Summary"
Jon Hall81d3d392015-04-24 14:40:35 -070076 self.stepName = ""
77 self.wikiCache = ""
78 # make this into two lists? one for step names, one for results?
79 # this way, the case result could be a true AND of these results
Jon Halld61331b2015-02-17 16:35:47 -080080 self.EXPERIMENTAL_MODE = False
adminbae64d82013-08-01 10:50:15 -070081 self.test_target = None
82 self.lastcommand = None
Jon Halld61331b2015-02-17 16:35:47 -080083 self.testDir = tests_path
84 self.configFile = config_path + "teston.cfg"
adminbae64d82013-08-01 10:50:15 -070085 self.parsingClass = "xmlparser"
86 self.parserPath = core_path + "/xmlparser"
87 self.loggerPath = core_path + "/logger"
88 self.loggerClass = "Logger"
89 self.logs_path = logs_path
90 self.driver = ''
kelvin-onlabfb521662015-02-27 09:52:40 -080091 self.Thread = Thread
Jon Hall65844a32015-03-09 19:09:37 -070092
adminbae64d82013-08-01 10:50:15 -070093 self.configparser()
94 verifyOptions(options)
95 load_logger()
96 self.componentDictionary = {}
97 self.componentDictionary = self.topology ['COMPONENT']
98 self.driversList=[]
99 if type(self.componentDictionary) == str :
100 self.componentDictionary = dict(self.componentDictionary)
Jon Hall65844a32015-03-09 19:09:37 -0700101
adminbae64d82013-08-01 10:50:15 -0700102 for component in self.componentDictionary :
103 self.driversList.append(self.componentDictionary[component]['type'])
Jon Hall65844a32015-03-09 19:09:37 -0700104
adminbae64d82013-08-01 10:50:15 -0700105 self.driversList = list(set(self.driversList)) # Removing duplicates.
106 # Checking the test_target option set for the component or not
107 if type(self.componentDictionary) == dict:
108 for component in self.componentDictionary.keys():
109 if 'test_target' in self.componentDictionary[component].keys():
110 self.test_target = component
Jon Hall65844a32015-03-09 19:09:37 -0700111
Jon Halld61331b2015-02-17 16:35:47 -0800112 # Checking for the openspeak file and test script
adminbae64d82013-08-01 10:50:15 -0700113 self.logger.initlog(self)
114
115 # Creating Drivers Handles
116 initString = "\n"+"*" * 30+"\n CASE INIT \n"+"*" * 30+"\n"
117 self.log.exact(initString)
118 self.driverObject = {}
119 self.random_order = 111 # Random order id to connect the components
120 components_connect_order = {}
121 #component_list.append()
122 if type(self.componentDictionary) == dict:
123 for component in self.componentDictionary.keys():
124 self.componentDictionary[component]['connect_order'] = self.componentDictionary[component]['connect_order'] if ('connect_order' in self.componentDictionary[component].keys()) else str(self.get_random())
125 components_connect_order[component] = eval(self.componentDictionary[component]['connect_order'])
126 #Ordering components based on the connect order.
127 ordered_component_list =sorted(components_connect_order, key=lambda key: components_connect_order[key])
128 print ordered_component_list
adminbae64d82013-08-01 10:50:15 -0700129 for component in ordered_component_list:
130 self.componentInit(component)
131
132 def configparser(self):
133 '''
134 It will parse the config file (teston.cfg) and return as dictionary
135 '''
136 matchFileName = re.match(r'(.*)\.cfg', self.configFile, re.M | re.I)
137 if matchFileName:
138 xml = open(self.configFile).read()
139 try :
140 self.configDict = xmldict.xml_to_dict(xml)
141 return self.configDict
Jon Hallfebb1c72015-03-05 13:30:09 -0800142 except Exception:
adminbae64d82013-08-01 10:50:15 -0700143 print "There is no such file to parse " + self.configFile
Jon Hall81d3d392015-04-24 14:40:35 -0700144
adminbae64d82013-08-01 10:50:15 -0700145 def componentInit(self,component):
146 '''
147 This method will initialize specified component
148 '''
149 global driver_options
150 self.log.info("Creating component Handle: "+component)
Jon Halld61331b2015-02-17 16:35:47 -0800151 driver_options = {}
adminbae64d82013-08-01 10:50:15 -0700152 if 'COMPONENTS' in self.componentDictionary[component].keys():
153 driver_options =dict(self.componentDictionary[component]['COMPONENTS'])
154
155 driver_options['name']=component
156 driverName = self.componentDictionary[component]['type']
157 driver_options ['type'] = driverName
Jon Hall81d3d392015-04-24 14:40:35 -0700158
adminbae64d82013-08-01 10:50:15 -0700159 classPath = self.getDriverPath(driverName.lower())
Jon Hall30b82fa2015-03-04 17:15:43 -0800160 driverModule = importlib.import_module(classPath)
adminbae64d82013-08-01 10:50:15 -0700161 driverClass = getattr(driverModule, driverName)
162 driverObject = driverClass()
Jon Hall81d3d392015-04-24 14:40:35 -0700163
adminbae64d82013-08-01 10:50:15 -0700164 connect_result = driverObject.connect(user_name = self.componentDictionary[component]['user'] if ('user' in self.componentDictionary[component].keys()) else getpass.getuser(),
165 ip_address= self.componentDictionary[component]['host'] if ('host' in self.componentDictionary[component].keys()) else 'localhost',
166 pwd = self.componentDictionary[component]['password'] if ('password' in self.componentDictionary[component].keys()) else 'changeme',
167 port = self.componentDictionary[component]['port'] if ('port' in self.componentDictionary[component].keys()) else None,
168 options = driver_options)
169 if not connect_result:
170 self.log.error("Exiting form the test execution because the connecting to the "+component+" component failed.")
Jon Halld61331b2015-02-17 16:35:47 -0800171 self.exit()
Jon Hall81d3d392015-04-24 14:40:35 -0700172
adminbae64d82013-08-01 10:50:15 -0700173 vars(self)[component] = driverObject
Jon Hall81d3d392015-04-24 14:40:35 -0700174
adminbae64d82013-08-01 10:50:15 -0700175 def run(self):
176 '''
Jon Hall81d3d392015-04-24 14:40:35 -0700177 The Execution of the test script's cases listed in the Test params file will be done here.
178 And Update each test case result.
179 This method will return TRUE if it executed all the test cases successfully,
adminbae64d82013-08-01 10:50:15 -0700180 else will retun FALSE
181 '''
adminbae64d82013-08-01 10:50:15 -0700182 self.testCaseResult = {}
Jon Halla1185982014-09-15 14:55:10 -0700183 self.TOTAL_TC = 0
adminbae64d82013-08-01 10:50:15 -0700184 self.TOTAL_TC_RUN = 0
Jon Halld61331b2015-02-17 16:35:47 -0800185 self.TOTAL_TC_PLANNED = 0
adminbae64d82013-08-01 10:50:15 -0700186 self.TOTAL_TC_NORESULT = 0
187 self.TOTAL_TC_FAIL = 0
188 self.TOTAL_TC_PASS = 0
Jon Halla1185982014-09-15 14:55:10 -0700189 self.TEST_ITERATION = 0
adminbae64d82013-08-01 10:50:15 -0700190 self.stepCount = 0
191 self.CASERESULT = self.TRUE
Jon Hall81d3d392015-04-24 14:40:35 -0700192
Jon Halld61331b2015-02-17 16:35:47 -0800193 import testparser
adminbae64d82013-08-01 10:50:15 -0700194 testFile = self.tests_path + "/"+self.TEST + "/"+self.TEST + ".py"
195 test = testparser.TestParser(testFile)
196 self.testscript = test.testscript
197 self.code = test.getStepCode()
Jon Hallfebb1c72015-03-05 13:30:09 -0800198 repeat= int(self.params['repeat']) if ('repeat' in self.params) else 1
199 self.TOTAL_TC_PLANNED = len(self.testcases_list)*repeat
Jon Hall81d3d392015-04-24 14:40:35 -0700200
adminbae64d82013-08-01 10:50:15 -0700201 result = self.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800202 while(repeat):
Jon Halla1185982014-09-15 14:55:10 -0700203 for self.CurrentTestCaseNumber in self.testcases_list:
Jon Halld61331b2015-02-17 16:35:47 -0800204 result = self.runCase(self.CurrentTestCaseNumber)
Jon Hallfebb1c72015-03-05 13:30:09 -0800205 repeat-=1
adminbae64d82013-08-01 10:50:15 -0700206 return result
Jon Hall81d3d392015-04-24 14:40:35 -0700207
adminbae64d82013-08-01 10:50:15 -0700208 def runCase(self,testCaseNumber):
209 self.CurrentTestCaseNumber = testCaseNumber
Jon Hall81d3d392015-04-24 14:40:35 -0700210 self.CurrentTestCase = ""
211 self.stepName = ""
adminbae64d82013-08-01 10:50:15 -0700212 result = self.TRUE
213 self.stepCount = 0
214 self.EXPERIMENTAL_MODE = self.FALSE
215 self.addCaseHeader()
216 self.testCaseNumber = str(testCaseNumber)
217 stopped = False
218 try :
219 self.stepList = self.code[self.testCaseNumber].keys()
Jon Halld61331b2015-02-17 16:35:47 -0800220 except KeyError:
Jon Hallfebb1c72015-03-05 13:30:09 -0800221 self.log.error("There is no Test-Case "+ self.testCaseNumber)
222 return self.FALSE
Jon Hall81d3d392015-04-24 14:40:35 -0700223
adminbae64d82013-08-01 10:50:15 -0700224 self.stepCount = 0
225 while self.stepCount < len(self.code[self.testCaseNumber].keys()):
226 result = self.runStep(self.stepList,self.code,self.testCaseNumber)
Jon Hallfebb1c72015-03-05 13:30:09 -0800227 if result == self.FALSE:
adminbae64d82013-08-01 10:50:15 -0700228 break
Jon Hallfebb1c72015-03-05 13:30:09 -0800229 elif result == self.TRUE:
adminbae64d82013-08-01 10:50:15 -0700230 continue
adminbae64d82013-08-01 10:50:15 -0700231 if not stopped :
232 self.testCaseResult[str(self.CurrentTestCaseNumber)] = self.CASERESULT
233 self.logger.updateCaseResults(self)
Jon Hall81d3d392015-04-24 14:40:35 -0700234 self.log.wiki(self.wikiCache)
235 self.wikiCache = ""
adminbae64d82013-08-01 10:50:15 -0700236 return result
Jon Hall81d3d392015-04-24 14:40:35 -0700237
adminbae64d82013-08-01 10:50:15 -0700238 def runStep(self,stepList,code,testCaseNumber):
239 if not cli.pause:
240 try :
241 step = stepList[self.stepCount]
242 exec code[testCaseNumber][step] in module.__dict__
243 self.stepCount = self.stepCount + 1
Jon Hall81d3d392015-04-24 14:40:35 -0700244 if step > 0: # FIXME: step 0 is from previous case - Why is it doing this?
245 #FIXME are we losing results because of this?
246 # Maybe we should be updating stepName sooner?
247 self.wikiCache += "\t"+str(testCaseNumber)+"."+str(step)+" "+self.stepName+" - "
248 if self.CASERESULT == self.TRUE:
249 self.wikiCache += "PASSED\n"
250 elif self.CASERESULT == self.FALSE:
251 self.wikiCache += "FAILED\n"
252 else:
253 self.wikiCache += "No Result\n"
254 '''
255 else: # FIXME : DEBUG
256 self.wikiCache += "DEBUG\t"+str(testCaseNumber)+"."+str(step)+" "+self.stepName+" - "
257 if self.CASERESULT == self.TRUE:
258 self.wikiCache += "PASSED\n"
259 elif self.CASERESULT == self.FALSE:
260 self.wikiCache += "FAILED\n"
261 else:
262 self.wikiCache += "No Result\n"
263 '''
adminbae64d82013-08-01 10:50:15 -0700264 except TypeError,e:
Jon Hall63604932015-02-26 17:09:50 -0800265 print "Exception in the following section of code: Test Step " +\
266 str(testCaseNumber) + "." + str(step) + " ):"
267 #print code[testCaseNumber][step]
adminbae64d82013-08-01 10:50:15 -0700268 self.stepCount = self.stepCount + 1
Jon Hall30b82fa2015-03-04 17:15:43 -0800269 self.log.exception(e)
shahshreya957feaa2015-03-23 16:08:29 -0700270 self.cleanup()
Jon Hall00539b12015-04-03 13:55:46 -0700271 self.exit()
adminbae64d82013-08-01 10:50:15 -0700272 return main.TRUE
adminbae64d82013-08-01 10:50:15 -0700273 if cli.stop:
274 cli.stop = False
275 stopped = True
276 self.TOTAL_TC_NORESULT = self.TOTAL_TC_NORESULT + 1
277 self.testCaseResult[str(self.CurrentTestCaseNumber)] = "Stopped"
278 self.logger.updateCaseResults(self)
279 result = self.cleanup()
280 return main.FALSE
Jon Hall81d3d392015-04-24 14:40:35 -0700281
adminbae64d82013-08-01 10:50:15 -0700282 def addCaseHeader(self):
283 caseHeader = "\n"+"*" * 30+"\n Result summary for Testcase"+str(self.CurrentTestCaseNumber)+"\n"+"*" * 30+"\n"
Jon Halld61331b2015-02-17 16:35:47 -0800284 self.log.exact(caseHeader)
285 caseHeader = "\n"+"*" * 40 +"\nStart of Test Case"+str(self.CurrentTestCaseNumber)+" : "
adminbae64d82013-08-01 10:50:15 -0700286 for driver in self.componentDictionary.keys():
287 vars(self)[driver+'log'].info(caseHeader)
Jon Hall81d3d392015-04-24 14:40:35 -0700288
adminbae64d82013-08-01 10:50:15 -0700289 def addCaseFooter(self):
290 if self.stepCount-1 > 0 :
291 previousStep = " "+str(self.CurrentTestCaseNumber)+"."+str(self.stepCount-1)+": "+ str(self.stepName) + ""
292 stepHeader = "\n"+"*" * 40+"\nEnd of Step "+previousStep+"\n"+"*" * 40+"\n"
Jon Hall81d3d392015-04-24 14:40:35 -0700293
adminbae64d82013-08-01 10:50:15 -0700294 caseFooter = "\n"+"*" * 40+"\nEnd of Test case "+str(self.CurrentTestCaseNumber)+"\n"+"*" * 40+"\n"
Jon Hall81d3d392015-04-24 14:40:35 -0700295
adminbae64d82013-08-01 10:50:15 -0700296 for driver in self.driversList:
297 vars(self)[driver].write(stepHeader+"\n"+caseFooter)
298
299 def cleanup(self):
300 '''
301 Release all the component handles and the close opened file handles.
302 This will return TRUE if all the component handles and log handles closed properly,
303 else return FALSE
304
305 '''
306 result = self.TRUE
307 self.logger.testSummary(self)
Jon Halld61331b2015-02-17 16:35:47 -0800308
adminbae64d82013-08-01 10:50:15 -0700309 #self.reportFile.close()
Jon Halld61331b2015-02-17 16:35:47 -0800310
admin2c7034f2013-08-02 15:09:17 -0700311 #utilities.send_mail()
Jon Hall00539b12015-04-03 13:55:46 -0700312 for component in self.componentDictionary.keys():
313 try :
Jon Halld61331b2015-02-17 16:35:47 -0800314 tempObject = vars(self)[component]
Jon Hall1a77a1e2015-04-06 10:41:13 -0700315 print "Disconnecting from " + str(tempObject.name) + ": " + \
316 str(tempObject)
adminbae64d82013-08-01 10:50:15 -0700317 tempObject.disconnect()
Jon Halld61331b2015-02-17 16:35:47 -0800318 #tempObject.execute(cmd="exit",prompt="(.*)",timeout=120)
adminbae64d82013-08-01 10:50:15 -0700319
Jon Hall00539b12015-04-03 13:55:46 -0700320 except (Exception):
321 self.log.exception( "Exception while disconnecting from " +
322 str( component ) )
323 result = self.FALSE
adminbae64d82013-08-01 10:50:15 -0700324 # Closing all the driver's session files
325 for driver in self.componentDictionary.keys():
326 vars(self)[driver].close_log_handles()
Jon Halld61331b2015-02-17 16:35:47 -0800327
adminbae64d82013-08-01 10:50:15 -0700328 return result
Jon Halld61331b2015-02-17 16:35:47 -0800329
adminbae64d82013-08-01 10:50:15 -0700330 def pause(self):
331 '''
332 This function will pause the test's execution, and will continue after user provide 'resume' command.
333 '''
334 __builtin__.testthread.pause()
Jon Hall81d3d392015-04-24 14:40:35 -0700335
adminbae64d82013-08-01 10:50:15 -0700336 def onfail(self,*components):
337 '''
Jon Hall81d3d392015-04-24 14:40:35 -0700338 When test step failed, calling all the components onfail.
adminbae64d82013-08-01 10:50:15 -0700339 '''
adminbae64d82013-08-01 10:50:15 -0700340 if not components:
341 try :
342 for component in self.componentDictionary.keys():
343 tempObject = vars(self)[component]
344 result = tempObject.onfail()
345 except(Exception),e:
346 print str(e)
347 result = self.FALSE
adminbae64d82013-08-01 10:50:15 -0700348 else:
349 try :
350 for component in components:
351 tempObject = vars(self)[component]
352 result = tempObject.onfail()
353 except(Exception),e:
354 print str(e)
355 result = self.FALSE
Jon Hall81d3d392015-04-24 14:40:35 -0700356
adminbae64d82013-08-01 10:50:15 -0700357 def getDriverPath(self,driverName):
358 '''
359 Based on the component 'type' specified in the params , this method will find the absolute path ,
360 by recursively searching the name of the component.
361 '''
362 import commands
363
364 cmd = "find "+drivers_path+" -name "+driverName+".py"
365 result = commands.getoutput(cmd)
Jon Hall81d3d392015-04-24 14:40:35 -0700366
adminbae64d82013-08-01 10:50:15 -0700367 result_array = str(result).split('\n')
368 result_count = 0
Jon Hall81d3d392015-04-24 14:40:35 -0700369
adminbae64d82013-08-01 10:50:15 -0700370 for drivers_list in result_array:
371 result_count = result_count+1
372 if result_count > 1 :
373 print "found "+driverName+" "+ str(result_count) + " times"+str(result_array)
374 self.exit()
Jon Hall81d3d392015-04-24 14:40:35 -0700375
adminbae64d82013-08-01 10:50:15 -0700376 result = re.sub("(.*)drivers","",result)
377 result = re.sub("\.py","",result)
378 result = re.sub("\.pyc","",result)
379 result = re.sub("\/",".",result)
380 result = "drivers"+result
381 return result
adminbae64d82013-08-01 10:50:15 -0700382
383 def step(self,stepDesc):
384 '''
385 The step information of the test-case will append to the logs.
386 '''
387 previousStep = " "+str(self.CurrentTestCaseNumber)+"."+str(self.stepCount-1)+": "+ str(self.stepName) + ""
388 self.stepName = stepDesc
389
390 stepName = " "+str(self.CurrentTestCaseNumber)+"."+str(self.stepCount)+": "+ str(stepDesc) + ""
391 try :
392 if self.stepCount == 0:
393 stepName = " INIT : Initializing the test case :"+self.CurrentTestCase
394 except AttributeError:
395 stepName = " INIT : Initializing the test case :"+str(self.CurrentTestCaseNumber)
Jon Hall81d3d392015-04-24 14:40:35 -0700396
adminbae64d82013-08-01 10:50:15 -0700397 self.log.step(stepName)
398 stepHeader = ""
399 if self.stepCount > 1 :
400 stepHeader = "\n"+"-"*45+"\nEnd of Step "+previousStep+"\n"+"-"*45+"\n"
Jon Hall81d3d392015-04-24 14:40:35 -0700401
Jon Halld61331b2015-02-17 16:35:47 -0800402 stepHeader += "\n"+"-"*45+"\nStart of Step"+stepName+"\n"+"-"*45+"\n"
adminbae64d82013-08-01 10:50:15 -0700403 for driver in self.componentDictionary.keys():
404 vars(self)[driver+'log'].info(stepHeader)
Jon Hall81d3d392015-04-24 14:40:35 -0700405
adminbae64d82013-08-01 10:50:15 -0700406 def case(self,testCaseName):
407 '''
408 Test's each test-case information will append to the logs.
409 '''
Jon Halld61331b2015-02-17 16:35:47 -0800410 self.CurrentTestCase = testCaseName
adminbae64d82013-08-01 10:50:15 -0700411 testCaseName = " " + str(testCaseName) + ""
412 self.log.case(testCaseName)
Jon Halld61331b2015-02-17 16:35:47 -0800413 caseHeader = testCaseName+"\n"+"*" * 40+"\n"
adminbae64d82013-08-01 10:50:15 -0700414 for driver in self.componentDictionary.keys():
415 vars(self)[driver+'log'].info(caseHeader)
Jon Hall81d3d392015-04-24 14:40:35 -0700416
adminbae64d82013-08-01 10:50:15 -0700417 def testDesc(self,description):
418 '''
419 Test description will append to the logs.
420 '''
421 description = "Test Description : " + str (description) + ""
422 self.log.info(description)
Jon Hall81d3d392015-04-24 14:40:35 -0700423
adminbae64d82013-08-01 10:50:15 -0700424 def _getTest(self):
425 '''
426 This method will parse the test script to find required test information.
427 '''
428 testFile = self.tests_path + "/"+self.TEST + "/"+self.TEST + ".py"
429 testFileHandler = open(testFile, 'r')
430 testFileList = testFileHandler.readlines()
431 testFileHandler.close()
432 #self.TOTAL_TC_PLANNED = 0
433 counter = 0
434 for index in range(len(testFileList)):
435 lineMatch = re.match('\s+def CASE(\d+)(.*):',testFileList[index],0)
436 if lineMatch:
437 counter = counter + 1
Jon Halla1185982014-09-15 14:55:10 -0700438 self.TC_PLANNED = len(self.testcases_list)
Jon Hall81d3d392015-04-24 14:40:35 -0700439
adminbae64d82013-08-01 10:50:15 -0700440 def response_parser(self,response, return_format):
441 ''' It will load the default response parser '''
442 response_dict = {}
443 response_dict = self.response_to_dict(response, return_format)
Jon Halld61331b2015-02-17 16:35:47 -0800444 return_format_string = self.dict_to_return_format(response,return_format,response_dict)
adminbae64d82013-08-01 10:50:15 -0700445 return return_format_string
Jon Hall81d3d392015-04-24 14:40:35 -0700446
adminbae64d82013-08-01 10:50:15 -0700447 def response_to_dict(self,response,return_format):
adminbae64d82013-08-01 10:50:15 -0700448 response_dict = {}
449 json_match = re.search('^\s*{', response)
450 xml_match = re.search('^\s*\<', response)
451 ini_match = re.search('^\s*\[', response)
452 if json_match :
Jon Hallfebb1c72015-03-05 13:30:09 -0800453 self.log.info(" Response is in 'JSON' format and Converting to '"+return_format+"' format")
Jon Halld61331b2015-02-17 16:35:47 -0800454 # Formatting the json string
adminbae64d82013-08-01 10:50:15 -0700455 response = re.sub(r"{\s*'?(\w)", r'{"\1', response)
456 response = re.sub(r",\s*'?(\w)", r',"\1', response)
457 response = re.sub(r"(\w)'?\s*:", r'\1":', response)
458 response = re.sub(r":\s*'(\w)'\s*([,}])", r':"\1"\2', response)
adminbae64d82013-08-01 10:50:15 -0700459 try :
460 import json
461 response_dict = json.loads(response)
Jon Hall30b82fa2015-03-04 17:15:43 -0800462 except Exception, e:
Jon Hallfebb1c72015-03-05 13:30:09 -0800463 self.log.exception( e )
464 self.log.error("Json Parser is unable to parse the string")
adminbae64d82013-08-01 10:50:15 -0700465 return response_dict
adminbae64d82013-08-01 10:50:15 -0700466 elif ini_match :
Jon Hallfebb1c72015-03-05 13:30:09 -0800467 self.log.info(" Response is in 'INI' format and Converting to '"+return_format+"' format")
adminbae64d82013-08-01 10:50:15 -0700468 from configobj import ConfigObj
469 response_file = open("respnse_file.temp",'w')
470 response_file.write(response)
Jon Halld61331b2015-02-17 16:35:47 -0800471 response_file.close()
adminbae64d82013-08-01 10:50:15 -0700472 response_dict = ConfigObj("respnse_file.temp")
473 return response_dict
adminbae64d82013-08-01 10:50:15 -0700474 elif xml_match :
Jon Hallfebb1c72015-03-05 13:30:09 -0800475 self.log.info(" Response is in 'XML' format and Converting to '"+return_format+"' format")
adminbae64d82013-08-01 10:50:15 -0700476 try :
adminbae64d82013-08-01 10:50:15 -0700477 response_dict = xmldict.xml_to_dict("<response> "+str(response)+" </response>")
478 except Exception, e:
Jon Hallfebb1c72015-03-05 13:30:09 -0800479 self.log.exception( e )
adminbae64d82013-08-01 10:50:15 -0700480 return response_dict
Jon Hall81d3d392015-04-24 14:40:35 -0700481
adminbae64d82013-08-01 10:50:15 -0700482 def dict_to_return_format(self,response,return_format,response_dict):
adminbae64d82013-08-01 10:50:15 -0700483 if return_format =='table' :
484 ''' Will return in table format'''
485 to_do = "Call the table output formatter"
486 global response_table
487 response_table = '\n'
488 response_table = response_table +'\t'.join(response_dict)+"\n"
Jon Hall81d3d392015-04-24 14:40:35 -0700489
adminbae64d82013-08-01 10:50:15 -0700490 def get_table(value_to_convert):
491 ''' This will parse the dictionary recusrsively and print as table format'''
492 table_data = ""
493 if type(value_to_convert) == dict :
494 table_data = table_data +'\t'.join(value_to_convert)+"\n"
495 for temp_val in value_to_convert.values() :
496 table_data = table_data + get_table(temp_val)
497 else :
498 table_data = table_data + str(value_to_convert) +"\t"
Jon Halld61331b2015-02-17 16:35:47 -0800499 return table_data
Jon Hall81d3d392015-04-24 14:40:35 -0700500
adminbae64d82013-08-01 10:50:15 -0700501 for value in response_dict.values() :
502 response_table = response_table + get_table(value)
Jon Hall88e498c2015-03-06 09:54:35 -0800503 # response_table = response_table + '\t'.join(response_dict.values())
adminbae64d82013-08-01 10:50:15 -0700504 return response_table
Jon Hall81d3d392015-04-24 14:40:35 -0700505
adminbae64d82013-08-01 10:50:15 -0700506 elif return_format =='config':
507 ''' Will return in config format'''
508 to_do = 'Call dict to config coverter'
509 response_string = str(response_dict)
510 print response_string
511 response_config = re.sub(",", "\n\t", response_string)
512 response_config = re.sub("u\'", "\'", response_config)
513 response_config = re.sub("{", "", response_config)
514 response_config = re.sub("}", "\n", response_config)
515 response_config = re.sub(":", " =", response_config)
516 return "[response]\n\t "+response_config
adminbae64d82013-08-01 10:50:15 -0700517 elif return_format == 'xml':
518 ''' Will return in xml format'''
adminbae64d82013-08-01 10:50:15 -0700519 response_xml = xmldict.dict_to_xml(response_dict)
520 response_xml = re.sub(">\s*<", ">\n<", response_xml)
521 return "\n"+response_xml
adminbae64d82013-08-01 10:50:15 -0700522 elif return_format == 'json':
523 ''' Will return in json format'''
524 to_do = 'Call dict to xml coverter'
525 import json
526 response_json = json.dumps(response_dict)
527 return response_json
Jon Hall81d3d392015-04-24 14:40:35 -0700528
adminbae64d82013-08-01 10:50:15 -0700529 def get_random(self):
530 self.random_order = self.random_order + 1
531 return self.random_order
Jon Hall81d3d392015-04-24 14:40:35 -0700532
adminbae64d82013-08-01 10:50:15 -0700533 def exit(self):
534 __builtin__.testthread = None
535 sys.exit()
536
537def verifyOptions(options):
538 '''
539 This will verify the command line options and set to default values, if any option not given in command line.
540 '''
541 import pprint
542 pp = pprint.PrettyPrinter(indent=4)
543
Jon Hall88e498c2015-03-06 09:54:35 -0800544 # pp.pprint(options)
adminbae64d82013-08-01 10:50:15 -0700545 verifyTest(options)
546 verifyExample(options)
547 verifyTestScript(options)
548 verifyParams()
549 verifyLogdir(options)
550 verifyMail(options)
551 verifyTestCases(options)
552
553def verifyTest(options):
554 if options.testname:
555 main.TEST = options.testname
556 main.classPath = "tests."+main.TEST+"."+main.TEST
557 main.tests_path = tests_path
558 elif options.example :
559 main.TEST = options.example
560 main.tests_path = path+"/examples/"
561 main.classPath = "examples."+main.TEST+"."+main.TEST
562 else :
563 print "Test or Example not specified please specify the --test <test name > or --example <example name>"
564 self.exit()
565
566def verifyExample(options):
567 if options.example:
568 main.testDir = path+'/examples/'
569 main.tests_path = path+"/examples/"
570 main.classPath = "examples."+main.TEST+"."+main.TEST
Jon Hall81d3d392015-04-24 14:40:35 -0700571
adminbae64d82013-08-01 10:50:15 -0700572def verifyLogdir(options):
Jon Hall88e498c2015-03-06 09:54:35 -0800573 # Verifying Log directory option
adminbae64d82013-08-01 10:50:15 -0700574 if options.logdir:
575 main.logdir = options.logdir
576 else :
Jon Halld61331b2015-02-17 16:35:47 -0800577 main.logdir = main.FALSE
Jon Hall81d3d392015-04-24 14:40:35 -0700578
adminbae64d82013-08-01 10:50:15 -0700579def verifyMail(options):
Jon Halld61331b2015-02-17 16:35:47 -0800580 # Checking the mailing list
adminbae64d82013-08-01 10:50:15 -0700581 if options.mail:
582 main.mail = options.mail
583 elif main.params.has_key('mail'):
584 main.mail = main.params['mail']
585 else :
586 main.mail = 'paxweb@paxterrasolutions.com'
587
588def verifyTestCases(options):
Jon Hall88e498c2015-03-06 09:54:35 -0800589 # Getting Test cases list
adminbae64d82013-08-01 10:50:15 -0700590 if options.testcases:
Jon Hallfebb1c72015-03-05 13:30:09 -0800591 testcases_list = options.testcases
Jon Hall88e498c2015-03-06 09:54:35 -0800592 # sys.exit()
adminbae64d82013-08-01 10:50:15 -0700593 testcases_list = re.sub("(\[|\])", "", options.testcases)
594 main.testcases_list = eval(testcases_list+",")
595 else :
596 if 'testcases' in main.params.keys():
Jon Halla1185982014-09-15 14:55:10 -0700597 temp = eval(main.params['testcases']+",")
598 list1=[]
599 if type(temp[0])==list:
Jon Hallfebb1c72015-03-05 13:30:09 -0800600 for test in temp:
601 for testcase in test:
602 if type(testcase)==int:
603 testcase=[testcase]
604 list1.extend(testcase)
605 else :
606 temp=list(temp)
607 for testcase in temp:
608 if type(testcase)==int:
609 testcase=[testcase]
610 list1.extend(testcase)
611 main.testcases_list=list1
adminbae64d82013-08-01 10:50:15 -0700612 else :
613 print "testcases not specifed in params, please provide in params file or 'testcases' commandline argument"
Jon Halld61331b2015-02-17 16:35:47 -0800614 sys.exit()
Jon Hall81d3d392015-04-24 14:40:35 -0700615
adminbae64d82013-08-01 10:50:15 -0700616def verifyTestScript(options):
617 '''
618 Verifyies test script.
619 '''
Jon Halld61331b2015-02-17 16:35:47 -0800620 main.openspeak = openspeak.OpenSpeak()
adminbae64d82013-08-01 10:50:15 -0700621 openspeakfile = main.testDir+"/" + main.TEST + "/" + main.TEST + ".ospk"
622 testfile = main.testDir+"/" + main.TEST + "/" + main.TEST + ".py"
623 if os.path.exists(openspeakfile) :
624 main.openspeak.compiler(openspeakfile=openspeakfile,writetofile=1)
625 elif os.path.exists(testfile):
626 print ''
627 else:
628 print "\nThere is no :\""+main.TEST+"\" test, Please Provide OpenSpeak Script/ test script"
629 __builtin__.testthread = None
630 main.exit()
adminbae64d82013-08-01 10:50:15 -0700631 try :
adminbae64d82013-08-01 10:50:15 -0700632 testModule = __import__(main.classPath, globals(), locals(), [main.TEST], -1)
633 except(ImportError):
Jon Hallf8ecf732014-12-02 21:14:16 -0500634 print "There was an import error, it might mean that there is no test like "+main.TEST
Jon Halld61331b2015-02-17 16:35:47 -0800635 main.exit()
adminbae64d82013-08-01 10:50:15 -0700636
637 testClass = getattr(testModule, main.TEST)
638 main.testObject = testClass()
639 load_parser()
Jon Halld61331b2015-02-17 16:35:47 -0800640 main.params = main.parser.parseParams(main.classPath)
641 main.topology = main.parser.parseTopology(main.classPath)
Jon Hall81d3d392015-04-24 14:40:35 -0700642
adminbae64d82013-08-01 10:50:15 -0700643def verifyParams():
644 try :
645 main.params = main.params['PARAMS']
646 except(KeyError):
647 print "Error with the params file: Either the file not specified or the format is not correct"
Jon Halld61331b2015-02-17 16:35:47 -0800648 main.exit()
adminbae64d82013-08-01 10:50:15 -0700649 try :
650 main.topology = main.topology['TOPOLOGY']
651 except(KeyError):
652 print "Error with the Topology file: Either the file not specified or the format is not correct"
653 main.exit()
Jon Hall81d3d392015-04-24 14:40:35 -0700654
adminbae64d82013-08-01 10:50:15 -0700655def load_parser() :
656 '''
657 It facilitates the loading customised parser for topology and params file.
658 It loads parser mentioned in tab named parser of teston.cfg file.
659 It also loads default xmlparser if no parser have specified in teston.cfg file.
660
661 '''
662 confighash = main.configDict
663 if 'file' in confighash['config']['parser'] and 'class' in confighash['config']['parser']:
664 if confighash['config']['parser']['file'] != None or confighash['config']['parser']['class']!= None :
665 if os.path.exists(confighash['config']['parser']['file']) :
666 module = re.sub(r".py\s*$","",confighash['config']['parser']['file'])
667 moduleList = module.split("/")
668 newModule = ".".join([moduleList[len(moduleList) - 2],moduleList[len(moduleList) - 1]])
669 try :
670 parsingClass = confighash['config']['parser']['class']
671 parsingModule = __import__(newModule, globals(), locals(), [parsingClass], -1)
672 parsingClass = getattr(parsingModule, parsingClass)
673 main.parser = parsingClass()
674 #hashobj = main.parser.parseParams(main.classPath)
675 if hasattr(main.parser,"parseParams") and hasattr(main.parser,"parseTopology") and hasattr(main.parser,"parse") :
adminbae64d82013-08-01 10:50:15 -0700676 pass
677 else:
678 main.exit()
adminbae64d82013-08-01 10:50:15 -0700679 except ImportError:
680 print sys.exc_info()[1]
681 main.exit()
682 else :
683 print "No Such File Exists !!"+ confighash['config']['parser']['file'] +"using default parser"
Jon Halld61331b2015-02-17 16:35:47 -0800684 load_defaultParser()
685 elif confighash['config']['parser']['file'] == None or confighash['config']['parser']['class'] == None :
686 load_defaultParser()
adminbae64d82013-08-01 10:50:15 -0700687 else:
688 load_defaultParser()
689
690def load_defaultParser():
691 '''
692 It will load the default parser which is xml parser to parse the params and topology file.
693 '''
694 moduleList = main.parserPath.split("/")
695 newModule = ".".join([moduleList[len(moduleList) - 2],moduleList[len(moduleList) - 1]])
696 try :
Jon Halld61331b2015-02-17 16:35:47 -0800697 parsingClass = main.parsingClass
adminbae64d82013-08-01 10:50:15 -0700698 parsingModule = __import__(newModule, globals(), locals(), [parsingClass], -1)
699 parsingClass = getattr(parsingModule, parsingClass)
700 main.parser = parsingClass()
701 if hasattr(main.parser,"parseParams") and hasattr(main.parser,"parseTopology") and hasattr(main.parser,"parse") :
702 pass
703 else:
704 main.exit()
705
706 except ImportError:
707 print sys.exc_info()[1]
708
adminbae64d82013-08-01 10:50:15 -0700709def load_logger() :
710 '''
711 It facilitates the loading customised parser for topology and params file.
712 It loads parser mentioned in tab named parser of teston.cfg file.
713 It also loads default xmlparser if no parser have specified in teston.cfg file.
714
715 '''
716 confighash = main.configDict
717 if 'file' in confighash['config']['logger'] and 'class' in confighash['config']['logger']:
718 if confighash['config']['logger']['file'] != None or confighash['config']['logger']['class']!= None :
719 if os.path.exists(confighash['config']['logger']['file']) :
720 module = re.sub(r".py\s*$","",confighash['config']['logger']['file'])
721 moduleList = module.split("/")
722 newModule = ".".join([moduleList[len(moduleList) - 2],moduleList[len(moduleList) - 1]])
723 try :
724 loggerClass = confighash['config']['logger']['class']
725 loggerModule = __import__(newModule, globals(), locals(), [loggerClass], -1)
726 loggerClass = getattr(loggerModule, loggerClass)
727 main.logger = loggerClass()
728 #hashobj = main.parser.parseParams(main.classPath)
729
730 except ImportError:
731 print sys.exc_info()[1]
732 else :
733 print "No Such File Exists !!"+confighash['config']['logger']['file']+ "Using default logger"
734 load_defaultlogger()
Jon Halld61331b2015-02-17 16:35:47 -0800735 elif confighash['config']['parser']['file'] == None or confighash['config']['parser']['class'] == None :
736 load_defaultlogger()
adminbae64d82013-08-01 10:50:15 -0700737 else:
738 load_defaultlogger()
739
740def load_defaultlogger():
741 '''
742 It will load the default parser which is xml parser to parse the params and topology file.
743 '''
744 moduleList = main.loggerPath.split("/")
745 newModule = ".".join([moduleList[len(moduleList) - 2],moduleList[len(moduleList) - 1]])
746 try :
Jon Halld61331b2015-02-17 16:35:47 -0800747 loggerClass = main.loggerClass
adminbae64d82013-08-01 10:50:15 -0700748 loggerModule = __import__(newModule, globals(), locals(), [loggerClass], -1)
749 loggerClass = getattr(loggerModule, loggerClass)
750 main.logger = loggerClass()
751
752 except ImportError:
753 print sys.exc_info()[1]
Jon Halld61331b2015-02-17 16:35:47 -0800754 main.exit()
adminbae64d82013-08-01 10:50:15 -0700755
756def load_defaultlogger():
757 '''
758 It will load the default parser which is xml parser to parse the params and topology file.
759 '''
760 moduleList = main.loggerPath.split("/")
761 newModule = ".".join([moduleList[len(moduleList) - 2],moduleList[len(moduleList) - 1]])
762 try :
Jon Halld61331b2015-02-17 16:35:47 -0800763 loggerClass = main.loggerClass
adminbae64d82013-08-01 10:50:15 -0700764 loggerModule = __import__(newModule, globals(), locals(), [loggerClass], -1)
765 loggerClass = getattr(loggerModule, loggerClass)
766 main.logger = loggerClass()
767
768 except ImportError:
769 print sys.exc_info()[1]
770 main.exit()
771
adminbae64d82013-08-01 10:50:15 -0700772def _echo(self):
773 print "THIS IS ECHO"