blob: 9dee93ec5ff3ec699f3b416142fe4b4fa5607212 [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,
Flavio Castrocc38a542016-03-03 13:15:46 -0800674 appString, onosIpAddrs, onosUser="sdn" ):
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
Flavio Castrocc38a542016-03-03 13:15:46 -0800686 * ONOS USER (onosUser)
687 - optional argument to set ONOS_USER environment variable
kelvin8ec71442015-01-15 16:57:00 -0800688
andrewonlab94282092014-10-10 13:00:11 -0400689 NOTE: Assumes cells are located at:
690 ~/<self.home>/tools/test/cells/
kelvin8ec71442015-01-15 16:57:00 -0800691 """
692 # Variable initialization
Jon Hall6801cda2015-07-15 14:13:45 -0700693 cellDirectory = self.home + "/tools/test/cells/"
kelvin8ec71442015-01-15 16:57:00 -0800694 # We want to create the cell file in the dependencies directory
695 # of TestON first, then copy over to ONOS bench
kelvin-onlabd3b64892015-01-20 13:26:24 -0800696 tempDirectory = "/tmp/"
kelvin8ec71442015-01-15 16:57:00 -0800697 # Create the cell file in the directory for writing ( w+ )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800698 cellFile = open( tempDirectory + fileName, 'w+' )
Jon Hall6801cda2015-07-15 14:13:45 -0700699 if isinstance( onosIpAddrs, types.StringType ):
700 onosIpAddrs = [ onosIpAddrs ]
kelvin8ec71442015-01-15 16:57:00 -0800701
cameron@onlab.us75900962015-03-30 13:22:49 -0700702 # App string is hardcoded environment variables
kelvin8ec71442015-01-15 16:57:00 -0800703 # That you may wish to use by default on startup.
cameron@onlab.us75900962015-03-30 13:22:49 -0700704 # Note that you may not want certain apps listed
kelvin8ec71442015-01-15 16:57:00 -0800705 # on here.
cameron@onlab.us75900962015-03-30 13:22:49 -0700706 appString = "export ONOS_APPS=" + appString
Flavio Castrocc38a542016-03-03 13:15:46 -0800707 onosGroup = "export ONOS_GROUP=" + onosUser
708 onosUser = "export ONOS_USER=" + onosUser
kelvin-onlabd3b64892015-01-20 13:26:24 -0800709 mnString = "export OCN="
kelvin-onlabf70fd542015-05-07 18:41:40 -0700710 if mnIpAddrs == "":
711 mnString = ""
kelvin-onlabd3b64892015-01-20 13:26:24 -0800712 onosString = "export OC"
713 tempCount = 1
kelvin8ec71442015-01-15 16:57:00 -0800714
kelvin-onlabd3b64892015-01-20 13:26:24 -0800715 # Create ONOSNIC ip address prefix
kelvin-onlaba4074292015-07-09 15:19:49 -0700716 tempOnosIp = str( onosIpAddrs[ 0 ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800717 tempList = []
718 tempList = tempOnosIp.split( "." )
kelvin8ec71442015-01-15 16:57:00 -0800719 # Omit last element of list to format for NIC
kelvin-onlabd3b64892015-01-20 13:26:24 -0800720 tempList = tempList[ :-1 ]
kelvin8ec71442015-01-15 16:57:00 -0800721 # Structure the nic string ip
kelvin-onlabd3b64892015-01-20 13:26:24 -0800722 nicAddr = ".".join( tempList ) + ".*"
723 onosNicString = "export ONOS_NIC=" + nicAddr
andrewonlab94282092014-10-10 13:00:11 -0400724
725 try:
kelvin8ec71442015-01-15 16:57:00 -0800726 # Start writing to file
kelvin-onlabd3b64892015-01-20 13:26:24 -0800727 cellFile.write( onosNicString + "\n" )
andrewonlab94282092014-10-10 13:00:11 -0400728
kelvin-onlabd3b64892015-01-20 13:26:24 -0800729 for arg in onosIpAddrs:
730 # For each argument in onosIpAddrs, write to file
kelvin8ec71442015-01-15 16:57:00 -0800731 # Output should look like the following:
andrewonlabd4940492014-10-24 12:21:27 -0400732 # export OC1="10.128.20.11"
733 # export OC2="10.128.20.12"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800734 cellFile.write( onosString + str( tempCount ) +
Jon Hall6f665652015-09-18 10:08:07 -0700735 "=\"" + arg + "\"\n" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800736 tempCount = tempCount + 1
kelvin8ec71442015-01-15 16:57:00 -0800737
Jon Hall6f665652015-09-18 10:08:07 -0700738 cellFile.write( "export OCI=$OC1\n" )
739 cellFile.write( mnString + "\"" + mnIpAddrs + "\"\n" )
cameron@onlab.us75900962015-03-30 13:22:49 -0700740 cellFile.write( appString + "\n" )
Flavio Castrocc38a542016-03-03 13:15:46 -0800741 cellFile.write( onosGroup + "\n" )
742 cellFile.write( onosUser + "\n" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800743 cellFile.close()
andrewonlab94282092014-10-10 13:00:11 -0400744
kelvin8ec71442015-01-15 16:57:00 -0800745 # We use os.system to send the command to TestON cluster
746 # to account for the case in which TestON is not located
747 # on the same cluster as the ONOS bench
748 # Note that even if TestON is located on the same cluster
749 # as ONOS bench, you must setup passwordless ssh
750 # between TestON and ONOS bench in order to automate the test.
kelvin-onlabc2b79102015-07-14 11:41:20 -0700751 os.system( "scp " + tempDirectory + fileName + " " +
752 self.user_name + "@" + self.ip_address + ":" + cellDirectory )
andrewonlab94282092014-10-10 13:00:11 -0400753
andrewonlab2a6c9342014-10-16 13:40:15 -0400754 return main.TRUE
755
andrewonlab94282092014-10-10 13:00:11 -0400756 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800757 main.log.error( self.name + ": EOF exception found" )
758 main.log.error( self.name + ": " + self.handle.before )
andrewonlab94282092014-10-10 13:00:11 -0400759 main.cleanup()
760 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800761 except Exception:
762 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab94282092014-10-10 13:00:11 -0400763 main.cleanup()
764 main.exit()
765
kelvin-onlabd3b64892015-01-20 13:26:24 -0800766 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800767 """
andrewonlab95ca1462014-10-09 14:04:24 -0400768 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800769 """
Hari Krishna03f530e2015-07-10 17:28:27 -0700770 import re
andrewonlab95ca1462014-10-09 14:04:24 -0400771 try:
772 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800773 main.log.error( "Must define cellname" )
andrewonlab95ca1462014-10-09 14:04:24 -0400774 main.cleanup()
775 main.exit()
776 else:
kelvin8ec71442015-01-15 16:57:00 -0800777 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800778 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800779 # Note that this variable name is subject to change
andrewonlab95ca1462014-10-09 14:04:24 -0400780 # and that this driver will have to change accordingly
Jon Hall3b489db2015-10-05 14:38:37 -0700781 self.handle.expect( str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800782 handleBefore = self.handle.before
783 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800784 # Get the rest of the handle
Jon Hall3b489db2015-10-05 14:38:37 -0700785 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800786 handleMore = self.handle.before
andrewonlab95ca1462014-10-09 14:04:24 -0400787
Hari Krishna03f530e2015-07-10 17:28:27 -0700788 cell_result = handleBefore + handleAfter + handleMore
789 print cell_result
790 if( re.search( "No such cell", cell_result ) ):
791 main.log.error( "Cell call returned: " + handleBefore +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800792 handleAfter + handleMore )
Hari Krishna03f530e2015-07-10 17:28:27 -0700793 main.cleanup()
794 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400795 return main.TRUE
andrewonlab95ca1462014-10-09 14:04:24 -0400796 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800797 main.log.error( self.name + ": EOF exception found" )
798 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ca1462014-10-09 14:04:24 -0400799 main.cleanup()
800 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800801 except Exception:
802 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ca1462014-10-09 14:04:24 -0400803 main.cleanup()
804 main.exit()
805
kelvin-onlabd3b64892015-01-20 13:26:24 -0800806 def verifyCell( self ):
kelvin8ec71442015-01-15 16:57:00 -0800807 """
andrewonlabc03bf6c2014-10-09 14:56:18 -0400808 Calls 'onos-verify-cell' to check for cell installation
kelvin8ec71442015-01-15 16:57:00 -0800809 """
810 # TODO: Add meaningful expect value
andrewonlab8d0d7d72014-10-09 16:33:15 -0400811
andrewonlabc03bf6c2014-10-09 14:56:18 -0400812 try:
kelvin8ec71442015-01-15 16:57:00 -0800813 # Clean handle by sending empty and expecting $
814 self.handle.sendline( "" )
815 self.handle.expect( "\$" )
816 self.handle.sendline( "onos-verify-cell" )
817 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800818 handleBefore = self.handle.before
819 handleAfter = self.handle.after
kelvin-onlabd3b64892015-01-20 13:26:24 -0800820 main.log.info( "Verify cell returned: " + handleBefore +
Jon Hall3b489db2015-10-05 14:38:37 -0700821 handleAfter )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400822 return main.TRUE
Jon Halla5cb6172015-02-23 09:28:28 -0800823 except pexpect.ExceptionPexpect as e:
Jon Hall3b489db2015-10-05 14:38:37 -0700824 main.log.exception( self.name + ": Pexpect exception found: " )
kelvin8ec71442015-01-15 16:57:00 -0800825 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -0400826 main.cleanup()
827 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800828 except Exception:
829 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400830 main.cleanup()
831 main.exit()
832
jenkins1e99e7b2015-04-02 18:15:39 -0700833 def onosCfgSet( self, ONOSIp, configName, configParam ):
834 """
835 Uses 'onos <node-ip> cfg set' to change a parameter value of an
Jon Hall4ba53f02015-07-29 13:07:41 -0700836 application.
837
jenkins1e99e7b2015-04-02 18:15:39 -0700838 ex)
839 onos 10.0.0.1 cfg set org.onosproject.myapp appSetting 1
jenkins1e99e7b2015-04-02 18:15:39 -0700840 ONOSIp = '10.0.0.1'
841 configName = 'org.onosproject.myapp'
842 configParam = 'appSetting 1'
jenkins1e99e7b2015-04-02 18:15:39 -0700843 """
Jon Hall72280bc2016-01-25 14:29:05 -0800844 try:
845 cfgStr = "onos {} cfg set {} {}".format( ONOSIp,
846 configName,
847 configParam )
848 self.handle.sendline( "" )
849 self.handle.expect( ":~" )
850 self.handle.sendline( cfgStr )
851 self.handle.expect("cfg set")
852 self.handle.expect( ":~" )
jenkins1e99e7b2015-04-02 18:15:39 -0700853
Jon Hall72280bc2016-01-25 14:29:05 -0800854 paramValue = configParam.split(" ")[1]
855 paramName = configParam.split(" ")[0]
Jon Hall4ba53f02015-07-29 13:07:41 -0700856
Jon Hall72280bc2016-01-25 14:29:05 -0800857 checkStr = 'onos {} cfg get " {} {} " '.format( ONOSIp, configName, paramName )
Jon Hall4ba53f02015-07-29 13:07:41 -0700858
Jon Hall72280bc2016-01-25 14:29:05 -0800859 self.handle.sendline( checkStr )
860 self.handle.expect( ":~" )
jenkins1e99e7b2015-04-02 18:15:39 -0700861
Jon Hall72280bc2016-01-25 14:29:05 -0800862 if "value=" + paramValue + "," in self.handle.before:
863 main.log.info("cfg " + configName + " successfully set to " + configParam)
864 return main.TRUE
865 except pexpect.ExceptionPexpect as e:
866 main.log.exception( self.name + ": Pexpect exception found: " )
867 main.log.error( self.name + ": " + self.handle.before )
868 main.cleanup()
869 main.exit()
870 except Exception:
871 main.log.exception( self.name + ": Uncaught exception!" )
872 main.cleanup()
873 main.exit()
Jon Hall4ba53f02015-07-29 13:07:41 -0700874
kelvin-onlabd3b64892015-01-20 13:26:24 -0800875 def onosCli( self, ONOSIp, cmdstr ):
kelvin8ec71442015-01-15 16:57:00 -0800876 """
andrewonlab05e362f2014-10-10 00:40:57 -0400877 Uses 'onos' command to send various ONOS CLI arguments.
878 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800879 * ONOSIp: specify the ip of the cell machine
andrewonlab94282092014-10-10 13:00:11 -0400880 * cmdstr: specify the command string to send
kelvin8ec71442015-01-15 16:57:00 -0800881
882 This function is intended to expose the entire karaf
andrewonlab6e20c342014-10-10 18:08:48 -0400883 CLI commands for ONOS. Try to use this function first
884 before attempting to write a ONOS CLI specific driver
kelvin8ec71442015-01-15 16:57:00 -0800885 function.
886 You can see a list of available 'cmdstr' arguments
andrewonlab6e20c342014-10-10 18:08:48 -0400887 by starting onos, and typing in 'onos' to enter the
888 onos> CLI. Then, type 'help' to see the list of
kelvin8ec71442015-01-15 16:57:00 -0800889 available commands.
890 """
andrewonlab05e362f2014-10-10 00:40:57 -0400891 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800892 if not ONOSIp:
kelvin8ec71442015-01-15 16:57:00 -0800893 main.log.error( "You must specify the IP address" )
andrewonlab05e362f2014-10-10 00:40:57 -0400894 return main.FALSE
895 if not cmdstr:
kelvin8ec71442015-01-15 16:57:00 -0800896 main.log.error( "You must specify the command string" )
andrewonlab05e362f2014-10-10 00:40:57 -0400897 return main.FALSE
898
kelvin8ec71442015-01-15 16:57:00 -0800899 cmdstr = str( cmdstr )
900 self.handle.sendline( "" )
901 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400902
kelvin-onlabd3b64892015-01-20 13:26:24 -0800903 self.handle.sendline( "onos -w " + ONOSIp + " " + cmdstr )
kelvin8ec71442015-01-15 16:57:00 -0800904 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400905
kelvin-onlabd3b64892015-01-20 13:26:24 -0800906 handleBefore = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -0800907 main.log.info( "Command sent successfully" )
kelvin8ec71442015-01-15 16:57:00 -0800908 # Obtain return handle that consists of result from
909 # the onos command. The string may need to be
910 # configured further.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800911 returnString = handleBefore
kelvin-onlabd3b64892015-01-20 13:26:24 -0800912 return returnString
andrewonlab05e362f2014-10-10 00:40:57 -0400913 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800914 main.log.error( self.name + ": EOF exception found" )
915 main.log.error( self.name + ": " + self.handle.before )
andrewonlab05e362f2014-10-10 00:40:57 -0400916 main.cleanup()
917 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800918 except Exception:
919 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab05e362f2014-10-10 00:40:57 -0400920 main.cleanup()
921 main.exit()
Jon Hall7993bfc2014-10-09 16:30:14 -0400922
kelvin-onlabd3b64892015-01-20 13:26:24 -0800923 def onosInstall( self, options="-f", node="" ):
kelvin8ec71442015-01-15 16:57:00 -0800924 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400925 Installs ONOS bits on the designated cell machine.
kelvin8ec71442015-01-15 16:57:00 -0800926 If -f option is provided, it also forces an uninstall.
927 Presently, install also includes onos-push-bits and
Jon Hall7993bfc2014-10-09 16:30:14 -0400928 onos-config within.
kelvin8ec71442015-01-15 16:57:00 -0800929 The node option allows you to selectively only push the jar
Jon Hall7993bfc2014-10-09 16:30:14 -0400930 files to certain onos nodes
931
932 Returns: main.TRUE on success and main.FALSE on failure
kelvin8ec71442015-01-15 16:57:00 -0800933 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400934 try:
andrewonlab114768a2014-11-14 12:44:44 -0500935 if options:
kelvin8ec71442015-01-15 16:57:00 -0800936 self.handle.sendline( "onos-install " + options + " " + node )
andrewonlab114768a2014-11-14 12:44:44 -0500937 else:
kelvin8ec71442015-01-15 16:57:00 -0800938 self.handle.sendline( "onos-install " + node )
939 self.handle.expect( "onos-install " )
940 # NOTE: this timeout may need to change depending on the network
941 # and size of ONOS
942 i = self.handle.expect( [ "Network\sis\sunreachable",
kelvin-onlabd3b64892015-01-20 13:26:24 -0800943 "onos\sstart/running,\sprocess",
kelvin8ec71442015-01-15 16:57:00 -0800944 "ONOS\sis\salready\sinstalled",
Jeremyc72b2582016-02-26 18:27:38 -0800945 "already\sup-to-date",
946 "\$",
kelvin8ec71442015-01-15 16:57:00 -0800947 pexpect.TIMEOUT ], timeout=60 )
Jon Hall7993bfc2014-10-09 16:30:14 -0400948 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800949 main.log.warn( "Network is unreachable" )
Jon Hall3b489db2015-10-05 14:38:37 -0700950 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400951 return main.FALSE
952 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800953 main.log.info(
954 "ONOS was installed on " +
955 node +
956 " and started" )
Jon Hall3b489db2015-10-05 14:38:37 -0700957 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400958 return main.TRUE
andrewonlabd9a73a72014-11-14 17:28:21 -0500959 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800960 main.log.info( "ONOS is already installed on " + node )
Jon Hall3b489db2015-10-05 14:38:37 -0700961 self.handle.expect( "\$" )
andrewonlabd9a73a72014-11-14 17:28:21 -0500962 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800963 elif i == 3:
Jeremyc72b2582016-02-26 18:27:38 -0800964 main.log.info( "ONOS is already installed on " + node )
965 self.handle.expect( "\$" )
966 return main.TRUE
967 elif i == 4:
968 main.log.info( "ONOS was installed on " + node )
969 return main.TRUE
970 elif i == 5:
kelvin8ec71442015-01-15 16:57:00 -0800971 main.log.info(
972 "Installation of ONOS on " +
973 node +
974 " timed out" )
Jon Hall3b489db2015-10-05 14:38:37 -0700975 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400976 return main.FALSE
andrewonlabc03bf6c2014-10-09 14:56:18 -0400977 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800978 main.log.error( self.name + ": EOF exception found" )
979 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400980 main.cleanup()
981 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800982 except Exception:
983 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400984 main.cleanup()
985 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400986
kelvin-onlabd3b64892015-01-20 13:26:24 -0800987 def onosStart( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800988 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400989 Calls onos command: 'onos-service [<node-ip>] start'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400990 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -0800991 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400992 try:
kelvin8ec71442015-01-15 16:57:00 -0800993 self.handle.sendline( "" )
994 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800995 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -0800996 " start" )
997 i = self.handle.expect( [
andrewonlab8d0d7d72014-10-09 16:33:15 -0400998 "Job\sis\salready\srunning",
999 "start/running",
Jeremyd0e9a6d2016-03-02 11:28:52 -08001000 "\$",
andrewonlab8d0d7d72014-10-09 16:33:15 -04001001 "Unknown\sinstance",
kelvin8ec71442015-01-15 16:57:00 -08001002 pexpect.TIMEOUT ], timeout=120 )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001003 if i == 0:
Jon Halleab7a242016-03-04 10:20:43 -08001004 self.handle.expect( "\$" )
kelvin8ec71442015-01-15 16:57:00 -08001005 main.log.info( "Service is already running" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001006 return main.TRUE
1007 elif i == 1:
Jon Halleab7a242016-03-04 10:20:43 -08001008 self.handle.expect( "\$" )
kelvin8ec71442015-01-15 16:57:00 -08001009 main.log.info( "ONOS service started" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001010 return main.TRUE
Jeremyd0e9a6d2016-03-02 11:28:52 -08001011 elif i == 2:
1012 main.log.info( "ONOS service started" )
1013 return main.TRUE
andrewonlab8d0d7d72014-10-09 16:33:15 -04001014 else:
Jon Halleab7a242016-03-04 10:20:43 -08001015 self.handle.expect( "\$" )
kelvin8ec71442015-01-15 16:57:00 -08001016 main.log.error( "ONOS service failed to start" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001017 main.cleanup()
1018 main.exit()
andrewonlab8d0d7d72014-10-09 16:33:15 -04001019 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001020 main.log.error( self.name + ": EOF exception found" )
1021 main.log.error( self.name + ": " + self.handle.before )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001022 main.cleanup()
1023 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001024 except Exception:
1025 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001026 main.cleanup()
1027 main.exit()
1028
kelvin-onlabd3b64892015-01-20 13:26:24 -08001029 def onosStop( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001030 """
andrewonlab2b30bd32014-10-09 16:48:55 -04001031 Calls onos command: 'onos-service [<node-ip>] stop'
andrewonlabe8e56fd2014-10-09 17:12:44 -04001032 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -08001033 """
andrewonlab2b30bd32014-10-09 16:48:55 -04001034 try:
kelvin8ec71442015-01-15 16:57:00 -08001035 self.handle.sendline( "" )
1036 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001037 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001038 " stop" )
1039 i = self.handle.expect( [
andrewonlab2b30bd32014-10-09 16:48:55 -04001040 "stop/waiting",
Jon Hall61282e32015-03-19 11:34:11 -07001041 "Could not resolve hostname",
andrewonlab2b30bd32014-10-09 16:48:55 -04001042 "Unknown\sinstance",
YPZhang77badfc2016-03-09 10:28:59 -08001043 "\$",
kelvin8ec71442015-01-15 16:57:00 -08001044 pexpect.TIMEOUT ], timeout=60 )
andrewonlab2b30bd32014-10-09 16:48:55 -04001045 if i == 0:
YPZhang77badfc2016-03-09 10:28:59 -08001046 self.handle.expect( "\$" )
kelvin8ec71442015-01-15 16:57:00 -08001047 main.log.info( "ONOS service stopped" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001048 return main.TRUE
1049 elif i == 1:
YPZhang77badfc2016-03-09 10:28:59 -08001050 self.handle.expect( "\$" )
Jon Hall65844a32015-03-09 19:09:37 -07001051 main.log.info( "onosStop() Unknown ONOS instance specified: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001052 str( nodeIp ) )
andrewonlab2b30bd32014-10-09 16:48:55 -04001053 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -07001054 elif i == 2:
YPZhang77badfc2016-03-09 10:28:59 -08001055 self.handle.expect( "\$" )
Jon Hall61282e32015-03-19 11:34:11 -07001056 main.log.warn( "ONOS wasn't running" )
1057 return main.TRUE
YPZhang77badfc2016-03-09 10:28:59 -08001058 elif i == 3:
1059 main.log.info( "ONOS service stopped" )
1060 return main.TRUE
andrewonlab2b30bd32014-10-09 16:48:55 -04001061 else:
kelvin8ec71442015-01-15 16:57:00 -08001062 main.log.error( "ONOS service failed to stop" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001063 return main.FALSE
andrewonlab2b30bd32014-10-09 16:48:55 -04001064 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001065 main.log.error( self.name + ": EOF exception found" )
1066 main.log.error( self.name + ": " + self.handle.before )
andrewonlab2b30bd32014-10-09 16:48:55 -04001067 main.cleanup()
1068 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001069 except Exception:
1070 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001071 main.cleanup()
1072 main.exit()
kelvin8ec71442015-01-15 16:57:00 -08001073
kelvin-onlabd3b64892015-01-20 13:26:24 -08001074 def onosUninstall( self, nodeIp="" ):
kelvin8ec71442015-01-15 16:57:00 -08001075 """
andrewonlabc8d47972014-10-09 16:52:36 -04001076 Calls the command: 'onos-uninstall'
kelvin8ec71442015-01-15 16:57:00 -08001077 Uninstalls ONOS from the designated cell machine, stopping
andrewonlabe8e56fd2014-10-09 17:12:44 -04001078 if needed
kelvin8ec71442015-01-15 16:57:00 -08001079 """
andrewonlabc8d47972014-10-09 16:52:36 -04001080 try:
kelvin8ec71442015-01-15 16:57:00 -08001081 self.handle.sendline( "" )
pingping-lin763ee042015-05-20 17:45:30 -07001082 self.handle.expect( "\$", timeout=60 )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001083 self.handle.sendline( "onos-uninstall " + str( nodeIp ) )
Jon Hall3b489db2015-10-05 14:38:37 -07001084 self.handle.expect( "\$", timeout=60 )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001085 main.log.info( "ONOS " + nodeIp + " was uninstalled" )
kelvin8ec71442015-01-15 16:57:00 -08001086 # onos-uninstall command does not return any text
andrewonlabc8d47972014-10-09 16:52:36 -04001087 return main.TRUE
pingping-lin763ee042015-05-20 17:45:30 -07001088 except pexpect.TIMEOUT:
1089 main.log.exception( self.name + ": Timeout in onosUninstall" )
1090 return main.FALSE
andrewonlabc8d47972014-10-09 16:52:36 -04001091 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001092 main.log.error( self.name + ": EOF exception found" )
1093 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc8d47972014-10-09 16:52:36 -04001094 main.cleanup()
1095 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001096 except Exception:
1097 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc8d47972014-10-09 16:52:36 -04001098 main.cleanup()
1099 main.exit()
andrewonlab2b30bd32014-10-09 16:48:55 -04001100
kelvin-onlabd3b64892015-01-20 13:26:24 -08001101 def onosDie( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001102 """
andrewonlabaedc8332014-12-04 12:43:03 -05001103 Issues the command 'onos-die <node-ip>'
1104 This command calls onos-kill and also stops the node
kelvin8ec71442015-01-15 16:57:00 -08001105 """
andrewonlabaedc8332014-12-04 12:43:03 -05001106 try:
kelvin8ec71442015-01-15 16:57:00 -08001107 self.handle.sendline( "" )
1108 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001109 cmdStr = "onos-kill " + str( nodeIp )
1110 self.handle.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -08001111 i = self.handle.expect( [
andrewonlabaedc8332014-12-04 12:43:03 -05001112 "Killing\sONOS",
1113 "ONOS\sprocess\sis\snot\srunning",
kelvin8ec71442015-01-15 16:57:00 -08001114 pexpect.TIMEOUT ], timeout=20 )
andrewonlabaedc8332014-12-04 12:43:03 -05001115 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001116 main.log.info( "ONOS instance " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001117 " was killed and stopped" )
andrewonlabaedc8332014-12-04 12:43:03 -05001118 return main.TRUE
1119 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001120 main.log.info( "ONOS process was not running" )
andrewonlabaedc8332014-12-04 12:43:03 -05001121 return main.FALSE
1122 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001123 main.log.error( self.name + ": EOF exception found" )
1124 main.log.error( self.name + ": " + self.handle.before )
andrewonlabaedc8332014-12-04 12:43:03 -05001125 main.cleanup()
1126 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001127 except Exception:
1128 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabaedc8332014-12-04 12:43:03 -05001129 main.cleanup()
1130 main.exit()
1131
kelvin-onlabd3b64892015-01-20 13:26:24 -08001132 def onosKill( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001133 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001134 Calls the command: 'onos-kill [<node-ip>]'
1135 "Remotely, and unceremoniously kills the ONOS instance running on
1136 the specified cell machine" - Tom V
kelvin8ec71442015-01-15 16:57:00 -08001137 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001138 try:
kelvin8ec71442015-01-15 16:57:00 -08001139 self.handle.sendline( "" )
1140 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001141 self.handle.sendline( "onos-kill " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -08001142 i = self.handle.expect( [
andrewonlabe8e56fd2014-10-09 17:12:44 -04001143 "\$",
1144 "No\sroute\sto\shost",
1145 "password:",
kelvin8ec71442015-01-15 16:57:00 -08001146 pexpect.TIMEOUT ], timeout=20 )
1147
andrewonlabe8e56fd2014-10-09 17:12:44 -04001148 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001149 main.log.info(
1150 "ONOS instance " + str(
kelvin-onlabd3b64892015-01-20 13:26:24 -08001151 nodeIp ) + " was killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001152 return main.TRUE
1153 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001154 main.log.info( "No route to host" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001155 return main.FALSE
1156 elif i == 2:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001157 main.log.info(
1158 "Passwordless login for host: " +
1159 str( nodeIp ) +
1160 " not configured" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001161 return main.FALSE
1162 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001163 main.log.info( "ONOS instance was not killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001164 return main.FALSE
kelvin8ec71442015-01-15 16:57:00 -08001165
andrewonlabe8e56fd2014-10-09 17:12:44 -04001166 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001167 main.log.error( self.name + ": EOF exception found" )
1168 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001169 main.cleanup()
1170 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001171 except Exception:
1172 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001173 main.cleanup()
1174 main.exit()
1175
kelvin-onlabd3b64892015-01-20 13:26:24 -08001176 def onosRemoveRaftLogs( self ):
kelvin8ec71442015-01-15 16:57:00 -08001177 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001178 Removes Raft / Copy cat files from ONOS to ensure
Jon Hallfcc88622014-11-25 13:09:54 -05001179 a cleaner environment.
1180
andrewonlab19fbdca2014-11-14 12:55:59 -05001181 Description:
Jon Hallfcc88622014-11-25 13:09:54 -05001182 Stops all ONOS defined in the cell,
andrewonlab19fbdca2014-11-14 12:55:59 -05001183 wipes the raft / copycat log files
kelvin8ec71442015-01-15 16:57:00 -08001184 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001185 try:
kelvin8ec71442015-01-15 16:57:00 -08001186 self.handle.sendline( "" )
1187 self.handle.expect( "\$" )
1188 self.handle.sendline( "onos-remove-raft-logs" )
1189 # Sometimes this command hangs
1190 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
1191 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001192 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001193 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
1194 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001195 if i == 1:
1196 return main.FALSE
andrewonlab19fbdca2014-11-14 12:55:59 -05001197 return main.TRUE
andrewonlab19fbdca2014-11-14 12:55:59 -05001198 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001199 main.log.error( self.name + ": EOF exception found" )
1200 main.log.error( self.name + ": " + self.handle.before )
andrewonlab19fbdca2014-11-14 12:55:59 -05001201 main.cleanup()
1202 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001203 except Exception:
1204 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab19fbdca2014-11-14 12:55:59 -05001205 main.cleanup()
1206 main.exit()
Jon Hallfcc88622014-11-25 13:09:54 -05001207
kelvin-onlabd3b64892015-01-20 13:26:24 -08001208 def onosStartNetwork( self, mntopo ):
kelvin8ec71442015-01-15 16:57:00 -08001209 """
1210 Calls the command 'onos-start-network [ <mininet-topo> ]
1211 "remotely starts the specified topology on the cell's
andrewonlab94282092014-10-10 13:00:11 -04001212 mininet machine against all controllers configured in the
kelvin8ec71442015-01-15 16:57:00 -08001213 cell."
andrewonlab94282092014-10-10 13:00:11 -04001214 * Specify mininet topology file name for mntopo
1215 * Topo files should be placed at:
1216 ~/<your-onos-directory>/tools/test/topos
kelvin8ec71442015-01-15 16:57:00 -08001217
andrewonlab94282092014-10-10 13:00:11 -04001218 NOTE: This function will take you to the mininet prompt
kelvin8ec71442015-01-15 16:57:00 -08001219 """
andrewonlab94282092014-10-10 13:00:11 -04001220 try:
1221 if not mntopo:
kelvin8ec71442015-01-15 16:57:00 -08001222 main.log.error( "You must specify a topo file to execute" )
andrewonlab94282092014-10-10 13:00:11 -04001223 return main.FALSE
andrewonlab94282092014-10-10 13:00:11 -04001224
kelvin8ec71442015-01-15 16:57:00 -08001225 mntopo = str( mntopo )
1226 self.handle.sendline( "" )
1227 self.handle.expect( "\$" )
andrewonlab94282092014-10-10 13:00:11 -04001228
kelvin8ec71442015-01-15 16:57:00 -08001229 self.handle.sendline( "onos-start-network " + mntopo )
1230 self.handle.expect( "mininet>" )
1231 main.log.info( "Network started, entered mininet prompt" )
1232
1233 # TODO: Think about whether return is necessary or not
andrewonlab94282092014-10-10 13:00:11 -04001234
1235 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001236 main.log.error( self.name + ": EOF exception found" )
1237 main.log.error( self.name + ": " + self.handle.before )
andrewonlab94282092014-10-10 13:00:11 -04001238 main.cleanup()
1239 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001240 except Exception:
1241 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab94282092014-10-10 13:00:11 -04001242 main.cleanup()
1243 main.exit()
1244
Jon Hall3b489db2015-10-05 14:38:37 -07001245 def isup( self, node="", timeout=120 ):
kelvin8ec71442015-01-15 16:57:00 -08001246 """
1247 Run's onos-wait-for-start which only returns once ONOS is at run
Cameron Franke9c94fb02015-01-21 10:20:20 -08001248 level 100(ready for use)
andrewonlab8d0d7d72014-10-09 16:33:15 -04001249
Jon Hall7993bfc2014-10-09 16:30:14 -04001250 Returns: main.TRUE if ONOS is running and main.FALSE on timeout
kelvin8ec71442015-01-15 16:57:00 -08001251 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001252 try:
Jon Hall3b489db2015-10-05 14:38:37 -07001253 self.handle.sendline( "onos-wait-for-start " + node )
1254 self.handle.expect( "onos-wait-for-start" )
kelvin8ec71442015-01-15 16:57:00 -08001255 # NOTE: this timeout is arbitrary"
Cameron Franke9c94fb02015-01-21 10:20:20 -08001256 i = self.handle.expect(["\$", pexpect.TIMEOUT], timeout)
Jon Hall7993bfc2014-10-09 16:30:14 -04001257 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001258 main.log.info( self.name + ": " + node + " is up" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001259 return main.TRUE
1260 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001261 # NOTE: since this function won't return until ONOS is ready,
Jon Hall7993bfc2014-10-09 16:30:14 -04001262 # we will kill it on timeout
kelvin8ec71442015-01-15 16:57:00 -08001263 main.log.error( "ONOS has not started yet" )
1264 self.handle.send( "\x03" ) # Control-C
1265 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001266 return main.FALSE
1267 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001268 main.log.error( self.name + ": EOF exception found" )
1269 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -04001270 main.cleanup()
1271 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001272 except Exception:
1273 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001274 main.cleanup()
1275 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001276
kelvin-onlabd3b64892015-01-20 13:26:24 -08001277 def pushTestIntentsShell(
1278 self,
1279 dpidSrc,
1280 dpidDst,
1281 numIntents,
1282 dirFile,
1283 onosIp,
1284 numMult="",
1285 appId="",
1286 report=True,
1287 options="" ):
kelvin8ec71442015-01-15 16:57:00 -08001288 """
andrewonlabb66dfa12014-12-02 15:51:10 -05001289 Description:
kelvin8ec71442015-01-15 16:57:00 -08001290 Use the linux prompt to push test intents to
andrewonlabb66dfa12014-12-02 15:51:10 -05001291 better parallelize the results than the CLI
1292 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001293 * dpidSrc: specify source dpid
1294 * dpidDst: specify destination dpid
1295 * numIntents: specify number of intents to push
1296 * dirFile: specify directory and file name to save
andrewonlabb66dfa12014-12-02 15:51:10 -05001297 results
kelvin-onlabd3b64892015-01-20 13:26:24 -08001298 * onosIp: specify the IP of ONOS to install on
kelvin8ec71442015-01-15 16:57:00 -08001299 NOTE:
andrewonlabb66dfa12014-12-02 15:51:10 -05001300 You must invoke this command at linux shell prompt
kelvin8ec71442015-01-15 16:57:00 -08001301 """
1302 try:
1303 # Create the string to sendline
andrewonlabaedc8332014-12-04 12:43:03 -05001304 if options:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001305 baseCmd = "onos " + str( onosIp ) + " push-test-intents " +\
kelvin8ec71442015-01-15 16:57:00 -08001306 options + " "
andrewonlabaedc8332014-12-04 12:43:03 -05001307 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001308 baseCmd = "onos " + str( onosIp ) + " push-test-intents "
kelvin8ec71442015-01-15 16:57:00 -08001309
kelvin-onlabd3b64892015-01-20 13:26:24 -08001310 addDpid = baseCmd + str( dpidSrc ) + " " + str( dpidDst )
1311 if not numMult:
1312 addIntents = addDpid + " " + str( numIntents )
1313 elif numMult:
1314 addIntents = addDpid + " " + str( numIntents ) + " " +\
1315 str( numMult )
1316 if appId:
1317 addApp = addIntents + " " + str( appId )
andrewonlabb66dfa12014-12-02 15:51:10 -05001318 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001319 addApp = addIntents
andrewonlabb66dfa12014-12-02 15:51:10 -05001320
andrewonlabaedc8332014-12-04 12:43:03 -05001321 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001322 sendCmd = addApp + " > " + str( dirFile ) + " &"
andrewonlabaedc8332014-12-04 12:43:03 -05001323 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001324 sendCmd = addApp + " &"
1325 main.log.info( "Send cmd: " + sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001326
kelvin-onlabd3b64892015-01-20 13:26:24 -08001327 self.handle.sendline( sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001328
1329 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001330 main.log.error( self.name + ": EOF exception found" )
1331 main.log.error( self.name + ": " + self.handle.before )
andrewonlabb66dfa12014-12-02 15:51:10 -05001332 main.cleanup()
1333 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001334 except Exception:
1335 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabb66dfa12014-12-02 15:51:10 -05001336 main.cleanup()
kelvin8ec71442015-01-15 16:57:00 -08001337 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001338
kelvin-onlabd3b64892015-01-20 13:26:24 -08001339 def getTopology( self, topologyOutput ):
kelvin8ec71442015-01-15 16:57:00 -08001340 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001341 Definition:
1342 Loads a json topology output
1343 Return:
1344 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -08001345 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001346 import json
Jon Hall77f53ce2014-10-13 18:02:06 -04001347 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001348 # either onos:topology or 'topology' will work in CLI
1349 topology = json.loads(topologyOutput)
1350 print topology
Jon Hall77f53ce2014-10-13 18:02:06 -04001351 return topology
1352 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001353 main.log.error( self.name + ": EOF exception found" )
1354 main.log.error( self.name + ": " + self.handle.before )
Jon Hall77f53ce2014-10-13 18:02:06 -04001355 main.cleanup()
1356 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001357 except Exception:
1358 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall77f53ce2014-10-13 18:02:06 -04001359 main.cleanup()
1360 main.exit()
1361
kelvin-onlabd3b64892015-01-20 13:26:24 -08001362 def checkStatus(
1363 self,
1364 topologyResult,
1365 numoswitch,
1366 numolink,
1367 logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08001368 """
Jon Hallefbd9792015-03-05 16:11:36 -08001369 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08001370 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08001371 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08001372
Jon Hall77f53ce2014-10-13 18:02:06 -04001373 Params: ip = ip used for the onos cli
1374 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08001375 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08001376 logLevel = level to log to.
1377 Currently accepts 'info', 'warn' and 'report'
Jon Hall77f53ce2014-10-13 18:02:06 -04001378
1379
kelvin-onlabd3b64892015-01-20 13:26:24 -08001380 logLevel can
Jon Hall77f53ce2014-10-13 18:02:06 -04001381
Jon Hallefbd9792015-03-05 16:11:36 -08001382 Returns: main.TRUE if the number of switches and links are correct,
1383 main.FALSE if the number of switches and links is incorrect,
Jon Hall77f53ce2014-10-13 18:02:06 -04001384 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08001385 """
Jon Hall77f53ce2014-10-13 18:02:06 -04001386 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001387 topology = self.getTopology( topologyResult )
Jon Hall77f53ce2014-10-13 18:02:06 -04001388 if topology == {}:
1389 return main.ERROR
1390 output = ""
kelvin8ec71442015-01-15 16:57:00 -08001391 # Is the number of switches is what we expected
shahshreya234a1682015-05-27 15:41:56 -07001392 devices = topology.get( 'devices', False )
1393 links = topology.get( 'links', False )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001394 if not devices or not links:
Jon Hall77f53ce2014-10-13 18:02:06 -04001395 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08001396 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08001397 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08001398 linkCheck = ( int( links ) == int( numolink ) )
Jon Hallefbd9792015-03-05 16:11:36 -08001399 if switchCheck and linkCheck:
kelvin8ec71442015-01-15 16:57:00 -08001400 # We expected the correct numbers
Jon Hall77f53ce2014-10-13 18:02:06 -04001401 output = output + "The number of links and switches match "\
kelvin8ec71442015-01-15 16:57:00 -08001402 + "what was expected"
Jon Hall77f53ce2014-10-13 18:02:06 -04001403 result = main.TRUE
1404 else:
1405 output = output + \
Jon Hall274b6642015-02-17 11:57:17 -08001406 "The number of links and switches does not match " + \
1407 "what was expected"
Jon Hall77f53ce2014-10-13 18:02:06 -04001408 result = main.FALSE
Jon Hallefbd9792015-03-05 16:11:36 -08001409 output = output + "\n ONOS sees %i devices" % int( devices )
1410 output = output + " (%i expected) " % int( numoswitch )
Jon Hall274b6642015-02-17 11:57:17 -08001411 output = output + "and %i links " % int( links )
1412 output = output + "(%i expected)" % int( numolink )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001413 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08001414 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001415 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08001416 main.log.warn( output )
Jon Hall77f53ce2014-10-13 18:02:06 -04001417 else:
kelvin8ec71442015-01-15 16:57:00 -08001418 main.log.info( output )
1419 return result
Jon Hall77f53ce2014-10-13 18:02:06 -04001420 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001421 main.log.error( self.name + ": EOF exception found" )
1422 main.log.error( self.name + ": " + self.handle.before )
Jon Hall77f53ce2014-10-13 18:02:06 -04001423 main.cleanup()
1424 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001425 except Exception:
1426 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall77f53ce2014-10-13 18:02:06 -04001427 main.cleanup()
1428 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001429
kelvin-onlabd3b64892015-01-20 13:26:24 -08001430 def tsharkPcap( self, interface, dirFile ):
kelvin8ec71442015-01-15 16:57:00 -08001431 """
andrewonlab970399c2014-11-07 13:09:32 -05001432 Capture all packet activity and store in specified
1433 directory/file
1434
1435 Required:
1436 * interface: interface to capture
1437 * dir: directory/filename to store pcap
kelvin8ec71442015-01-15 16:57:00 -08001438 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001439 try:
1440 self.handle.sendline( "" )
1441 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001442
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001443 self.handle.sendline( "tshark -i " + str( interface ) + " -t e -w " + str( dirFile ) + " &" )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001444 self.handle.sendline( "\n" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001445 self.handle.expect( "Capturing on" )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001446 self.handle.sendline( "\n" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001447 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001448
Jon Hallfebb1c72015-03-05 13:30:09 -08001449 main.log.info( "Tshark started capturing files on " +
1450 str( interface ) + " and saving to directory: " +
1451 str( dirFile ) )
1452 except pexpect.EOF:
1453 main.log.error( self.name + ": EOF exception found" )
1454 main.log.error( self.name + ": " + self.handle.before )
1455 main.cleanup()
1456 main.exit()
1457 except Exception:
1458 main.log.exception( self.name + ": Uncaught exception!" )
1459 main.cleanup()
1460 main.exit()
Shreya Shaha73aaad2014-10-27 18:03:09 -04001461
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001462 def onosTopoCfg( self, onosIp, jsonFile ):
kelvin8ec71442015-01-15 16:57:00 -08001463 """
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001464 Description:
1465 Execute onos-topo-cfg command
1466 Required:
1467 onosIp - IP of the onos node you want to send the json to
1468 jsonFile - File path of the json file
1469 Return:
1470 Returns main.TRUE if the command is successfull; Returns
1471 main.FALSE if there was an error
kelvin8ec71442015-01-15 16:57:00 -08001472 """
shahshreyae6c7cf42014-11-26 16:39:01 -08001473 try:
kelvin8ec71442015-01-15 16:57:00 -08001474 self.handle.sendline( "" )
1475 self.handle.expect( "\$" )
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001476 cmd = "onos-topo-cfg "
1477 self.handle.sendline( cmd + str( onosIp ) + " " + jsonFile )
1478 handle = self.handle.before
1479 print handle
1480 if "Error" in handle:
1481 main.log.error( self.name + ": " + self.handle.before )
1482 return main.FALSE
1483 else:
1484 self.handle.expect( "\$" )
1485 return main.TRUE
1486
Jon Hallfebb1c72015-03-05 13:30:09 -08001487 except pexpect.EOF:
1488 main.log.error( self.name + ": EOF exception found" )
1489 main.log.error( self.name + ": " + self.handle.before )
1490 main.cleanup()
1491 main.exit()
1492 except Exception:
1493 main.log.exception( self.name + ": Uncaught exception!" )
1494 main.cleanup()
1495 main.exit()
kelvin8ec71442015-01-15 16:57:00 -08001496
jenkins1e99e7b2015-04-02 18:15:39 -07001497 def tsharkGrep( self, grep, directory, interface='eth0', grepOptions='' ):
kelvin8ec71442015-01-15 16:57:00 -08001498 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001499 Required:
kelvin8ec71442015-01-15 16:57:00 -08001500 * grep string
andrewonlabba44bcf2014-10-16 16:54:41 -04001501 * directory to store results
1502 Optional:
1503 * interface - default: eth0
Jon Hall4ba53f02015-07-29 13:07:41 -07001504 * grepOptions - options for grep
andrewonlabba44bcf2014-10-16 16:54:41 -04001505 Description:
1506 Uses tshark command to grep specific group of packets
1507 and stores the results to specified directory.
kelvin8ec71442015-01-15 16:57:00 -08001508 The timestamp is hardcoded to be in epoch
1509 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001510 try:
1511 self.handle.sendline( "" )
1512 self.handle.expect( "\$" )
1513 self.handle.sendline( "" )
jenkins1e99e7b2015-04-02 18:15:39 -07001514 if grepOptions:
1515 grepStr = "grep "+str(grepOptions)
1516 else:
1517 grepStr = "grep"
Jon Hall4ba53f02015-07-29 13:07:41 -07001518
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001519 cmd = (
1520 "sudo tshark -i " +
Jon Hallfebb1c72015-03-05 13:30:09 -08001521 str( interface ) +
jenkins1e99e7b2015-04-02 18:15:39 -07001522 " -t e | " +
1523 grepStr + " --line-buffered \"" +
Jon Hallfebb1c72015-03-05 13:30:09 -08001524 str(grep) +
1525 "\" >" +
1526 directory +
1527 " &" )
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001528 self.handle.sendline(cmd)
1529 main.log.info(cmd)
Jon Hallfebb1c72015-03-05 13:30:09 -08001530 self.handle.expect( "Capturing on" )
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001531 self.handle.sendline( "\n" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001532 self.handle.expect( "\$" )
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
kelvin-onlabd3b64892015-01-20 13:26:24 -08001543 def tsharkStop( self ):
kelvin8ec71442015-01-15 16:57:00 -08001544 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001545 Removes wireshark files from /tmp and kills all tshark processes
kelvin8ec71442015-01-15 16:57:00 -08001546 """
1547 # Remove all pcap from previous captures
Jon Hallfebb1c72015-03-05 13:30:09 -08001548 try:
1549 self.execute( cmd="sudo rm /tmp/wireshark*" )
1550 self.handle.sendline( "" )
Jon Hallefbd9792015-03-05 16:11:36 -08001551 self.handle.sendline( "sudo kill -9 `ps -ef | grep \"tshark -i\"" +
1552 " | grep -v grep | awk '{print $2}'`" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001553 self.handle.sendline( "" )
1554 main.log.info( "Tshark stopped" )
1555 except pexpect.EOF:
1556 main.log.error( self.name + ": EOF exception found" )
1557 main.log.error( self.name + ": " + self.handle.before )
1558 main.cleanup()
1559 main.exit()
1560 except Exception:
1561 main.log.exception( self.name + ": Uncaught exception!" )
1562 main.cleanup()
1563 main.exit()
1564
kelvin8ec71442015-01-15 16:57:00 -08001565 def ptpd( self, args ):
1566 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001567 Initiate ptp with user-specified args.
1568 Required:
1569 * args: specify string of args after command
1570 'sudo ptpd'
kelvin8ec71442015-01-15 16:57:00 -08001571 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001572 try:
kelvin8ec71442015-01-15 16:57:00 -08001573 self.handle.sendline( "sudo ptpd " + str( args ) )
1574 i = self.handle.expect( [
andrewonlab0c38a4a2014-10-28 18:35:35 -04001575 "Multiple",
1576 "Error",
kelvin8ec71442015-01-15 16:57:00 -08001577 "\$" ] )
1578 self.handle.expect( "\$" )
andrewonlabba44bcf2014-10-16 16:54:41 -04001579
andrewonlab0c38a4a2014-10-28 18:35:35 -04001580 if i == 0:
1581 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001582 main.log.info( "ptpd returned an error: " +
1583 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001584 return handle
1585 elif i == 1:
1586 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001587 main.log.error( "ptpd returned an error: " +
1588 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001589 return handle
1590 else:
1591 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -08001592
andrewonlab0c38a4a2014-10-28 18:35:35 -04001593 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001594 main.log.error( self.name + ": EOF exception found" )
1595 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001596 main.cleanup()
1597 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001598 except Exception:
1599 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001600 main.cleanup()
1601 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001602
kelvin-onlabd3b64892015-01-20 13:26:24 -08001603 def cpLogsToDir( self, logToCopy,
Jon Hallefbd9792015-03-05 16:11:36 -08001604 destDir, copyFileName="" ):
kelvin8ec71442015-01-15 16:57:00 -08001605 """
1606 Copies logs to a desired directory.
andrewonlab5d7a8f32014-11-10 13:07:56 -05001607 Current implementation of ONOS deletes its karaf
1608 logs on every iteration. For debugging purposes,
kelvin8ec71442015-01-15 16:57:00 -08001609 you may want to use this function to capture
1610 certain karaf logs. ( or any other logs if needed )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001611 Localtime will be attached to the filename
1612
1613 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001614 * logToCopy: specify directory and log name to
andrewonlab5d7a8f32014-11-10 13:07:56 -05001615 copy.
kelvin8ec71442015-01-15 16:57:00 -08001616 ex ) /opt/onos/log/karaf.log.1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001617 For copying multiple files, leave copyFileName
1618 empty and only specify destDir -
kelvin8ec71442015-01-15 16:57:00 -08001619 ex ) /opt/onos/log/karaf*
kelvin-onlabd3b64892015-01-20 13:26:24 -08001620 * destDir: specify directory to copy to.
kelvin8ec71442015-01-15 16:57:00 -08001621 ex ) /tmp/
1622 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001623 * copyFileName: If you want to rename the log
1624 file, specify copyFileName. This will not work
andrewonlab5d7a8f32014-11-10 13:07:56 -05001625 with multiple file copying
kelvin8ec71442015-01-15 16:57:00 -08001626 """
andrewonlab5d7a8f32014-11-10 13:07:56 -05001627 try:
kelvin8ec71442015-01-15 16:57:00 -08001628 localtime = time.strftime( '%x %X' )
1629 localtime = localtime.replace( "/", "" )
1630 localtime = localtime.replace( " ", "_" )
1631 localtime = localtime.replace( ":", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001632 if destDir[ -1: ] != "/":
1633 destDir += "/"
andrewonlab5d7a8f32014-11-10 13:07:56 -05001634
kelvin-onlabd3b64892015-01-20 13:26:24 -08001635 if copyFileName:
Jon Hallfebb1c72015-03-05 13:30:09 -08001636 self.handle.sendline( "cp " + str( logToCopy ) + " " +
1637 str( destDir ) + str( copyFileName ) +
1638 localtime )
kelvin8ec71442015-01-15 16:57:00 -08001639 self.handle.expect( "cp" )
1640 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001641 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001642 self.handle.sendline( "cp " + str( logToCopy ) +
1643 " " + str( destDir ) )
kelvin8ec71442015-01-15 16:57:00 -08001644 self.handle.expect( "cp" )
1645 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001646
kelvin8ec71442015-01-15 16:57:00 -08001647 return self.handle.before
1648
1649 except pexpect.EOF:
1650 main.log.error( "Copying files failed" )
1651 main.log.error( self.name + ": EOF exception found" )
1652 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001653 except Exception:
1654 main.log.exception( "Copying files failed" )
1655
Jon Hall16b72c42015-05-20 10:23:36 -07001656 def checkLogs( self, onosIp, restart=False):
kelvin8ec71442015-01-15 16:57:00 -08001657 """
Jon Hall94fd0472014-12-08 11:52:42 -08001658 runs onos-check-logs on the given onos node
Jon Hall80daded2015-05-27 16:07:00 -07001659 If restart is True, use the old version of onos-check-logs which
1660 does not print the full stacktrace, but shows the entire log file,
1661 including across restarts
Jon Hall94fd0472014-12-08 11:52:42 -08001662 returns the response
kelvin8ec71442015-01-15 16:57:00 -08001663 """
Jon Hall94fd0472014-12-08 11:52:42 -08001664 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001665 cmd = "onos-check-logs " + str( onosIp )
Jon Hall16b72c42015-05-20 10:23:36 -07001666 if restart:
1667 cmd += " old"
kelvin8ec71442015-01-15 16:57:00 -08001668 self.handle.sendline( cmd )
1669 self.handle.expect( cmd )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001670 self.handle.expect( "\$ " )
Jon Hall94fd0472014-12-08 11:52:42 -08001671 response = self.handle.before
1672 return response
1673 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001674 main.log.error( "Lost ssh connection" )
1675 main.log.error( self.name + ": EOF exception found" )
1676 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001677 except Exception:
1678 main.log.exception( self.name + ": Uncaught exception!" )
1679 main.cleanup()
1680 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -08001681
kelvin-onlabd3b64892015-01-20 13:26:24 -08001682 def onosStatus( self, node="" ):
kelvin8ec71442015-01-15 16:57:00 -08001683 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001684 Calls onos command: 'onos-service [<node-ip>] status'
kelvin8ec71442015-01-15 16:57:00 -08001685 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001686 try:
kelvin8ec71442015-01-15 16:57:00 -08001687 self.handle.sendline( "" )
1688 self.handle.expect( "\$" )
1689 self.handle.sendline( "onos-service " + str( node ) +
1690 " status" )
1691 i = self.handle.expect( [
You Wangef1e6572016-03-08 12:53:18 -08001692 "start/running",
You Wang7bd83062016-03-01 11:50:00 -08001693 "Running ...",
You Wangef1e6572016-03-08 12:53:18 -08001694 "stop/waiting",
You Wang7bd83062016-03-01 11:50:00 -08001695 "Not Running ...",
kelvin8ec71442015-01-15 16:57:00 -08001696 pexpect.TIMEOUT ], timeout=120 )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001697
You Wangef1e6572016-03-08 12:53:18 -08001698 if i == 0 or i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001699 main.log.info( "ONOS is running" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001700 return main.TRUE
You Wangef1e6572016-03-08 12:53:18 -08001701 elif i == 2 or i == 3:
kelvin8ec71442015-01-15 16:57:00 -08001702 main.log.info( "ONOS is stopped" )
kelvin8ec71442015-01-15 16:57:00 -08001703 main.log.error( "ONOS service failed to check the status" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001704 main.cleanup()
1705 main.exit()
1706 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001707 main.log.error( self.name + ": EOF exception found" )
1708 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001709 main.cleanup()
1710 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001711 except Exception:
1712 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001713 main.cleanup()
1714 main.exit()
Jon Hall21270ac2015-02-16 17:59:55 -08001715
Jon Hall63604932015-02-26 17:09:50 -08001716 def setIpTables( self, ip, port='', action='add', packet_type='',
1717 direction='INPUT', rule='DROP', states=True ):
Jon Hallefbd9792015-03-05 16:11:36 -08001718 """
Jon Hall21270ac2015-02-16 17:59:55 -08001719 Description:
1720 add or remove iptables rule to DROP (default) packets from
1721 specific IP and PORT
1722 Usage:
1723 * specify action ('add' or 'remove')
1724 when removing, pass in the same argument as you would add. It will
1725 delete that specific rule.
1726 * specify the ip to block
1727 * specify the destination port to block (defaults to all ports)
1728 * optional packet type to block (default tcp)
1729 * optional iptables rule (default DROP)
1730 * optional direction to block (default 'INPUT')
Jon Hall63604932015-02-26 17:09:50 -08001731 * States boolean toggles adding all supported tcp states to the
1732 firewall rule
Jon Hall21270ac2015-02-16 17:59:55 -08001733 Returns:
1734 main.TRUE on success or
1735 main.FALSE if given invalid input or
1736 main.ERROR if there is an error in response from iptables
1737 WARNING:
1738 * This function uses root privilege iptables command which may result
1739 in unwanted network errors. USE WITH CAUTION
Jon Hallefbd9792015-03-05 16:11:36 -08001740 """
Jon Hall21270ac2015-02-16 17:59:55 -08001741
1742 # NOTE*********
1743 # The strict checking methods of this driver function is intentional
1744 # to discourage any misuse or error of iptables, which can cause
1745 # severe network errors
1746 # *************
1747
1748 # NOTE: Sleep needed to give some time for rule to be added and
1749 # registered to the instance. If you are calling this function
1750 # multiple times this sleep will prevent any errors.
1751 # DO NOT REMOVE
Jon Hall63604932015-02-26 17:09:50 -08001752 # time.sleep( 5 )
Jon Hall21270ac2015-02-16 17:59:55 -08001753 try:
1754 # input validation
1755 action_type = action.lower()
1756 rule = rule.upper()
1757 direction = direction.upper()
1758 if action_type != 'add' and action_type != 'remove':
1759 main.log.error( "Invalid action type. Use 'add' or "
1760 "'remove' table rule" )
1761 if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
1762 # NOTE Currently only supports rules DROP, ACCEPT, and LOG
1763 main.log.error( "Invalid rule. Valid rules are 'DROP' or "
1764 "'ACCEPT' or 'LOG' only." )
1765 if direction != 'INPUT' and direction != 'OUTPUT':
1766 # NOTE currently only supports rules INPUT and OUPTUT
1767 main.log.error( "Invalid rule. Valid directions are"
1768 " 'OUTPUT' or 'INPUT'" )
1769 return main.FALSE
1770 return main.FALSE
1771 return main.FALSE
1772 if action_type == 'add':
1773 # -A is the 'append' action of iptables
1774 actionFlag = '-A'
1775 elif action_type == 'remove':
1776 # -D is the 'delete' rule of iptables
1777 actionFlag = '-D'
1778 self.handle.sendline( "" )
1779 self.handle.expect( "\$" )
1780 cmd = "sudo iptables " + actionFlag + " " +\
1781 direction +\
Jon Hall21270ac2015-02-16 17:59:55 -08001782 " -s " + str( ip )
Jon Hall63604932015-02-26 17:09:50 -08001783 # " -p " + str( packet_type ) +\
1784 if packet_type:
1785 cmd += " -p " + str( packet_type )
Jon Hall21270ac2015-02-16 17:59:55 -08001786 if port:
1787 cmd += " --dport " + str( port )
Jon Hall63604932015-02-26 17:09:50 -08001788 if states:
1789 cmd += " -m state --state="
1790 #FIXME- Allow user to configure which states to block
1791 cmd += "INVALID,ESTABLISHED,NEW,RELATED,UNTRACKED"
Jon Hall21270ac2015-02-16 17:59:55 -08001792 cmd += " -j " + str( rule )
1793
1794 self.handle.sendline( cmd )
1795 self.handle.expect( "\$" )
1796 main.log.warn( self.handle.before )
1797
1798 info_string = "On " + str( self.name )
1799 info_string += " " + str( action_type )
1800 info_string += " iptable rule [ "
1801 info_string += " IP: " + str( ip )
1802 info_string += " Port: " + str( port )
1803 info_string += " Rule: " + str( rule )
1804 info_string += " Direction: " + str( direction ) + " ]"
1805 main.log.info( info_string )
1806 return main.TRUE
1807 except pexpect.TIMEOUT:
1808 main.log.exception( self.name + ": Timeout exception in "
1809 "setIpTables function" )
1810 return main.ERROR
1811 except pexpect.EOF:
1812 main.log.error( self.name + ": EOF exception found" )
1813 main.log.error( self.name + ": " + self.handle.before )
1814 main.cleanup()
1815 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001816 except Exception:
1817 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall21270ac2015-02-16 17:59:55 -08001818 main.cleanup()
1819 main.exit()
1820
Jon Hall0468b042015-02-19 19:08:21 -08001821 def detailed_status(self, log_filename):
Jon Hallefbd9792015-03-05 16:11:36 -08001822 """
Jon Hall0468b042015-02-19 19:08:21 -08001823 This method is used by STS to check the status of the controller
1824 Reports RUNNING, STARTING, STOPPED, FROZEN, ERROR (and reason)
Jon Hallefbd9792015-03-05 16:11:36 -08001825 """
Jon Hall0468b042015-02-19 19:08:21 -08001826 import re
1827 try:
1828 self.handle.sendline( "" )
1829 self.handle.expect( "\$" )
1830 self.handle.sendline( "cd " + self.home )
1831 self.handle.expect( "\$" )
1832 self.handle.sendline( "service onos status" )
1833 self.handle.expect( "\$" )
1834 response = self.handle.before
1835 if re.search( "onos start/running", response ):
1836 # onos start/running, process 10457
1837 return 'RUNNING'
1838 # FIXME: Implement this case
1839 # elif re.search( pattern, response ):
1840 # return 'STARTING'
1841 elif re.search( "onos stop/", response ):
1842 # onos stop/waiting
1843 # FIXME handle this differently?: onos stop/pre-stop
1844 return 'STOPPED'
1845 # FIXME: Implement this case
1846 # elif re.search( pattern, response ):
1847 # return 'FROZEN'
1848 else:
1849 main.log.warn( self.name +
Jon Hallefbd9792015-03-05 16:11:36 -08001850 " WARNING: status received unknown response" )
Jon Hall0468b042015-02-19 19:08:21 -08001851 main.log.warn( response )
1852 return 'ERROR', "Unknown response: %s" % response
1853 except pexpect.TIMEOUT:
1854 main.log.exception( self.name + ": Timeout exception in "
1855 "setIpTables function" )
1856 return 'ERROR', "Pexpect Timeout"
1857 except pexpect.EOF:
1858 main.log.error( self.name + ": EOF exception found" )
1859 main.log.error( self.name + ": " + self.handle.before )
1860 main.cleanup()
1861 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001862 except Exception:
1863 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall0468b042015-02-19 19:08:21 -08001864 main.cleanup()
1865 main.exit()
1866
andrew@onlab.us3b087132015-03-11 15:00:08 -07001867 def createLinkGraphFile( self, benchIp, ONOSIpList, deviceCount):
1868 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07001869 Create/formats the LinkGraph.cfg file based on arguments
1870 -only creates a linear topology and connects islands
1871 -evenly distributes devices
andrew@onlab.us3b087132015-03-11 15:00:08 -07001872 -must be called by ONOSbench
1873
Jon Hall4ba53f02015-07-29 13:07:41 -07001874 ONOSIpList - list of all of the node IPs to be used
1875
1876 deviceCount - number of switches to be assigned
andrew@onlab.us3b087132015-03-11 15:00:08 -07001877 '''
1878 main.log.step("Creating link graph configuration file." )
1879 linkGraphPath = self.home + "/tools/package/etc/linkGraph.cfg"
Jon Hall4ba53f02015-07-29 13:07:41 -07001880 tempFile = "/tmp/linkGraph.cfg"
andrew@onlab.us3b087132015-03-11 15:00:08 -07001881
1882 linkGraph = open(tempFile, 'w+')
1883 linkGraph.write("# NullLinkProvider topology description (config file).\n")
1884 linkGraph.write("# The NodeId is only added if the destination is another node's device.\n")
1885 linkGraph.write("# Bugs: Comments cannot be appended to a line to be read.\n")
Jon Hall4ba53f02015-07-29 13:07:41 -07001886
andrew@onlab.us3b087132015-03-11 15:00:08 -07001887 clusterCount = len(ONOSIpList)
Jon Hall4ba53f02015-07-29 13:07:41 -07001888
1889 if type(deviceCount) is int or type(deviceCount) is str:
andrew@onlab.us3b087132015-03-11 15:00:08 -07001890 deviceCount = int(deviceCount)
1891 switchList = [0]*(clusterCount+1)
1892 baselineSwitchCount = deviceCount/clusterCount
Jon Hall4ba53f02015-07-29 13:07:41 -07001893
andrew@onlab.us3b087132015-03-11 15:00:08 -07001894 for node in range(1, clusterCount + 1):
1895 switchList[node] = baselineSwitchCount
1896
1897 for node in range(1, (deviceCount%clusterCount)+1):
1898 switchList[node] += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07001899
andrew@onlab.us3b087132015-03-11 15:00:08 -07001900 if type(deviceCount) is list:
1901 main.log.info("Using provided device distribution")
1902 switchList = [0]
1903 for i in deviceCount:
1904 switchList.append(int(i))
1905
1906 tempList = ['0']
1907 tempList.extend(ONOSIpList)
1908 ONOSIpList = tempList
1909
1910 myPort = 6
1911 lastSwitch = 0
1912 for node in range(1, clusterCount+1):
1913 if switchList[node] == 0:
1914 continue
1915
1916 linkGraph.write("graph " + ONOSIpList[node] + " {\n")
Jon Hall4ba53f02015-07-29 13:07:41 -07001917
andrew@onlab.us3b087132015-03-11 15:00:08 -07001918 if node > 1:
1919 #connect to last device on previous node
Jon Hall4ba53f02015-07-29 13:07:41 -07001920 line = ("\t0:5 -> " + str(lastSwitch) + ":6:" + lastIp + "\n") #ONOSIpList[node-1]
1921 linkGraph.write(line)
1922
1923 lastSwitch = 0
1924 for switch in range (0, switchList[node]-1):
andrew@onlab.us3b087132015-03-11 15:00:08 -07001925 line = ""
1926 line = ("\t" + str(switch) + ":" + str(myPort))
1927 line += " -- "
1928 line += (str(switch+1) + ":" + str(myPort-1) + "\n")
1929 linkGraph.write(line)
Jon Hall4ba53f02015-07-29 13:07:41 -07001930 lastSwitch = switch+1
andrew@onlab.us3b087132015-03-11 15:00:08 -07001931 lastIp = ONOSIpList[node]
Jon Hall4ba53f02015-07-29 13:07:41 -07001932
andrew@onlab.us3b087132015-03-11 15:00:08 -07001933 #lastSwitch += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07001934 if node < (clusterCount):
andrew@onlab.us3b087132015-03-11 15:00:08 -07001935 #connect to first device on the next node
Jon Hall4ba53f02015-07-29 13:07:41 -07001936 line = ("\t" + str(lastSwitch) + ":6 -> 0:5:" + ONOSIpList[node+1] + "\n")
andrew@onlab.us3b087132015-03-11 15:00:08 -07001937 linkGraph.write(line)
Jon Hall4ba53f02015-07-29 13:07:41 -07001938
andrew@onlab.us3b087132015-03-11 15:00:08 -07001939 linkGraph.write("}\n")
1940 linkGraph.close()
1941
1942 #SCP
Jon Hall4ba53f02015-07-29 13:07:41 -07001943 os.system( "scp " + tempFile + " " + self.user_name + "@" + benchIp + ":" + linkGraphPath)
andrew@onlab.us3b087132015-03-11 15:00:08 -07001944 main.log.info("linkGraph.cfg creation complete")
1945
cameron@onlab.us75900962015-03-30 13:22:49 -07001946 def configNullDev( self, ONOSIpList, deviceCount, numPorts=10):
Jon Hall4ba53f02015-07-29 13:07:41 -07001947
andrew@onlab.us3b087132015-03-11 15:00:08 -07001948 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07001949 ONOSIpList = list of Ip addresses of nodes switches will be devided amongst
1950 deviceCount = number of switches to distribute, or list of values to use as custom distribution
cameron@onlab.us75900962015-03-30 13:22:49 -07001951 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 -07001952 '''
1953
cameron@onlab.us75900962015-03-30 13:22:49 -07001954 main.log.step("Configuring Null Device Provider" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07001955 clusterCount = len(ONOSIpList)
1956
Jon Hall4ba53f02015-07-29 13:07:41 -07001957 try:
1958
cameron@onlab.us75900962015-03-30 13:22:49 -07001959 if type(deviceCount) is int or type(deviceCount) is str:
1960 main.log.step("Creating device distribution")
1961 deviceCount = int(deviceCount)
1962 switchList = [0]*(clusterCount+1)
1963 baselineSwitchCount = deviceCount/clusterCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001964
cameron@onlab.us75900962015-03-30 13:22:49 -07001965 for node in range(1, clusterCount + 1):
1966 switchList[node] = baselineSwitchCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001967
cameron@onlab.us75900962015-03-30 13:22:49 -07001968 for node in range(1, (deviceCount%clusterCount)+1):
1969 switchList[node] += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07001970
1971 if type(deviceCount) is list:
1972 main.log.info("Using provided device distribution")
1973
1974 if len(deviceCount) == clusterCount:
cameron@onlab.us75900962015-03-30 13:22:49 -07001975 switchList = ['0']
1976 switchList.extend(deviceCount)
Jon Hall4ba53f02015-07-29 13:07:41 -07001977
1978 if len(deviceCount) == (clusterCount + 1):
1979 if deviceCount[0] == '0' or deviceCount[0] == 0:
cameron@onlab.us75900962015-03-30 13:22:49 -07001980 switchList = deviceCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001981
cameron@onlab.us75900962015-03-30 13:22:49 -07001982 assert len(switchList) == (clusterCount + 1)
Jon Hall4ba53f02015-07-29 13:07:41 -07001983
cameron@onlab.us75900962015-03-30 13:22:49 -07001984 except AssertionError:
Jon Hall4ba53f02015-07-29 13:07:41 -07001985 main.log.error( "Bad device/Ip list match")
cameron@onlab.us75900962015-03-30 13:22:49 -07001986 except TypeError:
1987 main.log.exception( self.name + ": Object not as expected" )
1988 return None
Jon Hall77ba41c2015-04-06 10:25:40 -07001989 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07001990 main.log.exception( self.name + ": Uncaught exception!" )
1991 main.cleanup()
1992 main.exit()
1993
andrew@onlab.us3b087132015-03-11 15:00:08 -07001994
1995 ONOSIp = [0]
1996 ONOSIp.extend(ONOSIpList)
Jon Hall4ba53f02015-07-29 13:07:41 -07001997
andrew@onlab.us3b087132015-03-11 15:00:08 -07001998 devicesString = "devConfigs = "
1999 for node in range(1, len(ONOSIp)):
2000 devicesString += (ONOSIp[node] + ":" + str(switchList[node] ))
2001 if node < clusterCount:
2002 devicesString += (",")
Jon Hall4ba53f02015-07-29 13:07:41 -07002003
2004 try:
cameron@onlab.us75900962015-03-30 13:22:49 -07002005 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider devConfigs " + devicesString )
2006 self.handle.expect(":~")
2007 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider numPorts " + str(numPorts) )
2008 self.handle.expect(":~")
andrew@onlab.us3b087132015-03-11 15:00:08 -07002009
cameron@onlab.us75900962015-03-30 13:22:49 -07002010 for i in range(10):
2011 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.device.impl.NullDeviceProvider")
2012 self.handle.expect(":~")
2013 verification = self.handle.before
2014 if (" value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification:
2015 break
2016 else:
2017 time.sleep(1)
andrew@onlab.us3b087132015-03-11 15:00:08 -07002018
cameron@onlab.us2cc8bf12015-04-02 14:12:30 -07002019 assert ("value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification
Jon Hall4ba53f02015-07-29 13:07:41 -07002020
cameron@onlab.us75900962015-03-30 13:22:49 -07002021 except AssertionError:
2022 main.log.error("Incorrect Config settings: " + verification)
Jon Hall77ba41c2015-04-06 10:25:40 -07002023 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002024 main.log.exception( self.name + ": Uncaught exception!" )
2025 main.cleanup()
2026 main.exit()
2027
Jon Hall4ba53f02015-07-29 13:07:41 -07002028 def configNullLink( self,fileName="/opt/onos/apache-karaf-3.0.3/etc/linkGraph.cfg", eventRate=0):
andrew@onlab.us3b087132015-03-11 15:00:08 -07002029 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07002030 fileName default is currently the same as the default on ONOS, specify alternate file if
cameron@onlab.us75900962015-03-30 13:22:49 -07002031 you want to use a different topology file than linkGraph.cfg
andrew@onlab.us3b087132015-03-11 15:00:08 -07002032 '''
2033
Jon Hall4ba53f02015-07-29 13:07:41 -07002034
2035 try:
2036 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider eventRate " + str(eventRate))
2037 self.handle.expect(":~")
cameron@onlab.us75900962015-03-30 13:22:49 -07002038 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider cfgFile " + fileName )
2039 self.handle.expect(":~")
Jon Hall4ba53f02015-07-29 13:07:41 -07002040
2041 for i in range(10):
2042 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.link.impl.NullLinkProvider")
cameron@onlab.us75900962015-03-30 13:22:49 -07002043 self.handle.expect(":~")
2044 verification = self.handle.before
Jon Hall4ba53f02015-07-29 13:07:41 -07002045 if (" value=" + str(eventRate)) in verification and (" value=" + fileName) in verification:
cameron@onlab.us75900962015-03-30 13:22:49 -07002046 break
Jon Hall4ba53f02015-07-29 13:07:41 -07002047 else:
cameron@onlab.us75900962015-03-30 13:22:49 -07002048 time.sleep(1)
Jon Hall4ba53f02015-07-29 13:07:41 -07002049
cameron@onlab.us75900962015-03-30 13:22:49 -07002050 assert ("value=" + str(eventRate)) in verification and (" value=" + fileName) in verification
Jon Hall4ba53f02015-07-29 13:07:41 -07002051
cameron@onlab.us75900962015-03-30 13:22:49 -07002052 except pexpect.EOF:
2053 main.log.error( self.name + ": EOF exception found" )
2054 main.log.error( self.name + ": " + self.handle.before )
2055 main.cleanup()
2056 main.exit()
cameron@onlab.us75900962015-03-30 13:22:49 -07002057 except AssertionError:
2058 main.log.info("Settings did not post to ONOS")
Jon Hall4ba53f02015-07-29 13:07:41 -07002059 main.log.error(varification)
Jon Hall77ba41c2015-04-06 10:25:40 -07002060 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002061 main.log.exception( self.name + ": Uncaught exception!" )
2062 main.log.error(varification)
2063 main.cleanup()
2064 main.exit()
andrew@onlab.us3b087132015-03-11 15:00:08 -07002065
kelvin-onlaba4074292015-07-09 15:19:49 -07002066 def getOnosIps( self ):
2067 """
2068 Get all onos IPs stored in
2069 """
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002070
kelvin-onlaba4074292015-07-09 15:19:49 -07002071 return sorted( self.onosIps.values() )
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002072
kelvin-onlaba4074292015-07-09 15:19:49 -07002073 def logReport( self, nodeIp, searchTerms, outputMode="s" ):
Jon Hallb4242222016-01-25 17:07:04 -08002074 """
2075 Searches the latest ONOS log file for the given search terms and
2076 prints the total occurances of each term. Returns to combined total of
2077 all occurances.
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002078
Jon Hallb4242222016-01-25 17:07:04 -08002079 Arguments:
2080 * nodeIp - The ip of the ONOS node where the log is located
2081 * searchTerms - A string to grep for or a list of strings to grep
2082 for in the ONOS log. Will print out the number of
2083 occurances for each term.
2084 Optional Arguments:
2085 * outputMode - 's' or 'd'. If 'd' will print the last 5 lines
2086 containing each search term as well as the total
2087 number of occurances of each term. Defaults to 's',
2088 which prints the simple output of just the number
2089 of occurances for each term.
2090 """
2091 try:
2092 main.log.info( " Log Report for {} ".format( nodeIp ).center( 70, '=' ) )
2093 if type( searchTerms ) is str:
2094 searchTerms = [searchTerms]
2095 numTerms = len( searchTerms )
2096 outputMode = outputMode.lower()
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002097
Jon Hallb4242222016-01-25 17:07:04 -08002098 totalHits = 0
2099 logLines = []
2100 for termIndex in range( numTerms ):
2101 term = searchTerms[termIndex]
2102 logLines.append( [term] )
2103 cmd = "onos-ssh " + nodeIp + " cat /opt/onos/log/karaf.log | grep " + term
2104 self.handle.sendline( cmd )
2105 self.handle.expect( ":~" )
2106 before = self.handle.before.splitlines()
2107 count = 0
2108 for line in before:
2109 if term in line and "grep" not in line:
2110 count += 1
2111 if before.index( line ) > ( len( before ) - 7 ):
2112 logLines[termIndex].append( line )
2113 main.log.info( "{}: {}".format( term, count ) )
2114 totalHits += count
2115 if termIndex == numTerms - 1:
2116 print "\n"
2117 if outputMode != "s":
2118 outputString = ""
2119 for term in logLines:
2120 outputString = term[0] + ": \n"
2121 for line in range( 1, len( term ) ):
2122 outputString += ( "\t" + term[line] + "\n" )
2123 if outputString != ( term[0] + ": \n" ):
2124 main.log.info( outputString )
2125 main.log.info( "=" * 70 )
2126 return totalHits
2127 except pexpect.EOF:
2128 main.log.error( self.name + ": EOF exception found" )
2129 main.log.error( self.name + ": " + self.handle.before )
2130 main.cleanup()
2131 main.exit()
2132 except pexpect.TIMEOUT:
2133 main.log.error( self.name + ": TIMEOUT exception found" )
2134 main.log.error( self.name + ": " + self.handle.before )
2135 main.cleanup()
2136 main.exit()
2137 except Exception:
2138 main.log.exception( self.name + ": Uncaught exception!" )
2139 main.cleanup()
2140 main.exit()
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002141
2142 def copyMininetFile( self, fileName, localPath, userName, ip,
2143 mnPath='~/mininet/custom/', timeout = 60 ):
2144 """
2145 Description:
2146 Copy mininet topology file from dependency folder in the test folder
2147 and paste it to the mininet machine's mininet/custom folder
2148 Required:
2149 fileName - Name of the topology file to copy
2150 localPath - File path of the mininet topology file
2151 userName - User name of the mininet machine to send the file to
2152 ip - Ip address of the mininet machine
2153 Optional:
2154 mnPath - of the mininet directory to send the file to
2155 Return:
2156 Return main.TRUE if successfully copied the file otherwise
2157 return main.FALSE
2158 """
2159
2160 try:
2161 cmd = "scp " + localPath + fileName + " " + userName + "@" + \
2162 str( ip ) + ":" + mnPath + fileName
2163
2164 self.handle.sendline( "" )
2165 self.handle.expect( "\$" )
2166
2167 main.log.info( self.name + ": Execute: " + cmd )
2168
2169 self.handle.sendline( cmd )
2170
2171 i = self.handle.expect( [ 'No such file',
2172 "100%",
2173 pexpect.TIMEOUT ] )
2174
2175 if i == 0:
2176 main.log.error( self.name + ": File " + fileName +
2177 " does not exist!" )
2178 return main.FALSE
2179
2180 if i == 1:
2181 main.log.info( self.name + ": File " + fileName +
2182 " has been copied!" )
2183 self.handle.sendline( "" )
2184 self.handle.expect( "\$" )
2185 return main.TRUE
2186
2187 except pexpect.EOF:
2188 main.log.error( self.name + ": EOF exception found" )
2189 main.log.error( self.name + ": " + self.handle.before )
2190 main.cleanup()
2191 main.exit()
2192 except pexpect.TIMEOUT:
2193 main.log.error( self.name + ": TIMEOUT exception found" )
2194 main.log.error( self.name + ": " + self.handle.before )
2195 main.cleanup()
2196 main.exit()
cameron@onlab.us78b89652015-07-08 15:21:03 -07002197
2198 def jvmSet(self, memory=8):
Jon Hall4ba53f02015-07-29 13:07:41 -07002199
cameron@onlab.us78b89652015-07-08 15:21:03 -07002200 import os
2201
2202 homeDir = os.path.expanduser('~')
2203 filename = "/onos/tools/package/bin/onos-service"
2204
2205 serviceConfig = open(homeDir + filename, 'w+')
2206 serviceConfig.write("#!/bin/bash\n ")
2207 serviceConfig.write("#------------------------------------- \n ")
2208 serviceConfig.write("# Starts ONOS Apache Karaf container\n ")
2209 serviceConfig.write("#------------------------------------- \n ")
2210 serviceConfig.write("#export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-7-openjdk-amd64/}\n ")
2211 serviceConfig.write("""export JAVA_OPTS="${JAVA_OPTS:--Xms""" + str(memory) + "G -Xmx" + str(memory) + """G}" \n """)
2212 serviceConfig.write("[ -d $ONOS_HOME ] && cd $ONOS_HOME || ONOS_HOME=$(dirname $0)/..\n")
2213 serviceConfig.write("""${ONOS_HOME}/apache-karaf-$KARAF_VERSION/bin/karaf "$@" \n """)
2214 serviceConfig.close()
2215
2216 def createDBFile(self, testData):
Jon Hall4ba53f02015-07-29 13:07:41 -07002217
cameron@onlab.us78b89652015-07-08 15:21:03 -07002218 filename = main.TEST + "DB"
2219 DBString = ""
Jon Hall4ba53f02015-07-29 13:07:41 -07002220
cameron@onlab.us78b89652015-07-08 15:21:03 -07002221 for item in testData:
Jon Hall4ba53f02015-07-29 13:07:41 -07002222 if type(item) is string:
cameron@onlab.us78b89652015-07-08 15:21:03 -07002223 item = "'" + item + "'"
2224 if testData.index(item) < len(testData-1):
2225 item += ","
Jon Hall4ba53f02015-07-29 13:07:41 -07002226 DBString += str(item)
cameron@onlab.us78b89652015-07-08 15:21:03 -07002227
2228 DBFile = open(filename, "a")
2229 DBFile.write(DBString)
2230 DBFile.close()
2231
Jon Hall4ba53f02015-07-29 13:07:41 -07002232 def verifySummary(self, ONOSIp,*deviceCount):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002233
2234 self.handle.sendline("onos " + ONOSIp + " summary")
2235 self.handle.expect(":~")
2236
2237 summaryStr = self.handle.before
2238 print "\nSummary\n==============\n" + summaryStr + "\n\n"
2239
2240 #passed = "SCC(s)=1" in summaryStr
2241 #if deviceCount:
2242 # passed = "devices=" + str(deviceCount) + "," not in summaryStr
2243
GlennRC772363b2015-08-25 13:05:57 -07002244 passed = False
cameron@onlab.us78b89652015-07-08 15:21:03 -07002245 if "SCC(s)=1," in summaryStr:
2246 passed = True
2247 print("Summary is verifed")
Jon Hall4ba53f02015-07-29 13:07:41 -07002248 else:
2249 print("Summary failed")
cameron@onlab.us78b89652015-07-08 15:21:03 -07002250
2251 if deviceCount:
2252 print" ============================="
2253 checkStr = "devices=" + str(deviceCount[0]) + ","
2254 print "Checkstr: " + checkStr
2255 if checkStr not in summaryStr:
2256 passed = False
Jon Hall4ba53f02015-07-29 13:07:41 -07002257 print("Device count failed")
2258 else:
2259 print "device count verified"
cameron@onlab.us78b89652015-07-08 15:21:03 -07002260
2261 return passed