blob: ed6e538a08b276942e93fc153ec09597e45bfa8c [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"""
Jon Hall05b2b432014-10-08 19:53:25 -040019import time
Jon Hall6801cda2015-07-15 14:13:45 -070020import types
Jon Hall05b2b432014-10-08 19:53:25 -040021import pexpect
kelvin-onlaba4074292015-07-09 15:19:49 -070022import os
andrewonlab7735d852014-10-09 13:02:47 -040023import os.path
pingping-lin6d23d9e2015-02-02 16:54:24 -080024from requests.models import Response
Jon Hall05b2b432014-10-08 19:53:25 -040025from drivers.common.clidriver import CLI
26
Jon Hall05b2b432014-10-08 19:53:25 -040027
kelvin8ec71442015-01-15 16:57:00 -080028class OnosDriver( CLI ):
Jon Hall05b2b432014-10-08 19:53:25 -040029
kelvin8ec71442015-01-15 16:57:00 -080030 def __init__( self ):
31 """
32 Initialize client
33 """
Jon Hallefbd9792015-03-05 16:11:36 -080034 self.name = None
35 self.home = None
36 self.handle = None
kelvin8ec71442015-01-15 16:57:00 -080037 super( CLI, self ).__init__()
38
39 def connect( self, **connectargs ):
40 """
Jon Hall05b2b432014-10-08 19:53:25 -040041 Creates ssh handle for ONOS "bench".
kelvin-onlaba4074292015-07-09 15:19:49 -070042 NOTE:
43 The ip_address would come from the topo file using the host tag, the
44 value can be an environment variable as well as a "localhost" to get
45 the ip address needed to ssh to the "bench"
kelvin8ec71442015-01-15 16:57:00 -080046 """
Jon Hall05b2b432014-10-08 19:53:25 -040047 try:
48 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080049 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us3b087132015-03-11 15:00:08 -070050 self.home = "~/onos"
Jon Hall05b2b432014-10-08 19:53:25 -040051 for key in self.options:
52 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080053 self.home = self.options[ 'home' ]
Jon Hall05b2b432014-10-08 19:53:25 -040054 break
Jon Hall274b6642015-02-17 11:57:17 -080055 if self.home is None or self.home == "":
Jon Halle94919c2015-03-23 11:42:57 -070056 self.home = "~/onos"
Jon Hall21270ac2015-02-16 17:59:55 -080057
kelvin8ec71442015-01-15 16:57:00 -080058 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070059
kelvin-onlabc2b79102015-07-14 11:41:20 -070060 # The 'nodes' tag is optional and it is not required in .topo file
kelvin-onlaba4074292015-07-09 15:19:49 -070061 for key in self.options:
62 if key == "nodes":
kelvin-onlabc2b79102015-07-14 11:41:20 -070063 # Maximum number of ONOS nodes to run, if there is any
kelvin-onlaba4074292015-07-09 15:19:49 -070064 self.maxNodes = int( self.options[ 'nodes' ] )
65 break
66 self.maxNodes = None
67
kelvin-onlabc2b79102015-07-14 11:41:20 -070068 if self.maxNodes == None or self.maxNodes == "":
69 self.maxNodes = 100
kelvin-onlaba4074292015-07-09 15:19:49 -070070
kelvin-onlabc2b79102015-07-14 11:41:20 -070071
72 # Grabs all OC environment variables based on max number of nodes
kelvin-onlaba4074292015-07-09 15:19:49 -070073 self.onosIps = {} # Dictionary of all possible ONOS ip
74
75 try:
76 if self.maxNodes:
kelvin-onlaba4074292015-07-09 15:19:49 -070077 for i in range( self.maxNodes ):
78 envString = "OC" + str( i + 1 )
kelvin-onlabc2b79102015-07-14 11:41:20 -070079 # If there is no more OC# then break the loop
80 if os.getenv( envString ):
81 self.onosIps[ envString ] = os.getenv( envString )
82 else:
83 self.maxNodes = len( self.onosIps )
84 main.log.info( self.name +
85 ": Created cluster data with " +
86 str( self.maxNodes ) +
87 " maximum number" +
88 " of nodes" )
89 break
kelvin-onlaba4074292015-07-09 15:19:49 -070090
91 if not self.onosIps:
92 main.log.info( "Could not read any environment variable"
93 + " please load a cell file with all" +
94 " onos IP" )
Jon Hall5cf14d52015-07-16 12:15:19 -070095 self.maxNodes = None
kelvin-onlaba4074292015-07-09 15:19:49 -070096 else:
97 main.log.info( self.name + ": Found " +
98 str( self.onosIps.values() ) +
99 " ONOS IPs" )
kelvin-onlaba4074292015-07-09 15:19:49 -0700100 except KeyError:
101 main.log.info( "Invalid environment variable" )
102 except Exception as inst:
103 main.log.error( "Uncaught exception: " + str( inst ) )
104
105 try:
106 if os.getenv( str( self.ip_address ) ) != None:
107 self.ip_address = os.getenv( str( self.ip_address ) )
108 else:
109 main.log.info( self.name +
110 ": Trying to connect to " +
111 self.ip_address )
kelvin-onlaba4074292015-07-09 15:19:49 -0700112 except KeyError:
113 main.log.info( "Invalid host name," +
114 " connecting to local host instead" )
115 self.ip_address = 'localhost'
116 except Exception as inst:
117 main.log.error( "Uncaught exception: " + str( inst ) )
118
kelvin8ec71442015-01-15 16:57:00 -0800119 self.handle = super( OnosDriver, self ).connect(
120 user_name=self.user_name,
kelvin-onlab08679eb2015-01-21 16:11:48 -0800121 ip_address=self.ip_address,
kelvin-onlabd3b64892015-01-20 13:26:24 -0800122 port=self.port,
123 pwd=self.pwd,
124 home=self.home )
Jon Hall05b2b432014-10-08 19:53:25 -0400125
Jon Hall05b2b432014-10-08 19:53:25 -0400126 if self.handle:
Jon Hall0fc0d452015-07-14 09:49:58 -0700127 self.handle.sendline( "cd " + self.home )
128 self.handle.expect( "\$" )
Jon Hall05b2b432014-10-08 19:53:25 -0400129 return self.handle
kelvin8ec71442015-01-15 16:57:00 -0800130 else:
Jon Hall0fc0d452015-07-14 09:49:58 -0700131 main.log.info( "Failed to create ONOS handle" )
Jon Hall05b2b432014-10-08 19:53:25 -0400132 return main.FALSE
133 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800134 main.log.error( self.name + ": EOF exception found" )
135 main.log.error( self.name + ": " + self.handle.before )
Jon Hall05b2b432014-10-08 19:53:25 -0400136 main.cleanup()
137 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800138 except Exception:
139 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall05b2b432014-10-08 19:53:25 -0400140 main.cleanup()
141 main.exit()
142
kelvin8ec71442015-01-15 16:57:00 -0800143 def disconnect( self ):
144 """
Jon Hall05b2b432014-10-08 19:53:25 -0400145 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800146 """
Jon Halld61331b2015-02-17 16:35:47 -0800147 response = main.TRUE
Jon Hall05b2b432014-10-08 19:53:25 -0400148 try:
Jon Hall61282e32015-03-19 11:34:11 -0700149 if self.handle:
150 self.handle.sendline( "" )
151 self.handle.expect( "\$" )
152 self.handle.sendline( "exit" )
153 self.handle.expect( "closed" )
Jon Hall05b2b432014-10-08 19:53:25 -0400154 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800155 main.log.error( self.name + ": EOF exception found" )
156 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700157 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700158 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700159 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800160 except Exception:
161 main.log.exception( self.name + ": Connection failed to the host" )
Jon Hall05b2b432014-10-08 19:53:25 -0400162 response = main.FALSE
163 return response
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400164
andrew@onlab.usaee415a2015-06-05 14:38:58 -0400165 def getEpochMs( self ):
166 """
167 Returns milliseconds since epoch
Jon Hall4ba53f02015-07-29 13:07:41 -0700168
169 When checking multiple nodes in a for loop,
170 around a hundred milliseconds of difference (ascending) is
171 generally acceptable due to calltime of the function.
172 Few seconds, however, is not and it means clocks
173 are off sync.
andrew@onlab.usaee415a2015-06-05 14:38:58 -0400174 """
175 try:
176 self.handle.sendline( 'date +%s.%N' )
177 self.handle.expect( 'date \+\%s\.\%N' )
178 self.handle.expect( '\$' )
179 epochMs = self.handle.before
180 return epochMs
181 except Exception:
182 main.log.exception( 'Uncaught exception getting epoch time' )
183 main.cleanup()
184 main.exit()
185
GlennRC9cc3dd92015-12-10 12:21:25 -0800186 def onosPackage( self, opTimeout=120 ):
kelvin8ec71442015-01-15 16:57:00 -0800187 """
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400188 Produce a self-contained tar.gz file that can be deployed
Jon Hall64af8502015-12-15 10:09:33 -0800189 and executed on any platform with Java 8 JRE.
kelvin8ec71442015-01-15 16:57:00 -0800190 """
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400191 try:
Jon Hall64af8502015-12-15 10:09:33 -0800192 ret = main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800193 self.handle.sendline( "onos-package" )
194 self.handle.expect( "onos-package" )
Jon Hall64af8502015-12-15 10:09:33 -0800195 i = self.handle.expect( ["tar.gz", "\$", "Unknown options"], opTimeout )
196 handle = str( self.handle.before + self.handle.after )
197 if i == 0:
198 self.handle.expect( "\$" )
199 handle += str( self.handle.before )
200 elif i == 1:
201 # This seems to be harmless, but may be a problem
202 main.log.warn( "onos-package output not as expected" )
203 elif i == 2:
204 # Incorrect usage
205 main.log.error( "onos-package does not recognize the given options" )
206 self.handle.expect( "\$" )
207 handle += str( self.handle.before )
208 ret = main.FALSE
kelvin8ec71442015-01-15 16:57:00 -0800209 main.log.info( "onos-package command returned: " +
210 handle )
211 # As long as the sendline does not time out,
212 # return true. However, be careful to interpret
213 # the results of the onos-package command return
Jon Hall64af8502015-12-15 10:09:33 -0800214 return ret
215 except pexpect.TIMEOUT:
216 main.log.exception( self.name + ": TIMEOUT exception found in onosPackage" )
217 main.log.error( self.name + ": " + self.handle.before )
218 return main.FALSE
andrewonlab7735d852014-10-09 13:02:47 -0400219 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800220 main.log.error( self.name + ": EOF exception found" )
221 main.log.error( self.name + ": " + self.handle.before )
Jon Hall64af8502015-12-15 10:09:33 -0800222 main.cleanup()
223 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800224 except Exception:
225 main.log.exception( "Failed to package ONOS" )
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400226 main.cleanup()
227 main.exit()
228
kelvin-onlabd3b64892015-01-20 13:26:24 -0800229 def onosBuild( self ):
kelvin8ec71442015-01-15 16:57:00 -0800230 """
andrewonlab8790abb2014-11-06 13:51:54 -0500231 Use the pre defined script to build onos via mvn
kelvin8ec71442015-01-15 16:57:00 -0800232 """
andrewonlab8790abb2014-11-06 13:51:54 -0500233 try:
kelvin8ec71442015-01-15 16:57:00 -0800234 self.handle.sendline( "onos-build" )
235 self.handle.expect( "onos-build" )
236 i = self.handle.expect( [
kelvin-onlabd3b64892015-01-20 13:26:24 -0800237 "BUILD SUCCESS",
238 "ERROR",
239 "BUILD FAILED" ],
240 timeout=120 )
kelvin8ec71442015-01-15 16:57:00 -0800241 handle = str( self.handle.before )
Jon Hall3b489db2015-10-05 14:38:37 -0700242 self.handle.expect( "\$" )
andrewonlab8790abb2014-11-06 13:51:54 -0500243
kelvin8ec71442015-01-15 16:57:00 -0800244 main.log.info( "onos-build command returned: " +
245 handle )
andrewonlab8790abb2014-11-06 13:51:54 -0500246
247 if i == 0:
248 return main.TRUE
249 else:
250 return handle
251
252 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800253 main.log.error( self.name + ": EOF exception found" )
254 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -0800255 except Exception:
256 main.log.exception( "Failed to build ONOS" )
andrewonlab8790abb2014-11-06 13:51:54 -0500257 main.cleanup()
258 main.exit()
259
shahshreya9f531fe2015-06-10 12:03:51 -0700260 def cleanInstall( self, skipTest=False, mciTimeout=600 ):
kelvin8ec71442015-01-15 16:57:00 -0800261 """
262 Runs mvn clean install in the root of the ONOS directory.
263 This will clean all ONOS artifacts then compile each module
shahshreya9f531fe2015-06-10 12:03:51 -0700264 Optional:
265 skipTest - Does "-DskipTests -Dcheckstyle.skip -U -T 1C" which
266 skip the test. This will make the building faster.
267 Disregarding the credibility of the build
kelvin8ec71442015-01-15 16:57:00 -0800268 Returns: main.TRUE on success
Jon Hallde9d9aa2014-10-08 20:36:02 -0400269 On Failure, exits the test
kelvin8ec71442015-01-15 16:57:00 -0800270 """
Jon Hallde9d9aa2014-10-08 20:36:02 -0400271 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800272 main.log.info( "Running 'mvn clean install' on " +
273 str( self.name ) +
kelvin8ec71442015-01-15 16:57:00 -0800274 ". This may take some time." )
275 self.handle.sendline( "cd " + self.home )
276 self.handle.expect( "\$" )
Jon Hallea7818b2014-10-09 14:30:59 -0400277
kelvin8ec71442015-01-15 16:57:00 -0800278 self.handle.sendline( "" )
279 self.handle.expect( "\$" )
shahshreya9f531fe2015-06-10 12:03:51 -0700280
281 if not skipTest:
282 self.handle.sendline( "mvn clean install" )
283 self.handle.expect( "mvn clean install" )
284 else:
285 self.handle.sendline( "mvn clean install -DskipTests" +
286 " -Dcheckstyle.skip -U -T 1C" )
287 self.handle.expect( "mvn clean install -DskipTests" +
288 " -Dcheckstyle.skip -U -T 1C" )
kelvin8ec71442015-01-15 16:57:00 -0800289 while True:
290 i = self.handle.expect( [
Jon Hall274b6642015-02-17 11:57:17 -0800291 'There\sis\sinsufficient\smemory\sfor\sthe\sJava\s' +
Jon Hallefbd9792015-03-05 16:11:36 -0800292 'Runtime\sEnvironment\sto\scontinue',
Jon Hallde9d9aa2014-10-08 20:36:02 -0400293 'BUILD\sFAILURE',
294 'BUILD\sSUCCESS',
Jon Halle94919c2015-03-23 11:42:57 -0700295 'onos\$', #TODO: fix this to be more generic?
Jon Hallde9d9aa2014-10-08 20:36:02 -0400296 'ONOS\$',
pingping-lin57a56ce2015-05-20 16:43:48 -0700297 pexpect.TIMEOUT ], mciTimeout )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400298 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800299 main.log.error( self.name + ":There is insufficient memory \
300 for the Java Runtime Environment to continue." )
301 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400302 main.cleanup()
303 main.exit()
304 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800305 main.log.error( self.name + ": Build failure!" )
306 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400307 main.cleanup()
308 main.exit()
309 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800310 main.log.info( self.name + ": Build success!" )
Jon Halle94919c2015-03-23 11:42:57 -0700311 elif i == 3 or i == 4:
kelvin8ec71442015-01-15 16:57:00 -0800312 main.log.info( self.name + ": Build complete" )
313 # Print the build time
Jon Hallf8ef52c2014-10-09 19:37:33 -0400314 for line in self.handle.before.splitlines():
315 if "Total time:" in line:
kelvin8ec71442015-01-15 16:57:00 -0800316 main.log.info( line )
317 self.handle.sendline( "" )
318 self.handle.expect( "\$", timeout=60 )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400319 return main.TRUE
Jon Halle94919c2015-03-23 11:42:57 -0700320 elif i == 5:
kelvin8ec71442015-01-15 16:57:00 -0800321 main.log.error(
322 self.name +
323 ": mvn clean install TIMEOUT!" )
324 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400325 main.cleanup()
326 main.exit()
327 else:
Jon Hall274b6642015-02-17 11:57:17 -0800328 main.log.error( self.name + ": unexpected response from " +
Jon Hallefbd9792015-03-05 16:11:36 -0800329 "mvn clean install" )
kelvin8ec71442015-01-15 16:57:00 -0800330 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400331 main.cleanup()
332 main.exit()
333 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800334 main.log.error( self.name + ": EOF exception found" )
335 main.log.error( self.name + ": " + self.handle.before )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400336 main.cleanup()
337 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800338 except Exception:
339 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400340 main.cleanup()
341 main.exit()
Jon Hallacabffd2014-10-09 12:36:53 -0400342
Jon Hall61282e32015-03-19 11:34:11 -0700343 def gitPull( self, comp1="", fastForward=True ):
kelvin8ec71442015-01-15 16:57:00 -0800344 """
Jon Hallacabffd2014-10-09 12:36:53 -0400345 Assumes that "git pull" works without login
Jon Hall47a93fb2015-01-06 16:46:06 -0800346
Jon Hall61282e32015-03-19 11:34:11 -0700347 If the fastForward boolean is set to true, only git pulls that can
348 be fast forwarded will be performed. IE if you have not local commits
349 in your branch.
350
Jon Hallacabffd2014-10-09 12:36:53 -0400351 This function will perform a git pull on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800352 If used as gitPull( "NODE" ) it will do git pull + NODE. This is
Jon Hallacabffd2014-10-09 12:36:53 -0400353 for the purpose of pulling from other nodes if necessary.
354
Jon Hall47a93fb2015-01-06 16:46:06 -0800355 Otherwise, this function will perform a git pull in the
Jon Hallacabffd2014-10-09 12:36:53 -0400356 ONOS repository. If it has any problems, it will return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -0800357 If it successfully does a gitPull, it will return a 1 ( main.TRUE )
Shreya Shahee15f6c2014-10-28 18:12:30 -0400358 If it has no updates, it will return 3.
Jon Hallacabffd2014-10-09 12:36:53 -0400359
kelvin8ec71442015-01-15 16:57:00 -0800360 """
Jon Hallacabffd2014-10-09 12:36:53 -0400361 try:
kelvin8ec71442015-01-15 16:57:00 -0800362 self.handle.sendline( "cd " + self.home )
kelvin-onlaba1484582015-02-02 15:46:20 -0800363 self.handle.expect( self.home + "\$" )
Jon Hall61282e32015-03-19 11:34:11 -0700364 cmd = "git pull"
365 if comp1 != "":
366 cmd += ' ' + comp1
367 if fastForward:
368 cmd += ' ' + " --ff-only"
369 self.handle.sendline( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800370 i = self.handle.expect(
371 [
372 'fatal',
373 'Username\sfor\s(.*):\s',
374 '\sfile(s*) changed,\s',
375 'Already up-to-date',
376 'Aborting',
377 'You\sare\snot\scurrently\son\sa\sbranch',
Jon Hall274b6642015-02-17 11:57:17 -0800378 'You asked me to pull without telling me which branch you',
379 'Pull is not possible because you have unmerged files',
Jon Hall61282e32015-03-19 11:34:11 -0700380 'Please enter a commit message to explain why this merge',
381 'Found a swap file by the name',
382 'Please, commit your changes before you can merge.',
kelvin-onlabd3b64892015-01-20 13:26:24 -0800383 pexpect.TIMEOUT ],
384 timeout=300 )
kelvin8ec71442015-01-15 16:57:00 -0800385 if i == 0:
Jon Hall61282e32015-03-19 11:34:11 -0700386 main.log.error( self.name + ": Git pull had some issue" )
387 output = self.handle.after
388 self.handle.expect( '\$' )
389 output += self.handle.before
390 main.log.warn( output )
Jon Hallacabffd2014-10-09 12:36:53 -0400391 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800392 elif i == 1:
393 main.log.error(
394 self.name +
395 ": Git Pull Asking for username. " )
Jon Hallacabffd2014-10-09 12:36:53 -0400396 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800397 elif i == 2:
398 main.log.info(
399 self.name +
400 ": Git Pull - pulling repository now" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800401 self.handle.expect( self.home + "\$", 120 )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800402 # So that only when git pull is done, we do mvn clean compile
403 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800404 elif i == 3:
405 main.log.info( self.name + ": Git Pull - Already up to date" )
Jon Hall47a93fb2015-01-06 16:46:06 -0800406 return i
kelvin8ec71442015-01-15 16:57:00 -0800407 elif i == 4:
408 main.log.info(
409 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800410 ": Git Pull - Aborting..." +
411 "Are there conflicting git files?" )
Jon Hallacabffd2014-10-09 12:36:53 -0400412 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800413 elif i == 5:
414 main.log.info(
415 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800416 ": Git Pull - You are not currently " +
417 "on a branch so git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400418 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800419 elif i == 6:
420 main.log.info(
421 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800422 ": Git Pull - You have not configured an upstream " +
423 "branch to pull from. Git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400424 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800425 elif i == 7:
426 main.log.info(
427 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800428 ": Git Pull - Pull is not possible because " +
429 "you have unmerged files." )
Jon Hallacabffd2014-10-09 12:36:53 -0400430 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800431 elif i == 8:
Jon Hall61282e32015-03-19 11:34:11 -0700432 # NOTE: abandoning test since we can't reliably handle this
433 # there could be different default text editors and we
434 # also don't know if we actually want to make the commit
435 main.log.error( "Git pull resulted in a merge commit message" +
436 ". Exiting test!" )
437 main.cleanup()
438 main.exit()
439 elif i == 9: # Merge commit message but swap file exists
440 main.log.error( "Git pull resulted in a merge commit message" +
441 " but a swap file exists." )
442 try:
443 self.handle.send( 'A' ) # Abort
444 self.handle.expect( "\$" )
445 return main.ERROR
446 except Exception:
447 main.log.exception( "Couldn't exit editor prompt!")
448 main.cleanup()
449 main.exit()
450 elif i == 10: # In the middle of a merge commit
451 main.log.error( "Git branch is in the middle of a merge. " )
452 main.log.warn( self.handle.before + self.handle.after )
453 return main.ERROR
454 elif i == 11:
kelvin8ec71442015-01-15 16:57:00 -0800455 main.log.error( self.name + ": Git Pull - TIMEOUT" )
456 main.log.error(
457 self.name + " Response was: " + str(
458 self.handle.before ) )
Jon Hallacabffd2014-10-09 12:36:53 -0400459 return main.ERROR
460 else:
kelvin8ec71442015-01-15 16:57:00 -0800461 main.log.error(
462 self.name +
463 ": Git Pull - Unexpected response, check for pull errors" )
Jon Hallacabffd2014-10-09 12:36:53 -0400464 return main.ERROR
465 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800466 main.log.error( self.name + ": EOF exception found" )
467 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400468 main.cleanup()
469 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800470 except Exception:
471 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400472 main.cleanup()
473 main.exit()
474
kelvin-onlabd3b64892015-01-20 13:26:24 -0800475 def gitCheckout( self, branch="master" ):
kelvin8ec71442015-01-15 16:57:00 -0800476 """
Jon Hallacabffd2014-10-09 12:36:53 -0400477 Assumes that "git pull" works without login
kelvin8ec71442015-01-15 16:57:00 -0800478
Jon Hallacabffd2014-10-09 12:36:53 -0400479 This function will perform a git git checkout on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800480 If used as gitCheckout( "branch" ) it will do git checkout
481 of the "branch".
Jon Hallacabffd2014-10-09 12:36:53 -0400482
483 Otherwise, this function will perform a git checkout of the master
kelvin8ec71442015-01-15 16:57:00 -0800484 branch of the ONOS repository. If it has any problems, it will return
485 main.ERROR.
486 If the branch was already the specified branch, or the git checkout was
Jon Hallacabffd2014-10-09 12:36:53 -0400487 successful then the function will return main.TRUE.
488
kelvin8ec71442015-01-15 16:57:00 -0800489 """
Jon Hallacabffd2014-10-09 12:36:53 -0400490 try:
kelvin8ec71442015-01-15 16:57:00 -0800491 self.handle.sendline( "cd " + self.home )
kelvin-onlaba1484582015-02-02 15:46:20 -0800492 self.handle.expect( self.home + "\$" )
Jon Hall274b6642015-02-17 11:57:17 -0800493 main.log.info( self.name +
494 ": Checking out git branch/ref: " + branch + "..." )
kelvin8ec71442015-01-15 16:57:00 -0800495 cmd = "git checkout " + branch
496 self.handle.sendline( cmd )
497 self.handle.expect( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800498 i = self.handle.expect(
Jon Hall274b6642015-02-17 11:57:17 -0800499 [ 'fatal',
Jon Hall61282e32015-03-19 11:34:11 -0700500 'Username for (.*): ',
501 'Already on \'',
Jon Hall7a8354f2015-06-10 15:37:00 -0700502 'Switched to (a new )?branch \'' + str( branch ),
Jon Hall274b6642015-02-17 11:57:17 -0800503 pexpect.TIMEOUT,
504 'error: Your local changes to the following files' +
Jon Hallefbd9792015-03-05 16:11:36 -0800505 'would be overwritten by checkout:',
Jon Hall274b6642015-02-17 11:57:17 -0800506 'error: you need to resolve your current index first',
507 "You are in 'detached HEAD' state.",
508 "HEAD is now at " ],
kelvin-onlabd3b64892015-01-20 13:26:24 -0800509 timeout=60 )
kelvin8ec71442015-01-15 16:57:00 -0800510 if i == 0:
511 main.log.error(
512 self.name +
513 ": Git checkout had some issue..." )
514 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400515 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800516 elif i == 1:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800517 main.log.error(
518 self.name +
519 ": Git checkout asking for username." +
520 " Please configure your local git repository to be able " +
521 "to access your remote repository passwordlessly" )
Jon Hall274b6642015-02-17 11:57:17 -0800522 # TODO add support for authenticating
Jon Hallacabffd2014-10-09 12:36:53 -0400523 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800524 elif i == 2:
525 main.log.info(
526 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800527 ": Git Checkout %s : Already on this branch" % branch )
kelvin-onlaba1484582015-02-02 15:46:20 -0800528 self.handle.expect( self.home + "\$" )
kelvin8ec71442015-01-15 16:57:00 -0800529 # main.log.info( "DEBUG: after checkout cmd = "+
530 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400531 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800532 elif i == 3:
533 main.log.info(
534 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800535 ": Git checkout %s - Switched to this branch" % branch )
kelvin-onlaba1484582015-02-02 15:46:20 -0800536 self.handle.expect( self.home + "\$" )
kelvin8ec71442015-01-15 16:57:00 -0800537 # main.log.info( "DEBUG: after checkout cmd = "+
538 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400539 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800540 elif i == 4:
541 main.log.error( self.name + ": Git Checkout- TIMEOUT" )
542 main.log.error(
Jon Hall274b6642015-02-17 11:57:17 -0800543 self.name + " Response was: " + str( self.handle.before ) )
Jon Hallacabffd2014-10-09 12:36:53 -0400544 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800545 elif i == 5:
546 self.handle.expect( "Aborting" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800547 main.log.error(
548 self.name +
549 ": Git checkout error: \n" +
Jon Hall274b6642015-02-17 11:57:17 -0800550 "Your local changes to the following files would" +
551 " be overwritten by checkout:" +
552 str( self.handle.before ) )
kelvin-onlaba1484582015-02-02 15:46:20 -0800553 self.handle.expect( self.home + "\$" )
Jon Hall81e29af2014-11-04 20:41:23 -0500554 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800555 elif i == 6:
Jon Hall274b6642015-02-17 11:57:17 -0800556 main.log.error(
557 self.name +
558 ": Git checkout error: \n" +
559 "You need to resolve your current index first:" +
560 str( self.handle.before ) )
kelvin-onlaba1484582015-02-02 15:46:20 -0800561 self.handle.expect( self.home + "\$" )
Jon Hall81e29af2014-11-04 20:41:23 -0500562 return main.ERROR
Jon Hall274b6642015-02-17 11:57:17 -0800563 elif i == 7:
564 main.log.info(
565 self.name +
566 ": Git checkout " + str( branch ) +
567 " - You are in 'detached HEAD' state. HEAD is now at " +
568 str( branch ) )
569 self.handle.expect( self.home + "\$" )
570 return main.TRUE
571 elif i == 8: # Already in detached HEAD on the specified commit
572 main.log.info(
573 self.name +
574 ": Git Checkout %s : Already on commit" % branch )
575 self.handle.expect( self.home + "\$" )
576 return main.TRUE
Jon Hallacabffd2014-10-09 12:36:53 -0400577 else:
kelvin8ec71442015-01-15 16:57:00 -0800578 main.log.error(
579 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800580 ": Git Checkout - Unexpected response, " +
581 "check for pull errors" )
kelvin8ec71442015-01-15 16:57:00 -0800582 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400583 return main.ERROR
584
585 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800586 main.log.error( self.name + ": EOF exception found" )
587 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400588 main.cleanup()
589 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800590 except Exception:
591 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400592 main.cleanup()
593 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400594
pingping-lin6d23d9e2015-02-02 16:54:24 -0800595 def getBranchName( self ):
pingping-linf30cf272015-05-29 15:54:07 -0700596 main.log.info( "self.home = " )
597 main.log.info( self.home )
pingping-lin6d23d9e2015-02-02 16:54:24 -0800598 self.handle.sendline( "cd " + self.home )
pingping-lin9bf3d8f2015-05-29 16:05:28 -0700599 self.handle.expect( self.home + "\$" )
pingping-lin6d23d9e2015-02-02 16:54:24 -0800600 self.handle.sendline( "git name-rev --name-only HEAD" )
601 self.handle.expect( "git name-rev --name-only HEAD" )
602 self.handle.expect( "\$" )
603
604 lines = self.handle.before.splitlines()
605 if lines[1] == "master":
606 return "master"
607 elif lines[1] == "onos-1.0":
608 return "onos-1.0"
609 else:
610 main.log.info( lines[1] )
611 return "unexpected ONOS branch for SDN-IP test"
612
kelvin-onlabd3b64892015-01-20 13:26:24 -0800613 def getVersion( self, report=False ):
kelvin8ec71442015-01-15 16:57:00 -0800614 """
Jon Hall274b6642015-02-17 11:57:17 -0800615 Writes the COMMIT number to the report to be parsed
Jon Hallefbd9792015-03-05 16:11:36 -0800616 by Jenkins data collector.
kelvin8ec71442015-01-15 16:57:00 -0800617 """
Jon Hall45ec0922014-10-10 19:33:49 -0400618 try:
kelvin8ec71442015-01-15 16:57:00 -0800619 self.handle.sendline( "" )
620 self.handle.expect( "\$" )
621 self.handle.sendline(
622 "cd " +
623 self.home +
Jon Hall274b6642015-02-17 11:57:17 -0800624 "; git log -1 --pretty=fuller --decorate=short | grep -A 6 " +
625 " \"commit\" --color=never" )
kelvin8ec71442015-01-15 16:57:00 -0800626 # NOTE: for some reason there are backspaces inserted in this
627 # phrase when run from Jenkins on some tests
628 self.handle.expect( "never" )
629 self.handle.expect( "\$" )
630 response = ( self.name + ": \n" + str(
631 self.handle.before + self.handle.after ) )
632 self.handle.sendline( "cd " + self.home )
633 self.handle.expect( "\$" )
634 lines = response.splitlines()
Jon Hall45ec0922014-10-10 19:33:49 -0400635 for line in lines:
Jon Hallfd191202014-11-07 18:36:09 -0500636 print line
637 if report:
pingping-lin763ee042015-05-20 17:45:30 -0700638 main.log.wiki( "<blockquote>" )
kelvin8ec71442015-01-15 16:57:00 -0800639 for line in lines[ 2:-1 ]:
640 # Bracket replacement is for Wiki-compliant
641 # formatting. '<' or '>' are interpreted
642 # as xml specific tags that cause errors
643 line = line.replace( "<", "[" )
644 line = line.replace( ">", "]" )
pingping-lin763ee042015-05-20 17:45:30 -0700645 #main.log.wiki( "\t" + line )
646 main.log.wiki( line + "<br /> " )
647 main.log.summary( line )
648 main.log.wiki( "</blockquote>" )
649 main.log.summary("\n")
kelvin8ec71442015-01-15 16:57:00 -0800650 return lines[ 2 ]
Jon Hall45ec0922014-10-10 19:33:49 -0400651 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800652 main.log.error( self.name + ": EOF exception found" )
653 main.log.error( self.name + ": " + self.handle.before )
Jon Hall45ec0922014-10-10 19:33:49 -0400654 main.cleanup()
655 main.exit()
Jon Hall368769f2014-11-19 15:43:35 -0800656 except pexpect.TIMEOUT:
kelvin8ec71442015-01-15 16:57:00 -0800657 main.log.error( self.name + ": TIMEOUT exception found" )
658 main.log.error( self.name + ": " + self.handle.before )
Jon Hall368769f2014-11-19 15:43:35 -0800659 main.cleanup()
660 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800661 except Exception:
662 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall45ec0922014-10-10 19:33:49 -0400663 main.cleanup()
664 main.exit()
665
kelvin-onlabd3b64892015-01-20 13:26:24 -0800666 def createCellFile( self, benchIp, fileName, mnIpAddrs,
kelvin-onlaba4074292015-07-09 15:19:49 -0700667 appString, onosIpAddrs ):
kelvin8ec71442015-01-15 16:57:00 -0800668 """
andrewonlab94282092014-10-10 13:00:11 -0400669 Creates a cell file based on arguments
670 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800671 * Bench IP address ( benchIp )
andrewonlab94282092014-10-10 13:00:11 -0400672 - Needed to copy the cell file over
kelvin-onlabd3b64892015-01-20 13:26:24 -0800673 * File name of the cell file ( fileName )
674 * Mininet IP address ( mnIpAddrs )
kelvin8ec71442015-01-15 16:57:00 -0800675 - Note that only 1 ip address is
andrewonlab94282092014-10-10 13:00:11 -0400676 supported currently
kelvin-onlabd3b64892015-01-20 13:26:24 -0800677 * ONOS IP addresses ( onosIpAddrs )
andrewonlab94282092014-10-10 13:00:11 -0400678 - Must be passed in as last arguments
kelvin8ec71442015-01-15 16:57:00 -0800679
andrewonlab94282092014-10-10 13:00:11 -0400680 NOTE: Assumes cells are located at:
681 ~/<self.home>/tools/test/cells/
kelvin8ec71442015-01-15 16:57:00 -0800682 """
683 # Variable initialization
Jon Hall6801cda2015-07-15 14:13:45 -0700684 cellDirectory = self.home + "/tools/test/cells/"
kelvin8ec71442015-01-15 16:57:00 -0800685 # We want to create the cell file in the dependencies directory
686 # of TestON first, then copy over to ONOS bench
kelvin-onlabd3b64892015-01-20 13:26:24 -0800687 tempDirectory = "/tmp/"
kelvin8ec71442015-01-15 16:57:00 -0800688 # Create the cell file in the directory for writing ( w+ )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800689 cellFile = open( tempDirectory + fileName, 'w+' )
Jon Hall6801cda2015-07-15 14:13:45 -0700690 if isinstance( onosIpAddrs, types.StringType ):
691 onosIpAddrs = [ onosIpAddrs ]
kelvin8ec71442015-01-15 16:57:00 -0800692
cameron@onlab.us75900962015-03-30 13:22:49 -0700693 # App string is hardcoded environment variables
kelvin8ec71442015-01-15 16:57:00 -0800694 # That you may wish to use by default on startup.
cameron@onlab.us75900962015-03-30 13:22:49 -0700695 # Note that you may not want certain apps listed
kelvin8ec71442015-01-15 16:57:00 -0800696 # on here.
cameron@onlab.us75900962015-03-30 13:22:49 -0700697 appString = "export ONOS_APPS=" + appString
kelvin-onlabd3b64892015-01-20 13:26:24 -0800698 mnString = "export OCN="
kelvin-onlabf70fd542015-05-07 18:41:40 -0700699 if mnIpAddrs == "":
700 mnString = ""
kelvin-onlabd3b64892015-01-20 13:26:24 -0800701 onosString = "export OC"
702 tempCount = 1
kelvin8ec71442015-01-15 16:57:00 -0800703
kelvin-onlabd3b64892015-01-20 13:26:24 -0800704 # Create ONOSNIC ip address prefix
kelvin-onlaba4074292015-07-09 15:19:49 -0700705 tempOnosIp = str( onosIpAddrs[ 0 ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800706 tempList = []
707 tempList = tempOnosIp.split( "." )
kelvin8ec71442015-01-15 16:57:00 -0800708 # Omit last element of list to format for NIC
kelvin-onlabd3b64892015-01-20 13:26:24 -0800709 tempList = tempList[ :-1 ]
kelvin8ec71442015-01-15 16:57:00 -0800710 # Structure the nic string ip
kelvin-onlabd3b64892015-01-20 13:26:24 -0800711 nicAddr = ".".join( tempList ) + ".*"
712 onosNicString = "export ONOS_NIC=" + nicAddr
andrewonlab94282092014-10-10 13:00:11 -0400713
714 try:
kelvin8ec71442015-01-15 16:57:00 -0800715 # Start writing to file
kelvin-onlabd3b64892015-01-20 13:26:24 -0800716 cellFile.write( onosNicString + "\n" )
andrewonlab94282092014-10-10 13:00:11 -0400717
kelvin-onlabd3b64892015-01-20 13:26:24 -0800718 for arg in onosIpAddrs:
719 # For each argument in onosIpAddrs, write to file
kelvin8ec71442015-01-15 16:57:00 -0800720 # Output should look like the following:
andrewonlabd4940492014-10-24 12:21:27 -0400721 # export OC1="10.128.20.11"
722 # export OC2="10.128.20.12"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800723 cellFile.write( onosString + str( tempCount ) +
Jon Hall6f665652015-09-18 10:08:07 -0700724 "=\"" + arg + "\"\n" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800725 tempCount = tempCount + 1
kelvin8ec71442015-01-15 16:57:00 -0800726
Jon Hall6f665652015-09-18 10:08:07 -0700727 cellFile.write( "export OCI=$OC1\n" )
728 cellFile.write( mnString + "\"" + mnIpAddrs + "\"\n" )
cameron@onlab.us75900962015-03-30 13:22:49 -0700729 cellFile.write( appString + "\n" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800730 cellFile.close()
andrewonlab94282092014-10-10 13:00:11 -0400731
kelvin8ec71442015-01-15 16:57:00 -0800732 # We use os.system to send the command to TestON cluster
733 # to account for the case in which TestON is not located
734 # on the same cluster as the ONOS bench
735 # Note that even if TestON is located on the same cluster
736 # as ONOS bench, you must setup passwordless ssh
737 # between TestON and ONOS bench in order to automate the test.
kelvin-onlabc2b79102015-07-14 11:41:20 -0700738 os.system( "scp " + tempDirectory + fileName + " " +
739 self.user_name + "@" + self.ip_address + ":" + cellDirectory )
andrewonlab94282092014-10-10 13:00:11 -0400740
andrewonlab2a6c9342014-10-16 13:40:15 -0400741 return main.TRUE
742
andrewonlab94282092014-10-10 13:00:11 -0400743 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800744 main.log.error( self.name + ": EOF exception found" )
745 main.log.error( self.name + ": " + self.handle.before )
andrewonlab94282092014-10-10 13:00:11 -0400746 main.cleanup()
747 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800748 except Exception:
749 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab94282092014-10-10 13:00:11 -0400750 main.cleanup()
751 main.exit()
752
kelvin-onlabd3b64892015-01-20 13:26:24 -0800753 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800754 """
andrewonlab95ca1462014-10-09 14:04:24 -0400755 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800756 """
Hari Krishna03f530e2015-07-10 17:28:27 -0700757 import re
andrewonlab95ca1462014-10-09 14:04:24 -0400758 try:
759 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800760 main.log.error( "Must define cellname" )
andrewonlab95ca1462014-10-09 14:04:24 -0400761 main.cleanup()
762 main.exit()
763 else:
kelvin8ec71442015-01-15 16:57:00 -0800764 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800765 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800766 # Note that this variable name is subject to change
andrewonlab95ca1462014-10-09 14:04:24 -0400767 # and that this driver will have to change accordingly
Jon Hall3b489db2015-10-05 14:38:37 -0700768 self.handle.expect( str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800769 handleBefore = self.handle.before
770 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800771 # Get the rest of the handle
Jon Hall3b489db2015-10-05 14:38:37 -0700772 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800773 handleMore = self.handle.before
andrewonlab95ca1462014-10-09 14:04:24 -0400774
Hari Krishna03f530e2015-07-10 17:28:27 -0700775 cell_result = handleBefore + handleAfter + handleMore
776 print cell_result
777 if( re.search( "No such cell", cell_result ) ):
778 main.log.error( "Cell call returned: " + handleBefore +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800779 handleAfter + handleMore )
Hari Krishna03f530e2015-07-10 17:28:27 -0700780 main.cleanup()
781 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400782 return main.TRUE
andrewonlab95ca1462014-10-09 14:04:24 -0400783 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800784 main.log.error( self.name + ": EOF exception found" )
785 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ca1462014-10-09 14:04:24 -0400786 main.cleanup()
787 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800788 except Exception:
789 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ca1462014-10-09 14:04:24 -0400790 main.cleanup()
791 main.exit()
792
kelvin-onlabd3b64892015-01-20 13:26:24 -0800793 def verifyCell( self ):
kelvin8ec71442015-01-15 16:57:00 -0800794 """
andrewonlabc03bf6c2014-10-09 14:56:18 -0400795 Calls 'onos-verify-cell' to check for cell installation
kelvin8ec71442015-01-15 16:57:00 -0800796 """
797 # TODO: Add meaningful expect value
andrewonlab8d0d7d72014-10-09 16:33:15 -0400798
andrewonlabc03bf6c2014-10-09 14:56:18 -0400799 try:
kelvin8ec71442015-01-15 16:57:00 -0800800 # Clean handle by sending empty and expecting $
801 self.handle.sendline( "" )
802 self.handle.expect( "\$" )
803 self.handle.sendline( "onos-verify-cell" )
804 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800805 handleBefore = self.handle.before
806 handleAfter = self.handle.after
kelvin-onlabd3b64892015-01-20 13:26:24 -0800807 main.log.info( "Verify cell returned: " + handleBefore +
Jon Hall3b489db2015-10-05 14:38:37 -0700808 handleAfter )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400809 return main.TRUE
Jon Halla5cb6172015-02-23 09:28:28 -0800810 except pexpect.ExceptionPexpect as e:
Jon Hall3b489db2015-10-05 14:38:37 -0700811 main.log.exception( self.name + ": Pexpect exception found: " )
kelvin8ec71442015-01-15 16:57:00 -0800812 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -0400813 main.cleanup()
814 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800815 except Exception:
816 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400817 main.cleanup()
818 main.exit()
819
jenkins1e99e7b2015-04-02 18:15:39 -0700820 def onosCfgSet( self, ONOSIp, configName, configParam ):
821 """
822 Uses 'onos <node-ip> cfg set' to change a parameter value of an
Jon Hall4ba53f02015-07-29 13:07:41 -0700823 application.
824
jenkins1e99e7b2015-04-02 18:15:39 -0700825 ex)
826 onos 10.0.0.1 cfg set org.onosproject.myapp appSetting 1
jenkins1e99e7b2015-04-02 18:15:39 -0700827 ONOSIp = '10.0.0.1'
828 configName = 'org.onosproject.myapp'
829 configParam = 'appSetting 1'
jenkins1e99e7b2015-04-02 18:15:39 -0700830 """
cameron@onlab.us78b89652015-07-08 15:21:03 -0700831 for i in range(5):
832 try:
833 cfgStr = ( "onos "+str(ONOSIp)+" cfg set "+
834 str(configName) + " " +
835 str(configParam)
836 )
jenkins1e99e7b2015-04-02 18:15:39 -0700837
cameron@onlab.us78b89652015-07-08 15:21:03 -0700838 self.handle.sendline( "" )
839 self.handle.expect( ":~" )
840 self.handle.sendline( cfgStr )
Jon Hall4ba53f02015-07-29 13:07:41 -0700841 self.handle.expect("cfg set")
cameron@onlab.us78b89652015-07-08 15:21:03 -0700842 self.handle.expect( ":~" )
Jon Hall4ba53f02015-07-29 13:07:41 -0700843
cameron@onlab.us78b89652015-07-08 15:21:03 -0700844 paramValue = configParam.split(" ")[1]
845 paramName = configParam.split(" ")[0]
Jon Hall4ba53f02015-07-29 13:07:41 -0700846
cameron@onlab.us78b89652015-07-08 15:21:03 -0700847 checkStr = ( "onos " + str(ONOSIp) + """ cfg get " """ + str(configName) + " " + paramName + """ " """)
jenkins1e99e7b2015-04-02 18:15:39 -0700848
cameron@onlab.us78b89652015-07-08 15:21:03 -0700849 self.handle.sendline( checkStr )
850 self.handle.expect( ":~" )
jenkins1e99e7b2015-04-02 18:15:39 -0700851
cameron@onlab.us78b89652015-07-08 15:21:03 -0700852 if "value=" + paramValue + "," in self.handle.before:
Jon Hall4ba53f02015-07-29 13:07:41 -0700853 main.log.info("cfg " + configName + " successfully set to " + configParam)
cameron@onlab.us78b89652015-07-08 15:21:03 -0700854 return main.TRUE
855
856 except pexpect.ExceptionPexpect as e:
Jon Hall3b489db2015-10-05 14:38:37 -0700857 main.log.exception( self.name + ": Pexpect exception found: " )
cameron@onlab.us78b89652015-07-08 15:21:03 -0700858 main.log.error( self.name + ": " + self.handle.before )
859 main.cleanup()
860 main.exit()
861 except Exception:
862 main.log.exception( self.name + ": Uncaught exception!" )
863 main.cleanup()
864 main.exit()
Jon Hall4ba53f02015-07-29 13:07:41 -0700865
cameron@onlab.us78b89652015-07-08 15:21:03 -0700866 time.sleep(5)
867
868 main.log.error("CFG SET FAILURE: " + configName + " " + configParam )
Jon Hall4ba53f02015-07-29 13:07:41 -0700869 main.ONOSbench.handle.sendline("onos $OC1 cfg get")
cameron@onlab.us78b89652015-07-08 15:21:03 -0700870 main.ONOSbench.handle.expect("\$")
871 print main.ONOSbench.handle.before
872 main.ONOSbench.logReport( ONOSIp, ["ERROR","WARN","EXCEPT"], "d")
873 return main.FALSE
874
Jon Hall4ba53f02015-07-29 13:07:41 -0700875
kelvin-onlabd3b64892015-01-20 13:26:24 -0800876 def onosCli( self, ONOSIp, cmdstr ):
kelvin8ec71442015-01-15 16:57:00 -0800877 """
andrewonlab05e362f2014-10-10 00:40:57 -0400878 Uses 'onos' command to send various ONOS CLI arguments.
879 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800880 * ONOSIp: specify the ip of the cell machine
andrewonlab94282092014-10-10 13:00:11 -0400881 * cmdstr: specify the command string to send
kelvin8ec71442015-01-15 16:57:00 -0800882
883 This function is intended to expose the entire karaf
andrewonlab6e20c342014-10-10 18:08:48 -0400884 CLI commands for ONOS. Try to use this function first
885 before attempting to write a ONOS CLI specific driver
kelvin8ec71442015-01-15 16:57:00 -0800886 function.
887 You can see a list of available 'cmdstr' arguments
andrewonlab6e20c342014-10-10 18:08:48 -0400888 by starting onos, and typing in 'onos' to enter the
889 onos> CLI. Then, type 'help' to see the list of
kelvin8ec71442015-01-15 16:57:00 -0800890 available commands.
891 """
andrewonlab05e362f2014-10-10 00:40:57 -0400892 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800893 if not ONOSIp:
kelvin8ec71442015-01-15 16:57:00 -0800894 main.log.error( "You must specify the IP address" )
andrewonlab05e362f2014-10-10 00:40:57 -0400895 return main.FALSE
896 if not cmdstr:
kelvin8ec71442015-01-15 16:57:00 -0800897 main.log.error( "You must specify the command string" )
andrewonlab05e362f2014-10-10 00:40:57 -0400898 return main.FALSE
899
kelvin8ec71442015-01-15 16:57:00 -0800900 cmdstr = str( cmdstr )
901 self.handle.sendline( "" )
902 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400903
kelvin-onlabd3b64892015-01-20 13:26:24 -0800904 self.handle.sendline( "onos -w " + ONOSIp + " " + cmdstr )
kelvin8ec71442015-01-15 16:57:00 -0800905 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400906
kelvin-onlabd3b64892015-01-20 13:26:24 -0800907 handleBefore = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -0800908 main.log.info( "Command sent successfully" )
kelvin8ec71442015-01-15 16:57:00 -0800909 # Obtain return handle that consists of result from
910 # the onos command. The string may need to be
911 # configured further.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800912 returnString = handleBefore
kelvin-onlabd3b64892015-01-20 13:26:24 -0800913 return returnString
andrewonlab05e362f2014-10-10 00:40:57 -0400914 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800915 main.log.error( self.name + ": EOF exception found" )
916 main.log.error( self.name + ": " + self.handle.before )
andrewonlab05e362f2014-10-10 00:40:57 -0400917 main.cleanup()
918 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800919 except Exception:
920 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab05e362f2014-10-10 00:40:57 -0400921 main.cleanup()
922 main.exit()
Jon Hall7993bfc2014-10-09 16:30:14 -0400923
kelvin-onlabd3b64892015-01-20 13:26:24 -0800924 def onosInstall( self, options="-f", node="" ):
kelvin8ec71442015-01-15 16:57:00 -0800925 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400926 Installs ONOS bits on the designated cell machine.
kelvin8ec71442015-01-15 16:57:00 -0800927 If -f option is provided, it also forces an uninstall.
928 Presently, install also includes onos-push-bits and
Jon Hall7993bfc2014-10-09 16:30:14 -0400929 onos-config within.
kelvin8ec71442015-01-15 16:57:00 -0800930 The node option allows you to selectively only push the jar
Jon Hall7993bfc2014-10-09 16:30:14 -0400931 files to certain onos nodes
932
933 Returns: main.TRUE on success and main.FALSE on failure
kelvin8ec71442015-01-15 16:57:00 -0800934 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400935 try:
andrewonlab114768a2014-11-14 12:44:44 -0500936 if options:
kelvin8ec71442015-01-15 16:57:00 -0800937 self.handle.sendline( "onos-install " + options + " " + node )
andrewonlab114768a2014-11-14 12:44:44 -0500938 else:
kelvin8ec71442015-01-15 16:57:00 -0800939 self.handle.sendline( "onos-install " + node )
940 self.handle.expect( "onos-install " )
941 # NOTE: this timeout may need to change depending on the network
942 # and size of ONOS
943 i = self.handle.expect( [ "Network\sis\sunreachable",
kelvin-onlabd3b64892015-01-20 13:26:24 -0800944 "onos\sstart/running,\sprocess",
kelvin8ec71442015-01-15 16:57:00 -0800945 "ONOS\sis\salready\sinstalled",
946 pexpect.TIMEOUT ], timeout=60 )
Jon Hall7993bfc2014-10-09 16:30:14 -0400947 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800948 main.log.warn( "Network is unreachable" )
Jon Hall3b489db2015-10-05 14:38:37 -0700949 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400950 return main.FALSE
951 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800952 main.log.info(
953 "ONOS was installed on " +
954 node +
955 " and started" )
Jon Hall3b489db2015-10-05 14:38:37 -0700956 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400957 return main.TRUE
andrewonlabd9a73a72014-11-14 17:28:21 -0500958 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800959 main.log.info( "ONOS is already installed on " + node )
Jon Hall3b489db2015-10-05 14:38:37 -0700960 self.handle.expect( "\$" )
andrewonlabd9a73a72014-11-14 17:28:21 -0500961 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800962 elif i == 3:
963 main.log.info(
964 "Installation of ONOS on " +
965 node +
966 " timed out" )
Jon Hall3b489db2015-10-05 14:38:37 -0700967 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400968 return main.FALSE
andrewonlabc03bf6c2014-10-09 14:56:18 -0400969 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800970 main.log.error( self.name + ": EOF exception found" )
971 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400972 main.cleanup()
973 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800974 except Exception:
975 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400976 main.cleanup()
977 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400978
kelvin-onlabd3b64892015-01-20 13:26:24 -0800979 def onosStart( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800980 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400981 Calls onos command: 'onos-service [<node-ip>] start'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400982 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -0800983 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400984 try:
kelvin8ec71442015-01-15 16:57:00 -0800985 self.handle.sendline( "" )
986 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800987 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -0800988 " start" )
989 i = self.handle.expect( [
andrewonlab8d0d7d72014-10-09 16:33:15 -0400990 "Job\sis\salready\srunning",
991 "start/running",
992 "Unknown\sinstance",
kelvin8ec71442015-01-15 16:57:00 -0800993 pexpect.TIMEOUT ], timeout=120 )
Jon Hall3b489db2015-10-05 14:38:37 -0700994 self.handle.expect( "\$" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400995 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800996 main.log.info( "Service is already running" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400997 return main.TRUE
998 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800999 main.log.info( "ONOS service started" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001000 return main.TRUE
1001 else:
kelvin8ec71442015-01-15 16:57:00 -08001002 main.log.error( "ONOS service failed to start" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001003 main.cleanup()
1004 main.exit()
andrewonlab8d0d7d72014-10-09 16:33:15 -04001005 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001006 main.log.error( self.name + ": EOF exception found" )
1007 main.log.error( self.name + ": " + self.handle.before )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001008 main.cleanup()
1009 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001010 except Exception:
1011 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001012 main.cleanup()
1013 main.exit()
1014
kelvin-onlabd3b64892015-01-20 13:26:24 -08001015 def onosStop( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001016 """
andrewonlab2b30bd32014-10-09 16:48:55 -04001017 Calls onos command: 'onos-service [<node-ip>] stop'
andrewonlabe8e56fd2014-10-09 17:12:44 -04001018 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -08001019 """
andrewonlab2b30bd32014-10-09 16:48:55 -04001020 try:
kelvin8ec71442015-01-15 16:57:00 -08001021 self.handle.sendline( "" )
1022 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001023 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001024 " stop" )
1025 i = self.handle.expect( [
andrewonlab2b30bd32014-10-09 16:48:55 -04001026 "stop/waiting",
Jon Hall61282e32015-03-19 11:34:11 -07001027 "Could not resolve hostname",
andrewonlab2b30bd32014-10-09 16:48:55 -04001028 "Unknown\sinstance",
kelvin8ec71442015-01-15 16:57:00 -08001029 pexpect.TIMEOUT ], timeout=60 )
Jon Hall3b489db2015-10-05 14:38:37 -07001030 self.handle.expect( "\$" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001031 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001032 main.log.info( "ONOS service stopped" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001033 return main.TRUE
1034 elif i == 1:
Jon Hall65844a32015-03-09 19:09:37 -07001035 main.log.info( "onosStop() Unknown ONOS instance specified: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001036 str( nodeIp ) )
andrewonlab2b30bd32014-10-09 16:48:55 -04001037 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -07001038 elif i == 2:
1039 main.log.warn( "ONOS wasn't running" )
1040 return main.TRUE
andrewonlab2b30bd32014-10-09 16:48:55 -04001041 else:
kelvin8ec71442015-01-15 16:57:00 -08001042 main.log.error( "ONOS service failed to stop" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001043 return main.FALSE
andrewonlab2b30bd32014-10-09 16:48:55 -04001044 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001045 main.log.error( self.name + ": EOF exception found" )
1046 main.log.error( self.name + ": " + self.handle.before )
andrewonlab2b30bd32014-10-09 16:48:55 -04001047 main.cleanup()
1048 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001049 except Exception:
1050 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001051 main.cleanup()
1052 main.exit()
kelvin8ec71442015-01-15 16:57:00 -08001053
kelvin-onlabd3b64892015-01-20 13:26:24 -08001054 def onosUninstall( self, nodeIp="" ):
kelvin8ec71442015-01-15 16:57:00 -08001055 """
andrewonlabc8d47972014-10-09 16:52:36 -04001056 Calls the command: 'onos-uninstall'
kelvin8ec71442015-01-15 16:57:00 -08001057 Uninstalls ONOS from the designated cell machine, stopping
andrewonlabe8e56fd2014-10-09 17:12:44 -04001058 if needed
kelvin8ec71442015-01-15 16:57:00 -08001059 """
andrewonlabc8d47972014-10-09 16:52:36 -04001060 try:
kelvin8ec71442015-01-15 16:57:00 -08001061 self.handle.sendline( "" )
pingping-lin763ee042015-05-20 17:45:30 -07001062 self.handle.expect( "\$", timeout=60 )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001063 self.handle.sendline( "onos-uninstall " + str( nodeIp ) )
Jon Hall3b489db2015-10-05 14:38:37 -07001064 self.handle.expect( "\$", timeout=60 )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001065 main.log.info( "ONOS " + nodeIp + " was uninstalled" )
kelvin8ec71442015-01-15 16:57:00 -08001066 # onos-uninstall command does not return any text
andrewonlabc8d47972014-10-09 16:52:36 -04001067 return main.TRUE
pingping-lin763ee042015-05-20 17:45:30 -07001068 except pexpect.TIMEOUT:
1069 main.log.exception( self.name + ": Timeout in onosUninstall" )
1070 return main.FALSE
andrewonlabc8d47972014-10-09 16:52:36 -04001071 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001072 main.log.error( self.name + ": EOF exception found" )
1073 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc8d47972014-10-09 16:52:36 -04001074 main.cleanup()
1075 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001076 except Exception:
1077 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc8d47972014-10-09 16:52:36 -04001078 main.cleanup()
1079 main.exit()
andrewonlab2b30bd32014-10-09 16:48:55 -04001080
kelvin-onlabd3b64892015-01-20 13:26:24 -08001081 def onosDie( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001082 """
andrewonlabaedc8332014-12-04 12:43:03 -05001083 Issues the command 'onos-die <node-ip>'
1084 This command calls onos-kill and also stops the node
kelvin8ec71442015-01-15 16:57:00 -08001085 """
andrewonlabaedc8332014-12-04 12:43:03 -05001086 try:
kelvin8ec71442015-01-15 16:57:00 -08001087 self.handle.sendline( "" )
1088 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001089 cmdStr = "onos-kill " + str( nodeIp )
1090 self.handle.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -08001091 i = self.handle.expect( [
andrewonlabaedc8332014-12-04 12:43:03 -05001092 "Killing\sONOS",
1093 "ONOS\sprocess\sis\snot\srunning",
kelvin8ec71442015-01-15 16:57:00 -08001094 pexpect.TIMEOUT ], timeout=20 )
andrewonlabaedc8332014-12-04 12:43:03 -05001095 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001096 main.log.info( "ONOS instance " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001097 " was killed and stopped" )
andrewonlabaedc8332014-12-04 12:43:03 -05001098 return main.TRUE
1099 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001100 main.log.info( "ONOS process was not running" )
andrewonlabaedc8332014-12-04 12:43:03 -05001101 return main.FALSE
1102 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001103 main.log.error( self.name + ": EOF exception found" )
1104 main.log.error( self.name + ": " + self.handle.before )
andrewonlabaedc8332014-12-04 12:43:03 -05001105 main.cleanup()
1106 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001107 except Exception:
1108 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabaedc8332014-12-04 12:43:03 -05001109 main.cleanup()
1110 main.exit()
1111
kelvin-onlabd3b64892015-01-20 13:26:24 -08001112 def onosKill( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001113 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001114 Calls the command: 'onos-kill [<node-ip>]'
1115 "Remotely, and unceremoniously kills the ONOS instance running on
1116 the specified cell machine" - Tom V
kelvin8ec71442015-01-15 16:57:00 -08001117 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001118 try:
kelvin8ec71442015-01-15 16:57:00 -08001119 self.handle.sendline( "" )
1120 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001121 self.handle.sendline( "onos-kill " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -08001122 i = self.handle.expect( [
andrewonlabe8e56fd2014-10-09 17:12:44 -04001123 "\$",
1124 "No\sroute\sto\shost",
1125 "password:",
kelvin8ec71442015-01-15 16:57:00 -08001126 pexpect.TIMEOUT ], timeout=20 )
1127
andrewonlabe8e56fd2014-10-09 17:12:44 -04001128 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001129 main.log.info(
1130 "ONOS instance " + str(
kelvin-onlabd3b64892015-01-20 13:26:24 -08001131 nodeIp ) + " was killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001132 return main.TRUE
1133 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001134 main.log.info( "No route to host" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001135 return main.FALSE
1136 elif i == 2:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001137 main.log.info(
1138 "Passwordless login for host: " +
1139 str( nodeIp ) +
1140 " not configured" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001141 return main.FALSE
1142 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001143 main.log.info( "ONOS instance was not killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001144 return main.FALSE
kelvin8ec71442015-01-15 16:57:00 -08001145
andrewonlabe8e56fd2014-10-09 17:12:44 -04001146 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001147 main.log.error( self.name + ": EOF exception found" )
1148 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001149 main.cleanup()
1150 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001151 except Exception:
1152 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001153 main.cleanup()
1154 main.exit()
1155
kelvin-onlabd3b64892015-01-20 13:26:24 -08001156 def onosRemoveRaftLogs( self ):
kelvin8ec71442015-01-15 16:57:00 -08001157 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001158 Removes Raft / Copy cat files from ONOS to ensure
Jon Hallfcc88622014-11-25 13:09:54 -05001159 a cleaner environment.
1160
andrewonlab19fbdca2014-11-14 12:55:59 -05001161 Description:
Jon Hallfcc88622014-11-25 13:09:54 -05001162 Stops all ONOS defined in the cell,
andrewonlab19fbdca2014-11-14 12:55:59 -05001163 wipes the raft / copycat log files
kelvin8ec71442015-01-15 16:57:00 -08001164 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001165 try:
kelvin8ec71442015-01-15 16:57:00 -08001166 self.handle.sendline( "" )
1167 self.handle.expect( "\$" )
1168 self.handle.sendline( "onos-remove-raft-logs" )
1169 # Sometimes this command hangs
1170 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
1171 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001172 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001173 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
1174 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001175 if i == 1:
1176 return main.FALSE
andrewonlab19fbdca2014-11-14 12:55:59 -05001177 return main.TRUE
andrewonlab19fbdca2014-11-14 12:55:59 -05001178 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001179 main.log.error( self.name + ": EOF exception found" )
1180 main.log.error( self.name + ": " + self.handle.before )
andrewonlab19fbdca2014-11-14 12:55:59 -05001181 main.cleanup()
1182 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001183 except Exception:
1184 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab19fbdca2014-11-14 12:55:59 -05001185 main.cleanup()
1186 main.exit()
Jon Hallfcc88622014-11-25 13:09:54 -05001187
kelvin-onlabd3b64892015-01-20 13:26:24 -08001188 def onosStartNetwork( self, mntopo ):
kelvin8ec71442015-01-15 16:57:00 -08001189 """
1190 Calls the command 'onos-start-network [ <mininet-topo> ]
1191 "remotely starts the specified topology on the cell's
andrewonlab94282092014-10-10 13:00:11 -04001192 mininet machine against all controllers configured in the
kelvin8ec71442015-01-15 16:57:00 -08001193 cell."
andrewonlab94282092014-10-10 13:00:11 -04001194 * Specify mininet topology file name for mntopo
1195 * Topo files should be placed at:
1196 ~/<your-onos-directory>/tools/test/topos
kelvin8ec71442015-01-15 16:57:00 -08001197
andrewonlab94282092014-10-10 13:00:11 -04001198 NOTE: This function will take you to the mininet prompt
kelvin8ec71442015-01-15 16:57:00 -08001199 """
andrewonlab94282092014-10-10 13:00:11 -04001200 try:
1201 if not mntopo:
kelvin8ec71442015-01-15 16:57:00 -08001202 main.log.error( "You must specify a topo file to execute" )
andrewonlab94282092014-10-10 13:00:11 -04001203 return main.FALSE
andrewonlab94282092014-10-10 13:00:11 -04001204
kelvin8ec71442015-01-15 16:57:00 -08001205 mntopo = str( mntopo )
1206 self.handle.sendline( "" )
1207 self.handle.expect( "\$" )
andrewonlab94282092014-10-10 13:00:11 -04001208
kelvin8ec71442015-01-15 16:57:00 -08001209 self.handle.sendline( "onos-start-network " + mntopo )
1210 self.handle.expect( "mininet>" )
1211 main.log.info( "Network started, entered mininet prompt" )
1212
1213 # TODO: Think about whether return is necessary or not
andrewonlab94282092014-10-10 13:00:11 -04001214
1215 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001216 main.log.error( self.name + ": EOF exception found" )
1217 main.log.error( self.name + ": " + self.handle.before )
andrewonlab94282092014-10-10 13:00:11 -04001218 main.cleanup()
1219 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001220 except Exception:
1221 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab94282092014-10-10 13:00:11 -04001222 main.cleanup()
1223 main.exit()
1224
Jon Hall3b489db2015-10-05 14:38:37 -07001225 def isup( self, node="", timeout=120 ):
kelvin8ec71442015-01-15 16:57:00 -08001226 """
1227 Run's onos-wait-for-start which only returns once ONOS is at run
Cameron Franke9c94fb02015-01-21 10:20:20 -08001228 level 100(ready for use)
andrewonlab8d0d7d72014-10-09 16:33:15 -04001229
Jon Hall7993bfc2014-10-09 16:30:14 -04001230 Returns: main.TRUE if ONOS is running and main.FALSE on timeout
kelvin8ec71442015-01-15 16:57:00 -08001231 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001232 try:
Jon Hall3b489db2015-10-05 14:38:37 -07001233 self.handle.sendline( "onos-wait-for-start " + node )
1234 self.handle.expect( "onos-wait-for-start" )
kelvin8ec71442015-01-15 16:57:00 -08001235 # NOTE: this timeout is arbitrary"
Cameron Franke9c94fb02015-01-21 10:20:20 -08001236 i = self.handle.expect(["\$", pexpect.TIMEOUT], timeout)
Jon Hall7993bfc2014-10-09 16:30:14 -04001237 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001238 main.log.info( self.name + ": " + node + " is up" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001239 return main.TRUE
1240 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001241 # NOTE: since this function won't return until ONOS is ready,
Jon Hall7993bfc2014-10-09 16:30:14 -04001242 # we will kill it on timeout
kelvin8ec71442015-01-15 16:57:00 -08001243 main.log.error( "ONOS has not started yet" )
1244 self.handle.send( "\x03" ) # Control-C
1245 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001246 return main.FALSE
1247 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001248 main.log.error( self.name + ": EOF exception found" )
1249 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -04001250 main.cleanup()
1251 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001252 except Exception:
1253 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001254 main.cleanup()
1255 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001256
kelvin-onlabd3b64892015-01-20 13:26:24 -08001257 def pushTestIntentsShell(
1258 self,
1259 dpidSrc,
1260 dpidDst,
1261 numIntents,
1262 dirFile,
1263 onosIp,
1264 numMult="",
1265 appId="",
1266 report=True,
1267 options="" ):
kelvin8ec71442015-01-15 16:57:00 -08001268 """
andrewonlabb66dfa12014-12-02 15:51:10 -05001269 Description:
kelvin8ec71442015-01-15 16:57:00 -08001270 Use the linux prompt to push test intents to
andrewonlabb66dfa12014-12-02 15:51:10 -05001271 better parallelize the results than the CLI
1272 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001273 * dpidSrc: specify source dpid
1274 * dpidDst: specify destination dpid
1275 * numIntents: specify number of intents to push
1276 * dirFile: specify directory and file name to save
andrewonlabb66dfa12014-12-02 15:51:10 -05001277 results
kelvin-onlabd3b64892015-01-20 13:26:24 -08001278 * onosIp: specify the IP of ONOS to install on
kelvin8ec71442015-01-15 16:57:00 -08001279 NOTE:
andrewonlabb66dfa12014-12-02 15:51:10 -05001280 You must invoke this command at linux shell prompt
kelvin8ec71442015-01-15 16:57:00 -08001281 """
1282 try:
1283 # Create the string to sendline
andrewonlabaedc8332014-12-04 12:43:03 -05001284 if options:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001285 baseCmd = "onos " + str( onosIp ) + " push-test-intents " +\
kelvin8ec71442015-01-15 16:57:00 -08001286 options + " "
andrewonlabaedc8332014-12-04 12:43:03 -05001287 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001288 baseCmd = "onos " + str( onosIp ) + " push-test-intents "
kelvin8ec71442015-01-15 16:57:00 -08001289
kelvin-onlabd3b64892015-01-20 13:26:24 -08001290 addDpid = baseCmd + str( dpidSrc ) + " " + str( dpidDst )
1291 if not numMult:
1292 addIntents = addDpid + " " + str( numIntents )
1293 elif numMult:
1294 addIntents = addDpid + " " + str( numIntents ) + " " +\
1295 str( numMult )
1296 if appId:
1297 addApp = addIntents + " " + str( appId )
andrewonlabb66dfa12014-12-02 15:51:10 -05001298 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001299 addApp = addIntents
andrewonlabb66dfa12014-12-02 15:51:10 -05001300
andrewonlabaedc8332014-12-04 12:43:03 -05001301 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001302 sendCmd = addApp + " > " + str( dirFile ) + " &"
andrewonlabaedc8332014-12-04 12:43:03 -05001303 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001304 sendCmd = addApp + " &"
1305 main.log.info( "Send cmd: " + sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001306
kelvin-onlabd3b64892015-01-20 13:26:24 -08001307 self.handle.sendline( sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001308
1309 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001310 main.log.error( self.name + ": EOF exception found" )
1311 main.log.error( self.name + ": " + self.handle.before )
andrewonlabb66dfa12014-12-02 15:51:10 -05001312 main.cleanup()
1313 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001314 except Exception:
1315 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabb66dfa12014-12-02 15:51:10 -05001316 main.cleanup()
kelvin8ec71442015-01-15 16:57:00 -08001317 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001318
kelvin-onlabd3b64892015-01-20 13:26:24 -08001319 def getTopology( self, topologyOutput ):
kelvin8ec71442015-01-15 16:57:00 -08001320 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001321 Definition:
1322 Loads a json topology output
1323 Return:
1324 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -08001325 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001326 import json
Jon Hall77f53ce2014-10-13 18:02:06 -04001327 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001328 # either onos:topology or 'topology' will work in CLI
1329 topology = json.loads(topologyOutput)
1330 print topology
Jon Hall77f53ce2014-10-13 18:02:06 -04001331 return topology
1332 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001333 main.log.error( self.name + ": EOF exception found" )
1334 main.log.error( self.name + ": " + self.handle.before )
Jon Hall77f53ce2014-10-13 18:02:06 -04001335 main.cleanup()
1336 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001337 except Exception:
1338 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall77f53ce2014-10-13 18:02:06 -04001339 main.cleanup()
1340 main.exit()
1341
kelvin-onlabd3b64892015-01-20 13:26:24 -08001342 def checkStatus(
1343 self,
1344 topologyResult,
1345 numoswitch,
1346 numolink,
1347 logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08001348 """
Jon Hallefbd9792015-03-05 16:11:36 -08001349 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08001350 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08001351 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08001352
Jon Hall77f53ce2014-10-13 18:02:06 -04001353 Params: ip = ip used for the onos cli
1354 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08001355 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08001356 logLevel = level to log to.
1357 Currently accepts 'info', 'warn' and 'report'
Jon Hall77f53ce2014-10-13 18:02:06 -04001358
1359
kelvin-onlabd3b64892015-01-20 13:26:24 -08001360 logLevel can
Jon Hall77f53ce2014-10-13 18:02:06 -04001361
Jon Hallefbd9792015-03-05 16:11:36 -08001362 Returns: main.TRUE if the number of switches and links are correct,
1363 main.FALSE if the number of switches and links is incorrect,
Jon Hall77f53ce2014-10-13 18:02:06 -04001364 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08001365 """
Jon Hall77f53ce2014-10-13 18:02:06 -04001366 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001367 topology = self.getTopology( topologyResult )
Jon Hall77f53ce2014-10-13 18:02:06 -04001368 if topology == {}:
1369 return main.ERROR
1370 output = ""
kelvin8ec71442015-01-15 16:57:00 -08001371 # Is the number of switches is what we expected
shahshreya234a1682015-05-27 15:41:56 -07001372 devices = topology.get( 'devices', False )
1373 links = topology.get( 'links', False )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001374 if not devices or not links:
Jon Hall77f53ce2014-10-13 18:02:06 -04001375 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08001376 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08001377 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08001378 linkCheck = ( int( links ) == int( numolink ) )
Jon Hallefbd9792015-03-05 16:11:36 -08001379 if switchCheck and linkCheck:
kelvin8ec71442015-01-15 16:57:00 -08001380 # We expected the correct numbers
Jon Hall77f53ce2014-10-13 18:02:06 -04001381 output = output + "The number of links and switches match "\
kelvin8ec71442015-01-15 16:57:00 -08001382 + "what was expected"
Jon Hall77f53ce2014-10-13 18:02:06 -04001383 result = main.TRUE
1384 else:
1385 output = output + \
Jon Hall274b6642015-02-17 11:57:17 -08001386 "The number of links and switches does not match " + \
1387 "what was expected"
Jon Hall77f53ce2014-10-13 18:02:06 -04001388 result = main.FALSE
Jon Hallefbd9792015-03-05 16:11:36 -08001389 output = output + "\n ONOS sees %i devices" % int( devices )
1390 output = output + " (%i expected) " % int( numoswitch )
Jon Hall274b6642015-02-17 11:57:17 -08001391 output = output + "and %i links " % int( links )
1392 output = output + "(%i expected)" % int( numolink )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001393 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08001394 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001395 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08001396 main.log.warn( output )
Jon Hall77f53ce2014-10-13 18:02:06 -04001397 else:
kelvin8ec71442015-01-15 16:57:00 -08001398 main.log.info( output )
1399 return result
Jon Hall77f53ce2014-10-13 18:02:06 -04001400 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001401 main.log.error( self.name + ": EOF exception found" )
1402 main.log.error( self.name + ": " + self.handle.before )
Jon Hall77f53ce2014-10-13 18:02:06 -04001403 main.cleanup()
1404 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001405 except Exception:
1406 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall77f53ce2014-10-13 18:02:06 -04001407 main.cleanup()
1408 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001409
kelvin-onlabd3b64892015-01-20 13:26:24 -08001410 def tsharkPcap( self, interface, dirFile ):
kelvin8ec71442015-01-15 16:57:00 -08001411 """
andrewonlab970399c2014-11-07 13:09:32 -05001412 Capture all packet activity and store in specified
1413 directory/file
1414
1415 Required:
1416 * interface: interface to capture
1417 * dir: directory/filename to store pcap
kelvin8ec71442015-01-15 16:57:00 -08001418 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001419 try:
1420 self.handle.sendline( "" )
1421 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001422
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001423 self.handle.sendline( "tshark -i " + str( interface ) + " -t e -w " + str( dirFile ) + " &" )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001424 self.handle.sendline( "\n" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001425 self.handle.expect( "Capturing on" )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001426 self.handle.sendline( "\n" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001427 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001428
Jon Hallfebb1c72015-03-05 13:30:09 -08001429 main.log.info( "Tshark started capturing files on " +
1430 str( interface ) + " and saving to directory: " +
1431 str( dirFile ) )
1432 except pexpect.EOF:
1433 main.log.error( self.name + ": EOF exception found" )
1434 main.log.error( self.name + ": " + self.handle.before )
1435 main.cleanup()
1436 main.exit()
1437 except Exception:
1438 main.log.exception( self.name + ": Uncaught exception!" )
1439 main.cleanup()
1440 main.exit()
Shreya Shaha73aaad2014-10-27 18:03:09 -04001441
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001442 def onosTopoCfg( self, onosIp, jsonFile ):
kelvin8ec71442015-01-15 16:57:00 -08001443 """
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001444 Description:
1445 Execute onos-topo-cfg command
1446 Required:
1447 onosIp - IP of the onos node you want to send the json to
1448 jsonFile - File path of the json file
1449 Return:
1450 Returns main.TRUE if the command is successfull; Returns
1451 main.FALSE if there was an error
kelvin8ec71442015-01-15 16:57:00 -08001452 """
shahshreyae6c7cf42014-11-26 16:39:01 -08001453 try:
kelvin8ec71442015-01-15 16:57:00 -08001454 self.handle.sendline( "" )
1455 self.handle.expect( "\$" )
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001456 cmd = "onos-topo-cfg "
1457 self.handle.sendline( cmd + str( onosIp ) + " " + jsonFile )
1458 handle = self.handle.before
1459 print handle
1460 if "Error" in handle:
1461 main.log.error( self.name + ": " + self.handle.before )
1462 return main.FALSE
1463 else:
1464 self.handle.expect( "\$" )
1465 return main.TRUE
1466
Jon Hallfebb1c72015-03-05 13:30:09 -08001467 except pexpect.EOF:
1468 main.log.error( self.name + ": EOF exception found" )
1469 main.log.error( self.name + ": " + self.handle.before )
1470 main.cleanup()
1471 main.exit()
1472 except Exception:
1473 main.log.exception( self.name + ": Uncaught exception!" )
1474 main.cleanup()
1475 main.exit()
kelvin8ec71442015-01-15 16:57:00 -08001476
jenkins1e99e7b2015-04-02 18:15:39 -07001477 def tsharkGrep( self, grep, directory, interface='eth0', grepOptions='' ):
kelvin8ec71442015-01-15 16:57:00 -08001478 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001479 Required:
kelvin8ec71442015-01-15 16:57:00 -08001480 * grep string
andrewonlabba44bcf2014-10-16 16:54:41 -04001481 * directory to store results
1482 Optional:
1483 * interface - default: eth0
Jon Hall4ba53f02015-07-29 13:07:41 -07001484 * grepOptions - options for grep
andrewonlabba44bcf2014-10-16 16:54:41 -04001485 Description:
1486 Uses tshark command to grep specific group of packets
1487 and stores the results to specified directory.
kelvin8ec71442015-01-15 16:57:00 -08001488 The timestamp is hardcoded to be in epoch
1489 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001490 try:
1491 self.handle.sendline( "" )
1492 self.handle.expect( "\$" )
1493 self.handle.sendline( "" )
jenkins1e99e7b2015-04-02 18:15:39 -07001494 if grepOptions:
1495 grepStr = "grep "+str(grepOptions)
1496 else:
1497 grepStr = "grep"
Jon Hall4ba53f02015-07-29 13:07:41 -07001498
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001499 cmd = (
1500 "sudo tshark -i " +
Jon Hallfebb1c72015-03-05 13:30:09 -08001501 str( interface ) +
jenkins1e99e7b2015-04-02 18:15:39 -07001502 " -t e | " +
1503 grepStr + " --line-buffered \"" +
Jon Hallfebb1c72015-03-05 13:30:09 -08001504 str(grep) +
1505 "\" >" +
1506 directory +
1507 " &" )
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001508 self.handle.sendline(cmd)
1509 main.log.info(cmd)
Jon Hallfebb1c72015-03-05 13:30:09 -08001510 self.handle.expect( "Capturing on" )
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001511 self.handle.sendline( "\n" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001512 self.handle.expect( "\$" )
1513 except pexpect.EOF:
1514 main.log.error( self.name + ": EOF exception found" )
1515 main.log.error( self.name + ": " + self.handle.before )
1516 main.cleanup()
1517 main.exit()
1518 except Exception:
1519 main.log.exception( self.name + ": Uncaught exception!" )
1520 main.cleanup()
1521 main.exit()
1522
kelvin-onlabd3b64892015-01-20 13:26:24 -08001523 def tsharkStop( self ):
kelvin8ec71442015-01-15 16:57:00 -08001524 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001525 Removes wireshark files from /tmp and kills all tshark processes
kelvin8ec71442015-01-15 16:57:00 -08001526 """
1527 # Remove all pcap from previous captures
Jon Hallfebb1c72015-03-05 13:30:09 -08001528 try:
1529 self.execute( cmd="sudo rm /tmp/wireshark*" )
1530 self.handle.sendline( "" )
Jon Hallefbd9792015-03-05 16:11:36 -08001531 self.handle.sendline( "sudo kill -9 `ps -ef | grep \"tshark -i\"" +
1532 " | grep -v grep | awk '{print $2}'`" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001533 self.handle.sendline( "" )
1534 main.log.info( "Tshark stopped" )
1535 except pexpect.EOF:
1536 main.log.error( self.name + ": EOF exception found" )
1537 main.log.error( self.name + ": " + self.handle.before )
1538 main.cleanup()
1539 main.exit()
1540 except Exception:
1541 main.log.exception( self.name + ": Uncaught exception!" )
1542 main.cleanup()
1543 main.exit()
1544
kelvin8ec71442015-01-15 16:57:00 -08001545 def ptpd( self, args ):
1546 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001547 Initiate ptp with user-specified args.
1548 Required:
1549 * args: specify string of args after command
1550 'sudo ptpd'
kelvin8ec71442015-01-15 16:57:00 -08001551 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001552 try:
kelvin8ec71442015-01-15 16:57:00 -08001553 self.handle.sendline( "sudo ptpd " + str( args ) )
1554 i = self.handle.expect( [
andrewonlab0c38a4a2014-10-28 18:35:35 -04001555 "Multiple",
1556 "Error",
kelvin8ec71442015-01-15 16:57:00 -08001557 "\$" ] )
1558 self.handle.expect( "\$" )
andrewonlabba44bcf2014-10-16 16:54:41 -04001559
andrewonlab0c38a4a2014-10-28 18:35:35 -04001560 if i == 0:
1561 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001562 main.log.info( "ptpd returned an error: " +
1563 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001564 return handle
1565 elif i == 1:
1566 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001567 main.log.error( "ptpd returned an error: " +
1568 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001569 return handle
1570 else:
1571 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -08001572
andrewonlab0c38a4a2014-10-28 18:35:35 -04001573 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001574 main.log.error( self.name + ": EOF exception found" )
1575 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001576 main.cleanup()
1577 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001578 except Exception:
1579 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001580 main.cleanup()
1581 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001582
kelvin-onlabd3b64892015-01-20 13:26:24 -08001583 def cpLogsToDir( self, logToCopy,
Jon Hallefbd9792015-03-05 16:11:36 -08001584 destDir, copyFileName="" ):
kelvin8ec71442015-01-15 16:57:00 -08001585 """
1586 Copies logs to a desired directory.
andrewonlab5d7a8f32014-11-10 13:07:56 -05001587 Current implementation of ONOS deletes its karaf
1588 logs on every iteration. For debugging purposes,
kelvin8ec71442015-01-15 16:57:00 -08001589 you may want to use this function to capture
1590 certain karaf logs. ( or any other logs if needed )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001591 Localtime will be attached to the filename
1592
1593 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001594 * logToCopy: specify directory and log name to
andrewonlab5d7a8f32014-11-10 13:07:56 -05001595 copy.
kelvin8ec71442015-01-15 16:57:00 -08001596 ex ) /opt/onos/log/karaf.log.1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001597 For copying multiple files, leave copyFileName
1598 empty and only specify destDir -
kelvin8ec71442015-01-15 16:57:00 -08001599 ex ) /opt/onos/log/karaf*
kelvin-onlabd3b64892015-01-20 13:26:24 -08001600 * destDir: specify directory to copy to.
kelvin8ec71442015-01-15 16:57:00 -08001601 ex ) /tmp/
1602 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001603 * copyFileName: If you want to rename the log
1604 file, specify copyFileName. This will not work
andrewonlab5d7a8f32014-11-10 13:07:56 -05001605 with multiple file copying
kelvin8ec71442015-01-15 16:57:00 -08001606 """
andrewonlab5d7a8f32014-11-10 13:07:56 -05001607 try:
kelvin8ec71442015-01-15 16:57:00 -08001608 localtime = time.strftime( '%x %X' )
1609 localtime = localtime.replace( "/", "" )
1610 localtime = localtime.replace( " ", "_" )
1611 localtime = localtime.replace( ":", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001612 if destDir[ -1: ] != "/":
1613 destDir += "/"
andrewonlab5d7a8f32014-11-10 13:07:56 -05001614
kelvin-onlabd3b64892015-01-20 13:26:24 -08001615 if copyFileName:
Jon Hallfebb1c72015-03-05 13:30:09 -08001616 self.handle.sendline( "cp " + str( logToCopy ) + " " +
1617 str( destDir ) + str( copyFileName ) +
1618 localtime )
kelvin8ec71442015-01-15 16:57:00 -08001619 self.handle.expect( "cp" )
1620 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001621 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001622 self.handle.sendline( "cp " + str( logToCopy ) +
1623 " " + str( destDir ) )
kelvin8ec71442015-01-15 16:57:00 -08001624 self.handle.expect( "cp" )
1625 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001626
kelvin8ec71442015-01-15 16:57:00 -08001627 return self.handle.before
1628
1629 except pexpect.EOF:
1630 main.log.error( "Copying files failed" )
1631 main.log.error( self.name + ": EOF exception found" )
1632 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001633 except Exception:
1634 main.log.exception( "Copying files failed" )
1635
Jon Hall16b72c42015-05-20 10:23:36 -07001636 def checkLogs( self, onosIp, restart=False):
kelvin8ec71442015-01-15 16:57:00 -08001637 """
Jon Hall94fd0472014-12-08 11:52:42 -08001638 runs onos-check-logs on the given onos node
Jon Hall80daded2015-05-27 16:07:00 -07001639 If restart is True, use the old version of onos-check-logs which
1640 does not print the full stacktrace, but shows the entire log file,
1641 including across restarts
Jon Hall94fd0472014-12-08 11:52:42 -08001642 returns the response
kelvin8ec71442015-01-15 16:57:00 -08001643 """
Jon Hall94fd0472014-12-08 11:52:42 -08001644 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001645 cmd = "onos-check-logs " + str( onosIp )
Jon Hall16b72c42015-05-20 10:23:36 -07001646 if restart:
1647 cmd += " old"
kelvin8ec71442015-01-15 16:57:00 -08001648 self.handle.sendline( cmd )
1649 self.handle.expect( cmd )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001650 self.handle.expect( "\$ " )
Jon Hall94fd0472014-12-08 11:52:42 -08001651 response = self.handle.before
1652 return response
1653 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001654 main.log.error( "Lost ssh connection" )
1655 main.log.error( self.name + ": EOF exception found" )
1656 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001657 except Exception:
1658 main.log.exception( self.name + ": Uncaught exception!" )
1659 main.cleanup()
1660 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -08001661
kelvin-onlabd3b64892015-01-20 13:26:24 -08001662 def onosStatus( self, node="" ):
kelvin8ec71442015-01-15 16:57:00 -08001663 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001664 Calls onos command: 'onos-service [<node-ip>] status'
kelvin8ec71442015-01-15 16:57:00 -08001665 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001666 try:
kelvin8ec71442015-01-15 16:57:00 -08001667 self.handle.sendline( "" )
1668 self.handle.expect( "\$" )
1669 self.handle.sendline( "onos-service " + str( node ) +
1670 " status" )
1671 i = self.handle.expect( [
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001672 "start/running",
1673 "stop/waiting",
kelvin8ec71442015-01-15 16:57:00 -08001674 pexpect.TIMEOUT ], timeout=120 )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001675
1676 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001677 main.log.info( "ONOS is running" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001678 return main.TRUE
1679 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001680 main.log.info( "ONOS is stopped" )
kelvin8ec71442015-01-15 16:57:00 -08001681 main.log.error( "ONOS service failed to check the status" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001682 main.cleanup()
1683 main.exit()
1684 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001685 main.log.error( self.name + ": EOF exception found" )
1686 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001687 main.cleanup()
1688 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001689 except Exception:
1690 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001691 main.cleanup()
1692 main.exit()
Jon Hall21270ac2015-02-16 17:59:55 -08001693
Jon Hall63604932015-02-26 17:09:50 -08001694 def setIpTables( self, ip, port='', action='add', packet_type='',
1695 direction='INPUT', rule='DROP', states=True ):
Jon Hallefbd9792015-03-05 16:11:36 -08001696 """
Jon Hall21270ac2015-02-16 17:59:55 -08001697 Description:
1698 add or remove iptables rule to DROP (default) packets from
1699 specific IP and PORT
1700 Usage:
1701 * specify action ('add' or 'remove')
1702 when removing, pass in the same argument as you would add. It will
1703 delete that specific rule.
1704 * specify the ip to block
1705 * specify the destination port to block (defaults to all ports)
1706 * optional packet type to block (default tcp)
1707 * optional iptables rule (default DROP)
1708 * optional direction to block (default 'INPUT')
Jon Hall63604932015-02-26 17:09:50 -08001709 * States boolean toggles adding all supported tcp states to the
1710 firewall rule
Jon Hall21270ac2015-02-16 17:59:55 -08001711 Returns:
1712 main.TRUE on success or
1713 main.FALSE if given invalid input or
1714 main.ERROR if there is an error in response from iptables
1715 WARNING:
1716 * This function uses root privilege iptables command which may result
1717 in unwanted network errors. USE WITH CAUTION
Jon Hallefbd9792015-03-05 16:11:36 -08001718 """
Jon Hall21270ac2015-02-16 17:59:55 -08001719
1720 # NOTE*********
1721 # The strict checking methods of this driver function is intentional
1722 # to discourage any misuse or error of iptables, which can cause
1723 # severe network errors
1724 # *************
1725
1726 # NOTE: Sleep needed to give some time for rule to be added and
1727 # registered to the instance. If you are calling this function
1728 # multiple times this sleep will prevent any errors.
1729 # DO NOT REMOVE
Jon Hall63604932015-02-26 17:09:50 -08001730 # time.sleep( 5 )
Jon Hall21270ac2015-02-16 17:59:55 -08001731 try:
1732 # input validation
1733 action_type = action.lower()
1734 rule = rule.upper()
1735 direction = direction.upper()
1736 if action_type != 'add' and action_type != 'remove':
1737 main.log.error( "Invalid action type. Use 'add' or "
1738 "'remove' table rule" )
1739 if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
1740 # NOTE Currently only supports rules DROP, ACCEPT, and LOG
1741 main.log.error( "Invalid rule. Valid rules are 'DROP' or "
1742 "'ACCEPT' or 'LOG' only." )
1743 if direction != 'INPUT' and direction != 'OUTPUT':
1744 # NOTE currently only supports rules INPUT and OUPTUT
1745 main.log.error( "Invalid rule. Valid directions are"
1746 " 'OUTPUT' or 'INPUT'" )
1747 return main.FALSE
1748 return main.FALSE
1749 return main.FALSE
1750 if action_type == 'add':
1751 # -A is the 'append' action of iptables
1752 actionFlag = '-A'
1753 elif action_type == 'remove':
1754 # -D is the 'delete' rule of iptables
1755 actionFlag = '-D'
1756 self.handle.sendline( "" )
1757 self.handle.expect( "\$" )
1758 cmd = "sudo iptables " + actionFlag + " " +\
1759 direction +\
Jon Hall21270ac2015-02-16 17:59:55 -08001760 " -s " + str( ip )
Jon Hall63604932015-02-26 17:09:50 -08001761 # " -p " + str( packet_type ) +\
1762 if packet_type:
1763 cmd += " -p " + str( packet_type )
Jon Hall21270ac2015-02-16 17:59:55 -08001764 if port:
1765 cmd += " --dport " + str( port )
Jon Hall63604932015-02-26 17:09:50 -08001766 if states:
1767 cmd += " -m state --state="
1768 #FIXME- Allow user to configure which states to block
1769 cmd += "INVALID,ESTABLISHED,NEW,RELATED,UNTRACKED"
Jon Hall21270ac2015-02-16 17:59:55 -08001770 cmd += " -j " + str( rule )
1771
1772 self.handle.sendline( cmd )
1773 self.handle.expect( "\$" )
1774 main.log.warn( self.handle.before )
1775
1776 info_string = "On " + str( self.name )
1777 info_string += " " + str( action_type )
1778 info_string += " iptable rule [ "
1779 info_string += " IP: " + str( ip )
1780 info_string += " Port: " + str( port )
1781 info_string += " Rule: " + str( rule )
1782 info_string += " Direction: " + str( direction ) + " ]"
1783 main.log.info( info_string )
1784 return main.TRUE
1785 except pexpect.TIMEOUT:
1786 main.log.exception( self.name + ": Timeout exception in "
1787 "setIpTables function" )
1788 return main.ERROR
1789 except pexpect.EOF:
1790 main.log.error( self.name + ": EOF exception found" )
1791 main.log.error( self.name + ": " + self.handle.before )
1792 main.cleanup()
1793 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001794 except Exception:
1795 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall21270ac2015-02-16 17:59:55 -08001796 main.cleanup()
1797 main.exit()
1798
Jon Hall0468b042015-02-19 19:08:21 -08001799 def detailed_status(self, log_filename):
Jon Hallefbd9792015-03-05 16:11:36 -08001800 """
Jon Hall0468b042015-02-19 19:08:21 -08001801 This method is used by STS to check the status of the controller
1802 Reports RUNNING, STARTING, STOPPED, FROZEN, ERROR (and reason)
Jon Hallefbd9792015-03-05 16:11:36 -08001803 """
Jon Hall0468b042015-02-19 19:08:21 -08001804 import re
1805 try:
1806 self.handle.sendline( "" )
1807 self.handle.expect( "\$" )
1808 self.handle.sendline( "cd " + self.home )
1809 self.handle.expect( "\$" )
1810 self.handle.sendline( "service onos status" )
1811 self.handle.expect( "\$" )
1812 response = self.handle.before
1813 if re.search( "onos start/running", response ):
1814 # onos start/running, process 10457
1815 return 'RUNNING'
1816 # FIXME: Implement this case
1817 # elif re.search( pattern, response ):
1818 # return 'STARTING'
1819 elif re.search( "onos stop/", response ):
1820 # onos stop/waiting
1821 # FIXME handle this differently?: onos stop/pre-stop
1822 return 'STOPPED'
1823 # FIXME: Implement this case
1824 # elif re.search( pattern, response ):
1825 # return 'FROZEN'
1826 else:
1827 main.log.warn( self.name +
Jon Hallefbd9792015-03-05 16:11:36 -08001828 " WARNING: status received unknown response" )
Jon Hall0468b042015-02-19 19:08:21 -08001829 main.log.warn( response )
1830 return 'ERROR', "Unknown response: %s" % response
1831 except pexpect.TIMEOUT:
1832 main.log.exception( self.name + ": Timeout exception in "
1833 "setIpTables function" )
1834 return 'ERROR', "Pexpect Timeout"
1835 except pexpect.EOF:
1836 main.log.error( self.name + ": EOF exception found" )
1837 main.log.error( self.name + ": " + self.handle.before )
1838 main.cleanup()
1839 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001840 except Exception:
1841 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall0468b042015-02-19 19:08:21 -08001842 main.cleanup()
1843 main.exit()
1844
andrew@onlab.us3b087132015-03-11 15:00:08 -07001845 def createLinkGraphFile( self, benchIp, ONOSIpList, deviceCount):
1846 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07001847 Create/formats the LinkGraph.cfg file based on arguments
1848 -only creates a linear topology and connects islands
1849 -evenly distributes devices
andrew@onlab.us3b087132015-03-11 15:00:08 -07001850 -must be called by ONOSbench
1851
Jon Hall4ba53f02015-07-29 13:07:41 -07001852 ONOSIpList - list of all of the node IPs to be used
1853
1854 deviceCount - number of switches to be assigned
andrew@onlab.us3b087132015-03-11 15:00:08 -07001855 '''
1856 main.log.step("Creating link graph configuration file." )
1857 linkGraphPath = self.home + "/tools/package/etc/linkGraph.cfg"
Jon Hall4ba53f02015-07-29 13:07:41 -07001858 tempFile = "/tmp/linkGraph.cfg"
andrew@onlab.us3b087132015-03-11 15:00:08 -07001859
1860 linkGraph = open(tempFile, 'w+')
1861 linkGraph.write("# NullLinkProvider topology description (config file).\n")
1862 linkGraph.write("# The NodeId is only added if the destination is another node's device.\n")
1863 linkGraph.write("# Bugs: Comments cannot be appended to a line to be read.\n")
Jon Hall4ba53f02015-07-29 13:07:41 -07001864
andrew@onlab.us3b087132015-03-11 15:00:08 -07001865 clusterCount = len(ONOSIpList)
Jon Hall4ba53f02015-07-29 13:07:41 -07001866
1867 if type(deviceCount) is int or type(deviceCount) is str:
andrew@onlab.us3b087132015-03-11 15:00:08 -07001868 deviceCount = int(deviceCount)
1869 switchList = [0]*(clusterCount+1)
1870 baselineSwitchCount = deviceCount/clusterCount
Jon Hall4ba53f02015-07-29 13:07:41 -07001871
andrew@onlab.us3b087132015-03-11 15:00:08 -07001872 for node in range(1, clusterCount + 1):
1873 switchList[node] = baselineSwitchCount
1874
1875 for node in range(1, (deviceCount%clusterCount)+1):
1876 switchList[node] += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07001877
andrew@onlab.us3b087132015-03-11 15:00:08 -07001878 if type(deviceCount) is list:
1879 main.log.info("Using provided device distribution")
1880 switchList = [0]
1881 for i in deviceCount:
1882 switchList.append(int(i))
1883
1884 tempList = ['0']
1885 tempList.extend(ONOSIpList)
1886 ONOSIpList = tempList
1887
1888 myPort = 6
1889 lastSwitch = 0
1890 for node in range(1, clusterCount+1):
1891 if switchList[node] == 0:
1892 continue
1893
1894 linkGraph.write("graph " + ONOSIpList[node] + " {\n")
Jon Hall4ba53f02015-07-29 13:07:41 -07001895
andrew@onlab.us3b087132015-03-11 15:00:08 -07001896 if node > 1:
1897 #connect to last device on previous node
Jon Hall4ba53f02015-07-29 13:07:41 -07001898 line = ("\t0:5 -> " + str(lastSwitch) + ":6:" + lastIp + "\n") #ONOSIpList[node-1]
1899 linkGraph.write(line)
1900
1901 lastSwitch = 0
1902 for switch in range (0, switchList[node]-1):
andrew@onlab.us3b087132015-03-11 15:00:08 -07001903 line = ""
1904 line = ("\t" + str(switch) + ":" + str(myPort))
1905 line += " -- "
1906 line += (str(switch+1) + ":" + str(myPort-1) + "\n")
1907 linkGraph.write(line)
Jon Hall4ba53f02015-07-29 13:07:41 -07001908 lastSwitch = switch+1
andrew@onlab.us3b087132015-03-11 15:00:08 -07001909 lastIp = ONOSIpList[node]
Jon Hall4ba53f02015-07-29 13:07:41 -07001910
andrew@onlab.us3b087132015-03-11 15:00:08 -07001911 #lastSwitch += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07001912 if node < (clusterCount):
andrew@onlab.us3b087132015-03-11 15:00:08 -07001913 #connect to first device on the next node
Jon Hall4ba53f02015-07-29 13:07:41 -07001914 line = ("\t" + str(lastSwitch) + ":6 -> 0:5:" + ONOSIpList[node+1] + "\n")
andrew@onlab.us3b087132015-03-11 15:00:08 -07001915 linkGraph.write(line)
Jon Hall4ba53f02015-07-29 13:07:41 -07001916
andrew@onlab.us3b087132015-03-11 15:00:08 -07001917 linkGraph.write("}\n")
1918 linkGraph.close()
1919
1920 #SCP
Jon Hall4ba53f02015-07-29 13:07:41 -07001921 os.system( "scp " + tempFile + " " + self.user_name + "@" + benchIp + ":" + linkGraphPath)
andrew@onlab.us3b087132015-03-11 15:00:08 -07001922 main.log.info("linkGraph.cfg creation complete")
1923
cameron@onlab.us75900962015-03-30 13:22:49 -07001924 def configNullDev( self, ONOSIpList, deviceCount, numPorts=10):
Jon Hall4ba53f02015-07-29 13:07:41 -07001925
andrew@onlab.us3b087132015-03-11 15:00:08 -07001926 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07001927 ONOSIpList = list of Ip addresses of nodes switches will be devided amongst
1928 deviceCount = number of switches to distribute, or list of values to use as custom distribution
cameron@onlab.us75900962015-03-30 13:22:49 -07001929 numPorts = number of ports per device. Defaults to 10 both in this function and in ONOS. Optional arg
andrew@onlab.us3b087132015-03-11 15:00:08 -07001930 '''
1931
cameron@onlab.us75900962015-03-30 13:22:49 -07001932 main.log.step("Configuring Null Device Provider" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07001933 clusterCount = len(ONOSIpList)
1934
Jon Hall4ba53f02015-07-29 13:07:41 -07001935 try:
1936
cameron@onlab.us75900962015-03-30 13:22:49 -07001937 if type(deviceCount) is int or type(deviceCount) is str:
1938 main.log.step("Creating device distribution")
1939 deviceCount = int(deviceCount)
1940 switchList = [0]*(clusterCount+1)
1941 baselineSwitchCount = deviceCount/clusterCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001942
cameron@onlab.us75900962015-03-30 13:22:49 -07001943 for node in range(1, clusterCount + 1):
1944 switchList[node] = baselineSwitchCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001945
cameron@onlab.us75900962015-03-30 13:22:49 -07001946 for node in range(1, (deviceCount%clusterCount)+1):
1947 switchList[node] += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07001948
1949 if type(deviceCount) is list:
1950 main.log.info("Using provided device distribution")
1951
1952 if len(deviceCount) == clusterCount:
cameron@onlab.us75900962015-03-30 13:22:49 -07001953 switchList = ['0']
1954 switchList.extend(deviceCount)
Jon Hall4ba53f02015-07-29 13:07:41 -07001955
1956 if len(deviceCount) == (clusterCount + 1):
1957 if deviceCount[0] == '0' or deviceCount[0] == 0:
cameron@onlab.us75900962015-03-30 13:22:49 -07001958 switchList = deviceCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001959
cameron@onlab.us75900962015-03-30 13:22:49 -07001960 assert len(switchList) == (clusterCount + 1)
Jon Hall4ba53f02015-07-29 13:07:41 -07001961
cameron@onlab.us75900962015-03-30 13:22:49 -07001962 except AssertionError:
Jon Hall4ba53f02015-07-29 13:07:41 -07001963 main.log.error( "Bad device/Ip list match")
cameron@onlab.us75900962015-03-30 13:22:49 -07001964 except TypeError:
1965 main.log.exception( self.name + ": Object not as expected" )
1966 return None
Jon Hall77ba41c2015-04-06 10:25:40 -07001967 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07001968 main.log.exception( self.name + ": Uncaught exception!" )
1969 main.cleanup()
1970 main.exit()
1971
andrew@onlab.us3b087132015-03-11 15:00:08 -07001972
1973 ONOSIp = [0]
1974 ONOSIp.extend(ONOSIpList)
Jon Hall4ba53f02015-07-29 13:07:41 -07001975
andrew@onlab.us3b087132015-03-11 15:00:08 -07001976 devicesString = "devConfigs = "
1977 for node in range(1, len(ONOSIp)):
1978 devicesString += (ONOSIp[node] + ":" + str(switchList[node] ))
1979 if node < clusterCount:
1980 devicesString += (",")
Jon Hall4ba53f02015-07-29 13:07:41 -07001981
1982 try:
cameron@onlab.us75900962015-03-30 13:22:49 -07001983 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider devConfigs " + devicesString )
1984 self.handle.expect(":~")
1985 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider numPorts " + str(numPorts) )
1986 self.handle.expect(":~")
andrew@onlab.us3b087132015-03-11 15:00:08 -07001987
cameron@onlab.us75900962015-03-30 13:22:49 -07001988 for i in range(10):
1989 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.device.impl.NullDeviceProvider")
1990 self.handle.expect(":~")
1991 verification = self.handle.before
1992 if (" value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification:
1993 break
1994 else:
1995 time.sleep(1)
andrew@onlab.us3b087132015-03-11 15:00:08 -07001996
cameron@onlab.us2cc8bf12015-04-02 14:12:30 -07001997 assert ("value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification
Jon Hall4ba53f02015-07-29 13:07:41 -07001998
cameron@onlab.us75900962015-03-30 13:22:49 -07001999 except AssertionError:
2000 main.log.error("Incorrect Config settings: " + verification)
Jon Hall77ba41c2015-04-06 10:25:40 -07002001 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002002 main.log.exception( self.name + ": Uncaught exception!" )
2003 main.cleanup()
2004 main.exit()
2005
Jon Hall4ba53f02015-07-29 13:07:41 -07002006 def configNullLink( self,fileName="/opt/onos/apache-karaf-3.0.3/etc/linkGraph.cfg", eventRate=0):
andrew@onlab.us3b087132015-03-11 15:00:08 -07002007 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07002008 fileName default is currently the same as the default on ONOS, specify alternate file if
cameron@onlab.us75900962015-03-30 13:22:49 -07002009 you want to use a different topology file than linkGraph.cfg
andrew@onlab.us3b087132015-03-11 15:00:08 -07002010 '''
2011
Jon Hall4ba53f02015-07-29 13:07:41 -07002012
2013 try:
2014 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider eventRate " + str(eventRate))
2015 self.handle.expect(":~")
cameron@onlab.us75900962015-03-30 13:22:49 -07002016 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider cfgFile " + fileName )
2017 self.handle.expect(":~")
Jon Hall4ba53f02015-07-29 13:07:41 -07002018
2019 for i in range(10):
2020 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.link.impl.NullLinkProvider")
cameron@onlab.us75900962015-03-30 13:22:49 -07002021 self.handle.expect(":~")
2022 verification = self.handle.before
Jon Hall4ba53f02015-07-29 13:07:41 -07002023 if (" value=" + str(eventRate)) in verification and (" value=" + fileName) in verification:
cameron@onlab.us75900962015-03-30 13:22:49 -07002024 break
Jon Hall4ba53f02015-07-29 13:07:41 -07002025 else:
cameron@onlab.us75900962015-03-30 13:22:49 -07002026 time.sleep(1)
Jon Hall4ba53f02015-07-29 13:07:41 -07002027
cameron@onlab.us75900962015-03-30 13:22:49 -07002028 assert ("value=" + str(eventRate)) in verification and (" value=" + fileName) in verification
Jon Hall4ba53f02015-07-29 13:07:41 -07002029
cameron@onlab.us75900962015-03-30 13:22:49 -07002030 except pexpect.EOF:
2031 main.log.error( self.name + ": EOF exception found" )
2032 main.log.error( self.name + ": " + self.handle.before )
2033 main.cleanup()
2034 main.exit()
cameron@onlab.us75900962015-03-30 13:22:49 -07002035 except AssertionError:
2036 main.log.info("Settings did not post to ONOS")
Jon Hall4ba53f02015-07-29 13:07:41 -07002037 main.log.error(varification)
Jon Hall77ba41c2015-04-06 10:25:40 -07002038 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002039 main.log.exception( self.name + ": Uncaught exception!" )
2040 main.log.error(varification)
2041 main.cleanup()
2042 main.exit()
andrew@onlab.us3b087132015-03-11 15:00:08 -07002043
kelvin-onlaba4074292015-07-09 15:19:49 -07002044 def getOnosIps( self ):
2045 """
2046 Get all onos IPs stored in
2047 """
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002048
kelvin-onlaba4074292015-07-09 15:19:49 -07002049 return sorted( self.onosIps.values() )
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002050
kelvin-onlaba4074292015-07-09 15:19:49 -07002051 def logReport( self, nodeIp, searchTerms, outputMode="s" ):
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002052 '''
2053 - accepts either a list or a string for "searchTerms" these
Jon Hall4ba53f02015-07-29 13:07:41 -07002054 terms will be searched for in the log and have their
2055 instances counted
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002056
Jon Hall4ba53f02015-07-29 13:07:41 -07002057 - nodeIp is the ip of the node whos log is to be scanned
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002058
Jon Hall4ba53f02015-07-29 13:07:41 -07002059 - output modes:
2060 "s" - Simple. Quiet output mode that just prints
2061 the occurences of each search term
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002062
cameron@onlab.us2e166212015-05-19 14:28:25 -07002063 "d" - Detailed. Prints number of occurences as well as the entire
Jon Hall4ba53f02015-07-29 13:07:41 -07002064 line for each of the last 5 occurences
cameron@onlab.us2e166212015-05-19 14:28:25 -07002065
2066 - returns total of the number of instances of all search terms
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002067 '''
2068 main.log.info("========================== Log Report ===========================\n")
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002069
Jon Hall4ba53f02015-07-29 13:07:41 -07002070 if type(searchTerms) is str:
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002071 searchTerms = [searchTerms]
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002072
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002073 logLines = [ [" "] for i in range(len(searchTerms)) ]
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002074
Jon Hall4ba53f02015-07-29 13:07:41 -07002075 for term in range(len(searchTerms)):
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002076 logLines[term][0] = searchTerms[term]
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002077
Jon Hall4ba53f02015-07-29 13:07:41 -07002078 totalHits = 0
2079 for term in range(len(searchTerms)):
2080 cmd = "onos-ssh " + nodeIp + " cat /opt/onos/log/karaf.log | grep " + searchTerms[term]
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002081 self.handle.sendline(cmd)
2082 self.handle.expect(":~")
2083 before = (self.handle.before).splitlines()
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002084
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002085 count = [searchTerms[term],0]
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002086
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002087 for line in before:
2088 if searchTerms[term] in line and "grep" not in line:
Jon Hall4ba53f02015-07-29 13:07:41 -07002089 count[1] += 1
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002090 if before.index(line) > ( len(before) - 7 ):
2091 logLines[term].append(line)
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002092
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002093 main.log.info( str(count[0]) + ": " + str(count[1]) )
Jon Hall4ba53f02015-07-29 13:07:41 -07002094 if term == len(searchTerms)-1:
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002095 print("\n")
Jon Hall4ba53f02015-07-29 13:07:41 -07002096 totalHits += int(count[1])
cameron@onlab.us2e166212015-05-19 14:28:25 -07002097
Jon Hall4ba53f02015-07-29 13:07:41 -07002098 if outputMode != "s" and outputMode != "S":
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002099 outputString = ""
2100 for i in logLines:
Jon Hall4ba53f02015-07-29 13:07:41 -07002101 outputString = i[0] + ": \n"
2102 for x in range(1,len(i)):
2103 outputString += ( i[x] + "\n" )
2104
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002105 if outputString != (i[0] + ": \n"):
Jon Hall4ba53f02015-07-29 13:07:41 -07002106 main.log.info(outputString)
2107
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002108 main.log.info("================================================================\n")
Hari Krishnabe4b97b2015-07-15 12:19:43 -07002109 return totalHits
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002110
2111 def copyMininetFile( self, fileName, localPath, userName, ip,
2112 mnPath='~/mininet/custom/', timeout = 60 ):
2113 """
2114 Description:
2115 Copy mininet topology file from dependency folder in the test folder
2116 and paste it to the mininet machine's mininet/custom folder
2117 Required:
2118 fileName - Name of the topology file to copy
2119 localPath - File path of the mininet topology file
2120 userName - User name of the mininet machine to send the file to
2121 ip - Ip address of the mininet machine
2122 Optional:
2123 mnPath - of the mininet directory to send the file to
2124 Return:
2125 Return main.TRUE if successfully copied the file otherwise
2126 return main.FALSE
2127 """
2128
2129 try:
2130 cmd = "scp " + localPath + fileName + " " + userName + "@" + \
2131 str( ip ) + ":" + mnPath + fileName
2132
2133 self.handle.sendline( "" )
2134 self.handle.expect( "\$" )
2135
2136 main.log.info( self.name + ": Execute: " + cmd )
2137
2138 self.handle.sendline( cmd )
2139
2140 i = self.handle.expect( [ 'No such file',
2141 "100%",
2142 pexpect.TIMEOUT ] )
2143
2144 if i == 0:
2145 main.log.error( self.name + ": File " + fileName +
2146 " does not exist!" )
2147 return main.FALSE
2148
2149 if i == 1:
2150 main.log.info( self.name + ": File " + fileName +
2151 " has been copied!" )
2152 self.handle.sendline( "" )
2153 self.handle.expect( "\$" )
2154 return main.TRUE
2155
2156 except pexpect.EOF:
2157 main.log.error( self.name + ": EOF exception found" )
2158 main.log.error( self.name + ": " + self.handle.before )
2159 main.cleanup()
2160 main.exit()
2161 except pexpect.TIMEOUT:
2162 main.log.error( self.name + ": TIMEOUT exception found" )
2163 main.log.error( self.name + ": " + self.handle.before )
2164 main.cleanup()
2165 main.exit()
cameron@onlab.us78b89652015-07-08 15:21:03 -07002166
2167 def jvmSet(self, memory=8):
Jon Hall4ba53f02015-07-29 13:07:41 -07002168
cameron@onlab.us78b89652015-07-08 15:21:03 -07002169 import os
2170
2171 homeDir = os.path.expanduser('~')
2172 filename = "/onos/tools/package/bin/onos-service"
2173
2174 serviceConfig = open(homeDir + filename, 'w+')
2175 serviceConfig.write("#!/bin/bash\n ")
2176 serviceConfig.write("#------------------------------------- \n ")
2177 serviceConfig.write("# Starts ONOS Apache Karaf container\n ")
2178 serviceConfig.write("#------------------------------------- \n ")
2179 serviceConfig.write("#export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-7-openjdk-amd64/}\n ")
2180 serviceConfig.write("""export JAVA_OPTS="${JAVA_OPTS:--Xms""" + str(memory) + "G -Xmx" + str(memory) + """G}" \n """)
2181 serviceConfig.write("[ -d $ONOS_HOME ] && cd $ONOS_HOME || ONOS_HOME=$(dirname $0)/..\n")
2182 serviceConfig.write("""${ONOS_HOME}/apache-karaf-$KARAF_VERSION/bin/karaf "$@" \n """)
2183 serviceConfig.close()
2184
2185 def createDBFile(self, testData):
Jon Hall4ba53f02015-07-29 13:07:41 -07002186
cameron@onlab.us78b89652015-07-08 15:21:03 -07002187 filename = main.TEST + "DB"
2188 DBString = ""
Jon Hall4ba53f02015-07-29 13:07:41 -07002189
cameron@onlab.us78b89652015-07-08 15:21:03 -07002190 for item in testData:
Jon Hall4ba53f02015-07-29 13:07:41 -07002191 if type(item) is string:
cameron@onlab.us78b89652015-07-08 15:21:03 -07002192 item = "'" + item + "'"
2193 if testData.index(item) < len(testData-1):
2194 item += ","
Jon Hall4ba53f02015-07-29 13:07:41 -07002195 DBString += str(item)
cameron@onlab.us78b89652015-07-08 15:21:03 -07002196
2197 DBFile = open(filename, "a")
2198 DBFile.write(DBString)
2199 DBFile.close()
2200
Jon Hall4ba53f02015-07-29 13:07:41 -07002201 def verifySummary(self, ONOSIp,*deviceCount):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002202
2203 self.handle.sendline("onos " + ONOSIp + " summary")
2204 self.handle.expect(":~")
2205
2206 summaryStr = self.handle.before
2207 print "\nSummary\n==============\n" + summaryStr + "\n\n"
2208
2209 #passed = "SCC(s)=1" in summaryStr
2210 #if deviceCount:
2211 # passed = "devices=" + str(deviceCount) + "," not in summaryStr
2212
GlennRC772363b2015-08-25 13:05:57 -07002213 passed = False
cameron@onlab.us78b89652015-07-08 15:21:03 -07002214 if "SCC(s)=1," in summaryStr:
2215 passed = True
2216 print("Summary is verifed")
Jon Hall4ba53f02015-07-29 13:07:41 -07002217 else:
2218 print("Summary failed")
cameron@onlab.us78b89652015-07-08 15:21:03 -07002219
2220 if deviceCount:
2221 print" ============================="
2222 checkStr = "devices=" + str(deviceCount[0]) + ","
2223 print "Checkstr: " + checkStr
2224 if checkStr not in summaryStr:
2225 passed = False
Jon Hall4ba53f02015-07-29 13:07:41 -07002226 print("Device count failed")
2227 else:
2228 print "device count verified"
cameron@onlab.us78b89652015-07-08 15:21:03 -07002229
2230 return passed