blob: 4cf26e56f173cc809a91ad074854c53958010c83 [file] [log] [blame]
Jon Hall05b2b432014-10-08 19:53:25 -04001#!/usr/bin/env python
andrewonlabe8e56fd2014-10-09 17:12:44 -04002
kelvin8ec71442015-01-15 16:57:00 -08003"""
4This driver interacts with ONOS bench, the OSGi platform
5that configures the ONOS nodes. ( aka ONOS-next )
andrewonlabe8e56fd2014-10-09 17:12:44 -04006
kelvin8ec71442015-01-15 16:57:00 -08007Please follow the coding style demonstrated by existing
andrewonlabe8e56fd2014-10-09 17:12:44 -04008functions and document properly.
9
10If you are a contributor to the driver, please
11list your email here for future contact:
12
13jhall@onlab.us
14andrew@onlab.us
15
16OCT 9 2014
17
kelvin8ec71442015-01-15 16:57:00 -080018"""
andrewonlab7735d852014-10-09 13:02:47 -040019import sys
Jon Hall05b2b432014-10-08 19:53:25 -040020import time
21import pexpect
andrewonlab7735d852014-10-09 13:02:47 -040022import os.path
kelvin8ec71442015-01-15 16:57:00 -080023sys.path.append( "../" )
Jon Hall05b2b432014-10-08 19:53:25 -040024from drivers.common.clidriver import CLI
25
Jon Hall05b2b432014-10-08 19:53:25 -040026
kelvin8ec71442015-01-15 16:57:00 -080027class OnosDriver( CLI ):
Jon Hall05b2b432014-10-08 19:53:25 -040028
kelvin8ec71442015-01-15 16:57:00 -080029 def __init__( self ):
30 """
31 Initialize client
32 """
Jon Hallefbd9792015-03-05 16:11:36 -080033 self.name = None
34 self.home = None
35 self.handle = None
kelvin8ec71442015-01-15 16:57:00 -080036 super( CLI, self ).__init__()
37
38 def connect( self, **connectargs ):
39 """
Jon Hall05b2b432014-10-08 19:53:25 -040040 Creates ssh handle for ONOS "bench".
kelvin8ec71442015-01-15 16:57:00 -080041 """
Jon Hall05b2b432014-10-08 19:53:25 -040042 try:
43 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080044 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us3b087132015-03-11 15:00:08 -070045 self.home = "~/onos"
Jon Hall05b2b432014-10-08 19:53:25 -040046 for key in self.options:
47 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080048 self.home = self.options[ 'home' ]
Jon Hall05b2b432014-10-08 19:53:25 -040049 break
Jon Hall274b6642015-02-17 11:57:17 -080050 if self.home is None or self.home == "":
kelvin-onlaba1484582015-02-02 15:46:20 -080051 self.home = "~/ONOS"
Jon Hall05b2b432014-10-08 19:53:25 -040052
kelvin8ec71442015-01-15 16:57:00 -080053 self.name = self.options[ 'name' ]
54 self.handle = super( OnosDriver, self ).connect(
55 user_name=self.user_name,
kelvin-onlab08679eb2015-01-21 16:11:48 -080056 ip_address=self.ip_address,
kelvin-onlabd3b64892015-01-20 13:26:24 -080057 port=self.port,
58 pwd=self.pwd,
59 home=self.home )
Jon Hall05b2b432014-10-08 19:53:25 -040060
kelvin8ec71442015-01-15 16:57:00 -080061 self.handle.sendline( "cd " + self.home )
62 self.handle.expect( "\$" )
Jon Hall05b2b432014-10-08 19:53:25 -040063 if self.handle:
64 return self.handle
kelvin8ec71442015-01-15 16:57:00 -080065 else:
66 main.log.info( "NO ONOS HANDLE" )
Jon Hall05b2b432014-10-08 19:53:25 -040067 return main.FALSE
68 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080069 main.log.error( self.name + ": EOF exception found" )
70 main.log.error( self.name + ": " + self.handle.before )
Jon Hall05b2b432014-10-08 19:53:25 -040071 main.cleanup()
72 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -080073 except Exception:
74 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall05b2b432014-10-08 19:53:25 -040075 main.cleanup()
76 main.exit()
77
kelvin8ec71442015-01-15 16:57:00 -080078 def disconnect( self ):
79 """
Jon Hall05b2b432014-10-08 19:53:25 -040080 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -080081 """
Jon Halld61331b2015-02-17 16:35:47 -080082 response = main.TRUE
Jon Hall05b2b432014-10-08 19:53:25 -040083 try:
kelvin8ec71442015-01-15 16:57:00 -080084 self.handle.sendline( "" )
85 self.handle.expect( "\$" )
86 self.handle.sendline( "exit" )
87 self.handle.expect( "closed" )
Jon Hall05b2b432014-10-08 19:53:25 -040088 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080089 main.log.error( self.name + ": EOF exception found" )
90 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -080091 except Exception:
92 main.log.exception( self.name + ": Connection failed to the host" )
Jon Hall05b2b432014-10-08 19:53:25 -040093 response = main.FALSE
94 return response
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -040095
kelvin-onlabd3b64892015-01-20 13:26:24 -080096 def onosPackage( self ):
kelvin8ec71442015-01-15 16:57:00 -080097 """
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -040098 Produce a self-contained tar.gz file that can be deployed
kelvin8ec71442015-01-15 16:57:00 -080099 and executed on any platform with Java 7 JRE.
100 """
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400101 try:
kelvin8ec71442015-01-15 16:57:00 -0800102 self.handle.sendline( "onos-package" )
103 self.handle.expect( "onos-package" )
104 self.handle.expect( "tar.gz", timeout=30 )
105 handle = str( self.handle.before )
106 main.log.info( "onos-package command returned: " +
107 handle )
108 # As long as the sendline does not time out,
109 # return true. However, be careful to interpret
110 # the results of the onos-package command return
andrewonlab0748d2a2014-10-09 13:24:17 -0400111 return main.TRUE
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400112
andrewonlab7735d852014-10-09 13:02:47 -0400113 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800114 main.log.error( self.name + ": EOF exception found" )
115 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -0800116 except Exception:
117 main.log.exception( "Failed to package ONOS" )
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400118 main.cleanup()
119 main.exit()
120
kelvin-onlabd3b64892015-01-20 13:26:24 -0800121 def onosBuild( self ):
kelvin8ec71442015-01-15 16:57:00 -0800122 """
andrewonlab8790abb2014-11-06 13:51:54 -0500123 Use the pre defined script to build onos via mvn
kelvin8ec71442015-01-15 16:57:00 -0800124 """
andrewonlab8790abb2014-11-06 13:51:54 -0500125 try:
kelvin8ec71442015-01-15 16:57:00 -0800126 self.handle.sendline( "onos-build" )
127 self.handle.expect( "onos-build" )
128 i = self.handle.expect( [
kelvin-onlabd3b64892015-01-20 13:26:24 -0800129 "BUILD SUCCESS",
130 "ERROR",
131 "BUILD FAILED" ],
132 timeout=120 )
kelvin8ec71442015-01-15 16:57:00 -0800133 handle = str( self.handle.before )
andrewonlab8790abb2014-11-06 13:51:54 -0500134
kelvin8ec71442015-01-15 16:57:00 -0800135 main.log.info( "onos-build command returned: " +
136 handle )
andrewonlab8790abb2014-11-06 13:51:54 -0500137
138 if i == 0:
139 return main.TRUE
140 else:
141 return handle
142
143 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800144 main.log.error( self.name + ": EOF exception found" )
145 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -0800146 except Exception:
147 main.log.exception( "Failed to build ONOS" )
andrewonlab8790abb2014-11-06 13:51:54 -0500148 main.cleanup()
149 main.exit()
150
kelvin-onlabd3b64892015-01-20 13:26:24 -0800151 def cleanInstall( self ):
kelvin8ec71442015-01-15 16:57:00 -0800152 """
153 Runs mvn clean install in the root of the ONOS directory.
154 This will clean all ONOS artifacts then compile each module
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400155
kelvin8ec71442015-01-15 16:57:00 -0800156 Returns: main.TRUE on success
Jon Hallde9d9aa2014-10-08 20:36:02 -0400157 On Failure, exits the test
kelvin8ec71442015-01-15 16:57:00 -0800158 """
Jon Hallde9d9aa2014-10-08 20:36:02 -0400159 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800160 main.log.info( "Running 'mvn clean install' on " +
161 str( self.name ) +
kelvin8ec71442015-01-15 16:57:00 -0800162 ". This may take some time." )
163 self.handle.sendline( "cd " + self.home )
164 self.handle.expect( "\$" )
Jon Hallea7818b2014-10-09 14:30:59 -0400165
kelvin8ec71442015-01-15 16:57:00 -0800166 self.handle.sendline( "" )
167 self.handle.expect( "\$" )
168 self.handle.sendline( "mvn clean install" )
169 self.handle.expect( "mvn clean install" )
170 while True:
171 i = self.handle.expect( [
Jon Hall274b6642015-02-17 11:57:17 -0800172 'There\sis\sinsufficient\smemory\sfor\sthe\sJava\s' +
Jon Hallefbd9792015-03-05 16:11:36 -0800173 'Runtime\sEnvironment\sto\scontinue',
Jon Hallde9d9aa2014-10-08 20:36:02 -0400174 'BUILD\sFAILURE',
175 'BUILD\sSUCCESS',
176 'ONOS\$',
kelvin8ec71442015-01-15 16:57:00 -0800177 pexpect.TIMEOUT ], timeout=600 )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400178 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800179 main.log.error( self.name + ":There is insufficient memory \
180 for the Java Runtime Environment to continue." )
181 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400182 main.cleanup()
183 main.exit()
184 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800185 main.log.error( self.name + ": Build failure!" )
186 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400187 main.cleanup()
188 main.exit()
189 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800190 main.log.info( self.name + ": Build success!" )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400191 elif i == 3:
kelvin8ec71442015-01-15 16:57:00 -0800192 main.log.info( self.name + ": Build complete" )
193 # Print the build time
Jon Hallf8ef52c2014-10-09 19:37:33 -0400194 for line in self.handle.before.splitlines():
195 if "Total time:" in line:
kelvin8ec71442015-01-15 16:57:00 -0800196 main.log.info( line )
197 self.handle.sendline( "" )
198 self.handle.expect( "\$", timeout=60 )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400199 return main.TRUE
200 elif i == 4:
kelvin8ec71442015-01-15 16:57:00 -0800201 main.log.error(
202 self.name +
203 ": mvn clean install TIMEOUT!" )
204 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400205 main.cleanup()
206 main.exit()
207 else:
Jon Hall274b6642015-02-17 11:57:17 -0800208 main.log.error( self.name + ": unexpected response from " +
Jon Hallefbd9792015-03-05 16:11:36 -0800209 "mvn clean install" )
kelvin8ec71442015-01-15 16:57:00 -0800210 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400211 main.cleanup()
212 main.exit()
213 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800214 main.log.error( self.name + ": EOF exception found" )
215 main.log.error( self.name + ": " + self.handle.before )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400216 main.cleanup()
217 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800218 except Exception:
219 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400220 main.cleanup()
221 main.exit()
Jon Hallacabffd2014-10-09 12:36:53 -0400222
kelvin-onlabd3b64892015-01-20 13:26:24 -0800223 def gitPull( self, comp1="" ):
kelvin8ec71442015-01-15 16:57:00 -0800224 """
Jon Hallacabffd2014-10-09 12:36:53 -0400225 Assumes that "git pull" works without login
Jon Hall47a93fb2015-01-06 16:46:06 -0800226
Jon Hallacabffd2014-10-09 12:36:53 -0400227 This function will perform a git pull on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800228 If used as gitPull( "NODE" ) it will do git pull + NODE. This is
Jon Hallacabffd2014-10-09 12:36:53 -0400229 for the purpose of pulling from other nodes if necessary.
230
Jon Hall47a93fb2015-01-06 16:46:06 -0800231 Otherwise, this function will perform a git pull in the
Jon Hallacabffd2014-10-09 12:36:53 -0400232 ONOS repository. If it has any problems, it will return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -0800233 If it successfully does a gitPull, it will return a 1 ( main.TRUE )
Shreya Shahee15f6c2014-10-28 18:12:30 -0400234 If it has no updates, it will return 3.
Jon Hallacabffd2014-10-09 12:36:53 -0400235
kelvin8ec71442015-01-15 16:57:00 -0800236 """
Jon Hallacabffd2014-10-09 12:36:53 -0400237 try:
kelvin8ec71442015-01-15 16:57:00 -0800238 # main.log.info( self.name + ": Stopping ONOS" )
239 # self.stop()
240 self.handle.sendline( "cd " + self.home )
kelvin-onlaba1484582015-02-02 15:46:20 -0800241 self.handle.expect( self.home + "\$" )
kelvin8ec71442015-01-15 16:57:00 -0800242 if comp1 == "":
243 self.handle.sendline( "git pull" )
Jon Hallacabffd2014-10-09 12:36:53 -0400244 else:
kelvin8ec71442015-01-15 16:57:00 -0800245 self.handle.sendline( "git pull " + comp1 )
Jon Hall47a93fb2015-01-06 16:46:06 -0800246
kelvin-onlabd3b64892015-01-20 13:26:24 -0800247 i = self.handle.expect(
248 [
249 'fatal',
250 'Username\sfor\s(.*):\s',
251 '\sfile(s*) changed,\s',
252 'Already up-to-date',
253 'Aborting',
254 'You\sare\snot\scurrently\son\sa\sbranch',
Jon Hall274b6642015-02-17 11:57:17 -0800255 'You asked me to pull without telling me which branch you',
256 'Pull is not possible because you have unmerged files',
kelvin-onlabd3b64892015-01-20 13:26:24 -0800257 pexpect.TIMEOUT ],
258 timeout=300 )
kelvin8ec71442015-01-15 16:57:00 -0800259 # debug
kelvin-onlabd3b64892015-01-20 13:26:24 -0800260 # main.log.report( self.name +": DEBUG: \n"+
261 # "git pull response: " +
262 # str( self.handle.before ) + str( self.handle.after ) )
kelvin8ec71442015-01-15 16:57:00 -0800263 if i == 0:
264 main.log.error( self.name + ": Git pull had some issue..." )
Jon Hallacabffd2014-10-09 12:36:53 -0400265 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800266 elif i == 1:
267 main.log.error(
268 self.name +
269 ": Git Pull Asking for username. " )
Jon Hallacabffd2014-10-09 12:36:53 -0400270 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800271 elif i == 2:
272 main.log.info(
273 self.name +
274 ": Git Pull - pulling repository now" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800275 self.handle.expect( self.home + "\$", 120 )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800276 # So that only when git pull is done, we do mvn clean compile
277 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800278 elif i == 3:
279 main.log.info( self.name + ": Git Pull - Already up to date" )
Jon Hall47a93fb2015-01-06 16:46:06 -0800280 return i
kelvin8ec71442015-01-15 16:57:00 -0800281 elif i == 4:
282 main.log.info(
283 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800284 ": Git Pull - Aborting..." +
285 "Are there conflicting git files?" )
Jon Hallacabffd2014-10-09 12:36:53 -0400286 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800287 elif i == 5:
288 main.log.info(
289 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800290 ": Git Pull - You are not currently " +
291 "on a branch so git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400292 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800293 elif i == 6:
294 main.log.info(
295 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800296 ": Git Pull - You have not configured an upstream " +
297 "branch to pull from. Git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400298 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800299 elif i == 7:
300 main.log.info(
301 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800302 ": Git Pull - Pull is not possible because " +
303 "you have unmerged files." )
Jon Hallacabffd2014-10-09 12:36:53 -0400304 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800305 elif i == 8:
306 main.log.error( self.name + ": Git Pull - TIMEOUT" )
307 main.log.error(
308 self.name + " Response was: " + str(
309 self.handle.before ) )
Jon Hallacabffd2014-10-09 12:36:53 -0400310 return main.ERROR
311 else:
kelvin8ec71442015-01-15 16:57:00 -0800312 main.log.error(
313 self.name +
314 ": Git Pull - Unexpected response, check for pull errors" )
Jon Hallacabffd2014-10-09 12:36:53 -0400315 return main.ERROR
316 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800317 main.log.error( self.name + ": EOF exception found" )
318 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400319 main.cleanup()
320 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800321 except Exception:
322 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400323 main.cleanup()
324 main.exit()
325
kelvin-onlabd3b64892015-01-20 13:26:24 -0800326 def gitCheckout( self, branch="master" ):
kelvin8ec71442015-01-15 16:57:00 -0800327 """
Jon Hallacabffd2014-10-09 12:36:53 -0400328 Assumes that "git pull" works without login
kelvin8ec71442015-01-15 16:57:00 -0800329
Jon Hallacabffd2014-10-09 12:36:53 -0400330 This function will perform a git git checkout on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800331 If used as gitCheckout( "branch" ) it will do git checkout
332 of the "branch".
Jon Hallacabffd2014-10-09 12:36:53 -0400333
334 Otherwise, this function will perform a git checkout of the master
kelvin8ec71442015-01-15 16:57:00 -0800335 branch of the ONOS repository. If it has any problems, it will return
336 main.ERROR.
337 If the branch was already the specified branch, or the git checkout was
Jon Hallacabffd2014-10-09 12:36:53 -0400338 successful then the function will return main.TRUE.
339
kelvin8ec71442015-01-15 16:57:00 -0800340 """
Jon Hallacabffd2014-10-09 12:36:53 -0400341 try:
kelvin8ec71442015-01-15 16:57:00 -0800342 self.handle.sendline( "cd " + self.home )
kelvin-onlaba1484582015-02-02 15:46:20 -0800343 self.handle.expect( self.home + "\$" )
Jon Hall274b6642015-02-17 11:57:17 -0800344 main.log.info( self.name +
345 ": Checking out git branch/ref: " + branch + "..." )
kelvin8ec71442015-01-15 16:57:00 -0800346 cmd = "git checkout " + branch
347 self.handle.sendline( cmd )
348 self.handle.expect( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800349 i = self.handle.expect(
Jon Hall274b6642015-02-17 11:57:17 -0800350 [ 'fatal',
351 'Username\sfor\s(.*):\s',
352 'Already\son\s\'',
353 'Switched\sto\sbranch\s\'' + str( branch ),
354 pexpect.TIMEOUT,
355 'error: Your local changes to the following files' +
Jon Hallefbd9792015-03-05 16:11:36 -0800356 'would be overwritten by checkout:',
Jon Hall274b6642015-02-17 11:57:17 -0800357 'error: you need to resolve your current index first',
358 "You are in 'detached HEAD' state.",
359 "HEAD is now at " ],
kelvin-onlabd3b64892015-01-20 13:26:24 -0800360 timeout=60 )
kelvin8ec71442015-01-15 16:57:00 -0800361 if i == 0:
362 main.log.error(
363 self.name +
364 ": Git checkout had some issue..." )
365 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400366 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800367 elif i == 1:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800368 main.log.error(
369 self.name +
370 ": Git checkout asking for username." +
371 " Please configure your local git repository to be able " +
372 "to access your remote repository passwordlessly" )
Jon Hall274b6642015-02-17 11:57:17 -0800373 # TODO add support for authenticating
Jon Hallacabffd2014-10-09 12:36:53 -0400374 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800375 elif i == 2:
376 main.log.info(
377 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800378 ": Git Checkout %s : Already on this branch" % branch )
kelvin-onlaba1484582015-02-02 15:46:20 -0800379 self.handle.expect( self.home + "\$" )
kelvin8ec71442015-01-15 16:57:00 -0800380 # main.log.info( "DEBUG: after checkout cmd = "+
381 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400382 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800383 elif i == 3:
384 main.log.info(
385 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800386 ": Git checkout %s - Switched to this branch" % branch )
kelvin-onlaba1484582015-02-02 15:46:20 -0800387 self.handle.expect( self.home + "\$" )
kelvin8ec71442015-01-15 16:57:00 -0800388 # main.log.info( "DEBUG: after checkout cmd = "+
389 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400390 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800391 elif i == 4:
392 main.log.error( self.name + ": Git Checkout- TIMEOUT" )
393 main.log.error(
Jon Hall274b6642015-02-17 11:57:17 -0800394 self.name + " Response was: " + str( self.handle.before ) )
Jon Hallacabffd2014-10-09 12:36:53 -0400395 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800396 elif i == 5:
397 self.handle.expect( "Aborting" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800398 main.log.error(
399 self.name +
400 ": Git checkout error: \n" +
Jon Hall274b6642015-02-17 11:57:17 -0800401 "Your local changes to the following files would" +
402 " be overwritten by checkout:" +
403 str( self.handle.before ) )
kelvin-onlaba1484582015-02-02 15:46:20 -0800404 self.handle.expect( self.home + "\$" )
Jon Hall81e29af2014-11-04 20:41:23 -0500405 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800406 elif i == 6:
Jon Hall274b6642015-02-17 11:57:17 -0800407 main.log.error(
408 self.name +
409 ": Git checkout error: \n" +
410 "You need to resolve your current index first:" +
411 str( self.handle.before ) )
kelvin-onlaba1484582015-02-02 15:46:20 -0800412 self.handle.expect( self.home + "\$" )
Jon Hall81e29af2014-11-04 20:41:23 -0500413 return main.ERROR
Jon Hall274b6642015-02-17 11:57:17 -0800414 elif i == 7:
415 main.log.info(
416 self.name +
417 ": Git checkout " + str( branch ) +
418 " - You are in 'detached HEAD' state. HEAD is now at " +
419 str( branch ) )
420 self.handle.expect( self.home + "\$" )
421 return main.TRUE
422 elif i == 8: # Already in detached HEAD on the specified commit
423 main.log.info(
424 self.name +
425 ": Git Checkout %s : Already on commit" % branch )
426 self.handle.expect( self.home + "\$" )
427 return main.TRUE
Jon Hallacabffd2014-10-09 12:36:53 -0400428 else:
kelvin8ec71442015-01-15 16:57:00 -0800429 main.log.error(
430 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800431 ": Git Checkout - Unexpected response, " +
432 "check for pull errors" )
kelvin8ec71442015-01-15 16:57:00 -0800433 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400434 return main.ERROR
435
436 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800437 main.log.error( self.name + ": EOF exception found" )
438 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400439 main.cleanup()
440 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800441 except Exception:
442 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400443 main.cleanup()
444 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400445
kelvin-onlabd3b64892015-01-20 13:26:24 -0800446 def getVersion( self, report=False ):
kelvin8ec71442015-01-15 16:57:00 -0800447 """
Jon Hall274b6642015-02-17 11:57:17 -0800448 Writes the COMMIT number to the report to be parsed
Jon Hallefbd9792015-03-05 16:11:36 -0800449 by Jenkins data collector.
kelvin8ec71442015-01-15 16:57:00 -0800450 """
Jon Hall45ec0922014-10-10 19:33:49 -0400451 try:
kelvin8ec71442015-01-15 16:57:00 -0800452 self.handle.sendline( "" )
453 self.handle.expect( "\$" )
454 self.handle.sendline(
455 "cd " +
456 self.home +
Jon Hall274b6642015-02-17 11:57:17 -0800457 "; git log -1 --pretty=fuller --decorate=short | grep -A 6 " +
458 " \"commit\" --color=never" )
kelvin8ec71442015-01-15 16:57:00 -0800459 # NOTE: for some reason there are backspaces inserted in this
460 # phrase when run from Jenkins on some tests
461 self.handle.expect( "never" )
462 self.handle.expect( "\$" )
463 response = ( self.name + ": \n" + str(
464 self.handle.before + self.handle.after ) )
465 self.handle.sendline( "cd " + self.home )
466 self.handle.expect( "\$" )
467 lines = response.splitlines()
Jon Hall45ec0922014-10-10 19:33:49 -0400468 for line in lines:
Jon Hallfd191202014-11-07 18:36:09 -0500469 print line
470 if report:
kelvin8ec71442015-01-15 16:57:00 -0800471 for line in lines[ 2:-1 ]:
472 # Bracket replacement is for Wiki-compliant
473 # formatting. '<' or '>' are interpreted
474 # as xml specific tags that cause errors
475 line = line.replace( "<", "[" )
476 line = line.replace( ">", "]" )
477 main.log.report( "\t" + line )
478 return lines[ 2 ]
Jon Hall45ec0922014-10-10 19:33:49 -0400479 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800480 main.log.error( self.name + ": EOF exception found" )
481 main.log.error( self.name + ": " + self.handle.before )
Jon Hall45ec0922014-10-10 19:33:49 -0400482 main.cleanup()
483 main.exit()
Jon Hall368769f2014-11-19 15:43:35 -0800484 except pexpect.TIMEOUT:
kelvin8ec71442015-01-15 16:57:00 -0800485 main.log.error( self.name + ": TIMEOUT exception found" )
486 main.log.error( self.name + ": " + self.handle.before )
Jon Hall368769f2014-11-19 15:43:35 -0800487 main.cleanup()
488 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800489 except Exception:
490 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall45ec0922014-10-10 19:33:49 -0400491 main.cleanup()
492 main.exit()
493
kelvin-onlabd3b64892015-01-20 13:26:24 -0800494 def createCellFile( self, benchIp, fileName, mnIpAddrs,
Jon Hallefbd9792015-03-05 16:11:36 -0800495 extraFeatureString, *onosIpAddrs ):
kelvin8ec71442015-01-15 16:57:00 -0800496 """
andrewonlab94282092014-10-10 13:00:11 -0400497 Creates a cell file based on arguments
498 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800499 * Bench IP address ( benchIp )
andrewonlab94282092014-10-10 13:00:11 -0400500 - Needed to copy the cell file over
kelvin-onlabd3b64892015-01-20 13:26:24 -0800501 * File name of the cell file ( fileName )
502 * Mininet IP address ( mnIpAddrs )
kelvin8ec71442015-01-15 16:57:00 -0800503 - Note that only 1 ip address is
andrewonlab94282092014-10-10 13:00:11 -0400504 supported currently
kelvin-onlabd3b64892015-01-20 13:26:24 -0800505 * ONOS IP addresses ( onosIpAddrs )
andrewonlab94282092014-10-10 13:00:11 -0400506 - Must be passed in as last arguments
kelvin8ec71442015-01-15 16:57:00 -0800507
andrewonlab94282092014-10-10 13:00:11 -0400508 NOTE: Assumes cells are located at:
509 ~/<self.home>/tools/test/cells/
kelvin8ec71442015-01-15 16:57:00 -0800510 """
511 # Variable initialization
kelvin-onlabd3b64892015-01-20 13:26:24 -0800512 cellDirectory = self.home + "/tools/test/cells/"
kelvin8ec71442015-01-15 16:57:00 -0800513 # We want to create the cell file in the dependencies directory
514 # of TestON first, then copy over to ONOS bench
kelvin-onlabd3b64892015-01-20 13:26:24 -0800515 tempDirectory = "/tmp/"
kelvin8ec71442015-01-15 16:57:00 -0800516 # Create the cell file in the directory for writing ( w+ )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800517 cellFile = open( tempDirectory + fileName, 'w+' )
kelvin8ec71442015-01-15 16:57:00 -0800518
519 # Feature string is hardcoded environment variables
520 # That you may wish to use by default on startup.
521 # Note that you may not want certain features listed
522 # on here.
andrew@onlab.us3b087132015-03-11 15:00:08 -0700523 coreFeatureString = "export ONOS_FEATURES=" + extraFeatureString
kelvin-onlabd3b64892015-01-20 13:26:24 -0800524 mnString = "export OCN="
525 onosString = "export OC"
526 tempCount = 1
kelvin8ec71442015-01-15 16:57:00 -0800527
kelvin-onlabd3b64892015-01-20 13:26:24 -0800528 # Create ONOSNIC ip address prefix
529 tempOnosIp = onosIpAddrs[ 0 ]
530 tempList = []
531 tempList = tempOnosIp.split( "." )
kelvin8ec71442015-01-15 16:57:00 -0800532 # Omit last element of list to format for NIC
kelvin-onlabd3b64892015-01-20 13:26:24 -0800533 tempList = tempList[ :-1 ]
kelvin8ec71442015-01-15 16:57:00 -0800534 # Structure the nic string ip
kelvin-onlabd3b64892015-01-20 13:26:24 -0800535 nicAddr = ".".join( tempList ) + ".*"
536 onosNicString = "export ONOS_NIC=" + nicAddr
andrewonlab94282092014-10-10 13:00:11 -0400537
538 try:
kelvin8ec71442015-01-15 16:57:00 -0800539 # Start writing to file
kelvin-onlabd3b64892015-01-20 13:26:24 -0800540 cellFile.write( onosNicString + "\n" )
andrewonlab94282092014-10-10 13:00:11 -0400541
kelvin-onlabd3b64892015-01-20 13:26:24 -0800542 for arg in onosIpAddrs:
543 # For each argument in onosIpAddrs, write to file
kelvin8ec71442015-01-15 16:57:00 -0800544 # Output should look like the following:
andrewonlabd4940492014-10-24 12:21:27 -0400545 # export OC1="10.128.20.11"
546 # export OC2="10.128.20.12"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800547 cellFile.write( onosString + str( tempCount ) +
548 "=" + "\"" + arg + "\"" + "\n" )
549 tempCount = tempCount + 1
kelvin8ec71442015-01-15 16:57:00 -0800550
kelvin-onlabd3b64892015-01-20 13:26:24 -0800551 cellFile.write( mnString + "\"" + mnIpAddrs + "\"" + "\n" )
552 cellFile.write( coreFeatureString + "\n" )
553 cellFile.close()
andrewonlab94282092014-10-10 13:00:11 -0400554
kelvin8ec71442015-01-15 16:57:00 -0800555 # We use os.system to send the command to TestON cluster
556 # to account for the case in which TestON is not located
557 # on the same cluster as the ONOS bench
558 # Note that even if TestON is located on the same cluster
559 # as ONOS bench, you must setup passwordless ssh
560 # between TestON and ONOS bench in order to automate the test.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800561 os.system( "scp " + tempDirectory + fileName +
562 " admin@" + benchIp + ":" + cellDirectory )
andrewonlab94282092014-10-10 13:00:11 -0400563
andrewonlab2a6c9342014-10-16 13:40:15 -0400564 return main.TRUE
565
andrewonlab94282092014-10-10 13:00:11 -0400566 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800567 main.log.error( self.name + ": EOF exception found" )
568 main.log.error( self.name + ": " + self.handle.before )
andrewonlab94282092014-10-10 13:00:11 -0400569 main.cleanup()
570 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800571 except Exception:
572 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab94282092014-10-10 13:00:11 -0400573 main.cleanup()
574 main.exit()
575
kelvin-onlabd3b64892015-01-20 13:26:24 -0800576 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800577 """
andrewonlab95ca1462014-10-09 14:04:24 -0400578 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800579 """
andrewonlab95ca1462014-10-09 14:04:24 -0400580 try:
581 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800582 main.log.error( "Must define cellname" )
andrewonlab95ca1462014-10-09 14:04:24 -0400583 main.cleanup()
584 main.exit()
585 else:
kelvin8ec71442015-01-15 16:57:00 -0800586 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800587 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800588 # Note that this variable name is subject to change
andrewonlab95ca1462014-10-09 14:04:24 -0400589 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800590 self.handle.expect(str(cellname))
andrew@onlab.us98eab872015-01-22 14:41:34 -0800591 handleBefore = self.handle.before
592 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800593 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800594 self.handle.sendline("")
595 self.handle.expect("\$")
andrew@onlab.us98eab872015-01-22 14:41:34 -0800596 handleMore = self.handle.before
andrewonlab95ca1462014-10-09 14:04:24 -0400597
kelvin-onlabd3b64892015-01-20 13:26:24 -0800598 main.log.info( "Cell call returned: " + handleBefore +
599 handleAfter + handleMore )
andrewonlab95ca1462014-10-09 14:04:24 -0400600
601 return main.TRUE
602
603 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800604 main.log.error( self.name + ": EOF exception found" )
605 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ca1462014-10-09 14:04:24 -0400606 main.cleanup()
607 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800608 except Exception:
609 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ca1462014-10-09 14:04:24 -0400610 main.cleanup()
611 main.exit()
612
kelvin-onlabd3b64892015-01-20 13:26:24 -0800613 def verifyCell( self ):
kelvin8ec71442015-01-15 16:57:00 -0800614 """
andrewonlabc03bf6c2014-10-09 14:56:18 -0400615 Calls 'onos-verify-cell' to check for cell installation
kelvin8ec71442015-01-15 16:57:00 -0800616 """
617 # TODO: Add meaningful expect value
andrewonlab8d0d7d72014-10-09 16:33:15 -0400618
andrewonlabc03bf6c2014-10-09 14:56:18 -0400619 try:
kelvin8ec71442015-01-15 16:57:00 -0800620 # Clean handle by sending empty and expecting $
621 self.handle.sendline( "" )
622 self.handle.expect( "\$" )
623 self.handle.sendline( "onos-verify-cell" )
624 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800625 handleBefore = self.handle.before
626 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800627 # Get the rest of the handle
628 self.handle.sendline( "" )
629 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800630 handleMore = self.handle.before
andrewonlabc03bf6c2014-10-09 14:56:18 -0400631
kelvin-onlabd3b64892015-01-20 13:26:24 -0800632 main.log.info( "Verify cell returned: " + handleBefore +
633 handleAfter + handleMore )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400634
635 return main.TRUE
Jon Halla5cb6172015-02-23 09:28:28 -0800636 except pexpect.ExceptionPexpect as e:
637 main.log.error( self.name + ": Pexpect exception found of type " +
638 str( type( e ) ) )
639 main.log.error ( e.get_trace() )
kelvin8ec71442015-01-15 16:57:00 -0800640 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -0400641 main.cleanup()
642 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800643 except Exception:
644 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400645 main.cleanup()
646 main.exit()
647
kelvin-onlabd3b64892015-01-20 13:26:24 -0800648 def onosCli( self, ONOSIp, cmdstr ):
kelvin8ec71442015-01-15 16:57:00 -0800649 """
andrewonlab05e362f2014-10-10 00:40:57 -0400650 Uses 'onos' command to send various ONOS CLI arguments.
651 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800652 * ONOSIp: specify the ip of the cell machine
andrewonlab94282092014-10-10 13:00:11 -0400653 * cmdstr: specify the command string to send
kelvin8ec71442015-01-15 16:57:00 -0800654
655 This function is intended to expose the entire karaf
andrewonlab6e20c342014-10-10 18:08:48 -0400656 CLI commands for ONOS. Try to use this function first
657 before attempting to write a ONOS CLI specific driver
kelvin8ec71442015-01-15 16:57:00 -0800658 function.
659 You can see a list of available 'cmdstr' arguments
andrewonlab6e20c342014-10-10 18:08:48 -0400660 by starting onos, and typing in 'onos' to enter the
661 onos> CLI. Then, type 'help' to see the list of
kelvin8ec71442015-01-15 16:57:00 -0800662 available commands.
663 """
andrewonlab05e362f2014-10-10 00:40:57 -0400664 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800665 if not ONOSIp:
kelvin8ec71442015-01-15 16:57:00 -0800666 main.log.error( "You must specify the IP address" )
andrewonlab05e362f2014-10-10 00:40:57 -0400667 return main.FALSE
668 if not cmdstr:
kelvin8ec71442015-01-15 16:57:00 -0800669 main.log.error( "You must specify the command string" )
andrewonlab05e362f2014-10-10 00:40:57 -0400670 return main.FALSE
671
kelvin8ec71442015-01-15 16:57:00 -0800672 cmdstr = str( cmdstr )
673 self.handle.sendline( "" )
674 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400675
kelvin-onlabd3b64892015-01-20 13:26:24 -0800676 self.handle.sendline( "onos -w " + ONOSIp + " " + cmdstr )
kelvin8ec71442015-01-15 16:57:00 -0800677 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400678
kelvin-onlabd3b64892015-01-20 13:26:24 -0800679 handleBefore = self.handle.before
Shreya Shaha73aaad2014-10-27 18:03:09 -0400680 print "handle_before = ", self.handle.before
kelvin-onlabd3b64892015-01-20 13:26:24 -0800681 # handleAfter = str( self.handle.after )
Jon Hall47a93fb2015-01-06 16:46:06 -0800682
kelvin8ec71442015-01-15 16:57:00 -0800683 # self.handle.sendline( "" )
684 # self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800685 # handleMore = str( self.handle.before )
andrewonlab05e362f2014-10-10 00:40:57 -0400686
kelvin8ec71442015-01-15 16:57:00 -0800687 main.log.info( "Command sent successfully" )
andrewonlab05e362f2014-10-10 00:40:57 -0400688
kelvin8ec71442015-01-15 16:57:00 -0800689 # Obtain return handle that consists of result from
690 # the onos command. The string may need to be
691 # configured further.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800692 # returnString = handleBefore + handleAfter
693 returnString = handleBefore
694 print "return_string = ", returnString
695 return returnString
andrewonlab05e362f2014-10-10 00:40:57 -0400696
697 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800698 main.log.error( self.name + ": EOF exception found" )
699 main.log.error( self.name + ": " + self.handle.before )
andrewonlab05e362f2014-10-10 00:40:57 -0400700 main.cleanup()
701 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800702 except Exception:
703 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab05e362f2014-10-10 00:40:57 -0400704 main.cleanup()
705 main.exit()
Jon Hall7993bfc2014-10-09 16:30:14 -0400706
kelvin-onlabd3b64892015-01-20 13:26:24 -0800707 def onosInstall( self, options="-f", node="" ):
kelvin8ec71442015-01-15 16:57:00 -0800708 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400709 Installs ONOS bits on the designated cell machine.
kelvin8ec71442015-01-15 16:57:00 -0800710 If -f option is provided, it also forces an uninstall.
711 Presently, install also includes onos-push-bits and
Jon Hall7993bfc2014-10-09 16:30:14 -0400712 onos-config within.
kelvin8ec71442015-01-15 16:57:00 -0800713 The node option allows you to selectively only push the jar
Jon Hall7993bfc2014-10-09 16:30:14 -0400714 files to certain onos nodes
715
716 Returns: main.TRUE on success and main.FALSE on failure
kelvin8ec71442015-01-15 16:57:00 -0800717 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400718 try:
andrewonlab114768a2014-11-14 12:44:44 -0500719 if options:
kelvin8ec71442015-01-15 16:57:00 -0800720 self.handle.sendline( "onos-install " + options + " " + node )
andrewonlab114768a2014-11-14 12:44:44 -0500721 else:
kelvin8ec71442015-01-15 16:57:00 -0800722 self.handle.sendline( "onos-install " + node )
723 self.handle.expect( "onos-install " )
724 # NOTE: this timeout may need to change depending on the network
725 # and size of ONOS
726 i = self.handle.expect( [ "Network\sis\sunreachable",
kelvin-onlabd3b64892015-01-20 13:26:24 -0800727 "onos\sstart/running,\sprocess",
kelvin8ec71442015-01-15 16:57:00 -0800728 "ONOS\sis\salready\sinstalled",
729 pexpect.TIMEOUT ], timeout=60 )
Jon Hall7993bfc2014-10-09 16:30:14 -0400730
Jon Hall7993bfc2014-10-09 16:30:14 -0400731 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800732 main.log.warn( "Network is unreachable" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400733 return main.FALSE
734 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800735 main.log.info(
736 "ONOS was installed on " +
737 node +
738 " and started" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400739 return main.TRUE
andrewonlabd9a73a72014-11-14 17:28:21 -0500740 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800741 main.log.info( "ONOS is already installed on " + node )
andrewonlabd9a73a72014-11-14 17:28:21 -0500742 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800743 elif i == 3:
744 main.log.info(
745 "Installation of ONOS on " +
746 node +
747 " timed out" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400748 return main.FALSE
andrewonlabc03bf6c2014-10-09 14:56:18 -0400749
750 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800751 main.log.error( self.name + ": EOF exception found" )
752 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400753 main.cleanup()
754 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800755 except Exception:
756 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400757 main.cleanup()
758 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400759
kelvin-onlabd3b64892015-01-20 13:26:24 -0800760 def onosStart( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800761 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400762 Calls onos command: 'onos-service [<node-ip>] start'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400763 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -0800764 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400765 try:
kelvin8ec71442015-01-15 16:57:00 -0800766 self.handle.sendline( "" )
767 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800768 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -0800769 " start" )
770 i = self.handle.expect( [
andrewonlab8d0d7d72014-10-09 16:33:15 -0400771 "Job\sis\salready\srunning",
772 "start/running",
773 "Unknown\sinstance",
kelvin8ec71442015-01-15 16:57:00 -0800774 pexpect.TIMEOUT ], timeout=120 )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400775
776 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800777 main.log.info( "Service is already running" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400778 return main.TRUE
779 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800780 main.log.info( "ONOS service started" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400781 return main.TRUE
782 else:
kelvin8ec71442015-01-15 16:57:00 -0800783 main.log.error( "ONOS service failed to start" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400784 main.cleanup()
785 main.exit()
andrewonlab8d0d7d72014-10-09 16:33:15 -0400786 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800787 main.log.error( self.name + ": EOF exception found" )
788 main.log.error( self.name + ": " + self.handle.before )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400789 main.cleanup()
790 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800791 except Exception:
792 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400793 main.cleanup()
794 main.exit()
795
kelvin-onlabd3b64892015-01-20 13:26:24 -0800796 def onosStop( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800797 """
andrewonlab2b30bd32014-10-09 16:48:55 -0400798 Calls onos command: 'onos-service [<node-ip>] stop'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400799 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -0800800 """
andrewonlab2b30bd32014-10-09 16:48:55 -0400801 try:
kelvin8ec71442015-01-15 16:57:00 -0800802 self.handle.sendline( "" )
803 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800804 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -0800805 " stop" )
806 i = self.handle.expect( [
andrewonlab2b30bd32014-10-09 16:48:55 -0400807 "stop/waiting",
808 "Unknown\sinstance",
kelvin8ec71442015-01-15 16:57:00 -0800809 pexpect.TIMEOUT ], timeout=60 )
andrewonlab2b30bd32014-10-09 16:48:55 -0400810
811 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800812 main.log.info( "ONOS service stopped" )
andrewonlab2b30bd32014-10-09 16:48:55 -0400813 return main.TRUE
814 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800815 main.log.info( "Unknown ONOS instance specified: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800816 str( nodeIp ) )
andrewonlab2b30bd32014-10-09 16:48:55 -0400817 return main.FALSE
818 else:
kelvin8ec71442015-01-15 16:57:00 -0800819 main.log.error( "ONOS service failed to stop" )
andrewonlab2b30bd32014-10-09 16:48:55 -0400820 return main.FALSE
821
822 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800823 main.log.error( self.name + ": EOF exception found" )
824 main.log.error( self.name + ": " + self.handle.before )
andrewonlab2b30bd32014-10-09 16:48:55 -0400825 main.cleanup()
826 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800827 except Exception:
828 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab2b30bd32014-10-09 16:48:55 -0400829 main.cleanup()
830 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800831
kelvin-onlabd3b64892015-01-20 13:26:24 -0800832 def onosUninstall( self, nodeIp="" ):
kelvin8ec71442015-01-15 16:57:00 -0800833 """
andrewonlabc8d47972014-10-09 16:52:36 -0400834 Calls the command: 'onos-uninstall'
kelvin8ec71442015-01-15 16:57:00 -0800835 Uninstalls ONOS from the designated cell machine, stopping
andrewonlabe8e56fd2014-10-09 17:12:44 -0400836 if needed
kelvin8ec71442015-01-15 16:57:00 -0800837 """
andrewonlabc8d47972014-10-09 16:52:36 -0400838 try:
kelvin8ec71442015-01-15 16:57:00 -0800839 self.handle.sendline( "" )
840 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800841 self.handle.sendline( "onos-uninstall " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800842 self.handle.expect( "\$" )
andrewonlabc8d47972014-10-09 16:52:36 -0400843
kelvin-onlabd3b64892015-01-20 13:26:24 -0800844 main.log.info( "ONOS " + nodeIp + " was uninstalled" )
andrewonlab9dfd2082014-11-13 17:44:03 -0500845
kelvin8ec71442015-01-15 16:57:00 -0800846 # onos-uninstall command does not return any text
andrewonlabc8d47972014-10-09 16:52:36 -0400847 return main.TRUE
848
849 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800850 main.log.error( self.name + ": EOF exception found" )
851 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc8d47972014-10-09 16:52:36 -0400852 main.cleanup()
853 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800854 except Exception:
855 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc8d47972014-10-09 16:52:36 -0400856 main.cleanup()
857 main.exit()
andrewonlab2b30bd32014-10-09 16:48:55 -0400858
kelvin-onlabd3b64892015-01-20 13:26:24 -0800859 def onosDie( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800860 """
andrewonlabaedc8332014-12-04 12:43:03 -0500861 Issues the command 'onos-die <node-ip>'
862 This command calls onos-kill and also stops the node
kelvin8ec71442015-01-15 16:57:00 -0800863 """
andrewonlabaedc8332014-12-04 12:43:03 -0500864 try:
kelvin8ec71442015-01-15 16:57:00 -0800865 self.handle.sendline( "" )
866 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800867 cmdStr = "onos-kill " + str( nodeIp )
868 self.handle.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -0800869 i = self.handle.expect( [
andrewonlabaedc8332014-12-04 12:43:03 -0500870 "Killing\sONOS",
871 "ONOS\sprocess\sis\snot\srunning",
kelvin8ec71442015-01-15 16:57:00 -0800872 pexpect.TIMEOUT ], timeout=20 )
andrewonlabaedc8332014-12-04 12:43:03 -0500873 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800874 main.log.info( "ONOS instance " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -0800875 " was killed and stopped" )
andrewonlabaedc8332014-12-04 12:43:03 -0500876 return main.TRUE
877 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800878 main.log.info( "ONOS process was not running" )
andrewonlabaedc8332014-12-04 12:43:03 -0500879 return main.FALSE
880 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800881 main.log.error( self.name + ": EOF exception found" )
882 main.log.error( self.name + ": " + self.handle.before )
andrewonlabaedc8332014-12-04 12:43:03 -0500883 main.cleanup()
884 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800885 except Exception:
886 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabaedc8332014-12-04 12:43:03 -0500887 main.cleanup()
888 main.exit()
889
kelvin-onlabd3b64892015-01-20 13:26:24 -0800890 def onosKill( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800891 """
andrewonlabe8e56fd2014-10-09 17:12:44 -0400892 Calls the command: 'onos-kill [<node-ip>]'
893 "Remotely, and unceremoniously kills the ONOS instance running on
894 the specified cell machine" - Tom V
kelvin8ec71442015-01-15 16:57:00 -0800895 """
andrewonlabe8e56fd2014-10-09 17:12:44 -0400896 try:
kelvin8ec71442015-01-15 16:57:00 -0800897 self.handle.sendline( "" )
898 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800899 self.handle.sendline( "onos-kill " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800900 i = self.handle.expect( [
andrewonlabe8e56fd2014-10-09 17:12:44 -0400901 "\$",
902 "No\sroute\sto\shost",
903 "password:",
kelvin8ec71442015-01-15 16:57:00 -0800904 pexpect.TIMEOUT ], timeout=20 )
905
andrewonlabe8e56fd2014-10-09 17:12:44 -0400906 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800907 main.log.info(
908 "ONOS instance " + str(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800909 nodeIp ) + " was killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -0400910 return main.TRUE
911 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800912 main.log.info( "No route to host" )
andrewonlabe8e56fd2014-10-09 17:12:44 -0400913 return main.FALSE
914 elif i == 2:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800915 main.log.info(
916 "Passwordless login for host: " +
917 str( nodeIp ) +
918 " not configured" )
andrewonlabe8e56fd2014-10-09 17:12:44 -0400919 return main.FALSE
920 else:
Jon Hallefbd9792015-03-05 16:11:36 -0800921 main.log.info( "ONOS instance was not killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -0400922 return main.FALSE
kelvin8ec71442015-01-15 16:57:00 -0800923
andrewonlabe8e56fd2014-10-09 17:12:44 -0400924 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800925 main.log.error( self.name + ": EOF exception found" )
926 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe8e56fd2014-10-09 17:12:44 -0400927 main.cleanup()
928 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800929 except Exception:
930 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe8e56fd2014-10-09 17:12:44 -0400931 main.cleanup()
932 main.exit()
933
kelvin-onlabd3b64892015-01-20 13:26:24 -0800934 def onosRemoveRaftLogs( self ):
kelvin8ec71442015-01-15 16:57:00 -0800935 """
andrewonlab19fbdca2014-11-14 12:55:59 -0500936 Removes Raft / Copy cat files from ONOS to ensure
Jon Hallfcc88622014-11-25 13:09:54 -0500937 a cleaner environment.
938
andrewonlab19fbdca2014-11-14 12:55:59 -0500939 Description:
Jon Hallfcc88622014-11-25 13:09:54 -0500940 Stops all ONOS defined in the cell,
andrewonlab19fbdca2014-11-14 12:55:59 -0500941 wipes the raft / copycat log files
kelvin8ec71442015-01-15 16:57:00 -0800942 """
andrewonlab19fbdca2014-11-14 12:55:59 -0500943 try:
kelvin8ec71442015-01-15 16:57:00 -0800944 self.handle.sendline( "" )
945 self.handle.expect( "\$" )
946 self.handle.sendline( "onos-remove-raft-logs" )
947 # Sometimes this command hangs
948 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
949 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -0500950 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800951 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
952 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -0500953 if i == 1:
954 return main.FALSE
kelvin8ec71442015-01-15 16:57:00 -0800955 self.handle.sendline( "" )
956 self.handle.expect( "\$" )
andrewonlab19fbdca2014-11-14 12:55:59 -0500957 return main.TRUE
958
959 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800960 main.log.error( self.name + ": EOF exception found" )
961 main.log.error( self.name + ": " + self.handle.before )
andrewonlab19fbdca2014-11-14 12:55:59 -0500962 main.cleanup()
963 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800964 except Exception:
965 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab19fbdca2014-11-14 12:55:59 -0500966 main.cleanup()
967 main.exit()
Jon Hallfcc88622014-11-25 13:09:54 -0500968
kelvin-onlabd3b64892015-01-20 13:26:24 -0800969 def onosStartNetwork( self, mntopo ):
kelvin8ec71442015-01-15 16:57:00 -0800970 """
971 Calls the command 'onos-start-network [ <mininet-topo> ]
972 "remotely starts the specified topology on the cell's
andrewonlab94282092014-10-10 13:00:11 -0400973 mininet machine against all controllers configured in the
kelvin8ec71442015-01-15 16:57:00 -0800974 cell."
andrewonlab94282092014-10-10 13:00:11 -0400975 * Specify mininet topology file name for mntopo
976 * Topo files should be placed at:
977 ~/<your-onos-directory>/tools/test/topos
kelvin8ec71442015-01-15 16:57:00 -0800978
andrewonlab94282092014-10-10 13:00:11 -0400979 NOTE: This function will take you to the mininet prompt
kelvin8ec71442015-01-15 16:57:00 -0800980 """
andrewonlab94282092014-10-10 13:00:11 -0400981 try:
982 if not mntopo:
kelvin8ec71442015-01-15 16:57:00 -0800983 main.log.error( "You must specify a topo file to execute" )
andrewonlab94282092014-10-10 13:00:11 -0400984 return main.FALSE
andrewonlab94282092014-10-10 13:00:11 -0400985
kelvin8ec71442015-01-15 16:57:00 -0800986 mntopo = str( mntopo )
987 self.handle.sendline( "" )
988 self.handle.expect( "\$" )
andrewonlab94282092014-10-10 13:00:11 -0400989
kelvin8ec71442015-01-15 16:57:00 -0800990 self.handle.sendline( "onos-start-network " + mntopo )
991 self.handle.expect( "mininet>" )
992 main.log.info( "Network started, entered mininet prompt" )
993
994 # TODO: Think about whether return is necessary or not
andrewonlab94282092014-10-10 13:00:11 -0400995
996 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800997 main.log.error( self.name + ": EOF exception found" )
998 main.log.error( self.name + ": " + self.handle.before )
andrewonlab94282092014-10-10 13:00:11 -0400999 main.cleanup()
1000 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001001 except Exception:
1002 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab94282092014-10-10 13:00:11 -04001003 main.cleanup()
1004 main.exit()
1005
Cameron Franke9c94fb02015-01-21 10:20:20 -08001006 def isup(self, node = "", timeout = 120):
kelvin8ec71442015-01-15 16:57:00 -08001007 """
1008 Run's onos-wait-for-start which only returns once ONOS is at run
Cameron Franke9c94fb02015-01-21 10:20:20 -08001009 level 100(ready for use)
andrewonlab8d0d7d72014-10-09 16:33:15 -04001010
Jon Hall7993bfc2014-10-09 16:30:14 -04001011 Returns: main.TRUE if ONOS is running and main.FALSE on timeout
kelvin8ec71442015-01-15 16:57:00 -08001012 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001013 try:
Cameron Franke9c94fb02015-01-21 10:20:20 -08001014 self.handle.sendline("onos-wait-for-start " + node )
1015 self.handle.expect("onos-wait-for-start")
kelvin8ec71442015-01-15 16:57:00 -08001016 # NOTE: this timeout is arbitrary"
Cameron Franke9c94fb02015-01-21 10:20:20 -08001017 i = self.handle.expect(["\$", pexpect.TIMEOUT], timeout)
Jon Hall7993bfc2014-10-09 16:30:14 -04001018 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001019 main.log.info( self.name + ": " + node + " is up" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001020 return main.TRUE
1021 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001022 # NOTE: since this function won't return until ONOS is ready,
Jon Hall7993bfc2014-10-09 16:30:14 -04001023 # we will kill it on timeout
kelvin8ec71442015-01-15 16:57:00 -08001024 main.log.error( "ONOS has not started yet" )
1025 self.handle.send( "\x03" ) # Control-C
1026 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001027 return main.FALSE
1028 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001029 main.log.error( self.name + ": EOF exception found" )
1030 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -04001031 main.cleanup()
1032 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001033 except Exception:
1034 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001035 main.cleanup()
1036 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001037
kelvin-onlabd3b64892015-01-20 13:26:24 -08001038 def pushTestIntentsShell(
1039 self,
1040 dpidSrc,
1041 dpidDst,
1042 numIntents,
1043 dirFile,
1044 onosIp,
1045 numMult="",
1046 appId="",
1047 report=True,
1048 options="" ):
kelvin8ec71442015-01-15 16:57:00 -08001049 """
andrewonlabb66dfa12014-12-02 15:51:10 -05001050 Description:
kelvin8ec71442015-01-15 16:57:00 -08001051 Use the linux prompt to push test intents to
andrewonlabb66dfa12014-12-02 15:51:10 -05001052 better parallelize the results than the CLI
1053 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001054 * dpidSrc: specify source dpid
1055 * dpidDst: specify destination dpid
1056 * numIntents: specify number of intents to push
1057 * dirFile: specify directory and file name to save
andrewonlabb66dfa12014-12-02 15:51:10 -05001058 results
kelvin-onlabd3b64892015-01-20 13:26:24 -08001059 * onosIp: specify the IP of ONOS to install on
kelvin8ec71442015-01-15 16:57:00 -08001060 NOTE:
andrewonlabb66dfa12014-12-02 15:51:10 -05001061 You must invoke this command at linux shell prompt
kelvin8ec71442015-01-15 16:57:00 -08001062 """
1063 try:
1064 # Create the string to sendline
andrewonlabaedc8332014-12-04 12:43:03 -05001065 if options:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001066 baseCmd = "onos " + str( onosIp ) + " push-test-intents " +\
kelvin8ec71442015-01-15 16:57:00 -08001067 options + " "
andrewonlabaedc8332014-12-04 12:43:03 -05001068 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001069 baseCmd = "onos " + str( onosIp ) + " push-test-intents "
kelvin8ec71442015-01-15 16:57:00 -08001070
kelvin-onlabd3b64892015-01-20 13:26:24 -08001071 addDpid = baseCmd + str( dpidSrc ) + " " + str( dpidDst )
1072 if not numMult:
1073 addIntents = addDpid + " " + str( numIntents )
1074 elif numMult:
1075 addIntents = addDpid + " " + str( numIntents ) + " " +\
1076 str( numMult )
1077 if appId:
1078 addApp = addIntents + " " + str( appId )
andrewonlabb66dfa12014-12-02 15:51:10 -05001079 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001080 addApp = addIntents
andrewonlabb66dfa12014-12-02 15:51:10 -05001081
andrewonlabaedc8332014-12-04 12:43:03 -05001082 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001083 sendCmd = addApp + " > " + str( dirFile ) + " &"
andrewonlabaedc8332014-12-04 12:43:03 -05001084 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001085 sendCmd = addApp + " &"
1086 main.log.info( "Send cmd: " + sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001087
kelvin-onlabd3b64892015-01-20 13:26:24 -08001088 self.handle.sendline( sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001089
1090 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001091 main.log.error( self.name + ": EOF exception found" )
1092 main.log.error( self.name + ": " + self.handle.before )
andrewonlabb66dfa12014-12-02 15:51:10 -05001093 main.cleanup()
1094 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001095 except Exception:
1096 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabb66dfa12014-12-02 15:51:10 -05001097 main.cleanup()
kelvin8ec71442015-01-15 16:57:00 -08001098 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001099
kelvin-onlabd3b64892015-01-20 13:26:24 -08001100 def getTopology( self, topologyOutput ):
kelvin8ec71442015-01-15 16:57:00 -08001101 """
Jon Hall77f53ce2014-10-13 18:02:06 -04001102 parses the onos:topology output
kelvin8ec71442015-01-15 16:57:00 -08001103 Returns: a topology dict populated by the key values found in
Jon Hall77f53ce2014-10-13 18:02:06 -04001104 the cli command.
kelvin8ec71442015-01-15 16:57:00 -08001105 """
Jon Hall77f53ce2014-10-13 18:02:06 -04001106 try:
kelvin8ec71442015-01-15 16:57:00 -08001107 # call the cli to get the topology summary
1108 # cmdstr = "onos:topology"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001109 # cliResult = self.onosCli( ip, cmdstr )
1110 # print "cli_result = ", cliResult
Jon Hall77f53ce2014-10-13 18:02:06 -04001111
kelvin8ec71442015-01-15 16:57:00 -08001112 # Parse the output
Jon Hall77f53ce2014-10-13 18:02:06 -04001113 topology = {}
kelvin-onlabd3b64892015-01-20 13:26:24 -08001114 # for line in cliResult.split( "\n" ):
1115 for line in topologyOutput.splitlines():
kelvin8ec71442015-01-15 16:57:00 -08001116 if not line.startswith( "time=" ):
Jon Hall77f53ce2014-10-13 18:02:06 -04001117 continue
kelvin8ec71442015-01-15 16:57:00 -08001118 # else
1119 # print line
1120 for var in line.split( "," ):
1121 # print "'"+var+"'"
1122 # print "'"+var.strip()+"'"
1123 key, value = var.strip().split( "=" )
1124 topology[ key ] = value
1125 # print "topology = ", topology
1126 # devices = topology.get( 'devices', False )
1127 # print "devices = ", devices
1128 # links = topology.get( 'links', False )
1129 # print "links = ", links
1130 # SCCs = topology.get( 'SCC(s)', False )
1131 # print "SCCs = ", SCCs
1132 # paths = topology.get( 'paths', False )
1133 # print "paths = ", paths
Jon Hall77f53ce2014-10-13 18:02:06 -04001134
1135 return topology
1136 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001137 main.log.error( self.name + ": EOF exception found" )
1138 main.log.error( self.name + ": " + self.handle.before )
Jon Hall77f53ce2014-10-13 18:02:06 -04001139 main.cleanup()
1140 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001141 except Exception:
1142 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall77f53ce2014-10-13 18:02:06 -04001143 main.cleanup()
1144 main.exit()
1145
kelvin-onlabd3b64892015-01-20 13:26:24 -08001146 def checkStatus(
1147 self,
1148 topologyResult,
1149 numoswitch,
1150 numolink,
1151 logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08001152 """
Jon Hallefbd9792015-03-05 16:11:36 -08001153 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08001154 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08001155 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08001156
Jon Hall77f53ce2014-10-13 18:02:06 -04001157 Params: ip = ip used for the onos cli
1158 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08001159 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08001160 logLevel = level to log to.
1161 Currently accepts 'info', 'warn' and 'report'
Jon Hall77f53ce2014-10-13 18:02:06 -04001162
1163
kelvin-onlabd3b64892015-01-20 13:26:24 -08001164 logLevel can
Jon Hall77f53ce2014-10-13 18:02:06 -04001165
Jon Hallefbd9792015-03-05 16:11:36 -08001166 Returns: main.TRUE if the number of switches and links are correct,
1167 main.FALSE if the number of switches and links is incorrect,
Jon Hall77f53ce2014-10-13 18:02:06 -04001168 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08001169 """
Jon Hall77f53ce2014-10-13 18:02:06 -04001170 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001171 topology = self.getTopology( topologyResult )
Jon Hall77f53ce2014-10-13 18:02:06 -04001172 if topology == {}:
1173 return main.ERROR
1174 output = ""
kelvin8ec71442015-01-15 16:57:00 -08001175 # Is the number of switches is what we expected
1176 devices = topology.get( 'devices', False )
1177 links = topology.get( 'links', False )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001178 if not devices or not links:
Jon Hall77f53ce2014-10-13 18:02:06 -04001179 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08001180 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08001181 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08001182 linkCheck = ( int( links ) == int( numolink ) )
Jon Hallefbd9792015-03-05 16:11:36 -08001183 if switchCheck and linkCheck:
kelvin8ec71442015-01-15 16:57:00 -08001184 # We expected the correct numbers
Jon Hall77f53ce2014-10-13 18:02:06 -04001185 output = output + "The number of links and switches match "\
kelvin8ec71442015-01-15 16:57:00 -08001186 + "what was expected"
Jon Hall77f53ce2014-10-13 18:02:06 -04001187 result = main.TRUE
1188 else:
1189 output = output + \
Jon Hall274b6642015-02-17 11:57:17 -08001190 "The number of links and switches does not match " + \
1191 "what was expected"
Jon Hall77f53ce2014-10-13 18:02:06 -04001192 result = main.FALSE
Jon Hallefbd9792015-03-05 16:11:36 -08001193 output = output + "\n ONOS sees %i devices" % int( devices )
1194 output = output + " (%i expected) " % int( numoswitch )
Jon Hall274b6642015-02-17 11:57:17 -08001195 output = output + "and %i links " % int( links )
1196 output = output + "(%i expected)" % int( numolink )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001197 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08001198 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001199 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08001200 main.log.warn( output )
Jon Hall77f53ce2014-10-13 18:02:06 -04001201 else:
kelvin8ec71442015-01-15 16:57:00 -08001202 main.log.info( output )
1203 return result
Jon Hall77f53ce2014-10-13 18:02:06 -04001204 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001205 main.log.error( self.name + ": EOF exception found" )
1206 main.log.error( self.name + ": " + self.handle.before )
Jon Hall77f53ce2014-10-13 18:02:06 -04001207 main.cleanup()
1208 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001209 except Exception:
1210 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall77f53ce2014-10-13 18:02:06 -04001211 main.cleanup()
1212 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001213
kelvin-onlabd3b64892015-01-20 13:26:24 -08001214 def tsharkPcap( self, interface, dirFile ):
kelvin8ec71442015-01-15 16:57:00 -08001215 """
andrewonlab970399c2014-11-07 13:09:32 -05001216 Capture all packet activity and store in specified
1217 directory/file
1218
1219 Required:
1220 * interface: interface to capture
1221 * dir: directory/filename to store pcap
kelvin8ec71442015-01-15 16:57:00 -08001222 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001223 try:
1224 self.handle.sendline( "" )
1225 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001226
Jon Hallfebb1c72015-03-05 13:30:09 -08001227 self.handle.sendline( "tshark -i " + str( interface ) +
1228 " -t e -w " + str( dirFile ) + " &" )
1229 self.handle.sendline( "\r" )
1230 self.handle.expect( "Capturing on" )
1231 self.handle.sendline( "\r" )
1232 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001233
Jon Hallfebb1c72015-03-05 13:30:09 -08001234 main.log.info( "Tshark started capturing files on " +
1235 str( interface ) + " and saving to directory: " +
1236 str( dirFile ) )
1237 except pexpect.EOF:
1238 main.log.error( self.name + ": EOF exception found" )
1239 main.log.error( self.name + ": " + self.handle.before )
1240 main.cleanup()
1241 main.exit()
1242 except Exception:
1243 main.log.exception( self.name + ": Uncaught exception!" )
1244 main.cleanup()
1245 main.exit()
Shreya Shaha73aaad2014-10-27 18:03:09 -04001246
kelvin-onlabd3b64892015-01-20 13:26:24 -08001247 def runOnosTopoCfg( self, instanceName, jsonFile ):
kelvin8ec71442015-01-15 16:57:00 -08001248 """
kelvin-onlabd3b64892015-01-20 13:26:24 -08001249 On ONOS bench, run this command:
1250 ./~/ONOS/tools/test/bin/onos-topo-cfg $OC1 filename
1251 which starts the rest and copies
1252 the json file to the onos instance
kelvin8ec71442015-01-15 16:57:00 -08001253 """
shahshreyae6c7cf42014-11-26 16:39:01 -08001254 try:
kelvin8ec71442015-01-15 16:57:00 -08001255 self.handle.sendline( "" )
1256 self.handle.expect( "\$" )
1257 self.handle.sendline( "cd ~/ONOS/tools/test/bin" )
1258 self.handle.expect( "/bin$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001259 cmd = "./onos-topo-cfg " + instanceName + " " + jsonFile
shahshreyae6c7cf42014-11-26 16:39:01 -08001260 print "cmd = ", cmd
kelvin8ec71442015-01-15 16:57:00 -08001261 self.handle.sendline( cmd )
1262 self.handle.expect( "\$" )
1263 self.handle.sendline( "cd ~" )
1264 self.handle.expect( "\$" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001265 return main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -08001266 except pexpect.EOF:
1267 main.log.error( self.name + ": EOF exception found" )
1268 main.log.error( self.name + ": " + self.handle.before )
1269 main.cleanup()
1270 main.exit()
1271 except Exception:
1272 main.log.exception( self.name + ": Uncaught exception!" )
1273 main.cleanup()
1274 main.exit()
kelvin8ec71442015-01-15 16:57:00 -08001275
kelvin-onlabd3b64892015-01-20 13:26:24 -08001276 def tsharkGrep( self, grep, directory, interface='eth0' ):
kelvin8ec71442015-01-15 16:57:00 -08001277 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001278 Required:
kelvin8ec71442015-01-15 16:57:00 -08001279 * grep string
andrewonlabba44bcf2014-10-16 16:54:41 -04001280 * directory to store results
1281 Optional:
1282 * interface - default: eth0
1283 Description:
1284 Uses tshark command to grep specific group of packets
1285 and stores the results to specified directory.
kelvin8ec71442015-01-15 16:57:00 -08001286 The timestamp is hardcoded to be in epoch
1287 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001288 try:
1289 self.handle.sendline( "" )
1290 self.handle.expect( "\$" )
1291 self.handle.sendline( "" )
1292 self.handle.sendline(
1293 "tshark -i " +
1294 str( interface ) +
1295 " -t e | grep --line-buffered \"" +
1296 str(grep) +
1297 "\" >" +
1298 directory +
1299 " &" )
1300 self.handle.sendline( "\r" )
1301 self.handle.expect( "Capturing on" )
1302 self.handle.sendline( "\r" )
1303 self.handle.expect( "\$" )
1304 except pexpect.EOF:
1305 main.log.error( self.name + ": EOF exception found" )
1306 main.log.error( self.name + ": " + self.handle.before )
1307 main.cleanup()
1308 main.exit()
1309 except Exception:
1310 main.log.exception( self.name + ": Uncaught exception!" )
1311 main.cleanup()
1312 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001313
kelvin-onlabd3b64892015-01-20 13:26:24 -08001314 def tsharkStop( self ):
kelvin8ec71442015-01-15 16:57:00 -08001315 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001316 Removes wireshark files from /tmp and kills all tshark processes
kelvin8ec71442015-01-15 16:57:00 -08001317 """
1318 # Remove all pcap from previous captures
Jon Hallfebb1c72015-03-05 13:30:09 -08001319 try:
1320 self.execute( cmd="sudo rm /tmp/wireshark*" )
1321 self.handle.sendline( "" )
Jon Hallefbd9792015-03-05 16:11:36 -08001322 self.handle.sendline( "sudo kill -9 `ps -ef | grep \"tshark -i\"" +
1323 " | grep -v grep | awk '{print $2}'`" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001324 self.handle.sendline( "" )
1325 main.log.info( "Tshark stopped" )
1326 except pexpect.EOF:
1327 main.log.error( self.name + ": EOF exception found" )
1328 main.log.error( self.name + ": " + self.handle.before )
1329 main.cleanup()
1330 main.exit()
1331 except Exception:
1332 main.log.exception( self.name + ": Uncaught exception!" )
1333 main.cleanup()
1334 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001335
kelvin8ec71442015-01-15 16:57:00 -08001336 def ptpd( self, args ):
1337 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001338 Initiate ptp with user-specified args.
1339 Required:
1340 * args: specify string of args after command
1341 'sudo ptpd'
kelvin8ec71442015-01-15 16:57:00 -08001342 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001343 try:
kelvin8ec71442015-01-15 16:57:00 -08001344 self.handle.sendline( "sudo ptpd " + str( args ) )
1345 i = self.handle.expect( [
andrewonlab0c38a4a2014-10-28 18:35:35 -04001346 "Multiple",
1347 "Error",
kelvin8ec71442015-01-15 16:57:00 -08001348 "\$" ] )
1349 self.handle.expect( "\$" )
andrewonlabba44bcf2014-10-16 16:54:41 -04001350
andrewonlab0c38a4a2014-10-28 18:35:35 -04001351 if i == 0:
1352 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001353 main.log.info( "ptpd returned an error: " +
1354 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001355 return handle
1356 elif i == 1:
1357 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001358 main.log.error( "ptpd returned an error: " +
1359 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001360 return handle
1361 else:
1362 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -08001363
andrewonlab0c38a4a2014-10-28 18:35:35 -04001364 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001365 main.log.error( self.name + ": EOF exception found" )
1366 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001367 main.cleanup()
1368 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001369 except Exception:
1370 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001371 main.cleanup()
1372 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001373
kelvin-onlabd3b64892015-01-20 13:26:24 -08001374 def cpLogsToDir( self, logToCopy,
Jon Hallefbd9792015-03-05 16:11:36 -08001375 destDir, copyFileName="" ):
kelvin8ec71442015-01-15 16:57:00 -08001376 """
1377 Copies logs to a desired directory.
andrewonlab5d7a8f32014-11-10 13:07:56 -05001378 Current implementation of ONOS deletes its karaf
1379 logs on every iteration. For debugging purposes,
kelvin8ec71442015-01-15 16:57:00 -08001380 you may want to use this function to capture
1381 certain karaf logs. ( or any other logs if needed )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001382 Localtime will be attached to the filename
1383
1384 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001385 * logToCopy: specify directory and log name to
andrewonlab5d7a8f32014-11-10 13:07:56 -05001386 copy.
kelvin8ec71442015-01-15 16:57:00 -08001387 ex ) /opt/onos/log/karaf.log.1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001388 For copying multiple files, leave copyFileName
1389 empty and only specify destDir -
kelvin8ec71442015-01-15 16:57:00 -08001390 ex ) /opt/onos/log/karaf*
kelvin-onlabd3b64892015-01-20 13:26:24 -08001391 * destDir: specify directory to copy to.
kelvin8ec71442015-01-15 16:57:00 -08001392 ex ) /tmp/
1393 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001394 * copyFileName: If you want to rename the log
1395 file, specify copyFileName. This will not work
andrewonlab5d7a8f32014-11-10 13:07:56 -05001396 with multiple file copying
kelvin8ec71442015-01-15 16:57:00 -08001397 """
andrewonlab5d7a8f32014-11-10 13:07:56 -05001398 try:
kelvin8ec71442015-01-15 16:57:00 -08001399 localtime = time.strftime( '%x %X' )
1400 localtime = localtime.replace( "/", "" )
1401 localtime = localtime.replace( " ", "_" )
1402 localtime = localtime.replace( ":", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001403 if destDir[ -1: ] != "/":
1404 destDir += "/"
andrewonlab5d7a8f32014-11-10 13:07:56 -05001405
kelvin-onlabd3b64892015-01-20 13:26:24 -08001406 if copyFileName:
Jon Hallfebb1c72015-03-05 13:30:09 -08001407 self.handle.sendline( "cp " + str( logToCopy ) + " " +
1408 str( destDir ) + str( copyFileName ) +
1409 localtime )
kelvin8ec71442015-01-15 16:57:00 -08001410 self.handle.expect( "cp" )
1411 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001412 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001413 self.handle.sendline( "cp " + str( logToCopy ) +
1414 " " + str( destDir ) )
kelvin8ec71442015-01-15 16:57:00 -08001415 self.handle.expect( "cp" )
1416 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001417
kelvin8ec71442015-01-15 16:57:00 -08001418 return self.handle.before
1419
1420 except pexpect.EOF:
1421 main.log.error( "Copying files failed" )
1422 main.log.error( self.name + ": EOF exception found" )
1423 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001424 except Exception:
1425 main.log.exception( "Copying files failed" )
kelvin8ec71442015-01-15 16:57:00 -08001426
kelvin-onlabd3b64892015-01-20 13:26:24 -08001427 def checkLogs( self, onosIp ):
kelvin8ec71442015-01-15 16:57:00 -08001428 """
Jon Hall94fd0472014-12-08 11:52:42 -08001429 runs onos-check-logs on the given onos node
1430 returns the response
kelvin8ec71442015-01-15 16:57:00 -08001431 """
Jon Hall94fd0472014-12-08 11:52:42 -08001432 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001433 cmd = "onos-check-logs " + str( onosIp )
kelvin8ec71442015-01-15 16:57:00 -08001434 self.handle.sendline( cmd )
1435 self.handle.expect( cmd )
1436 self.handle.expect( "\$" )
Jon Hall94fd0472014-12-08 11:52:42 -08001437 response = self.handle.before
1438 return response
1439 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001440 main.log.error( "Lost ssh connection" )
1441 main.log.error( self.name + ": EOF exception found" )
1442 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001443 except Exception:
1444 main.log.exception( self.name + ": Uncaught exception!" )
1445 main.cleanup()
1446 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -08001447
kelvin-onlabd3b64892015-01-20 13:26:24 -08001448 def onosStatus( self, node="" ):
kelvin8ec71442015-01-15 16:57:00 -08001449 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001450 Calls onos command: 'onos-service [<node-ip>] status'
kelvin8ec71442015-01-15 16:57:00 -08001451 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001452 try:
kelvin8ec71442015-01-15 16:57:00 -08001453 self.handle.sendline( "" )
1454 self.handle.expect( "\$" )
1455 self.handle.sendline( "onos-service " + str( node ) +
1456 " status" )
1457 i = self.handle.expect( [
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001458 "start/running",
1459 "stop/waiting",
kelvin8ec71442015-01-15 16:57:00 -08001460 pexpect.TIMEOUT ], timeout=120 )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001461
1462 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001463 main.log.info( "ONOS is running" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001464 return main.TRUE
1465 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001466 main.log.info( "ONOS is stopped" )
kelvin8ec71442015-01-15 16:57:00 -08001467 main.log.error( "ONOS service failed to check the status" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001468 main.cleanup()
1469 main.exit()
1470 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001471 main.log.error( self.name + ": EOF exception found" )
1472 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001473 main.cleanup()
1474 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001475 except Exception:
1476 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001477 main.cleanup()
1478 main.exit()
Jon Hall21270ac2015-02-16 17:59:55 -08001479
Jon Hall63604932015-02-26 17:09:50 -08001480 def setIpTables( self, ip, port='', action='add', packet_type='',
1481 direction='INPUT', rule='DROP', states=True ):
Jon Hallefbd9792015-03-05 16:11:36 -08001482 """
Jon Hall21270ac2015-02-16 17:59:55 -08001483 Description:
1484 add or remove iptables rule to DROP (default) packets from
1485 specific IP and PORT
1486 Usage:
1487 * specify action ('add' or 'remove')
1488 when removing, pass in the same argument as you would add. It will
1489 delete that specific rule.
1490 * specify the ip to block
1491 * specify the destination port to block (defaults to all ports)
1492 * optional packet type to block (default tcp)
1493 * optional iptables rule (default DROP)
1494 * optional direction to block (default 'INPUT')
Jon Hall63604932015-02-26 17:09:50 -08001495 * States boolean toggles adding all supported tcp states to the
1496 firewall rule
Jon Hall21270ac2015-02-16 17:59:55 -08001497 Returns:
1498 main.TRUE on success or
1499 main.FALSE if given invalid input or
1500 main.ERROR if there is an error in response from iptables
1501 WARNING:
1502 * This function uses root privilege iptables command which may result
1503 in unwanted network errors. USE WITH CAUTION
Jon Hallefbd9792015-03-05 16:11:36 -08001504 """
Jon Hall21270ac2015-02-16 17:59:55 -08001505 import time
1506
1507 # NOTE*********
1508 # The strict checking methods of this driver function is intentional
1509 # to discourage any misuse or error of iptables, which can cause
1510 # severe network errors
1511 # *************
1512
1513 # NOTE: Sleep needed to give some time for rule to be added and
1514 # registered to the instance. If you are calling this function
1515 # multiple times this sleep will prevent any errors.
1516 # DO NOT REMOVE
Jon Hall63604932015-02-26 17:09:50 -08001517 # time.sleep( 5 )
Jon Hall21270ac2015-02-16 17:59:55 -08001518 try:
1519 # input validation
1520 action_type = action.lower()
1521 rule = rule.upper()
1522 direction = direction.upper()
1523 if action_type != 'add' and action_type != 'remove':
1524 main.log.error( "Invalid action type. Use 'add' or "
1525 "'remove' table rule" )
1526 if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
1527 # NOTE Currently only supports rules DROP, ACCEPT, and LOG
1528 main.log.error( "Invalid rule. Valid rules are 'DROP' or "
1529 "'ACCEPT' or 'LOG' only." )
1530 if direction != 'INPUT' and direction != 'OUTPUT':
1531 # NOTE currently only supports rules INPUT and OUPTUT
1532 main.log.error( "Invalid rule. Valid directions are"
1533 " 'OUTPUT' or 'INPUT'" )
1534 return main.FALSE
1535 return main.FALSE
1536 return main.FALSE
1537 if action_type == 'add':
1538 # -A is the 'append' action of iptables
1539 actionFlag = '-A'
1540 elif action_type == 'remove':
1541 # -D is the 'delete' rule of iptables
1542 actionFlag = '-D'
1543 self.handle.sendline( "" )
1544 self.handle.expect( "\$" )
1545 cmd = "sudo iptables " + actionFlag + " " +\
1546 direction +\
Jon Hall21270ac2015-02-16 17:59:55 -08001547 " -s " + str( ip )
Jon Hall63604932015-02-26 17:09:50 -08001548 # " -p " + str( packet_type ) +\
1549 if packet_type:
1550 cmd += " -p " + str( packet_type )
Jon Hall21270ac2015-02-16 17:59:55 -08001551 if port:
1552 cmd += " --dport " + str( port )
Jon Hall63604932015-02-26 17:09:50 -08001553 if states:
1554 cmd += " -m state --state="
1555 #FIXME- Allow user to configure which states to block
1556 cmd += "INVALID,ESTABLISHED,NEW,RELATED,UNTRACKED"
Jon Hall21270ac2015-02-16 17:59:55 -08001557 cmd += " -j " + str( rule )
1558
1559 self.handle.sendline( cmd )
1560 self.handle.expect( "\$" )
1561 main.log.warn( self.handle.before )
1562
1563 info_string = "On " + str( self.name )
1564 info_string += " " + str( action_type )
1565 info_string += " iptable rule [ "
1566 info_string += " IP: " + str( ip )
1567 info_string += " Port: " + str( port )
1568 info_string += " Rule: " + str( rule )
1569 info_string += " Direction: " + str( direction ) + " ]"
1570 main.log.info( info_string )
1571 return main.TRUE
1572 except pexpect.TIMEOUT:
1573 main.log.exception( self.name + ": Timeout exception in "
1574 "setIpTables function" )
1575 return main.ERROR
1576 except pexpect.EOF:
1577 main.log.error( self.name + ": EOF exception found" )
1578 main.log.error( self.name + ": " + self.handle.before )
1579 main.cleanup()
1580 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001581 except Exception:
1582 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall21270ac2015-02-16 17:59:55 -08001583 main.cleanup()
1584 main.exit()
1585
Jon Hall0468b042015-02-19 19:08:21 -08001586 def detailed_status(self, log_filename):
Jon Hallefbd9792015-03-05 16:11:36 -08001587 """
Jon Hall0468b042015-02-19 19:08:21 -08001588 This method is used by STS to check the status of the controller
1589 Reports RUNNING, STARTING, STOPPED, FROZEN, ERROR (and reason)
Jon Hallefbd9792015-03-05 16:11:36 -08001590 """
Jon Hall0468b042015-02-19 19:08:21 -08001591 import re
1592 try:
1593 self.handle.sendline( "" )
1594 self.handle.expect( "\$" )
1595 self.handle.sendline( "cd " + self.home )
1596 self.handle.expect( "\$" )
1597 self.handle.sendline( "service onos status" )
1598 self.handle.expect( "\$" )
1599 response = self.handle.before
1600 if re.search( "onos start/running", response ):
1601 # onos start/running, process 10457
1602 return 'RUNNING'
1603 # FIXME: Implement this case
1604 # elif re.search( pattern, response ):
1605 # return 'STARTING'
1606 elif re.search( "onos stop/", response ):
1607 # onos stop/waiting
1608 # FIXME handle this differently?: onos stop/pre-stop
1609 return 'STOPPED'
1610 # FIXME: Implement this case
1611 # elif re.search( pattern, response ):
1612 # return 'FROZEN'
1613 else:
1614 main.log.warn( self.name +
Jon Hallefbd9792015-03-05 16:11:36 -08001615 " WARNING: status received unknown response" )
Jon Hall0468b042015-02-19 19:08:21 -08001616 main.log.warn( response )
1617 return 'ERROR', "Unknown response: %s" % response
1618 except pexpect.TIMEOUT:
1619 main.log.exception( self.name + ": Timeout exception in "
1620 "setIpTables function" )
1621 return 'ERROR', "Pexpect Timeout"
1622 except pexpect.EOF:
1623 main.log.error( self.name + ": EOF exception found" )
1624 main.log.error( self.name + ": " + self.handle.before )
1625 main.cleanup()
1626 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001627 except Exception:
1628 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall05b2b432014-10-08 19:53:25 -04001629 main.cleanup()
1630 main.exit()
andrew@onlab.us3b087132015-03-11 15:00:08 -07001631
1632 def createLinkGraphFile( self, benchIp, ONOSIpList, deviceCount):
1633 '''
1634 Create/formats the LinkGraph.cfg file based on arguments
1635 -only creates a linear topology and connects islands
1636 -evenly distributes devices
1637 -must be called by ONOSbench
1638
1639 ONOSIpList - list of all of the node IPs to be used
1640
1641 deviceCount - number of switches to be assigned
1642 '''
1643 main.log.step("Creating link graph configuration file." )
1644 linkGraphPath = self.home + "/tools/package/etc/linkGraph.cfg"
1645 tempFile = "/tmp/linkGraph.cfg"
1646
1647 linkGraph = open(tempFile, 'w+')
1648 linkGraph.write("# NullLinkProvider topology description (config file).\n")
1649 linkGraph.write("# The NodeId is only added if the destination is another node's device.\n")
1650 linkGraph.write("# Bugs: Comments cannot be appended to a line to be read.\n")
1651
1652 clusterCount = len(ONOSIpList)
1653
1654 if type(deviceCount) is int or type(deviceCount) is str:
1655 deviceCount = int(deviceCount)
1656 switchList = [0]*(clusterCount+1)
1657 baselineSwitchCount = deviceCount/clusterCount
1658
1659 for node in range(1, clusterCount + 1):
1660 switchList[node] = baselineSwitchCount
1661
1662 for node in range(1, (deviceCount%clusterCount)+1):
1663 switchList[node] += 1
1664
1665 if type(deviceCount) is list:
1666 main.log.info("Using provided device distribution")
1667 switchList = [0]
1668 for i in deviceCount:
1669 switchList.append(int(i))
1670
1671 tempList = ['0']
1672 tempList.extend(ONOSIpList)
1673 ONOSIpList = tempList
1674
1675 myPort = 6
1676 lastSwitch = 0
1677 for node in range(1, clusterCount+1):
1678 if switchList[node] == 0:
1679 continue
1680
1681 linkGraph.write("graph " + ONOSIpList[node] + " {\n")
1682
1683 if node > 1:
1684 #connect to last device on previous node
1685 line = ("\t0:5 -> " + str(lastSwitch) + ":6:" + lastIp + "\n") #ONOSIpList[node-1]
1686 linkGraph.write(line)
1687
1688 lastSwitch = 0
1689 for switch in range (0, switchList[node]-1):
1690 line = ""
1691 line = ("\t" + str(switch) + ":" + str(myPort))
1692 line += " -- "
1693 line += (str(switch+1) + ":" + str(myPort-1) + "\n")
1694 linkGraph.write(line)
1695 lastSwitch = switch+1
1696 lastIp = ONOSIpList[node]
1697
1698 #lastSwitch += 1
1699 if node < (clusterCount):
1700 #connect to first device on the next node
1701 line = ("\t" + str(lastSwitch) + ":6 -> 0:5:" + ONOSIpList[node+1] + "\n")
1702 linkGraph.write(line)
1703
1704 linkGraph.write("}\n")
1705 linkGraph.close()
1706
1707 #SCP
1708 os.system( "scp " + tempFile + " admin@" + benchIp + ":" + linkGraphPath)
1709 main.log.info("linkGraph.cfg creation complete")
1710
1711 def createNullDevProviderFile( self, benchIp, ONOSIpList, deviceCount, numPorts=10):
1712
1713 '''
1714 benchIp = Ip address of the test bench
1715 ONOSIpList = list of Ip addresses of nodes switches will be devided amongst
1716 deviceCount = number of switches to distribute
1717 numPorts = number of ports per device, when not specified in file it defaults to 10, optional arg
1718 '''
1719
1720 main.log.step("Creating null device provider configuration file." )
1721 nullDevicePath = self.home + "/tools/package/etc/org.onosproject.provider.nil.device.impl.NullDeviceProvider.cfg"
1722 tempFile = "/tmp/org.onosproject.provider.nil.device.impl.NullDeviceProvider.cfg"
1723 configFile = open(tempFile, 'w+')
1724 clusterCount = len(ONOSIpList)
1725
1726 if type(deviceCount) is int or type(deviceCount) is str:
1727 main.log.info("Creating device distribution")
1728 deviceCount = int(deviceCount)
1729 switchList = [0]*(clusterCount+1)
1730 baselineSwitchCount = deviceCount/clusterCount
1731
1732 for node in range(1, clusterCount + 1):
1733 switchList[node] = baselineSwitchCount
1734
1735 for node in range(1, (deviceCount%clusterCount)+1):
1736 switchList[node] += 1
1737
1738 if type(deviceCount) is list:
1739 main.log.info("Using provided device distribution")
1740 switchList = ['0']
1741 switchList.extend(deviceCount)
1742
1743 ONOSIp = [0]
1744 ONOSIp.extend(ONOSIpList)
1745
1746 devicesString = "devConfigs = "
1747 for node in range(1, len(ONOSIp)):
1748 devicesString += (ONOSIp[node] + ":" + str(switchList[node] ))
1749 if node < clusterCount:
1750 devicesString += (",")
1751
1752 configFile.write(devicesString + "\n")
1753 if numPorts == 10:
1754 configFile.write("#numPorts = 10")
1755 else:
1756 configFile.write("numPorts = " + str(numPorts))
1757
1758 configFile.close()
1759 os.system( "scp " + tempFile + " admin@" + benchIp + ":" + nullDevicePath)
1760
jenkinsa2852772015-03-24 10:55:48 -07001761 def createNullLinkProviderFile( self, benchIp, neighborIpList=0,fileName="", eventRate=0, onNode=False):
andrew@onlab.us3b087132015-03-11 15:00:08 -07001762 '''
1763 neighbor list is an optional list of neighbors to be written directly to the file
1764 onNode - bool, if true, alternate file path will be used to scp, inteneded
1765 for use on cell
1766 '''
1767
1768 main.log.step("Creating Null Link Provider config file")
1769 nullLinkPath = self.home + "/tools/package/etc/org.onosproject.provider.nil.link.impl.NullLinkProvider.cfg"
1770 if onNode == True:
1771 nullLinkPath = "/opt/onos/apache-karaf-3.0.2/etc/org.onosproject.provider.nil.link.impl.NullLinkProvider.cfg"
1772 tempFile = "/tmp/org.onosproject.provider.nil.link.impl.NullLinkProvider.cfg"
1773 configFile = open(tempFile, 'w+')
1774
1775 eventRate = int(eventRate)
1776
1777 if eventRate == 0:
1778 configFile.write("#eventRate = \n")
1779 else:
1780 configFile.write("eventRate = " + str(eventRate) + "\n")
andrew@onlab.us3b087132015-03-11 15:00:08 -07001781
jenkinsa2852772015-03-24 10:55:48 -07001782 if fileName == "":
1783 configFile.write("#cfgFile = /tmp/foo.cfg #If enabled, points to the full path to the topology file.\n")
1784 else:
1785 configFile.write("cfgFile =" + str(fileName) + "\n")
1786
andrew@onlab.us3b087132015-03-11 15:00:08 -07001787 if neighborIpList != 0:
1788 configFile.write("neighbors = ")
1789 for n in range (0, len(neighborIpList)):
1790 configFile.write(neighborIpList[n])
1791 if n < (len(neighborIpList) - 1):
1792 configFile.write(",")
1793 else:
1794 configFile.write("#neighbors = ")
1795
1796 configFile.close()
1797 if onNode == False:
1798 os.system( "scp " + tempFile + " admin@" + benchIp + ":" + nullLinkPath)
1799 if onNode == True:
1800 os.system( "scp " + tempFile + " sdn@" + benchIp + ":" + nullLinkPath)
1801
1802
1803
1804