blob: d0e95a58feeefc81d2d8fb9eadb5323fd79e7140 [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
kelvin8ec71442015-01-15 16:57:00 -0800189 and executed on any platform with Java 7 JRE.
190 """
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400191 try:
kelvin8ec71442015-01-15 16:57:00 -0800192 self.handle.sendline( "onos-package" )
193 self.handle.expect( "onos-package" )
pingping-lin57a56ce2015-05-20 16:43:48 -0700194 self.handle.expect( "tar.gz", opTimeout )
Jon Hall3b489db2015-10-05 14:38:37 -0700195 self.handle.expect( "\$" )
kelvin8ec71442015-01-15 16:57:00 -0800196 handle = str( self.handle.before )
197 main.log.info( "onos-package command returned: " +
198 handle )
199 # As long as the sendline does not time out,
200 # return true. However, be careful to interpret
201 # the results of the onos-package command return
andrewonlab0748d2a2014-10-09 13:24:17 -0400202 return main.TRUE
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400203
andrewonlab7735d852014-10-09 13:02:47 -0400204 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800205 main.log.error( self.name + ": EOF exception found" )
206 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -0800207 except Exception:
208 main.log.exception( "Failed to package ONOS" )
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400209 main.cleanup()
210 main.exit()
211
kelvin-onlabd3b64892015-01-20 13:26:24 -0800212 def onosBuild( self ):
kelvin8ec71442015-01-15 16:57:00 -0800213 """
andrewonlab8790abb2014-11-06 13:51:54 -0500214 Use the pre defined script to build onos via mvn
kelvin8ec71442015-01-15 16:57:00 -0800215 """
andrewonlab8790abb2014-11-06 13:51:54 -0500216 try:
kelvin8ec71442015-01-15 16:57:00 -0800217 self.handle.sendline( "onos-build" )
218 self.handle.expect( "onos-build" )
219 i = self.handle.expect( [
kelvin-onlabd3b64892015-01-20 13:26:24 -0800220 "BUILD SUCCESS",
221 "ERROR",
222 "BUILD FAILED" ],
223 timeout=120 )
kelvin8ec71442015-01-15 16:57:00 -0800224 handle = str( self.handle.before )
Jon Hall3b489db2015-10-05 14:38:37 -0700225 self.handle.expect( "\$" )
andrewonlab8790abb2014-11-06 13:51:54 -0500226
kelvin8ec71442015-01-15 16:57:00 -0800227 main.log.info( "onos-build command returned: " +
228 handle )
andrewonlab8790abb2014-11-06 13:51:54 -0500229
230 if i == 0:
231 return main.TRUE
232 else:
233 return handle
234
235 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800236 main.log.error( self.name + ": EOF exception found" )
237 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -0800238 except Exception:
239 main.log.exception( "Failed to build ONOS" )
andrewonlab8790abb2014-11-06 13:51:54 -0500240 main.cleanup()
241 main.exit()
242
shahshreya9f531fe2015-06-10 12:03:51 -0700243 def cleanInstall( self, skipTest=False, mciTimeout=600 ):
kelvin8ec71442015-01-15 16:57:00 -0800244 """
245 Runs mvn clean install in the root of the ONOS directory.
246 This will clean all ONOS artifacts then compile each module
shahshreya9f531fe2015-06-10 12:03:51 -0700247 Optional:
248 skipTest - Does "-DskipTests -Dcheckstyle.skip -U -T 1C" which
249 skip the test. This will make the building faster.
250 Disregarding the credibility of the build
kelvin8ec71442015-01-15 16:57:00 -0800251 Returns: main.TRUE on success
Jon Hallde9d9aa2014-10-08 20:36:02 -0400252 On Failure, exits the test
kelvin8ec71442015-01-15 16:57:00 -0800253 """
Jon Hallde9d9aa2014-10-08 20:36:02 -0400254 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800255 main.log.info( "Running 'mvn clean install' on " +
256 str( self.name ) +
kelvin8ec71442015-01-15 16:57:00 -0800257 ". This may take some time." )
258 self.handle.sendline( "cd " + self.home )
259 self.handle.expect( "\$" )
Jon Hallea7818b2014-10-09 14:30:59 -0400260
kelvin8ec71442015-01-15 16:57:00 -0800261 self.handle.sendline( "" )
262 self.handle.expect( "\$" )
shahshreya9f531fe2015-06-10 12:03:51 -0700263
264 if not skipTest:
265 self.handle.sendline( "mvn clean install" )
266 self.handle.expect( "mvn clean install" )
267 else:
268 self.handle.sendline( "mvn clean install -DskipTests" +
269 " -Dcheckstyle.skip -U -T 1C" )
270 self.handle.expect( "mvn clean install -DskipTests" +
271 " -Dcheckstyle.skip -U -T 1C" )
kelvin8ec71442015-01-15 16:57:00 -0800272 while True:
273 i = self.handle.expect( [
Jon Hall274b6642015-02-17 11:57:17 -0800274 'There\sis\sinsufficient\smemory\sfor\sthe\sJava\s' +
Jon Hallefbd9792015-03-05 16:11:36 -0800275 'Runtime\sEnvironment\sto\scontinue',
Jon Hallde9d9aa2014-10-08 20:36:02 -0400276 'BUILD\sFAILURE',
277 'BUILD\sSUCCESS',
Jon Halle94919c2015-03-23 11:42:57 -0700278 'onos\$', #TODO: fix this to be more generic?
Jon Hallde9d9aa2014-10-08 20:36:02 -0400279 'ONOS\$',
pingping-lin57a56ce2015-05-20 16:43:48 -0700280 pexpect.TIMEOUT ], mciTimeout )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400281 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800282 main.log.error( self.name + ":There is insufficient memory \
283 for the Java Runtime Environment to continue." )
284 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400285 main.cleanup()
286 main.exit()
287 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800288 main.log.error( self.name + ": Build failure!" )
289 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400290 main.cleanup()
291 main.exit()
292 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800293 main.log.info( self.name + ": Build success!" )
Jon Halle94919c2015-03-23 11:42:57 -0700294 elif i == 3 or i == 4:
kelvin8ec71442015-01-15 16:57:00 -0800295 main.log.info( self.name + ": Build complete" )
296 # Print the build time
Jon Hallf8ef52c2014-10-09 19:37:33 -0400297 for line in self.handle.before.splitlines():
298 if "Total time:" in line:
kelvin8ec71442015-01-15 16:57:00 -0800299 main.log.info( line )
300 self.handle.sendline( "" )
301 self.handle.expect( "\$", timeout=60 )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400302 return main.TRUE
Jon Halle94919c2015-03-23 11:42:57 -0700303 elif i == 5:
kelvin8ec71442015-01-15 16:57:00 -0800304 main.log.error(
305 self.name +
306 ": mvn clean install TIMEOUT!" )
307 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400308 main.cleanup()
309 main.exit()
310 else:
Jon Hall274b6642015-02-17 11:57:17 -0800311 main.log.error( self.name + ": unexpected response from " +
Jon Hallefbd9792015-03-05 16:11:36 -0800312 "mvn clean install" )
kelvin8ec71442015-01-15 16:57:00 -0800313 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400314 main.cleanup()
315 main.exit()
316 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800317 main.log.error( self.name + ": EOF exception found" )
318 main.log.error( self.name + ": " + self.handle.before )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400319 main.cleanup()
320 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800321 except Exception:
322 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400323 main.cleanup()
324 main.exit()
Jon Hallacabffd2014-10-09 12:36:53 -0400325
Jon Hall61282e32015-03-19 11:34:11 -0700326 def gitPull( self, comp1="", fastForward=True ):
kelvin8ec71442015-01-15 16:57:00 -0800327 """
Jon Hallacabffd2014-10-09 12:36:53 -0400328 Assumes that "git pull" works without login
Jon Hall47a93fb2015-01-06 16:46:06 -0800329
Jon Hall61282e32015-03-19 11:34:11 -0700330 If the fastForward boolean is set to true, only git pulls that can
331 be fast forwarded will be performed. IE if you have not local commits
332 in your branch.
333
Jon Hallacabffd2014-10-09 12:36:53 -0400334 This function will perform a git pull on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800335 If used as gitPull( "NODE" ) it will do git pull + NODE. This is
Jon Hallacabffd2014-10-09 12:36:53 -0400336 for the purpose of pulling from other nodes if necessary.
337
Jon Hall47a93fb2015-01-06 16:46:06 -0800338 Otherwise, this function will perform a git pull in the
Jon Hallacabffd2014-10-09 12:36:53 -0400339 ONOS repository. If it has any problems, it will return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -0800340 If it successfully does a gitPull, it will return a 1 ( main.TRUE )
Shreya Shahee15f6c2014-10-28 18:12:30 -0400341 If it has no updates, it will return 3.
Jon Hallacabffd2014-10-09 12:36:53 -0400342
kelvin8ec71442015-01-15 16:57:00 -0800343 """
Jon Hallacabffd2014-10-09 12:36:53 -0400344 try:
kelvin8ec71442015-01-15 16:57:00 -0800345 # main.log.info( self.name + ": Stopping ONOS" )
346 # self.stop()
347 self.handle.sendline( "cd " + self.home )
kelvin-onlaba1484582015-02-02 15:46:20 -0800348 self.handle.expect( self.home + "\$" )
Jon Hall61282e32015-03-19 11:34:11 -0700349 cmd = "git pull"
350 if comp1 != "":
351 cmd += ' ' + comp1
352 if fastForward:
353 cmd += ' ' + " --ff-only"
354 self.handle.sendline( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800355 i = self.handle.expect(
356 [
357 'fatal',
358 'Username\sfor\s(.*):\s',
359 '\sfile(s*) changed,\s',
360 'Already up-to-date',
361 'Aborting',
362 'You\sare\snot\scurrently\son\sa\sbranch',
Jon Hall274b6642015-02-17 11:57:17 -0800363 'You asked me to pull without telling me which branch you',
364 'Pull is not possible because you have unmerged files',
Jon Hall61282e32015-03-19 11:34:11 -0700365 'Please enter a commit message to explain why this merge',
366 'Found a swap file by the name',
367 'Please, commit your changes before you can merge.',
kelvin-onlabd3b64892015-01-20 13:26:24 -0800368 pexpect.TIMEOUT ],
369 timeout=300 )
kelvin8ec71442015-01-15 16:57:00 -0800370 # debug
kelvin-onlabd3b64892015-01-20 13:26:24 -0800371 # main.log.report( self.name +": DEBUG: \n"+
372 # "git pull response: " +
373 # str( self.handle.before ) + str( self.handle.after ) )
kelvin8ec71442015-01-15 16:57:00 -0800374 if i == 0:
Jon Hall61282e32015-03-19 11:34:11 -0700375 main.log.error( self.name + ": Git pull had some issue" )
376 output = self.handle.after
377 self.handle.expect( '\$' )
378 output += self.handle.before
379 main.log.warn( output )
Jon Hallacabffd2014-10-09 12:36:53 -0400380 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800381 elif i == 1:
382 main.log.error(
383 self.name +
384 ": Git Pull Asking for username. " )
Jon Hallacabffd2014-10-09 12:36:53 -0400385 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800386 elif i == 2:
387 main.log.info(
388 self.name +
389 ": Git Pull - pulling repository now" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800390 self.handle.expect( self.home + "\$", 120 )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800391 # So that only when git pull is done, we do mvn clean compile
392 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800393 elif i == 3:
394 main.log.info( self.name + ": Git Pull - Already up to date" )
Jon Hall47a93fb2015-01-06 16:46:06 -0800395 return i
kelvin8ec71442015-01-15 16:57:00 -0800396 elif i == 4:
397 main.log.info(
398 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800399 ": Git Pull - Aborting..." +
400 "Are there conflicting git files?" )
Jon Hallacabffd2014-10-09 12:36:53 -0400401 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800402 elif i == 5:
403 main.log.info(
404 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800405 ": Git Pull - You are not currently " +
406 "on a branch so git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400407 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800408 elif i == 6:
409 main.log.info(
410 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800411 ": Git Pull - You have not configured an upstream " +
412 "branch to pull from. Git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400413 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800414 elif i == 7:
415 main.log.info(
416 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800417 ": Git Pull - Pull is not possible because " +
418 "you have unmerged files." )
Jon Hallacabffd2014-10-09 12:36:53 -0400419 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800420 elif i == 8:
Jon Hall61282e32015-03-19 11:34:11 -0700421 # NOTE: abandoning test since we can't reliably handle this
422 # there could be different default text editors and we
423 # also don't know if we actually want to make the commit
424 main.log.error( "Git pull resulted in a merge commit message" +
425 ". Exiting test!" )
426 main.cleanup()
427 main.exit()
428 elif i == 9: # Merge commit message but swap file exists
429 main.log.error( "Git pull resulted in a merge commit message" +
430 " but a swap file exists." )
431 try:
432 self.handle.send( 'A' ) # Abort
433 self.handle.expect( "\$" )
434 return main.ERROR
435 except Exception:
436 main.log.exception( "Couldn't exit editor prompt!")
437 main.cleanup()
438 main.exit()
439 elif i == 10: # In the middle of a merge commit
440 main.log.error( "Git branch is in the middle of a merge. " )
441 main.log.warn( self.handle.before + self.handle.after )
442 return main.ERROR
443 elif i == 11:
kelvin8ec71442015-01-15 16:57:00 -0800444 main.log.error( self.name + ": Git Pull - TIMEOUT" )
445 main.log.error(
446 self.name + " Response was: " + str(
447 self.handle.before ) )
Jon Hallacabffd2014-10-09 12:36:53 -0400448 return main.ERROR
449 else:
kelvin8ec71442015-01-15 16:57:00 -0800450 main.log.error(
451 self.name +
452 ": Git Pull - Unexpected response, check for pull errors" )
Jon Hallacabffd2014-10-09 12:36:53 -0400453 return main.ERROR
454 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800455 main.log.error( self.name + ": EOF exception found" )
456 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400457 main.cleanup()
458 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800459 except Exception:
460 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400461 main.cleanup()
462 main.exit()
463
kelvin-onlabd3b64892015-01-20 13:26:24 -0800464 def gitCheckout( self, branch="master" ):
kelvin8ec71442015-01-15 16:57:00 -0800465 """
Jon Hallacabffd2014-10-09 12:36:53 -0400466 Assumes that "git pull" works without login
kelvin8ec71442015-01-15 16:57:00 -0800467
Jon Hallacabffd2014-10-09 12:36:53 -0400468 This function will perform a git git checkout on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800469 If used as gitCheckout( "branch" ) it will do git checkout
470 of the "branch".
Jon Hallacabffd2014-10-09 12:36:53 -0400471
472 Otherwise, this function will perform a git checkout of the master
kelvin8ec71442015-01-15 16:57:00 -0800473 branch of the ONOS repository. If it has any problems, it will return
474 main.ERROR.
475 If the branch was already the specified branch, or the git checkout was
Jon Hallacabffd2014-10-09 12:36:53 -0400476 successful then the function will return main.TRUE.
477
kelvin8ec71442015-01-15 16:57:00 -0800478 """
Jon Hallacabffd2014-10-09 12:36:53 -0400479 try:
kelvin8ec71442015-01-15 16:57:00 -0800480 self.handle.sendline( "cd " + self.home )
kelvin-onlaba1484582015-02-02 15:46:20 -0800481 self.handle.expect( self.home + "\$" )
Jon Hall274b6642015-02-17 11:57:17 -0800482 main.log.info( self.name +
483 ": Checking out git branch/ref: " + branch + "..." )
kelvin8ec71442015-01-15 16:57:00 -0800484 cmd = "git checkout " + branch
485 self.handle.sendline( cmd )
486 self.handle.expect( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800487 i = self.handle.expect(
Jon Hall274b6642015-02-17 11:57:17 -0800488 [ 'fatal',
Jon Hall61282e32015-03-19 11:34:11 -0700489 'Username for (.*): ',
490 'Already on \'',
Jon Hall7a8354f2015-06-10 15:37:00 -0700491 'Switched to (a new )?branch \'' + str( branch ),
Jon Hall274b6642015-02-17 11:57:17 -0800492 pexpect.TIMEOUT,
493 'error: Your local changes to the following files' +
Jon Hallefbd9792015-03-05 16:11:36 -0800494 'would be overwritten by checkout:',
Jon Hall274b6642015-02-17 11:57:17 -0800495 'error: you need to resolve your current index first',
496 "You are in 'detached HEAD' state.",
497 "HEAD is now at " ],
kelvin-onlabd3b64892015-01-20 13:26:24 -0800498 timeout=60 )
kelvin8ec71442015-01-15 16:57:00 -0800499 if i == 0:
500 main.log.error(
501 self.name +
502 ": Git checkout had some issue..." )
503 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400504 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800505 elif i == 1:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800506 main.log.error(
507 self.name +
508 ": Git checkout asking for username." +
509 " Please configure your local git repository to be able " +
510 "to access your remote repository passwordlessly" )
Jon Hall274b6642015-02-17 11:57:17 -0800511 # TODO add support for authenticating
Jon Hallacabffd2014-10-09 12:36:53 -0400512 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800513 elif i == 2:
514 main.log.info(
515 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800516 ": Git Checkout %s : Already on this branch" % branch )
kelvin-onlaba1484582015-02-02 15:46:20 -0800517 self.handle.expect( self.home + "\$" )
kelvin8ec71442015-01-15 16:57:00 -0800518 # main.log.info( "DEBUG: after checkout cmd = "+
519 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400520 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800521 elif i == 3:
522 main.log.info(
523 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800524 ": Git checkout %s - Switched to this branch" % branch )
kelvin-onlaba1484582015-02-02 15:46:20 -0800525 self.handle.expect( self.home + "\$" )
kelvin8ec71442015-01-15 16:57:00 -0800526 # main.log.info( "DEBUG: after checkout cmd = "+
527 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400528 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800529 elif i == 4:
530 main.log.error( self.name + ": Git Checkout- TIMEOUT" )
531 main.log.error(
Jon Hall274b6642015-02-17 11:57:17 -0800532 self.name + " Response was: " + str( self.handle.before ) )
Jon Hallacabffd2014-10-09 12:36:53 -0400533 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800534 elif i == 5:
535 self.handle.expect( "Aborting" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800536 main.log.error(
537 self.name +
538 ": Git checkout error: \n" +
Jon Hall274b6642015-02-17 11:57:17 -0800539 "Your local changes to the following files would" +
540 " be overwritten by checkout:" +
541 str( self.handle.before ) )
kelvin-onlaba1484582015-02-02 15:46:20 -0800542 self.handle.expect( self.home + "\$" )
Jon Hall81e29af2014-11-04 20:41:23 -0500543 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800544 elif i == 6:
Jon Hall274b6642015-02-17 11:57:17 -0800545 main.log.error(
546 self.name +
547 ": Git checkout error: \n" +
548 "You need to resolve your current index first:" +
549 str( self.handle.before ) )
kelvin-onlaba1484582015-02-02 15:46:20 -0800550 self.handle.expect( self.home + "\$" )
Jon Hall81e29af2014-11-04 20:41:23 -0500551 return main.ERROR
Jon Hall274b6642015-02-17 11:57:17 -0800552 elif i == 7:
553 main.log.info(
554 self.name +
555 ": Git checkout " + str( branch ) +
556 " - You are in 'detached HEAD' state. HEAD is now at " +
557 str( branch ) )
558 self.handle.expect( self.home + "\$" )
559 return main.TRUE
560 elif i == 8: # Already in detached HEAD on the specified commit
561 main.log.info(
562 self.name +
563 ": Git Checkout %s : Already on commit" % branch )
564 self.handle.expect( self.home + "\$" )
565 return main.TRUE
Jon Hallacabffd2014-10-09 12:36:53 -0400566 else:
kelvin8ec71442015-01-15 16:57:00 -0800567 main.log.error(
568 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800569 ": Git Checkout - Unexpected response, " +
570 "check for pull errors" )
kelvin8ec71442015-01-15 16:57:00 -0800571 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400572 return main.ERROR
573
574 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800575 main.log.error( self.name + ": EOF exception found" )
576 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400577 main.cleanup()
578 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800579 except Exception:
580 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400581 main.cleanup()
582 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400583
pingping-lin6d23d9e2015-02-02 16:54:24 -0800584 def getBranchName( self ):
pingping-linf30cf272015-05-29 15:54:07 -0700585 main.log.info( "self.home = " )
586 main.log.info( self.home )
pingping-lin6d23d9e2015-02-02 16:54:24 -0800587 self.handle.sendline( "cd " + self.home )
pingping-lin9bf3d8f2015-05-29 16:05:28 -0700588 self.handle.expect( self.home + "\$" )
pingping-lin6d23d9e2015-02-02 16:54:24 -0800589 self.handle.sendline( "git name-rev --name-only HEAD" )
590 self.handle.expect( "git name-rev --name-only HEAD" )
591 self.handle.expect( "\$" )
592
593 lines = self.handle.before.splitlines()
594 if lines[1] == "master":
595 return "master"
596 elif lines[1] == "onos-1.0":
597 return "onos-1.0"
598 else:
599 main.log.info( lines[1] )
600 return "unexpected ONOS branch for SDN-IP test"
601
kelvin-onlabd3b64892015-01-20 13:26:24 -0800602 def getVersion( self, report=False ):
kelvin8ec71442015-01-15 16:57:00 -0800603 """
Jon Hall274b6642015-02-17 11:57:17 -0800604 Writes the COMMIT number to the report to be parsed
Jon Hallefbd9792015-03-05 16:11:36 -0800605 by Jenkins data collector.
kelvin8ec71442015-01-15 16:57:00 -0800606 """
Jon Hall45ec0922014-10-10 19:33:49 -0400607 try:
kelvin8ec71442015-01-15 16:57:00 -0800608 self.handle.sendline( "" )
609 self.handle.expect( "\$" )
610 self.handle.sendline(
611 "cd " +
612 self.home +
Jon Hall274b6642015-02-17 11:57:17 -0800613 "; git log -1 --pretty=fuller --decorate=short | grep -A 6 " +
614 " \"commit\" --color=never" )
kelvin8ec71442015-01-15 16:57:00 -0800615 # NOTE: for some reason there are backspaces inserted in this
616 # phrase when run from Jenkins on some tests
617 self.handle.expect( "never" )
618 self.handle.expect( "\$" )
619 response = ( self.name + ": \n" + str(
620 self.handle.before + self.handle.after ) )
621 self.handle.sendline( "cd " + self.home )
622 self.handle.expect( "\$" )
623 lines = response.splitlines()
Jon Hall45ec0922014-10-10 19:33:49 -0400624 for line in lines:
Jon Hallfd191202014-11-07 18:36:09 -0500625 print line
626 if report:
pingping-lin763ee042015-05-20 17:45:30 -0700627 main.log.wiki( "<blockquote>" )
kelvin8ec71442015-01-15 16:57:00 -0800628 for line in lines[ 2:-1 ]:
629 # Bracket replacement is for Wiki-compliant
630 # formatting. '<' or '>' are interpreted
631 # as xml specific tags that cause errors
632 line = line.replace( "<", "[" )
633 line = line.replace( ">", "]" )
pingping-lin763ee042015-05-20 17:45:30 -0700634 #main.log.wiki( "\t" + line )
635 main.log.wiki( line + "<br /> " )
636 main.log.summary( line )
637 main.log.wiki( "</blockquote>" )
638 main.log.summary("\n")
kelvin8ec71442015-01-15 16:57:00 -0800639 return lines[ 2 ]
Jon Hall45ec0922014-10-10 19:33:49 -0400640 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800641 main.log.error( self.name + ": EOF exception found" )
642 main.log.error( self.name + ": " + self.handle.before )
Jon Hall45ec0922014-10-10 19:33:49 -0400643 main.cleanup()
644 main.exit()
Jon Hall368769f2014-11-19 15:43:35 -0800645 except pexpect.TIMEOUT:
kelvin8ec71442015-01-15 16:57:00 -0800646 main.log.error( self.name + ": TIMEOUT exception found" )
647 main.log.error( self.name + ": " + self.handle.before )
Jon Hall368769f2014-11-19 15:43:35 -0800648 main.cleanup()
649 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800650 except Exception:
651 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall45ec0922014-10-10 19:33:49 -0400652 main.cleanup()
653 main.exit()
654
kelvin-onlabd3b64892015-01-20 13:26:24 -0800655 def createCellFile( self, benchIp, fileName, mnIpAddrs,
kelvin-onlaba4074292015-07-09 15:19:49 -0700656 appString, onosIpAddrs ):
kelvin8ec71442015-01-15 16:57:00 -0800657 """
andrewonlab94282092014-10-10 13:00:11 -0400658 Creates a cell file based on arguments
659 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800660 * Bench IP address ( benchIp )
andrewonlab94282092014-10-10 13:00:11 -0400661 - Needed to copy the cell file over
kelvin-onlabd3b64892015-01-20 13:26:24 -0800662 * File name of the cell file ( fileName )
663 * Mininet IP address ( mnIpAddrs )
kelvin8ec71442015-01-15 16:57:00 -0800664 - Note that only 1 ip address is
andrewonlab94282092014-10-10 13:00:11 -0400665 supported currently
kelvin-onlabd3b64892015-01-20 13:26:24 -0800666 * ONOS IP addresses ( onosIpAddrs )
andrewonlab94282092014-10-10 13:00:11 -0400667 - Must be passed in as last arguments
kelvin8ec71442015-01-15 16:57:00 -0800668
andrewonlab94282092014-10-10 13:00:11 -0400669 NOTE: Assumes cells are located at:
670 ~/<self.home>/tools/test/cells/
kelvin8ec71442015-01-15 16:57:00 -0800671 """
672 # Variable initialization
Jon Hall6801cda2015-07-15 14:13:45 -0700673 cellDirectory = self.home + "/tools/test/cells/"
kelvin8ec71442015-01-15 16:57:00 -0800674 # We want to create the cell file in the dependencies directory
675 # of TestON first, then copy over to ONOS bench
kelvin-onlabd3b64892015-01-20 13:26:24 -0800676 tempDirectory = "/tmp/"
kelvin8ec71442015-01-15 16:57:00 -0800677 # Create the cell file in the directory for writing ( w+ )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800678 cellFile = open( tempDirectory + fileName, 'w+' )
Jon Hall6801cda2015-07-15 14:13:45 -0700679 if isinstance( onosIpAddrs, types.StringType ):
680 onosIpAddrs = [ onosIpAddrs ]
kelvin8ec71442015-01-15 16:57:00 -0800681
cameron@onlab.us75900962015-03-30 13:22:49 -0700682 # App string is hardcoded environment variables
kelvin8ec71442015-01-15 16:57:00 -0800683 # That you may wish to use by default on startup.
cameron@onlab.us75900962015-03-30 13:22:49 -0700684 # Note that you may not want certain apps listed
kelvin8ec71442015-01-15 16:57:00 -0800685 # on here.
cameron@onlab.us75900962015-03-30 13:22:49 -0700686 appString = "export ONOS_APPS=" + appString
kelvin-onlabd3b64892015-01-20 13:26:24 -0800687 mnString = "export OCN="
kelvin-onlabf70fd542015-05-07 18:41:40 -0700688 if mnIpAddrs == "":
689 mnString = ""
kelvin-onlabd3b64892015-01-20 13:26:24 -0800690 onosString = "export OC"
691 tempCount = 1
kelvin8ec71442015-01-15 16:57:00 -0800692
kelvin-onlabd3b64892015-01-20 13:26:24 -0800693 # Create ONOSNIC ip address prefix
kelvin-onlaba4074292015-07-09 15:19:49 -0700694 tempOnosIp = str( onosIpAddrs[ 0 ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800695 tempList = []
696 tempList = tempOnosIp.split( "." )
kelvin8ec71442015-01-15 16:57:00 -0800697 # Omit last element of list to format for NIC
kelvin-onlabd3b64892015-01-20 13:26:24 -0800698 tempList = tempList[ :-1 ]
kelvin8ec71442015-01-15 16:57:00 -0800699 # Structure the nic string ip
kelvin-onlabd3b64892015-01-20 13:26:24 -0800700 nicAddr = ".".join( tempList ) + ".*"
701 onosNicString = "export ONOS_NIC=" + nicAddr
andrewonlab94282092014-10-10 13:00:11 -0400702
703 try:
kelvin8ec71442015-01-15 16:57:00 -0800704 # Start writing to file
kelvin-onlabd3b64892015-01-20 13:26:24 -0800705 cellFile.write( onosNicString + "\n" )
andrewonlab94282092014-10-10 13:00:11 -0400706
kelvin-onlabd3b64892015-01-20 13:26:24 -0800707 for arg in onosIpAddrs:
708 # For each argument in onosIpAddrs, write to file
kelvin8ec71442015-01-15 16:57:00 -0800709 # Output should look like the following:
andrewonlabd4940492014-10-24 12:21:27 -0400710 # export OC1="10.128.20.11"
711 # export OC2="10.128.20.12"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800712 cellFile.write( onosString + str( tempCount ) +
Jon Hall6f665652015-09-18 10:08:07 -0700713 "=\"" + arg + "\"\n" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800714 tempCount = tempCount + 1
kelvin8ec71442015-01-15 16:57:00 -0800715
Jon Hall6f665652015-09-18 10:08:07 -0700716 cellFile.write( "export OCI=$OC1\n" )
717 cellFile.write( mnString + "\"" + mnIpAddrs + "\"\n" )
cameron@onlab.us75900962015-03-30 13:22:49 -0700718 cellFile.write( appString + "\n" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800719 cellFile.close()
andrewonlab94282092014-10-10 13:00:11 -0400720
kelvin8ec71442015-01-15 16:57:00 -0800721 # We use os.system to send the command to TestON cluster
722 # to account for the case in which TestON is not located
723 # on the same cluster as the ONOS bench
724 # Note that even if TestON is located on the same cluster
725 # as ONOS bench, you must setup passwordless ssh
726 # between TestON and ONOS bench in order to automate the test.
kelvin-onlabc2b79102015-07-14 11:41:20 -0700727 os.system( "scp " + tempDirectory + fileName + " " +
728 self.user_name + "@" + self.ip_address + ":" + cellDirectory )
andrewonlab94282092014-10-10 13:00:11 -0400729
andrewonlab2a6c9342014-10-16 13:40:15 -0400730 return main.TRUE
731
andrewonlab94282092014-10-10 13:00:11 -0400732 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800733 main.log.error( self.name + ": EOF exception found" )
734 main.log.error( self.name + ": " + self.handle.before )
andrewonlab94282092014-10-10 13:00:11 -0400735 main.cleanup()
736 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800737 except Exception:
738 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab94282092014-10-10 13:00:11 -0400739 main.cleanup()
740 main.exit()
741
kelvin-onlabd3b64892015-01-20 13:26:24 -0800742 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800743 """
andrewonlab95ca1462014-10-09 14:04:24 -0400744 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800745 """
Hari Krishna03f530e2015-07-10 17:28:27 -0700746 import re
andrewonlab95ca1462014-10-09 14:04:24 -0400747 try:
748 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800749 main.log.error( "Must define cellname" )
andrewonlab95ca1462014-10-09 14:04:24 -0400750 main.cleanup()
751 main.exit()
752 else:
kelvin8ec71442015-01-15 16:57:00 -0800753 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800754 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800755 # Note that this variable name is subject to change
andrewonlab95ca1462014-10-09 14:04:24 -0400756 # and that this driver will have to change accordingly
Jon Hall3b489db2015-10-05 14:38:37 -0700757 self.handle.expect( str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800758 handleBefore = self.handle.before
759 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800760 # Get the rest of the handle
Jon Hall3b489db2015-10-05 14:38:37 -0700761 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800762 handleMore = self.handle.before
andrewonlab95ca1462014-10-09 14:04:24 -0400763
Hari Krishna03f530e2015-07-10 17:28:27 -0700764 cell_result = handleBefore + handleAfter + handleMore
765 print cell_result
766 if( re.search( "No such cell", cell_result ) ):
767 main.log.error( "Cell call returned: " + handleBefore +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800768 handleAfter + handleMore )
Hari Krishna03f530e2015-07-10 17:28:27 -0700769 main.cleanup()
770 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400771 return main.TRUE
andrewonlab95ca1462014-10-09 14:04:24 -0400772 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800773 main.log.error( self.name + ": EOF exception found" )
774 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ca1462014-10-09 14:04:24 -0400775 main.cleanup()
776 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800777 except Exception:
778 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ca1462014-10-09 14:04:24 -0400779 main.cleanup()
780 main.exit()
781
kelvin-onlabd3b64892015-01-20 13:26:24 -0800782 def verifyCell( self ):
kelvin8ec71442015-01-15 16:57:00 -0800783 """
andrewonlabc03bf6c2014-10-09 14:56:18 -0400784 Calls 'onos-verify-cell' to check for cell installation
kelvin8ec71442015-01-15 16:57:00 -0800785 """
786 # TODO: Add meaningful expect value
andrewonlab8d0d7d72014-10-09 16:33:15 -0400787
andrewonlabc03bf6c2014-10-09 14:56:18 -0400788 try:
kelvin8ec71442015-01-15 16:57:00 -0800789 # Clean handle by sending empty and expecting $
790 self.handle.sendline( "" )
791 self.handle.expect( "\$" )
792 self.handle.sendline( "onos-verify-cell" )
793 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800794 handleBefore = self.handle.before
795 handleAfter = self.handle.after
kelvin-onlabd3b64892015-01-20 13:26:24 -0800796 main.log.info( "Verify cell returned: " + handleBefore +
Jon Hall3b489db2015-10-05 14:38:37 -0700797 handleAfter )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400798 return main.TRUE
Jon Halla5cb6172015-02-23 09:28:28 -0800799 except pexpect.ExceptionPexpect as e:
Jon Hall3b489db2015-10-05 14:38:37 -0700800 main.log.exception( self.name + ": Pexpect exception found: " )
kelvin8ec71442015-01-15 16:57:00 -0800801 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -0400802 main.cleanup()
803 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800804 except Exception:
805 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400806 main.cleanup()
807 main.exit()
808
jenkins1e99e7b2015-04-02 18:15:39 -0700809 def onosCfgSet( self, ONOSIp, configName, configParam ):
810 """
811 Uses 'onos <node-ip> cfg set' to change a parameter value of an
Jon Hall4ba53f02015-07-29 13:07:41 -0700812 application.
813
jenkins1e99e7b2015-04-02 18:15:39 -0700814 ex)
815 onos 10.0.0.1 cfg set org.onosproject.myapp appSetting 1
jenkins1e99e7b2015-04-02 18:15:39 -0700816 ONOSIp = '10.0.0.1'
817 configName = 'org.onosproject.myapp'
818 configParam = 'appSetting 1'
jenkins1e99e7b2015-04-02 18:15:39 -0700819 """
cameron@onlab.us78b89652015-07-08 15:21:03 -0700820 for i in range(5):
821 try:
822 cfgStr = ( "onos "+str(ONOSIp)+" cfg set "+
823 str(configName) + " " +
824 str(configParam)
825 )
jenkins1e99e7b2015-04-02 18:15:39 -0700826
cameron@onlab.us78b89652015-07-08 15:21:03 -0700827 self.handle.sendline( "" )
828 self.handle.expect( ":~" )
829 self.handle.sendline( cfgStr )
Jon Hall4ba53f02015-07-29 13:07:41 -0700830 self.handle.expect("cfg set")
cameron@onlab.us78b89652015-07-08 15:21:03 -0700831 self.handle.expect( ":~" )
Jon Hall4ba53f02015-07-29 13:07:41 -0700832
cameron@onlab.us78b89652015-07-08 15:21:03 -0700833 paramValue = configParam.split(" ")[1]
834 paramName = configParam.split(" ")[0]
Jon Hall4ba53f02015-07-29 13:07:41 -0700835
cameron@onlab.us78b89652015-07-08 15:21:03 -0700836 checkStr = ( "onos " + str(ONOSIp) + """ cfg get " """ + str(configName) + " " + paramName + """ " """)
jenkins1e99e7b2015-04-02 18:15:39 -0700837
cameron@onlab.us78b89652015-07-08 15:21:03 -0700838 self.handle.sendline( checkStr )
839 self.handle.expect( ":~" )
jenkins1e99e7b2015-04-02 18:15:39 -0700840
cameron@onlab.us78b89652015-07-08 15:21:03 -0700841 if "value=" + paramValue + "," in self.handle.before:
Jon Hall4ba53f02015-07-29 13:07:41 -0700842 main.log.info("cfg " + configName + " successfully set to " + configParam)
cameron@onlab.us78b89652015-07-08 15:21:03 -0700843 return main.TRUE
844
845 except pexpect.ExceptionPexpect as e:
Jon Hall3b489db2015-10-05 14:38:37 -0700846 main.log.exception( self.name + ": Pexpect exception found: " )
cameron@onlab.us78b89652015-07-08 15:21:03 -0700847 main.log.error( self.name + ": " + self.handle.before )
848 main.cleanup()
849 main.exit()
850 except Exception:
851 main.log.exception( self.name + ": Uncaught exception!" )
852 main.cleanup()
853 main.exit()
Jon Hall4ba53f02015-07-29 13:07:41 -0700854
cameron@onlab.us78b89652015-07-08 15:21:03 -0700855 time.sleep(5)
856
857 main.log.error("CFG SET FAILURE: " + configName + " " + configParam )
Jon Hall4ba53f02015-07-29 13:07:41 -0700858 main.ONOSbench.handle.sendline("onos $OC1 cfg get")
cameron@onlab.us78b89652015-07-08 15:21:03 -0700859 main.ONOSbench.handle.expect("\$")
860 print main.ONOSbench.handle.before
861 main.ONOSbench.logReport( ONOSIp, ["ERROR","WARN","EXCEPT"], "d")
862 return main.FALSE
863
Jon Hall4ba53f02015-07-29 13:07:41 -0700864
kelvin-onlabd3b64892015-01-20 13:26:24 -0800865 def onosCli( self, ONOSIp, cmdstr ):
kelvin8ec71442015-01-15 16:57:00 -0800866 """
andrewonlab05e362f2014-10-10 00:40:57 -0400867 Uses 'onos' command to send various ONOS CLI arguments.
868 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800869 * ONOSIp: specify the ip of the cell machine
andrewonlab94282092014-10-10 13:00:11 -0400870 * cmdstr: specify the command string to send
kelvin8ec71442015-01-15 16:57:00 -0800871
872 This function is intended to expose the entire karaf
andrewonlab6e20c342014-10-10 18:08:48 -0400873 CLI commands for ONOS. Try to use this function first
874 before attempting to write a ONOS CLI specific driver
kelvin8ec71442015-01-15 16:57:00 -0800875 function.
876 You can see a list of available 'cmdstr' arguments
andrewonlab6e20c342014-10-10 18:08:48 -0400877 by starting onos, and typing in 'onos' to enter the
878 onos> CLI. Then, type 'help' to see the list of
kelvin8ec71442015-01-15 16:57:00 -0800879 available commands.
880 """
andrewonlab05e362f2014-10-10 00:40:57 -0400881 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800882 if not ONOSIp:
kelvin8ec71442015-01-15 16:57:00 -0800883 main.log.error( "You must specify the IP address" )
andrewonlab05e362f2014-10-10 00:40:57 -0400884 return main.FALSE
885 if not cmdstr:
kelvin8ec71442015-01-15 16:57:00 -0800886 main.log.error( "You must specify the command string" )
andrewonlab05e362f2014-10-10 00:40:57 -0400887 return main.FALSE
888
kelvin8ec71442015-01-15 16:57:00 -0800889 cmdstr = str( cmdstr )
890 self.handle.sendline( "" )
891 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400892
kelvin-onlabd3b64892015-01-20 13:26:24 -0800893 self.handle.sendline( "onos -w " + ONOSIp + " " + cmdstr )
kelvin8ec71442015-01-15 16:57:00 -0800894 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400895
kelvin-onlabd3b64892015-01-20 13:26:24 -0800896 handleBefore = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -0800897 main.log.info( "Command sent successfully" )
kelvin8ec71442015-01-15 16:57:00 -0800898 # Obtain return handle that consists of result from
899 # the onos command. The string may need to be
900 # configured further.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800901 returnString = handleBefore
kelvin-onlabd3b64892015-01-20 13:26:24 -0800902 return returnString
andrewonlab05e362f2014-10-10 00:40:57 -0400903 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800904 main.log.error( self.name + ": EOF exception found" )
905 main.log.error( self.name + ": " + self.handle.before )
andrewonlab05e362f2014-10-10 00:40:57 -0400906 main.cleanup()
907 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800908 except Exception:
909 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab05e362f2014-10-10 00:40:57 -0400910 main.cleanup()
911 main.exit()
Jon Hall7993bfc2014-10-09 16:30:14 -0400912
kelvin-onlabd3b64892015-01-20 13:26:24 -0800913 def onosInstall( self, options="-f", node="" ):
kelvin8ec71442015-01-15 16:57:00 -0800914 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400915 Installs ONOS bits on the designated cell machine.
kelvin8ec71442015-01-15 16:57:00 -0800916 If -f option is provided, it also forces an uninstall.
917 Presently, install also includes onos-push-bits and
Jon Hall7993bfc2014-10-09 16:30:14 -0400918 onos-config within.
kelvin8ec71442015-01-15 16:57:00 -0800919 The node option allows you to selectively only push the jar
Jon Hall7993bfc2014-10-09 16:30:14 -0400920 files to certain onos nodes
921
922 Returns: main.TRUE on success and main.FALSE on failure
kelvin8ec71442015-01-15 16:57:00 -0800923 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400924 try:
andrewonlab114768a2014-11-14 12:44:44 -0500925 if options:
kelvin8ec71442015-01-15 16:57:00 -0800926 self.handle.sendline( "onos-install " + options + " " + node )
andrewonlab114768a2014-11-14 12:44:44 -0500927 else:
kelvin8ec71442015-01-15 16:57:00 -0800928 self.handle.sendline( "onos-install " + node )
929 self.handle.expect( "onos-install " )
930 # NOTE: this timeout may need to change depending on the network
931 # and size of ONOS
932 i = self.handle.expect( [ "Network\sis\sunreachable",
kelvin-onlabd3b64892015-01-20 13:26:24 -0800933 "onos\sstart/running,\sprocess",
kelvin8ec71442015-01-15 16:57:00 -0800934 "ONOS\sis\salready\sinstalled",
935 pexpect.TIMEOUT ], timeout=60 )
Jon Hall7993bfc2014-10-09 16:30:14 -0400936 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800937 main.log.warn( "Network is unreachable" )
Jon Hall3b489db2015-10-05 14:38:37 -0700938 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400939 return main.FALSE
940 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800941 main.log.info(
942 "ONOS was installed on " +
943 node +
944 " and started" )
Jon Hall3b489db2015-10-05 14:38:37 -0700945 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400946 return main.TRUE
andrewonlabd9a73a72014-11-14 17:28:21 -0500947 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800948 main.log.info( "ONOS is already installed on " + node )
Jon Hall3b489db2015-10-05 14:38:37 -0700949 self.handle.expect( "\$" )
andrewonlabd9a73a72014-11-14 17:28:21 -0500950 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800951 elif i == 3:
952 main.log.info(
953 "Installation of ONOS on " +
954 node +
955 " timed out" )
Jon Hall3b489db2015-10-05 14:38:37 -0700956 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400957 return main.FALSE
andrewonlabc03bf6c2014-10-09 14:56:18 -0400958 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800959 main.log.error( self.name + ": EOF exception found" )
960 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400961 main.cleanup()
962 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800963 except Exception:
964 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400965 main.cleanup()
966 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400967
kelvin-onlabd3b64892015-01-20 13:26:24 -0800968 def onosStart( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800969 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400970 Calls onos command: 'onos-service [<node-ip>] start'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400971 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -0800972 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400973 try:
kelvin8ec71442015-01-15 16:57:00 -0800974 self.handle.sendline( "" )
975 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800976 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -0800977 " start" )
978 i = self.handle.expect( [
andrewonlab8d0d7d72014-10-09 16:33:15 -0400979 "Job\sis\salready\srunning",
980 "start/running",
981 "Unknown\sinstance",
kelvin8ec71442015-01-15 16:57:00 -0800982 pexpect.TIMEOUT ], timeout=120 )
Jon Hall3b489db2015-10-05 14:38:37 -0700983 self.handle.expect( "\$" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400984 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800985 main.log.info( "Service is already running" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400986 return main.TRUE
987 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800988 main.log.info( "ONOS service started" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400989 return main.TRUE
990 else:
kelvin8ec71442015-01-15 16:57:00 -0800991 main.log.error( "ONOS service failed to start" )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400992 main.cleanup()
993 main.exit()
andrewonlab8d0d7d72014-10-09 16:33:15 -0400994 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800995 main.log.error( self.name + ": EOF exception found" )
996 main.log.error( self.name + ": " + self.handle.before )
andrewonlab8d0d7d72014-10-09 16:33:15 -0400997 main.cleanup()
998 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800999 except Exception:
1000 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001001 main.cleanup()
1002 main.exit()
1003
kelvin-onlabd3b64892015-01-20 13:26:24 -08001004 def onosStop( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001005 """
andrewonlab2b30bd32014-10-09 16:48:55 -04001006 Calls onos command: 'onos-service [<node-ip>] stop'
andrewonlabe8e56fd2014-10-09 17:12:44 -04001007 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -08001008 """
andrewonlab2b30bd32014-10-09 16:48:55 -04001009 try:
kelvin8ec71442015-01-15 16:57:00 -08001010 self.handle.sendline( "" )
1011 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001012 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001013 " stop" )
1014 i = self.handle.expect( [
andrewonlab2b30bd32014-10-09 16:48:55 -04001015 "stop/waiting",
Jon Hall61282e32015-03-19 11:34:11 -07001016 "Could not resolve hostname",
andrewonlab2b30bd32014-10-09 16:48:55 -04001017 "Unknown\sinstance",
kelvin8ec71442015-01-15 16:57:00 -08001018 pexpect.TIMEOUT ], timeout=60 )
Jon Hall3b489db2015-10-05 14:38:37 -07001019 self.handle.expect( "\$" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001020 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001021 main.log.info( "ONOS service stopped" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001022 return main.TRUE
1023 elif i == 1:
Jon Hall65844a32015-03-09 19:09:37 -07001024 main.log.info( "onosStop() Unknown ONOS instance specified: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001025 str( nodeIp ) )
andrewonlab2b30bd32014-10-09 16:48:55 -04001026 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -07001027 elif i == 2:
1028 main.log.warn( "ONOS wasn't running" )
1029 return main.TRUE
andrewonlab2b30bd32014-10-09 16:48:55 -04001030 else:
kelvin8ec71442015-01-15 16:57:00 -08001031 main.log.error( "ONOS service failed to stop" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001032 return main.FALSE
andrewonlab2b30bd32014-10-09 16:48:55 -04001033 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001034 main.log.error( self.name + ": EOF exception found" )
1035 main.log.error( self.name + ": " + self.handle.before )
andrewonlab2b30bd32014-10-09 16:48:55 -04001036 main.cleanup()
1037 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001038 except Exception:
1039 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001040 main.cleanup()
1041 main.exit()
kelvin8ec71442015-01-15 16:57:00 -08001042
kelvin-onlabd3b64892015-01-20 13:26:24 -08001043 def onosUninstall( self, nodeIp="" ):
kelvin8ec71442015-01-15 16:57:00 -08001044 """
andrewonlabc8d47972014-10-09 16:52:36 -04001045 Calls the command: 'onos-uninstall'
kelvin8ec71442015-01-15 16:57:00 -08001046 Uninstalls ONOS from the designated cell machine, stopping
andrewonlabe8e56fd2014-10-09 17:12:44 -04001047 if needed
kelvin8ec71442015-01-15 16:57:00 -08001048 """
andrewonlabc8d47972014-10-09 16:52:36 -04001049 try:
kelvin8ec71442015-01-15 16:57:00 -08001050 self.handle.sendline( "" )
pingping-lin763ee042015-05-20 17:45:30 -07001051 self.handle.expect( "\$", timeout=60 )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001052 self.handle.sendline( "onos-uninstall " + str( nodeIp ) )
Jon Hall3b489db2015-10-05 14:38:37 -07001053 self.handle.expect( "\$", timeout=60 )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001054 main.log.info( "ONOS " + nodeIp + " was uninstalled" )
kelvin8ec71442015-01-15 16:57:00 -08001055 # onos-uninstall command does not return any text
andrewonlabc8d47972014-10-09 16:52:36 -04001056 return main.TRUE
pingping-lin763ee042015-05-20 17:45:30 -07001057 except pexpect.TIMEOUT:
1058 main.log.exception( self.name + ": Timeout in onosUninstall" )
1059 return main.FALSE
andrewonlabc8d47972014-10-09 16:52:36 -04001060 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001061 main.log.error( self.name + ": EOF exception found" )
1062 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc8d47972014-10-09 16:52:36 -04001063 main.cleanup()
1064 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001065 except Exception:
1066 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc8d47972014-10-09 16:52:36 -04001067 main.cleanup()
1068 main.exit()
andrewonlab2b30bd32014-10-09 16:48:55 -04001069
kelvin-onlabd3b64892015-01-20 13:26:24 -08001070 def onosDie( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001071 """
andrewonlabaedc8332014-12-04 12:43:03 -05001072 Issues the command 'onos-die <node-ip>'
1073 This command calls onos-kill and also stops the node
kelvin8ec71442015-01-15 16:57:00 -08001074 """
andrewonlabaedc8332014-12-04 12:43:03 -05001075 try:
kelvin8ec71442015-01-15 16:57:00 -08001076 self.handle.sendline( "" )
1077 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001078 cmdStr = "onos-kill " + str( nodeIp )
1079 self.handle.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -08001080 i = self.handle.expect( [
andrewonlabaedc8332014-12-04 12:43:03 -05001081 "Killing\sONOS",
1082 "ONOS\sprocess\sis\snot\srunning",
kelvin8ec71442015-01-15 16:57:00 -08001083 pexpect.TIMEOUT ], timeout=20 )
andrewonlabaedc8332014-12-04 12:43:03 -05001084 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001085 main.log.info( "ONOS instance " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001086 " was killed and stopped" )
andrewonlabaedc8332014-12-04 12:43:03 -05001087 return main.TRUE
1088 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001089 main.log.info( "ONOS process was not running" )
andrewonlabaedc8332014-12-04 12:43:03 -05001090 return main.FALSE
1091 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 )
andrewonlabaedc8332014-12-04 12:43:03 -05001094 main.cleanup()
1095 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001096 except Exception:
1097 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabaedc8332014-12-04 12:43:03 -05001098 main.cleanup()
1099 main.exit()
1100
kelvin-onlabd3b64892015-01-20 13:26:24 -08001101 def onosKill( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001102 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001103 Calls the command: 'onos-kill [<node-ip>]'
1104 "Remotely, and unceremoniously kills the ONOS instance running on
1105 the specified cell machine" - Tom V
kelvin8ec71442015-01-15 16:57:00 -08001106 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001107 try:
kelvin8ec71442015-01-15 16:57:00 -08001108 self.handle.sendline( "" )
1109 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001110 self.handle.sendline( "onos-kill " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -08001111 i = self.handle.expect( [
andrewonlabe8e56fd2014-10-09 17:12:44 -04001112 "\$",
1113 "No\sroute\sto\shost",
1114 "password:",
kelvin8ec71442015-01-15 16:57:00 -08001115 pexpect.TIMEOUT ], timeout=20 )
1116
andrewonlabe8e56fd2014-10-09 17:12:44 -04001117 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001118 main.log.info(
1119 "ONOS instance " + str(
kelvin-onlabd3b64892015-01-20 13:26:24 -08001120 nodeIp ) + " was killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001121 return main.TRUE
1122 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001123 main.log.info( "No route to host" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001124 return main.FALSE
1125 elif i == 2:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001126 main.log.info(
1127 "Passwordless login for host: " +
1128 str( nodeIp ) +
1129 " not configured" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001130 return main.FALSE
1131 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001132 main.log.info( "ONOS instance was not killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001133 return main.FALSE
kelvin8ec71442015-01-15 16:57:00 -08001134
andrewonlabe8e56fd2014-10-09 17:12:44 -04001135 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001136 main.log.error( self.name + ": EOF exception found" )
1137 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001138 main.cleanup()
1139 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001140 except Exception:
1141 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001142 main.cleanup()
1143 main.exit()
1144
kelvin-onlabd3b64892015-01-20 13:26:24 -08001145 def onosRemoveRaftLogs( self ):
kelvin8ec71442015-01-15 16:57:00 -08001146 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001147 Removes Raft / Copy cat files from ONOS to ensure
Jon Hallfcc88622014-11-25 13:09:54 -05001148 a cleaner environment.
1149
andrewonlab19fbdca2014-11-14 12:55:59 -05001150 Description:
Jon Hallfcc88622014-11-25 13:09:54 -05001151 Stops all ONOS defined in the cell,
andrewonlab19fbdca2014-11-14 12:55:59 -05001152 wipes the raft / copycat log files
kelvin8ec71442015-01-15 16:57:00 -08001153 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001154 try:
kelvin8ec71442015-01-15 16:57:00 -08001155 self.handle.sendline( "" )
1156 self.handle.expect( "\$" )
1157 self.handle.sendline( "onos-remove-raft-logs" )
1158 # Sometimes this command hangs
1159 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
1160 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001161 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001162 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
1163 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001164 if i == 1:
1165 return main.FALSE
andrewonlab19fbdca2014-11-14 12:55:59 -05001166 return main.TRUE
andrewonlab19fbdca2014-11-14 12:55:59 -05001167 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001168 main.log.error( self.name + ": EOF exception found" )
1169 main.log.error( self.name + ": " + self.handle.before )
andrewonlab19fbdca2014-11-14 12:55:59 -05001170 main.cleanup()
1171 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001172 except Exception:
1173 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab19fbdca2014-11-14 12:55:59 -05001174 main.cleanup()
1175 main.exit()
Jon Hallfcc88622014-11-25 13:09:54 -05001176
kelvin-onlabd3b64892015-01-20 13:26:24 -08001177 def onosStartNetwork( self, mntopo ):
kelvin8ec71442015-01-15 16:57:00 -08001178 """
1179 Calls the command 'onos-start-network [ <mininet-topo> ]
1180 "remotely starts the specified topology on the cell's
andrewonlab94282092014-10-10 13:00:11 -04001181 mininet machine against all controllers configured in the
kelvin8ec71442015-01-15 16:57:00 -08001182 cell."
andrewonlab94282092014-10-10 13:00:11 -04001183 * Specify mininet topology file name for mntopo
1184 * Topo files should be placed at:
1185 ~/<your-onos-directory>/tools/test/topos
kelvin8ec71442015-01-15 16:57:00 -08001186
andrewonlab94282092014-10-10 13:00:11 -04001187 NOTE: This function will take you to the mininet prompt
kelvin8ec71442015-01-15 16:57:00 -08001188 """
andrewonlab94282092014-10-10 13:00:11 -04001189 try:
1190 if not mntopo:
kelvin8ec71442015-01-15 16:57:00 -08001191 main.log.error( "You must specify a topo file to execute" )
andrewonlab94282092014-10-10 13:00:11 -04001192 return main.FALSE
andrewonlab94282092014-10-10 13:00:11 -04001193
kelvin8ec71442015-01-15 16:57:00 -08001194 mntopo = str( mntopo )
1195 self.handle.sendline( "" )
1196 self.handle.expect( "\$" )
andrewonlab94282092014-10-10 13:00:11 -04001197
kelvin8ec71442015-01-15 16:57:00 -08001198 self.handle.sendline( "onos-start-network " + mntopo )
1199 self.handle.expect( "mininet>" )
1200 main.log.info( "Network started, entered mininet prompt" )
1201
1202 # TODO: Think about whether return is necessary or not
andrewonlab94282092014-10-10 13:00:11 -04001203
1204 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001205 main.log.error( self.name + ": EOF exception found" )
1206 main.log.error( self.name + ": " + self.handle.before )
andrewonlab94282092014-10-10 13:00:11 -04001207 main.cleanup()
1208 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001209 except Exception:
1210 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab94282092014-10-10 13:00:11 -04001211 main.cleanup()
1212 main.exit()
1213
Jon Hall3b489db2015-10-05 14:38:37 -07001214 def isup( self, node="", timeout=120 ):
kelvin8ec71442015-01-15 16:57:00 -08001215 """
1216 Run's onos-wait-for-start which only returns once ONOS is at run
Cameron Franke9c94fb02015-01-21 10:20:20 -08001217 level 100(ready for use)
andrewonlab8d0d7d72014-10-09 16:33:15 -04001218
Jon Hall7993bfc2014-10-09 16:30:14 -04001219 Returns: main.TRUE if ONOS is running and main.FALSE on timeout
kelvin8ec71442015-01-15 16:57:00 -08001220 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001221 try:
Jon Hall3b489db2015-10-05 14:38:37 -07001222 self.handle.sendline( "onos-wait-for-start " + node )
1223 self.handle.expect( "onos-wait-for-start" )
kelvin8ec71442015-01-15 16:57:00 -08001224 # NOTE: this timeout is arbitrary"
Cameron Franke9c94fb02015-01-21 10:20:20 -08001225 i = self.handle.expect(["\$", pexpect.TIMEOUT], timeout)
Jon Hall7993bfc2014-10-09 16:30:14 -04001226 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001227 main.log.info( self.name + ": " + node + " is up" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001228 return main.TRUE
1229 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001230 # NOTE: since this function won't return until ONOS is ready,
Jon Hall7993bfc2014-10-09 16:30:14 -04001231 # we will kill it on timeout
kelvin8ec71442015-01-15 16:57:00 -08001232 main.log.error( "ONOS has not started yet" )
1233 self.handle.send( "\x03" ) # Control-C
1234 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001235 return main.FALSE
1236 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001237 main.log.error( self.name + ": EOF exception found" )
1238 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -04001239 main.cleanup()
1240 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001241 except Exception:
1242 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001243 main.cleanup()
1244 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001245
kelvin-onlabd3b64892015-01-20 13:26:24 -08001246 def pushTestIntentsShell(
1247 self,
1248 dpidSrc,
1249 dpidDst,
1250 numIntents,
1251 dirFile,
1252 onosIp,
1253 numMult="",
1254 appId="",
1255 report=True,
1256 options="" ):
kelvin8ec71442015-01-15 16:57:00 -08001257 """
andrewonlabb66dfa12014-12-02 15:51:10 -05001258 Description:
kelvin8ec71442015-01-15 16:57:00 -08001259 Use the linux prompt to push test intents to
andrewonlabb66dfa12014-12-02 15:51:10 -05001260 better parallelize the results than the CLI
1261 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001262 * dpidSrc: specify source dpid
1263 * dpidDst: specify destination dpid
1264 * numIntents: specify number of intents to push
1265 * dirFile: specify directory and file name to save
andrewonlabb66dfa12014-12-02 15:51:10 -05001266 results
kelvin-onlabd3b64892015-01-20 13:26:24 -08001267 * onosIp: specify the IP of ONOS to install on
kelvin8ec71442015-01-15 16:57:00 -08001268 NOTE:
andrewonlabb66dfa12014-12-02 15:51:10 -05001269 You must invoke this command at linux shell prompt
kelvin8ec71442015-01-15 16:57:00 -08001270 """
1271 try:
1272 # Create the string to sendline
andrewonlabaedc8332014-12-04 12:43:03 -05001273 if options:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001274 baseCmd = "onos " + str( onosIp ) + " push-test-intents " +\
kelvin8ec71442015-01-15 16:57:00 -08001275 options + " "
andrewonlabaedc8332014-12-04 12:43:03 -05001276 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001277 baseCmd = "onos " + str( onosIp ) + " push-test-intents "
kelvin8ec71442015-01-15 16:57:00 -08001278
kelvin-onlabd3b64892015-01-20 13:26:24 -08001279 addDpid = baseCmd + str( dpidSrc ) + " " + str( dpidDst )
1280 if not numMult:
1281 addIntents = addDpid + " " + str( numIntents )
1282 elif numMult:
1283 addIntents = addDpid + " " + str( numIntents ) + " " +\
1284 str( numMult )
1285 if appId:
1286 addApp = addIntents + " " + str( appId )
andrewonlabb66dfa12014-12-02 15:51:10 -05001287 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001288 addApp = addIntents
andrewonlabb66dfa12014-12-02 15:51:10 -05001289
andrewonlabaedc8332014-12-04 12:43:03 -05001290 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001291 sendCmd = addApp + " > " + str( dirFile ) + " &"
andrewonlabaedc8332014-12-04 12:43:03 -05001292 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001293 sendCmd = addApp + " &"
1294 main.log.info( "Send cmd: " + sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001295
kelvin-onlabd3b64892015-01-20 13:26:24 -08001296 self.handle.sendline( sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001297
1298 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001299 main.log.error( self.name + ": EOF exception found" )
1300 main.log.error( self.name + ": " + self.handle.before )
andrewonlabb66dfa12014-12-02 15:51:10 -05001301 main.cleanup()
1302 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001303 except Exception:
1304 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabb66dfa12014-12-02 15:51:10 -05001305 main.cleanup()
kelvin8ec71442015-01-15 16:57:00 -08001306 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001307
kelvin-onlabd3b64892015-01-20 13:26:24 -08001308 def getTopology( self, topologyOutput ):
kelvin8ec71442015-01-15 16:57:00 -08001309 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001310 Definition:
1311 Loads a json topology output
1312 Return:
1313 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -08001314 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001315 import json
Jon Hall77f53ce2014-10-13 18:02:06 -04001316 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001317 # either onos:topology or 'topology' will work in CLI
1318 topology = json.loads(topologyOutput)
1319 print topology
Jon Hall77f53ce2014-10-13 18:02:06 -04001320 return topology
1321 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001322 main.log.error( self.name + ": EOF exception found" )
1323 main.log.error( self.name + ": " + self.handle.before )
Jon Hall77f53ce2014-10-13 18:02:06 -04001324 main.cleanup()
1325 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001326 except Exception:
1327 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall77f53ce2014-10-13 18:02:06 -04001328 main.cleanup()
1329 main.exit()
1330
kelvin-onlabd3b64892015-01-20 13:26:24 -08001331 def checkStatus(
1332 self,
1333 topologyResult,
1334 numoswitch,
1335 numolink,
1336 logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08001337 """
Jon Hallefbd9792015-03-05 16:11:36 -08001338 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08001339 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08001340 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08001341
Jon Hall77f53ce2014-10-13 18:02:06 -04001342 Params: ip = ip used for the onos cli
1343 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08001344 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08001345 logLevel = level to log to.
1346 Currently accepts 'info', 'warn' and 'report'
Jon Hall77f53ce2014-10-13 18:02:06 -04001347
1348
kelvin-onlabd3b64892015-01-20 13:26:24 -08001349 logLevel can
Jon Hall77f53ce2014-10-13 18:02:06 -04001350
Jon Hallefbd9792015-03-05 16:11:36 -08001351 Returns: main.TRUE if the number of switches and links are correct,
1352 main.FALSE if the number of switches and links is incorrect,
Jon Hall77f53ce2014-10-13 18:02:06 -04001353 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08001354 """
Jon Hall77f53ce2014-10-13 18:02:06 -04001355 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001356 topology = self.getTopology( topologyResult )
Jon Hall77f53ce2014-10-13 18:02:06 -04001357 if topology == {}:
1358 return main.ERROR
1359 output = ""
kelvin8ec71442015-01-15 16:57:00 -08001360 # Is the number of switches is what we expected
shahshreya234a1682015-05-27 15:41:56 -07001361 devices = topology.get( 'devices', False )
1362 links = topology.get( 'links', False )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001363 if not devices or not links:
Jon Hall77f53ce2014-10-13 18:02:06 -04001364 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08001365 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08001366 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08001367 linkCheck = ( int( links ) == int( numolink ) )
Jon Hallefbd9792015-03-05 16:11:36 -08001368 if switchCheck and linkCheck:
kelvin8ec71442015-01-15 16:57:00 -08001369 # We expected the correct numbers
Jon Hall77f53ce2014-10-13 18:02:06 -04001370 output = output + "The number of links and switches match "\
kelvin8ec71442015-01-15 16:57:00 -08001371 + "what was expected"
Jon Hall77f53ce2014-10-13 18:02:06 -04001372 result = main.TRUE
1373 else:
1374 output = output + \
Jon Hall274b6642015-02-17 11:57:17 -08001375 "The number of links and switches does not match " + \
1376 "what was expected"
Jon Hall77f53ce2014-10-13 18:02:06 -04001377 result = main.FALSE
Jon Hallefbd9792015-03-05 16:11:36 -08001378 output = output + "\n ONOS sees %i devices" % int( devices )
1379 output = output + " (%i expected) " % int( numoswitch )
Jon Hall274b6642015-02-17 11:57:17 -08001380 output = output + "and %i links " % int( links )
1381 output = output + "(%i expected)" % int( numolink )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001382 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08001383 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001384 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08001385 main.log.warn( output )
Jon Hall77f53ce2014-10-13 18:02:06 -04001386 else:
kelvin8ec71442015-01-15 16:57:00 -08001387 main.log.info( output )
1388 return result
Jon Hall77f53ce2014-10-13 18:02:06 -04001389 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001390 main.log.error( self.name + ": EOF exception found" )
1391 main.log.error( self.name + ": " + self.handle.before )
Jon Hall77f53ce2014-10-13 18:02:06 -04001392 main.cleanup()
1393 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001394 except Exception:
1395 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall77f53ce2014-10-13 18:02:06 -04001396 main.cleanup()
1397 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001398
kelvin-onlabd3b64892015-01-20 13:26:24 -08001399 def tsharkPcap( self, interface, dirFile ):
kelvin8ec71442015-01-15 16:57:00 -08001400 """
andrewonlab970399c2014-11-07 13:09:32 -05001401 Capture all packet activity and store in specified
1402 directory/file
1403
1404 Required:
1405 * interface: interface to capture
1406 * dir: directory/filename to store pcap
kelvin8ec71442015-01-15 16:57:00 -08001407 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001408 try:
1409 self.handle.sendline( "" )
1410 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001411
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001412 self.handle.sendline( "tshark -i " + str( interface ) + " -t e -w " + str( dirFile ) + " &" )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001413 self.handle.sendline( "\n" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001414 self.handle.expect( "Capturing on" )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001415 self.handle.sendline( "\n" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001416 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001417
Jon Hallfebb1c72015-03-05 13:30:09 -08001418 main.log.info( "Tshark started capturing files on " +
1419 str( interface ) + " and saving to directory: " +
1420 str( dirFile ) )
1421 except pexpect.EOF:
1422 main.log.error( self.name + ": EOF exception found" )
1423 main.log.error( self.name + ": " + self.handle.before )
1424 main.cleanup()
1425 main.exit()
1426 except Exception:
1427 main.log.exception( self.name + ": Uncaught exception!" )
1428 main.cleanup()
1429 main.exit()
Shreya Shaha73aaad2014-10-27 18:03:09 -04001430
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001431 def onosTopoCfg( self, onosIp, jsonFile ):
kelvin8ec71442015-01-15 16:57:00 -08001432 """
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001433 Description:
1434 Execute onos-topo-cfg command
1435 Required:
1436 onosIp - IP of the onos node you want to send the json to
1437 jsonFile - File path of the json file
1438 Return:
1439 Returns main.TRUE if the command is successfull; Returns
1440 main.FALSE if there was an error
kelvin8ec71442015-01-15 16:57:00 -08001441 """
shahshreyae6c7cf42014-11-26 16:39:01 -08001442 try:
kelvin8ec71442015-01-15 16:57:00 -08001443 self.handle.sendline( "" )
1444 self.handle.expect( "\$" )
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001445 cmd = "onos-topo-cfg "
1446 self.handle.sendline( cmd + str( onosIp ) + " " + jsonFile )
1447 handle = self.handle.before
1448 print handle
1449 if "Error" in handle:
1450 main.log.error( self.name + ": " + self.handle.before )
1451 return main.FALSE
1452 else:
1453 self.handle.expect( "\$" )
1454 return main.TRUE
1455
Jon Hallfebb1c72015-03-05 13:30:09 -08001456 except pexpect.EOF:
1457 main.log.error( self.name + ": EOF exception found" )
1458 main.log.error( self.name + ": " + self.handle.before )
1459 main.cleanup()
1460 main.exit()
1461 except Exception:
1462 main.log.exception( self.name + ": Uncaught exception!" )
1463 main.cleanup()
1464 main.exit()
kelvin8ec71442015-01-15 16:57:00 -08001465
jenkins1e99e7b2015-04-02 18:15:39 -07001466 def tsharkGrep( self, grep, directory, interface='eth0', grepOptions='' ):
kelvin8ec71442015-01-15 16:57:00 -08001467 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001468 Required:
kelvin8ec71442015-01-15 16:57:00 -08001469 * grep string
andrewonlabba44bcf2014-10-16 16:54:41 -04001470 * directory to store results
1471 Optional:
1472 * interface - default: eth0
Jon Hall4ba53f02015-07-29 13:07:41 -07001473 * grepOptions - options for grep
andrewonlabba44bcf2014-10-16 16:54:41 -04001474 Description:
1475 Uses tshark command to grep specific group of packets
1476 and stores the results to specified directory.
kelvin8ec71442015-01-15 16:57:00 -08001477 The timestamp is hardcoded to be in epoch
1478 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001479 try:
1480 self.handle.sendline( "" )
1481 self.handle.expect( "\$" )
1482 self.handle.sendline( "" )
jenkins1e99e7b2015-04-02 18:15:39 -07001483 if grepOptions:
1484 grepStr = "grep "+str(grepOptions)
1485 else:
1486 grepStr = "grep"
Jon Hall4ba53f02015-07-29 13:07:41 -07001487
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001488 cmd = (
1489 "sudo tshark -i " +
Jon Hallfebb1c72015-03-05 13:30:09 -08001490 str( interface ) +
jenkins1e99e7b2015-04-02 18:15:39 -07001491 " -t e | " +
1492 grepStr + " --line-buffered \"" +
Jon Hallfebb1c72015-03-05 13:30:09 -08001493 str(grep) +
1494 "\" >" +
1495 directory +
1496 " &" )
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001497 self.handle.sendline(cmd)
1498 main.log.info(cmd)
Jon Hallfebb1c72015-03-05 13:30:09 -08001499 self.handle.expect( "Capturing on" )
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001500 self.handle.sendline( "\n" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001501 self.handle.expect( "\$" )
1502 except pexpect.EOF:
1503 main.log.error( self.name + ": EOF exception found" )
1504 main.log.error( self.name + ": " + self.handle.before )
1505 main.cleanup()
1506 main.exit()
1507 except Exception:
1508 main.log.exception( self.name + ": Uncaught exception!" )
1509 main.cleanup()
1510 main.exit()
1511
kelvin-onlabd3b64892015-01-20 13:26:24 -08001512 def tsharkStop( self ):
kelvin8ec71442015-01-15 16:57:00 -08001513 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001514 Removes wireshark files from /tmp and kills all tshark processes
kelvin8ec71442015-01-15 16:57:00 -08001515 """
1516 # Remove all pcap from previous captures
Jon Hallfebb1c72015-03-05 13:30:09 -08001517 try:
1518 self.execute( cmd="sudo rm /tmp/wireshark*" )
1519 self.handle.sendline( "" )
Jon Hallefbd9792015-03-05 16:11:36 -08001520 self.handle.sendline( "sudo kill -9 `ps -ef | grep \"tshark -i\"" +
1521 " | grep -v grep | awk '{print $2}'`" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001522 self.handle.sendline( "" )
1523 main.log.info( "Tshark stopped" )
1524 except pexpect.EOF:
1525 main.log.error( self.name + ": EOF exception found" )
1526 main.log.error( self.name + ": " + self.handle.before )
1527 main.cleanup()
1528 main.exit()
1529 except Exception:
1530 main.log.exception( self.name + ": Uncaught exception!" )
1531 main.cleanup()
1532 main.exit()
1533
kelvin8ec71442015-01-15 16:57:00 -08001534 def ptpd( self, args ):
1535 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001536 Initiate ptp with user-specified args.
1537 Required:
1538 * args: specify string of args after command
1539 'sudo ptpd'
kelvin8ec71442015-01-15 16:57:00 -08001540 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001541 try:
kelvin8ec71442015-01-15 16:57:00 -08001542 self.handle.sendline( "sudo ptpd " + str( args ) )
1543 i = self.handle.expect( [
andrewonlab0c38a4a2014-10-28 18:35:35 -04001544 "Multiple",
1545 "Error",
kelvin8ec71442015-01-15 16:57:00 -08001546 "\$" ] )
1547 self.handle.expect( "\$" )
andrewonlabba44bcf2014-10-16 16:54:41 -04001548
andrewonlab0c38a4a2014-10-28 18:35:35 -04001549 if i == 0:
1550 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001551 main.log.info( "ptpd returned an error: " +
1552 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001553 return handle
1554 elif i == 1:
1555 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001556 main.log.error( "ptpd returned an error: " +
1557 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001558 return handle
1559 else:
1560 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -08001561
andrewonlab0c38a4a2014-10-28 18:35:35 -04001562 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001563 main.log.error( self.name + ": EOF exception found" )
1564 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001565 main.cleanup()
1566 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001567 except Exception:
1568 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001569 main.cleanup()
1570 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001571
kelvin-onlabd3b64892015-01-20 13:26:24 -08001572 def cpLogsToDir( self, logToCopy,
Jon Hallefbd9792015-03-05 16:11:36 -08001573 destDir, copyFileName="" ):
kelvin8ec71442015-01-15 16:57:00 -08001574 """
1575 Copies logs to a desired directory.
andrewonlab5d7a8f32014-11-10 13:07:56 -05001576 Current implementation of ONOS deletes its karaf
1577 logs on every iteration. For debugging purposes,
kelvin8ec71442015-01-15 16:57:00 -08001578 you may want to use this function to capture
1579 certain karaf logs. ( or any other logs if needed )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001580 Localtime will be attached to the filename
1581
1582 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001583 * logToCopy: specify directory and log name to
andrewonlab5d7a8f32014-11-10 13:07:56 -05001584 copy.
kelvin8ec71442015-01-15 16:57:00 -08001585 ex ) /opt/onos/log/karaf.log.1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001586 For copying multiple files, leave copyFileName
1587 empty and only specify destDir -
kelvin8ec71442015-01-15 16:57:00 -08001588 ex ) /opt/onos/log/karaf*
kelvin-onlabd3b64892015-01-20 13:26:24 -08001589 * destDir: specify directory to copy to.
kelvin8ec71442015-01-15 16:57:00 -08001590 ex ) /tmp/
1591 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001592 * copyFileName: If you want to rename the log
1593 file, specify copyFileName. This will not work
andrewonlab5d7a8f32014-11-10 13:07:56 -05001594 with multiple file copying
kelvin8ec71442015-01-15 16:57:00 -08001595 """
andrewonlab5d7a8f32014-11-10 13:07:56 -05001596 try:
kelvin8ec71442015-01-15 16:57:00 -08001597 localtime = time.strftime( '%x %X' )
1598 localtime = localtime.replace( "/", "" )
1599 localtime = localtime.replace( " ", "_" )
1600 localtime = localtime.replace( ":", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001601 if destDir[ -1: ] != "/":
1602 destDir += "/"
andrewonlab5d7a8f32014-11-10 13:07:56 -05001603
kelvin-onlabd3b64892015-01-20 13:26:24 -08001604 if copyFileName:
Jon Hallfebb1c72015-03-05 13:30:09 -08001605 self.handle.sendline( "cp " + str( logToCopy ) + " " +
1606 str( destDir ) + str( copyFileName ) +
1607 localtime )
kelvin8ec71442015-01-15 16:57:00 -08001608 self.handle.expect( "cp" )
1609 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001610 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001611 self.handle.sendline( "cp " + str( logToCopy ) +
1612 " " + str( destDir ) )
kelvin8ec71442015-01-15 16:57:00 -08001613 self.handle.expect( "cp" )
1614 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001615
kelvin8ec71442015-01-15 16:57:00 -08001616 return self.handle.before
1617
1618 except pexpect.EOF:
1619 main.log.error( "Copying files failed" )
1620 main.log.error( self.name + ": EOF exception found" )
1621 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001622 except Exception:
1623 main.log.exception( "Copying files failed" )
1624
Jon Hall16b72c42015-05-20 10:23:36 -07001625 def checkLogs( self, onosIp, restart=False):
kelvin8ec71442015-01-15 16:57:00 -08001626 """
Jon Hall94fd0472014-12-08 11:52:42 -08001627 runs onos-check-logs on the given onos node
Jon Hall80daded2015-05-27 16:07:00 -07001628 If restart is True, use the old version of onos-check-logs which
1629 does not print the full stacktrace, but shows the entire log file,
1630 including across restarts
Jon Hall94fd0472014-12-08 11:52:42 -08001631 returns the response
kelvin8ec71442015-01-15 16:57:00 -08001632 """
Jon Hall94fd0472014-12-08 11:52:42 -08001633 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001634 cmd = "onos-check-logs " + str( onosIp )
Jon Hall16b72c42015-05-20 10:23:36 -07001635 if restart:
1636 cmd += " old"
kelvin8ec71442015-01-15 16:57:00 -08001637 self.handle.sendline( cmd )
1638 self.handle.expect( cmd )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001639 self.handle.expect( "\$ " )
Jon Hall94fd0472014-12-08 11:52:42 -08001640 response = self.handle.before
1641 return response
1642 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001643 main.log.error( "Lost ssh connection" )
1644 main.log.error( self.name + ": EOF exception found" )
1645 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001646 except Exception:
1647 main.log.exception( self.name + ": Uncaught exception!" )
1648 main.cleanup()
1649 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -08001650
kelvin-onlabd3b64892015-01-20 13:26:24 -08001651 def onosStatus( self, node="" ):
kelvin8ec71442015-01-15 16:57:00 -08001652 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001653 Calls onos command: 'onos-service [<node-ip>] status'
kelvin8ec71442015-01-15 16:57:00 -08001654 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001655 try:
kelvin8ec71442015-01-15 16:57:00 -08001656 self.handle.sendline( "" )
1657 self.handle.expect( "\$" )
1658 self.handle.sendline( "onos-service " + str( node ) +
1659 " status" )
1660 i = self.handle.expect( [
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001661 "start/running",
1662 "stop/waiting",
kelvin8ec71442015-01-15 16:57:00 -08001663 pexpect.TIMEOUT ], timeout=120 )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001664
1665 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001666 main.log.info( "ONOS is running" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001667 return main.TRUE
1668 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001669 main.log.info( "ONOS is stopped" )
kelvin8ec71442015-01-15 16:57:00 -08001670 main.log.error( "ONOS service failed to check the status" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001671 main.cleanup()
1672 main.exit()
1673 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001674 main.log.error( self.name + ": EOF exception found" )
1675 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001676 main.cleanup()
1677 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001678 except Exception:
1679 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001680 main.cleanup()
1681 main.exit()
Jon Hall21270ac2015-02-16 17:59:55 -08001682
Jon Hall63604932015-02-26 17:09:50 -08001683 def setIpTables( self, ip, port='', action='add', packet_type='',
1684 direction='INPUT', rule='DROP', states=True ):
Jon Hallefbd9792015-03-05 16:11:36 -08001685 """
Jon Hall21270ac2015-02-16 17:59:55 -08001686 Description:
1687 add or remove iptables rule to DROP (default) packets from
1688 specific IP and PORT
1689 Usage:
1690 * specify action ('add' or 'remove')
1691 when removing, pass in the same argument as you would add. It will
1692 delete that specific rule.
1693 * specify the ip to block
1694 * specify the destination port to block (defaults to all ports)
1695 * optional packet type to block (default tcp)
1696 * optional iptables rule (default DROP)
1697 * optional direction to block (default 'INPUT')
Jon Hall63604932015-02-26 17:09:50 -08001698 * States boolean toggles adding all supported tcp states to the
1699 firewall rule
Jon Hall21270ac2015-02-16 17:59:55 -08001700 Returns:
1701 main.TRUE on success or
1702 main.FALSE if given invalid input or
1703 main.ERROR if there is an error in response from iptables
1704 WARNING:
1705 * This function uses root privilege iptables command which may result
1706 in unwanted network errors. USE WITH CAUTION
Jon Hallefbd9792015-03-05 16:11:36 -08001707 """
Jon Hall21270ac2015-02-16 17:59:55 -08001708
1709 # NOTE*********
1710 # The strict checking methods of this driver function is intentional
1711 # to discourage any misuse or error of iptables, which can cause
1712 # severe network errors
1713 # *************
1714
1715 # NOTE: Sleep needed to give some time for rule to be added and
1716 # registered to the instance. If you are calling this function
1717 # multiple times this sleep will prevent any errors.
1718 # DO NOT REMOVE
Jon Hall63604932015-02-26 17:09:50 -08001719 # time.sleep( 5 )
Jon Hall21270ac2015-02-16 17:59:55 -08001720 try:
1721 # input validation
1722 action_type = action.lower()
1723 rule = rule.upper()
1724 direction = direction.upper()
1725 if action_type != 'add' and action_type != 'remove':
1726 main.log.error( "Invalid action type. Use 'add' or "
1727 "'remove' table rule" )
1728 if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
1729 # NOTE Currently only supports rules DROP, ACCEPT, and LOG
1730 main.log.error( "Invalid rule. Valid rules are 'DROP' or "
1731 "'ACCEPT' or 'LOG' only." )
1732 if direction != 'INPUT' and direction != 'OUTPUT':
1733 # NOTE currently only supports rules INPUT and OUPTUT
1734 main.log.error( "Invalid rule. Valid directions are"
1735 " 'OUTPUT' or 'INPUT'" )
1736 return main.FALSE
1737 return main.FALSE
1738 return main.FALSE
1739 if action_type == 'add':
1740 # -A is the 'append' action of iptables
1741 actionFlag = '-A'
1742 elif action_type == 'remove':
1743 # -D is the 'delete' rule of iptables
1744 actionFlag = '-D'
1745 self.handle.sendline( "" )
1746 self.handle.expect( "\$" )
1747 cmd = "sudo iptables " + actionFlag + " " +\
1748 direction +\
Jon Hall21270ac2015-02-16 17:59:55 -08001749 " -s " + str( ip )
Jon Hall63604932015-02-26 17:09:50 -08001750 # " -p " + str( packet_type ) +\
1751 if packet_type:
1752 cmd += " -p " + str( packet_type )
Jon Hall21270ac2015-02-16 17:59:55 -08001753 if port:
1754 cmd += " --dport " + str( port )
Jon Hall63604932015-02-26 17:09:50 -08001755 if states:
1756 cmd += " -m state --state="
1757 #FIXME- Allow user to configure which states to block
1758 cmd += "INVALID,ESTABLISHED,NEW,RELATED,UNTRACKED"
Jon Hall21270ac2015-02-16 17:59:55 -08001759 cmd += " -j " + str( rule )
1760
1761 self.handle.sendline( cmd )
1762 self.handle.expect( "\$" )
1763 main.log.warn( self.handle.before )
1764
1765 info_string = "On " + str( self.name )
1766 info_string += " " + str( action_type )
1767 info_string += " iptable rule [ "
1768 info_string += " IP: " + str( ip )
1769 info_string += " Port: " + str( port )
1770 info_string += " Rule: " + str( rule )
1771 info_string += " Direction: " + str( direction ) + " ]"
1772 main.log.info( info_string )
1773 return main.TRUE
1774 except pexpect.TIMEOUT:
1775 main.log.exception( self.name + ": Timeout exception in "
1776 "setIpTables function" )
1777 return main.ERROR
1778 except pexpect.EOF:
1779 main.log.error( self.name + ": EOF exception found" )
1780 main.log.error( self.name + ": " + self.handle.before )
1781 main.cleanup()
1782 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001783 except Exception:
1784 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall21270ac2015-02-16 17:59:55 -08001785 main.cleanup()
1786 main.exit()
1787
Jon Hall0468b042015-02-19 19:08:21 -08001788 def detailed_status(self, log_filename):
Jon Hallefbd9792015-03-05 16:11:36 -08001789 """
Jon Hall0468b042015-02-19 19:08:21 -08001790 This method is used by STS to check the status of the controller
1791 Reports RUNNING, STARTING, STOPPED, FROZEN, ERROR (and reason)
Jon Hallefbd9792015-03-05 16:11:36 -08001792 """
Jon Hall0468b042015-02-19 19:08:21 -08001793 import re
1794 try:
1795 self.handle.sendline( "" )
1796 self.handle.expect( "\$" )
1797 self.handle.sendline( "cd " + self.home )
1798 self.handle.expect( "\$" )
1799 self.handle.sendline( "service onos status" )
1800 self.handle.expect( "\$" )
1801 response = self.handle.before
1802 if re.search( "onos start/running", response ):
1803 # onos start/running, process 10457
1804 return 'RUNNING'
1805 # FIXME: Implement this case
1806 # elif re.search( pattern, response ):
1807 # return 'STARTING'
1808 elif re.search( "onos stop/", response ):
1809 # onos stop/waiting
1810 # FIXME handle this differently?: onos stop/pre-stop
1811 return 'STOPPED'
1812 # FIXME: Implement this case
1813 # elif re.search( pattern, response ):
1814 # return 'FROZEN'
1815 else:
1816 main.log.warn( self.name +
Jon Hallefbd9792015-03-05 16:11:36 -08001817 " WARNING: status received unknown response" )
Jon Hall0468b042015-02-19 19:08:21 -08001818 main.log.warn( response )
1819 return 'ERROR', "Unknown response: %s" % response
1820 except pexpect.TIMEOUT:
1821 main.log.exception( self.name + ": Timeout exception in "
1822 "setIpTables function" )
1823 return 'ERROR', "Pexpect Timeout"
1824 except pexpect.EOF:
1825 main.log.error( self.name + ": EOF exception found" )
1826 main.log.error( self.name + ": " + self.handle.before )
1827 main.cleanup()
1828 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001829 except Exception:
1830 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall0468b042015-02-19 19:08:21 -08001831 main.cleanup()
1832 main.exit()
1833
andrew@onlab.us3b087132015-03-11 15:00:08 -07001834 def createLinkGraphFile( self, benchIp, ONOSIpList, deviceCount):
1835 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07001836 Create/formats the LinkGraph.cfg file based on arguments
1837 -only creates a linear topology and connects islands
1838 -evenly distributes devices
andrew@onlab.us3b087132015-03-11 15:00:08 -07001839 -must be called by ONOSbench
1840
Jon Hall4ba53f02015-07-29 13:07:41 -07001841 ONOSIpList - list of all of the node IPs to be used
1842
1843 deviceCount - number of switches to be assigned
andrew@onlab.us3b087132015-03-11 15:00:08 -07001844 '''
1845 main.log.step("Creating link graph configuration file." )
1846 linkGraphPath = self.home + "/tools/package/etc/linkGraph.cfg"
Jon Hall4ba53f02015-07-29 13:07:41 -07001847 tempFile = "/tmp/linkGraph.cfg"
andrew@onlab.us3b087132015-03-11 15:00:08 -07001848
1849 linkGraph = open(tempFile, 'w+')
1850 linkGraph.write("# NullLinkProvider topology description (config file).\n")
1851 linkGraph.write("# The NodeId is only added if the destination is another node's device.\n")
1852 linkGraph.write("# Bugs: Comments cannot be appended to a line to be read.\n")
Jon Hall4ba53f02015-07-29 13:07:41 -07001853
andrew@onlab.us3b087132015-03-11 15:00:08 -07001854 clusterCount = len(ONOSIpList)
Jon Hall4ba53f02015-07-29 13:07:41 -07001855
1856 if type(deviceCount) is int or type(deviceCount) is str:
andrew@onlab.us3b087132015-03-11 15:00:08 -07001857 deviceCount = int(deviceCount)
1858 switchList = [0]*(clusterCount+1)
1859 baselineSwitchCount = deviceCount/clusterCount
Jon Hall4ba53f02015-07-29 13:07:41 -07001860
andrew@onlab.us3b087132015-03-11 15:00:08 -07001861 for node in range(1, clusterCount + 1):
1862 switchList[node] = baselineSwitchCount
1863
1864 for node in range(1, (deviceCount%clusterCount)+1):
1865 switchList[node] += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07001866
andrew@onlab.us3b087132015-03-11 15:00:08 -07001867 if type(deviceCount) is list:
1868 main.log.info("Using provided device distribution")
1869 switchList = [0]
1870 for i in deviceCount:
1871 switchList.append(int(i))
1872
1873 tempList = ['0']
1874 tempList.extend(ONOSIpList)
1875 ONOSIpList = tempList
1876
1877 myPort = 6
1878 lastSwitch = 0
1879 for node in range(1, clusterCount+1):
1880 if switchList[node] == 0:
1881 continue
1882
1883 linkGraph.write("graph " + ONOSIpList[node] + " {\n")
Jon Hall4ba53f02015-07-29 13:07:41 -07001884
andrew@onlab.us3b087132015-03-11 15:00:08 -07001885 if node > 1:
1886 #connect to last device on previous node
Jon Hall4ba53f02015-07-29 13:07:41 -07001887 line = ("\t0:5 -> " + str(lastSwitch) + ":6:" + lastIp + "\n") #ONOSIpList[node-1]
1888 linkGraph.write(line)
1889
1890 lastSwitch = 0
1891 for switch in range (0, switchList[node]-1):
andrew@onlab.us3b087132015-03-11 15:00:08 -07001892 line = ""
1893 line = ("\t" + str(switch) + ":" + str(myPort))
1894 line += " -- "
1895 line += (str(switch+1) + ":" + str(myPort-1) + "\n")
1896 linkGraph.write(line)
Jon Hall4ba53f02015-07-29 13:07:41 -07001897 lastSwitch = switch+1
andrew@onlab.us3b087132015-03-11 15:00:08 -07001898 lastIp = ONOSIpList[node]
Jon Hall4ba53f02015-07-29 13:07:41 -07001899
andrew@onlab.us3b087132015-03-11 15:00:08 -07001900 #lastSwitch += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07001901 if node < (clusterCount):
andrew@onlab.us3b087132015-03-11 15:00:08 -07001902 #connect to first device on the next node
Jon Hall4ba53f02015-07-29 13:07:41 -07001903 line = ("\t" + str(lastSwitch) + ":6 -> 0:5:" + ONOSIpList[node+1] + "\n")
andrew@onlab.us3b087132015-03-11 15:00:08 -07001904 linkGraph.write(line)
Jon Hall4ba53f02015-07-29 13:07:41 -07001905
andrew@onlab.us3b087132015-03-11 15:00:08 -07001906 linkGraph.write("}\n")
1907 linkGraph.close()
1908
1909 #SCP
Jon Hall4ba53f02015-07-29 13:07:41 -07001910 os.system( "scp " + tempFile + " " + self.user_name + "@" + benchIp + ":" + linkGraphPath)
andrew@onlab.us3b087132015-03-11 15:00:08 -07001911 main.log.info("linkGraph.cfg creation complete")
1912
cameron@onlab.us75900962015-03-30 13:22:49 -07001913 def configNullDev( self, ONOSIpList, deviceCount, numPorts=10):
Jon Hall4ba53f02015-07-29 13:07:41 -07001914
andrew@onlab.us3b087132015-03-11 15:00:08 -07001915 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07001916 ONOSIpList = list of Ip addresses of nodes switches will be devided amongst
1917 deviceCount = number of switches to distribute, or list of values to use as custom distribution
cameron@onlab.us75900962015-03-30 13:22:49 -07001918 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 -07001919 '''
1920
cameron@onlab.us75900962015-03-30 13:22:49 -07001921 main.log.step("Configuring Null Device Provider" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07001922 clusterCount = len(ONOSIpList)
1923
Jon Hall4ba53f02015-07-29 13:07:41 -07001924 try:
1925
cameron@onlab.us75900962015-03-30 13:22:49 -07001926 if type(deviceCount) is int or type(deviceCount) is str:
1927 main.log.step("Creating device distribution")
1928 deviceCount = int(deviceCount)
1929 switchList = [0]*(clusterCount+1)
1930 baselineSwitchCount = deviceCount/clusterCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001931
cameron@onlab.us75900962015-03-30 13:22:49 -07001932 for node in range(1, clusterCount + 1):
1933 switchList[node] = baselineSwitchCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001934
cameron@onlab.us75900962015-03-30 13:22:49 -07001935 for node in range(1, (deviceCount%clusterCount)+1):
1936 switchList[node] += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07001937
1938 if type(deviceCount) is list:
1939 main.log.info("Using provided device distribution")
1940
1941 if len(deviceCount) == clusterCount:
cameron@onlab.us75900962015-03-30 13:22:49 -07001942 switchList = ['0']
1943 switchList.extend(deviceCount)
Jon Hall4ba53f02015-07-29 13:07:41 -07001944
1945 if len(deviceCount) == (clusterCount + 1):
1946 if deviceCount[0] == '0' or deviceCount[0] == 0:
cameron@onlab.us75900962015-03-30 13:22:49 -07001947 switchList = deviceCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001948
cameron@onlab.us75900962015-03-30 13:22:49 -07001949 assert len(switchList) == (clusterCount + 1)
Jon Hall4ba53f02015-07-29 13:07:41 -07001950
cameron@onlab.us75900962015-03-30 13:22:49 -07001951 except AssertionError:
Jon Hall4ba53f02015-07-29 13:07:41 -07001952 main.log.error( "Bad device/Ip list match")
cameron@onlab.us75900962015-03-30 13:22:49 -07001953 except TypeError:
1954 main.log.exception( self.name + ": Object not as expected" )
1955 return None
Jon Hall77ba41c2015-04-06 10:25:40 -07001956 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07001957 main.log.exception( self.name + ": Uncaught exception!" )
1958 main.cleanup()
1959 main.exit()
1960
andrew@onlab.us3b087132015-03-11 15:00:08 -07001961
1962 ONOSIp = [0]
1963 ONOSIp.extend(ONOSIpList)
Jon Hall4ba53f02015-07-29 13:07:41 -07001964
andrew@onlab.us3b087132015-03-11 15:00:08 -07001965 devicesString = "devConfigs = "
1966 for node in range(1, len(ONOSIp)):
1967 devicesString += (ONOSIp[node] + ":" + str(switchList[node] ))
1968 if node < clusterCount:
1969 devicesString += (",")
Jon Hall4ba53f02015-07-29 13:07:41 -07001970
1971 try:
cameron@onlab.us75900962015-03-30 13:22:49 -07001972 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider devConfigs " + devicesString )
1973 self.handle.expect(":~")
1974 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider numPorts " + str(numPorts) )
1975 self.handle.expect(":~")
andrew@onlab.us3b087132015-03-11 15:00:08 -07001976
cameron@onlab.us75900962015-03-30 13:22:49 -07001977 for i in range(10):
1978 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.device.impl.NullDeviceProvider")
1979 self.handle.expect(":~")
1980 verification = self.handle.before
1981 if (" value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification:
1982 break
1983 else:
1984 time.sleep(1)
andrew@onlab.us3b087132015-03-11 15:00:08 -07001985
cameron@onlab.us2cc8bf12015-04-02 14:12:30 -07001986 assert ("value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification
Jon Hall4ba53f02015-07-29 13:07:41 -07001987
cameron@onlab.us75900962015-03-30 13:22:49 -07001988 except AssertionError:
1989 main.log.error("Incorrect Config settings: " + verification)
Jon Hall77ba41c2015-04-06 10:25:40 -07001990 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07001991 main.log.exception( self.name + ": Uncaught exception!" )
1992 main.cleanup()
1993 main.exit()
1994
Jon Hall4ba53f02015-07-29 13:07:41 -07001995 def configNullLink( self,fileName="/opt/onos/apache-karaf-3.0.3/etc/linkGraph.cfg", eventRate=0):
andrew@onlab.us3b087132015-03-11 15:00:08 -07001996 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07001997 fileName default is currently the same as the default on ONOS, specify alternate file if
cameron@onlab.us75900962015-03-30 13:22:49 -07001998 you want to use a different topology file than linkGraph.cfg
andrew@onlab.us3b087132015-03-11 15:00:08 -07001999 '''
2000
Jon Hall4ba53f02015-07-29 13:07:41 -07002001
2002 try:
2003 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider eventRate " + str(eventRate))
2004 self.handle.expect(":~")
cameron@onlab.us75900962015-03-30 13:22:49 -07002005 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider cfgFile " + fileName )
2006 self.handle.expect(":~")
Jon Hall4ba53f02015-07-29 13:07:41 -07002007
2008 for i in range(10):
2009 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.link.impl.NullLinkProvider")
cameron@onlab.us75900962015-03-30 13:22:49 -07002010 self.handle.expect(":~")
2011 verification = self.handle.before
Jon Hall4ba53f02015-07-29 13:07:41 -07002012 if (" value=" + str(eventRate)) in verification and (" value=" + fileName) in verification:
cameron@onlab.us75900962015-03-30 13:22:49 -07002013 break
Jon Hall4ba53f02015-07-29 13:07:41 -07002014 else:
cameron@onlab.us75900962015-03-30 13:22:49 -07002015 time.sleep(1)
Jon Hall4ba53f02015-07-29 13:07:41 -07002016
cameron@onlab.us75900962015-03-30 13:22:49 -07002017 assert ("value=" + str(eventRate)) in verification and (" value=" + fileName) in verification
Jon Hall4ba53f02015-07-29 13:07:41 -07002018
cameron@onlab.us75900962015-03-30 13:22:49 -07002019 except pexpect.EOF:
2020 main.log.error( self.name + ": EOF exception found" )
2021 main.log.error( self.name + ": " + self.handle.before )
2022 main.cleanup()
2023 main.exit()
cameron@onlab.us75900962015-03-30 13:22:49 -07002024 except AssertionError:
2025 main.log.info("Settings did not post to ONOS")
Jon Hall4ba53f02015-07-29 13:07:41 -07002026 main.log.error(varification)
Jon Hall77ba41c2015-04-06 10:25:40 -07002027 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002028 main.log.exception( self.name + ": Uncaught exception!" )
2029 main.log.error(varification)
2030 main.cleanup()
2031 main.exit()
andrew@onlab.us3b087132015-03-11 15:00:08 -07002032
kelvin-onlaba4074292015-07-09 15:19:49 -07002033 def getOnosIps( self ):
2034 """
2035 Get all onos IPs stored in
2036 """
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002037
kelvin-onlaba4074292015-07-09 15:19:49 -07002038 return sorted( self.onosIps.values() )
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002039
kelvin-onlaba4074292015-07-09 15:19:49 -07002040 def logReport( self, nodeIp, searchTerms, outputMode="s" ):
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002041 '''
2042 - accepts either a list or a string for "searchTerms" these
Jon Hall4ba53f02015-07-29 13:07:41 -07002043 terms will be searched for in the log and have their
2044 instances counted
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002045
Jon Hall4ba53f02015-07-29 13:07:41 -07002046 - nodeIp is the ip of the node whos log is to be scanned
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002047
Jon Hall4ba53f02015-07-29 13:07:41 -07002048 - output modes:
2049 "s" - Simple. Quiet output mode that just prints
2050 the occurences of each search term
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002051
cameron@onlab.us2e166212015-05-19 14:28:25 -07002052 "d" - Detailed. Prints number of occurences as well as the entire
Jon Hall4ba53f02015-07-29 13:07:41 -07002053 line for each of the last 5 occurences
cameron@onlab.us2e166212015-05-19 14:28:25 -07002054
2055 - returns total of the number of instances of all search terms
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002056 '''
2057 main.log.info("========================== Log Report ===========================\n")
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002058
Jon Hall4ba53f02015-07-29 13:07:41 -07002059 if type(searchTerms) is str:
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002060 searchTerms = [searchTerms]
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002061
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002062 logLines = [ [" "] for i in range(len(searchTerms)) ]
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002063
Jon Hall4ba53f02015-07-29 13:07:41 -07002064 for term in range(len(searchTerms)):
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002065 logLines[term][0] = searchTerms[term]
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002066
Jon Hall4ba53f02015-07-29 13:07:41 -07002067 totalHits = 0
2068 for term in range(len(searchTerms)):
2069 cmd = "onos-ssh " + nodeIp + " cat /opt/onos/log/karaf.log | grep " + searchTerms[term]
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002070 self.handle.sendline(cmd)
2071 self.handle.expect(":~")
2072 before = (self.handle.before).splitlines()
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002073
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002074 count = [searchTerms[term],0]
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002075
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002076 for line in before:
2077 if searchTerms[term] in line and "grep" not in line:
Jon Hall4ba53f02015-07-29 13:07:41 -07002078 count[1] += 1
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002079 if before.index(line) > ( len(before) - 7 ):
2080 logLines[term].append(line)
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002081
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002082 main.log.info( str(count[0]) + ": " + str(count[1]) )
Jon Hall4ba53f02015-07-29 13:07:41 -07002083 if term == len(searchTerms)-1:
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002084 print("\n")
Jon Hall4ba53f02015-07-29 13:07:41 -07002085 totalHits += int(count[1])
cameron@onlab.us2e166212015-05-19 14:28:25 -07002086
Jon Hall4ba53f02015-07-29 13:07:41 -07002087 if outputMode != "s" and outputMode != "S":
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002088 outputString = ""
2089 for i in logLines:
Jon Hall4ba53f02015-07-29 13:07:41 -07002090 outputString = i[0] + ": \n"
2091 for x in range(1,len(i)):
2092 outputString += ( i[x] + "\n" )
2093
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002094 if outputString != (i[0] + ": \n"):
Jon Hall4ba53f02015-07-29 13:07:41 -07002095 main.log.info(outputString)
2096
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002097 main.log.info("================================================================\n")
Hari Krishnabe4b97b2015-07-15 12:19:43 -07002098 return totalHits
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002099
2100 def copyMininetFile( self, fileName, localPath, userName, ip,
2101 mnPath='~/mininet/custom/', timeout = 60 ):
2102 """
2103 Description:
2104 Copy mininet topology file from dependency folder in the test folder
2105 and paste it to the mininet machine's mininet/custom folder
2106 Required:
2107 fileName - Name of the topology file to copy
2108 localPath - File path of the mininet topology file
2109 userName - User name of the mininet machine to send the file to
2110 ip - Ip address of the mininet machine
2111 Optional:
2112 mnPath - of the mininet directory to send the file to
2113 Return:
2114 Return main.TRUE if successfully copied the file otherwise
2115 return main.FALSE
2116 """
2117
2118 try:
2119 cmd = "scp " + localPath + fileName + " " + userName + "@" + \
2120 str( ip ) + ":" + mnPath + fileName
2121
2122 self.handle.sendline( "" )
2123 self.handle.expect( "\$" )
2124
2125 main.log.info( self.name + ": Execute: " + cmd )
2126
2127 self.handle.sendline( cmd )
2128
2129 i = self.handle.expect( [ 'No such file',
2130 "100%",
2131 pexpect.TIMEOUT ] )
2132
2133 if i == 0:
2134 main.log.error( self.name + ": File " + fileName +
2135 " does not exist!" )
2136 return main.FALSE
2137
2138 if i == 1:
2139 main.log.info( self.name + ": File " + fileName +
2140 " has been copied!" )
2141 self.handle.sendline( "" )
2142 self.handle.expect( "\$" )
2143 return main.TRUE
2144
2145 except pexpect.EOF:
2146 main.log.error( self.name + ": EOF exception found" )
2147 main.log.error( self.name + ": " + self.handle.before )
2148 main.cleanup()
2149 main.exit()
2150 except pexpect.TIMEOUT:
2151 main.log.error( self.name + ": TIMEOUT exception found" )
2152 main.log.error( self.name + ": " + self.handle.before )
2153 main.cleanup()
2154 main.exit()
cameron@onlab.us78b89652015-07-08 15:21:03 -07002155
2156 def jvmSet(self, memory=8):
Jon Hall4ba53f02015-07-29 13:07:41 -07002157
cameron@onlab.us78b89652015-07-08 15:21:03 -07002158 import os
2159
2160 homeDir = os.path.expanduser('~')
2161 filename = "/onos/tools/package/bin/onos-service"
2162
2163 serviceConfig = open(homeDir + filename, 'w+')
2164 serviceConfig.write("#!/bin/bash\n ")
2165 serviceConfig.write("#------------------------------------- \n ")
2166 serviceConfig.write("# Starts ONOS Apache Karaf container\n ")
2167 serviceConfig.write("#------------------------------------- \n ")
2168 serviceConfig.write("#export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-7-openjdk-amd64/}\n ")
2169 serviceConfig.write("""export JAVA_OPTS="${JAVA_OPTS:--Xms""" + str(memory) + "G -Xmx" + str(memory) + """G}" \n """)
2170 serviceConfig.write("[ -d $ONOS_HOME ] && cd $ONOS_HOME || ONOS_HOME=$(dirname $0)/..\n")
2171 serviceConfig.write("""${ONOS_HOME}/apache-karaf-$KARAF_VERSION/bin/karaf "$@" \n """)
2172 serviceConfig.close()
2173
2174 def createDBFile(self, testData):
Jon Hall4ba53f02015-07-29 13:07:41 -07002175
cameron@onlab.us78b89652015-07-08 15:21:03 -07002176 filename = main.TEST + "DB"
2177 DBString = ""
Jon Hall4ba53f02015-07-29 13:07:41 -07002178
cameron@onlab.us78b89652015-07-08 15:21:03 -07002179 for item in testData:
Jon Hall4ba53f02015-07-29 13:07:41 -07002180 if type(item) is string:
cameron@onlab.us78b89652015-07-08 15:21:03 -07002181 item = "'" + item + "'"
2182 if testData.index(item) < len(testData-1):
2183 item += ","
Jon Hall4ba53f02015-07-29 13:07:41 -07002184 DBString += str(item)
cameron@onlab.us78b89652015-07-08 15:21:03 -07002185
2186 DBFile = open(filename, "a")
2187 DBFile.write(DBString)
2188 DBFile.close()
2189
Jon Hall4ba53f02015-07-29 13:07:41 -07002190 def verifySummary(self, ONOSIp,*deviceCount):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002191
2192 self.handle.sendline("onos " + ONOSIp + " summary")
2193 self.handle.expect(":~")
2194
2195 summaryStr = self.handle.before
2196 print "\nSummary\n==============\n" + summaryStr + "\n\n"
2197
2198 #passed = "SCC(s)=1" in summaryStr
2199 #if deviceCount:
2200 # passed = "devices=" + str(deviceCount) + "," not in summaryStr
2201
GlennRC772363b2015-08-25 13:05:57 -07002202 passed = False
cameron@onlab.us78b89652015-07-08 15:21:03 -07002203 if "SCC(s)=1," in summaryStr:
2204 passed = True
2205 print("Summary is verifed")
Jon Hall4ba53f02015-07-29 13:07:41 -07002206 else:
2207 print("Summary failed")
cameron@onlab.us78b89652015-07-08 15:21:03 -07002208
2209 if deviceCount:
2210 print" ============================="
2211 checkStr = "devices=" + str(deviceCount[0]) + ","
2212 print "Checkstr: " + checkStr
2213 if checkStr not in summaryStr:
2214 passed = False
Jon Hall4ba53f02015-07-29 13:07:41 -07002215 print("Device count failed")
2216 else:
2217 print "device count verified"
cameron@onlab.us78b89652015-07-08 15:21:03 -07002218
2219 return passed