blob: d6ebc895062f1886f5b191fe77e1a7ae244dc38a [file] [log] [blame]
adminbae64d82013-08-01 10:50:15 -07001#!/usr/bin/env python
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002"""
adminbae64d82013-08-01 10:50:15 -07003Created on 22-Oct-2012
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004Copyright 2012 Open Networking Foundation ( ONF )
Jon Hall65844a32015-03-09 19:09:37 -07005
Jeremy Songsterae01bba2016-07-11 15:39:17 -07006Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
7the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
8or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
adminbae64d82013-08-01 10:50:15 -07009
10 TestON is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation, either version 2 of the License, or
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070013 ( at your option ) any later version.
adminbae64d82013-08-01 10:50:15 -070014
15 TestON is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
Jon Hall65844a32015-03-09 19:09:37 -070021 along with TestON. If not, see <http://www.gnu.org/licenses/>.
adminbae64d82013-08-01 10:50:15 -070022
23
24
25teston is the main module.
26
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070027"""
adminbae64d82013-08-01 10:50:15 -070028import sys
29import getpass
30import os
31import re
32import __builtin__
33import new
34import xmldict
Jon Hall30b82fa2015-03-04 17:15:43 -080035import importlib
Jon Hall5b586732015-06-11 11:39:39 -070036import threading
Jeremy Ronquillo15ff1072017-07-17 10:55:46 -070037import pdb
Jon Hall714eeba2015-09-29 17:53:10 -070038module = new.module( "test" )
adminbae64d82013-08-01 10:50:15 -070039import openspeak
Hari Krishnabe4b97b2015-07-15 12:19:43 -070040import subprocess
Jon Hall714eeba2015-09-29 17:53:10 -070041global path, drivers_path, core_path, tests_path, logs_path
Jon Hall44506242015-07-29 17:40:26 -070042location = os.path.abspath( os.path.dirname( __file__ ) )
43path = re.sub( "(core|bin)$", "", location )
Jon Hall714eeba2015-09-29 17:53:10 -070044drivers_path = path + "drivers"
45core_path = path + "core"
46tests_path = path + "tests"
47logs_path = path + "logs/"
adminbae64d82013-08-01 10:50:15 -070048config_path = path + "config/"
Jon Hall44506242015-07-29 17:40:26 -070049sys.path.append( path )
50sys.path.append( drivers_path )
51sys.path.append( core_path )
52sys.path.append( tests_path )
adminbae64d82013-08-01 10:50:15 -070053
54from core.utilities import Utilities
kelvin-onlabfb521662015-02-27 09:52:40 -080055from core.Thread import Thread
adminbae64d82013-08-01 10:50:15 -070056
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070057
Jon Hallca319892017-06-15 15:25:22 -070058class SkipCase( Exception ):
59 pass
60
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070061
adminbae64d82013-08-01 10:50:15 -070062class TestON:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070063
64 """
kelvin-onlabf70fd542015-05-07 18:41:40 -070065 TestON will initiate the specified test.
Jon Hall714eeba2015-09-29 17:53:10 -070066 The main tasks are:
kelvin-onlabf70fd542015-05-07 18:41:40 -070067 * Initiate the required Component handles for the test.
adminbae64d82013-08-01 10:50:15 -070068 * Create Log file Handles.
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070069 """
Jon Hall714eeba2015-09-29 17:53:10 -070070 def __init__( self, options ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070071 """
Jon Hall714eeba2015-09-29 17:53:10 -070072 Initialise the component handles specified in the topology file of
73 the specified test.
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070074 """
adminbae64d82013-08-01 10:50:15 -070075 # Initialization of the variables.
76 __builtin__.main = self
adminbae64d82013-08-01 10:50:15 -070077 __builtin__.path = path
78 __builtin__.utilities = Utilities()
79 self.TRUE = 1
80 self.FALSE = 0
81 self.ERROR = -1
kelvin-onlabf70fd542015-05-07 18:41:40 -070082 self.NORESULT = 2
adminbae64d82013-08-01 10:50:15 -070083 self.FAIL = False
84 self.PASS = True
kelvin-onlabf70fd542015-05-07 18:41:40 -070085 self.CASERESULT = self.ERROR
86 self.STEPRESULT = self.NORESULT
adminbae64d82013-08-01 10:50:15 -070087 self.init_result = self.TRUE
88 self.testResult = "Summary"
kelvin-onlabf70fd542015-05-07 18:41:40 -070089 self.stepName = ""
90 self.stepCache = ""
Jon Halld61331b2015-02-17 16:35:47 -080091 self.EXPERIMENTAL_MODE = False
adminbae64d82013-08-01 10:50:15 -070092 self.test_target = None
93 self.lastcommand = None
Jon Halld61331b2015-02-17 16:35:47 -080094 self.testDir = tests_path
95 self.configFile = config_path + "teston.cfg"
adminbae64d82013-08-01 10:50:15 -070096 self.parsingClass = "xmlparser"
97 self.parserPath = core_path + "/xmlparser"
98 self.loggerPath = core_path + "/logger"
99 self.loggerClass = "Logger"
100 self.logs_path = logs_path
101 self.driver = ''
kelvin-onlabfb521662015-02-27 09:52:40 -0800102 self.Thread = Thread
Jon Hall5b586732015-06-11 11:39:39 -0700103 self.cleanupFlag = False
104 self.cleanupLock = threading.Lock()
Jon Hall0fc0d452015-07-14 09:49:58 -0700105 self.initiated = False
Devin Limec989792017-08-15 15:57:55 -0700106 self.executedCase = []
107 self.leftCase = []
108 self.failedCase = []
109 self.noResultCase = []
Jon Hall65844a32015-03-09 19:09:37 -0700110
Jon Hall25079782015-10-13 13:54:39 -0700111 self.config = self.configparser()
Jon Hall714eeba2015-09-29 17:53:10 -0700112 verifyOptions( options )
adminbae64d82013-08-01 10:50:15 -0700113 load_logger()
114 self.componentDictionary = {}
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700115 self.componentDictionary = self.topology[ 'COMPONENT' ]
Jon Hall714eeba2015-09-29 17:53:10 -0700116 self.driversList = []
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700117 if isinstance( self.componentDictionary, str ):
Jon Hall714eeba2015-09-29 17:53:10 -0700118 self.componentDictionary = dict( self.componentDictionary )
Jon Hall65844a32015-03-09 19:09:37 -0700119
Jon Hall714eeba2015-09-29 17:53:10 -0700120 for component in self.componentDictionary:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700121 self.driversList.append( self.componentDictionary[ component ][ 'type' ] )
Jon Hall65844a32015-03-09 19:09:37 -0700122
Jon Hall714eeba2015-09-29 17:53:10 -0700123 self.driversList = list( set( self.driversList ) ) # Removing duplicates.
adminbae64d82013-08-01 10:50:15 -0700124 # Checking the test_target option set for the component or not
Jon Hall714eeba2015-09-29 17:53:10 -0700125 if isinstance( self.componentDictionary, dict ):
adminbae64d82013-08-01 10:50:15 -0700126 for component in self.componentDictionary.keys():
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700127 if 'test_target' in self.componentDictionary[ component ].keys():
adminbae64d82013-08-01 10:50:15 -0700128 self.test_target = component
Jon Hall65844a32015-03-09 19:09:37 -0700129
Jon Halld61331b2015-02-17 16:35:47 -0800130 # Checking for the openspeak file and test script
Jon Hall714eeba2015-09-29 17:53:10 -0700131 self.logger.initlog( self )
adminbae64d82013-08-01 10:50:15 -0700132
133 # Creating Drivers Handles
Jon Hall714eeba2015-09-29 17:53:10 -0700134 initString = "\n" + "*" * 30 + "\n CASE INIT \n" + "*" * 30 + "\n"
135 self.log.exact( initString )
adminbae64d82013-08-01 10:50:15 -0700136 self.driverObject = {}
Jon Hall714eeba2015-09-29 17:53:10 -0700137 self.random_order = 111 # Random order id to connect the components
adminbae64d82013-08-01 10:50:15 -0700138 components_connect_order = {}
Jon Hall714eeba2015-09-29 17:53:10 -0700139 if isinstance( self.componentDictionary, dict ):
adminbae64d82013-08-01 10:50:15 -0700140 for component in self.componentDictionary.keys():
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700141 if 'connect_order' not in self.componentDictionary[ component ].keys():
142 self.componentDictionary[ component ][ 'connect_order' ] = str( self.get_random() )
143 components_connect_order[ component ] = eval( self.componentDictionary[ component ][ 'connect_order' ] )
Jon Hall714eeba2015-09-29 17:53:10 -0700144 # Ordering components based on the connect order.
145 ordered_component_list = sorted( components_connect_order,
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700146 key=lambda key: components_connect_order[ key ] )
adminbae64d82013-08-01 10:50:15 -0700147 print ordered_component_list
adminbae64d82013-08-01 10:50:15 -0700148 for component in ordered_component_list:
Jon Hall714eeba2015-09-29 17:53:10 -0700149 self.componentInit( component )
adminbae64d82013-08-01 10:50:15 -0700150
Jon Hall714eeba2015-09-29 17:53:10 -0700151 def configparser( self ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700152 """
153 It will parse the config file ( teston.cfg ) and return as dictionary
154 """
Jon Hall714eeba2015-09-29 17:53:10 -0700155 matchFileName = re.match( r'(.*)\.cfg', self.configFile, re.M | re.I )
adminbae64d82013-08-01 10:50:15 -0700156 if matchFileName:
Jon Hall714eeba2015-09-29 17:53:10 -0700157 xml = open( self.configFile ).read()
158 try:
159 self.configDict = xmldict.xml_to_dict( xml )
adminbae64d82013-08-01 10:50:15 -0700160 return self.configDict
Jon Hall1306a562015-09-04 11:21:24 -0700161 except IOError:
adminbae64d82013-08-01 10:50:15 -0700162 print "There is no such file to parse " + self.configFile
Jon Hall1306a562015-09-04 11:21:24 -0700163 else:
164 print "There is no such file to parse " + self.configFile
kelvin-onlabf70fd542015-05-07 18:41:40 -0700165
Jon Hall714eeba2015-09-29 17:53:10 -0700166 def componentInit( self, component ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700167 """
adminbae64d82013-08-01 10:50:15 -0700168 This method will initialize specified component
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700169 """
adminbae64d82013-08-01 10:50:15 -0700170 global driver_options
Jon Hall0fc0d452015-07-14 09:49:58 -0700171 self.initiated = False
Jon Hall714eeba2015-09-29 17:53:10 -0700172 self.log.info( "Creating component Handle: " + component )
Jon Halld61331b2015-02-17 16:35:47 -0800173 driver_options = {}
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700174 if 'COMPONENTS' in self.componentDictionary[ component ].keys():
175 driver_options = dict( self.componentDictionary[ component ][ 'COMPONENTS' ] )
176 driver_options[ 'name' ] = component
177 driverName = self.componentDictionary[ component ][ 'type' ]
178 driver_options[ 'type' ] = driverName
kelvin-onlabf70fd542015-05-07 18:41:40 -0700179
Jon Hall714eeba2015-09-29 17:53:10 -0700180 classPath = self.getDriverPath( driverName.lower() )
181 driverModule = importlib.import_module( classPath )
182 driverClass = getattr( driverModule, driverName )
adminbae64d82013-08-01 10:50:15 -0700183 driverObject = driverClass()
kelvin-onlabf70fd542015-05-07 18:41:40 -0700184
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700185 if "OCN" in self.componentDictionary[ component ][ 'host' ] and\
Jon Hall714eeba2015-09-29 17:53:10 -0700186 main.onoscell:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700187 self.componentDictionary[ component ][ 'host' ] = main.mnIP
Hari Krishnabe4b97b2015-07-15 12:19:43 -0700188
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700189 user_name = self.componentDictionary[ component ].get( 'user',
190 getpass.getuser() )
191 ip_address = self.componentDictionary[ component ].get( 'host',
192 'localhost' )
193 pwd = self.componentDictionary[ component ].get( 'password',
194 'changeme' )
195 port = self.componentDictionary[ component ].get( 'port' )
Jon Hall714eeba2015-09-29 17:53:10 -0700196 connect_result = driverObject.connect( user_name=user_name,
197 ip_address=ip_address,
198 pwd=pwd,
199 port=port,
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700200 options=driver_options )
cameron@onlab.us5cc6a372015-05-11 17:18:07 -0700201
adminbae64d82013-08-01 10:50:15 -0700202 if not connect_result:
Jon Hall714eeba2015-09-29 17:53:10 -0700203 self.log.error( "Exiting from the test execution because connecting to the " +
204 component + " component failed." )
Jon Halld61331b2015-02-17 16:35:47 -0800205 self.exit()
kelvin-onlabf70fd542015-05-07 18:41:40 -0700206
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700207 vars( self )[ component ] = driverObject
Jon Hall0fc0d452015-07-14 09:49:58 -0700208 self.initiated = True
Jon Hallca319892017-06-15 15:25:22 -0700209 return driverObject
kelvin-onlabf70fd542015-05-07 18:41:40 -0700210
Jon Hall714eeba2015-09-29 17:53:10 -0700211 def run( self ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700212 """
Jon Hall714eeba2015-09-29 17:53:10 -0700213 The Execution of the test script's cases listed in the Test params
214 file will be done here then update each test case result.
215 This method will return main.TRUE if it executed all the test cases
216 successfully, else will retun main.FALSE
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700217 """
adminbae64d82013-08-01 10:50:15 -0700218 self.testCaseResult = {}
Jon Halla1185982014-09-15 14:55:10 -0700219 self.TOTAL_TC = 0
adminbae64d82013-08-01 10:50:15 -0700220 self.TOTAL_TC_RUN = 0
Jon Halld61331b2015-02-17 16:35:47 -0800221 self.TOTAL_TC_PLANNED = 0
adminbae64d82013-08-01 10:50:15 -0700222 self.TOTAL_TC_NORESULT = 0
223 self.TOTAL_TC_FAIL = 0
224 self.TOTAL_TC_PASS = 0
Jon Halla1185982014-09-15 14:55:10 -0700225 self.TEST_ITERATION = 0
Jon Hall714eeba2015-09-29 17:53:10 -0700226
227 # NOTE: number of main.step statements in the
228 # outer most level of the test case. used to
229 # execute code in smaller steps
230 self.stepCount = 0
kelvin-onlabf70fd542015-05-07 18:41:40 -0700231 self.CASERESULT = self.NORESULT
232
Jon Halld61331b2015-02-17 16:35:47 -0800233 import testparser
Jon Hall53c5e662016-04-13 16:06:56 -0700234 test = testparser.TestParser( main.testFile )
adminbae64d82013-08-01 10:50:15 -0700235 self.testscript = test.testscript
236 self.code = test.getStepCode()
Jon Hall714eeba2015-09-29 17:53:10 -0700237 repeat = int( self.params.get( 'repeat', 1 ) )
238 self.TOTAL_TC_PLANNED = len( self.testcases_list ) * repeat
kelvin-onlabf70fd542015-05-07 18:41:40 -0700239
adminbae64d82013-08-01 10:50:15 -0700240 result = self.TRUE
Jon Hall714eeba2015-09-29 17:53:10 -0700241 while repeat:
Devin Limec989792017-08-15 15:57:55 -0700242 self.leftCase.extend( self.testcases_list )
Jon Halla1185982014-09-15 14:55:10 -0700243 for self.CurrentTestCaseNumber in self.testcases_list:
Devin Limec989792017-08-15 15:57:55 -0700244 self.executedCase.append( self.leftCase.pop( 0 ) )
Jon Hall714eeba2015-09-29 17:53:10 -0700245 result = self.runCase( self.CurrentTestCaseNumber )
246 repeat -= 1
adminbae64d82013-08-01 10:50:15 -0700247 return result
kelvin-onlabf70fd542015-05-07 18:41:40 -0700248
Jon Halle234cc42015-08-31 15:26:47 -0700249 def runCase( self, testCaseNumber ):
adminbae64d82013-08-01 10:50:15 -0700250 self.CurrentTestCaseNumber = testCaseNumber
kelvin-onlabf70fd542015-05-07 18:41:40 -0700251 self.CurrentTestCase = ""
Jon Hall714eeba2015-09-29 17:53:10 -0700252
253 # List of step results in a case. ANDed together to get the result
254 self.stepResultsList = []
kelvin-onlabf70fd542015-05-07 18:41:40 -0700255 self.stepName = ""
Jon Hall783bbf92015-07-23 14:33:19 -0700256 self.caseExplanation = ""
adminbae64d82013-08-01 10:50:15 -0700257 result = self.TRUE
Jon Hall714eeba2015-09-29 17:53:10 -0700258
259 # NOTE: number of main.step statements in the
260 # outer most level of the test case. used to
261 # execute code in smaller steps
262 self.stepCount = 0
263
264 # NOTE: This is the current number of main.step()'s executed
265 # in a case. Used for logging.
266 self.stepNumber = 0
adminbae64d82013-08-01 10:50:15 -0700267 self.EXPERIMENTAL_MODE = self.FALSE
268 self.addCaseHeader()
Devin Limec989792017-08-15 15:57:55 -0700269 self.log.debug( "Case Executed : " + str( self.executedCase ) )
270 self.log.debug( "Case to be executed : " + str( self.leftCase ) )
Jon Halle234cc42015-08-31 15:26:47 -0700271 self.testCaseNumber = str( testCaseNumber )
272 self.CASERESULT = self.NORESULT
adminbae64d82013-08-01 10:50:15 -0700273 stopped = False
Jon Hall5a72b712015-09-28 12:20:59 -0700274 try:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700275 self.code[ self.testCaseNumber ]
Jon Halld61331b2015-02-17 16:35:47 -0800276 except KeyError:
Jon Halle234cc42015-08-31 15:26:47 -0700277 self.log.error( "There is no Test-Case " + self.testCaseNumber )
Jon Hallfebb1c72015-03-05 13:30:09 -0800278 return self.FALSE
adminbae64d82013-08-01 10:50:15 -0700279 self.stepCount = 0
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700280 while self.stepCount < len( self.code[ self.testCaseNumber ].keys() ):
Jon Hall714eeba2015-09-29 17:53:10 -0700281 result = self.runStep( self.code, self.testCaseNumber )
Jon Hallfebb1c72015-03-05 13:30:09 -0800282 if result == self.FALSE:
adminbae64d82013-08-01 10:50:15 -0700283 break
Jon Hallfebb1c72015-03-05 13:30:09 -0800284 elif result == self.TRUE:
adminbae64d82013-08-01 10:50:15 -0700285 continue
Jon Hall5a72b712015-09-28 12:20:59 -0700286 # stepResults format: ( stepNo[], stepName[], stepResult[], onFail[] )
287 stepResults = self.stepResultsList
Jon Halle234cc42015-08-31 15:26:47 -0700288 if not stopped:
289 if self.CASERESULT == self.TRUE or self.CASERESULT == self.FALSE:
Jon Hall714eeba2015-09-29 17:53:10 -0700290 # Result was already explitily set somewhere else like
291 # in skipCase()
Jon Halle234cc42015-08-31 15:26:47 -0700292 pass
Jon Hall5a72b712015-09-28 12:20:59 -0700293 elif all( self.TRUE == i for i in stepResults ):
kelvin-onlabf70fd542015-05-07 18:41:40 -0700294 # ALL PASSED
295 self.CASERESULT = self.TRUE
Jon Hall5a72b712015-09-28 12:20:59 -0700296 elif self.FALSE in stepResults:
kelvin-onlabf70fd542015-05-07 18:41:40 -0700297 # AT LEAST ONE FAILED
298 self.CASERESULT = self.FALSE
Jon Hall5a72b712015-09-28 12:20:59 -0700299 elif self.TRUE in stepResults:
kelvin-onlabf70fd542015-05-07 18:41:40 -0700300 # AT LEAST ONE PASSED
301 self.CASERESULT = self.TRUE
302 else:
303 self.CASERESULT = self.NORESULT
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700304 self.testCaseResult[ str( self.CurrentTestCaseNumber ) ] = self.CASERESULT
Devin Limec989792017-08-15 15:57:55 -0700305 self.organizeResult( self.CurrentTestCaseNumber, self.CASERESULT )
Jon Hall714eeba2015-09-29 17:53:10 -0700306 self.logger.updateCaseResults( self )
Jon Hall783bbf92015-07-23 14:33:19 -0700307 self.log.wiki( "<p>" + self.caseExplanation + "</p>" )
308 self.log.summary( self.caseExplanation )
kelvin-onlabf70fd542015-05-07 18:41:40 -0700309 self.log.wiki( "<ul>" )
acsmarse2d1ed12015-10-05 13:51:17 -0700310 subcaseMessage = False
kelvin-onlabf70fd542015-05-07 18:41:40 -0700311 for line in self.stepCache.splitlines():
acsmarse2d1ed12015-10-05 13:51:17 -0700312 if re.search( "[0-9]\.[0-9]", line ): # Step
313 if subcaseMessage: # End of Failure Message Printout
314 self.log.wiki( "</ul>\n" )
315 subcaseMessage = False
316 if re.search( " - PASS$", line ):
317 self.log.wiki( "<li>" + line + " <ac:emoticon ac:name=\"tick\" /></li>\n" )
318 elif re.search( " - FAIL$", line ):
319 self.log.wiki( "<li>" + line + " <ac:emoticon ac:name=\"cross\" /></li>\n" )
320 elif re.search( " - No Result$", line ):
321 self.log.wiki( "<li>" + line + " <ac:emoticon ac:name=\"warning\" /></li>\n" )
322 else: # Substep
323 if not subcaseMessage: # Open Failure Message Printout
324 self.log.wiki( "<ul><li>" + line + "</li>\n" )
325 subcaseMessage = True
326 else: # Add to Failure Message Printout
327 self.log.wiki( "<li>" + line + "</li>\n" )
acsmars27e62dd2015-10-06 11:35:47 -0700328 if subcaseMessage: # End of Failure Message Printout for last item
329 self.log.wiki( "</ul>\n" )
kelvin-onlabf70fd542015-05-07 18:41:40 -0700330 self.log.wiki( "</ul>" )
331 self.log.summary( self.stepCache )
332 self.stepCache = ""
adminbae64d82013-08-01 10:50:15 -0700333 return result
kelvin-onlabf70fd542015-05-07 18:41:40 -0700334
Devin Limec989792017-08-15 15:57:55 -0700335 def organizeResult( self, caseNum, result ):
336 """
337 Organize the result and put the current number into either
338 failed/noResult lists.
339 * caseNum - number of the case
340 * result - result of the case
341 """
342 if result == main.FALSE:
343 self.failedCase.append( caseNum )
344 elif result == self.NORESULT:
345 self.noResultCase.append( caseNum )
346
Jon Hall714eeba2015-09-29 17:53:10 -0700347 def runStep( self, code, testCaseNumber ):
adminbae64d82013-08-01 10:50:15 -0700348 if not cli.pause:
Jon Hall5a72b712015-09-28 12:20:59 -0700349 try:
350 step = self.stepCount
351 # stepResults format: ( stepNo, stepName, stepResult, onFail )
352 # NOTE: This is needed to catch results of main.step()'s
353 # called inside functions or loops
354 self.stepResults = ( [], [], [], [] )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700355 exec code[ testCaseNumber ][ step ] in module.__dict__
adminbae64d82013-08-01 10:50:15 -0700356 self.stepCount = self.stepCount + 1
Jon Hall96b816f2015-11-03 12:00:56 -0800357 self.parseStepResults( testCaseNumber )
Jon Hallca319892017-06-15 15:25:22 -0700358 except SkipCase: # Raised in self.skipCase()
Jon Halle234cc42015-08-31 15:26:47 -0700359 self.log.warn( "Skipping the rest of CASE" +
360 str( testCaseNumber ) )
Jon Hall96b816f2015-11-03 12:00:56 -0800361 self.parseStepResults( testCaseNumber )
Jon Hall714eeba2015-09-29 17:53:10 -0700362 self.stepResultsList.append( self.STEPRESULT )
Jon Halle234cc42015-08-31 15:26:47 -0700363 self.stepCache += "\t\t" + self.onFailMsg + "\n"
364 self.stepCount = self.stepCount + 1
365 return self.FALSE
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700366 except Exception as e:
Jon Hallc1606352015-10-06 14:51:36 -0700367 try:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700368 stepNo = self.stepResults[ 0 ][ self.stepNumber - 1 ]
Jon Hallc1606352015-10-06 14:51:36 -0700369 except IndexError:
370 stepNo = "<IndexError>"
371 main.log.warn( "Error trying to get step number. " +
372 "It is likely between step " +
Jon Hall6e709752016-02-01 13:38:46 -0800373 str( self.stepNumber ) + " and step " +
Jon Hallc1606352015-10-06 14:51:36 -0700374 str( self.stepNumber + 1 ) )
375 try:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700376 stepName = self.stepResults[ 1 ][ self.stepNumber - 1 ]
Jon Hallc1606352015-10-06 14:51:36 -0700377 except IndexError:
378 stepName = "<IndexError>"
379 self.log.error( "\nException in the following section of" +
380 " code: " + str( testCaseNumber ) + "." +
381 str( stepNo ) + ": " + stepName )
Jeremyd9e4eb12016-04-13 12:09:06 -0700382 self.log.error( str( e.__class__ ) + str( e.message ) )
adminbae64d82013-08-01 10:50:15 -0700383 self.stepCount = self.stepCount + 1
Jon Hall714eeba2015-09-29 17:53:10 -0700384 self.logger.updateCaseResults( self )
385 # WIKI results
kelvin-onlabf70fd542015-05-07 18:41:40 -0700386 self.log.wiki( "<ul>" )
387 for line in self.stepCache.splitlines():
388 if re.search( " - PASS$", line ):
389 self.log.wiki( "<li>" + line + " <ac:emoticon ac:name=\"tick\" /></li>\n" )
390 elif re.search( " - FAIL$", line ):
391 self.log.wiki( "<li>" + line + " <ac:emoticon ac:name=\"cross\" /></li>\n" )
392 elif re.search( " - No Result$", line ):
393 self.log.wiki( "<li>" + line + " <ac:emoticon ac:name=\"warning\" /></li>\n" )
Jon Hall90627612015-06-09 14:57:02 -0700394 else: # Should only be on fail message
395 self.log.wiki( "<ul><li>" + line + "</li></ul>\n" )
kelvin-onlabf70fd542015-05-07 18:41:40 -0700396 self.log.wiki( "</ul>" )
Jon Hall714eeba2015-09-29 17:53:10 -0700397 # summary results
kelvin-onlabf70fd542015-05-07 18:41:40 -0700398 self.log.summary( self.stepCache )
399 self.stepCache = ""
shahshreya957feaa2015-03-23 16:08:29 -0700400 self.cleanup()
Jon Hall00539b12015-04-03 13:55:46 -0700401 self.exit()
Jon Halle234cc42015-08-31 15:26:47 -0700402 return self.TRUE
adminbae64d82013-08-01 10:50:15 -0700403 if cli.stop:
404 cli.stop = False
adminbae64d82013-08-01 10:50:15 -0700405 self.TOTAL_TC_NORESULT = self.TOTAL_TC_NORESULT + 1
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700406 self.testCaseResult[ str( self.CurrentTestCaseNumber ) ] = "Stopped"
Jon Hall714eeba2015-09-29 17:53:10 -0700407 self.logger.updateCaseResults( self )
adminbae64d82013-08-01 10:50:15 -0700408 result = self.cleanup()
Jon Halle234cc42015-08-31 15:26:47 -0700409 return self.FALSE
410
Jon Hall96b816f2015-11-03 12:00:56 -0800411 def parseStepResults( self, testCaseNumber ):
412 """
413 Parse throught the step results for the wiki
414 """
415 try:
416 # Iterate through each of the steps and print them
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700417 for index in range( len( self.stepResults[ 0 ] ) ):
Jon Hall96b816f2015-11-03 12:00:56 -0800418 # stepResults = ( stepNo, stepName, stepResult, onFail )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700419 stepNo = self.stepResults[ 0 ][ index ]
420 stepName = self.stepResults[ 1 ][ index ]
421 stepResult = self.stepResults[ 2 ][ index ]
422 onFail = self.stepResults[ 3 ][ index ]
Jon Hall96b816f2015-11-03 12:00:56 -0800423 self.stepCache += "\t" + str( testCaseNumber ) + "."
424 self.stepCache += str( stepNo ) + " "
425 self.stepCache += stepName + " - "
426 if stepResult == self.TRUE:
427 self.stepCache += "PASS\n"
428 elif stepResult == self.FALSE:
429 self.stepCache += "FAIL\n"
430 self.stepCache += "\t\t" + onFail + "\n"
431 else:
432 self.stepCache += "No Result\n"
433 self.stepResultsList.append( stepResult )
434 except Exception:
435 self.log.exception( "Error parsing step results" )
436
Jon Halle234cc42015-08-31 15:26:47 -0700437 def skipCase( self, result="DEFAULT", msg=None ):
438 """
439 Will skip the rest of the code in a test case. The case results will be
440 determined as normal based on completed assertions unless the result
441 argument is given.
442
443 Optional Arguments:
Jon Hall7c4f4302016-07-15 14:39:02 -0700444 result: Case insensitive string. Can be 'PASS' or 'FAIL' and will set
Jon Halle234cc42015-08-31 15:26:47 -0700445 the case result accordingly.
446 msg: Message to be printed when the case is skipped in the reports.
447 """
448 result = result.upper().strip()
449 if result == "PASS":
450 self.CASERESULT = self.TRUE
451 elif result == "FAIL":
452 self.CASERESULT = self.FALSE
453 self.onFailMsg = "Skipping the rest of this case. "
454 if msg:
455 self.onFailMsg += str( msg )
Jon Hallca319892017-06-15 15:25:22 -0700456 raise SkipCase
kelvin-onlabf70fd542015-05-07 18:41:40 -0700457
Jon Hall714eeba2015-09-29 17:53:10 -0700458 def addCaseHeader( self ):
459 caseHeader = "\n" + "*" * 30 + "\n Result summary for Testcase" +\
460 str( self.CurrentTestCaseNumber ) + "\n" + "*" * 30 + "\n"
461 self.log.exact( caseHeader )
462 caseHeader = "\n" + "*" * 40 + "\nStart of Test Case" +\
463 str( self.CurrentTestCaseNumber ) + " : "
adminbae64d82013-08-01 10:50:15 -0700464 for driver in self.componentDictionary.keys():
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700465 vars( self )[ driver + 'log' ].info( caseHeader )
kelvin-onlabf70fd542015-05-07 18:41:40 -0700466
Jon Hall714eeba2015-09-29 17:53:10 -0700467 def addCaseFooter( self ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700468 stepNo = self.stepResults[ 0 ][ -2 ]
Jon Hall714eeba2015-09-29 17:53:10 -0700469 if stepNo > 0:
470 previousStep = " " + str( self.CurrentTestCaseNumber ) + "." +\
471 str( stepNo ) + ": " + str( self.stepName )
472 stepHeader = "\n" + "*" * 40 + "\nEnd of Step " + previousStep +\
473 "\n" + "*" * 40 + "\n"
kelvin-onlabf70fd542015-05-07 18:41:40 -0700474
Jon Hall714eeba2015-09-29 17:53:10 -0700475 caseFooter = "\n" + "*" * 40 + "\nEnd of Test case " +\
476 str( self.CurrentTestCaseNumber ) + "\n" + "*" * 40 + "\n"
kelvin-onlabf70fd542015-05-07 18:41:40 -0700477
adminbae64d82013-08-01 10:50:15 -0700478 for driver in self.driversList:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700479 vars( self )[ driver ].write( stepHeader + "\n" + caseFooter )
adminbae64d82013-08-01 10:50:15 -0700480
Jon Hall714eeba2015-09-29 17:53:10 -0700481 def cleanup( self ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700482 """
Jon Hall5b586732015-06-11 11:39:39 -0700483 Print a summary of the current test's results then attempt to release
484 all the component handles and the close opened file handles.
adminbae64d82013-08-01 10:50:15 -0700485
Jon Hall5b586732015-06-11 11:39:39 -0700486 This function shouldbe threadsafe such that cleanup will only be
487 executed once per test.
488
489 This will return TRUE if all the component handles and log handles
490 closed properly, else return FALSE.
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700491 """
adminbae64d82013-08-01 10:50:15 -0700492 result = self.TRUE
Jon Hall5b586732015-06-11 11:39:39 -0700493 lock = self.cleanupLock
494 if lock.acquire( False ):
495 try:
496 if self.cleanupFlag is False: # First thread to run this
497 self.cleanupFlag = True
Jon Hall0fc0d452015-07-14 09:49:58 -0700498 if self.initiated:
Jon Hall714eeba2015-09-29 17:53:10 -0700499 self.logger.testSummary( self )
Jon Hall892818c2015-10-20 17:58:34 -0700500 components = self.componentDictionary
501 for component in sorted( components,
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700502 key=lambda item: components[ item ][ 'connect_order' ],
Jon Hall892818c2015-10-20 17:58:34 -0700503 reverse=True ):
Jon Hall714eeba2015-09-29 17:53:10 -0700504 try:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700505 tempObject = vars( self )[ component ]
Jon Hall714eeba2015-09-29 17:53:10 -0700506 print "Disconnecting from " + str( tempObject.name ) +\
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700507 ": " + str( tempObject.__class__ )
Jon Hall5b586732015-06-11 11:39:39 -0700508 tempObject.disconnect()
Jon Hall1306a562015-09-04 11:21:24 -0700509 except KeyboardInterrupt:
510 pass
511 except KeyError:
512 # Component not created yet
513 self.log.warn( "Could not find the component " +
514 str( component ) )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700515 except Exception:
Jon Hall5b586732015-06-11 11:39:39 -0700516 self.log.exception( "Exception while disconnecting from " +
517 str( component ) )
518 result = self.FALSE
519 # Closing all the driver's session files
520 for driver in self.componentDictionary.keys():
521 try:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700522 vars( self )[ driver ].close_log_handles()
Jon Hall1306a562015-09-04 11:21:24 -0700523 except KeyboardInterrupt:
524 pass
525 except KeyError:
526 # Component not created yet
527 self.log.warn( "Could not find the component " +
528 str( driver ) + " while trying to" +
529 " close log file" )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700530 except Exception:
Jon Hall5b586732015-06-11 11:39:39 -0700531 self.log.exception( "Exception while closing log files for " +
532 str( driver ) )
533 result = self.FALSE
534 else:
535 pass # Someone else already ran through this function
536 finally:
537 lock.release()
538 else: # Someone already has a lock
539 # NOTE: This could cause problems if we don't release the lock
540 # correctly
541 lock.acquire() # Wait for the other thread to finish
542 # NOTE: If we don't wait, exit could be called while the thread
543 # with the lock is still cleaning up
544 lock.release()
adminbae64d82013-08-01 10:50:15 -0700545 return result
Jon Halld61331b2015-02-17 16:35:47 -0800546
Jon Hall714eeba2015-09-29 17:53:10 -0700547 def pause( self ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700548 """
Jon Hall714eeba2015-09-29 17:53:10 -0700549 This function will pause the test's execution, and will continue after
550 user provide 'resume' command.
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700551 """
adminbae64d82013-08-01 10:50:15 -0700552 __builtin__.testthread.pause()
kelvin-onlabf70fd542015-05-07 18:41:40 -0700553
Jon Hall714eeba2015-09-29 17:53:10 -0700554 def onfail( self, *components ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700555 """
kelvin-onlabf70fd542015-05-07 18:41:40 -0700556 When test step failed, calling all the components onfail.
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700557 """
adminbae64d82013-08-01 10:50:15 -0700558 if not components:
Jon Hall714eeba2015-09-29 17:53:10 -0700559 try:
adminbae64d82013-08-01 10:50:15 -0700560 for component in self.componentDictionary.keys():
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700561 tempObject = vars( self )[ component ]
adminbae64d82013-08-01 10:50:15 -0700562 result = tempObject.onfail()
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700563 except Exception as e:
Jon Hall714eeba2015-09-29 17:53:10 -0700564 print str( e )
adminbae64d82013-08-01 10:50:15 -0700565 result = self.FALSE
adminbae64d82013-08-01 10:50:15 -0700566 else:
Jon Hall714eeba2015-09-29 17:53:10 -0700567 try:
adminbae64d82013-08-01 10:50:15 -0700568 for component in components:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700569 tempObject = vars( self )[ component ]
adminbae64d82013-08-01 10:50:15 -0700570 result = tempObject.onfail()
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700571 except Exception as e:
Jon Hall714eeba2015-09-29 17:53:10 -0700572 print str( e )
adminbae64d82013-08-01 10:50:15 -0700573 result = self.FALSE
kelvin-onlabf70fd542015-05-07 18:41:40 -0700574
Jon Hall714eeba2015-09-29 17:53:10 -0700575 def getDriverPath( self, driverName ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700576 """
Jon Hall714eeba2015-09-29 17:53:10 -0700577 Based on the component 'type' specified in the params , this method
578 will find the absolute path, by recursively searching the name of
579 the component.
580
581 NOTE: This function requires the linux 'find' command.
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700582 """
adminbae64d82013-08-01 10:50:15 -0700583 import commands
584
Jon Hall714eeba2015-09-29 17:53:10 -0700585 cmd = "find " + drivers_path + " -name " + driverName + ".py"
586 result = commands.getoutput( cmd )
kelvin-onlabf70fd542015-05-07 18:41:40 -0700587
Jon Hall714eeba2015-09-29 17:53:10 -0700588 result_array = str( result ).split( '\n' )
adminbae64d82013-08-01 10:50:15 -0700589 result_count = 0
kelvin-onlabf70fd542015-05-07 18:41:40 -0700590
adminbae64d82013-08-01 10:50:15 -0700591 for drivers_list in result_array:
Jon Hall714eeba2015-09-29 17:53:10 -0700592 result_count = result_count + 1
593 if result_count > 1:
594 print "Found " + driverName + " " + str( result_count ) + " times:"
595 print str( result_array )
adminbae64d82013-08-01 10:50:15 -0700596 self.exit()
kelvin-onlabf70fd542015-05-07 18:41:40 -0700597
Jon Hall714eeba2015-09-29 17:53:10 -0700598 result = re.sub( "(.*)drivers", "", result )
599 result = re.sub( "\/\/", "/", result )
600 result = re.sub( "\.py", "", result )
601 result = re.sub( "\.pyc", "", result )
602 result = re.sub( "\/", ".", result )
603 result = "drivers" + result
adminbae64d82013-08-01 10:50:15 -0700604 return result
adminbae64d82013-08-01 10:50:15 -0700605
Jon Hall714eeba2015-09-29 17:53:10 -0700606 def step( self, stepDesc ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700607 """
adminbae64d82013-08-01 10:50:15 -0700608 The step information of the test-case will append to the logs.
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700609 """
Jon Hall714eeba2015-09-29 17:53:10 -0700610 previousStep = " " + str( self.CurrentTestCaseNumber ) + "." +\
611 str( self.stepNumber ) + ": " + str( self.stepName )
adminbae64d82013-08-01 10:50:15 -0700612 self.stepName = stepDesc
Jon Hall5a72b712015-09-28 12:20:59 -0700613 self.stepNumber += 1
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700614 self.stepResults[ 0 ].append( self.stepNumber )
615 self.stepResults[ 1 ].append( stepDesc )
616 self.stepResults[ 2 ].append( self.NORESULT )
617 self.stepResults[ 3 ].append( "No on fail message given" )
adminbae64d82013-08-01 10:50:15 -0700618
Jon Hall714eeba2015-09-29 17:53:10 -0700619 stepName = " " + str( self.CurrentTestCaseNumber ) + "." +\
620 str( self.stepNumber ) + ": " + str( stepDesc )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700621 self.log.step( stepName )
adminbae64d82013-08-01 10:50:15 -0700622 stepHeader = ""
Jon Hall714eeba2015-09-29 17:53:10 -0700623 line = "\n" + "-" * 45 + "\n"
624 if self.stepNumber > 1:
625 stepHeader = line + "End of Step " + previousStep + line
626 stepHeader += line + "Start of Step" + stepName + line
adminbae64d82013-08-01 10:50:15 -0700627 for driver in self.componentDictionary.keys():
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700628 vars( self )[ driver + 'log' ].info( stepHeader )
kelvin-onlabf70fd542015-05-07 18:41:40 -0700629
Jon Hall714eeba2015-09-29 17:53:10 -0700630 def case( self, testCaseName ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700631 """
adminbae64d82013-08-01 10:50:15 -0700632 Test's each test-case information will append to the logs.
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700633 """
Jon Halld61331b2015-02-17 16:35:47 -0800634 self.CurrentTestCase = testCaseName
Jon Hall714eeba2015-09-29 17:53:10 -0700635 testCaseName = " " + str( testCaseName )
636 self.log.case( testCaseName )
637 caseHeader = testCaseName + "\n" + "*" * 40 + "\n"
adminbae64d82013-08-01 10:50:15 -0700638 for driver in self.componentDictionary.keys():
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700639 vars( self )[ driver + 'log' ].info( caseHeader )
kelvin-onlabf70fd542015-05-07 18:41:40 -0700640
Jon Hall714eeba2015-09-29 17:53:10 -0700641 def testDesc( self, description ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700642 """
adminbae64d82013-08-01 10:50:15 -0700643 Test description will append to the logs.
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700644 """
Jon Hall714eeba2015-09-29 17:53:10 -0700645 description = "Test Description : " + str( description )
646 self.log.info( description )
kelvin-onlabf70fd542015-05-07 18:41:40 -0700647
Jon Hall714eeba2015-09-29 17:53:10 -0700648 def _getTest( self ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700649 """
Jon Hall714eeba2015-09-29 17:53:10 -0700650 This method will parse the test script to find required test
651 information.
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700652 """
Jon Hall53c5e662016-04-13 16:06:56 -0700653 testFileHandler = open( main.testFile, 'r' )
adminbae64d82013-08-01 10:50:15 -0700654 testFileList = testFileHandler.readlines()
655 testFileHandler.close()
adminbae64d82013-08-01 10:50:15 -0700656 counter = 0
Jon Hall714eeba2015-09-29 17:53:10 -0700657 for index in range( len( testFileList ) ):
658 lineMatch = re.match( '\s+def CASE(\d+)(.*):',
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700659 testFileList[ index ],
Jon Hall714eeba2015-09-29 17:53:10 -0700660 0 )
adminbae64d82013-08-01 10:50:15 -0700661 if lineMatch:
Jon Hall714eeba2015-09-29 17:53:10 -0700662 counter = counter + 1
663 self.TC_PLANNED = len( self.testcases_list )
kelvin-onlabf70fd542015-05-07 18:41:40 -0700664
Jon Hall714eeba2015-09-29 17:53:10 -0700665 def response_parser( self, response, return_format ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700666 " It will load the default response parser "
adminbae64d82013-08-01 10:50:15 -0700667 response_dict = {}
Jon Hall714eeba2015-09-29 17:53:10 -0700668 response_dict = self.response_to_dict( response, return_format )
669 return_format_string = self.dict_to_return_format( response,
670 return_format,
671 response_dict )
adminbae64d82013-08-01 10:50:15 -0700672 return return_format_string
kelvin-onlabf70fd542015-05-07 18:41:40 -0700673
Jon Hall714eeba2015-09-29 17:53:10 -0700674 def response_to_dict( self, response, return_format ):
adminbae64d82013-08-01 10:50:15 -0700675 response_dict = {}
Jon Hall714eeba2015-09-29 17:53:10 -0700676 json_match = re.search( '^\s*{', response )
677 xml_match = re.search( '^\s*\<', response )
678 ini_match = re.search( '^\s*\[', response )
679 if json_match:
680 self.log.info( "Response is in 'JSON' format, converting to '" +
681 return_format + "' format" )
Jon Halld61331b2015-02-17 16:35:47 -0800682 # Formatting the json string
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700683 response = re.sub( r"{\s*'?(\w)", r'{ "\1', response )
Jon Hall714eeba2015-09-29 17:53:10 -0700684 response = re.sub( r",\s*'?(\w)", r',"\1', response )
685 response = re.sub( r"(\w)'?\s*:", r'\1":', response )
686 response = re.sub( r":\s*'(\w)'\s*([,}])", r':"\1"\2', response )
687 try:
adminbae64d82013-08-01 10:50:15 -0700688 import json
Jon Hall714eeba2015-09-29 17:53:10 -0700689 response_dict = json.loads( response )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700690 except Exception:
Jon Hall2a5002c2015-08-21 16:49:11 -0700691 self.log.exception( "Json Parser is unable to parse the string" )
adminbae64d82013-08-01 10:50:15 -0700692 return response_dict
Jon Hall714eeba2015-09-29 17:53:10 -0700693 elif ini_match:
694 self.log.info( "Response is in 'INI' format, converting to '" +
695 return_format + "' format" )
adminbae64d82013-08-01 10:50:15 -0700696 from configobj import ConfigObj
Jon Hall714eeba2015-09-29 17:53:10 -0700697 response_file = open( "respnse_file.temp", 'w' )
698 response_file.write( response )
Jon Halld61331b2015-02-17 16:35:47 -0800699 response_file.close()
Jon Hall714eeba2015-09-29 17:53:10 -0700700 response_dict = ConfigObj( "respnse_file.temp" )
adminbae64d82013-08-01 10:50:15 -0700701 return response_dict
Jon Hall714eeba2015-09-29 17:53:10 -0700702 elif xml_match:
703 self.log.info( "Response is in 'XML' format, converting to '" +
704 return_format + "' format" )
705 try:
706 response_dict = xmldict.xml_to_dict( "<response> " +
707 str( response ) +
708 " </response>" )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700709 except Exception:
Jon Hall1306a562015-09-04 11:21:24 -0700710 self.log.exception()
adminbae64d82013-08-01 10:50:15 -0700711 return response_dict
kelvin-onlabf70fd542015-05-07 18:41:40 -0700712
Jon Hall714eeba2015-09-29 17:53:10 -0700713 def dict_to_return_format( self, response, return_format, response_dict ):
714 if return_format == 'table':
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700715 " Will return in table format"
adminbae64d82013-08-01 10:50:15 -0700716 to_do = "Call the table output formatter"
717 global response_table
718 response_table = '\n'
Jon Hall714eeba2015-09-29 17:53:10 -0700719 response_table = response_table + '\t'.join( response_dict ) + "\n"
kelvin-onlabf70fd542015-05-07 18:41:40 -0700720
Jon Hall714eeba2015-09-29 17:53:10 -0700721 def get_table( value_to_convert ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700722 """ This will parse the dictionary recusrsively and print as
723 table format"""
adminbae64d82013-08-01 10:50:15 -0700724 table_data = ""
Jon Hall714eeba2015-09-29 17:53:10 -0700725 if isinstance( value_to_convert, dict ):
726 table_data = table_data + '\t'.join( value_to_convert ) +\
727 "\n"
728 for temp_val in value_to_convert.values():
729 table_data = table_data + get_table( temp_val )
730 else:
731 table_data = table_data + str( value_to_convert ) + "\t"
Jon Halld61331b2015-02-17 16:35:47 -0800732 return table_data
kelvin-onlabf70fd542015-05-07 18:41:40 -0700733
Jon Hall714eeba2015-09-29 17:53:10 -0700734 for value in response_dict.values():
735 response_table = response_table + get_table( value )
adminbae64d82013-08-01 10:50:15 -0700736 return response_table
kelvin-onlabf70fd542015-05-07 18:41:40 -0700737
Jon Hall714eeba2015-09-29 17:53:10 -0700738 elif return_format == 'config':
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700739 " Will return in config format"
adminbae64d82013-08-01 10:50:15 -0700740 to_do = 'Call dict to config coverter'
Jon Hall714eeba2015-09-29 17:53:10 -0700741 response_string = str( response_dict )
adminbae64d82013-08-01 10:50:15 -0700742 print response_string
Jon Hall714eeba2015-09-29 17:53:10 -0700743 response_config = re.sub( ",", "\n\t", response_string )
744 response_config = re.sub( "u\'", "\'", response_config )
745 response_config = re.sub( "{", "", response_config )
746 response_config = re.sub( "}", "\n", response_config )
747 response_config = re.sub( ":", " =", response_config )
748 return "[response]\n\t " + response_config
adminbae64d82013-08-01 10:50:15 -0700749 elif return_format == 'xml':
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700750 " Will return in xml format"
Jon Hall714eeba2015-09-29 17:53:10 -0700751 response_xml = xmldict.dict_to_xml( response_dict )
752 response_xml = re.sub( ">\s*<", ">\n<", response_xml )
753 return "\n" + response_xml
adminbae64d82013-08-01 10:50:15 -0700754 elif return_format == 'json':
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700755 " Will return in json format"
adminbae64d82013-08-01 10:50:15 -0700756 to_do = 'Call dict to xml coverter'
757 import json
Jon Hall714eeba2015-09-29 17:53:10 -0700758 response_json = json.dumps( response_dict )
adminbae64d82013-08-01 10:50:15 -0700759 return response_json
kelvin-onlabf70fd542015-05-07 18:41:40 -0700760
Jon Hall714eeba2015-09-29 17:53:10 -0700761 def get_random( self ):
adminbae64d82013-08-01 10:50:15 -0700762 self.random_order = self.random_order + 1
763 return self.random_order
kelvin-onlabf70fd542015-05-07 18:41:40 -0700764
Jon Hall714eeba2015-09-29 17:53:10 -0700765 def exit( self ):
adminbae64d82013-08-01 10:50:15 -0700766 __builtin__.testthread = None
Jon Hall5b586732015-06-11 11:39:39 -0700767 for thread in threading.enumerate():
768 if thread.isAlive():
769 try:
770 thread._Thread__stop()
771 except:
Jon Hall1306a562015-09-04 11:21:24 -0700772 # NOTE: We should catch any exceptions while trying to
773 # close the thread so that we can try to close the other
774 # threads as well
Jon Hall714eeba2015-09-29 17:53:10 -0700775 print str( thread.getName() ) +\
776 ' could not be terminated'
Jeremy Ronquillo15ff1072017-07-17 10:55:46 -0700777 os.system( "stty sane" ) # fix format if necessary
adminbae64d82013-08-01 10:50:15 -0700778 sys.exit()
779
Devin Lim44075962017-08-11 10:56:37 -0700780 def cleanAndExit( self ):
781 """
782 It will set the testcase result to be FAILED and update it
783 before cleaning up and exitting the test.
784 :return:
785 """
786 if self.CurrentTestCaseNumber:
787 self.testCaseResult[ str( self.CurrentTestCaseNumber ) ] = self.FALSE
Devin Limec989792017-08-15 15:57:55 -0700788 self.organizeResult( self.CurrentTestCaseNumber, self.FALSE )
Devin Lim44075962017-08-11 10:56:37 -0700789 self.logger.updateCaseResults( self )
790 self.cleanup()
791 self.exit()
Jeremy Ronquillo15ff1072017-07-17 10:55:46 -0700792
Jon Hallcd3d2a32015-10-01 11:07:28 -0700793 def stop( self, email=False ):
794 """
795 Stop the test until Ctrl-D is entered.
796 Ctrl-C will kill the test
Jon Hall25079782015-10-13 13:54:39 -0700797
798 Optional arguments:
799 email can either be a bool, or you can specify the email address
800 to send the email to
Jon Hallcd3d2a32015-10-01 11:07:28 -0700801 """
802 try:
803 if email:
Jon Hall25079782015-10-13 13:54:39 -0700804 if '@' in email:
805 main.mail = email
806 utilities.send_warning_email()
Jeremy Ronquillo15ff1072017-07-17 10:55:46 -0700807 self.log.debug( "Test execution suspended. \n"
808 "- Type 'c' to resume the test.\n"
809 "- Type Ctrl-C to exit the test.\n"
810 "- Enter interactive python interpreter commands.\n"
811 "\t- ie: main.Mininet1.pingall()\n"
812 "- Type 'help' for help with pdb." )
813 pdb.set_trace()
Jon Hallcd3d2a32015-10-01 11:07:28 -0700814 except EOFError:
815 return
816 # Pass all other exceptions up to caller
817
818
Jon Hall714eeba2015-09-29 17:53:10 -0700819def verifyOptions( options ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700820 """
Jon Hall714eeba2015-09-29 17:53:10 -0700821 This will verify the command line options and set to default values,
822 if any option not given in command line.
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700823 """
Jon Hall714eeba2015-09-29 17:53:10 -0700824 verifyTest( options )
825 verifyExample( options )
826 verifyTestScript( options )
YPZhang1c89e762016-06-29 10:43:58 -0700827 verifyParams( options )
Jon Hall714eeba2015-09-29 17:53:10 -0700828 verifyLogdir( options )
829 verifyMail( options )
830 verifyTestCases( options )
831 verifyOnosCell( options )
adminbae64d82013-08-01 10:50:15 -0700832
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700833
Jon Hall714eeba2015-09-29 17:53:10 -0700834def verifyTest( options ):
Jon Hall44506242015-07-29 17:40:26 -0700835 try:
836 if options.testname:
837 main.TEST = options.testname
Jon Hall714eeba2015-09-29 17:53:10 -0700838 main.classPath = "tests." + main.TEST + "." + main.TEST
Jon Hall44506242015-07-29 17:40:26 -0700839 main.tests_path = tests_path
840 elif options.example:
841 main.TEST = options.example
Jon Hall714eeba2015-09-29 17:53:10 -0700842 main.tests_path = path + "/examples/"
843 main.classPath = "examples." + main.TEST + "." + main.TEST
Jon Hall44506242015-07-29 17:40:26 -0700844 except AttributeError:
adminbae64d82013-08-01 10:50:15 -0700845 print "Test or Example not specified please specify the --test <test name > or --example <example name>"
Jon Hall5b586732015-06-11 11:39:39 -0700846 main.exit()
adminbae64d82013-08-01 10:50:15 -0700847
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700848
Jon Hall714eeba2015-09-29 17:53:10 -0700849def verifyExample( options ):
adminbae64d82013-08-01 10:50:15 -0700850 if options.example:
Jon Hall714eeba2015-09-29 17:53:10 -0700851 main.testDir = path + '/examples/'
852 main.tests_path = path + "/examples/"
853 main.classPath = "examples." + main.TEST + "." + main.TEST
kelvin-onlabf70fd542015-05-07 18:41:40 -0700854
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700855
Jon Hall714eeba2015-09-29 17:53:10 -0700856def verifyLogdir( options ):
Jon Hall88e498c2015-03-06 09:54:35 -0800857 # Verifying Log directory option
adminbae64d82013-08-01 10:50:15 -0700858 if options.logdir:
859 main.logdir = options.logdir
Jon Hall714eeba2015-09-29 17:53:10 -0700860 else:
Jon Halld61331b2015-02-17 16:35:47 -0800861 main.logdir = main.FALSE
kelvin-onlabf70fd542015-05-07 18:41:40 -0700862
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700863
Jon Hall714eeba2015-09-29 17:53:10 -0700864def verifyMail( options ):
Jon Hall25079782015-10-13 13:54:39 -0700865 # Mail-To: field
866 if options.mail: # Test run specific
adminbae64d82013-08-01 10:50:15 -0700867 main.mail = options.mail
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700868 elif main.params.get( 'mail' ): # Test suite specific
Jon Hall25079782015-10-13 13:54:39 -0700869 main.mail = main.params.get( 'mail' )
870 else: # TestON specific
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700871 main.mail = main.config[ 'config' ].get( 'mail_to' )
Jon Hall25079782015-10-13 13:54:39 -0700872 # Mail-From: field
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700873 main.sender = main.config[ 'config' ].get( 'mail_from' )
Jon Hall25079782015-10-13 13:54:39 -0700874 # Mail smtp server
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700875 main.smtp = main.config[ 'config' ].get( 'mail_server' )
Jon Hall25079782015-10-13 13:54:39 -0700876 # Mail-From account password
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700877 main.senderPwd = main.config[ 'config' ].get( 'mail_pass' )
878
Jon Hall25079782015-10-13 13:54:39 -0700879
Devin Lim2df68a12017-06-30 15:39:05 -0700880def evalTestCase( tempList ):
881 tList = []
882 for tcase in tempList:
883 if isinstance( tcase, list ):
884 tList.extend( evalTestCase( tcase ) )
885 else:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700886 tList.extend( [ tcase ] )
Devin Lim2df68a12017-06-30 15:39:05 -0700887 return tList
adminbae64d82013-08-01 10:50:15 -0700888
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700889
Jon Hall714eeba2015-09-29 17:53:10 -0700890def verifyTestCases( options ):
Jon Hall88e498c2015-03-06 09:54:35 -0800891 # Getting Test cases list
adminbae64d82013-08-01 10:50:15 -0700892 if options.testcases:
Jon Hallfebb1c72015-03-05 13:30:09 -0800893 testcases_list = options.testcases
Jon Hall88e498c2015-03-06 09:54:35 -0800894 # sys.exit()
Jon Hall714eeba2015-09-29 17:53:10 -0700895 testcases_list = re.sub( "(\[|\])", "", options.testcases )
896 main.testcases_list = eval( testcases_list + "," )
897 else:
adminbae64d82013-08-01 10:50:15 -0700898 if 'testcases' in main.params.keys():
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700899 temp = eval( main.params[ 'testcases' ] + "," )
Devin Lim2df68a12017-06-30 15:39:05 -0700900 main.testcases_list = evalTestCase( list( temp ) )
Jon Hall714eeba2015-09-29 17:53:10 -0700901 else:
902 print "Testcases not specifed in params, please provide in " +\
903 "params file or 'testcases' commandline argument"
Jon Halld61331b2015-02-17 16:35:47 -0800904 sys.exit()
kelvin-onlabf70fd542015-05-07 18:41:40 -0700905
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700906
Jon Hall714eeba2015-09-29 17:53:10 -0700907def verifyOnosCell( options ):
Hari Krishnabe4b97b2015-07-15 12:19:43 -0700908 # Verifying onoscell option
Hari Krishna03f530e2015-07-10 17:28:27 -0700909 if options.onoscell:
910 main.onoscell = options.onoscell
Devin Lim58046fa2017-07-05 16:55:00 -0700911 main.ONOSip = []
Hari Krishnabe4b97b2015-07-15 12:19:43 -0700912 main.mnIP = ""
Devin Lim58046fa2017-07-05 16:55:00 -0700913 cellCMD = ". ~/onos/tools/dev/bash_profile; cell " + main.onoscell
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700914 output = subprocess.check_output( [ "bash", '-c', cellCMD ] )
Hari Krishnabe4b97b2015-07-15 12:19:43 -0700915 splitOutput = output.splitlines()
Devin Lim58046fa2017-07-05 16:55:00 -0700916 main.apps = ""
Jon Hall714eeba2015-09-29 17:53:10 -0700917 for i in range( len( splitOutput ) ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700918 if re.match( "OCN", splitOutput[ i ] ):
919 mnNode = splitOutput[ i ].split( "=" )
920 main.mnIP = mnNode[ 1 ]
Jon Hall714eeba2015-09-29 17:53:10 -0700921 # cell already sorts OC variables in bash, so no need to
922 # sort in TestON
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700923 elif re.match( "OC[1-9]", splitOutput[ i ] ):
924 onosNodes = splitOutput[ i ].split( "=" )
925 main.ONOSip.append( onosNodes[ 1 ] )
926 elif re.match( "ONOS_APPS", splitOutput[ i ] ):
927 main.apps = ( splitOutput[ i ].split( "=" ) )[ 1 ]
Jon Hall714eeba2015-09-29 17:53:10 -0700928 else:
Hari Krishna03f530e2015-07-10 17:28:27 -0700929 main.onoscell = main.FALSE
930
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700931
Jon Hall714eeba2015-09-29 17:53:10 -0700932def verifyTestScript( options ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700933 """
adminbae64d82013-08-01 10:50:15 -0700934 Verifyies test script.
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700935 """
Jon Halld61331b2015-02-17 16:35:47 -0800936 main.openspeak = openspeak.OpenSpeak()
Jon Hall53c5e662016-04-13 16:06:56 -0700937 directory = main.testDir + "/" + main.TEST
938 if os.path.exists( directory ):
939 pass
940 else:
941 directory = ""
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700942 for root, dirs, files in os.walk( main.testDir, topdown=True ):
Jon Hall53c5e662016-04-13 16:06:56 -0700943 if not directory:
944 for name in dirs:
945 if name == main.TEST:
946 directory = ( os.path.join( root, name ) )
947 index = directory.find( "/tests/" ) + 1
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700948 main.classPath = directory[ index: ].replace( '/', '.' ) + "." + main.TEST
Jon Hall53c5e662016-04-13 16:06:56 -0700949 break
950 openspeakfile = directory + "/" + main.TEST + ".ospk"
951 main.testFile = directory + "/" + main.TEST + ".py"
Jon Hall714eeba2015-09-29 17:53:10 -0700952 if os.path.exists( openspeakfile ):
Jon Hall44506242015-07-29 17:40:26 -0700953 # Openspeak file found, compiling to python
Jon Hall714eeba2015-09-29 17:53:10 -0700954 main.openspeak.compiler( openspeakfile=openspeakfile, writetofile=1 )
Jon Hall53c5e662016-04-13 16:06:56 -0700955 elif os.path.exists( main.testFile ):
Jon Hall44506242015-07-29 17:40:26 -0700956 # No openspeak found, using python file instead
957 pass
adminbae64d82013-08-01 10:50:15 -0700958 else:
Jon Hall714eeba2015-09-29 17:53:10 -0700959 print "\nThere is no \"" + main.TEST + "\" test script.\nPlease provide a " +\
Jon Hall44506242015-07-29 17:40:26 -0700960 "Python or OpenSpeak test script in the tests folder: " +\
Jon Hall714eeba2015-09-29 17:53:10 -0700961 main.testDir + "/" + main.TEST + "/"
adminbae64d82013-08-01 10:50:15 -0700962 __builtin__.testthread = None
963 main.exit()
Jon Hall714eeba2015-09-29 17:53:10 -0700964 try:
965 testModule = __import__( main.classPath,
966 globals(),
967 locals(),
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700968 [ main.TEST ],
Jon Hall714eeba2015-09-29 17:53:10 -0700969 -1 )
Jon Hall1306a562015-09-04 11:21:24 -0700970 except ImportError:
Jon Hall714eeba2015-09-29 17:53:10 -0700971 print "There was an import error, it might mean that there is " +\
972 "no test named " + main.TEST
Jon Halld61331b2015-02-17 16:35:47 -0800973 main.exit()
adminbae64d82013-08-01 10:50:15 -0700974
Jon Hall714eeba2015-09-29 17:53:10 -0700975 testClass = getattr( testModule, main.TEST )
adminbae64d82013-08-01 10:50:15 -0700976 main.testObject = testClass()
977 load_parser()
Jon Hall714eeba2015-09-29 17:53:10 -0700978 main.params = main.parser.parseParams( main.classPath )
979 main.topology = main.parser.parseTopology( main.classPath )
kelvin-onlabf70fd542015-05-07 18:41:40 -0700980
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700981
YPZhang1c89e762016-06-29 10:43:58 -0700982def verifyParams( options ):
Jon Hall714eeba2015-09-29 17:53:10 -0700983 try:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700984 main.params = main.params[ 'PARAMS' ]
Jon Hall1306a562015-09-04 11:21:24 -0700985 except KeyError:
Jon Hall714eeba2015-09-29 17:53:10 -0700986 print "Error with the params file: Either the file not specified " +\
987 "or the format is not correct"
Jon Halld61331b2015-02-17 16:35:47 -0800988 main.exit()
Jon Hall714eeba2015-09-29 17:53:10 -0700989 try:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700990 main.topology = main.topology[ 'TOPOLOGY' ]
Jon Hall1306a562015-09-04 11:21:24 -0700991 except KeyError:
Jon Hall714eeba2015-09-29 17:53:10 -0700992 print "Error with the Topology file: Either the file not specified " +\
993 "or the format is not correct"
adminbae64d82013-08-01 10:50:15 -0700994 main.exit()
YPZhang1c89e762016-06-29 10:43:58 -0700995 # Overwrite existing params variables if they are specified from command line
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700996 if len( options.params ) > 0:
YPZhang1c89e762016-06-29 10:43:58 -0700997 # Some params variables are specified from command line
998 for param in options.params:
999 if not re.search( ".=.", param ):
1000 print( "Error when parsing params: params should follow key=value format" )
1001 continue
Jon Hall7c4f4302016-07-15 14:39:02 -07001002 # Split the param string to catch nested keys and the value
YPZhang1c89e762016-06-29 10:43:58 -07001003 [ keys, value ] = param.split( "=" )
1004 # Split the nested keys according to its hierarchy
1005 keyList = keys.split( "/" )
1006 # Get the outermost dictionary
1007 paramDict = main.params
1008 # Get the innermost dictionary
1009 try:
1010 while len( keyList ) > 1:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001011 key = keyList.pop( 0 )
YPZhang1c89e762016-06-29 10:43:58 -07001012 assert isinstance( paramDict[ key ], dict )
1013 paramDict = paramDict[ key ]
1014 except KeyError:
1015 print( "Error when parsing params: key \"" + key + "\" not found in main.params" )
1016 main.exit()
1017 except AssertionError:
1018 print( "Error when parsing params: \"" + key + "\" is already the innermost level in main.params" )
1019 main.exit()
1020 # Change the value
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001021 if keyList[ 0 ] not in paramDict:
YPZhang1c89e762016-06-29 10:43:58 -07001022 print( "Error when parsing params: key \"" + keyList[0] + "\" not found in main.params" )
1023 main.exit()
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001024 elif isinstance( paramDict[ keyList[ 0 ] ], dict ):
YPZhang1c89e762016-06-29 10:43:58 -07001025 print( "Error when parsing params: more levels under key \"" + keyList[0] + "\" in main.params" )
1026 main.exit()
1027 else:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001028 paramDict[ keyList[ 0 ] ] = value
1029
kelvin-onlabf70fd542015-05-07 18:41:40 -07001030
Jon Hall714eeba2015-09-29 17:53:10 -07001031def load_parser():
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001032 """
adminbae64d82013-08-01 10:50:15 -07001033 It facilitates the loading customised parser for topology and params file.
1034 It loads parser mentioned in tab named parser of teston.cfg file.
Jon Hall714eeba2015-09-29 17:53:10 -07001035 It also loads default xmlparser if no parser have specified in teston.cfg
1036 file.
adminbae64d82013-08-01 10:50:15 -07001037
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001038 """
adminbae64d82013-08-01 10:50:15 -07001039 confighash = main.configDict
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001040 if 'file' in confighash[ 'config' ][ 'parser' ] and\
1041 'class' in confighash[ 'config' ][ 'parser' ]:
1042 path = confighash[ 'config' ][ 'parser' ][ 'file' ]
Jon Hall714eeba2015-09-29 17:53:10 -07001043 if path is not None or\
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001044 confighash[ 'config' ][ 'parser' ][ 'class' ] is not None:
Jon Hall44506242015-07-29 17:40:26 -07001045 try:
1046 module = re.sub( r".py\s*$", "", path )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001047 moduleList = module.split( "/" )
1048 newModule = ".".join( moduleList[ -2: ] )
1049 parsingClass = confighash[ 'config' ][ 'parser' ][ 'class' ]
Jon Hall714eeba2015-09-29 17:53:10 -07001050 parsingModule = __import__( newModule,
1051 globals(),
1052 locals(),
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001053 [ parsingClass ],
Jon Hall714eeba2015-09-29 17:53:10 -07001054 -1 )
1055 parsingClass = getattr( parsingModule, parsingClass )
Jon Hall44506242015-07-29 17:40:26 -07001056 main.parser = parsingClass()
Jon Hall714eeba2015-09-29 17:53:10 -07001057 if hasattr( main.parser, "parseParams" ) and\
1058 hasattr( main.parser, "parseTopology" ) and\
1059 hasattr( main.parser, "parse" ):
Jon Hall44506242015-07-29 17:40:26 -07001060 pass
1061 else:
1062 print "Invalid parser format"
adminbae64d82013-08-01 10:50:15 -07001063 main.exit()
Jon Hall44506242015-07-29 17:40:26 -07001064 except ImportError:
Jon Hall714eeba2015-09-29 17:53:10 -07001065 print "Could not find the file " + path +\
1066 " using default parser."
Jon Halld61331b2015-02-17 16:35:47 -08001067 load_defaultParser()
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001068 elif confighash[ 'config' ][ 'parser' ][ 'file' ] is None or\
1069 confighash[ 'config' ][ 'parser' ][ 'class' ] is None:
Jon Halld61331b2015-02-17 16:35:47 -08001070 load_defaultParser()
adminbae64d82013-08-01 10:50:15 -07001071 else:
1072 load_defaultParser()
1073
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001074
adminbae64d82013-08-01 10:50:15 -07001075def load_defaultParser():
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001076 """
Jon Hall714eeba2015-09-29 17:53:10 -07001077 It will load the default parser which is xml parser to parse the params and
1078 topology file.
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001079 """
1080 moduleList = main.parserPath.split( "/" )
1081 newModule = ".".join( moduleList[ -2: ] )
Jon Hall714eeba2015-09-29 17:53:10 -07001082 try:
Jon Halld61331b2015-02-17 16:35:47 -08001083 parsingClass = main.parsingClass
Jon Hall714eeba2015-09-29 17:53:10 -07001084 parsingModule = __import__( newModule,
1085 globals(),
1086 locals(),
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001087 [ parsingClass ],
Jon Hall714eeba2015-09-29 17:53:10 -07001088 -1 )
1089 parsingClass = getattr( parsingModule, parsingClass )
adminbae64d82013-08-01 10:50:15 -07001090 main.parser = parsingClass()
Jon Hall714eeba2015-09-29 17:53:10 -07001091 if hasattr( main.parser, "parseParams" ) and\
1092 hasattr( main.parser, "parseTopology" ) and\
1093 hasattr( main.parser, "parse" ):
adminbae64d82013-08-01 10:50:15 -07001094 pass
1095 else:
1096 main.exit()
adminbae64d82013-08-01 10:50:15 -07001097 except ImportError:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001098 print sys.exc_info()[ 1 ]
1099
adminbae64d82013-08-01 10:50:15 -07001100
Jon Hall714eeba2015-09-29 17:53:10 -07001101def load_logger():
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001102 """
adminbae64d82013-08-01 10:50:15 -07001103 It facilitates the loading customised parser for topology and params file.
1104 It loads parser mentioned in tab named parser of teston.cfg file.
Jon Hall714eeba2015-09-29 17:53:10 -07001105 It also loads default xmlparser if no parser have specified in teston.cfg
1106 file.
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001107 """
adminbae64d82013-08-01 10:50:15 -07001108 confighash = main.configDict
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001109 if 'file' in confighash[ 'config' ][ 'logger' ] and\
1110 'class' in confighash[ 'config' ][ 'logger' ]:
1111 path = confighash[ 'config' ][ 'logger' ][ 'file' ]
Jon Hall714eeba2015-09-29 17:53:10 -07001112 if path is not None or\
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001113 confighash[ 'config' ][ 'logger' ][ 'class' ] is not None:
Jon Hall44506242015-07-29 17:40:26 -07001114 try:
1115 module = re.sub( r".py\s*$", "", path )
Jon Hall714eeba2015-09-29 17:53:10 -07001116 moduleList = module.split( "/" )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001117 newModule = ".".join( moduleList[ -2: ] )
1118 loggerClass = confighash[ 'config' ][ 'logger' ][ 'class' ]
Jon Hall714eeba2015-09-29 17:53:10 -07001119 loggerModule = __import__( newModule,
1120 globals(),
1121 locals(),
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001122 [ loggerClass ],
Jon Hall714eeba2015-09-29 17:53:10 -07001123 -1 )
1124 loggerClass = getattr( loggerModule, loggerClass )
Jon Hall44506242015-07-29 17:40:26 -07001125 main.logger = loggerClass()
Jon Hall44506242015-07-29 17:40:26 -07001126 except ImportError:
Jon Hall714eeba2015-09-29 17:53:10 -07001127 print "Could not find the file " + path +\
1128 " using default logger."
adminbae64d82013-08-01 10:50:15 -07001129 load_defaultlogger()
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001130 elif confighash[ 'config' ][ 'parser' ][ 'file' ] is None or\
1131 confighash[ 'config' ][ 'parser' ][ 'class' ] is None:
Jon Halld61331b2015-02-17 16:35:47 -08001132 load_defaultlogger()
adminbae64d82013-08-01 10:50:15 -07001133 else:
1134 load_defaultlogger()
1135
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001136
adminbae64d82013-08-01 10:50:15 -07001137def load_defaultlogger():
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001138 """
Jon Hall714eeba2015-09-29 17:53:10 -07001139 It will load the default parser which is xml parser to parse the params and
1140 topology file.
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001141 """
1142 moduleList = main.loggerPath.split( "/" )
1143 newModule = ".".join( moduleList[ -2: ] )
Jon Hall714eeba2015-09-29 17:53:10 -07001144 try:
Jon Halld61331b2015-02-17 16:35:47 -08001145 loggerClass = main.loggerClass
Jon Hall714eeba2015-09-29 17:53:10 -07001146 loggerModule = __import__( newModule,
1147 globals(),
1148 locals(),
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001149 [ loggerClass ],
Jon Hall714eeba2015-09-29 17:53:10 -07001150 -1 )
1151 loggerClass = getattr( loggerModule, loggerClass )
adminbae64d82013-08-01 10:50:15 -07001152 main.logger = loggerClass()
1153
1154 except ImportError:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001155 print sys.exc_info()[ 1 ]
Jon Halld61331b2015-02-17 16:35:47 -08001156 main.exit()
adminbae64d82013-08-01 10:50:15 -07001157
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001158
Jon Hall714eeba2015-09-29 17:53:10 -07001159def _echo( self ):
adminbae64d82013-08-01 10:50:15 -07001160 print "THIS IS ECHO"