blob: 8e4831133d112e794b531ee960f57eaddc5923ff [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 Ronquillo696f4262017-10-17 10:56:26 -070049dump = 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 Ronquillo696f4262017-10-17 10:56:26 -070054path = 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 Ronquillo696f4262017-10-17 10:56:26 -070058class 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 Ronquillo696f4262017-10-17 10:56:26 -070067 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 Ronquillo696f4262017-10-17 10:56:26 -070089
90 def do_run( self, args ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +000091 '''
adminbae64d82013-08-01 10:50:15 -070092 run command will execute the test with following optional command line arguments
93 logdir <directory to store logs in>
94 testcases <list of testcases separated by comma or range of testcases separated by hypen>
95 mail <mail-id or list of mail-ids seperated by comma>
96 example 1, to execute the examples specified in the ~/examples diretory.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +000097 '''
Jon Hall1306a562015-09-04 11:21:24 -070098 try:
99 args = args.split()
100 options = {}
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700101 options = self.parseArgs( args, options )
102 options = dictToObj( options )
Jon Hall1306a562015-09-04 11:21:24 -0700103 if not testthread:
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700104 test = TestThread( options )
Jon Hall1306a562015-09-04 11:21:24 -0700105 test.start()
106 while test.isAlive():
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700107 test.join( 1 )
Jon Hall1306a562015-09-04 11:21:24 -0700108 else:
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700109 print main.TEST + " test execution paused, please resume that before executing to another test"
Jon Hall1306a562015-09-04 11:21:24 -0700110 except KeyboardInterrupt, SystemExit:
111 print "Interrupt called, Exiting."
112 test._Thread__stop()
113 main.cleanup()
114 main.exit()
Jon Hall4ba53f02015-07-29 13:07:41 -0700115
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700116 def do_resume( self, line ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000117 '''
adminbae64d82013-08-01 10:50:15 -0700118 resume command will continue the execution of paused test.
119 teston>resume
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000120 [2013-01-07 23:03:44.640723] [PoxTest] [STEP] 1.1: Checking the host reachability using pingHost
adminbae64d82013-08-01 10:50:15 -0700121 2013-01-07 23:03:44,858 - PoxTest - INFO - Expected Prompt Found
122 ....
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000123 '''
adminbae64d82013-08-01 10:50:15 -0700124 if testthread:
125 testthread.play()
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700126 else:
adminbae64d82013-08-01 10:50:15 -0700127 print "There is no test to resume"
Jon Hall4ba53f02015-07-29 13:07:41 -0700128
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700129 def do_nextstep( self, line ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000130 '''
Jon Hall4ba53f02015-07-29 13:07:41 -0700131 nextstep will execute the next-step of the paused test and
adminbae64d82013-08-01 10:50:15 -0700132 it will pause the test after finishing of step.
Jon Hall4ba53f02015-07-29 13:07:41 -0700133
adminbae64d82013-08-01 10:50:15 -0700134 teston> nextstep
135 Will pause the test's execution, after completion of this step.....
Jon Hall4ba53f02015-07-29 13:07:41 -0700136
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000137 teston> [2013-01-07 21:24:26.286601] [PoxTest] [STEP] 1.8: Checking the host reachability using pingHost
adminbae64d82013-08-01 10:50:15 -0700138 2013-01-07 21:24:26,455 - PoxTest - INFO - Expected Prompt Found
139 .....
140 teston>
Jon Hall4ba53f02015-07-29 13:07:41 -0700141
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000142 '''
adminbae64d82013-08-01 10:50:15 -0700143 if testthread:
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700144 main.log.info( "Executing the nextstep, Will pause test execution, after completion of the step" )
adminbae64d82013-08-01 10:50:15 -0700145 testthread.play()
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700146 time.sleep( .1 )
adminbae64d82013-08-01 10:50:15 -0700147 testthread.pause()
148 else:
149 print "There is no paused test "
Jon Hall4ba53f02015-07-29 13:07:41 -0700150
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700151 def do_dumpvar( self, line ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000152 '''
adminbae64d82013-08-01 10:50:15 -0700153 dumpvar will print all the test data in raw format.
Jon Hall4ba53f02015-07-29 13:07:41 -0700154 usgae :
adminbae64d82013-08-01 10:50:15 -0700155 teston>dumpvar main
156 Here 'main' will be the test object.
Jon Hall4ba53f02015-07-29 13:07:41 -0700157
158 teston>dumpvar params
adminbae64d82013-08-01 10:50:15 -0700159 here 'params' will be the parameters specified in the params file.
Jon Hall4ba53f02015-07-29 13:07:41 -0700160
adminbae64d82013-08-01 10:50:15 -0700161 teston>dumpvar topology
162 here 'topology' will be topology specification of the test specified in topo file.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000163 '''
adminbae64d82013-08-01 10:50:15 -0700164 if testthread:
165 if line == "main":
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700166 dump.pprint( vars( main ) )
167 else:
168 try:
169 dump.pprint( vars( main )[ line ] )
Jon Hall1306a562015-09-04 11:21:24 -0700170 except KeyError as e:
adminbae64d82013-08-01 10:50:15 -0700171 print e
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700172 else:
adminbae64d82013-08-01 10:50:15 -0700173 print "There is no paused test "
Jon Hall4ba53f02015-07-29 13:07:41 -0700174
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700175 def do_currentcase( self, line ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000176 '''
adminbae64d82013-08-01 10:50:15 -0700177 currentcase will return the current case in the test execution.
Jon Hall4ba53f02015-07-29 13:07:41 -0700178
adminbae64d82013-08-01 10:50:15 -0700179 teston>currentcase
180 Currently executing test case is: 2
Jon Hall4ba53f02015-07-29 13:07:41 -0700181
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000182 '''
adminbae64d82013-08-01 10:50:15 -0700183 if testthread:
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700184 print "Currently executing test case is: " + str( main.CurrentTestCaseNumber )
185 else:
adminbae64d82013-08-01 10:50:15 -0700186 print "There is no paused test "
Jon Hall4ba53f02015-07-29 13:07:41 -0700187
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700188 def do_currentstep( self, line ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000189 '''
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 Ronquillo696f4262017-10-17 10:56:26 -0700196 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 Ronquillo696f4262017-10-17 10:56:26 -0700200 def do_stop( self, line ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000201 '''
adminbae64d82013-08-01 10:50:15 -0700202 Will stop the paused test, if any !
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000203 '''
adminbae64d82013-08-01 10:50:15 -0700204 if testthread:
205 testthread.stop()
Jon Hall4ba53f02015-07-29 13:07:41 -0700206
adminbae64d82013-08-01 10:50:15 -0700207 return 'exited by user command'
Jon Hall4ba53f02015-07-29 13:07:41 -0700208
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700209 def do_gettest( self, line ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000210 '''
adminbae64d82013-08-01 10:50:15 -0700211 gettest will return the test name which is under execution or recently executed.
Jon Hall4ba53f02015-07-29 13:07:41 -0700212
adminbae64d82013-08-01 10:50:15 -0700213 Test under execution:
Jon Hall4ba53f02015-07-29 13:07:41 -0700214 teston>gettest
adminbae64d82013-08-01 10:50:15 -0700215 Currently executing Test is: PoxTest
Jon Hall4ba53f02015-07-29 13:07:41 -0700216
adminbae64d82013-08-01 10:50:15 -0700217 Test recently executed:
218 Recently executed test is: MininetTest
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000219 '''
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700220 try:
221 if testthread:
222 print "Currently executing Test is: " + main.TEST
223 else:
224 print "Recently executed test is: " + main.TEST
Jon Hall4ba53f02015-07-29 13:07:41 -0700225
adminbae64d82013-08-01 10:50:15 -0700226 except NameError:
227 print "There is no previously executed Test"
Jon Hall4ba53f02015-07-29 13:07:41 -0700228
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700229 def do_showlog( self, line ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000230 '''
adminbae64d82013-08-01 10:50:15 -0700231 showlog will show the test's Log
232 teston>showlog
233 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
234 .....
235 teston>showlog
236 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
237 .....
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000238 '''
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700239 try:
240 if testthread:
241 print "Currently executing Test's log is: " + main.LogFileName
Jon Hall4ba53f02015-07-29 13:07:41 -0700242
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700243 else:
244 print "Last executed test's log is : " + main.LogFileName
Jon Hall4ba53f02015-07-29 13:07:41 -0700245
adminbae64d82013-08-01 10:50:15 -0700246 logFile = main.LogFileName
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700247 logFileHandler = open( logFile, 'r' )
248 for msg in logFileHandler.readlines():
adminbae64d82013-08-01 10:50:15 -0700249 print msg,
Jon Hall4ba53f02015-07-29 13:07:41 -0700250
adminbae64d82013-08-01 10:50:15 -0700251 logFileHandler.close()
Jon Hall4ba53f02015-07-29 13:07:41 -0700252
adminbae64d82013-08-01 10:50:15 -0700253 except NameError:
254 print "There is no previously executed Test"
Jon Hall4ba53f02015-07-29 13:07:41 -0700255
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700256 def parseArgs( self, args, options ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000257 '''
adminbae64d82013-08-01 10:50:15 -0700258 This will parse the command line arguments.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000259 '''
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700260 options = self.initOptions( options )
261 try:
YPZhang16f6e562016-07-12 15:50:31 -0700262 index = 0
263 while index < len( args ):
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700264 option = args[ index ]
265 if index > 0:
266 if re.match( "--params", option, flags=0 ):
YPZhang1c89e762016-06-29 10:43:58 -0700267 # check if there is a params
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700268 options[ 'params' ].append( args[ index + 1 ] )
269 elif re.match( "logdir|mail|example|testdir|testcases|onoscell", option, flags = 0 ):
270 options[ option ] = args[ index + 1 ]
271 options = self.testcasesInRange( index + 1, option, args, options )
YPZhang16f6e562016-07-12 15:50:31 -0700272 index += 2
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700273 else:
274 options[ 'testname' ] = option
YPZhang16f6e562016-07-12 15:50:31 -0700275 index += 1
Jon Hall1306a562015-09-04 11:21:24 -0700276 except IndexError as e:
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700277 print ( e )
YPZhang16f6e562016-07-12 15:50:31 -0700278 main.cleanup()
279 main.exit()
Jon Hall4ba53f02015-07-29 13:07:41 -0700280
adminbae64d82013-08-01 10:50:15 -0700281 return options
Jon Hall4ba53f02015-07-29 13:07:41 -0700282
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700283 def initOptions( self, options ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000284 '''
adminbae64d82013-08-01 10:50:15 -0700285 This will initialize the commandline options.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000286 '''
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700287 options[ 'logdir' ] = None
288 options[ 'mail' ] = None
289 options[ 'example' ] = None
290 options[ 'testdir' ] = None
291 options[ 'testcases' ] = None
292 options[ 'onoscell' ] = None
YPZhang1c89e762016-06-29 10:43:58 -0700293 # init params as a empty list
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700294 options[ 'params' ] = []
Jon Hall4ba53f02015-07-29 13:07:41 -0700295 return options
296
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700297 def testcasesInRange( self, index, option, args, options ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000298 '''
299 This method will handle testcases list,specified in range [1-10].
300 '''
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700301 if re.match( "testcases", option, 1 ):
adminbae64d82013-08-01 10:50:15 -0700302 testcases = []
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700303 args[ index ] = re.sub( "\[|\]", "", args[ index ], 0 )
304 m = re.match( "(\d+)\-(\d+)", args[ index ], flags=0 )
adminbae64d82013-08-01 10:50:15 -0700305 if m:
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700306 start_case = eval( m.group( 1 ) )
307 end_case = eval( m.group( 2 ) )
308 if ( start_case <= end_case ):
adminbae64d82013-08-01 10:50:15 -0700309 i = start_case
310 while i <= end_case:
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700311 testcases.append( i )
312 i = i + 1
313 else:
adminbae64d82013-08-01 10:50:15 -0700314 print "Please specify testcases properly like 1-5"
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700315 else:
316 options[ option ] = args[ index ]
adminbae64d82013-08-01 10:50:15 -0700317 return options
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700318 options[ option ] = str( testcases )
Jon Hall4ba53f02015-07-29 13:07:41 -0700319
adminbae64d82013-08-01 10:50:15 -0700320 return options
Jon Hall4ba53f02015-07-29 13:07:41 -0700321
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700322 def cmdloop( self, intro=introduction ):
adminbae64d82013-08-01 10:50:15 -0700323 print introduction
324 while True:
325 try:
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700326 super( CLI, self ).cmdloop( intro="" )
adminbae64d82013-08-01 10:50:15 -0700327 self.postloop()
328 except KeyboardInterrupt:
Jon Hall1306a562015-09-04 11:21:24 -0700329 if testthread:
330 testthread.pause()
331 else:
332 print "KeyboardInterrupt, Exiting."
333 sys.exit()
adminbae64d82013-08-01 10:50:15 -0700334
335 def do_echo( self, line ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000336 '''
adminbae64d82013-08-01 10:50:15 -0700337 Echoing of given input.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000338 '''
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700339 output( line )
adminbae64d82013-08-01 10:50:15 -0700340
341 def do_sh( self, line ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000342 '''
adminbae64d82013-08-01 10:50:15 -0700343 Run an external shell command
344 sh pwd
345 sh ifconfig etc.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000346 '''
adminbae64d82013-08-01 10:50:15 -0700347 call( line, shell=True )
348
adminbae64d82013-08-01 10:50:15 -0700349 def do_py( self, line ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000350 '''
adminbae64d82013-08-01 10:50:15 -0700351 Evaluate a Python expression.
Jon Hall4ba53f02015-07-29 13:07:41 -0700352
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000353 py main.log.info("Sample Log Information")
adminbae64d82013-08-01 10:50:15 -0700354 2013-01-07 12:07:26,804 - PoxTest - INFO - Sample Log Information
Jon Hall4ba53f02015-07-29 13:07:41 -0700355
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000356 '''
adminbae64d82013-08-01 10:50:15 -0700357 try:
358 exec( line )
Jon Hall1306a562015-09-04 11:21:24 -0700359 except Exception as e:
adminbae64d82013-08-01 10:50:15 -0700360 output( str( e ) + '\n' )
Jon Hall4ba53f02015-07-29 13:07:41 -0700361
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700362 def do_interpret( self, line ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000363 '''
adminbae64d82013-08-01 10:50:15 -0700364 interpret will translate the single line openspeak statement to equivalent python script.
Jon Hall4ba53f02015-07-29 13:07:41 -0700365
adminbae64d82013-08-01 10:50:15 -0700366 teston> interpret ASSERT result EQUALS main.TRUE ONPASS "Ping executed successfully" ONFAIL "Ping failed"
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000367 utilities.assert_equals(expect=main.TRUE,actual=result,onpass="Ping executed successfully",onfail="Ping failed")
Jon Hall4ba53f02015-07-29 13:07:41 -0700368
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000369 '''
adminbae64d82013-08-01 10:50:15 -0700370 from core import openspeak
371 ospk = openspeak.OpenSpeak()
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700372 try:
373 translated_code = ospk.interpret( text=line )
adminbae64d82013-08-01 10:50:15 -0700374 print translated_code
Jon Hall1306a562015-09-04 11:21:24 -0700375 except AttributeError as e:
adminbae64d82013-08-01 10:50:15 -0700376 print 'Dynamic params are not allowed in single statement translations'
Jon Hall4ba53f02015-07-29 13:07:41 -0700377
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700378 def do_do( self, line ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000379 '''
adminbae64d82013-08-01 10:50:15 -0700380 Do will translate and execute the openspeak statement for the paused test.
381 do <OpenSpeak statement>
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000382 '''
adminbae64d82013-08-01 10:50:15 -0700383 if testthread:
384 from core import openspeak
385 ospk = openspeak.OpenSpeak()
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700386 try:
387 translated_code = ospk.interpret( text=line )
388 eval( translated_code )
Jon Hall1306a562015-09-04 11:21:24 -0700389 except ( AttributeError, SyntaxError ) as e:
390 print 'Dynamic params are not allowed in single statement translations:'
391 print e
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700392 else:
adminbae64d82013-08-01 10:50:15 -0700393 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 -0700394
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700395 def do_compile( self, line ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000396 '''
397 compile will translate the openspeak (.ospk) file into TestON test script (python).
Jon Hall4ba53f02015-07-29 13:07:41 -0700398 It will receive the openspeak file path as input and will generate
399 equivalent test-script file in the same directory.
400
adminbae64d82013-08-01 10:50:15 -0700401 usage:
402 -----
403 teston>compile /home/openflow/TestON/PoxTest.ospk
Jon Hall4ba53f02015-07-29 13:07:41 -0700404
adminbae64d82013-08-01 10:50:15 -0700405 Auto-generated test-script file is /home/openflow/TestON/PoxTest.py
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000406 '''
adminbae64d82013-08-01 10:50:15 -0700407 from core import openspeak
Jon Hall4ba53f02015-07-29 13:07:41 -0700408 openspeak = openspeak.OpenSpeak()
adminbae64d82013-08-01 10:50:15 -0700409 openspeakfile = line
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700410 if os.path.exists( openspeakfile ):
411 openspeak.compiler( openspeakfile=openspeakfile, writetofile=1 )
412 print "Auto-generated test-script file is " + re.sub( "ospk", "py", openspeakfile, 0 )
adminbae64d82013-08-01 10:50:15 -0700413 else:
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700414 print 'There is no such file : ' + line
adminbae64d82013-08-01 10:50:15 -0700415
416 def do_exit( self, _line ):
417 "Exit"
418 if testthread:
419 testthread.stop()
Jon Hall4ba53f02015-07-29 13:07:41 -0700420
adminbae64d82013-08-01 10:50:15 -0700421 sys.exit()
422
423 return 'exited by user command'
424
425 def do_quit( self, line ):
426 "Exit"
427 return self.do_exit( line )
428
429 def do_EOF( self, line ):
430 "Exit"
431 output( '\n' )
432 return self.do_exit( line )
433
434 def isatty( self ):
435 "Is our standard input a tty?"
436 return isatty( self.stdin.fileno() )
437
438 def do_source( self, line ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000439 '''
adminbae64d82013-08-01 10:50:15 -0700440 Read shell commands from an input file and execute them sequentially.
441 cmdsource.txt :
Jon Hall4ba53f02015-07-29 13:07:41 -0700442
adminbae64d82013-08-01 10:50:15 -0700443 "pwd
444 ls "
Jon Hall4ba53f02015-07-29 13:07:41 -0700445
adminbae64d82013-08-01 10:50:15 -0700446 teston>source /home/openflow/cmdsource.txt
447 /home/openflow/TestON/bin/
448 cli.py __init__.py
Jon Hall4ba53f02015-07-29 13:07:41 -0700449
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000450 '''
451
adminbae64d82013-08-01 10:50:15 -0700452 args = line.split()
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700453 if len( args ) != 1:
adminbae64d82013-08-01 10:50:15 -0700454 error( 'usage: source <file>\n' )
455 return
456 try:
457 self.inputFile = open( args[ 0 ] )
458 while True:
459 line = self.inputFile.readline()
460 if len( line ) > 0:
461 call( line, shell=True )
462 else:
463 break
464 except IOError:
465 error( 'error reading file %s\n' % args[ 0 ] )
Jon Hall4ba53f02015-07-29 13:07:41 -0700466
adminbae64d82013-08-01 10:50:15 -0700467 def do_time( self, line ):
468 "Measure time taken for any command in TestON."
469 start = time.time()
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700470 self.onecmd( line )
adminbae64d82013-08-01 10:50:15 -0700471 elapsed = time.time() - start
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700472 self.stdout.write( "*** Elapsed time: %0.6f secs\n" % elapsed )
adminbae64d82013-08-01 10:50:15 -0700473
474 def default( self, line ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000475 """Called on an input line when the command prefix is not recognized."""
adminbae64d82013-08-01 10:50:15 -0700476 first, args, line = self.parseline( line )
477 if not args:
478 return
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700479 if args and len( args ) > 0 and args[ -1 ] == '\n':
480 args = args[:-1 ]
adminbae64d82013-08-01 10:50:15 -0700481 rest = args.split( ' ' )
482
483 error( '*** Unknown command: %s\n' % first )
484
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700485class TestThread( threading.Thread ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000486 '''
adminbae64d82013-08-01 10:50:15 -0700487 TestThread class will handle the test execution and will communicate with the thread in the do_run.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000488 '''
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700489 def __init__( self, options ):
adminbae64d82013-08-01 10:50:15 -0700490 self._stopevent = threading.Event()
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700491 threading.Thread.__init__( self )
adminbae64d82013-08-01 10:50:15 -0700492 self.is_stop = False
493 self.options = options
494 __builtin__.testthread = self
495
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700496 def run( self ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000497 '''
adminbae64d82013-08-01 10:50:15 -0700498 Will execute the test.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000499 '''
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700500 while not self.is_stop:
adminbae64d82013-08-01 10:50:15 -0700501 if not self._stopevent.isSet():
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700502 self.test_on = TestON( self.options )
503 try:
adminbae64d82013-08-01 10:50:15 -0700504 if self.test_on.init_result:
505 result = self.test_on.run()
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700506 if not self.is_stop:
adminbae64d82013-08-01 10:50:15 -0700507 result = self.test_on.cleanup()
508 self.is_stop = True
Jon Hall1306a562015-09-04 11:21:24 -0700509 except KeyboardInterrupt:
510 print "Recevied Interrupt, cleaning-up the logs and drivers before exiting"
adminbae64d82013-08-01 10:50:15 -0700511 result = self.test_on.cleanup()
512 self.is_stop = True
513
Jon Hall4ba53f02015-07-29 13:07:41 -0700514 __builtin__.testthread = False
adminbae64d82013-08-01 10:50:15 -0700515
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700516 def pause( self ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000517 '''
adminbae64d82013-08-01 10:50:15 -0700518 Will pause the test.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000519 '''
Jon Hall1306a562015-09-04 11:21:24 -0700520 if not cli.pause:
521 print "Will pause the test's execution, after completion of this step.....\n\n\n\n"
522 cli.pause = True
523 self._stopevent.set()
524 elif cli.pause and self.is_stop:
525 print "KeyboardInterrupt, Exiting."
526 self.test_on.exit()
527 else:
528 print "Recevied Interrupt, cleaning-up the logs and drivers before exiting"
529 result = self.test_on.cleanup()
530 self.is_stop = True
adminbae64d82013-08-01 10:50:15 -0700531
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700532 def play( self ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000533 '''
adminbae64d82013-08-01 10:50:15 -0700534 Will resume the paused test.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000535 '''
adminbae64d82013-08-01 10:50:15 -0700536 self._stopevent.clear()
537 cli.pause = False
Jon Hall4ba53f02015-07-29 13:07:41 -0700538
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700539 def stop( self ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000540 '''
adminbae64d82013-08-01 10:50:15 -0700541 Will stop the test execution.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000542 '''
543
adminbae64d82013-08-01 10:50:15 -0700544 print "Stopping the test"
545 self.is_stop = True
546 cli.stop = True
547 __builtin__.testthread = False
Jon Hall4ba53f02015-07-29 13:07:41 -0700548
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700549def output( msg ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000550 '''
adminbae64d82013-08-01 10:50:15 -0700551 Simply, print the message in console
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000552 '''
adminbae64d82013-08-01 10:50:15 -0700553 print msg
554
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700555def error( msg ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000556 '''
adminbae64d82013-08-01 10:50:15 -0700557 print the error message.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000558 '''
adminbae64d82013-08-01 10:50:15 -0700559 print msg
560
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700561def dictToObj( dictionary ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000562 '''
adminbae64d82013-08-01 10:50:15 -0700563 This will facilitates the converting of the dictionary to the object.
564 This method will help to send options as object format to the test.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000565 '''
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700566 if isinstance( dictionary, list ):
567 dictionary = [ dictToObj( x ) for x in dictionary ]
568 if not isinstance( dictionary, dict ):
adminbae64d82013-08-01 10:50:15 -0700569 return dictionary
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700570
571 class Convert( object ):
adminbae64d82013-08-01 10:50:15 -0700572 pass
573 obj = Convert()
574 for k in dictionary:
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700575 obj.__dict__[ k ] = dictToObj( dictionary[ k ] )
adminbae64d82013-08-01 10:50:15 -0700576 return obj
577
578
579if __name__ == '__main__':
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700580 if len( sys.argv ) > 1:
Jon Hall0bde9ba2015-03-19 11:32:57 -0700581 __builtin__.COLORS = True
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700582 CLI( "test" ).onecmd( ' '.join( sys.argv[ 1: ] ) )
adminbae64d82013-08-01 10:50:15 -0700583 else:
Jon Hall0bde9ba2015-03-19 11:32:57 -0700584 __builtin__.COLORS = False
Jeremy Ronquillo696f4262017-10-17 10:56:26 -0700585 CLI( "test" ).cmdloop()