blob: a7e1297d59142c768670ce1b500c38301de81976 [file] [log] [blame]
adminbae64d82013-08-01 10:50:15 -07001#!/usr/bin/env python
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002'''
adminbae64d82013-08-01 10:50:15 -07003Created on 20-Dec-2012
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -07004Copyright 2012 Open Networking Foundation
Jon Hall5f15fef2015-07-17 14:22:14 -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 Ronquillo4d5f1d02017-10-13 20:23:57 +000013 (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 Hall4ba53f02015-07-29 13:07:41 -070021 along with TestON. If not, see <http://www.gnu.org/licenses/>.
adminbae64d82013-08-01 10:50:15 -070022
23
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +000024'''
25
26
adminbae64d82013-08-01 10:50:15 -070027"""
28cli will provide the CLI shell for teston framework.
29
30A simple command-line interface for TestON.
31
32The TestON CLI provides a simple console which
33makes it easy to launch the test. For example, the command run will execute the test.
34
35teston> run test DpctlTest
36Several useful commands are provided.
37"""
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +000038
adminbae64d82013-08-01 10:50:15 -070039from subprocess import call
40from cmd import Cmd
41from os import isatty
42import sys
43import re
44import os
45import time
46import threading
47import __builtin__
48import pprint
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +000049dump = pprint.PrettyPrinter(indent=4)
adminbae64d82013-08-01 10:50:15 -070050__builtin__.testthread = False
51introduction = "TestON is the testing framework \nDeveloped by Paxterra Solutions (www.paxterrasolutions.com)"
Jon Hall0bde9ba2015-03-19 11:32:57 -070052__builtin__.COLORS = False
adminbae64d82013-08-01 10:50:15 -070053
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +000054path = re.sub( "/bin$", "", sys.path[0] )
Jon Hall1dd5a0a2015-07-08 10:49:26 -070055sys.path.insert( 1, path )
Jon Hall0bde9ba2015-03-19 11:32:57 -070056from core.teston import *
adminbae64d82013-08-01 10:50:15 -070057
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +000058class CLI( threading.Thread,Cmd,object ):
adminbae64d82013-08-01 10:50:15 -070059 "command-line interface to execute the test."
60
61 prompt = 'teston> '
62
63 def __init__( self, teston, stdin=sys.stdin ):
64 self.teston = teston
Jon Hall0bde9ba2015-03-19 11:32:57 -070065
adminbae64d82013-08-01 10:50:15 -070066 self._mainevent = threading.Event()
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +000067 threading.Thread.__init__(self)
adminbae64d82013-08-01 10:50:15 -070068 self.main_stop = False
69 self.locals = { 'test': teston }
70 self.stdin = stdin
71 Cmd.__init__( self )
72 self.pause = False
73 self.stop = False
74 __builtin__.cli = self
75
76 def emptyline( self ):
77 "Don't repeat last command when you hit return."
78 pass
79
80 helpStr = (
81 " teston help"
82 )
83
84 def do_help( self, line ):
85 "Describe available CLI commands."
86 Cmd.do_help( self, line )
87 if line is '':
88 output( self.helpStr )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +000089 def do_run(self,args):
90 '''
adminbae64d82013-08-01 10:50:15 -070091 run command will execute the test with following optional command line arguments
92 logdir <directory to store logs in>
93 testcases <list of testcases separated by comma or range of testcases separated by hypen>
94 mail <mail-id or list of mail-ids seperated by comma>
95 example 1, to execute the examples specified in the ~/examples diretory.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +000096 '''
Jon Hall1306a562015-09-04 11:21:24 -070097 try:
98 args = args.split()
99 options = {}
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000100 options = self.parseArgs(args,options)
101 options = dictToObj(options)
Jon Hall1306a562015-09-04 11:21:24 -0700102 if not testthread:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000103 test = TestThread(options)
Jon Hall1306a562015-09-04 11:21:24 -0700104 test.start()
105 while test.isAlive():
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000106 test.join(1)
Jon Hall1306a562015-09-04 11:21:24 -0700107 else:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000108 print main.TEST+ " test execution paused, please resume that before executing to another test"
Jon Hall1306a562015-09-04 11:21:24 -0700109 except KeyboardInterrupt, SystemExit:
110 print "Interrupt called, Exiting."
111 test._Thread__stop()
112 main.cleanup()
113 main.exit()
Jon Hall4ba53f02015-07-29 13:07:41 -0700114
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000115 def do_resume(self, line):
116 '''
adminbae64d82013-08-01 10:50:15 -0700117 resume command will continue the execution of paused test.
118 teston>resume
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000119 [2013-01-07 23:03:44.640723] [PoxTest] [STEP] 1.1: Checking the host reachability using pingHost
adminbae64d82013-08-01 10:50:15 -0700120 2013-01-07 23:03:44,858 - PoxTest - INFO - Expected Prompt Found
121 ....
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000122 '''
adminbae64d82013-08-01 10:50:15 -0700123 if testthread:
124 testthread.play()
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000125 else :
adminbae64d82013-08-01 10:50:15 -0700126 print "There is no test to resume"
Jon Hall4ba53f02015-07-29 13:07:41 -0700127
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000128 def do_nextstep(self,line):
129 '''
Jon Hall4ba53f02015-07-29 13:07:41 -0700130 nextstep will execute the next-step of the paused test and
adminbae64d82013-08-01 10:50:15 -0700131 it will pause the test after finishing of step.
Jon Hall4ba53f02015-07-29 13:07:41 -0700132
adminbae64d82013-08-01 10:50:15 -0700133 teston> nextstep
134 Will pause the test's execution, after completion of this step.....
Jon Hall4ba53f02015-07-29 13:07:41 -0700135
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000136 teston> [2013-01-07 21:24:26.286601] [PoxTest] [STEP] 1.8: Checking the host reachability using pingHost
adminbae64d82013-08-01 10:50:15 -0700137 2013-01-07 21:24:26,455 - PoxTest - INFO - Expected Prompt Found
138 .....
139 teston>
Jon Hall4ba53f02015-07-29 13:07:41 -0700140
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000141 '''
adminbae64d82013-08-01 10:50:15 -0700142 if testthread:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000143 main.log.info("Executing the nextstep, Will pause test execution, after completion of the step")
adminbae64d82013-08-01 10:50:15 -0700144 testthread.play()
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000145 time.sleep(.1)
adminbae64d82013-08-01 10:50:15 -0700146 testthread.pause()
147 else:
148 print "There is no paused test "
Jon Hall4ba53f02015-07-29 13:07:41 -0700149
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000150 def do_dumpvar(self,line):
151 '''
adminbae64d82013-08-01 10:50:15 -0700152 dumpvar will print all the test data in raw format.
Jon Hall4ba53f02015-07-29 13:07:41 -0700153 usgae :
adminbae64d82013-08-01 10:50:15 -0700154 teston>dumpvar main
155 Here 'main' will be the test object.
Jon Hall4ba53f02015-07-29 13:07:41 -0700156
157 teston>dumpvar params
adminbae64d82013-08-01 10:50:15 -0700158 here 'params' will be the parameters specified in the params file.
Jon Hall4ba53f02015-07-29 13:07:41 -0700159
adminbae64d82013-08-01 10:50:15 -0700160 teston>dumpvar topology
161 here 'topology' will be topology specification of the test specified in topo file.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000162 '''
adminbae64d82013-08-01 10:50:15 -0700163 if testthread:
164 if line == "main":
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000165 dump.pprint(vars(main))
166 else :
167 try :
168 dump.pprint(vars(main)[line])
Jon Hall1306a562015-09-04 11:21:24 -0700169 except KeyError as e:
adminbae64d82013-08-01 10:50:15 -0700170 print e
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000171 else :
adminbae64d82013-08-01 10:50:15 -0700172 print "There is no paused test "
Jon Hall4ba53f02015-07-29 13:07:41 -0700173
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000174 def do_currentcase(self,line):
175 '''
adminbae64d82013-08-01 10:50:15 -0700176 currentcase will return the current case in the test execution.
Jon Hall4ba53f02015-07-29 13:07:41 -0700177
adminbae64d82013-08-01 10:50:15 -0700178 teston>currentcase
179 Currently executing test case is: 2
Jon Hall4ba53f02015-07-29 13:07:41 -0700180
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000181 '''
adminbae64d82013-08-01 10:50:15 -0700182 if testthread:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000183 print "Currently executing test case is: "+str(main.CurrentTestCaseNumber)
184 else :
adminbae64d82013-08-01 10:50:15 -0700185 print "There is no paused test "
Jon Hall4ba53f02015-07-29 13:07:41 -0700186
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000187
188 def do_currentstep(self,line):
189 '''
adminbae64d82013-08-01 10:50:15 -0700190 currentstep will return the current step in the test execution.
Jon Hall4ba53f02015-07-29 13:07:41 -0700191
adminbae64d82013-08-01 10:50:15 -0700192 teston>currentstep
193 Currently executing test step is: 2.3
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000194 '''
adminbae64d82013-08-01 10:50:15 -0700195 if testthread:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000196 print "Currently executing test step is: "+str(main.CurrentTestCaseNumber)+'.'+str(main.stepCount)
197 else :
adminbae64d82013-08-01 10:50:15 -0700198 print "There is no paused test "
Jon Hall4ba53f02015-07-29 13:07:41 -0700199
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000200
201 def do_stop(self,line):
202 '''
adminbae64d82013-08-01 10:50:15 -0700203 Will stop the paused test, if any !
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000204 '''
adminbae64d82013-08-01 10:50:15 -0700205 if testthread:
206 testthread.stop()
Jon Hall4ba53f02015-07-29 13:07:41 -0700207
adminbae64d82013-08-01 10:50:15 -0700208 return 'exited by user command'
Jon Hall4ba53f02015-07-29 13:07:41 -0700209
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000210 def do_gettest(self,line):
211 '''
adminbae64d82013-08-01 10:50:15 -0700212 gettest will return the test name which is under execution or recently executed.
Jon Hall4ba53f02015-07-29 13:07:41 -0700213
adminbae64d82013-08-01 10:50:15 -0700214 Test under execution:
Jon Hall4ba53f02015-07-29 13:07:41 -0700215 teston>gettest
adminbae64d82013-08-01 10:50:15 -0700216 Currently executing Test is: PoxTest
Jon Hall4ba53f02015-07-29 13:07:41 -0700217
adminbae64d82013-08-01 10:50:15 -0700218 Test recently executed:
219 Recently executed test is: MininetTest
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000220 '''
221 try :
222 if testthread :
223 print "Currently executing Test is: "+main.TEST
224 else :
225 print "Recently executed test is: "+main.TEST
Jon Hall4ba53f02015-07-29 13:07:41 -0700226
adminbae64d82013-08-01 10:50:15 -0700227 except NameError:
228 print "There is no previously executed Test"
Jon Hall4ba53f02015-07-29 13:07:41 -0700229
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000230 def do_showlog(self,line):
231 '''
adminbae64d82013-08-01 10:50:15 -0700232 showlog will show the test's Log
233 teston>showlog
234 Last executed test's log is : //home/openflow/TestON/logs/PoxTest_07_Jan_2013_21_42_11/PoxTest_07_Jan_2013_21_42_11.log
235 .....
236 teston>showlog
237 Currently executing Test's log is: /home/openflow/TestON/logs/PoxTest_07_Jan_2013_21_46_58/PoxTest_07_Jan_2013_21_46_58.log
238 .....
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000239 '''
240 try :
241 if testthread :
242 print "Currently executing Test's log is: "+main.LogFileName
Jon Hall4ba53f02015-07-29 13:07:41 -0700243
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000244 else :
245 print "Last executed test's log is : "+main.LogFileName
Jon Hall4ba53f02015-07-29 13:07:41 -0700246
adminbae64d82013-08-01 10:50:15 -0700247 logFile = main.LogFileName
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000248 logFileHandler = open(logFile, 'r')
249 for msg in logFileHandler.readlines() :
adminbae64d82013-08-01 10:50:15 -0700250 print msg,
Jon Hall4ba53f02015-07-29 13:07:41 -0700251
adminbae64d82013-08-01 10:50:15 -0700252 logFileHandler.close()
Jon Hall4ba53f02015-07-29 13:07:41 -0700253
adminbae64d82013-08-01 10:50:15 -0700254 except NameError:
255 print "There is no previously executed Test"
Jon Hall4ba53f02015-07-29 13:07:41 -0700256
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000257
258
259 def parseArgs(self,args,options):
260 '''
adminbae64d82013-08-01 10:50:15 -0700261 This will parse the command line arguments.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000262 '''
263 options = self.initOptions(options)
264 try :
YPZhang16f6e562016-07-12 15:50:31 -0700265 index = 0
266 while index < len( args ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000267 option = args[index]
268 if index > 0 :
269 if re.match("--params", option, flags=0):
YPZhang1c89e762016-06-29 10:43:58 -0700270 # check if there is a params
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000271 options['params'].append(args[index+1])
272 elif re.match("logdir|mail|example|testdir|testcases|onoscell", option, flags = 0):
273 options[option] = args[index+1]
274 options = self.testcasesInRange(index+1,option,args,options)
YPZhang16f6e562016-07-12 15:50:31 -0700275 index += 2
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000276 else :
277 options['testname'] = option
YPZhang16f6e562016-07-12 15:50:31 -0700278 index += 1
Jon Hall1306a562015-09-04 11:21:24 -0700279 except IndexError as e:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000280 print (e)
YPZhang16f6e562016-07-12 15:50:31 -0700281 main.cleanup()
282 main.exit()
Jon Hall4ba53f02015-07-29 13:07:41 -0700283
adminbae64d82013-08-01 10:50:15 -0700284 return options
Jon Hall4ba53f02015-07-29 13:07:41 -0700285
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000286 def initOptions(self,options):
287 '''
adminbae64d82013-08-01 10:50:15 -0700288 This will initialize the commandline options.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000289 '''
290 options['logdir'] = None
291 options['mail'] = None
292 options['example'] = None
293 options['testdir'] = None
294 options['testcases'] = None
295 options['onoscell'] = None
YPZhang1c89e762016-06-29 10:43:58 -0700296 # init params as a empty list
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000297 options['params'] = []
Jon Hall4ba53f02015-07-29 13:07:41 -0700298 return options
299
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000300 def testcasesInRange(self,index,option,args,options):
301 '''
302 This method will handle testcases list,specified in range [1-10].
303 '''
304 if re.match("testcases",option,1):
adminbae64d82013-08-01 10:50:15 -0700305 testcases = []
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000306 args[index] = re.sub("\[|\]","",args[index],0)
307 m = re.match("(\d+)\-(\d+)",args[index],flags=0)
adminbae64d82013-08-01 10:50:15 -0700308 if m:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000309 start_case = eval(m.group(1))
310 end_case = eval(m.group(2))
311 if (start_case <= end_case):
adminbae64d82013-08-01 10:50:15 -0700312 i = start_case
313 while i <= end_case:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000314 testcases.append(i)
315 i= i+1
316 else :
adminbae64d82013-08-01 10:50:15 -0700317 print "Please specify testcases properly like 1-5"
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000318 else :
319 options[option] = args[index]
adminbae64d82013-08-01 10:50:15 -0700320 return options
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000321 options[option] = str(testcases)
Jon Hall4ba53f02015-07-29 13:07:41 -0700322
adminbae64d82013-08-01 10:50:15 -0700323 return options
Jon Hall4ba53f02015-07-29 13:07:41 -0700324
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000325 def cmdloop(self, intro=introduction):
adminbae64d82013-08-01 10:50:15 -0700326 print introduction
327 while True:
328 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000329 super(CLI, self).cmdloop(intro="")
adminbae64d82013-08-01 10:50:15 -0700330 self.postloop()
331 except KeyboardInterrupt:
Jon Hall1306a562015-09-04 11:21:24 -0700332 if testthread:
333 testthread.pause()
334 else:
335 print "KeyboardInterrupt, Exiting."
336 sys.exit()
adminbae64d82013-08-01 10:50:15 -0700337
338 def do_echo( self, line ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000339 '''
adminbae64d82013-08-01 10:50:15 -0700340 Echoing of given input.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000341 '''
342 output(line)
adminbae64d82013-08-01 10:50:15 -0700343
344 def do_sh( self, line ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000345 '''
adminbae64d82013-08-01 10:50:15 -0700346 Run an external shell command
347 sh pwd
348 sh ifconfig etc.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000349 '''
adminbae64d82013-08-01 10:50:15 -0700350 call( line, shell=True )
351
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000352
adminbae64d82013-08-01 10:50:15 -0700353 def do_py( self, line ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000354 '''
adminbae64d82013-08-01 10:50:15 -0700355 Evaluate a Python expression.
Jon Hall4ba53f02015-07-29 13:07:41 -0700356
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000357 py main.log.info("Sample Log Information")
adminbae64d82013-08-01 10:50:15 -0700358 2013-01-07 12:07:26,804 - PoxTest - INFO - Sample Log Information
Jon Hall4ba53f02015-07-29 13:07:41 -0700359
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000360 '''
adminbae64d82013-08-01 10:50:15 -0700361 try:
362 exec( line )
Jon Hall1306a562015-09-04 11:21:24 -0700363 except Exception as e:
adminbae64d82013-08-01 10:50:15 -0700364 output( str( e ) + '\n' )
Jon Hall4ba53f02015-07-29 13:07:41 -0700365
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000366 def do_interpret(self,line):
367 '''
adminbae64d82013-08-01 10:50:15 -0700368 interpret will translate the single line openspeak statement to equivalent python script.
Jon Hall4ba53f02015-07-29 13:07:41 -0700369
adminbae64d82013-08-01 10:50:15 -0700370 teston> interpret ASSERT result EQUALS main.TRUE ONPASS "Ping executed successfully" ONFAIL "Ping failed"
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000371 utilities.assert_equals(expect=main.TRUE,actual=result,onpass="Ping executed successfully",onfail="Ping failed")
Jon Hall4ba53f02015-07-29 13:07:41 -0700372
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000373 '''
adminbae64d82013-08-01 10:50:15 -0700374 from core import openspeak
375 ospk = openspeak.OpenSpeak()
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000376 try :
377 translated_code = ospk.interpret(text=line)
adminbae64d82013-08-01 10:50:15 -0700378 print translated_code
Jon Hall1306a562015-09-04 11:21:24 -0700379 except AttributeError as e:
adminbae64d82013-08-01 10:50:15 -0700380 print 'Dynamic params are not allowed in single statement translations'
Jon Hall4ba53f02015-07-29 13:07:41 -0700381
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000382 def do_do (self,line):
383 '''
adminbae64d82013-08-01 10:50:15 -0700384 Do will translate and execute the openspeak statement for the paused test.
385 do <OpenSpeak statement>
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000386 '''
adminbae64d82013-08-01 10:50:15 -0700387 if testthread:
388 from core import openspeak
389 ospk = openspeak.OpenSpeak()
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000390 try :
391 translated_code = ospk.interpret(text=line)
392 eval(translated_code)
Jon Hall1306a562015-09-04 11:21:24 -0700393 except ( AttributeError, SyntaxError ) as e:
394 print 'Dynamic params are not allowed in single statement translations:'
395 print e
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000396 else :
adminbae64d82013-08-01 10:50:15 -0700397 print "Do will translate and execute the openspeak statement for the paused test.\nPlease use interpret to translate the OpenSpeak statement."
Jon Hall4ba53f02015-07-29 13:07:41 -0700398
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000399 def do_compile(self,line):
400 '''
401 compile will translate the openspeak (.ospk) file into TestON test script (python).
Jon Hall4ba53f02015-07-29 13:07:41 -0700402 It will receive the openspeak file path as input and will generate
403 equivalent test-script file in the same directory.
404
adminbae64d82013-08-01 10:50:15 -0700405 usage:
406 -----
407 teston>compile /home/openflow/TestON/PoxTest.ospk
Jon Hall4ba53f02015-07-29 13:07:41 -0700408
adminbae64d82013-08-01 10:50:15 -0700409 Auto-generated test-script file is /home/openflow/TestON/PoxTest.py
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000410 '''
adminbae64d82013-08-01 10:50:15 -0700411 from core import openspeak
Jon Hall4ba53f02015-07-29 13:07:41 -0700412 openspeak = openspeak.OpenSpeak()
adminbae64d82013-08-01 10:50:15 -0700413 openspeakfile = line
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000414 if os.path.exists(openspeakfile) :
415 openspeak.compiler(openspeakfile=openspeakfile,writetofile=1)
416 print "Auto-generated test-script file is "+ re.sub("ospk","py",openspeakfile,0)
adminbae64d82013-08-01 10:50:15 -0700417 else:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000418 print 'There is no such file : '+line
adminbae64d82013-08-01 10:50:15 -0700419
420 def do_exit( self, _line ):
421 "Exit"
422 if testthread:
423 testthread.stop()
Jon Hall4ba53f02015-07-29 13:07:41 -0700424
adminbae64d82013-08-01 10:50:15 -0700425 sys.exit()
426
427 return 'exited by user command'
428
429 def do_quit( self, line ):
430 "Exit"
431 return self.do_exit( line )
432
433 def do_EOF( self, line ):
434 "Exit"
435 output( '\n' )
436 return self.do_exit( line )
437
438 def isatty( self ):
439 "Is our standard input a tty?"
440 return isatty( self.stdin.fileno() )
441
442 def do_source( self, line ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000443 '''
adminbae64d82013-08-01 10:50:15 -0700444 Read shell commands from an input file and execute them sequentially.
445 cmdsource.txt :
Jon Hall4ba53f02015-07-29 13:07:41 -0700446
adminbae64d82013-08-01 10:50:15 -0700447 "pwd
448 ls "
Jon Hall4ba53f02015-07-29 13:07:41 -0700449
adminbae64d82013-08-01 10:50:15 -0700450 teston>source /home/openflow/cmdsource.txt
451 /home/openflow/TestON/bin/
452 cli.py __init__.py
Jon Hall4ba53f02015-07-29 13:07:41 -0700453
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000454 '''
455
adminbae64d82013-08-01 10:50:15 -0700456 args = line.split()
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000457 if len(args) != 1:
adminbae64d82013-08-01 10:50:15 -0700458 error( 'usage: source <file>\n' )
459 return
460 try:
461 self.inputFile = open( args[ 0 ] )
462 while True:
463 line = self.inputFile.readline()
464 if len( line ) > 0:
465 call( line, shell=True )
466 else:
467 break
468 except IOError:
469 error( 'error reading file %s\n' % args[ 0 ] )
Jon Hall4ba53f02015-07-29 13:07:41 -0700470
adminbae64d82013-08-01 10:50:15 -0700471 def do_time( self, line ):
472 "Measure time taken for any command in TestON."
473 start = time.time()
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000474 self.onecmd(line)
adminbae64d82013-08-01 10:50:15 -0700475 elapsed = time.time() - start
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000476 self.stdout.write("*** Elapsed time: %0.6f secs\n" % elapsed)
adminbae64d82013-08-01 10:50:15 -0700477
478 def default( self, line ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000479 """Called on an input line when the command prefix is not recognized."""
adminbae64d82013-08-01 10:50:15 -0700480 first, args, line = self.parseline( line )
481 if not args:
482 return
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000483 if args and len(args) > 0 and args[ -1 ] == '\n':
adminbae64d82013-08-01 10:50:15 -0700484 args = args[ :-1 ]
485 rest = args.split( ' ' )
486
487 error( '*** Unknown command: %s\n' % first )
488
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000489class TestThread(threading.Thread):
490 '''
adminbae64d82013-08-01 10:50:15 -0700491 TestThread class will handle the test execution and will communicate with the thread in the do_run.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000492 '''
493 def __init__(self,options):
adminbae64d82013-08-01 10:50:15 -0700494 self._stopevent = threading.Event()
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000495 threading.Thread.__init__(self)
adminbae64d82013-08-01 10:50:15 -0700496 self.is_stop = False
497 self.options = options
498 __builtin__.testthread = self
499
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000500 def run(self):
501 '''
adminbae64d82013-08-01 10:50:15 -0700502 Will execute the test.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000503 '''
504 while not self.is_stop :
adminbae64d82013-08-01 10:50:15 -0700505 if not self._stopevent.isSet():
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000506 self.test_on = TestON(self.options)
507 try :
adminbae64d82013-08-01 10:50:15 -0700508 if self.test_on.init_result:
509 result = self.test_on.run()
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000510 if not self.is_stop :
adminbae64d82013-08-01 10:50:15 -0700511 result = self.test_on.cleanup()
512 self.is_stop = True
Jon Hall1306a562015-09-04 11:21:24 -0700513 except KeyboardInterrupt:
514 print "Recevied Interrupt, cleaning-up the logs and drivers before exiting"
adminbae64d82013-08-01 10:50:15 -0700515 result = self.test_on.cleanup()
516 self.is_stop = True
517
Jon Hall4ba53f02015-07-29 13:07:41 -0700518 __builtin__.testthread = False
adminbae64d82013-08-01 10:50:15 -0700519
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000520 def pause(self):
521 '''
adminbae64d82013-08-01 10:50:15 -0700522 Will pause the test.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000523 '''
Jon Hall1306a562015-09-04 11:21:24 -0700524 if not cli.pause:
525 print "Will pause the test's execution, after completion of this step.....\n\n\n\n"
526 cli.pause = True
527 self._stopevent.set()
528 elif cli.pause and self.is_stop:
529 print "KeyboardInterrupt, Exiting."
530 self.test_on.exit()
531 else:
532 print "Recevied Interrupt, cleaning-up the logs and drivers before exiting"
533 result = self.test_on.cleanup()
534 self.is_stop = True
adminbae64d82013-08-01 10:50:15 -0700535
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000536 def play(self):
537 '''
adminbae64d82013-08-01 10:50:15 -0700538 Will resume the paused test.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000539 '''
adminbae64d82013-08-01 10:50:15 -0700540 self._stopevent.clear()
541 cli.pause = False
Jon Hall4ba53f02015-07-29 13:07:41 -0700542
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000543 def stop(self):
544 '''
adminbae64d82013-08-01 10:50:15 -0700545 Will stop the test execution.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000546 '''
547
adminbae64d82013-08-01 10:50:15 -0700548 print "Stopping the test"
549 self.is_stop = True
550 cli.stop = True
551 __builtin__.testthread = False
Jon Hall4ba53f02015-07-29 13:07:41 -0700552
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000553def output(msg):
554 '''
adminbae64d82013-08-01 10:50:15 -0700555 Simply, print the message in console
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000556 '''
adminbae64d82013-08-01 10:50:15 -0700557 print msg
558
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000559def error(msg):
560 '''
adminbae64d82013-08-01 10:50:15 -0700561 print the error message.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000562 '''
adminbae64d82013-08-01 10:50:15 -0700563 print msg
564
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000565def dictToObj(dictionary):
566 '''
adminbae64d82013-08-01 10:50:15 -0700567 This will facilitates the converting of the dictionary to the object.
568 This method will help to send options as object format to the test.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000569 '''
570 if isinstance(dictionary, list):
571 dictionary = [dictToObj(x) for x in dictionary]
572 if not isinstance(dictionary, dict):
adminbae64d82013-08-01 10:50:15 -0700573 return dictionary
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000574 class Convert(object):
adminbae64d82013-08-01 10:50:15 -0700575 pass
576 obj = Convert()
577 for k in dictionary:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000578 obj.__dict__[k] = dictToObj(dictionary[k])
adminbae64d82013-08-01 10:50:15 -0700579 return obj
580
581
582if __name__ == '__main__':
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000583 if len(sys.argv) > 1:
Jon Hall0bde9ba2015-03-19 11:32:57 -0700584 __builtin__.COLORS = True
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000585 CLI("test").onecmd(' '.join(sys.argv[1:]))
adminbae64d82013-08-01 10:50:15 -0700586 else:
Jon Hall0bde9ba2015-03-19 11:32:57 -0700587 __builtin__.COLORS = False
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000588 CLI("test").cmdloop()