blob: 3cb984319a79e48ea5ef4d710e624b38e0ddb656 [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 Hallc6793552016-01-19 14:18:37 -0800195 i = self.handle.expect( [ "Downloading",
196 "tar.gz",
197 "\$",
198 "Unknown options" ],
199 opTimeout )
Jon Hall64af8502015-12-15 10:09:33 -0800200 handle = str( self.handle.before + self.handle.after )
201 if i == 0:
Jon Hallc6793552016-01-19 14:18:37 -0800202 # Give more time to download the file
203 self.handle.expect( "\$", opTimeout * 2 )
Jon Hall64af8502015-12-15 10:09:33 -0800204 handle += str( self.handle.before )
205 elif i == 1:
Jon Hallc6793552016-01-19 14:18:37 -0800206 self.handle.expect( "\$" )
207 handle += str( self.handle.before )
208 elif i == 2:
Jon Hall64af8502015-12-15 10:09:33 -0800209 # This seems to be harmless, but may be a problem
210 main.log.warn( "onos-package output not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -0800211 elif i == 3:
Jon Hall64af8502015-12-15 10:09:33 -0800212 # Incorrect usage
213 main.log.error( "onos-package does not recognize the given options" )
214 self.handle.expect( "\$" )
215 handle += str( self.handle.before )
216 ret = main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -0800217 main.log.info( "onos-package command returned: " + handle )
kelvin8ec71442015-01-15 16:57:00 -0800218 # As long as the sendline does not time out,
219 # return true. However, be careful to interpret
220 # the results of the onos-package command return
Jon Hall64af8502015-12-15 10:09:33 -0800221 return ret
222 except pexpect.TIMEOUT:
223 main.log.exception( self.name + ": TIMEOUT exception found in onosPackage" )
224 main.log.error( self.name + ": " + self.handle.before )
225 return main.FALSE
andrewonlab7735d852014-10-09 13:02:47 -0400226 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800227 main.log.error( self.name + ": EOF exception found" )
228 main.log.error( self.name + ": " + self.handle.before )
Jon Hall64af8502015-12-15 10:09:33 -0800229 main.cleanup()
230 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800231 except Exception:
232 main.log.exception( "Failed to package ONOS" )
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400233 main.cleanup()
234 main.exit()
235
kelvin-onlabd3b64892015-01-20 13:26:24 -0800236 def onosBuild( self ):
kelvin8ec71442015-01-15 16:57:00 -0800237 """
andrewonlab8790abb2014-11-06 13:51:54 -0500238 Use the pre defined script to build onos via mvn
kelvin8ec71442015-01-15 16:57:00 -0800239 """
andrewonlab8790abb2014-11-06 13:51:54 -0500240 try:
kelvin8ec71442015-01-15 16:57:00 -0800241 self.handle.sendline( "onos-build" )
242 self.handle.expect( "onos-build" )
243 i = self.handle.expect( [
kelvin-onlabd3b64892015-01-20 13:26:24 -0800244 "BUILD SUCCESS",
245 "ERROR",
246 "BUILD FAILED" ],
247 timeout=120 )
kelvin8ec71442015-01-15 16:57:00 -0800248 handle = str( self.handle.before )
Jon Hall3b489db2015-10-05 14:38:37 -0700249 self.handle.expect( "\$" )
andrewonlab8790abb2014-11-06 13:51:54 -0500250
kelvin8ec71442015-01-15 16:57:00 -0800251 main.log.info( "onos-build command returned: " +
252 handle )
andrewonlab8790abb2014-11-06 13:51:54 -0500253
254 if i == 0:
255 return main.TRUE
256 else:
257 return handle
258
259 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800260 main.log.error( self.name + ": EOF exception found" )
261 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -0800262 except Exception:
263 main.log.exception( "Failed to build ONOS" )
andrewonlab8790abb2014-11-06 13:51:54 -0500264 main.cleanup()
265 main.exit()
266
shahshreya9f531fe2015-06-10 12:03:51 -0700267 def cleanInstall( self, skipTest=False, mciTimeout=600 ):
kelvin8ec71442015-01-15 16:57:00 -0800268 """
269 Runs mvn clean install in the root of the ONOS directory.
270 This will clean all ONOS artifacts then compile each module
shahshreya9f531fe2015-06-10 12:03:51 -0700271 Optional:
272 skipTest - Does "-DskipTests -Dcheckstyle.skip -U -T 1C" which
273 skip the test. This will make the building faster.
274 Disregarding the credibility of the build
kelvin8ec71442015-01-15 16:57:00 -0800275 Returns: main.TRUE on success
Jon Hallde9d9aa2014-10-08 20:36:02 -0400276 On Failure, exits the test
kelvin8ec71442015-01-15 16:57:00 -0800277 """
Jon Hallde9d9aa2014-10-08 20:36:02 -0400278 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800279 main.log.info( "Running 'mvn clean install' on " +
280 str( self.name ) +
kelvin8ec71442015-01-15 16:57:00 -0800281 ". This may take some time." )
282 self.handle.sendline( "cd " + self.home )
283 self.handle.expect( "\$" )
Jon Hallea7818b2014-10-09 14:30:59 -0400284
kelvin8ec71442015-01-15 16:57:00 -0800285 self.handle.sendline( "" )
286 self.handle.expect( "\$" )
shahshreya9f531fe2015-06-10 12:03:51 -0700287
288 if not skipTest:
289 self.handle.sendline( "mvn clean install" )
290 self.handle.expect( "mvn clean install" )
291 else:
292 self.handle.sendline( "mvn clean install -DskipTests" +
293 " -Dcheckstyle.skip -U -T 1C" )
294 self.handle.expect( "mvn clean install -DskipTests" +
295 " -Dcheckstyle.skip -U -T 1C" )
kelvin8ec71442015-01-15 16:57:00 -0800296 while True:
297 i = self.handle.expect( [
Jon Hall274b6642015-02-17 11:57:17 -0800298 'There\sis\sinsufficient\smemory\sfor\sthe\sJava\s' +
Jon Hallefbd9792015-03-05 16:11:36 -0800299 'Runtime\sEnvironment\sto\scontinue',
Jon Hallde9d9aa2014-10-08 20:36:02 -0400300 'BUILD\sFAILURE',
301 'BUILD\sSUCCESS',
Jon Halle94919c2015-03-23 11:42:57 -0700302 'onos\$', #TODO: fix this to be more generic?
Jon Hallde9d9aa2014-10-08 20:36:02 -0400303 'ONOS\$',
pingping-lin57a56ce2015-05-20 16:43:48 -0700304 pexpect.TIMEOUT ], mciTimeout )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400305 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800306 main.log.error( self.name + ":There is insufficient memory \
307 for the Java Runtime Environment to continue." )
308 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400309 main.cleanup()
310 main.exit()
311 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800312 main.log.error( self.name + ": Build failure!" )
313 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400314 main.cleanup()
315 main.exit()
316 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800317 main.log.info( self.name + ": Build success!" )
Jon Halle94919c2015-03-23 11:42:57 -0700318 elif i == 3 or i == 4:
kelvin8ec71442015-01-15 16:57:00 -0800319 main.log.info( self.name + ": Build complete" )
320 # Print the build time
Jon Hallf8ef52c2014-10-09 19:37:33 -0400321 for line in self.handle.before.splitlines():
322 if "Total time:" in line:
kelvin8ec71442015-01-15 16:57:00 -0800323 main.log.info( line )
324 self.handle.sendline( "" )
325 self.handle.expect( "\$", timeout=60 )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400326 return main.TRUE
Jon Halle94919c2015-03-23 11:42:57 -0700327 elif i == 5:
kelvin8ec71442015-01-15 16:57:00 -0800328 main.log.error(
329 self.name +
330 ": mvn clean install TIMEOUT!" )
331 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400332 main.cleanup()
333 main.exit()
334 else:
Jon Hall274b6642015-02-17 11:57:17 -0800335 main.log.error( self.name + ": unexpected response from " +
Jon Hallefbd9792015-03-05 16:11:36 -0800336 "mvn clean install" )
kelvin8ec71442015-01-15 16:57:00 -0800337 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400338 main.cleanup()
339 main.exit()
340 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800341 main.log.error( self.name + ": EOF exception found" )
342 main.log.error( self.name + ": " + self.handle.before )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400343 main.cleanup()
344 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800345 except Exception:
346 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400347 main.cleanup()
348 main.exit()
Jon Hallacabffd2014-10-09 12:36:53 -0400349
Jon Hall61282e32015-03-19 11:34:11 -0700350 def gitPull( self, comp1="", fastForward=True ):
kelvin8ec71442015-01-15 16:57:00 -0800351 """
Jon Hallacabffd2014-10-09 12:36:53 -0400352 Assumes that "git pull" works without login
Jon Hall47a93fb2015-01-06 16:46:06 -0800353
Jon Hall61282e32015-03-19 11:34:11 -0700354 If the fastForward boolean is set to true, only git pulls that can
355 be fast forwarded will be performed. IE if you have not local commits
356 in your branch.
357
Jon Hallacabffd2014-10-09 12:36:53 -0400358 This function will perform a git pull on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800359 If used as gitPull( "NODE" ) it will do git pull + NODE. This is
Jon Hallacabffd2014-10-09 12:36:53 -0400360 for the purpose of pulling from other nodes if necessary.
361
Jon Hall47a93fb2015-01-06 16:46:06 -0800362 Otherwise, this function will perform a git pull in the
Jon Hallacabffd2014-10-09 12:36:53 -0400363 ONOS repository. If it has any problems, it will return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -0800364 If it successfully does a gitPull, it will return a 1 ( main.TRUE )
Shreya Shahee15f6c2014-10-28 18:12:30 -0400365 If it has no updates, it will return 3.
Jon Hallacabffd2014-10-09 12:36:53 -0400366
kelvin8ec71442015-01-15 16:57:00 -0800367 """
Jon Hallacabffd2014-10-09 12:36:53 -0400368 try:
kelvin8ec71442015-01-15 16:57:00 -0800369 self.handle.sendline( "cd " + self.home )
kelvin-onlaba1484582015-02-02 15:46:20 -0800370 self.handle.expect( self.home + "\$" )
Jon Hall61282e32015-03-19 11:34:11 -0700371 cmd = "git pull"
372 if comp1 != "":
373 cmd += ' ' + comp1
374 if fastForward:
375 cmd += ' ' + " --ff-only"
376 self.handle.sendline( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800377 i = self.handle.expect(
378 [
379 'fatal',
380 'Username\sfor\s(.*):\s',
381 '\sfile(s*) changed,\s',
382 'Already up-to-date',
383 'Aborting',
384 'You\sare\snot\scurrently\son\sa\sbranch',
Jon Hall274b6642015-02-17 11:57:17 -0800385 'You asked me to pull without telling me which branch you',
386 'Pull is not possible because you have unmerged files',
Jon Hall61282e32015-03-19 11:34:11 -0700387 'Please enter a commit message to explain why this merge',
388 'Found a swap file by the name',
389 'Please, commit your changes before you can merge.',
kelvin-onlabd3b64892015-01-20 13:26:24 -0800390 pexpect.TIMEOUT ],
391 timeout=300 )
kelvin8ec71442015-01-15 16:57:00 -0800392 if i == 0:
Jon Hall61282e32015-03-19 11:34:11 -0700393 main.log.error( self.name + ": Git pull had some issue" )
394 output = self.handle.after
395 self.handle.expect( '\$' )
396 output += self.handle.before
397 main.log.warn( output )
Jon Hallacabffd2014-10-09 12:36:53 -0400398 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800399 elif i == 1:
400 main.log.error(
401 self.name +
402 ": Git Pull Asking for username. " )
Jon Hallacabffd2014-10-09 12:36:53 -0400403 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800404 elif i == 2:
405 main.log.info(
406 self.name +
407 ": Git Pull - pulling repository now" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800408 self.handle.expect( self.home + "\$", 120 )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800409 # So that only when git pull is done, we do mvn clean compile
410 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800411 elif i == 3:
412 main.log.info( self.name + ": Git Pull - Already up to date" )
Jon Hall47a93fb2015-01-06 16:46:06 -0800413 return i
kelvin8ec71442015-01-15 16:57:00 -0800414 elif i == 4:
415 main.log.info(
416 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800417 ": Git Pull - Aborting..." +
418 "Are there conflicting git files?" )
Jon Hallacabffd2014-10-09 12:36:53 -0400419 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800420 elif i == 5:
421 main.log.info(
422 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800423 ": Git Pull - You are not currently " +
424 "on a branch so git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400425 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800426 elif i == 6:
427 main.log.info(
428 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800429 ": Git Pull - You have not configured an upstream " +
430 "branch to pull from. Git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400431 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800432 elif i == 7:
433 main.log.info(
434 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800435 ": Git Pull - Pull is not possible because " +
436 "you have unmerged files." )
Jon Hallacabffd2014-10-09 12:36:53 -0400437 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800438 elif i == 8:
Jon Hall61282e32015-03-19 11:34:11 -0700439 # NOTE: abandoning test since we can't reliably handle this
440 # there could be different default text editors and we
441 # also don't know if we actually want to make the commit
442 main.log.error( "Git pull resulted in a merge commit message" +
443 ". Exiting test!" )
444 main.cleanup()
445 main.exit()
446 elif i == 9: # Merge commit message but swap file exists
447 main.log.error( "Git pull resulted in a merge commit message" +
448 " but a swap file exists." )
449 try:
450 self.handle.send( 'A' ) # Abort
451 self.handle.expect( "\$" )
452 return main.ERROR
453 except Exception:
454 main.log.exception( "Couldn't exit editor prompt!")
455 main.cleanup()
456 main.exit()
457 elif i == 10: # In the middle of a merge commit
458 main.log.error( "Git branch is in the middle of a merge. " )
459 main.log.warn( self.handle.before + self.handle.after )
460 return main.ERROR
461 elif i == 11:
kelvin8ec71442015-01-15 16:57:00 -0800462 main.log.error( self.name + ": Git Pull - TIMEOUT" )
463 main.log.error(
464 self.name + " Response was: " + str(
465 self.handle.before ) )
Jon Hallacabffd2014-10-09 12:36:53 -0400466 return main.ERROR
467 else:
kelvin8ec71442015-01-15 16:57:00 -0800468 main.log.error(
469 self.name +
470 ": Git Pull - Unexpected response, check for pull errors" )
Jon Hallacabffd2014-10-09 12:36:53 -0400471 return main.ERROR
472 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800473 main.log.error( self.name + ": EOF exception found" )
474 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400475 main.cleanup()
476 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800477 except Exception:
478 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400479 main.cleanup()
480 main.exit()
481
kelvin-onlabd3b64892015-01-20 13:26:24 -0800482 def gitCheckout( self, branch="master" ):
kelvin8ec71442015-01-15 16:57:00 -0800483 """
Jon Hallacabffd2014-10-09 12:36:53 -0400484 Assumes that "git pull" works without login
kelvin8ec71442015-01-15 16:57:00 -0800485
Jon Hallacabffd2014-10-09 12:36:53 -0400486 This function will perform a git git checkout on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800487 If used as gitCheckout( "branch" ) it will do git checkout
488 of the "branch".
Jon Hallacabffd2014-10-09 12:36:53 -0400489
490 Otherwise, this function will perform a git checkout of the master
kelvin8ec71442015-01-15 16:57:00 -0800491 branch of the ONOS repository. If it has any problems, it will return
492 main.ERROR.
493 If the branch was already the specified branch, or the git checkout was
Jon Hallacabffd2014-10-09 12:36:53 -0400494 successful then the function will return main.TRUE.
495
kelvin8ec71442015-01-15 16:57:00 -0800496 """
Jon Hallacabffd2014-10-09 12:36:53 -0400497 try:
kelvin8ec71442015-01-15 16:57:00 -0800498 self.handle.sendline( "cd " + self.home )
kelvin-onlaba1484582015-02-02 15:46:20 -0800499 self.handle.expect( self.home + "\$" )
Jon Hall274b6642015-02-17 11:57:17 -0800500 main.log.info( self.name +
501 ": Checking out git branch/ref: " + branch + "..." )
kelvin8ec71442015-01-15 16:57:00 -0800502 cmd = "git checkout " + branch
503 self.handle.sendline( cmd )
504 self.handle.expect( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800505 i = self.handle.expect(
Jon Hall274b6642015-02-17 11:57:17 -0800506 [ 'fatal',
Jon Hall61282e32015-03-19 11:34:11 -0700507 'Username for (.*): ',
508 'Already on \'',
Jon Hall7a8354f2015-06-10 15:37:00 -0700509 'Switched to (a new )?branch \'' + str( branch ),
Jon Hall274b6642015-02-17 11:57:17 -0800510 pexpect.TIMEOUT,
511 'error: Your local changes to the following files' +
Jon Hallefbd9792015-03-05 16:11:36 -0800512 'would be overwritten by checkout:',
Jon Hall274b6642015-02-17 11:57:17 -0800513 'error: you need to resolve your current index first',
514 "You are in 'detached HEAD' state.",
515 "HEAD is now at " ],
kelvin-onlabd3b64892015-01-20 13:26:24 -0800516 timeout=60 )
kelvin8ec71442015-01-15 16:57:00 -0800517 if i == 0:
518 main.log.error(
519 self.name +
520 ": Git checkout had some issue..." )
521 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400522 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800523 elif i == 1:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800524 main.log.error(
525 self.name +
526 ": Git checkout asking for username." +
527 " Please configure your local git repository to be able " +
528 "to access your remote repository passwordlessly" )
Jon Hall274b6642015-02-17 11:57:17 -0800529 # TODO add support for authenticating
Jon Hallacabffd2014-10-09 12:36:53 -0400530 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800531 elif i == 2:
532 main.log.info(
533 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800534 ": Git Checkout %s : Already on this branch" % branch )
kelvin-onlaba1484582015-02-02 15:46:20 -0800535 self.handle.expect( self.home + "\$" )
kelvin8ec71442015-01-15 16:57:00 -0800536 # main.log.info( "DEBUG: after checkout cmd = "+
537 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400538 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800539 elif i == 3:
540 main.log.info(
541 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800542 ": Git checkout %s - Switched to this branch" % branch )
kelvin-onlaba1484582015-02-02 15:46:20 -0800543 self.handle.expect( self.home + "\$" )
kelvin8ec71442015-01-15 16:57:00 -0800544 # main.log.info( "DEBUG: after checkout cmd = "+
545 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400546 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800547 elif i == 4:
548 main.log.error( self.name + ": Git Checkout- TIMEOUT" )
549 main.log.error(
Jon Hall274b6642015-02-17 11:57:17 -0800550 self.name + " Response was: " + str( self.handle.before ) )
Jon Hallacabffd2014-10-09 12:36:53 -0400551 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800552 elif i == 5:
553 self.handle.expect( "Aborting" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800554 main.log.error(
555 self.name +
556 ": Git checkout error: \n" +
Jon Hall274b6642015-02-17 11:57:17 -0800557 "Your local changes to the following files would" +
558 " be overwritten by checkout:" +
559 str( self.handle.before ) )
kelvin-onlaba1484582015-02-02 15:46:20 -0800560 self.handle.expect( self.home + "\$" )
Jon Hall81e29af2014-11-04 20:41:23 -0500561 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800562 elif i == 6:
Jon Hall274b6642015-02-17 11:57:17 -0800563 main.log.error(
564 self.name +
565 ": Git checkout error: \n" +
566 "You need to resolve your current index first:" +
567 str( self.handle.before ) )
kelvin-onlaba1484582015-02-02 15:46:20 -0800568 self.handle.expect( self.home + "\$" )
Jon Hall81e29af2014-11-04 20:41:23 -0500569 return main.ERROR
Jon Hall274b6642015-02-17 11:57:17 -0800570 elif i == 7:
571 main.log.info(
572 self.name +
573 ": Git checkout " + str( branch ) +
574 " - You are in 'detached HEAD' state. HEAD is now at " +
575 str( branch ) )
576 self.handle.expect( self.home + "\$" )
577 return main.TRUE
578 elif i == 8: # Already in detached HEAD on the specified commit
579 main.log.info(
580 self.name +
581 ": Git Checkout %s : Already on commit" % branch )
582 self.handle.expect( self.home + "\$" )
583 return main.TRUE
Jon Hallacabffd2014-10-09 12:36:53 -0400584 else:
kelvin8ec71442015-01-15 16:57:00 -0800585 main.log.error(
586 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800587 ": Git Checkout - Unexpected response, " +
588 "check for pull errors" )
kelvin8ec71442015-01-15 16:57:00 -0800589 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400590 return main.ERROR
591
592 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800593 main.log.error( self.name + ": EOF exception found" )
594 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400595 main.cleanup()
596 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800597 except Exception:
598 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400599 main.cleanup()
600 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400601
pingping-lin6d23d9e2015-02-02 16:54:24 -0800602 def getBranchName( self ):
pingping-linf30cf272015-05-29 15:54:07 -0700603 main.log.info( "self.home = " )
604 main.log.info( self.home )
pingping-lin6d23d9e2015-02-02 16:54:24 -0800605 self.handle.sendline( "cd " + self.home )
pingping-lin9bf3d8f2015-05-29 16:05:28 -0700606 self.handle.expect( self.home + "\$" )
pingping-lin6d23d9e2015-02-02 16:54:24 -0800607 self.handle.sendline( "git name-rev --name-only HEAD" )
608 self.handle.expect( "git name-rev --name-only HEAD" )
609 self.handle.expect( "\$" )
610
611 lines = self.handle.before.splitlines()
612 if lines[1] == "master":
613 return "master"
614 elif lines[1] == "onos-1.0":
615 return "onos-1.0"
616 else:
617 main.log.info( lines[1] )
618 return "unexpected ONOS branch for SDN-IP test"
619
kelvin-onlabd3b64892015-01-20 13:26:24 -0800620 def getVersion( self, report=False ):
kelvin8ec71442015-01-15 16:57:00 -0800621 """
Jon Hall274b6642015-02-17 11:57:17 -0800622 Writes the COMMIT number to the report to be parsed
Jon Hallefbd9792015-03-05 16:11:36 -0800623 by Jenkins data collector.
kelvin8ec71442015-01-15 16:57:00 -0800624 """
Jon Hall45ec0922014-10-10 19:33:49 -0400625 try:
kelvin8ec71442015-01-15 16:57:00 -0800626 self.handle.sendline( "" )
627 self.handle.expect( "\$" )
628 self.handle.sendline(
629 "cd " +
630 self.home +
Jon Hall274b6642015-02-17 11:57:17 -0800631 "; git log -1 --pretty=fuller --decorate=short | grep -A 6 " +
632 " \"commit\" --color=never" )
kelvin8ec71442015-01-15 16:57:00 -0800633 # NOTE: for some reason there are backspaces inserted in this
634 # phrase when run from Jenkins on some tests
635 self.handle.expect( "never" )
636 self.handle.expect( "\$" )
637 response = ( self.name + ": \n" + str(
638 self.handle.before + self.handle.after ) )
639 self.handle.sendline( "cd " + self.home )
640 self.handle.expect( "\$" )
641 lines = response.splitlines()
Jon Hall45ec0922014-10-10 19:33:49 -0400642 for line in lines:
Jon Hallfd191202014-11-07 18:36:09 -0500643 print line
644 if report:
pingping-lin763ee042015-05-20 17:45:30 -0700645 main.log.wiki( "<blockquote>" )
kelvin8ec71442015-01-15 16:57:00 -0800646 for line in lines[ 2:-1 ]:
647 # Bracket replacement is for Wiki-compliant
648 # formatting. '<' or '>' are interpreted
649 # as xml specific tags that cause errors
650 line = line.replace( "<", "[" )
651 line = line.replace( ">", "]" )
pingping-lin763ee042015-05-20 17:45:30 -0700652 #main.log.wiki( "\t" + line )
653 main.log.wiki( line + "<br /> " )
654 main.log.summary( line )
655 main.log.wiki( "</blockquote>" )
656 main.log.summary("\n")
kelvin8ec71442015-01-15 16:57:00 -0800657 return lines[ 2 ]
Jon Hall45ec0922014-10-10 19:33:49 -0400658 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800659 main.log.error( self.name + ": EOF exception found" )
660 main.log.error( self.name + ": " + self.handle.before )
Jon Hall45ec0922014-10-10 19:33:49 -0400661 main.cleanup()
662 main.exit()
Jon Hall368769f2014-11-19 15:43:35 -0800663 except pexpect.TIMEOUT:
kelvin8ec71442015-01-15 16:57:00 -0800664 main.log.error( self.name + ": TIMEOUT exception found" )
665 main.log.error( self.name + ": " + self.handle.before )
Jon Hall368769f2014-11-19 15:43:35 -0800666 main.cleanup()
667 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800668 except Exception:
669 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall45ec0922014-10-10 19:33:49 -0400670 main.cleanup()
671 main.exit()
672
kelvin-onlabd3b64892015-01-20 13:26:24 -0800673 def createCellFile( self, benchIp, fileName, mnIpAddrs,
kelvin-onlaba4074292015-07-09 15:19:49 -0700674 appString, onosIpAddrs ):
kelvin8ec71442015-01-15 16:57:00 -0800675 """
andrewonlab94282092014-10-10 13:00:11 -0400676 Creates a cell file based on arguments
677 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800678 * Bench IP address ( benchIp )
andrewonlab94282092014-10-10 13:00:11 -0400679 - Needed to copy the cell file over
kelvin-onlabd3b64892015-01-20 13:26:24 -0800680 * File name of the cell file ( fileName )
681 * Mininet IP address ( mnIpAddrs )
kelvin8ec71442015-01-15 16:57:00 -0800682 - Note that only 1 ip address is
andrewonlab94282092014-10-10 13:00:11 -0400683 supported currently
kelvin-onlabd3b64892015-01-20 13:26:24 -0800684 * ONOS IP addresses ( onosIpAddrs )
andrewonlab94282092014-10-10 13:00:11 -0400685 - Must be passed in as last arguments
kelvin8ec71442015-01-15 16:57:00 -0800686
andrewonlab94282092014-10-10 13:00:11 -0400687 NOTE: Assumes cells are located at:
688 ~/<self.home>/tools/test/cells/
kelvin8ec71442015-01-15 16:57:00 -0800689 """
690 # Variable initialization
Jon Hall6801cda2015-07-15 14:13:45 -0700691 cellDirectory = self.home + "/tools/test/cells/"
kelvin8ec71442015-01-15 16:57:00 -0800692 # We want to create the cell file in the dependencies directory
693 # of TestON first, then copy over to ONOS bench
kelvin-onlabd3b64892015-01-20 13:26:24 -0800694 tempDirectory = "/tmp/"
kelvin8ec71442015-01-15 16:57:00 -0800695 # Create the cell file in the directory for writing ( w+ )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800696 cellFile = open( tempDirectory + fileName, 'w+' )
Jon Hall6801cda2015-07-15 14:13:45 -0700697 if isinstance( onosIpAddrs, types.StringType ):
698 onosIpAddrs = [ onosIpAddrs ]
kelvin8ec71442015-01-15 16:57:00 -0800699
cameron@onlab.us75900962015-03-30 13:22:49 -0700700 # App string is hardcoded environment variables
kelvin8ec71442015-01-15 16:57:00 -0800701 # That you may wish to use by default on startup.
cameron@onlab.us75900962015-03-30 13:22:49 -0700702 # Note that you may not want certain apps listed
kelvin8ec71442015-01-15 16:57:00 -0800703 # on here.
cameron@onlab.us75900962015-03-30 13:22:49 -0700704 appString = "export ONOS_APPS=" + appString
kelvin-onlabd3b64892015-01-20 13:26:24 -0800705 mnString = "export OCN="
kelvin-onlabf70fd542015-05-07 18:41:40 -0700706 if mnIpAddrs == "":
707 mnString = ""
kelvin-onlabd3b64892015-01-20 13:26:24 -0800708 onosString = "export OC"
709 tempCount = 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800710 # Create ONOSNIC ip address prefix
kelvin-onlaba4074292015-07-09 15:19:49 -0700711 tempOnosIp = str( onosIpAddrs[ 0 ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800712 tempList = []
713 tempList = tempOnosIp.split( "." )
kelvin8ec71442015-01-15 16:57:00 -0800714 # Omit last element of list to format for NIC
kelvin-onlabd3b64892015-01-20 13:26:24 -0800715 tempList = tempList[ :-1 ]
kelvin8ec71442015-01-15 16:57:00 -0800716 # Structure the nic string ip
kelvin-onlabd3b64892015-01-20 13:26:24 -0800717 nicAddr = ".".join( tempList ) + ".*"
718 onosNicString = "export ONOS_NIC=" + nicAddr
andrewonlab94282092014-10-10 13:00:11 -0400719 try:
kelvin8ec71442015-01-15 16:57:00 -0800720 # Start writing to file
kelvin-onlabd3b64892015-01-20 13:26:24 -0800721 cellFile.write( onosNicString + "\n" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800722 for arg in onosIpAddrs:
723 # For each argument in onosIpAddrs, write to file
kelvin8ec71442015-01-15 16:57:00 -0800724 # Output should look like the following:
andrewonlabd4940492014-10-24 12:21:27 -0400725 # export OC1="10.128.20.11"
726 # export OC2="10.128.20.12"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800727 cellFile.write( onosString + str( tempCount ) +
Jon Hall6f665652015-09-18 10:08:07 -0700728 "=\"" + arg + "\"\n" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800729 tempCount = tempCount + 1
Jon Hall6f665652015-09-18 10:08:07 -0700730 cellFile.write( "export OCI=$OC1\n" )
731 cellFile.write( mnString + "\"" + mnIpAddrs + "\"\n" )
cameron@onlab.us75900962015-03-30 13:22:49 -0700732 cellFile.write( appString + "\n" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800733 cellFile.close()
kelvin8ec71442015-01-15 16:57:00 -0800734 # We use os.system to send the command to TestON cluster
735 # to account for the case in which TestON is not located
736 # on the same cluster as the ONOS bench
737 # Note that even if TestON is located on the same cluster
738 # as ONOS bench, you must setup passwordless ssh
739 # between TestON and ONOS bench in order to automate the test.
kelvin-onlabc2b79102015-07-14 11:41:20 -0700740 os.system( "scp " + tempDirectory + fileName + " " +
741 self.user_name + "@" + self.ip_address + ":" + cellDirectory )
andrewonlab2a6c9342014-10-16 13:40:15 -0400742 return main.TRUE
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
Hari Krishna03f530e2015-07-10 17:28:27 -0700776 if( re.search( "No such cell", cell_result ) ):
777 main.log.error( "Cell call returned: " + handleBefore +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800778 handleAfter + handleMore )
Hari Krishna03f530e2015-07-10 17:28:27 -0700779 main.cleanup()
780 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400781 return main.TRUE
andrewonlab95ca1462014-10-09 14:04:24 -0400782 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800783 main.log.error( self.name + ": EOF exception found" )
784 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ca1462014-10-09 14:04:24 -0400785 main.cleanup()
786 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800787 except Exception:
788 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ca1462014-10-09 14:04:24 -0400789 main.cleanup()
790 main.exit()
791
kelvin-onlabd3b64892015-01-20 13:26:24 -0800792 def verifyCell( self ):
kelvin8ec71442015-01-15 16:57:00 -0800793 """
andrewonlabc03bf6c2014-10-09 14:56:18 -0400794 Calls 'onos-verify-cell' to check for cell installation
kelvin8ec71442015-01-15 16:57:00 -0800795 """
796 # TODO: Add meaningful expect value
andrewonlab8d0d7d72014-10-09 16:33:15 -0400797
andrewonlabc03bf6c2014-10-09 14:56:18 -0400798 try:
kelvin8ec71442015-01-15 16:57:00 -0800799 # Clean handle by sending empty and expecting $
800 self.handle.sendline( "" )
801 self.handle.expect( "\$" )
802 self.handle.sendline( "onos-verify-cell" )
803 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800804 handleBefore = self.handle.before
805 handleAfter = self.handle.after
andrewonlabc03bf6c2014-10-09 14:56:18 -0400806 return main.TRUE
Jon Halla5cb6172015-02-23 09:28:28 -0800807 except pexpect.ExceptionPexpect as e:
Jon Hall3b489db2015-10-05 14:38:37 -0700808 main.log.exception( self.name + ": Pexpect exception found: " )
kelvin8ec71442015-01-15 16:57:00 -0800809 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -0400810 main.cleanup()
811 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800812 except Exception:
813 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400814 main.cleanup()
815 main.exit()
816
jenkins1e99e7b2015-04-02 18:15:39 -0700817 def onosCfgSet( self, ONOSIp, configName, configParam ):
818 """
819 Uses 'onos <node-ip> cfg set' to change a parameter value of an
Jon Hall4ba53f02015-07-29 13:07:41 -0700820 application.
821
jenkins1e99e7b2015-04-02 18:15:39 -0700822 ex)
823 onos 10.0.0.1 cfg set org.onosproject.myapp appSetting 1
jenkins1e99e7b2015-04-02 18:15:39 -0700824 ONOSIp = '10.0.0.1'
825 configName = 'org.onosproject.myapp'
826 configParam = 'appSetting 1'
jenkins1e99e7b2015-04-02 18:15:39 -0700827 """
Jon Hall72280bc2016-01-25 14:29:05 -0800828 try:
829 cfgStr = "onos {} cfg set {} {}".format( ONOSIp,
830 configName,
831 configParam )
832 self.handle.sendline( "" )
833 self.handle.expect( ":~" )
834 self.handle.sendline( cfgStr )
835 self.handle.expect("cfg set")
836 self.handle.expect( ":~" )
jenkins1e99e7b2015-04-02 18:15:39 -0700837
Jon Hall72280bc2016-01-25 14:29:05 -0800838 paramValue = configParam.split(" ")[1]
839 paramName = configParam.split(" ")[0]
Jon Hall4ba53f02015-07-29 13:07:41 -0700840
Jon Hall72280bc2016-01-25 14:29:05 -0800841 checkStr = 'onos {} cfg get " {} {} " '.format( ONOSIp, configName, paramName )
Jon Hall4ba53f02015-07-29 13:07:41 -0700842
Jon Hall72280bc2016-01-25 14:29:05 -0800843 self.handle.sendline( checkStr )
844 self.handle.expect( ":~" )
jenkins1e99e7b2015-04-02 18:15:39 -0700845
Jon Hall72280bc2016-01-25 14:29:05 -0800846 if "value=" + paramValue + "," in self.handle.before:
847 main.log.info("cfg " + configName + " successfully set to " + configParam)
848 return main.TRUE
849 except pexpect.ExceptionPexpect as e:
850 main.log.exception( self.name + ": Pexpect exception found: " )
851 main.log.error( self.name + ": " + self.handle.before )
852 main.cleanup()
853 main.exit()
854 except Exception:
855 main.log.exception( self.name + ": Uncaught exception!" )
856 main.cleanup()
857 main.exit()
Jon Hall4ba53f02015-07-29 13:07:41 -0700858
kelvin-onlabd3b64892015-01-20 13:26:24 -0800859 def onosCli( self, ONOSIp, cmdstr ):
kelvin8ec71442015-01-15 16:57:00 -0800860 """
andrewonlab05e362f2014-10-10 00:40:57 -0400861 Uses 'onos' command to send various ONOS CLI arguments.
862 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800863 * ONOSIp: specify the ip of the cell machine
andrewonlab94282092014-10-10 13:00:11 -0400864 * cmdstr: specify the command string to send
kelvin8ec71442015-01-15 16:57:00 -0800865
866 This function is intended to expose the entire karaf
andrewonlab6e20c342014-10-10 18:08:48 -0400867 CLI commands for ONOS. Try to use this function first
868 before attempting to write a ONOS CLI specific driver
kelvin8ec71442015-01-15 16:57:00 -0800869 function.
870 You can see a list of available 'cmdstr' arguments
andrewonlab6e20c342014-10-10 18:08:48 -0400871 by starting onos, and typing in 'onos' to enter the
872 onos> CLI. Then, type 'help' to see the list of
kelvin8ec71442015-01-15 16:57:00 -0800873 available commands.
874 """
andrewonlab05e362f2014-10-10 00:40:57 -0400875 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800876 if not ONOSIp:
kelvin8ec71442015-01-15 16:57:00 -0800877 main.log.error( "You must specify the IP address" )
andrewonlab05e362f2014-10-10 00:40:57 -0400878 return main.FALSE
879 if not cmdstr:
kelvin8ec71442015-01-15 16:57:00 -0800880 main.log.error( "You must specify the command string" )
andrewonlab05e362f2014-10-10 00:40:57 -0400881 return main.FALSE
882
kelvin8ec71442015-01-15 16:57:00 -0800883 cmdstr = str( cmdstr )
884 self.handle.sendline( "" )
885 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400886
kelvin-onlabd3b64892015-01-20 13:26:24 -0800887 self.handle.sendline( "onos -w " + ONOSIp + " " + cmdstr )
kelvin8ec71442015-01-15 16:57:00 -0800888 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400889
kelvin-onlabd3b64892015-01-20 13:26:24 -0800890 handleBefore = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -0800891 main.log.info( "Command sent successfully" )
kelvin8ec71442015-01-15 16:57:00 -0800892 # Obtain return handle that consists of result from
893 # the onos command. The string may need to be
894 # configured further.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800895 returnString = handleBefore
kelvin-onlabd3b64892015-01-20 13:26:24 -0800896 return returnString
andrewonlab05e362f2014-10-10 00:40:57 -0400897 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800898 main.log.error( self.name + ": EOF exception found" )
899 main.log.error( self.name + ": " + self.handle.before )
andrewonlab05e362f2014-10-10 00:40:57 -0400900 main.cleanup()
901 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800902 except Exception:
903 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab05e362f2014-10-10 00:40:57 -0400904 main.cleanup()
905 main.exit()
Jon Hall7993bfc2014-10-09 16:30:14 -0400906
kelvin-onlabd3b64892015-01-20 13:26:24 -0800907 def onosInstall( self, options="-f", node="" ):
kelvin8ec71442015-01-15 16:57:00 -0800908 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400909 Installs ONOS bits on the designated cell machine.
kelvin8ec71442015-01-15 16:57:00 -0800910 If -f option is provided, it also forces an uninstall.
911 Presently, install also includes onos-push-bits and
Jon Hall7993bfc2014-10-09 16:30:14 -0400912 onos-config within.
kelvin8ec71442015-01-15 16:57:00 -0800913 The node option allows you to selectively only push the jar
Jon Hall7993bfc2014-10-09 16:30:14 -0400914 files to certain onos nodes
915
916 Returns: main.TRUE on success and main.FALSE on failure
kelvin8ec71442015-01-15 16:57:00 -0800917 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400918 try:
andrewonlab114768a2014-11-14 12:44:44 -0500919 if options:
kelvin8ec71442015-01-15 16:57:00 -0800920 self.handle.sendline( "onos-install " + options + " " + node )
andrewonlab114768a2014-11-14 12:44:44 -0500921 else:
kelvin8ec71442015-01-15 16:57:00 -0800922 self.handle.sendline( "onos-install " + node )
923 self.handle.expect( "onos-install " )
924 # NOTE: this timeout may need to change depending on the network
925 # and size of ONOS
926 i = self.handle.expect( [ "Network\sis\sunreachable",
kelvin-onlabd3b64892015-01-20 13:26:24 -0800927 "onos\sstart/running,\sprocess",
kelvin8ec71442015-01-15 16:57:00 -0800928 "ONOS\sis\salready\sinstalled",
Jon Hall17673bf2016-03-04 13:01:40 -0800929 "already\sup-to-date",
930 "\$",
kelvin8ec71442015-01-15 16:57:00 -0800931 pexpect.TIMEOUT ], timeout=60 )
Jon Hall7993bfc2014-10-09 16:30:14 -0400932 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800933 main.log.warn( "Network is unreachable" )
Jon Hall3b489db2015-10-05 14:38:37 -0700934 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400935 return main.FALSE
936 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800937 main.log.info(
938 "ONOS was installed on " +
939 node +
940 " and started" )
Jon Hall3b489db2015-10-05 14:38:37 -0700941 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400942 return main.TRUE
andrewonlabd9a73a72014-11-14 17:28:21 -0500943 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800944 main.log.info( "ONOS is already installed on " + node )
Jon Hall3b489db2015-10-05 14:38:37 -0700945 self.handle.expect( "\$" )
andrewonlabd9a73a72014-11-14 17:28:21 -0500946 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800947 elif i == 3:
Jon Hall17673bf2016-03-04 13:01:40 -0800948 main.log.info( "ONOS is already installed on " + node )
949 self.handle.expect( "\$" )
950 return main.TRUE
951 elif i == 4:
952 main.log.info( "ONOS was installed on " + node )
953 return main.TRUE
954 elif i == 5:
kelvin8ec71442015-01-15 16:57:00 -0800955 main.log.info(
956 "Installation of ONOS on " +
957 node +
958 " timed out" )
Jon Hall3b489db2015-10-05 14:38:37 -0700959 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400960 return main.FALSE
andrewonlabc03bf6c2014-10-09 14:56:18 -0400961 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800962 main.log.error( self.name + ": EOF exception found" )
963 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400964 main.cleanup()
965 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800966 except Exception:
967 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400968 main.cleanup()
969 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400970
kelvin-onlabd3b64892015-01-20 13:26:24 -0800971 def onosStart( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800972 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400973 Calls onos command: 'onos-service [<node-ip>] start'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400974 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -0800975 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400976 try:
kelvin8ec71442015-01-15 16:57:00 -0800977 self.handle.sendline( "" )
978 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800979 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -0800980 " start" )
981 i = self.handle.expect( [
andrewonlab8d0d7d72014-10-09 16:33:15 -0400982 "Job\sis\salready\srunning",
983 "start/running",
Jon Hall17673bf2016-03-04 13:01:40 -0800984 "\$",
andrewonlab8d0d7d72014-10-09 16:33:15 -0400985 "Unknown\sinstance",
kelvin8ec71442015-01-15 16:57:00 -0800986 pexpect.TIMEOUT ], timeout=120 )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400987 if i == 0:
Jon Hall17673bf2016-03-04 13:01:40 -0800988 self.handle.expect( "\$" )
kelvin8ec71442015-01-15 16:57:00 -0800989 main.log.info( "Service is already running" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400990 return main.TRUE
991 elif i == 1:
Jon Hall17673bf2016-03-04 13:01:40 -0800992 self.handle.expect( "\$" )
993 main.log.info( "ONOS service started" )
994 return main.TRUE
995 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800996 main.log.info( "ONOS service started" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400997 return main.TRUE
998 else:
Jon Hall17673bf2016-03-04 13:01:40 -0800999 self.handle.expect( "\$" )
kelvin8ec71442015-01-15 16:57:00 -08001000 main.log.error( "ONOS service failed to start" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001001 main.cleanup()
1002 main.exit()
andrewonlab8d0d7d72014-10-09 16:33:15 -04001003 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001004 main.log.error( self.name + ": EOF exception found" )
1005 main.log.error( self.name + ": " + self.handle.before )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001006 main.cleanup()
1007 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001008 except Exception:
1009 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001010 main.cleanup()
1011 main.exit()
1012
kelvin-onlabd3b64892015-01-20 13:26:24 -08001013 def onosStop( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001014 """
andrewonlab2b30bd32014-10-09 16:48:55 -04001015 Calls onos command: 'onos-service [<node-ip>] stop'
andrewonlabe8e56fd2014-10-09 17:12:44 -04001016 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -08001017 """
andrewonlab2b30bd32014-10-09 16:48:55 -04001018 try:
kelvin8ec71442015-01-15 16:57:00 -08001019 self.handle.sendline( "" )
1020 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001021 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001022 " stop" )
1023 i = self.handle.expect( [
andrewonlab2b30bd32014-10-09 16:48:55 -04001024 "stop/waiting",
Jon Hall61282e32015-03-19 11:34:11 -07001025 "Could not resolve hostname",
andrewonlab2b30bd32014-10-09 16:48:55 -04001026 "Unknown\sinstance",
kelvin8ec71442015-01-15 16:57:00 -08001027 pexpect.TIMEOUT ], timeout=60 )
Jon Hall3b489db2015-10-05 14:38:37 -07001028 self.handle.expect( "\$" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001029 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001030 main.log.info( "ONOS service stopped" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001031 return main.TRUE
1032 elif i == 1:
Jon Hall65844a32015-03-09 19:09:37 -07001033 main.log.info( "onosStop() Unknown ONOS instance specified: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001034 str( nodeIp ) )
andrewonlab2b30bd32014-10-09 16:48:55 -04001035 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -07001036 elif i == 2:
1037 main.log.warn( "ONOS wasn't running" )
1038 return main.TRUE
andrewonlab2b30bd32014-10-09 16:48:55 -04001039 else:
kelvin8ec71442015-01-15 16:57:00 -08001040 main.log.error( "ONOS service failed to stop" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001041 return main.FALSE
andrewonlab2b30bd32014-10-09 16:48:55 -04001042 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001043 main.log.error( self.name + ": EOF exception found" )
1044 main.log.error( self.name + ": " + self.handle.before )
andrewonlab2b30bd32014-10-09 16:48:55 -04001045 main.cleanup()
1046 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001047 except Exception:
1048 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001049 main.cleanup()
1050 main.exit()
kelvin8ec71442015-01-15 16:57:00 -08001051
kelvin-onlabd3b64892015-01-20 13:26:24 -08001052 def onosUninstall( self, nodeIp="" ):
kelvin8ec71442015-01-15 16:57:00 -08001053 """
andrewonlabc8d47972014-10-09 16:52:36 -04001054 Calls the command: 'onos-uninstall'
kelvin8ec71442015-01-15 16:57:00 -08001055 Uninstalls ONOS from the designated cell machine, stopping
andrewonlabe8e56fd2014-10-09 17:12:44 -04001056 if needed
kelvin8ec71442015-01-15 16:57:00 -08001057 """
andrewonlabc8d47972014-10-09 16:52:36 -04001058 try:
kelvin8ec71442015-01-15 16:57:00 -08001059 self.handle.sendline( "" )
pingping-lin763ee042015-05-20 17:45:30 -07001060 self.handle.expect( "\$", timeout=60 )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001061 self.handle.sendline( "onos-uninstall " + str( nodeIp ) )
Jon Hall3b489db2015-10-05 14:38:37 -07001062 self.handle.expect( "\$", timeout=60 )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001063 main.log.info( "ONOS " + nodeIp + " was uninstalled" )
kelvin8ec71442015-01-15 16:57:00 -08001064 # onos-uninstall command does not return any text
andrewonlabc8d47972014-10-09 16:52:36 -04001065 return main.TRUE
pingping-lin763ee042015-05-20 17:45:30 -07001066 except pexpect.TIMEOUT:
1067 main.log.exception( self.name + ": Timeout in onosUninstall" )
1068 return main.FALSE
andrewonlabc8d47972014-10-09 16:52:36 -04001069 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001070 main.log.error( self.name + ": EOF exception found" )
1071 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc8d47972014-10-09 16:52:36 -04001072 main.cleanup()
1073 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001074 except Exception:
1075 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc8d47972014-10-09 16:52:36 -04001076 main.cleanup()
1077 main.exit()
andrewonlab2b30bd32014-10-09 16:48:55 -04001078
kelvin-onlabd3b64892015-01-20 13:26:24 -08001079 def onosDie( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001080 """
andrewonlabaedc8332014-12-04 12:43:03 -05001081 Issues the command 'onos-die <node-ip>'
1082 This command calls onos-kill and also stops the node
kelvin8ec71442015-01-15 16:57:00 -08001083 """
andrewonlabaedc8332014-12-04 12:43:03 -05001084 try:
kelvin8ec71442015-01-15 16:57:00 -08001085 self.handle.sendline( "" )
1086 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001087 cmdStr = "onos-kill " + str( nodeIp )
1088 self.handle.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -08001089 i = self.handle.expect( [
andrewonlabaedc8332014-12-04 12:43:03 -05001090 "Killing\sONOS",
1091 "ONOS\sprocess\sis\snot\srunning",
kelvin8ec71442015-01-15 16:57:00 -08001092 pexpect.TIMEOUT ], timeout=20 )
andrewonlabaedc8332014-12-04 12:43:03 -05001093 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001094 main.log.info( "ONOS instance " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001095 " was killed and stopped" )
andrewonlabaedc8332014-12-04 12:43:03 -05001096 return main.TRUE
1097 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001098 main.log.info( "ONOS process was not running" )
andrewonlabaedc8332014-12-04 12:43:03 -05001099 return main.FALSE
1100 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001101 main.log.error( self.name + ": EOF exception found" )
1102 main.log.error( self.name + ": " + self.handle.before )
andrewonlabaedc8332014-12-04 12:43:03 -05001103 main.cleanup()
1104 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001105 except Exception:
1106 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabaedc8332014-12-04 12:43:03 -05001107 main.cleanup()
1108 main.exit()
1109
kelvin-onlabd3b64892015-01-20 13:26:24 -08001110 def onosKill( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001111 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001112 Calls the command: 'onos-kill [<node-ip>]'
1113 "Remotely, and unceremoniously kills the ONOS instance running on
1114 the specified cell machine" - Tom V
kelvin8ec71442015-01-15 16:57:00 -08001115 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001116 try:
kelvin8ec71442015-01-15 16:57:00 -08001117 self.handle.sendline( "" )
1118 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001119 self.handle.sendline( "onos-kill " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -08001120 i = self.handle.expect( [
andrewonlabe8e56fd2014-10-09 17:12:44 -04001121 "\$",
1122 "No\sroute\sto\shost",
1123 "password:",
kelvin8ec71442015-01-15 16:57:00 -08001124 pexpect.TIMEOUT ], timeout=20 )
1125
andrewonlabe8e56fd2014-10-09 17:12:44 -04001126 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001127 main.log.info(
1128 "ONOS instance " + str(
kelvin-onlabd3b64892015-01-20 13:26:24 -08001129 nodeIp ) + " was killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001130 return main.TRUE
1131 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001132 main.log.info( "No route to host" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001133 return main.FALSE
1134 elif i == 2:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001135 main.log.info(
1136 "Passwordless login for host: " +
1137 str( nodeIp ) +
1138 " not configured" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001139 return main.FALSE
1140 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001141 main.log.info( "ONOS instance was not killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001142 return main.FALSE
kelvin8ec71442015-01-15 16:57:00 -08001143
andrewonlabe8e56fd2014-10-09 17:12:44 -04001144 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001145 main.log.error( self.name + ": EOF exception found" )
1146 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001147 main.cleanup()
1148 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001149 except Exception:
1150 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001151 main.cleanup()
1152 main.exit()
1153
kelvin-onlabd3b64892015-01-20 13:26:24 -08001154 def onosRemoveRaftLogs( self ):
kelvin8ec71442015-01-15 16:57:00 -08001155 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001156 Removes Raft / Copy cat files from ONOS to ensure
Jon Hallfcc88622014-11-25 13:09:54 -05001157 a cleaner environment.
1158
andrewonlab19fbdca2014-11-14 12:55:59 -05001159 Description:
Jon Hallfcc88622014-11-25 13:09:54 -05001160 Stops all ONOS defined in the cell,
andrewonlab19fbdca2014-11-14 12:55:59 -05001161 wipes the raft / copycat log files
kelvin8ec71442015-01-15 16:57:00 -08001162 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001163 try:
kelvin8ec71442015-01-15 16:57:00 -08001164 self.handle.sendline( "" )
1165 self.handle.expect( "\$" )
1166 self.handle.sendline( "onos-remove-raft-logs" )
1167 # Sometimes this command hangs
1168 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
1169 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001170 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001171 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
1172 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001173 if i == 1:
1174 return main.FALSE
andrewonlab19fbdca2014-11-14 12:55:59 -05001175 return main.TRUE
andrewonlab19fbdca2014-11-14 12:55:59 -05001176 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001177 main.log.error( self.name + ": EOF exception found" )
1178 main.log.error( self.name + ": " + self.handle.before )
andrewonlab19fbdca2014-11-14 12:55:59 -05001179 main.cleanup()
1180 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001181 except Exception:
1182 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab19fbdca2014-11-14 12:55:59 -05001183 main.cleanup()
1184 main.exit()
Jon Hallfcc88622014-11-25 13:09:54 -05001185
kelvin-onlabd3b64892015-01-20 13:26:24 -08001186 def onosStartNetwork( self, mntopo ):
kelvin8ec71442015-01-15 16:57:00 -08001187 """
1188 Calls the command 'onos-start-network [ <mininet-topo> ]
1189 "remotely starts the specified topology on the cell's
andrewonlab94282092014-10-10 13:00:11 -04001190 mininet machine against all controllers configured in the
kelvin8ec71442015-01-15 16:57:00 -08001191 cell."
andrewonlab94282092014-10-10 13:00:11 -04001192 * Specify mininet topology file name for mntopo
1193 * Topo files should be placed at:
1194 ~/<your-onos-directory>/tools/test/topos
kelvin8ec71442015-01-15 16:57:00 -08001195
andrewonlab94282092014-10-10 13:00:11 -04001196 NOTE: This function will take you to the mininet prompt
kelvin8ec71442015-01-15 16:57:00 -08001197 """
andrewonlab94282092014-10-10 13:00:11 -04001198 try:
1199 if not mntopo:
kelvin8ec71442015-01-15 16:57:00 -08001200 main.log.error( "You must specify a topo file to execute" )
andrewonlab94282092014-10-10 13:00:11 -04001201 return main.FALSE
andrewonlab94282092014-10-10 13:00:11 -04001202
kelvin8ec71442015-01-15 16:57:00 -08001203 mntopo = str( mntopo )
1204 self.handle.sendline( "" )
1205 self.handle.expect( "\$" )
andrewonlab94282092014-10-10 13:00:11 -04001206
kelvin8ec71442015-01-15 16:57:00 -08001207 self.handle.sendline( "onos-start-network " + mntopo )
1208 self.handle.expect( "mininet>" )
1209 main.log.info( "Network started, entered mininet prompt" )
1210
1211 # TODO: Think about whether return is necessary or not
andrewonlab94282092014-10-10 13:00:11 -04001212
1213 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001214 main.log.error( self.name + ": EOF exception found" )
1215 main.log.error( self.name + ": " + self.handle.before )
andrewonlab94282092014-10-10 13:00:11 -04001216 main.cleanup()
1217 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001218 except Exception:
1219 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab94282092014-10-10 13:00:11 -04001220 main.cleanup()
1221 main.exit()
1222
Jon Hall3b489db2015-10-05 14:38:37 -07001223 def isup( self, node="", timeout=120 ):
kelvin8ec71442015-01-15 16:57:00 -08001224 """
1225 Run's onos-wait-for-start which only returns once ONOS is at run
Cameron Franke9c94fb02015-01-21 10:20:20 -08001226 level 100(ready for use)
andrewonlab8d0d7d72014-10-09 16:33:15 -04001227
Jon Hall7993bfc2014-10-09 16:30:14 -04001228 Returns: main.TRUE if ONOS is running and main.FALSE on timeout
kelvin8ec71442015-01-15 16:57:00 -08001229 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001230 try:
Jon Hall3b489db2015-10-05 14:38:37 -07001231 self.handle.sendline( "onos-wait-for-start " + node )
1232 self.handle.expect( "onos-wait-for-start" )
kelvin8ec71442015-01-15 16:57:00 -08001233 # NOTE: this timeout is arbitrary"
Cameron Franke9c94fb02015-01-21 10:20:20 -08001234 i = self.handle.expect(["\$", pexpect.TIMEOUT], timeout)
Jon Hall7993bfc2014-10-09 16:30:14 -04001235 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001236 main.log.info( self.name + ": " + node + " is up" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001237 return main.TRUE
1238 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001239 # NOTE: since this function won't return until ONOS is ready,
Jon Hall7993bfc2014-10-09 16:30:14 -04001240 # we will kill it on timeout
kelvin8ec71442015-01-15 16:57:00 -08001241 main.log.error( "ONOS has not started yet" )
1242 self.handle.send( "\x03" ) # Control-C
1243 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001244 return main.FALSE
1245 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001246 main.log.error( self.name + ": EOF exception found" )
1247 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -04001248 main.cleanup()
1249 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001250 except Exception:
1251 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001252 main.cleanup()
1253 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001254
kelvin-onlabd3b64892015-01-20 13:26:24 -08001255 def pushTestIntentsShell(
1256 self,
1257 dpidSrc,
1258 dpidDst,
1259 numIntents,
1260 dirFile,
1261 onosIp,
1262 numMult="",
1263 appId="",
1264 report=True,
1265 options="" ):
kelvin8ec71442015-01-15 16:57:00 -08001266 """
andrewonlabb66dfa12014-12-02 15:51:10 -05001267 Description:
kelvin8ec71442015-01-15 16:57:00 -08001268 Use the linux prompt to push test intents to
andrewonlabb66dfa12014-12-02 15:51:10 -05001269 better parallelize the results than the CLI
1270 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001271 * dpidSrc: specify source dpid
1272 * dpidDst: specify destination dpid
1273 * numIntents: specify number of intents to push
1274 * dirFile: specify directory and file name to save
andrewonlabb66dfa12014-12-02 15:51:10 -05001275 results
kelvin-onlabd3b64892015-01-20 13:26:24 -08001276 * onosIp: specify the IP of ONOS to install on
kelvin8ec71442015-01-15 16:57:00 -08001277 NOTE:
andrewonlabb66dfa12014-12-02 15:51:10 -05001278 You must invoke this command at linux shell prompt
kelvin8ec71442015-01-15 16:57:00 -08001279 """
1280 try:
1281 # Create the string to sendline
andrewonlabaedc8332014-12-04 12:43:03 -05001282 if options:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001283 baseCmd = "onos " + str( onosIp ) + " push-test-intents " +\
kelvin8ec71442015-01-15 16:57:00 -08001284 options + " "
andrewonlabaedc8332014-12-04 12:43:03 -05001285 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001286 baseCmd = "onos " + str( onosIp ) + " push-test-intents "
kelvin8ec71442015-01-15 16:57:00 -08001287
kelvin-onlabd3b64892015-01-20 13:26:24 -08001288 addDpid = baseCmd + str( dpidSrc ) + " " + str( dpidDst )
1289 if not numMult:
1290 addIntents = addDpid + " " + str( numIntents )
1291 elif numMult:
1292 addIntents = addDpid + " " + str( numIntents ) + " " +\
1293 str( numMult )
1294 if appId:
1295 addApp = addIntents + " " + str( appId )
andrewonlabb66dfa12014-12-02 15:51:10 -05001296 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001297 addApp = addIntents
andrewonlabb66dfa12014-12-02 15:51:10 -05001298
andrewonlabaedc8332014-12-04 12:43:03 -05001299 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001300 sendCmd = addApp + " > " + str( dirFile ) + " &"
andrewonlabaedc8332014-12-04 12:43:03 -05001301 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001302 sendCmd = addApp + " &"
1303 main.log.info( "Send cmd: " + sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001304
kelvin-onlabd3b64892015-01-20 13:26:24 -08001305 self.handle.sendline( sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001306
1307 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001308 main.log.error( self.name + ": EOF exception found" )
1309 main.log.error( self.name + ": " + self.handle.before )
andrewonlabb66dfa12014-12-02 15:51:10 -05001310 main.cleanup()
1311 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001312 except Exception:
1313 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabb66dfa12014-12-02 15:51:10 -05001314 main.cleanup()
kelvin8ec71442015-01-15 16:57:00 -08001315 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001316
kelvin-onlabd3b64892015-01-20 13:26:24 -08001317 def getTopology( self, topologyOutput ):
kelvin8ec71442015-01-15 16:57:00 -08001318 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001319 Definition:
1320 Loads a json topology output
1321 Return:
1322 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -08001323 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001324 import json
Jon Hall77f53ce2014-10-13 18:02:06 -04001325 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001326 # either onos:topology or 'topology' will work in CLI
1327 topology = json.loads(topologyOutput)
1328 print topology
Jon Hall77f53ce2014-10-13 18:02:06 -04001329 return topology
1330 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001331 main.log.error( self.name + ": EOF exception found" )
1332 main.log.error( self.name + ": " + self.handle.before )
Jon Hall77f53ce2014-10-13 18:02:06 -04001333 main.cleanup()
1334 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001335 except Exception:
1336 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall77f53ce2014-10-13 18:02:06 -04001337 main.cleanup()
1338 main.exit()
1339
kelvin-onlabd3b64892015-01-20 13:26:24 -08001340 def checkStatus(
1341 self,
1342 topologyResult,
1343 numoswitch,
1344 numolink,
1345 logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08001346 """
Jon Hallefbd9792015-03-05 16:11:36 -08001347 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08001348 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08001349 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08001350
Jon Hall77f53ce2014-10-13 18:02:06 -04001351 Params: ip = ip used for the onos cli
1352 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08001353 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08001354 logLevel = level to log to.
1355 Currently accepts 'info', 'warn' and 'report'
Jon Hall77f53ce2014-10-13 18:02:06 -04001356
1357
kelvin-onlabd3b64892015-01-20 13:26:24 -08001358 logLevel can
Jon Hall77f53ce2014-10-13 18:02:06 -04001359
Jon Hallefbd9792015-03-05 16:11:36 -08001360 Returns: main.TRUE if the number of switches and links are correct,
1361 main.FALSE if the number of switches and links is incorrect,
Jon Hall77f53ce2014-10-13 18:02:06 -04001362 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08001363 """
Jon Hall77f53ce2014-10-13 18:02:06 -04001364 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001365 topology = self.getTopology( topologyResult )
Jon Hall77f53ce2014-10-13 18:02:06 -04001366 if topology == {}:
1367 return main.ERROR
1368 output = ""
kelvin8ec71442015-01-15 16:57:00 -08001369 # Is the number of switches is what we expected
shahshreya234a1682015-05-27 15:41:56 -07001370 devices = topology.get( 'devices', False )
1371 links = topology.get( 'links', False )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001372 if not devices or not links:
Jon Hall77f53ce2014-10-13 18:02:06 -04001373 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08001374 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08001375 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08001376 linkCheck = ( int( links ) == int( numolink ) )
Jon Hallefbd9792015-03-05 16:11:36 -08001377 if switchCheck and linkCheck:
kelvin8ec71442015-01-15 16:57:00 -08001378 # We expected the correct numbers
Jon Hall77f53ce2014-10-13 18:02:06 -04001379 output = output + "The number of links and switches match "\
kelvin8ec71442015-01-15 16:57:00 -08001380 + "what was expected"
Jon Hall77f53ce2014-10-13 18:02:06 -04001381 result = main.TRUE
1382 else:
1383 output = output + \
Jon Hall274b6642015-02-17 11:57:17 -08001384 "The number of links and switches does not match " + \
1385 "what was expected"
Jon Hall77f53ce2014-10-13 18:02:06 -04001386 result = main.FALSE
Jon Hallefbd9792015-03-05 16:11:36 -08001387 output = output + "\n ONOS sees %i devices" % int( devices )
1388 output = output + " (%i expected) " % int( numoswitch )
Jon Hall274b6642015-02-17 11:57:17 -08001389 output = output + "and %i links " % int( links )
1390 output = output + "(%i expected)" % int( numolink )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001391 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08001392 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001393 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08001394 main.log.warn( output )
Jon Hall77f53ce2014-10-13 18:02:06 -04001395 else:
kelvin8ec71442015-01-15 16:57:00 -08001396 main.log.info( output )
1397 return result
Jon Hall77f53ce2014-10-13 18:02:06 -04001398 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001399 main.log.error( self.name + ": EOF exception found" )
1400 main.log.error( self.name + ": " + self.handle.before )
Jon Hall77f53ce2014-10-13 18:02:06 -04001401 main.cleanup()
1402 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001403 except Exception:
1404 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall77f53ce2014-10-13 18:02:06 -04001405 main.cleanup()
1406 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001407
kelvin-onlabd3b64892015-01-20 13:26:24 -08001408 def tsharkPcap( self, interface, dirFile ):
kelvin8ec71442015-01-15 16:57:00 -08001409 """
andrewonlab970399c2014-11-07 13:09:32 -05001410 Capture all packet activity and store in specified
1411 directory/file
1412
1413 Required:
1414 * interface: interface to capture
1415 * dir: directory/filename to store pcap
kelvin8ec71442015-01-15 16:57:00 -08001416 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001417 try:
1418 self.handle.sendline( "" )
1419 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001420
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001421 self.handle.sendline( "tshark -i " + str( interface ) + " -t e -w " + str( dirFile ) + " &" )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001422 self.handle.sendline( "\n" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001423 self.handle.expect( "Capturing on" )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001424 self.handle.sendline( "\n" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001425 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001426
Jon Hallfebb1c72015-03-05 13:30:09 -08001427 main.log.info( "Tshark started capturing files on " +
1428 str( interface ) + " and saving to directory: " +
1429 str( dirFile ) )
1430 except pexpect.EOF:
1431 main.log.error( self.name + ": EOF exception found" )
1432 main.log.error( self.name + ": " + self.handle.before )
1433 main.cleanup()
1434 main.exit()
1435 except Exception:
1436 main.log.exception( self.name + ": Uncaught exception!" )
1437 main.cleanup()
1438 main.exit()
Shreya Shaha73aaad2014-10-27 18:03:09 -04001439
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001440 def onosTopoCfg( self, onosIp, jsonFile ):
kelvin8ec71442015-01-15 16:57:00 -08001441 """
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001442 Description:
1443 Execute onos-topo-cfg command
1444 Required:
1445 onosIp - IP of the onos node you want to send the json to
1446 jsonFile - File path of the json file
1447 Return:
1448 Returns main.TRUE if the command is successfull; Returns
1449 main.FALSE if there was an error
kelvin8ec71442015-01-15 16:57:00 -08001450 """
shahshreyae6c7cf42014-11-26 16:39:01 -08001451 try:
kelvin8ec71442015-01-15 16:57:00 -08001452 self.handle.sendline( "" )
1453 self.handle.expect( "\$" )
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001454 cmd = "onos-topo-cfg "
1455 self.handle.sendline( cmd + str( onosIp ) + " " + jsonFile )
1456 handle = self.handle.before
1457 print handle
1458 if "Error" in handle:
1459 main.log.error( self.name + ": " + self.handle.before )
1460 return main.FALSE
1461 else:
1462 self.handle.expect( "\$" )
1463 return main.TRUE
1464
Jon Hallfebb1c72015-03-05 13:30:09 -08001465 except pexpect.EOF:
1466 main.log.error( self.name + ": EOF exception found" )
1467 main.log.error( self.name + ": " + self.handle.before )
1468 main.cleanup()
1469 main.exit()
1470 except Exception:
1471 main.log.exception( self.name + ": Uncaught exception!" )
1472 main.cleanup()
1473 main.exit()
kelvin8ec71442015-01-15 16:57:00 -08001474
jenkins1e99e7b2015-04-02 18:15:39 -07001475 def tsharkGrep( self, grep, directory, interface='eth0', grepOptions='' ):
kelvin8ec71442015-01-15 16:57:00 -08001476 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001477 Required:
kelvin8ec71442015-01-15 16:57:00 -08001478 * grep string
andrewonlabba44bcf2014-10-16 16:54:41 -04001479 * directory to store results
1480 Optional:
1481 * interface - default: eth0
Jon Hall4ba53f02015-07-29 13:07:41 -07001482 * grepOptions - options for grep
andrewonlabba44bcf2014-10-16 16:54:41 -04001483 Description:
1484 Uses tshark command to grep specific group of packets
1485 and stores the results to specified directory.
kelvin8ec71442015-01-15 16:57:00 -08001486 The timestamp is hardcoded to be in epoch
1487 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001488 try:
1489 self.handle.sendline( "" )
1490 self.handle.expect( "\$" )
1491 self.handle.sendline( "" )
jenkins1e99e7b2015-04-02 18:15:39 -07001492 if grepOptions:
1493 grepStr = "grep "+str(grepOptions)
1494 else:
1495 grepStr = "grep"
Jon Hall4ba53f02015-07-29 13:07:41 -07001496
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001497 cmd = (
1498 "sudo tshark -i " +
Jon Hallfebb1c72015-03-05 13:30:09 -08001499 str( interface ) +
jenkins1e99e7b2015-04-02 18:15:39 -07001500 " -t e | " +
1501 grepStr + " --line-buffered \"" +
Jon Hallfebb1c72015-03-05 13:30:09 -08001502 str(grep) +
1503 "\" >" +
1504 directory +
1505 " &" )
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001506 self.handle.sendline(cmd)
1507 main.log.info(cmd)
Jon Hallfebb1c72015-03-05 13:30:09 -08001508 self.handle.expect( "Capturing on" )
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001509 self.handle.sendline( "\n" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001510 self.handle.expect( "\$" )
1511 except pexpect.EOF:
1512 main.log.error( self.name + ": EOF exception found" )
1513 main.log.error( self.name + ": " + self.handle.before )
1514 main.cleanup()
1515 main.exit()
1516 except Exception:
1517 main.log.exception( self.name + ": Uncaught exception!" )
1518 main.cleanup()
1519 main.exit()
1520
kelvin-onlabd3b64892015-01-20 13:26:24 -08001521 def tsharkStop( self ):
kelvin8ec71442015-01-15 16:57:00 -08001522 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001523 Removes wireshark files from /tmp and kills all tshark processes
kelvin8ec71442015-01-15 16:57:00 -08001524 """
1525 # Remove all pcap from previous captures
Jon Hallfebb1c72015-03-05 13:30:09 -08001526 try:
1527 self.execute( cmd="sudo rm /tmp/wireshark*" )
1528 self.handle.sendline( "" )
Jon Hallefbd9792015-03-05 16:11:36 -08001529 self.handle.sendline( "sudo kill -9 `ps -ef | grep \"tshark -i\"" +
1530 " | grep -v grep | awk '{print $2}'`" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001531 self.handle.sendline( "" )
1532 main.log.info( "Tshark stopped" )
1533 except pexpect.EOF:
1534 main.log.error( self.name + ": EOF exception found" )
1535 main.log.error( self.name + ": " + self.handle.before )
1536 main.cleanup()
1537 main.exit()
1538 except Exception:
1539 main.log.exception( self.name + ": Uncaught exception!" )
1540 main.cleanup()
1541 main.exit()
1542
kelvin8ec71442015-01-15 16:57:00 -08001543 def ptpd( self, args ):
1544 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001545 Initiate ptp with user-specified args.
1546 Required:
1547 * args: specify string of args after command
1548 'sudo ptpd'
kelvin8ec71442015-01-15 16:57:00 -08001549 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001550 try:
kelvin8ec71442015-01-15 16:57:00 -08001551 self.handle.sendline( "sudo ptpd " + str( args ) )
1552 i = self.handle.expect( [
andrewonlab0c38a4a2014-10-28 18:35:35 -04001553 "Multiple",
1554 "Error",
kelvin8ec71442015-01-15 16:57:00 -08001555 "\$" ] )
1556 self.handle.expect( "\$" )
andrewonlabba44bcf2014-10-16 16:54:41 -04001557
andrewonlab0c38a4a2014-10-28 18:35:35 -04001558 if i == 0:
1559 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001560 main.log.info( "ptpd returned an error: " +
1561 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001562 return handle
1563 elif i == 1:
1564 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001565 main.log.error( "ptpd returned an error: " +
1566 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001567 return handle
1568 else:
1569 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -08001570
andrewonlab0c38a4a2014-10-28 18:35:35 -04001571 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001572 main.log.error( self.name + ": EOF exception found" )
1573 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001574 main.cleanup()
1575 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001576 except Exception:
1577 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001578 main.cleanup()
1579 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001580
kelvin-onlabd3b64892015-01-20 13:26:24 -08001581 def cpLogsToDir( self, logToCopy,
Jon Hallefbd9792015-03-05 16:11:36 -08001582 destDir, copyFileName="" ):
kelvin8ec71442015-01-15 16:57:00 -08001583 """
1584 Copies logs to a desired directory.
andrewonlab5d7a8f32014-11-10 13:07:56 -05001585 Current implementation of ONOS deletes its karaf
1586 logs on every iteration. For debugging purposes,
kelvin8ec71442015-01-15 16:57:00 -08001587 you may want to use this function to capture
1588 certain karaf logs. ( or any other logs if needed )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001589 Localtime will be attached to the filename
1590
1591 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001592 * logToCopy: specify directory and log name to
andrewonlab5d7a8f32014-11-10 13:07:56 -05001593 copy.
kelvin8ec71442015-01-15 16:57:00 -08001594 ex ) /opt/onos/log/karaf.log.1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001595 For copying multiple files, leave copyFileName
1596 empty and only specify destDir -
kelvin8ec71442015-01-15 16:57:00 -08001597 ex ) /opt/onos/log/karaf*
kelvin-onlabd3b64892015-01-20 13:26:24 -08001598 * destDir: specify directory to copy to.
kelvin8ec71442015-01-15 16:57:00 -08001599 ex ) /tmp/
1600 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001601 * copyFileName: If you want to rename the log
1602 file, specify copyFileName. This will not work
andrewonlab5d7a8f32014-11-10 13:07:56 -05001603 with multiple file copying
kelvin8ec71442015-01-15 16:57:00 -08001604 """
andrewonlab5d7a8f32014-11-10 13:07:56 -05001605 try:
kelvin8ec71442015-01-15 16:57:00 -08001606 localtime = time.strftime( '%x %X' )
1607 localtime = localtime.replace( "/", "" )
1608 localtime = localtime.replace( " ", "_" )
1609 localtime = localtime.replace( ":", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001610 if destDir[ -1: ] != "/":
1611 destDir += "/"
andrewonlab5d7a8f32014-11-10 13:07:56 -05001612
kelvin-onlabd3b64892015-01-20 13:26:24 -08001613 if copyFileName:
Jon Hallfebb1c72015-03-05 13:30:09 -08001614 self.handle.sendline( "cp " + str( logToCopy ) + " " +
1615 str( destDir ) + str( copyFileName ) +
1616 localtime )
kelvin8ec71442015-01-15 16:57:00 -08001617 self.handle.expect( "cp" )
1618 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001619 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001620 self.handle.sendline( "cp " + str( logToCopy ) +
1621 " " + str( destDir ) )
kelvin8ec71442015-01-15 16:57:00 -08001622 self.handle.expect( "cp" )
1623 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001624
kelvin8ec71442015-01-15 16:57:00 -08001625 return self.handle.before
1626
1627 except pexpect.EOF:
1628 main.log.error( "Copying files failed" )
1629 main.log.error( self.name + ": EOF exception found" )
1630 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001631 except Exception:
1632 main.log.exception( "Copying files failed" )
1633
Jon Hall16b72c42015-05-20 10:23:36 -07001634 def checkLogs( self, onosIp, restart=False):
kelvin8ec71442015-01-15 16:57:00 -08001635 """
Jon Hall94fd0472014-12-08 11:52:42 -08001636 runs onos-check-logs on the given onos node
Jon Hall80daded2015-05-27 16:07:00 -07001637 If restart is True, use the old version of onos-check-logs which
1638 does not print the full stacktrace, but shows the entire log file,
1639 including across restarts
Jon Hall94fd0472014-12-08 11:52:42 -08001640 returns the response
kelvin8ec71442015-01-15 16:57:00 -08001641 """
Jon Hall94fd0472014-12-08 11:52:42 -08001642 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001643 cmd = "onos-check-logs " + str( onosIp )
Jon Hall16b72c42015-05-20 10:23:36 -07001644 if restart:
1645 cmd += " old"
kelvin8ec71442015-01-15 16:57:00 -08001646 self.handle.sendline( cmd )
1647 self.handle.expect( cmd )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001648 self.handle.expect( "\$ " )
Jon Hall94fd0472014-12-08 11:52:42 -08001649 response = self.handle.before
1650 return response
1651 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001652 main.log.error( "Lost ssh connection" )
1653 main.log.error( self.name + ": EOF exception found" )
1654 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001655 except Exception:
1656 main.log.exception( self.name + ": Uncaught exception!" )
1657 main.cleanup()
1658 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -08001659
kelvin-onlabd3b64892015-01-20 13:26:24 -08001660 def onosStatus( self, node="" ):
kelvin8ec71442015-01-15 16:57:00 -08001661 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001662 Calls onos command: 'onos-service [<node-ip>] status'
kelvin8ec71442015-01-15 16:57:00 -08001663 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001664 try:
kelvin8ec71442015-01-15 16:57:00 -08001665 self.handle.sendline( "" )
1666 self.handle.expect( "\$" )
1667 self.handle.sendline( "onos-service " + str( node ) +
1668 " status" )
1669 i = self.handle.expect( [
Jon Hall17673bf2016-03-04 13:01:40 -08001670 "Running ...",
1671 "Not Running ...",
kelvin8ec71442015-01-15 16:57:00 -08001672 pexpect.TIMEOUT ], timeout=120 )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001673
1674 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001675 main.log.info( "ONOS is running" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001676 return main.TRUE
1677 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001678 main.log.info( "ONOS is stopped" )
kelvin8ec71442015-01-15 16:57:00 -08001679 main.log.error( "ONOS service failed to check the status" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001680 main.cleanup()
1681 main.exit()
1682 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001683 main.log.error( self.name + ": EOF exception found" )
1684 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001685 main.cleanup()
1686 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001687 except Exception:
1688 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001689 main.cleanup()
1690 main.exit()
Jon Hall21270ac2015-02-16 17:59:55 -08001691
Jon Hall63604932015-02-26 17:09:50 -08001692 def setIpTables( self, ip, port='', action='add', packet_type='',
1693 direction='INPUT', rule='DROP', states=True ):
Jon Hallefbd9792015-03-05 16:11:36 -08001694 """
Jon Hall21270ac2015-02-16 17:59:55 -08001695 Description:
1696 add or remove iptables rule to DROP (default) packets from
1697 specific IP and PORT
1698 Usage:
1699 * specify action ('add' or 'remove')
1700 when removing, pass in the same argument as you would add. It will
1701 delete that specific rule.
1702 * specify the ip to block
1703 * specify the destination port to block (defaults to all ports)
1704 * optional packet type to block (default tcp)
1705 * optional iptables rule (default DROP)
1706 * optional direction to block (default 'INPUT')
Jon Hall63604932015-02-26 17:09:50 -08001707 * States boolean toggles adding all supported tcp states to the
1708 firewall rule
Jon Hall21270ac2015-02-16 17:59:55 -08001709 Returns:
1710 main.TRUE on success or
1711 main.FALSE if given invalid input or
1712 main.ERROR if there is an error in response from iptables
1713 WARNING:
1714 * This function uses root privilege iptables command which may result
1715 in unwanted network errors. USE WITH CAUTION
Jon Hallefbd9792015-03-05 16:11:36 -08001716 """
Jon Hall21270ac2015-02-16 17:59:55 -08001717
1718 # NOTE*********
1719 # The strict checking methods of this driver function is intentional
1720 # to discourage any misuse or error of iptables, which can cause
1721 # severe network errors
1722 # *************
1723
1724 # NOTE: Sleep needed to give some time for rule to be added and
1725 # registered to the instance. If you are calling this function
1726 # multiple times this sleep will prevent any errors.
1727 # DO NOT REMOVE
Jon Hall63604932015-02-26 17:09:50 -08001728 # time.sleep( 5 )
Jon Hall21270ac2015-02-16 17:59:55 -08001729 try:
1730 # input validation
1731 action_type = action.lower()
1732 rule = rule.upper()
1733 direction = direction.upper()
1734 if action_type != 'add' and action_type != 'remove':
1735 main.log.error( "Invalid action type. Use 'add' or "
1736 "'remove' table rule" )
1737 if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
1738 # NOTE Currently only supports rules DROP, ACCEPT, and LOG
1739 main.log.error( "Invalid rule. Valid rules are 'DROP' or "
1740 "'ACCEPT' or 'LOG' only." )
1741 if direction != 'INPUT' and direction != 'OUTPUT':
1742 # NOTE currently only supports rules INPUT and OUPTUT
1743 main.log.error( "Invalid rule. Valid directions are"
1744 " 'OUTPUT' or 'INPUT'" )
1745 return main.FALSE
1746 return main.FALSE
1747 return main.FALSE
1748 if action_type == 'add':
1749 # -A is the 'append' action of iptables
1750 actionFlag = '-A'
1751 elif action_type == 'remove':
1752 # -D is the 'delete' rule of iptables
1753 actionFlag = '-D'
1754 self.handle.sendline( "" )
1755 self.handle.expect( "\$" )
1756 cmd = "sudo iptables " + actionFlag + " " +\
1757 direction +\
Jon Hall21270ac2015-02-16 17:59:55 -08001758 " -s " + str( ip )
Jon Hall63604932015-02-26 17:09:50 -08001759 # " -p " + str( packet_type ) +\
1760 if packet_type:
1761 cmd += " -p " + str( packet_type )
Jon Hall21270ac2015-02-16 17:59:55 -08001762 if port:
1763 cmd += " --dport " + str( port )
Jon Hall63604932015-02-26 17:09:50 -08001764 if states:
1765 cmd += " -m state --state="
1766 #FIXME- Allow user to configure which states to block
1767 cmd += "INVALID,ESTABLISHED,NEW,RELATED,UNTRACKED"
Jon Hall21270ac2015-02-16 17:59:55 -08001768 cmd += " -j " + str( rule )
1769
1770 self.handle.sendline( cmd )
1771 self.handle.expect( "\$" )
1772 main.log.warn( self.handle.before )
1773
1774 info_string = "On " + str( self.name )
1775 info_string += " " + str( action_type )
1776 info_string += " iptable rule [ "
1777 info_string += " IP: " + str( ip )
1778 info_string += " Port: " + str( port )
1779 info_string += " Rule: " + str( rule )
1780 info_string += " Direction: " + str( direction ) + " ]"
1781 main.log.info( info_string )
1782 return main.TRUE
1783 except pexpect.TIMEOUT:
1784 main.log.exception( self.name + ": Timeout exception in "
1785 "setIpTables function" )
1786 return main.ERROR
1787 except pexpect.EOF:
1788 main.log.error( self.name + ": EOF exception found" )
1789 main.log.error( self.name + ": " + self.handle.before )
1790 main.cleanup()
1791 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001792 except Exception:
1793 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall21270ac2015-02-16 17:59:55 -08001794 main.cleanup()
1795 main.exit()
1796
Jon Hall0468b042015-02-19 19:08:21 -08001797 def detailed_status(self, log_filename):
Jon Hallefbd9792015-03-05 16:11:36 -08001798 """
Jon Hall0468b042015-02-19 19:08:21 -08001799 This method is used by STS to check the status of the controller
1800 Reports RUNNING, STARTING, STOPPED, FROZEN, ERROR (and reason)
Jon Hallefbd9792015-03-05 16:11:36 -08001801 """
Jon Hall0468b042015-02-19 19:08:21 -08001802 import re
1803 try:
1804 self.handle.sendline( "" )
1805 self.handle.expect( "\$" )
1806 self.handle.sendline( "cd " + self.home )
1807 self.handle.expect( "\$" )
1808 self.handle.sendline( "service onos status" )
1809 self.handle.expect( "\$" )
1810 response = self.handle.before
1811 if re.search( "onos start/running", response ):
1812 # onos start/running, process 10457
1813 return 'RUNNING'
1814 # FIXME: Implement this case
1815 # elif re.search( pattern, response ):
1816 # return 'STARTING'
1817 elif re.search( "onos stop/", response ):
1818 # onos stop/waiting
1819 # FIXME handle this differently?: onos stop/pre-stop
1820 return 'STOPPED'
1821 # FIXME: Implement this case
1822 # elif re.search( pattern, response ):
1823 # return 'FROZEN'
1824 else:
1825 main.log.warn( self.name +
Jon Hallefbd9792015-03-05 16:11:36 -08001826 " WARNING: status received unknown response" )
Jon Hall0468b042015-02-19 19:08:21 -08001827 main.log.warn( response )
1828 return 'ERROR', "Unknown response: %s" % response
1829 except pexpect.TIMEOUT:
1830 main.log.exception( self.name + ": Timeout exception in "
1831 "setIpTables function" )
1832 return 'ERROR', "Pexpect Timeout"
1833 except pexpect.EOF:
1834 main.log.error( self.name + ": EOF exception found" )
1835 main.log.error( self.name + ": " + self.handle.before )
1836 main.cleanup()
1837 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001838 except Exception:
1839 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall0468b042015-02-19 19:08:21 -08001840 main.cleanup()
1841 main.exit()
1842
andrew@onlab.us3b087132015-03-11 15:00:08 -07001843 def createLinkGraphFile( self, benchIp, ONOSIpList, deviceCount):
1844 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07001845 Create/formats the LinkGraph.cfg file based on arguments
1846 -only creates a linear topology and connects islands
1847 -evenly distributes devices
andrew@onlab.us3b087132015-03-11 15:00:08 -07001848 -must be called by ONOSbench
1849
Jon Hall4ba53f02015-07-29 13:07:41 -07001850 ONOSIpList - list of all of the node IPs to be used
1851
1852 deviceCount - number of switches to be assigned
andrew@onlab.us3b087132015-03-11 15:00:08 -07001853 '''
1854 main.log.step("Creating link graph configuration file." )
1855 linkGraphPath = self.home + "/tools/package/etc/linkGraph.cfg"
Jon Hall4ba53f02015-07-29 13:07:41 -07001856 tempFile = "/tmp/linkGraph.cfg"
andrew@onlab.us3b087132015-03-11 15:00:08 -07001857
1858 linkGraph = open(tempFile, 'w+')
1859 linkGraph.write("# NullLinkProvider topology description (config file).\n")
1860 linkGraph.write("# The NodeId is only added if the destination is another node's device.\n")
1861 linkGraph.write("# Bugs: Comments cannot be appended to a line to be read.\n")
Jon Hall4ba53f02015-07-29 13:07:41 -07001862
andrew@onlab.us3b087132015-03-11 15:00:08 -07001863 clusterCount = len(ONOSIpList)
Jon Hall4ba53f02015-07-29 13:07:41 -07001864
1865 if type(deviceCount) is int or type(deviceCount) is str:
andrew@onlab.us3b087132015-03-11 15:00:08 -07001866 deviceCount = int(deviceCount)
1867 switchList = [0]*(clusterCount+1)
1868 baselineSwitchCount = deviceCount/clusterCount
Jon Hall4ba53f02015-07-29 13:07:41 -07001869
andrew@onlab.us3b087132015-03-11 15:00:08 -07001870 for node in range(1, clusterCount + 1):
1871 switchList[node] = baselineSwitchCount
1872
1873 for node in range(1, (deviceCount%clusterCount)+1):
1874 switchList[node] += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07001875
andrew@onlab.us3b087132015-03-11 15:00:08 -07001876 if type(deviceCount) is list:
1877 main.log.info("Using provided device distribution")
1878 switchList = [0]
1879 for i in deviceCount:
1880 switchList.append(int(i))
1881
1882 tempList = ['0']
1883 tempList.extend(ONOSIpList)
1884 ONOSIpList = tempList
1885
1886 myPort = 6
1887 lastSwitch = 0
1888 for node in range(1, clusterCount+1):
1889 if switchList[node] == 0:
1890 continue
1891
1892 linkGraph.write("graph " + ONOSIpList[node] + " {\n")
Jon Hall4ba53f02015-07-29 13:07:41 -07001893
andrew@onlab.us3b087132015-03-11 15:00:08 -07001894 if node > 1:
1895 #connect to last device on previous node
Jon Hall4ba53f02015-07-29 13:07:41 -07001896 line = ("\t0:5 -> " + str(lastSwitch) + ":6:" + lastIp + "\n") #ONOSIpList[node-1]
1897 linkGraph.write(line)
1898
1899 lastSwitch = 0
1900 for switch in range (0, switchList[node]-1):
andrew@onlab.us3b087132015-03-11 15:00:08 -07001901 line = ""
1902 line = ("\t" + str(switch) + ":" + str(myPort))
1903 line += " -- "
1904 line += (str(switch+1) + ":" + str(myPort-1) + "\n")
1905 linkGraph.write(line)
Jon Hall4ba53f02015-07-29 13:07:41 -07001906 lastSwitch = switch+1
andrew@onlab.us3b087132015-03-11 15:00:08 -07001907 lastIp = ONOSIpList[node]
Jon Hall4ba53f02015-07-29 13:07:41 -07001908
andrew@onlab.us3b087132015-03-11 15:00:08 -07001909 #lastSwitch += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07001910 if node < (clusterCount):
andrew@onlab.us3b087132015-03-11 15:00:08 -07001911 #connect to first device on the next node
Jon Hall4ba53f02015-07-29 13:07:41 -07001912 line = ("\t" + str(lastSwitch) + ":6 -> 0:5:" + ONOSIpList[node+1] + "\n")
andrew@onlab.us3b087132015-03-11 15:00:08 -07001913 linkGraph.write(line)
Jon Hall4ba53f02015-07-29 13:07:41 -07001914
andrew@onlab.us3b087132015-03-11 15:00:08 -07001915 linkGraph.write("}\n")
1916 linkGraph.close()
1917
1918 #SCP
Jon Hall4ba53f02015-07-29 13:07:41 -07001919 os.system( "scp " + tempFile + " " + self.user_name + "@" + benchIp + ":" + linkGraphPath)
andrew@onlab.us3b087132015-03-11 15:00:08 -07001920 main.log.info("linkGraph.cfg creation complete")
1921
cameron@onlab.us75900962015-03-30 13:22:49 -07001922 def configNullDev( self, ONOSIpList, deviceCount, numPorts=10):
Jon Hall4ba53f02015-07-29 13:07:41 -07001923
andrew@onlab.us3b087132015-03-11 15:00:08 -07001924 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07001925 ONOSIpList = list of Ip addresses of nodes switches will be devided amongst
1926 deviceCount = number of switches to distribute, or list of values to use as custom distribution
cameron@onlab.us75900962015-03-30 13:22:49 -07001927 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 -07001928 '''
1929
cameron@onlab.us75900962015-03-30 13:22:49 -07001930 main.log.step("Configuring Null Device Provider" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07001931 clusterCount = len(ONOSIpList)
1932
Jon Hall4ba53f02015-07-29 13:07:41 -07001933 try:
1934
cameron@onlab.us75900962015-03-30 13:22:49 -07001935 if type(deviceCount) is int or type(deviceCount) is str:
1936 main.log.step("Creating device distribution")
1937 deviceCount = int(deviceCount)
1938 switchList = [0]*(clusterCount+1)
1939 baselineSwitchCount = deviceCount/clusterCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001940
cameron@onlab.us75900962015-03-30 13:22:49 -07001941 for node in range(1, clusterCount + 1):
1942 switchList[node] = baselineSwitchCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001943
cameron@onlab.us75900962015-03-30 13:22:49 -07001944 for node in range(1, (deviceCount%clusterCount)+1):
1945 switchList[node] += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07001946
1947 if type(deviceCount) is list:
1948 main.log.info("Using provided device distribution")
1949
1950 if len(deviceCount) == clusterCount:
cameron@onlab.us75900962015-03-30 13:22:49 -07001951 switchList = ['0']
1952 switchList.extend(deviceCount)
Jon Hall4ba53f02015-07-29 13:07:41 -07001953
1954 if len(deviceCount) == (clusterCount + 1):
1955 if deviceCount[0] == '0' or deviceCount[0] == 0:
cameron@onlab.us75900962015-03-30 13:22:49 -07001956 switchList = deviceCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001957
cameron@onlab.us75900962015-03-30 13:22:49 -07001958 assert len(switchList) == (clusterCount + 1)
Jon Hall4ba53f02015-07-29 13:07:41 -07001959
cameron@onlab.us75900962015-03-30 13:22:49 -07001960 except AssertionError:
Jon Hall4ba53f02015-07-29 13:07:41 -07001961 main.log.error( "Bad device/Ip list match")
cameron@onlab.us75900962015-03-30 13:22:49 -07001962 except TypeError:
1963 main.log.exception( self.name + ": Object not as expected" )
1964 return None
Jon Hall77ba41c2015-04-06 10:25:40 -07001965 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07001966 main.log.exception( self.name + ": Uncaught exception!" )
1967 main.cleanup()
1968 main.exit()
1969
andrew@onlab.us3b087132015-03-11 15:00:08 -07001970
1971 ONOSIp = [0]
1972 ONOSIp.extend(ONOSIpList)
Jon Hall4ba53f02015-07-29 13:07:41 -07001973
andrew@onlab.us3b087132015-03-11 15:00:08 -07001974 devicesString = "devConfigs = "
1975 for node in range(1, len(ONOSIp)):
1976 devicesString += (ONOSIp[node] + ":" + str(switchList[node] ))
1977 if node < clusterCount:
1978 devicesString += (",")
Jon Hall4ba53f02015-07-29 13:07:41 -07001979
1980 try:
cameron@onlab.us75900962015-03-30 13:22:49 -07001981 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider devConfigs " + devicesString )
1982 self.handle.expect(":~")
1983 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider numPorts " + str(numPorts) )
1984 self.handle.expect(":~")
andrew@onlab.us3b087132015-03-11 15:00:08 -07001985
cameron@onlab.us75900962015-03-30 13:22:49 -07001986 for i in range(10):
1987 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.device.impl.NullDeviceProvider")
1988 self.handle.expect(":~")
1989 verification = self.handle.before
1990 if (" value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification:
1991 break
1992 else:
1993 time.sleep(1)
andrew@onlab.us3b087132015-03-11 15:00:08 -07001994
cameron@onlab.us2cc8bf12015-04-02 14:12:30 -07001995 assert ("value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification
Jon Hall4ba53f02015-07-29 13:07:41 -07001996
cameron@onlab.us75900962015-03-30 13:22:49 -07001997 except AssertionError:
1998 main.log.error("Incorrect Config settings: " + verification)
Jon Hall77ba41c2015-04-06 10:25:40 -07001999 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002000 main.log.exception( self.name + ": Uncaught exception!" )
2001 main.cleanup()
2002 main.exit()
2003
Jon Hall4ba53f02015-07-29 13:07:41 -07002004 def configNullLink( self,fileName="/opt/onos/apache-karaf-3.0.3/etc/linkGraph.cfg", eventRate=0):
andrew@onlab.us3b087132015-03-11 15:00:08 -07002005 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07002006 fileName default is currently the same as the default on ONOS, specify alternate file if
cameron@onlab.us75900962015-03-30 13:22:49 -07002007 you want to use a different topology file than linkGraph.cfg
andrew@onlab.us3b087132015-03-11 15:00:08 -07002008 '''
2009
Jon Hall4ba53f02015-07-29 13:07:41 -07002010
2011 try:
2012 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider eventRate " + str(eventRate))
2013 self.handle.expect(":~")
cameron@onlab.us75900962015-03-30 13:22:49 -07002014 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider cfgFile " + fileName )
2015 self.handle.expect(":~")
Jon Hall4ba53f02015-07-29 13:07:41 -07002016
2017 for i in range(10):
2018 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.link.impl.NullLinkProvider")
cameron@onlab.us75900962015-03-30 13:22:49 -07002019 self.handle.expect(":~")
2020 verification = self.handle.before
Jon Hall4ba53f02015-07-29 13:07:41 -07002021 if (" value=" + str(eventRate)) in verification and (" value=" + fileName) in verification:
cameron@onlab.us75900962015-03-30 13:22:49 -07002022 break
Jon Hall4ba53f02015-07-29 13:07:41 -07002023 else:
cameron@onlab.us75900962015-03-30 13:22:49 -07002024 time.sleep(1)
Jon Hall4ba53f02015-07-29 13:07:41 -07002025
cameron@onlab.us75900962015-03-30 13:22:49 -07002026 assert ("value=" + str(eventRate)) in verification and (" value=" + fileName) in verification
Jon Hall4ba53f02015-07-29 13:07:41 -07002027
cameron@onlab.us75900962015-03-30 13:22:49 -07002028 except pexpect.EOF:
2029 main.log.error( self.name + ": EOF exception found" )
2030 main.log.error( self.name + ": " + self.handle.before )
2031 main.cleanup()
2032 main.exit()
cameron@onlab.us75900962015-03-30 13:22:49 -07002033 except AssertionError:
2034 main.log.info("Settings did not post to ONOS")
Jon Hall4ba53f02015-07-29 13:07:41 -07002035 main.log.error(varification)
Jon Hall77ba41c2015-04-06 10:25:40 -07002036 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002037 main.log.exception( self.name + ": Uncaught exception!" )
2038 main.log.error(varification)
2039 main.cleanup()
2040 main.exit()
andrew@onlab.us3b087132015-03-11 15:00:08 -07002041
kelvin-onlaba4074292015-07-09 15:19:49 -07002042 def getOnosIps( self ):
2043 """
2044 Get all onos IPs stored in
2045 """
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002046
kelvin-onlaba4074292015-07-09 15:19:49 -07002047 return sorted( self.onosIps.values() )
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002048
kelvin-onlaba4074292015-07-09 15:19:49 -07002049 def logReport( self, nodeIp, searchTerms, outputMode="s" ):
Jon Hallb4242222016-01-25 17:07:04 -08002050 """
2051 Searches the latest ONOS log file for the given search terms and
2052 prints the total occurances of each term. Returns to combined total of
2053 all occurances.
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002054
Jon Hallb4242222016-01-25 17:07:04 -08002055 Arguments:
2056 * nodeIp - The ip of the ONOS node where the log is located
2057 * searchTerms - A string to grep for or a list of strings to grep
2058 for in the ONOS log. Will print out the number of
2059 occurances for each term.
2060 Optional Arguments:
2061 * outputMode - 's' or 'd'. If 'd' will print the last 5 lines
2062 containing each search term as well as the total
2063 number of occurances of each term. Defaults to 's',
2064 which prints the simple output of just the number
2065 of occurances for each term.
2066 """
2067 try:
2068 main.log.info( " Log Report for {} ".format( nodeIp ).center( 70, '=' ) )
2069 if type( searchTerms ) is str:
2070 searchTerms = [searchTerms]
2071 numTerms = len( searchTerms )
2072 outputMode = outputMode.lower()
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002073
Jon Hallb4242222016-01-25 17:07:04 -08002074 totalHits = 0
2075 logLines = []
2076 for termIndex in range( numTerms ):
2077 term = searchTerms[termIndex]
2078 logLines.append( [term] )
2079 cmd = "onos-ssh " + nodeIp + " cat /opt/onos/log/karaf.log | grep " + term
2080 self.handle.sendline( cmd )
2081 self.handle.expect( ":~" )
2082 before = self.handle.before.splitlines()
2083 count = 0
2084 for line in before:
2085 if term in line and "grep" not in line:
2086 count += 1
2087 if before.index( line ) > ( len( before ) - 7 ):
2088 logLines[termIndex].append( line )
2089 main.log.info( "{}: {}".format( term, count ) )
2090 totalHits += count
2091 if termIndex == numTerms - 1:
2092 print "\n"
2093 if outputMode != "s":
2094 outputString = ""
2095 for term in logLines:
2096 outputString = term[0] + ": \n"
2097 for line in range( 1, len( term ) ):
2098 outputString += ( "\t" + term[line] + "\n" )
2099 if outputString != ( term[0] + ": \n" ):
2100 main.log.info( outputString )
2101 main.log.info( "=" * 70 )
2102 return totalHits
2103 except pexpect.EOF:
2104 main.log.error( self.name + ": EOF exception found" )
2105 main.log.error( self.name + ": " + self.handle.before )
2106 main.cleanup()
2107 main.exit()
2108 except pexpect.TIMEOUT:
2109 main.log.error( self.name + ": TIMEOUT exception found" )
2110 main.log.error( self.name + ": " + self.handle.before )
2111 main.cleanup()
2112 main.exit()
2113 except Exception:
2114 main.log.exception( self.name + ": Uncaught exception!" )
2115 main.cleanup()
2116 main.exit()
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002117
2118 def copyMininetFile( self, fileName, localPath, userName, ip,
2119 mnPath='~/mininet/custom/', timeout = 60 ):
2120 """
2121 Description:
2122 Copy mininet topology file from dependency folder in the test folder
2123 and paste it to the mininet machine's mininet/custom folder
2124 Required:
2125 fileName - Name of the topology file to copy
2126 localPath - File path of the mininet topology file
2127 userName - User name of the mininet machine to send the file to
2128 ip - Ip address of the mininet machine
2129 Optional:
2130 mnPath - of the mininet directory to send the file to
2131 Return:
2132 Return main.TRUE if successfully copied the file otherwise
2133 return main.FALSE
2134 """
2135
2136 try:
2137 cmd = "scp " + localPath + fileName + " " + userName + "@" + \
2138 str( ip ) + ":" + mnPath + fileName
2139
2140 self.handle.sendline( "" )
2141 self.handle.expect( "\$" )
2142
2143 main.log.info( self.name + ": Execute: " + cmd )
2144
2145 self.handle.sendline( cmd )
2146
2147 i = self.handle.expect( [ 'No such file',
2148 "100%",
2149 pexpect.TIMEOUT ] )
2150
2151 if i == 0:
2152 main.log.error( self.name + ": File " + fileName +
2153 " does not exist!" )
2154 return main.FALSE
2155
2156 if i == 1:
2157 main.log.info( self.name + ": File " + fileName +
2158 " has been copied!" )
2159 self.handle.sendline( "" )
2160 self.handle.expect( "\$" )
2161 return main.TRUE
2162
2163 except pexpect.EOF:
2164 main.log.error( self.name + ": EOF exception found" )
2165 main.log.error( self.name + ": " + self.handle.before )
2166 main.cleanup()
2167 main.exit()
2168 except pexpect.TIMEOUT:
2169 main.log.error( self.name + ": TIMEOUT exception found" )
2170 main.log.error( self.name + ": " + self.handle.before )
2171 main.cleanup()
2172 main.exit()
cameron@onlab.us78b89652015-07-08 15:21:03 -07002173
2174 def jvmSet(self, memory=8):
Jon Hall4ba53f02015-07-29 13:07:41 -07002175
cameron@onlab.us78b89652015-07-08 15:21:03 -07002176 import os
2177
2178 homeDir = os.path.expanduser('~')
2179 filename = "/onos/tools/package/bin/onos-service"
2180
2181 serviceConfig = open(homeDir + filename, 'w+')
2182 serviceConfig.write("#!/bin/bash\n ")
2183 serviceConfig.write("#------------------------------------- \n ")
2184 serviceConfig.write("# Starts ONOS Apache Karaf container\n ")
2185 serviceConfig.write("#------------------------------------- \n ")
2186 serviceConfig.write("#export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-7-openjdk-amd64/}\n ")
2187 serviceConfig.write("""export JAVA_OPTS="${JAVA_OPTS:--Xms""" + str(memory) + "G -Xmx" + str(memory) + """G}" \n """)
2188 serviceConfig.write("[ -d $ONOS_HOME ] && cd $ONOS_HOME || ONOS_HOME=$(dirname $0)/..\n")
2189 serviceConfig.write("""${ONOS_HOME}/apache-karaf-$KARAF_VERSION/bin/karaf "$@" \n """)
2190 serviceConfig.close()
2191
2192 def createDBFile(self, testData):
Jon Hall4ba53f02015-07-29 13:07:41 -07002193
cameron@onlab.us78b89652015-07-08 15:21:03 -07002194 filename = main.TEST + "DB"
2195 DBString = ""
Jon Hall4ba53f02015-07-29 13:07:41 -07002196
cameron@onlab.us78b89652015-07-08 15:21:03 -07002197 for item in testData:
Jon Hall4ba53f02015-07-29 13:07:41 -07002198 if type(item) is string:
cameron@onlab.us78b89652015-07-08 15:21:03 -07002199 item = "'" + item + "'"
2200 if testData.index(item) < len(testData-1):
2201 item += ","
Jon Hall4ba53f02015-07-29 13:07:41 -07002202 DBString += str(item)
cameron@onlab.us78b89652015-07-08 15:21:03 -07002203
2204 DBFile = open(filename, "a")
2205 DBFile.write(DBString)
2206 DBFile.close()
2207
Jon Hall4ba53f02015-07-29 13:07:41 -07002208 def verifySummary(self, ONOSIp,*deviceCount):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002209
2210 self.handle.sendline("onos " + ONOSIp + " summary")
2211 self.handle.expect(":~")
2212
2213 summaryStr = self.handle.before
2214 print "\nSummary\n==============\n" + summaryStr + "\n\n"
2215
2216 #passed = "SCC(s)=1" in summaryStr
2217 #if deviceCount:
2218 # passed = "devices=" + str(deviceCount) + "," not in summaryStr
2219
GlennRC772363b2015-08-25 13:05:57 -07002220 passed = False
cameron@onlab.us78b89652015-07-08 15:21:03 -07002221 if "SCC(s)=1," in summaryStr:
2222 passed = True
2223 print("Summary is verifed")
Jon Hall4ba53f02015-07-29 13:07:41 -07002224 else:
2225 print("Summary failed")
cameron@onlab.us78b89652015-07-08 15:21:03 -07002226
2227 if deviceCount:
2228 print" ============================="
2229 checkStr = "devices=" + str(deviceCount[0]) + ","
2230 print "Checkstr: " + checkStr
2231 if checkStr not in summaryStr:
2232 passed = False
Jon Hall4ba53f02015-07-29 13:07:41 -07002233 print("Device count failed")
2234 else:
2235 print "device count verified"
cameron@onlab.us78b89652015-07-08 15:21:03 -07002236
2237 return passed