blob: 8e9b3e036bfbb8c966cc36c387fb95b1bf27957f [file] [log] [blame]
Jon Hall05b2b432014-10-08 19:53:25 -04001#!/usr/bin/env python
andrewonlabe8e56fd2014-10-09 17:12:44 -04002
kelvin8ec71442015-01-15 16:57:00 -08003"""
4This driver interacts with ONOS bench, the OSGi platform
5that configures the ONOS nodes. ( aka ONOS-next )
andrewonlabe8e56fd2014-10-09 17:12:44 -04006
kelvin8ec71442015-01-15 16:57:00 -08007Please follow the coding style demonstrated by existing
andrewonlabe8e56fd2014-10-09 17:12:44 -04008functions and document properly.
9
10If you are a contributor to the driver, please
11list your email here for future contact:
12
13jhall@onlab.us
14andrew@onlab.us
15
16OCT 9 2014
17
kelvin8ec71442015-01-15 16:57:00 -080018"""
andrewonlab7735d852014-10-09 13:02:47 -040019import sys
Jon Hall05b2b432014-10-08 19:53:25 -040020import time
Jon Hall6801cda2015-07-15 14:13:45 -070021import types
Jon Hall05b2b432014-10-08 19:53:25 -040022import pexpect
kelvin-onlaba4074292015-07-09 15:19:49 -070023import os
andrewonlab7735d852014-10-09 13:02:47 -040024import os.path
pingping-lin6d23d9e2015-02-02 16:54:24 -080025from requests.models import Response
kelvin8ec71442015-01-15 16:57:00 -080026sys.path.append( "../" )
Jon Hall05b2b432014-10-08 19:53:25 -040027from drivers.common.clidriver import CLI
28
Jon Hall05b2b432014-10-08 19:53:25 -040029
kelvin8ec71442015-01-15 16:57:00 -080030class OnosDriver( CLI ):
Jon Hall05b2b432014-10-08 19:53:25 -040031
kelvin8ec71442015-01-15 16:57:00 -080032 def __init__( self ):
33 """
34 Initialize client
35 """
Jon Hallefbd9792015-03-05 16:11:36 -080036 self.name = None
37 self.home = None
38 self.handle = None
kelvin8ec71442015-01-15 16:57:00 -080039 super( CLI, self ).__init__()
40
41 def connect( self, **connectargs ):
42 """
Jon Hall05b2b432014-10-08 19:53:25 -040043 Creates ssh handle for ONOS "bench".
kelvin-onlaba4074292015-07-09 15:19:49 -070044 NOTE:
45 The ip_address would come from the topo file using the host tag, the
46 value can be an environment variable as well as a "localhost" to get
47 the ip address needed to ssh to the "bench"
kelvin8ec71442015-01-15 16:57:00 -080048 """
Jon Hall05b2b432014-10-08 19:53:25 -040049 try:
50 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080051 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us3b087132015-03-11 15:00:08 -070052 self.home = "~/onos"
Jon Hall05b2b432014-10-08 19:53:25 -040053 for key in self.options:
54 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080055 self.home = self.options[ 'home' ]
Jon Hall05b2b432014-10-08 19:53:25 -040056 break
Jon Hall274b6642015-02-17 11:57:17 -080057 if self.home is None or self.home == "":
Jon Halle94919c2015-03-23 11:42:57 -070058 self.home = "~/onos"
Jon Hall21270ac2015-02-16 17:59:55 -080059
kelvin8ec71442015-01-15 16:57:00 -080060 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070061
kelvin-onlabc2b79102015-07-14 11:41:20 -070062 # The 'nodes' tag is optional and it is not required in .topo file
kelvin-onlaba4074292015-07-09 15:19:49 -070063 for key in self.options:
64 if key == "nodes":
kelvin-onlabc2b79102015-07-14 11:41:20 -070065 # Maximum number of ONOS nodes to run, if there is any
kelvin-onlaba4074292015-07-09 15:19:49 -070066 self.maxNodes = int( self.options[ 'nodes' ] )
67 break
68 self.maxNodes = None
69
kelvin-onlabc2b79102015-07-14 11:41:20 -070070 if self.maxNodes == None or self.maxNodes == "":
71 self.maxNodes = 100
kelvin-onlaba4074292015-07-09 15:19:49 -070072
kelvin-onlabc2b79102015-07-14 11:41:20 -070073
74 # Grabs all OC environment variables based on max number of nodes
kelvin-onlaba4074292015-07-09 15:19:49 -070075 self.onosIps = {} # Dictionary of all possible ONOS ip
76
77 try:
78 if self.maxNodes:
kelvin-onlaba4074292015-07-09 15:19:49 -070079 for i in range( self.maxNodes ):
80 envString = "OC" + str( i + 1 )
kelvin-onlabc2b79102015-07-14 11:41:20 -070081 # If there is no more OC# then break the loop
82 if os.getenv( envString ):
83 self.onosIps[ envString ] = os.getenv( envString )
84 else:
85 self.maxNodes = len( self.onosIps )
86 main.log.info( self.name +
87 ": Created cluster data with " +
88 str( self.maxNodes ) +
89 " maximum number" +
90 " of nodes" )
91 break
kelvin-onlaba4074292015-07-09 15:19:49 -070092
93 if not self.onosIps:
94 main.log.info( "Could not read any environment variable"
95 + " please load a cell file with all" +
96 " onos IP" )
97 else:
98 main.log.info( self.name + ": Found " +
99 str( self.onosIps.values() ) +
100 " ONOS IPs" )
kelvin-onlaba4074292015-07-09 15:19:49 -0700101 except KeyError:
102 main.log.info( "Invalid environment variable" )
103 except Exception as inst:
104 main.log.error( "Uncaught exception: " + str( inst ) )
105
106 try:
107 if os.getenv( str( self.ip_address ) ) != None:
108 self.ip_address = os.getenv( str( self.ip_address ) )
109 else:
110 main.log.info( self.name +
111 ": Trying to connect to " +
112 self.ip_address )
kelvin-onlaba4074292015-07-09 15:19:49 -0700113 except KeyError:
114 main.log.info( "Invalid host name," +
115 " connecting to local host instead" )
116 self.ip_address = 'localhost'
117 except Exception as inst:
118 main.log.error( "Uncaught exception: " + str( inst ) )
119
kelvin8ec71442015-01-15 16:57:00 -0800120 self.handle = super( OnosDriver, self ).connect(
121 user_name=self.user_name,
kelvin-onlab08679eb2015-01-21 16:11:48 -0800122 ip_address=self.ip_address,
kelvin-onlabd3b64892015-01-20 13:26:24 -0800123 port=self.port,
124 pwd=self.pwd,
125 home=self.home )
Jon Hall05b2b432014-10-08 19:53:25 -0400126
Jon Hall05b2b432014-10-08 19:53:25 -0400127 if self.handle:
Jon Hall0fc0d452015-07-14 09:49:58 -0700128 self.handle.sendline( "cd " + self.home )
129 self.handle.expect( "\$" )
Jon Hall05b2b432014-10-08 19:53:25 -0400130 return self.handle
kelvin8ec71442015-01-15 16:57:00 -0800131 else:
Jon Hall0fc0d452015-07-14 09:49:58 -0700132 main.log.info( "Failed to create ONOS handle" )
Jon Hall05b2b432014-10-08 19:53:25 -0400133 return main.FALSE
134 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800135 main.log.error( self.name + ": EOF exception found" )
136 main.log.error( self.name + ": " + self.handle.before )
Jon Hall05b2b432014-10-08 19:53:25 -0400137 main.cleanup()
138 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800139 except Exception:
140 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall05b2b432014-10-08 19:53:25 -0400141 main.cleanup()
142 main.exit()
143
kelvin8ec71442015-01-15 16:57:00 -0800144 def disconnect( self ):
145 """
Jon Hall05b2b432014-10-08 19:53:25 -0400146 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800147 """
Jon Halld61331b2015-02-17 16:35:47 -0800148 response = main.TRUE
Jon Hall05b2b432014-10-08 19:53:25 -0400149 try:
Jon Hall61282e32015-03-19 11:34:11 -0700150 if self.handle:
151 self.handle.sendline( "" )
152 self.handle.expect( "\$" )
153 self.handle.sendline( "exit" )
154 self.handle.expect( "closed" )
Jon Hall05b2b432014-10-08 19:53:25 -0400155 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800156 main.log.error( self.name + ": EOF exception found" )
157 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700158 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700159 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700160 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800161 except Exception:
162 main.log.exception( self.name + ": Connection failed to the host" )
Jon Hall05b2b432014-10-08 19:53:25 -0400163 response = main.FALSE
164 return response
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400165
andrew@onlab.usaee415a2015-06-05 14:38:58 -0400166 def getEpochMs( self ):
167 """
168 Returns milliseconds since epoch
169
170 When checking multiple nodes in a for loop,
171 around a hundred milliseconds of difference (ascending) is
172 generally acceptable due to calltime of the function.
173 Few seconds, however, is not and it means clocks
174 are off sync.
175 """
176 try:
177 self.handle.sendline( 'date +%s.%N' )
178 self.handle.expect( 'date \+\%s\.\%N' )
179 self.handle.expect( '\$' )
180 epochMs = self.handle.before
181 return epochMs
182 except Exception:
183 main.log.exception( 'Uncaught exception getting epoch time' )
184 main.cleanup()
185 main.exit()
186
pingping-lin57a56ce2015-05-20 16:43:48 -0700187 def onosPackage( self, opTimeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800188 """
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400189 Produce a self-contained tar.gz file that can be deployed
kelvin8ec71442015-01-15 16:57:00 -0800190 and executed on any platform with Java 7 JRE.
191 """
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400192 try:
kelvin8ec71442015-01-15 16:57:00 -0800193 self.handle.sendline( "onos-package" )
194 self.handle.expect( "onos-package" )
pingping-lin57a56ce2015-05-20 16:43:48 -0700195 self.handle.expect( "tar.gz", opTimeout )
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 )
andrewonlab8790abb2014-11-06 13:51:54 -0500225
kelvin8ec71442015-01-15 16:57:00 -0800226 main.log.info( "onos-build command returned: " +
227 handle )
andrewonlab8790abb2014-11-06 13:51:54 -0500228
229 if i == 0:
230 return main.TRUE
231 else:
232 return handle
233
234 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800235 main.log.error( self.name + ": EOF exception found" )
236 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -0800237 except Exception:
238 main.log.exception( "Failed to build ONOS" )
andrewonlab8790abb2014-11-06 13:51:54 -0500239 main.cleanup()
240 main.exit()
241
shahshreya9f531fe2015-06-10 12:03:51 -0700242 def cleanInstall( self, skipTest=False, mciTimeout=600 ):
kelvin8ec71442015-01-15 16:57:00 -0800243 """
244 Runs mvn clean install in the root of the ONOS directory.
245 This will clean all ONOS artifacts then compile each module
shahshreya9f531fe2015-06-10 12:03:51 -0700246 Optional:
247 skipTest - Does "-DskipTests -Dcheckstyle.skip -U -T 1C" which
248 skip the test. This will make the building faster.
249 Disregarding the credibility of the build
kelvin8ec71442015-01-15 16:57:00 -0800250 Returns: main.TRUE on success
Jon Hallde9d9aa2014-10-08 20:36:02 -0400251 On Failure, exits the test
kelvin8ec71442015-01-15 16:57:00 -0800252 """
Jon Hallde9d9aa2014-10-08 20:36:02 -0400253 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800254 main.log.info( "Running 'mvn clean install' on " +
255 str( self.name ) +
kelvin8ec71442015-01-15 16:57:00 -0800256 ". This may take some time." )
257 self.handle.sendline( "cd " + self.home )
258 self.handle.expect( "\$" )
Jon Hallea7818b2014-10-09 14:30:59 -0400259
kelvin8ec71442015-01-15 16:57:00 -0800260 self.handle.sendline( "" )
261 self.handle.expect( "\$" )
shahshreya9f531fe2015-06-10 12:03:51 -0700262
263 if not skipTest:
264 self.handle.sendline( "mvn clean install" )
265 self.handle.expect( "mvn clean install" )
266 else:
267 self.handle.sendline( "mvn clean install -DskipTests" +
268 " -Dcheckstyle.skip -U -T 1C" )
269 self.handle.expect( "mvn clean install -DskipTests" +
270 " -Dcheckstyle.skip -U -T 1C" )
kelvin8ec71442015-01-15 16:57:00 -0800271 while True:
272 i = self.handle.expect( [
Jon Hall274b6642015-02-17 11:57:17 -0800273 'There\sis\sinsufficient\smemory\sfor\sthe\sJava\s' +
Jon Hallefbd9792015-03-05 16:11:36 -0800274 'Runtime\sEnvironment\sto\scontinue',
Jon Hallde9d9aa2014-10-08 20:36:02 -0400275 'BUILD\sFAILURE',
276 'BUILD\sSUCCESS',
Jon Halle94919c2015-03-23 11:42:57 -0700277 'onos\$', #TODO: fix this to be more generic?
Jon Hallde9d9aa2014-10-08 20:36:02 -0400278 'ONOS\$',
pingping-lin57a56ce2015-05-20 16:43:48 -0700279 pexpect.TIMEOUT ], mciTimeout )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400280 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800281 main.log.error( self.name + ":There is insufficient memory \
282 for the Java Runtime Environment to continue." )
283 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400284 main.cleanup()
285 main.exit()
286 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800287 main.log.error( self.name + ": Build failure!" )
288 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400289 main.cleanup()
290 main.exit()
291 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800292 main.log.info( self.name + ": Build success!" )
Jon Halle94919c2015-03-23 11:42:57 -0700293 elif i == 3 or i == 4:
kelvin8ec71442015-01-15 16:57:00 -0800294 main.log.info( self.name + ": Build complete" )
295 # Print the build time
Jon Hallf8ef52c2014-10-09 19:37:33 -0400296 for line in self.handle.before.splitlines():
297 if "Total time:" in line:
kelvin8ec71442015-01-15 16:57:00 -0800298 main.log.info( line )
299 self.handle.sendline( "" )
300 self.handle.expect( "\$", timeout=60 )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400301 return main.TRUE
Jon Halle94919c2015-03-23 11:42:57 -0700302 elif i == 5:
kelvin8ec71442015-01-15 16:57:00 -0800303 main.log.error(
304 self.name +
305 ": mvn clean install TIMEOUT!" )
306 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400307 main.cleanup()
308 main.exit()
309 else:
Jon Hall274b6642015-02-17 11:57:17 -0800310 main.log.error( self.name + ": unexpected response from " +
Jon Hallefbd9792015-03-05 16:11:36 -0800311 "mvn clean install" )
kelvin8ec71442015-01-15 16:57:00 -0800312 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400313 main.cleanup()
314 main.exit()
315 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800316 main.log.error( self.name + ": EOF exception found" )
317 main.log.error( self.name + ": " + self.handle.before )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400318 main.cleanup()
319 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800320 except Exception:
321 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400322 main.cleanup()
323 main.exit()
Jon Hallacabffd2014-10-09 12:36:53 -0400324
Jon Hall61282e32015-03-19 11:34:11 -0700325 def gitPull( self, comp1="", fastForward=True ):
kelvin8ec71442015-01-15 16:57:00 -0800326 """
Jon Hallacabffd2014-10-09 12:36:53 -0400327 Assumes that "git pull" works without login
Jon Hall47a93fb2015-01-06 16:46:06 -0800328
Jon Hall61282e32015-03-19 11:34:11 -0700329 If the fastForward boolean is set to true, only git pulls that can
330 be fast forwarded will be performed. IE if you have not local commits
331 in your branch.
332
Jon Hallacabffd2014-10-09 12:36:53 -0400333 This function will perform a git pull on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800334 If used as gitPull( "NODE" ) it will do git pull + NODE. This is
Jon Hallacabffd2014-10-09 12:36:53 -0400335 for the purpose of pulling from other nodes if necessary.
336
Jon Hall47a93fb2015-01-06 16:46:06 -0800337 Otherwise, this function will perform a git pull in the
Jon Hallacabffd2014-10-09 12:36:53 -0400338 ONOS repository. If it has any problems, it will return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -0800339 If it successfully does a gitPull, it will return a 1 ( main.TRUE )
Shreya Shahee15f6c2014-10-28 18:12:30 -0400340 If it has no updates, it will return 3.
Jon Hallacabffd2014-10-09 12:36:53 -0400341
kelvin8ec71442015-01-15 16:57:00 -0800342 """
Jon Hallacabffd2014-10-09 12:36:53 -0400343 try:
kelvin8ec71442015-01-15 16:57:00 -0800344 # main.log.info( self.name + ": Stopping ONOS" )
345 # self.stop()
346 self.handle.sendline( "cd " + self.home )
kelvin-onlaba1484582015-02-02 15:46:20 -0800347 self.handle.expect( self.home + "\$" )
Jon Hall61282e32015-03-19 11:34:11 -0700348 cmd = "git pull"
349 if comp1 != "":
350 cmd += ' ' + comp1
351 if fastForward:
352 cmd += ' ' + " --ff-only"
353 self.handle.sendline( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800354 i = self.handle.expect(
355 [
356 'fatal',
357 'Username\sfor\s(.*):\s',
358 '\sfile(s*) changed,\s',
359 'Already up-to-date',
360 'Aborting',
361 'You\sare\snot\scurrently\son\sa\sbranch',
Jon Hall274b6642015-02-17 11:57:17 -0800362 'You asked me to pull without telling me which branch you',
363 'Pull is not possible because you have unmerged files',
Jon Hall61282e32015-03-19 11:34:11 -0700364 'Please enter a commit message to explain why this merge',
365 'Found a swap file by the name',
366 'Please, commit your changes before you can merge.',
kelvin-onlabd3b64892015-01-20 13:26:24 -0800367 pexpect.TIMEOUT ],
368 timeout=300 )
kelvin8ec71442015-01-15 16:57:00 -0800369 # debug
kelvin-onlabd3b64892015-01-20 13:26:24 -0800370 # main.log.report( self.name +": DEBUG: \n"+
371 # "git pull response: " +
372 # str( self.handle.before ) + str( self.handle.after ) )
kelvin8ec71442015-01-15 16:57:00 -0800373 if i == 0:
Jon Hall61282e32015-03-19 11:34:11 -0700374 main.log.error( self.name + ": Git pull had some issue" )
375 output = self.handle.after
376 self.handle.expect( '\$' )
377 output += self.handle.before
378 main.log.warn( output )
Jon Hallacabffd2014-10-09 12:36:53 -0400379 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800380 elif i == 1:
381 main.log.error(
382 self.name +
383 ": Git Pull Asking for username. " )
Jon Hallacabffd2014-10-09 12:36:53 -0400384 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800385 elif i == 2:
386 main.log.info(
387 self.name +
388 ": Git Pull - pulling repository now" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800389 self.handle.expect( self.home + "\$", 120 )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800390 # So that only when git pull is done, we do mvn clean compile
391 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800392 elif i == 3:
393 main.log.info( self.name + ": Git Pull - Already up to date" )
Jon Hall47a93fb2015-01-06 16:46:06 -0800394 return i
kelvin8ec71442015-01-15 16:57:00 -0800395 elif i == 4:
396 main.log.info(
397 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800398 ": Git Pull - Aborting..." +
399 "Are there conflicting git files?" )
Jon Hallacabffd2014-10-09 12:36:53 -0400400 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800401 elif i == 5:
402 main.log.info(
403 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800404 ": Git Pull - You are not currently " +
405 "on a branch so git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400406 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800407 elif i == 6:
408 main.log.info(
409 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800410 ": Git Pull - You have not configured an upstream " +
411 "branch to pull from. Git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400412 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800413 elif i == 7:
414 main.log.info(
415 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800416 ": Git Pull - Pull is not possible because " +
417 "you have unmerged files." )
Jon Hallacabffd2014-10-09 12:36:53 -0400418 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800419 elif i == 8:
Jon Hall61282e32015-03-19 11:34:11 -0700420 # NOTE: abandoning test since we can't reliably handle this
421 # there could be different default text editors and we
422 # also don't know if we actually want to make the commit
423 main.log.error( "Git pull resulted in a merge commit message" +
424 ". Exiting test!" )
425 main.cleanup()
426 main.exit()
427 elif i == 9: # Merge commit message but swap file exists
428 main.log.error( "Git pull resulted in a merge commit message" +
429 " but a swap file exists." )
430 try:
431 self.handle.send( 'A' ) # Abort
432 self.handle.expect( "\$" )
433 return main.ERROR
434 except Exception:
435 main.log.exception( "Couldn't exit editor prompt!")
436 main.cleanup()
437 main.exit()
438 elif i == 10: # In the middle of a merge commit
439 main.log.error( "Git branch is in the middle of a merge. " )
440 main.log.warn( self.handle.before + self.handle.after )
441 return main.ERROR
442 elif i == 11:
kelvin8ec71442015-01-15 16:57:00 -0800443 main.log.error( self.name + ": Git Pull - TIMEOUT" )
444 main.log.error(
445 self.name + " Response was: " + str(
446 self.handle.before ) )
Jon Hallacabffd2014-10-09 12:36:53 -0400447 return main.ERROR
448 else:
kelvin8ec71442015-01-15 16:57:00 -0800449 main.log.error(
450 self.name +
451 ": Git Pull - Unexpected response, check for pull errors" )
Jon Hallacabffd2014-10-09 12:36:53 -0400452 return main.ERROR
453 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800454 main.log.error( self.name + ": EOF exception found" )
455 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400456 main.cleanup()
457 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800458 except Exception:
459 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400460 main.cleanup()
461 main.exit()
462
kelvin-onlabd3b64892015-01-20 13:26:24 -0800463 def gitCheckout( self, branch="master" ):
kelvin8ec71442015-01-15 16:57:00 -0800464 """
Jon Hallacabffd2014-10-09 12:36:53 -0400465 Assumes that "git pull" works without login
kelvin8ec71442015-01-15 16:57:00 -0800466
Jon Hallacabffd2014-10-09 12:36:53 -0400467 This function will perform a git git checkout on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800468 If used as gitCheckout( "branch" ) it will do git checkout
469 of the "branch".
Jon Hallacabffd2014-10-09 12:36:53 -0400470
471 Otherwise, this function will perform a git checkout of the master
kelvin8ec71442015-01-15 16:57:00 -0800472 branch of the ONOS repository. If it has any problems, it will return
473 main.ERROR.
474 If the branch was already the specified branch, or the git checkout was
Jon Hallacabffd2014-10-09 12:36:53 -0400475 successful then the function will return main.TRUE.
476
kelvin8ec71442015-01-15 16:57:00 -0800477 """
Jon Hallacabffd2014-10-09 12:36:53 -0400478 try:
kelvin8ec71442015-01-15 16:57:00 -0800479 self.handle.sendline( "cd " + self.home )
kelvin-onlaba1484582015-02-02 15:46:20 -0800480 self.handle.expect( self.home + "\$" )
Jon Hall274b6642015-02-17 11:57:17 -0800481 main.log.info( self.name +
482 ": Checking out git branch/ref: " + branch + "..." )
kelvin8ec71442015-01-15 16:57:00 -0800483 cmd = "git checkout " + branch
484 self.handle.sendline( cmd )
485 self.handle.expect( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800486 i = self.handle.expect(
Jon Hall274b6642015-02-17 11:57:17 -0800487 [ 'fatal',
Jon Hall61282e32015-03-19 11:34:11 -0700488 'Username for (.*): ',
489 'Already on \'',
Jon Hall7a8354f2015-06-10 15:37:00 -0700490 'Switched to (a new )?branch \'' + str( branch ),
Jon Hall274b6642015-02-17 11:57:17 -0800491 pexpect.TIMEOUT,
492 'error: Your local changes to the following files' +
Jon Hallefbd9792015-03-05 16:11:36 -0800493 'would be overwritten by checkout:',
Jon Hall274b6642015-02-17 11:57:17 -0800494 'error: you need to resolve your current index first',
495 "You are in 'detached HEAD' state.",
496 "HEAD is now at " ],
kelvin-onlabd3b64892015-01-20 13:26:24 -0800497 timeout=60 )
kelvin8ec71442015-01-15 16:57:00 -0800498 if i == 0:
499 main.log.error(
500 self.name +
501 ": Git checkout had some issue..." )
502 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400503 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800504 elif i == 1:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800505 main.log.error(
506 self.name +
507 ": Git checkout asking for username." +
508 " Please configure your local git repository to be able " +
509 "to access your remote repository passwordlessly" )
Jon Hall274b6642015-02-17 11:57:17 -0800510 # TODO add support for authenticating
Jon Hallacabffd2014-10-09 12:36:53 -0400511 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800512 elif i == 2:
513 main.log.info(
514 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800515 ": Git Checkout %s : Already on this branch" % branch )
kelvin-onlaba1484582015-02-02 15:46:20 -0800516 self.handle.expect( self.home + "\$" )
kelvin8ec71442015-01-15 16:57:00 -0800517 # main.log.info( "DEBUG: after checkout cmd = "+
518 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400519 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800520 elif i == 3:
521 main.log.info(
522 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800523 ": Git checkout %s - Switched to this branch" % branch )
kelvin-onlaba1484582015-02-02 15:46:20 -0800524 self.handle.expect( self.home + "\$" )
kelvin8ec71442015-01-15 16:57:00 -0800525 # main.log.info( "DEBUG: after checkout cmd = "+
526 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400527 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800528 elif i == 4:
529 main.log.error( self.name + ": Git Checkout- TIMEOUT" )
530 main.log.error(
Jon Hall274b6642015-02-17 11:57:17 -0800531 self.name + " Response was: " + str( self.handle.before ) )
Jon Hallacabffd2014-10-09 12:36:53 -0400532 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800533 elif i == 5:
534 self.handle.expect( "Aborting" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800535 main.log.error(
536 self.name +
537 ": Git checkout error: \n" +
Jon Hall274b6642015-02-17 11:57:17 -0800538 "Your local changes to the following files would" +
539 " be overwritten by checkout:" +
540 str( self.handle.before ) )
kelvin-onlaba1484582015-02-02 15:46:20 -0800541 self.handle.expect( self.home + "\$" )
Jon Hall81e29af2014-11-04 20:41:23 -0500542 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800543 elif i == 6:
Jon Hall274b6642015-02-17 11:57:17 -0800544 main.log.error(
545 self.name +
546 ": Git checkout error: \n" +
547 "You need to resolve your current index first:" +
548 str( self.handle.before ) )
kelvin-onlaba1484582015-02-02 15:46:20 -0800549 self.handle.expect( self.home + "\$" )
Jon Hall81e29af2014-11-04 20:41:23 -0500550 return main.ERROR
Jon Hall274b6642015-02-17 11:57:17 -0800551 elif i == 7:
552 main.log.info(
553 self.name +
554 ": Git checkout " + str( branch ) +
555 " - You are in 'detached HEAD' state. HEAD is now at " +
556 str( branch ) )
557 self.handle.expect( self.home + "\$" )
558 return main.TRUE
559 elif i == 8: # Already in detached HEAD on the specified commit
560 main.log.info(
561 self.name +
562 ": Git Checkout %s : Already on commit" % branch )
563 self.handle.expect( self.home + "\$" )
564 return main.TRUE
Jon Hallacabffd2014-10-09 12:36:53 -0400565 else:
kelvin8ec71442015-01-15 16:57:00 -0800566 main.log.error(
567 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800568 ": Git Checkout - Unexpected response, " +
569 "check for pull errors" )
kelvin8ec71442015-01-15 16:57:00 -0800570 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400571 return main.ERROR
572
573 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800574 main.log.error( self.name + ": EOF exception found" )
575 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400576 main.cleanup()
577 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800578 except Exception:
579 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400580 main.cleanup()
581 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400582
pingping-lin6d23d9e2015-02-02 16:54:24 -0800583 def getBranchName( self ):
pingping-linf30cf272015-05-29 15:54:07 -0700584 main.log.info( "self.home = " )
585 main.log.info( self.home )
pingping-lin6d23d9e2015-02-02 16:54:24 -0800586 self.handle.sendline( "cd " + self.home )
pingping-lin9bf3d8f2015-05-29 16:05:28 -0700587 self.handle.expect( self.home + "\$" )
pingping-lin6d23d9e2015-02-02 16:54:24 -0800588 self.handle.sendline( "git name-rev --name-only HEAD" )
589 self.handle.expect( "git name-rev --name-only HEAD" )
590 self.handle.expect( "\$" )
591
592 lines = self.handle.before.splitlines()
593 if lines[1] == "master":
594 return "master"
595 elif lines[1] == "onos-1.0":
596 return "onos-1.0"
597 else:
598 main.log.info( lines[1] )
599 return "unexpected ONOS branch for SDN-IP test"
600
kelvin-onlabd3b64892015-01-20 13:26:24 -0800601 def getVersion( self, report=False ):
kelvin8ec71442015-01-15 16:57:00 -0800602 """
Jon Hall274b6642015-02-17 11:57:17 -0800603 Writes the COMMIT number to the report to be parsed
Jon Hallefbd9792015-03-05 16:11:36 -0800604 by Jenkins data collector.
kelvin8ec71442015-01-15 16:57:00 -0800605 """
Jon Hall45ec0922014-10-10 19:33:49 -0400606 try:
kelvin8ec71442015-01-15 16:57:00 -0800607 self.handle.sendline( "" )
608 self.handle.expect( "\$" )
609 self.handle.sendline(
610 "cd " +
611 self.home +
Jon Hall274b6642015-02-17 11:57:17 -0800612 "; git log -1 --pretty=fuller --decorate=short | grep -A 6 " +
613 " \"commit\" --color=never" )
kelvin8ec71442015-01-15 16:57:00 -0800614 # NOTE: for some reason there are backspaces inserted in this
615 # phrase when run from Jenkins on some tests
616 self.handle.expect( "never" )
617 self.handle.expect( "\$" )
618 response = ( self.name + ": \n" + str(
619 self.handle.before + self.handle.after ) )
620 self.handle.sendline( "cd " + self.home )
621 self.handle.expect( "\$" )
622 lines = response.splitlines()
Jon Hall45ec0922014-10-10 19:33:49 -0400623 for line in lines:
Jon Hallfd191202014-11-07 18:36:09 -0500624 print line
625 if report:
pingping-lin763ee042015-05-20 17:45:30 -0700626 main.log.wiki( "<blockquote>" )
kelvin8ec71442015-01-15 16:57:00 -0800627 for line in lines[ 2:-1 ]:
628 # Bracket replacement is for Wiki-compliant
629 # formatting. '<' or '>' are interpreted
630 # as xml specific tags that cause errors
631 line = line.replace( "<", "[" )
632 line = line.replace( ">", "]" )
pingping-lin763ee042015-05-20 17:45:30 -0700633 #main.log.wiki( "\t" + line )
634 main.log.wiki( line + "<br /> " )
635 main.log.summary( line )
636 main.log.wiki( "</blockquote>" )
637 main.log.summary("\n")
kelvin8ec71442015-01-15 16:57:00 -0800638 return lines[ 2 ]
Jon Hall45ec0922014-10-10 19:33:49 -0400639 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800640 main.log.error( self.name + ": EOF exception found" )
641 main.log.error( self.name + ": " + self.handle.before )
Jon Hall45ec0922014-10-10 19:33:49 -0400642 main.cleanup()
643 main.exit()
Jon Hall368769f2014-11-19 15:43:35 -0800644 except pexpect.TIMEOUT:
kelvin8ec71442015-01-15 16:57:00 -0800645 main.log.error( self.name + ": TIMEOUT exception found" )
646 main.log.error( self.name + ": " + self.handle.before )
Jon Hall368769f2014-11-19 15:43:35 -0800647 main.cleanup()
648 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800649 except Exception:
650 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall45ec0922014-10-10 19:33:49 -0400651 main.cleanup()
652 main.exit()
653
kelvin-onlabd3b64892015-01-20 13:26:24 -0800654 def createCellFile( self, benchIp, fileName, mnIpAddrs,
kelvin-onlaba4074292015-07-09 15:19:49 -0700655 appString, onosIpAddrs ):
kelvin8ec71442015-01-15 16:57:00 -0800656 """
andrewonlab94282092014-10-10 13:00:11 -0400657 Creates a cell file based on arguments
658 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800659 * Bench IP address ( benchIp )
andrewonlab94282092014-10-10 13:00:11 -0400660 - Needed to copy the cell file over
kelvin-onlabd3b64892015-01-20 13:26:24 -0800661 * File name of the cell file ( fileName )
662 * Mininet IP address ( mnIpAddrs )
kelvin8ec71442015-01-15 16:57:00 -0800663 - Note that only 1 ip address is
andrewonlab94282092014-10-10 13:00:11 -0400664 supported currently
kelvin-onlabd3b64892015-01-20 13:26:24 -0800665 * ONOS IP addresses ( onosIpAddrs )
andrewonlab94282092014-10-10 13:00:11 -0400666 - Must be passed in as last arguments
kelvin8ec71442015-01-15 16:57:00 -0800667
andrewonlab94282092014-10-10 13:00:11 -0400668 NOTE: Assumes cells are located at:
669 ~/<self.home>/tools/test/cells/
kelvin8ec71442015-01-15 16:57:00 -0800670 """
671 # Variable initialization
Jon Hall6801cda2015-07-15 14:13:45 -0700672 cellDirectory = self.home + "/tools/test/cells/"
kelvin8ec71442015-01-15 16:57:00 -0800673 # We want to create the cell file in the dependencies directory
674 # of TestON first, then copy over to ONOS bench
kelvin-onlabd3b64892015-01-20 13:26:24 -0800675 tempDirectory = "/tmp/"
kelvin8ec71442015-01-15 16:57:00 -0800676 # Create the cell file in the directory for writing ( w+ )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800677 cellFile = open( tempDirectory + fileName, 'w+' )
Jon Hall6801cda2015-07-15 14:13:45 -0700678 if isinstance( onosIpAddrs, types.StringType ):
679 onosIpAddrs = [ onosIpAddrs ]
kelvin8ec71442015-01-15 16:57:00 -0800680
cameron@onlab.us75900962015-03-30 13:22:49 -0700681 # App string is hardcoded environment variables
kelvin8ec71442015-01-15 16:57:00 -0800682 # That you may wish to use by default on startup.
cameron@onlab.us75900962015-03-30 13:22:49 -0700683 # Note that you may not want certain apps listed
kelvin8ec71442015-01-15 16:57:00 -0800684 # on here.
cameron@onlab.us75900962015-03-30 13:22:49 -0700685 appString = "export ONOS_APPS=" + appString
kelvin-onlabd3b64892015-01-20 13:26:24 -0800686 mnString = "export OCN="
kelvin-onlabf70fd542015-05-07 18:41:40 -0700687 if mnIpAddrs == "":
688 mnString = ""
kelvin-onlabd3b64892015-01-20 13:26:24 -0800689 onosString = "export OC"
690 tempCount = 1
kelvin8ec71442015-01-15 16:57:00 -0800691
kelvin-onlabd3b64892015-01-20 13:26:24 -0800692 # Create ONOSNIC ip address prefix
kelvin-onlaba4074292015-07-09 15:19:49 -0700693 tempOnosIp = str( onosIpAddrs[ 0 ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800694 tempList = []
695 tempList = tempOnosIp.split( "." )
kelvin8ec71442015-01-15 16:57:00 -0800696 # Omit last element of list to format for NIC
kelvin-onlabd3b64892015-01-20 13:26:24 -0800697 tempList = tempList[ :-1 ]
kelvin8ec71442015-01-15 16:57:00 -0800698 # Structure the nic string ip
kelvin-onlabd3b64892015-01-20 13:26:24 -0800699 nicAddr = ".".join( tempList ) + ".*"
700 onosNicString = "export ONOS_NIC=" + nicAddr
andrewonlab94282092014-10-10 13:00:11 -0400701
702 try:
kelvin8ec71442015-01-15 16:57:00 -0800703 # Start writing to file
kelvin-onlabd3b64892015-01-20 13:26:24 -0800704 cellFile.write( onosNicString + "\n" )
andrewonlab94282092014-10-10 13:00:11 -0400705
kelvin-onlabd3b64892015-01-20 13:26:24 -0800706 for arg in onosIpAddrs:
707 # For each argument in onosIpAddrs, write to file
kelvin8ec71442015-01-15 16:57:00 -0800708 # Output should look like the following:
andrewonlabd4940492014-10-24 12:21:27 -0400709 # export OC1="10.128.20.11"
710 # export OC2="10.128.20.12"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800711 cellFile.write( onosString + str( tempCount ) +
712 "=" + "\"" + arg + "\"" + "\n" )
713 tempCount = tempCount + 1
kelvin8ec71442015-01-15 16:57:00 -0800714
kelvin-onlabd3b64892015-01-20 13:26:24 -0800715 cellFile.write( mnString + "\"" + mnIpAddrs + "\"" + "\n" )
cameron@onlab.us75900962015-03-30 13:22:49 -0700716 cellFile.write( appString + "\n" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800717 cellFile.close()
andrewonlab94282092014-10-10 13:00:11 -0400718
kelvin8ec71442015-01-15 16:57:00 -0800719 # We use os.system to send the command to TestON cluster
720 # to account for the case in which TestON is not located
721 # on the same cluster as the ONOS bench
722 # Note that even if TestON is located on the same cluster
723 # as ONOS bench, you must setup passwordless ssh
724 # between TestON and ONOS bench in order to automate the test.
kelvin-onlabc2b79102015-07-14 11:41:20 -0700725 os.system( "scp " + tempDirectory + fileName + " " +
726 self.user_name + "@" + self.ip_address + ":" + cellDirectory )
andrewonlab94282092014-10-10 13:00:11 -0400727
andrewonlab2a6c9342014-10-16 13:40:15 -0400728 return main.TRUE
729
andrewonlab94282092014-10-10 13:00:11 -0400730 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800731 main.log.error( self.name + ": EOF exception found" )
732 main.log.error( self.name + ": " + self.handle.before )
andrewonlab94282092014-10-10 13:00:11 -0400733 main.cleanup()
734 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800735 except Exception:
736 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab94282092014-10-10 13:00:11 -0400737 main.cleanup()
738 main.exit()
739
kelvin-onlabd3b64892015-01-20 13:26:24 -0800740 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800741 """
andrewonlab95ca1462014-10-09 14:04:24 -0400742 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800743 """
Hari Krishna03f530e2015-07-10 17:28:27 -0700744 import re
andrewonlab95ca1462014-10-09 14:04:24 -0400745 try:
746 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800747 main.log.error( "Must define cellname" )
andrewonlab95ca1462014-10-09 14:04:24 -0400748 main.cleanup()
749 main.exit()
750 else:
kelvin8ec71442015-01-15 16:57:00 -0800751 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800752 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800753 # Note that this variable name is subject to change
andrewonlab95ca1462014-10-09 14:04:24 -0400754 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800755 self.handle.expect(str(cellname))
kelvin-onlabd3b64892015-01-20 13:26:24 -0800756 handleBefore = self.handle.before
757 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800758 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800759 self.handle.sendline("")
760 self.handle.expect("\$")
kelvin-onlabd3b64892015-01-20 13:26:24 -0800761 handleMore = self.handle.before
andrewonlab95ca1462014-10-09 14:04:24 -0400762
Hari Krishna03f530e2015-07-10 17:28:27 -0700763 cell_result = handleBefore + handleAfter + handleMore
764 print cell_result
765 if( re.search( "No such cell", cell_result ) ):
766 main.log.error( "Cell call returned: " + handleBefore +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800767 handleAfter + handleMore )
Hari Krishna03f530e2015-07-10 17:28:27 -0700768 main.cleanup()
769 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400770 return main.TRUE
771
772 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
kelvin8ec71442015-01-15 16:57:00 -0800796 # Get the rest of the handle
797 self.handle.sendline( "" )
798 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800799 handleMore = self.handle.before
andrewonlabc03bf6c2014-10-09 14:56:18 -0400800
kelvin-onlabd3b64892015-01-20 13:26:24 -0800801 main.log.info( "Verify cell returned: " + handleBefore +
802 handleAfter + handleMore )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400803
804 return main.TRUE
Jon Halla5cb6172015-02-23 09:28:28 -0800805 except pexpect.ExceptionPexpect as e:
806 main.log.error( self.name + ": Pexpect exception found of type " +
807 str( type( e ) ) )
808 main.log.error ( e.get_trace() )
kelvin8ec71442015-01-15 16:57:00 -0800809 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -0400810 main.cleanup()
811 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800812 except Exception:
813 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400814 main.cleanup()
815 main.exit()
816
jenkins1e99e7b2015-04-02 18:15:39 -0700817 def onosCfgSet( self, ONOSIp, configName, configParam ):
818 """
819 Uses 'onos <node-ip> cfg set' to change a parameter value of an
820 application.
821
822 ex)
823 onos 10.0.0.1 cfg set org.onosproject.myapp appSetting 1
jenkins1e99e7b2015-04-02 18:15:39 -0700824 ONOSIp = '10.0.0.1'
825 configName = 'org.onosproject.myapp'
826 configParam = 'appSetting 1'
jenkins1e99e7b2015-04-02 18:15:39 -0700827 """
cameron@onlab.us78b89652015-07-08 15:21:03 -0700828 for i in range(5):
829 try:
830 cfgStr = ( "onos "+str(ONOSIp)+" cfg set "+
831 str(configName) + " " +
832 str(configParam)
833 )
jenkins1e99e7b2015-04-02 18:15:39 -0700834
cameron@onlab.us78b89652015-07-08 15:21:03 -0700835 self.handle.sendline( "" )
836 self.handle.expect( ":~" )
837 self.handle.sendline( cfgStr )
838 self.handle.expect("cfg set")
839 self.handle.expect( ":~" )
jenkins1e99e7b2015-04-02 18:15:39 -0700840
cameron@onlab.us78b89652015-07-08 15:21:03 -0700841 paramValue = configParam.split(" ")[1]
842 paramName = configParam.split(" ")[0]
843
844 checkStr = ( "onos " + str(ONOSIp) + """ cfg get " """ + str(configName) + " " + paramName + """ " """)
jenkins1e99e7b2015-04-02 18:15:39 -0700845
cameron@onlab.us78b89652015-07-08 15:21:03 -0700846 self.handle.sendline( checkStr )
847 self.handle.expect( ":~" )
jenkins1e99e7b2015-04-02 18:15:39 -0700848
cameron@onlab.us78b89652015-07-08 15:21:03 -0700849 if "value=" + paramValue + "," in self.handle.before:
850 main.log.info("cfg " + configName + " successfully set to " + configParam)
851 return main.TRUE
852
853 except pexpect.ExceptionPexpect as e:
854 main.log.error( self.name + ": Pexpect exception found of type " +
855 str( type( e ) ) )
856 main.log.error ( e.get_trace() )
857 main.log.error( self.name + ": " + self.handle.before )
858 main.cleanup()
859 main.exit()
860 except Exception:
861 main.log.exception( self.name + ": Uncaught exception!" )
862 main.cleanup()
863 main.exit()
864
865 time.sleep(5)
866
867 main.log.error("CFG SET FAILURE: " + configName + " " + configParam )
868 main.ONOSbench.handle.sendline("onos $OC1 cfg get")
869 main.ONOSbench.handle.expect("\$")
870 print main.ONOSbench.handle.before
871 main.ONOSbench.logReport( ONOSIp, ["ERROR","WARN","EXCEPT"], "d")
872 return main.FALSE
873
874
kelvin-onlabd3b64892015-01-20 13:26:24 -0800875 def onosCli( self, ONOSIp, cmdstr ):
kelvin8ec71442015-01-15 16:57:00 -0800876 """
andrewonlab05e362f2014-10-10 00:40:57 -0400877 Uses 'onos' command to send various ONOS CLI arguments.
878 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800879 * ONOSIp: specify the ip of the cell machine
andrewonlab94282092014-10-10 13:00:11 -0400880 * cmdstr: specify the command string to send
kelvin8ec71442015-01-15 16:57:00 -0800881
882 This function is intended to expose the entire karaf
andrewonlab6e20c342014-10-10 18:08:48 -0400883 CLI commands for ONOS. Try to use this function first
884 before attempting to write a ONOS CLI specific driver
kelvin8ec71442015-01-15 16:57:00 -0800885 function.
886 You can see a list of available 'cmdstr' arguments
andrewonlab6e20c342014-10-10 18:08:48 -0400887 by starting onos, and typing in 'onos' to enter the
888 onos> CLI. Then, type 'help' to see the list of
kelvin8ec71442015-01-15 16:57:00 -0800889 available commands.
890 """
andrewonlab05e362f2014-10-10 00:40:57 -0400891 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800892 if not ONOSIp:
kelvin8ec71442015-01-15 16:57:00 -0800893 main.log.error( "You must specify the IP address" )
andrewonlab05e362f2014-10-10 00:40:57 -0400894 return main.FALSE
895 if not cmdstr:
kelvin8ec71442015-01-15 16:57:00 -0800896 main.log.error( "You must specify the command string" )
andrewonlab05e362f2014-10-10 00:40:57 -0400897 return main.FALSE
898
kelvin8ec71442015-01-15 16:57:00 -0800899 cmdstr = str( cmdstr )
900 self.handle.sendline( "" )
901 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400902
kelvin-onlabd3b64892015-01-20 13:26:24 -0800903 self.handle.sendline( "onos -w " + ONOSIp + " " + cmdstr )
kelvin8ec71442015-01-15 16:57:00 -0800904 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400905
kelvin-onlabd3b64892015-01-20 13:26:24 -0800906 handleBefore = self.handle.before
Shreya Shaha73aaad2014-10-27 18:03:09 -0400907 print "handle_before = ", self.handle.before
kelvin-onlabd3b64892015-01-20 13:26:24 -0800908 # handleAfter = str( self.handle.after )
Jon Hall47a93fb2015-01-06 16:46:06 -0800909
kelvin8ec71442015-01-15 16:57:00 -0800910 # self.handle.sendline( "" )
911 # self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800912 # handleMore = str( self.handle.before )
andrewonlab05e362f2014-10-10 00:40:57 -0400913
kelvin8ec71442015-01-15 16:57:00 -0800914 main.log.info( "Command sent successfully" )
andrewonlab05e362f2014-10-10 00:40:57 -0400915
kelvin8ec71442015-01-15 16:57:00 -0800916 # Obtain return handle that consists of result from
917 # the onos command. The string may need to be
918 # configured further.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800919 # returnString = handleBefore + handleAfter
920 returnString = handleBefore
921 print "return_string = ", returnString
922 return returnString
andrewonlab05e362f2014-10-10 00:40:57 -0400923
924 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800925 main.log.error( self.name + ": EOF exception found" )
926 main.log.error( self.name + ": " + self.handle.before )
andrewonlab05e362f2014-10-10 00:40:57 -0400927 main.cleanup()
928 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800929 except Exception:
930 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab05e362f2014-10-10 00:40:57 -0400931 main.cleanup()
932 main.exit()
Jon Hall7993bfc2014-10-09 16:30:14 -0400933
kelvin-onlabd3b64892015-01-20 13:26:24 -0800934 def onosInstall( self, options="-f", node="" ):
kelvin8ec71442015-01-15 16:57:00 -0800935 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400936 Installs ONOS bits on the designated cell machine.
kelvin8ec71442015-01-15 16:57:00 -0800937 If -f option is provided, it also forces an uninstall.
938 Presently, install also includes onos-push-bits and
Jon Hall7993bfc2014-10-09 16:30:14 -0400939 onos-config within.
kelvin8ec71442015-01-15 16:57:00 -0800940 The node option allows you to selectively only push the jar
Jon Hall7993bfc2014-10-09 16:30:14 -0400941 files to certain onos nodes
942
943 Returns: main.TRUE on success and main.FALSE on failure
kelvin8ec71442015-01-15 16:57:00 -0800944 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400945 try:
andrewonlab114768a2014-11-14 12:44:44 -0500946 if options:
kelvin8ec71442015-01-15 16:57:00 -0800947 self.handle.sendline( "onos-install " + options + " " + node )
andrewonlab114768a2014-11-14 12:44:44 -0500948 else:
kelvin8ec71442015-01-15 16:57:00 -0800949 self.handle.sendline( "onos-install " + node )
950 self.handle.expect( "onos-install " )
951 # NOTE: this timeout may need to change depending on the network
952 # and size of ONOS
953 i = self.handle.expect( [ "Network\sis\sunreachable",
kelvin-onlabd3b64892015-01-20 13:26:24 -0800954 "onos\sstart/running,\sprocess",
kelvin8ec71442015-01-15 16:57:00 -0800955 "ONOS\sis\salready\sinstalled",
956 pexpect.TIMEOUT ], timeout=60 )
Jon Hall7993bfc2014-10-09 16:30:14 -0400957
Jon Hall7993bfc2014-10-09 16:30:14 -0400958 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800959 main.log.warn( "Network is unreachable" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400960 return main.FALSE
961 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800962 main.log.info(
963 "ONOS was installed on " +
964 node +
965 " and started" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400966 return main.TRUE
andrewonlabd9a73a72014-11-14 17:28:21 -0500967 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800968 main.log.info( "ONOS is already installed on " + node )
andrewonlabd9a73a72014-11-14 17:28:21 -0500969 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800970 elif i == 3:
971 main.log.info(
972 "Installation of ONOS on " +
973 node +
974 " timed out" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400975 return main.FALSE
andrewonlabc03bf6c2014-10-09 14:56:18 -0400976
977 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800978 main.log.error( self.name + ": EOF exception found" )
979 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400980 main.cleanup()
981 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800982 except Exception:
983 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400984 main.cleanup()
985 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400986
kelvin-onlabd3b64892015-01-20 13:26:24 -0800987 def onosStart( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800988 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400989 Calls onos command: 'onos-service [<node-ip>] start'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400990 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -0800991 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400992 try:
kelvin8ec71442015-01-15 16:57:00 -0800993 self.handle.sendline( "" )
994 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800995 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -0800996 " start" )
997 i = self.handle.expect( [
andrewonlab8d0d7d72014-10-09 16:33:15 -0400998 "Job\sis\salready\srunning",
999 "start/running",
1000 "Unknown\sinstance",
kelvin8ec71442015-01-15 16:57:00 -08001001 pexpect.TIMEOUT ], timeout=120 )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001002
1003 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001004 main.log.info( "Service is already running" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001005 return main.TRUE
1006 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001007 main.log.info( "ONOS service started" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001008 return main.TRUE
1009 else:
kelvin8ec71442015-01-15 16:57:00 -08001010 main.log.error( "ONOS service failed to start" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001011 main.cleanup()
1012 main.exit()
andrewonlab8d0d7d72014-10-09 16:33:15 -04001013 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001014 main.log.error( self.name + ": EOF exception found" )
1015 main.log.error( self.name + ": " + self.handle.before )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001016 main.cleanup()
1017 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001018 except Exception:
1019 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001020 main.cleanup()
1021 main.exit()
1022
kelvin-onlabd3b64892015-01-20 13:26:24 -08001023 def onosStop( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001024 """
andrewonlab2b30bd32014-10-09 16:48:55 -04001025 Calls onos command: 'onos-service [<node-ip>] stop'
andrewonlabe8e56fd2014-10-09 17:12:44 -04001026 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -08001027 """
andrewonlab2b30bd32014-10-09 16:48:55 -04001028 try:
kelvin8ec71442015-01-15 16:57:00 -08001029 self.handle.sendline( "" )
1030 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001031 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001032 " stop" )
1033 i = self.handle.expect( [
andrewonlab2b30bd32014-10-09 16:48:55 -04001034 "stop/waiting",
Jon Hall61282e32015-03-19 11:34:11 -07001035 "Could not resolve hostname",
andrewonlab2b30bd32014-10-09 16:48:55 -04001036 "Unknown\sinstance",
kelvin8ec71442015-01-15 16:57:00 -08001037 pexpect.TIMEOUT ], timeout=60 )
andrewonlab2b30bd32014-10-09 16:48:55 -04001038
1039 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001040 main.log.info( "ONOS service stopped" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001041 return main.TRUE
1042 elif i == 1:
Jon Hall65844a32015-03-09 19:09:37 -07001043 main.log.info( "onosStop() Unknown ONOS instance specified: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001044 str( nodeIp ) )
andrewonlab2b30bd32014-10-09 16:48:55 -04001045 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -07001046 elif i == 2:
1047 main.log.warn( "ONOS wasn't running" )
1048 return main.TRUE
andrewonlab2b30bd32014-10-09 16:48:55 -04001049 else:
kelvin8ec71442015-01-15 16:57:00 -08001050 main.log.error( "ONOS service failed to stop" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001051 return main.FALSE
1052
1053 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001054 main.log.error( self.name + ": EOF exception found" )
1055 main.log.error( self.name + ": " + self.handle.before )
andrewonlab2b30bd32014-10-09 16:48:55 -04001056 main.cleanup()
1057 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001058 except Exception:
1059 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001060 main.cleanup()
1061 main.exit()
kelvin8ec71442015-01-15 16:57:00 -08001062
kelvin-onlabd3b64892015-01-20 13:26:24 -08001063 def onosUninstall( self, nodeIp="" ):
kelvin8ec71442015-01-15 16:57:00 -08001064 """
andrewonlabc8d47972014-10-09 16:52:36 -04001065 Calls the command: 'onos-uninstall'
kelvin8ec71442015-01-15 16:57:00 -08001066 Uninstalls ONOS from the designated cell machine, stopping
andrewonlabe8e56fd2014-10-09 17:12:44 -04001067 if needed
kelvin8ec71442015-01-15 16:57:00 -08001068 """
andrewonlabc8d47972014-10-09 16:52:36 -04001069 try:
kelvin8ec71442015-01-15 16:57:00 -08001070 self.handle.sendline( "" )
pingping-lin763ee042015-05-20 17:45:30 -07001071 self.handle.expect( "\$", timeout=60 )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001072 self.handle.sendline( "onos-uninstall " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -08001073 self.handle.expect( "\$" )
andrewonlabc8d47972014-10-09 16:52:36 -04001074
kelvin-onlabd3b64892015-01-20 13:26:24 -08001075 main.log.info( "ONOS " + nodeIp + " was uninstalled" )
andrewonlab9dfd2082014-11-13 17:44:03 -05001076
kelvin8ec71442015-01-15 16:57:00 -08001077 # onos-uninstall command does not return any text
andrewonlabc8d47972014-10-09 16:52:36 -04001078 return main.TRUE
1079
pingping-lin763ee042015-05-20 17:45:30 -07001080 except pexpect.TIMEOUT:
1081 main.log.exception( self.name + ": Timeout in onosUninstall" )
1082 return main.FALSE
andrewonlabc8d47972014-10-09 16:52:36 -04001083 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001084 main.log.error( self.name + ": EOF exception found" )
1085 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc8d47972014-10-09 16:52:36 -04001086 main.cleanup()
1087 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001088 except Exception:
1089 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc8d47972014-10-09 16:52:36 -04001090 main.cleanup()
1091 main.exit()
andrewonlab2b30bd32014-10-09 16:48:55 -04001092
kelvin-onlabd3b64892015-01-20 13:26:24 -08001093 def onosDie( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001094 """
andrewonlabaedc8332014-12-04 12:43:03 -05001095 Issues the command 'onos-die <node-ip>'
1096 This command calls onos-kill and also stops the node
kelvin8ec71442015-01-15 16:57:00 -08001097 """
andrewonlabaedc8332014-12-04 12:43:03 -05001098 try:
kelvin8ec71442015-01-15 16:57:00 -08001099 self.handle.sendline( "" )
1100 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001101 cmdStr = "onos-kill " + str( nodeIp )
1102 self.handle.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -08001103 i = self.handle.expect( [
andrewonlabaedc8332014-12-04 12:43:03 -05001104 "Killing\sONOS",
1105 "ONOS\sprocess\sis\snot\srunning",
kelvin8ec71442015-01-15 16:57:00 -08001106 pexpect.TIMEOUT ], timeout=20 )
andrewonlabaedc8332014-12-04 12:43:03 -05001107 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001108 main.log.info( "ONOS instance " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001109 " was killed and stopped" )
andrewonlabaedc8332014-12-04 12:43:03 -05001110 return main.TRUE
1111 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001112 main.log.info( "ONOS process was not running" )
andrewonlabaedc8332014-12-04 12:43:03 -05001113 return main.FALSE
1114 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001115 main.log.error( self.name + ": EOF exception found" )
1116 main.log.error( self.name + ": " + self.handle.before )
andrewonlabaedc8332014-12-04 12:43:03 -05001117 main.cleanup()
1118 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001119 except Exception:
1120 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabaedc8332014-12-04 12:43:03 -05001121 main.cleanup()
1122 main.exit()
1123
kelvin-onlabd3b64892015-01-20 13:26:24 -08001124 def onosKill( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001125 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001126 Calls the command: 'onos-kill [<node-ip>]'
1127 "Remotely, and unceremoniously kills the ONOS instance running on
1128 the specified cell machine" - Tom V
kelvin8ec71442015-01-15 16:57:00 -08001129 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001130 try:
kelvin8ec71442015-01-15 16:57:00 -08001131 self.handle.sendline( "" )
1132 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001133 self.handle.sendline( "onos-kill " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -08001134 i = self.handle.expect( [
andrewonlabe8e56fd2014-10-09 17:12:44 -04001135 "\$",
1136 "No\sroute\sto\shost",
1137 "password:",
kelvin8ec71442015-01-15 16:57:00 -08001138 pexpect.TIMEOUT ], timeout=20 )
1139
andrewonlabe8e56fd2014-10-09 17:12:44 -04001140 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001141 main.log.info(
1142 "ONOS instance " + str(
kelvin-onlabd3b64892015-01-20 13:26:24 -08001143 nodeIp ) + " was killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001144 return main.TRUE
1145 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001146 main.log.info( "No route to host" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001147 return main.FALSE
1148 elif i == 2:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001149 main.log.info(
1150 "Passwordless login for host: " +
1151 str( nodeIp ) +
1152 " not configured" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001153 return main.FALSE
1154 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001155 main.log.info( "ONOS instance was not killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001156 return main.FALSE
kelvin8ec71442015-01-15 16:57:00 -08001157
andrewonlabe8e56fd2014-10-09 17:12:44 -04001158 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001159 main.log.error( self.name + ": EOF exception found" )
1160 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001161 main.cleanup()
1162 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001163 except Exception:
1164 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001165 main.cleanup()
1166 main.exit()
1167
kelvin-onlabd3b64892015-01-20 13:26:24 -08001168 def onosRemoveRaftLogs( self ):
kelvin8ec71442015-01-15 16:57:00 -08001169 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001170 Removes Raft / Copy cat files from ONOS to ensure
Jon Hallfcc88622014-11-25 13:09:54 -05001171 a cleaner environment.
1172
andrewonlab19fbdca2014-11-14 12:55:59 -05001173 Description:
Jon Hallfcc88622014-11-25 13:09:54 -05001174 Stops all ONOS defined in the cell,
andrewonlab19fbdca2014-11-14 12:55:59 -05001175 wipes the raft / copycat log files
kelvin8ec71442015-01-15 16:57:00 -08001176 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001177 try:
kelvin8ec71442015-01-15 16:57:00 -08001178 self.handle.sendline( "" )
1179 self.handle.expect( "\$" )
1180 self.handle.sendline( "onos-remove-raft-logs" )
1181 # Sometimes this command hangs
1182 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
1183 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001184 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001185 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
1186 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001187 if i == 1:
1188 return main.FALSE
shahshreya957feaa2015-03-23 16:08:29 -07001189 #self.handle.sendline( "" )
1190 #self.handle.expect( "\$" )
andrewonlab19fbdca2014-11-14 12:55:59 -05001191 return main.TRUE
1192
1193 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001194 main.log.error( self.name + ": EOF exception found" )
1195 main.log.error( self.name + ": " + self.handle.before )
andrewonlab19fbdca2014-11-14 12:55:59 -05001196 main.cleanup()
1197 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001198 except Exception:
1199 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab19fbdca2014-11-14 12:55:59 -05001200 main.cleanup()
1201 main.exit()
Jon Hallfcc88622014-11-25 13:09:54 -05001202
kelvin-onlabd3b64892015-01-20 13:26:24 -08001203 def onosStartNetwork( self, mntopo ):
kelvin8ec71442015-01-15 16:57:00 -08001204 """
1205 Calls the command 'onos-start-network [ <mininet-topo> ]
1206 "remotely starts the specified topology on the cell's
andrewonlab94282092014-10-10 13:00:11 -04001207 mininet machine against all controllers configured in the
kelvin8ec71442015-01-15 16:57:00 -08001208 cell."
andrewonlab94282092014-10-10 13:00:11 -04001209 * Specify mininet topology file name for mntopo
1210 * Topo files should be placed at:
1211 ~/<your-onos-directory>/tools/test/topos
kelvin8ec71442015-01-15 16:57:00 -08001212
andrewonlab94282092014-10-10 13:00:11 -04001213 NOTE: This function will take you to the mininet prompt
kelvin8ec71442015-01-15 16:57:00 -08001214 """
andrewonlab94282092014-10-10 13:00:11 -04001215 try:
1216 if not mntopo:
kelvin8ec71442015-01-15 16:57:00 -08001217 main.log.error( "You must specify a topo file to execute" )
andrewonlab94282092014-10-10 13:00:11 -04001218 return main.FALSE
andrewonlab94282092014-10-10 13:00:11 -04001219
kelvin8ec71442015-01-15 16:57:00 -08001220 mntopo = str( mntopo )
1221 self.handle.sendline( "" )
1222 self.handle.expect( "\$" )
andrewonlab94282092014-10-10 13:00:11 -04001223
kelvin8ec71442015-01-15 16:57:00 -08001224 self.handle.sendline( "onos-start-network " + mntopo )
1225 self.handle.expect( "mininet>" )
1226 main.log.info( "Network started, entered mininet prompt" )
1227
1228 # TODO: Think about whether return is necessary or not
andrewonlab94282092014-10-10 13:00:11 -04001229
1230 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001231 main.log.error( self.name + ": EOF exception found" )
1232 main.log.error( self.name + ": " + self.handle.before )
andrewonlab94282092014-10-10 13:00:11 -04001233 main.cleanup()
1234 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001235 except Exception:
1236 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab94282092014-10-10 13:00:11 -04001237 main.cleanup()
1238 main.exit()
1239
Cameron Franke9c94fb02015-01-21 10:20:20 -08001240 def isup(self, node = "", timeout = 120):
kelvin8ec71442015-01-15 16:57:00 -08001241 """
1242 Run's onos-wait-for-start which only returns once ONOS is at run
Cameron Franke9c94fb02015-01-21 10:20:20 -08001243 level 100(ready for use)
andrewonlab8d0d7d72014-10-09 16:33:15 -04001244
Jon Hall7993bfc2014-10-09 16:30:14 -04001245 Returns: main.TRUE if ONOS is running and main.FALSE on timeout
kelvin8ec71442015-01-15 16:57:00 -08001246 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001247 try:
Cameron Franke9c94fb02015-01-21 10:20:20 -08001248 self.handle.sendline("onos-wait-for-start " + node )
1249 self.handle.expect("onos-wait-for-start")
kelvin8ec71442015-01-15 16:57:00 -08001250 # NOTE: this timeout is arbitrary"
Cameron Franke9c94fb02015-01-21 10:20:20 -08001251 i = self.handle.expect(["\$", pexpect.TIMEOUT], timeout)
Jon Hall7993bfc2014-10-09 16:30:14 -04001252 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001253 main.log.info( self.name + ": " + node + " is up" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001254 return main.TRUE
1255 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001256 # NOTE: since this function won't return until ONOS is ready,
Jon Hall7993bfc2014-10-09 16:30:14 -04001257 # we will kill it on timeout
kelvin8ec71442015-01-15 16:57:00 -08001258 main.log.error( "ONOS has not started yet" )
1259 self.handle.send( "\x03" ) # Control-C
1260 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001261 return main.FALSE
1262 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001263 main.log.error( self.name + ": EOF exception found" )
1264 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -04001265 main.cleanup()
1266 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001267 except Exception:
1268 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001269 main.cleanup()
1270 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001271
kelvin-onlabd3b64892015-01-20 13:26:24 -08001272 def pushTestIntentsShell(
1273 self,
1274 dpidSrc,
1275 dpidDst,
1276 numIntents,
1277 dirFile,
1278 onosIp,
1279 numMult="",
1280 appId="",
1281 report=True,
1282 options="" ):
kelvin8ec71442015-01-15 16:57:00 -08001283 """
andrewonlabb66dfa12014-12-02 15:51:10 -05001284 Description:
kelvin8ec71442015-01-15 16:57:00 -08001285 Use the linux prompt to push test intents to
andrewonlabb66dfa12014-12-02 15:51:10 -05001286 better parallelize the results than the CLI
1287 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001288 * dpidSrc: specify source dpid
1289 * dpidDst: specify destination dpid
1290 * numIntents: specify number of intents to push
1291 * dirFile: specify directory and file name to save
andrewonlabb66dfa12014-12-02 15:51:10 -05001292 results
kelvin-onlabd3b64892015-01-20 13:26:24 -08001293 * onosIp: specify the IP of ONOS to install on
kelvin8ec71442015-01-15 16:57:00 -08001294 NOTE:
andrewonlabb66dfa12014-12-02 15:51:10 -05001295 You must invoke this command at linux shell prompt
kelvin8ec71442015-01-15 16:57:00 -08001296 """
1297 try:
1298 # Create the string to sendline
andrewonlabaedc8332014-12-04 12:43:03 -05001299 if options:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001300 baseCmd = "onos " + str( onosIp ) + " push-test-intents " +\
kelvin8ec71442015-01-15 16:57:00 -08001301 options + " "
andrewonlabaedc8332014-12-04 12:43:03 -05001302 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001303 baseCmd = "onos " + str( onosIp ) + " push-test-intents "
kelvin8ec71442015-01-15 16:57:00 -08001304
kelvin-onlabd3b64892015-01-20 13:26:24 -08001305 addDpid = baseCmd + str( dpidSrc ) + " " + str( dpidDst )
1306 if not numMult:
1307 addIntents = addDpid + " " + str( numIntents )
1308 elif numMult:
1309 addIntents = addDpid + " " + str( numIntents ) + " " +\
1310 str( numMult )
1311 if appId:
1312 addApp = addIntents + " " + str( appId )
andrewonlabb66dfa12014-12-02 15:51:10 -05001313 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001314 addApp = addIntents
andrewonlabb66dfa12014-12-02 15:51:10 -05001315
andrewonlabaedc8332014-12-04 12:43:03 -05001316 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001317 sendCmd = addApp + " > " + str( dirFile ) + " &"
andrewonlabaedc8332014-12-04 12:43:03 -05001318 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001319 sendCmd = addApp + " &"
1320 main.log.info( "Send cmd: " + sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001321
kelvin-onlabd3b64892015-01-20 13:26:24 -08001322 self.handle.sendline( sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001323
1324 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001325 main.log.error( self.name + ": EOF exception found" )
1326 main.log.error( self.name + ": " + self.handle.before )
andrewonlabb66dfa12014-12-02 15:51:10 -05001327 main.cleanup()
1328 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001329 except Exception:
1330 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabb66dfa12014-12-02 15:51:10 -05001331 main.cleanup()
kelvin8ec71442015-01-15 16:57:00 -08001332 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001333
kelvin-onlabd3b64892015-01-20 13:26:24 -08001334 def getTopology( self, topologyOutput ):
kelvin8ec71442015-01-15 16:57:00 -08001335 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001336 Definition:
1337 Loads a json topology output
1338 Return:
1339 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -08001340 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001341 import json
Jon Hall77f53ce2014-10-13 18:02:06 -04001342 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -07001343 # either onos:topology or 'topology' will work in CLI
1344 topology = json.loads(topologyOutput)
1345 print topology
Jon Hall77f53ce2014-10-13 18:02:06 -04001346 return topology
1347 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001348 main.log.error( self.name + ": EOF exception found" )
1349 main.log.error( self.name + ": " + self.handle.before )
Jon Hall77f53ce2014-10-13 18:02:06 -04001350 main.cleanup()
1351 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001352 except Exception:
1353 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall77f53ce2014-10-13 18:02:06 -04001354 main.cleanup()
1355 main.exit()
1356
kelvin-onlabd3b64892015-01-20 13:26:24 -08001357 def checkStatus(
1358 self,
1359 topologyResult,
1360 numoswitch,
1361 numolink,
1362 logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08001363 """
Jon Hallefbd9792015-03-05 16:11:36 -08001364 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08001365 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08001366 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08001367
Jon Hall77f53ce2014-10-13 18:02:06 -04001368 Params: ip = ip used for the onos cli
1369 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08001370 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08001371 logLevel = level to log to.
1372 Currently accepts 'info', 'warn' and 'report'
Jon Hall77f53ce2014-10-13 18:02:06 -04001373
1374
kelvin-onlabd3b64892015-01-20 13:26:24 -08001375 logLevel can
Jon Hall77f53ce2014-10-13 18:02:06 -04001376
Jon Hallefbd9792015-03-05 16:11:36 -08001377 Returns: main.TRUE if the number of switches and links are correct,
1378 main.FALSE if the number of switches and links is incorrect,
Jon Hall77f53ce2014-10-13 18:02:06 -04001379 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08001380 """
Jon Hall77f53ce2014-10-13 18:02:06 -04001381 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001382 topology = self.getTopology( topologyResult )
Jon Hall77f53ce2014-10-13 18:02:06 -04001383 if topology == {}:
1384 return main.ERROR
1385 output = ""
kelvin8ec71442015-01-15 16:57:00 -08001386 # Is the number of switches is what we expected
shahshreya234a1682015-05-27 15:41:56 -07001387 devices = topology.get( 'devices', False )
1388 links = topology.get( 'links', False )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001389 if not devices or not links:
Jon Hall77f53ce2014-10-13 18:02:06 -04001390 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08001391 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08001392 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08001393 linkCheck = ( int( links ) == int( numolink ) )
Jon Hallefbd9792015-03-05 16:11:36 -08001394 if switchCheck and linkCheck:
kelvin8ec71442015-01-15 16:57:00 -08001395 # We expected the correct numbers
Jon Hall77f53ce2014-10-13 18:02:06 -04001396 output = output + "The number of links and switches match "\
kelvin8ec71442015-01-15 16:57:00 -08001397 + "what was expected"
Jon Hall77f53ce2014-10-13 18:02:06 -04001398 result = main.TRUE
1399 else:
1400 output = output + \
Jon Hall274b6642015-02-17 11:57:17 -08001401 "The number of links and switches does not match " + \
1402 "what was expected"
Jon Hall77f53ce2014-10-13 18:02:06 -04001403 result = main.FALSE
Jon Hallefbd9792015-03-05 16:11:36 -08001404 output = output + "\n ONOS sees %i devices" % int( devices )
1405 output = output + " (%i expected) " % int( numoswitch )
Jon Hall274b6642015-02-17 11:57:17 -08001406 output = output + "and %i links " % int( links )
1407 output = output + "(%i expected)" % int( numolink )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001408 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08001409 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001410 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08001411 main.log.warn( output )
Jon Hall77f53ce2014-10-13 18:02:06 -04001412 else:
kelvin8ec71442015-01-15 16:57:00 -08001413 main.log.info( output )
1414 return result
Jon Hall77f53ce2014-10-13 18:02:06 -04001415 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001416 main.log.error( self.name + ": EOF exception found" )
1417 main.log.error( self.name + ": " + self.handle.before )
Jon Hall77f53ce2014-10-13 18:02:06 -04001418 main.cleanup()
1419 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001420 except Exception:
1421 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall77f53ce2014-10-13 18:02:06 -04001422 main.cleanup()
1423 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001424
kelvin-onlabd3b64892015-01-20 13:26:24 -08001425 def tsharkPcap( self, interface, dirFile ):
kelvin8ec71442015-01-15 16:57:00 -08001426 """
andrewonlab970399c2014-11-07 13:09:32 -05001427 Capture all packet activity and store in specified
1428 directory/file
1429
1430 Required:
1431 * interface: interface to capture
1432 * dir: directory/filename to store pcap
kelvin8ec71442015-01-15 16:57:00 -08001433 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001434 try:
1435 self.handle.sendline( "" )
1436 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001437
Jon Hallfebb1c72015-03-05 13:30:09 -08001438 self.handle.sendline( "tshark -i " + str( interface ) +
1439 " -t e -w " + str( dirFile ) + " &" )
1440 self.handle.sendline( "\r" )
1441 self.handle.expect( "Capturing on" )
1442 self.handle.sendline( "\r" )
1443 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001444
Jon Hallfebb1c72015-03-05 13:30:09 -08001445 main.log.info( "Tshark started capturing files on " +
1446 str( interface ) + " and saving to directory: " +
1447 str( dirFile ) )
1448 except pexpect.EOF:
1449 main.log.error( self.name + ": EOF exception found" )
1450 main.log.error( self.name + ": " + self.handle.before )
1451 main.cleanup()
1452 main.exit()
1453 except Exception:
1454 main.log.exception( self.name + ": Uncaught exception!" )
1455 main.cleanup()
1456 main.exit()
Shreya Shaha73aaad2014-10-27 18:03:09 -04001457
kelvin-onlabd3b64892015-01-20 13:26:24 -08001458 def runOnosTopoCfg( self, instanceName, jsonFile ):
kelvin8ec71442015-01-15 16:57:00 -08001459 """
kelvin-onlabd3b64892015-01-20 13:26:24 -08001460 On ONOS bench, run this command:
Jon Halle94919c2015-03-23 11:42:57 -07001461 {ONOS_HOME}/tools/test/bin/onos-topo-cfg $OC1 filename
kelvin-onlabd3b64892015-01-20 13:26:24 -08001462 which starts the rest and copies
1463 the json file to the onos instance
kelvin8ec71442015-01-15 16:57:00 -08001464 """
shahshreyae6c7cf42014-11-26 16:39:01 -08001465 try:
kelvin8ec71442015-01-15 16:57:00 -08001466 self.handle.sendline( "" )
1467 self.handle.expect( "\$" )
Jon Halle94919c2015-03-23 11:42:57 -07001468 self.handle.sendline( "cd " + self.home + "/tools/test/bin" )
kelvin8ec71442015-01-15 16:57:00 -08001469 self.handle.expect( "/bin$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001470 cmd = "./onos-topo-cfg " + instanceName + " " + jsonFile
shahshreyae6c7cf42014-11-26 16:39:01 -08001471 print "cmd = ", cmd
kelvin8ec71442015-01-15 16:57:00 -08001472 self.handle.sendline( cmd )
1473 self.handle.expect( "\$" )
1474 self.handle.sendline( "cd ~" )
1475 self.handle.expect( "\$" )
shahshreyae6c7cf42014-11-26 16:39:01 -08001476 return main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -08001477 except pexpect.EOF:
1478 main.log.error( self.name + ": EOF exception found" )
1479 main.log.error( self.name + ": " + self.handle.before )
1480 main.cleanup()
1481 main.exit()
1482 except Exception:
1483 main.log.exception( self.name + ": Uncaught exception!" )
1484 main.cleanup()
1485 main.exit()
kelvin8ec71442015-01-15 16:57:00 -08001486
jenkins1e99e7b2015-04-02 18:15:39 -07001487 def tsharkGrep( self, grep, directory, interface='eth0', grepOptions='' ):
kelvin8ec71442015-01-15 16:57:00 -08001488 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001489 Required:
kelvin8ec71442015-01-15 16:57:00 -08001490 * grep string
andrewonlabba44bcf2014-10-16 16:54:41 -04001491 * directory to store results
1492 Optional:
1493 * interface - default: eth0
jenkins1e99e7b2015-04-02 18:15:39 -07001494 * grepOptions - options for grep
andrewonlabba44bcf2014-10-16 16:54:41 -04001495 Description:
1496 Uses tshark command to grep specific group of packets
1497 and stores the results to specified directory.
kelvin8ec71442015-01-15 16:57:00 -08001498 The timestamp is hardcoded to be in epoch
1499 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001500 try:
1501 self.handle.sendline( "" )
1502 self.handle.expect( "\$" )
1503 self.handle.sendline( "" )
jenkins1e99e7b2015-04-02 18:15:39 -07001504 if grepOptions:
1505 grepStr = "grep "+str(grepOptions)
1506 else:
1507 grepStr = "grep"
1508
Jon Hallfebb1c72015-03-05 13:30:09 -08001509 self.handle.sendline(
1510 "tshark -i " +
1511 str( interface ) +
jenkins1e99e7b2015-04-02 18:15:39 -07001512 " -t e | " +
1513 grepStr + " --line-buffered \"" +
Jon Hallfebb1c72015-03-05 13:30:09 -08001514 str(grep) +
1515 "\" >" +
1516 directory +
1517 " &" )
1518 self.handle.sendline( "\r" )
1519 self.handle.expect( "Capturing on" )
1520 self.handle.sendline( "\r" )
1521 self.handle.expect( "\$" )
1522 except pexpect.EOF:
1523 main.log.error( self.name + ": EOF exception found" )
1524 main.log.error( self.name + ": " + self.handle.before )
1525 main.cleanup()
1526 main.exit()
1527 except Exception:
1528 main.log.exception( self.name + ": Uncaught exception!" )
1529 main.cleanup()
1530 main.exit()
1531
kelvin-onlabd3b64892015-01-20 13:26:24 -08001532 def tsharkStop( self ):
kelvin8ec71442015-01-15 16:57:00 -08001533 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001534 Removes wireshark files from /tmp and kills all tshark processes
kelvin8ec71442015-01-15 16:57:00 -08001535 """
1536 # Remove all pcap from previous captures
Jon Hallfebb1c72015-03-05 13:30:09 -08001537 try:
1538 self.execute( cmd="sudo rm /tmp/wireshark*" )
1539 self.handle.sendline( "" )
Jon Hallefbd9792015-03-05 16:11:36 -08001540 self.handle.sendline( "sudo kill -9 `ps -ef | grep \"tshark -i\"" +
1541 " | grep -v grep | awk '{print $2}'`" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001542 self.handle.sendline( "" )
1543 main.log.info( "Tshark stopped" )
1544 except pexpect.EOF:
1545 main.log.error( self.name + ": EOF exception found" )
1546 main.log.error( self.name + ": " + self.handle.before )
1547 main.cleanup()
1548 main.exit()
1549 except Exception:
1550 main.log.exception( self.name + ": Uncaught exception!" )
1551 main.cleanup()
1552 main.exit()
1553
kelvin8ec71442015-01-15 16:57:00 -08001554 def ptpd( self, args ):
1555 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001556 Initiate ptp with user-specified args.
1557 Required:
1558 * args: specify string of args after command
1559 'sudo ptpd'
kelvin8ec71442015-01-15 16:57:00 -08001560 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001561 try:
kelvin8ec71442015-01-15 16:57:00 -08001562 self.handle.sendline( "sudo ptpd " + str( args ) )
1563 i = self.handle.expect( [
andrewonlab0c38a4a2014-10-28 18:35:35 -04001564 "Multiple",
1565 "Error",
kelvin8ec71442015-01-15 16:57:00 -08001566 "\$" ] )
1567 self.handle.expect( "\$" )
andrewonlabba44bcf2014-10-16 16:54:41 -04001568
andrewonlab0c38a4a2014-10-28 18:35:35 -04001569 if i == 0:
1570 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001571 main.log.info( "ptpd returned an error: " +
1572 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001573 return handle
1574 elif i == 1:
1575 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001576 main.log.error( "ptpd returned an error: " +
1577 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001578 return handle
1579 else:
1580 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -08001581
andrewonlab0c38a4a2014-10-28 18:35:35 -04001582 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001583 main.log.error( self.name + ": EOF exception found" )
1584 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001585 main.cleanup()
1586 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001587 except Exception:
1588 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001589 main.cleanup()
1590 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001591
kelvin-onlabd3b64892015-01-20 13:26:24 -08001592 def cpLogsToDir( self, logToCopy,
Jon Hallefbd9792015-03-05 16:11:36 -08001593 destDir, copyFileName="" ):
kelvin8ec71442015-01-15 16:57:00 -08001594 """
1595 Copies logs to a desired directory.
andrewonlab5d7a8f32014-11-10 13:07:56 -05001596 Current implementation of ONOS deletes its karaf
1597 logs on every iteration. For debugging purposes,
kelvin8ec71442015-01-15 16:57:00 -08001598 you may want to use this function to capture
1599 certain karaf logs. ( or any other logs if needed )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001600 Localtime will be attached to the filename
1601
1602 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001603 * logToCopy: specify directory and log name to
andrewonlab5d7a8f32014-11-10 13:07:56 -05001604 copy.
kelvin8ec71442015-01-15 16:57:00 -08001605 ex ) /opt/onos/log/karaf.log.1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001606 For copying multiple files, leave copyFileName
1607 empty and only specify destDir -
kelvin8ec71442015-01-15 16:57:00 -08001608 ex ) /opt/onos/log/karaf*
kelvin-onlabd3b64892015-01-20 13:26:24 -08001609 * destDir: specify directory to copy to.
kelvin8ec71442015-01-15 16:57:00 -08001610 ex ) /tmp/
1611 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001612 * copyFileName: If you want to rename the log
1613 file, specify copyFileName. This will not work
andrewonlab5d7a8f32014-11-10 13:07:56 -05001614 with multiple file copying
kelvin8ec71442015-01-15 16:57:00 -08001615 """
andrewonlab5d7a8f32014-11-10 13:07:56 -05001616 try:
kelvin8ec71442015-01-15 16:57:00 -08001617 localtime = time.strftime( '%x %X' )
1618 localtime = localtime.replace( "/", "" )
1619 localtime = localtime.replace( " ", "_" )
1620 localtime = localtime.replace( ":", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001621 if destDir[ -1: ] != "/":
1622 destDir += "/"
andrewonlab5d7a8f32014-11-10 13:07:56 -05001623
kelvin-onlabd3b64892015-01-20 13:26:24 -08001624 if copyFileName:
Jon Hallfebb1c72015-03-05 13:30:09 -08001625 self.handle.sendline( "cp " + str( logToCopy ) + " " +
1626 str( destDir ) + str( copyFileName ) +
1627 localtime )
kelvin8ec71442015-01-15 16:57:00 -08001628 self.handle.expect( "cp" )
1629 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001630 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001631 self.handle.sendline( "cp " + str( logToCopy ) +
1632 " " + str( destDir ) )
kelvin8ec71442015-01-15 16:57:00 -08001633 self.handle.expect( "cp" )
1634 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001635
kelvin8ec71442015-01-15 16:57:00 -08001636 return self.handle.before
1637
1638 except pexpect.EOF:
1639 main.log.error( "Copying files failed" )
1640 main.log.error( self.name + ": EOF exception found" )
1641 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001642 except Exception:
1643 main.log.exception( "Copying files failed" )
1644
Jon Hall16b72c42015-05-20 10:23:36 -07001645 def checkLogs( self, onosIp, restart=False):
kelvin8ec71442015-01-15 16:57:00 -08001646 """
Jon Hall94fd0472014-12-08 11:52:42 -08001647 runs onos-check-logs on the given onos node
Jon Hall80daded2015-05-27 16:07:00 -07001648 If restart is True, use the old version of onos-check-logs which
1649 does not print the full stacktrace, but shows the entire log file,
1650 including across restarts
Jon Hall94fd0472014-12-08 11:52:42 -08001651 returns the response
kelvin8ec71442015-01-15 16:57:00 -08001652 """
Jon Hall94fd0472014-12-08 11:52:42 -08001653 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001654 cmd = "onos-check-logs " + str( onosIp )
Jon Hall16b72c42015-05-20 10:23:36 -07001655 if restart:
1656 cmd += " old"
kelvin8ec71442015-01-15 16:57:00 -08001657 self.handle.sendline( cmd )
1658 self.handle.expect( cmd )
1659 self.handle.expect( "\$" )
Jon Hall94fd0472014-12-08 11:52:42 -08001660 response = self.handle.before
1661 return response
1662 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001663 main.log.error( "Lost ssh connection" )
1664 main.log.error( self.name + ": EOF exception found" )
1665 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001666 except Exception:
1667 main.log.exception( self.name + ": Uncaught exception!" )
1668 main.cleanup()
1669 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -08001670
kelvin-onlabd3b64892015-01-20 13:26:24 -08001671 def onosStatus( self, node="" ):
kelvin8ec71442015-01-15 16:57:00 -08001672 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001673 Calls onos command: 'onos-service [<node-ip>] status'
kelvin8ec71442015-01-15 16:57:00 -08001674 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001675 try:
kelvin8ec71442015-01-15 16:57:00 -08001676 self.handle.sendline( "" )
1677 self.handle.expect( "\$" )
1678 self.handle.sendline( "onos-service " + str( node ) +
1679 " status" )
1680 i = self.handle.expect( [
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001681 "start/running",
1682 "stop/waiting",
kelvin8ec71442015-01-15 16:57:00 -08001683 pexpect.TIMEOUT ], timeout=120 )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001684
1685 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001686 main.log.info( "ONOS is running" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001687 return main.TRUE
1688 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001689 main.log.info( "ONOS is stopped" )
kelvin8ec71442015-01-15 16:57:00 -08001690 main.log.error( "ONOS service failed to check the status" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001691 main.cleanup()
1692 main.exit()
1693 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001694 main.log.error( self.name + ": EOF exception found" )
1695 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001696 main.cleanup()
1697 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001698 except Exception:
1699 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001700 main.cleanup()
1701 main.exit()
Jon Hall21270ac2015-02-16 17:59:55 -08001702
Jon Hall63604932015-02-26 17:09:50 -08001703 def setIpTables( self, ip, port='', action='add', packet_type='',
1704 direction='INPUT', rule='DROP', states=True ):
Jon Hallefbd9792015-03-05 16:11:36 -08001705 """
Jon Hall21270ac2015-02-16 17:59:55 -08001706 Description:
1707 add or remove iptables rule to DROP (default) packets from
1708 specific IP and PORT
1709 Usage:
1710 * specify action ('add' or 'remove')
1711 when removing, pass in the same argument as you would add. It will
1712 delete that specific rule.
1713 * specify the ip to block
1714 * specify the destination port to block (defaults to all ports)
1715 * optional packet type to block (default tcp)
1716 * optional iptables rule (default DROP)
1717 * optional direction to block (default 'INPUT')
Jon Hall63604932015-02-26 17:09:50 -08001718 * States boolean toggles adding all supported tcp states to the
1719 firewall rule
Jon Hall21270ac2015-02-16 17:59:55 -08001720 Returns:
1721 main.TRUE on success or
1722 main.FALSE if given invalid input or
1723 main.ERROR if there is an error in response from iptables
1724 WARNING:
1725 * This function uses root privilege iptables command which may result
1726 in unwanted network errors. USE WITH CAUTION
Jon Hallefbd9792015-03-05 16:11:36 -08001727 """
Jon Hall21270ac2015-02-16 17:59:55 -08001728 import time
1729
1730 # NOTE*********
1731 # The strict checking methods of this driver function is intentional
1732 # to discourage any misuse or error of iptables, which can cause
1733 # severe network errors
1734 # *************
1735
1736 # NOTE: Sleep needed to give some time for rule to be added and
1737 # registered to the instance. If you are calling this function
1738 # multiple times this sleep will prevent any errors.
1739 # DO NOT REMOVE
Jon Hall63604932015-02-26 17:09:50 -08001740 # time.sleep( 5 )
Jon Hall21270ac2015-02-16 17:59:55 -08001741 try:
1742 # input validation
1743 action_type = action.lower()
1744 rule = rule.upper()
1745 direction = direction.upper()
1746 if action_type != 'add' and action_type != 'remove':
1747 main.log.error( "Invalid action type. Use 'add' or "
1748 "'remove' table rule" )
1749 if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
1750 # NOTE Currently only supports rules DROP, ACCEPT, and LOG
1751 main.log.error( "Invalid rule. Valid rules are 'DROP' or "
1752 "'ACCEPT' or 'LOG' only." )
1753 if direction != 'INPUT' and direction != 'OUTPUT':
1754 # NOTE currently only supports rules INPUT and OUPTUT
1755 main.log.error( "Invalid rule. Valid directions are"
1756 " 'OUTPUT' or 'INPUT'" )
1757 return main.FALSE
1758 return main.FALSE
1759 return main.FALSE
1760 if action_type == 'add':
1761 # -A is the 'append' action of iptables
1762 actionFlag = '-A'
1763 elif action_type == 'remove':
1764 # -D is the 'delete' rule of iptables
1765 actionFlag = '-D'
1766 self.handle.sendline( "" )
1767 self.handle.expect( "\$" )
1768 cmd = "sudo iptables " + actionFlag + " " +\
1769 direction +\
Jon Hall21270ac2015-02-16 17:59:55 -08001770 " -s " + str( ip )
Jon Hall63604932015-02-26 17:09:50 -08001771 # " -p " + str( packet_type ) +\
1772 if packet_type:
1773 cmd += " -p " + str( packet_type )
Jon Hall21270ac2015-02-16 17:59:55 -08001774 if port:
1775 cmd += " --dport " + str( port )
Jon Hall63604932015-02-26 17:09:50 -08001776 if states:
1777 cmd += " -m state --state="
1778 #FIXME- Allow user to configure which states to block
1779 cmd += "INVALID,ESTABLISHED,NEW,RELATED,UNTRACKED"
Jon Hall21270ac2015-02-16 17:59:55 -08001780 cmd += " -j " + str( rule )
1781
1782 self.handle.sendline( cmd )
1783 self.handle.expect( "\$" )
1784 main.log.warn( self.handle.before )
1785
1786 info_string = "On " + str( self.name )
1787 info_string += " " + str( action_type )
1788 info_string += " iptable rule [ "
1789 info_string += " IP: " + str( ip )
1790 info_string += " Port: " + str( port )
1791 info_string += " Rule: " + str( rule )
1792 info_string += " Direction: " + str( direction ) + " ]"
1793 main.log.info( info_string )
1794 return main.TRUE
1795 except pexpect.TIMEOUT:
1796 main.log.exception( self.name + ": Timeout exception in "
1797 "setIpTables function" )
1798 return main.ERROR
1799 except pexpect.EOF:
1800 main.log.error( self.name + ": EOF exception found" )
1801 main.log.error( self.name + ": " + self.handle.before )
1802 main.cleanup()
1803 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001804 except Exception:
1805 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall21270ac2015-02-16 17:59:55 -08001806 main.cleanup()
1807 main.exit()
1808
Jon Hall0468b042015-02-19 19:08:21 -08001809 def detailed_status(self, log_filename):
Jon Hallefbd9792015-03-05 16:11:36 -08001810 """
Jon Hall0468b042015-02-19 19:08:21 -08001811 This method is used by STS to check the status of the controller
1812 Reports RUNNING, STARTING, STOPPED, FROZEN, ERROR (and reason)
Jon Hallefbd9792015-03-05 16:11:36 -08001813 """
Jon Hall0468b042015-02-19 19:08:21 -08001814 import re
1815 try:
1816 self.handle.sendline( "" )
1817 self.handle.expect( "\$" )
1818 self.handle.sendline( "cd " + self.home )
1819 self.handle.expect( "\$" )
1820 self.handle.sendline( "service onos status" )
1821 self.handle.expect( "\$" )
1822 response = self.handle.before
1823 if re.search( "onos start/running", response ):
1824 # onos start/running, process 10457
1825 return 'RUNNING'
1826 # FIXME: Implement this case
1827 # elif re.search( pattern, response ):
1828 # return 'STARTING'
1829 elif re.search( "onos stop/", response ):
1830 # onos stop/waiting
1831 # FIXME handle this differently?: onos stop/pre-stop
1832 return 'STOPPED'
1833 # FIXME: Implement this case
1834 # elif re.search( pattern, response ):
1835 # return 'FROZEN'
1836 else:
1837 main.log.warn( self.name +
Jon Hallefbd9792015-03-05 16:11:36 -08001838 " WARNING: status received unknown response" )
Jon Hall0468b042015-02-19 19:08:21 -08001839 main.log.warn( response )
1840 return 'ERROR', "Unknown response: %s" % response
1841 except pexpect.TIMEOUT:
1842 main.log.exception( self.name + ": Timeout exception in "
1843 "setIpTables function" )
1844 return 'ERROR', "Pexpect Timeout"
1845 except pexpect.EOF:
1846 main.log.error( self.name + ": EOF exception found" )
1847 main.log.error( self.name + ": " + self.handle.before )
1848 main.cleanup()
1849 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001850 except Exception:
1851 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall0468b042015-02-19 19:08:21 -08001852 main.cleanup()
1853 main.exit()
1854
andrew@onlab.us3b087132015-03-11 15:00:08 -07001855 def createLinkGraphFile( self, benchIp, ONOSIpList, deviceCount):
1856 '''
1857 Create/formats the LinkGraph.cfg file based on arguments
1858 -only creates a linear topology and connects islands
1859 -evenly distributes devices
1860 -must be called by ONOSbench
1861
1862 ONOSIpList - list of all of the node IPs to be used
1863
1864 deviceCount - number of switches to be assigned
1865 '''
1866 main.log.step("Creating link graph configuration file." )
1867 linkGraphPath = self.home + "/tools/package/etc/linkGraph.cfg"
1868 tempFile = "/tmp/linkGraph.cfg"
1869
1870 linkGraph = open(tempFile, 'w+')
1871 linkGraph.write("# NullLinkProvider topology description (config file).\n")
1872 linkGraph.write("# The NodeId is only added if the destination is another node's device.\n")
1873 linkGraph.write("# Bugs: Comments cannot be appended to a line to be read.\n")
1874
1875 clusterCount = len(ONOSIpList)
1876
1877 if type(deviceCount) is int or type(deviceCount) is str:
1878 deviceCount = int(deviceCount)
1879 switchList = [0]*(clusterCount+1)
1880 baselineSwitchCount = deviceCount/clusterCount
1881
1882 for node in range(1, clusterCount + 1):
1883 switchList[node] = baselineSwitchCount
1884
1885 for node in range(1, (deviceCount%clusterCount)+1):
1886 switchList[node] += 1
1887
1888 if type(deviceCount) is list:
1889 main.log.info("Using provided device distribution")
1890 switchList = [0]
1891 for i in deviceCount:
1892 switchList.append(int(i))
1893
1894 tempList = ['0']
1895 tempList.extend(ONOSIpList)
1896 ONOSIpList = tempList
1897
1898 myPort = 6
1899 lastSwitch = 0
1900 for node in range(1, clusterCount+1):
1901 if switchList[node] == 0:
1902 continue
1903
1904 linkGraph.write("graph " + ONOSIpList[node] + " {\n")
1905
1906 if node > 1:
1907 #connect to last device on previous node
1908 line = ("\t0:5 -> " + str(lastSwitch) + ":6:" + lastIp + "\n") #ONOSIpList[node-1]
1909 linkGraph.write(line)
1910
1911 lastSwitch = 0
1912 for switch in range (0, switchList[node]-1):
1913 line = ""
1914 line = ("\t" + str(switch) + ":" + str(myPort))
1915 line += " -- "
1916 line += (str(switch+1) + ":" + str(myPort-1) + "\n")
1917 linkGraph.write(line)
1918 lastSwitch = switch+1
1919 lastIp = ONOSIpList[node]
1920
1921 #lastSwitch += 1
1922 if node < (clusterCount):
1923 #connect to first device on the next node
1924 line = ("\t" + str(lastSwitch) + ":6 -> 0:5:" + ONOSIpList[node+1] + "\n")
1925 linkGraph.write(line)
1926
1927 linkGraph.write("}\n")
1928 linkGraph.close()
1929
1930 #SCP
kelvin-onlabc2b79102015-07-14 11:41:20 -07001931 os.system( "scp " + tempFile + " " + self.user_name + "@" + benchIp + ":" + linkGraphPath)
andrew@onlab.us3b087132015-03-11 15:00:08 -07001932 main.log.info("linkGraph.cfg creation complete")
1933
cameron@onlab.us75900962015-03-30 13:22:49 -07001934 def configNullDev( self, ONOSIpList, deviceCount, numPorts=10):
andrew@onlab.us3b087132015-03-11 15:00:08 -07001935
1936 '''
andrew@onlab.us3b087132015-03-11 15:00:08 -07001937 ONOSIpList = list of Ip addresses of nodes switches will be devided amongst
cameron@onlab.us75900962015-03-30 13:22:49 -07001938 deviceCount = number of switches to distribute, or list of values to use as custom distribution
1939 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 -07001940 '''
1941
cameron@onlab.us75900962015-03-30 13:22:49 -07001942 main.log.step("Configuring Null Device Provider" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07001943 clusterCount = len(ONOSIpList)
1944
cameron@onlab.us75900962015-03-30 13:22:49 -07001945 try:
1946
1947 if type(deviceCount) is int or type(deviceCount) is str:
1948 main.log.step("Creating device distribution")
1949 deviceCount = int(deviceCount)
1950 switchList = [0]*(clusterCount+1)
1951 baselineSwitchCount = deviceCount/clusterCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001952
cameron@onlab.us75900962015-03-30 13:22:49 -07001953 for node in range(1, clusterCount + 1):
1954 switchList[node] = baselineSwitchCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001955
cameron@onlab.us75900962015-03-30 13:22:49 -07001956 for node in range(1, (deviceCount%clusterCount)+1):
1957 switchList[node] += 1
1958
1959 if type(deviceCount) is list:
1960 main.log.info("Using provided device distribution")
1961
1962 if len(deviceCount) == clusterCount:
1963 switchList = ['0']
1964 switchList.extend(deviceCount)
1965
1966 if len(deviceCount) == (clusterCount + 1):
1967 if deviceCount[0] == '0' or deviceCount[0] == 0:
1968 switchList = deviceCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001969
cameron@onlab.us75900962015-03-30 13:22:49 -07001970 assert len(switchList) == (clusterCount + 1)
1971
1972 except AssertionError:
1973 main.log.error( "Bad device/Ip list match")
1974 except TypeError:
1975 main.log.exception( self.name + ": Object not as expected" )
1976 return None
Jon Hall77ba41c2015-04-06 10:25:40 -07001977 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07001978 main.log.exception( self.name + ": Uncaught exception!" )
1979 main.cleanup()
1980 main.exit()
1981
andrew@onlab.us3b087132015-03-11 15:00:08 -07001982
1983 ONOSIp = [0]
1984 ONOSIp.extend(ONOSIpList)
1985
1986 devicesString = "devConfigs = "
1987 for node in range(1, len(ONOSIp)):
1988 devicesString += (ONOSIp[node] + ":" + str(switchList[node] ))
1989 if node < clusterCount:
1990 devicesString += (",")
cameron@onlab.us75900962015-03-30 13:22:49 -07001991
1992 try:
1993 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider devConfigs " + devicesString )
1994 self.handle.expect(":~")
1995 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider numPorts " + str(numPorts) )
1996 self.handle.expect(":~")
andrew@onlab.us3b087132015-03-11 15:00:08 -07001997
cameron@onlab.us75900962015-03-30 13:22:49 -07001998 for i in range(10):
1999 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.device.impl.NullDeviceProvider")
2000 self.handle.expect(":~")
2001 verification = self.handle.before
2002 if (" value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification:
2003 break
2004 else:
2005 time.sleep(1)
andrew@onlab.us3b087132015-03-11 15:00:08 -07002006
cameron@onlab.us2cc8bf12015-04-02 14:12:30 -07002007 assert ("value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification
cameron@onlab.us75900962015-03-30 13:22:49 -07002008
2009 except AssertionError:
2010 main.log.error("Incorrect Config settings: " + verification)
Jon Hall77ba41c2015-04-06 10:25:40 -07002011 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002012 main.log.exception( self.name + ": Uncaught exception!" )
2013 main.cleanup()
2014 main.exit()
2015
cameron@onlab.usc80a8c82015-04-15 14:57:37 -07002016 def configNullLink( self,fileName="/opt/onos/apache-karaf-3.0.3/etc/linkGraph.cfg", eventRate=0):
andrew@onlab.us3b087132015-03-11 15:00:08 -07002017 '''
cameron@onlab.us75900962015-03-30 13:22:49 -07002018 fileName default is currently the same as the default on ONOS, specify alternate file if
2019 you want to use a different topology file than linkGraph.cfg
andrew@onlab.us3b087132015-03-11 15:00:08 -07002020 '''
2021
andrew@onlab.us3b087132015-03-11 15:00:08 -07002022
cameron@onlab.us75900962015-03-30 13:22:49 -07002023 try:
2024 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider eventRate " + str(eventRate))
2025 self.handle.expect(":~")
2026 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider cfgFile " + fileName )
2027 self.handle.expect(":~")
2028
2029 for i in range(10):
2030 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.link.impl.NullLinkProvider")
2031 self.handle.expect(":~")
2032 verification = self.handle.before
2033 if (" value=" + str(eventRate)) in verification and (" value=" + fileName) in verification:
2034 break
2035 else:
2036 time.sleep(1)
2037
2038 assert ("value=" + str(eventRate)) in verification and (" value=" + fileName) in verification
2039
2040 except pexpect.EOF:
2041 main.log.error( self.name + ": EOF exception found" )
2042 main.log.error( self.name + ": " + self.handle.before )
2043 main.cleanup()
2044 main.exit()
cameron@onlab.us75900962015-03-30 13:22:49 -07002045 except AssertionError:
2046 main.log.info("Settings did not post to ONOS")
2047 main.log.error(varification)
Jon Hall77ba41c2015-04-06 10:25:40 -07002048 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002049 main.log.exception( self.name + ": Uncaught exception!" )
2050 main.log.error(varification)
2051 main.cleanup()
2052 main.exit()
andrew@onlab.us3b087132015-03-11 15:00:08 -07002053
kelvin-onlaba4074292015-07-09 15:19:49 -07002054 def getOnosIps( self ):
2055 """
2056 Get all onos IPs stored in
2057 """
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002058
kelvin-onlaba4074292015-07-09 15:19:49 -07002059 return sorted( self.onosIps.values() )
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002060
kelvin-onlaba4074292015-07-09 15:19:49 -07002061 def logReport( self, nodeIp, searchTerms, outputMode="s" ):
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002062 '''
2063 - accepts either a list or a string for "searchTerms" these
2064 terms will be searched for in the log and have their
2065 instances counted
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002066
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002067 - nodeIp is the ip of the node whos log is to be scanned
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002068
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002069 - output modes:
2070 "s" - Simple. Quiet output mode that just prints
cameron@onlab.us2e166212015-05-19 14:28:25 -07002071 the occurences of each search term
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002072
cameron@onlab.us2e166212015-05-19 14:28:25 -07002073 "d" - Detailed. Prints number of occurences as well as the entire
2074 line for each of the last 5 occurences
2075
2076 - returns total of the number of instances of all search terms
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002077 '''
2078 main.log.info("========================== Log Report ===========================\n")
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002079
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002080 if type(searchTerms) is str:
2081 searchTerms = [searchTerms]
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002082
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002083 logLines = [ [" "] for i in range(len(searchTerms)) ]
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002084
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002085 for term in range(len(searchTerms)):
2086 logLines[term][0] = searchTerms[term]
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002087
cameron@onlab.us2e166212015-05-19 14:28:25 -07002088 totalHits = 0
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002089 for term in range(len(searchTerms)):
2090 cmd = "onos-ssh " + nodeIp + " cat /opt/onos/log/karaf.log | grep " + searchTerms[term]
2091 self.handle.sendline(cmd)
2092 self.handle.expect(":~")
2093 before = (self.handle.before).splitlines()
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002094
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002095 count = [searchTerms[term],0]
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002096
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002097 for line in before:
2098 if searchTerms[term] in line and "grep" not in line:
2099 count[1] += 1
2100 if before.index(line) > ( len(before) - 7 ):
2101 logLines[term].append(line)
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002102
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002103 main.log.info( str(count[0]) + ": " + str(count[1]) )
2104 if term == len(searchTerms)-1:
2105 print("\n")
cameron@onlab.us2e166212015-05-19 14:28:25 -07002106 totalHits += int(count[1])
2107
cameron@onlab.us966d1be2015-05-15 14:54:09 -07002108 if outputMode != "s" and outputMode != "S":
2109 outputString = ""
2110 for i in logLines:
2111 outputString = i[0] + ": \n"
2112 for x in range(1,len(i)):
2113 outputString += ( i[x] + "\n" )
2114
2115 if outputString != (i[0] + ": \n"):
2116 main.log.info(outputString)
2117
2118 main.log.info("================================================================\n")
cameron@onlab.us2e166212015-05-19 14:28:25 -07002119 return totalHits
pingping-lin763ee042015-05-20 17:45:30 -07002120
Hari Krishnaade11a72015-07-01 17:06:46 -07002121 def getOnosIPfromCell(self):
2122 '''
2123 Returns the ONOS node names and their IP addresses as defined in the cell and applied to shell environment
Hari Krishnaa25104c2015-07-09 22:34:01 -07002124 Example output return: ['10.128.40.41','10.128.40.42','10.128.40.43']. This will work even if the Mininet is
2125 not part of the cell definition and also if there are multiple mininets, just by using static hostname
2126 in TOPO file.
2127 '''
Hari Krishnaade11a72015-07-01 17:06:46 -07002128 import re
2129 try:
2130 # Clean handle by sending empty and expecting $
2131 self.handle.sendline( "" )
2132 self.handle.expect( "\$" )
2133 self.handle.sendline( "cell" )
2134 self.handle.expect( "\$" )
2135 handleBefore = self.handle.before
2136 handleAfter = self.handle.after
2137 # Get the rest of the handle
2138 self.handle.sendline( "" )
2139 self.handle.expect( "\$" )
2140 handleMore = self.handle.before
2141 ipList = []
2142 cellOutput = handleBefore + handleAfter + handleMore
2143 cellOutput = cellOutput.replace("\r\r","")
2144 cellOutput = cellOutput.splitlines()
2145 for i in range( len(cellOutput) ):
2146 if( re.match( "OC", cellOutput[i] ) ):
2147 if( re.match( "OCI", cellOutput[i] ) or re.match( "OCN", cellOutput[i] ) ):
2148 continue
2149 else:
2150 onosIP = cellOutput[i].split("=")
Hari Krishnac195f3b2015-07-08 20:02:24 -07002151 ipList.append(onosIP[1])
Hari Krishnaade11a72015-07-01 17:06:46 -07002152 return ipList
2153 except pexpect.ExceptionPexpect as e:
2154 main.log.error( self.name + ": Pexpect exception found of type " +
2155 str( type( e ) ) )
2156 main.log.error ( e.get_trace() )
2157 main.log.error( self.name + ": " + self.handle.before )
2158 main.cleanup()
2159 main.exit()
2160 except Exception:
2161 main.log.exception( self.name + ": Uncaught exception!" )
2162 main.cleanup()
2163 main.exit()
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002164
2165 def copyMininetFile( self, fileName, localPath, userName, ip,
2166 mnPath='~/mininet/custom/', timeout = 60 ):
2167 """
2168 Description:
2169 Copy mininet topology file from dependency folder in the test folder
2170 and paste it to the mininet machine's mininet/custom folder
2171 Required:
2172 fileName - Name of the topology file to copy
2173 localPath - File path of the mininet topology file
2174 userName - User name of the mininet machine to send the file to
2175 ip - Ip address of the mininet machine
2176 Optional:
2177 mnPath - of the mininet directory to send the file to
2178 Return:
2179 Return main.TRUE if successfully copied the file otherwise
2180 return main.FALSE
2181 """
2182
2183 try:
2184 cmd = "scp " + localPath + fileName + " " + userName + "@" + \
2185 str( ip ) + ":" + mnPath + fileName
2186
2187 self.handle.sendline( "" )
2188 self.handle.expect( "\$" )
2189
2190 main.log.info( self.name + ": Execute: " + cmd )
2191
2192 self.handle.sendline( cmd )
2193
2194 i = self.handle.expect( [ 'No such file',
2195 "100%",
2196 pexpect.TIMEOUT ] )
2197
2198 if i == 0:
2199 main.log.error( self.name + ": File " + fileName +
2200 " does not exist!" )
2201 return main.FALSE
2202
2203 if i == 1:
2204 main.log.info( self.name + ": File " + fileName +
2205 " has been copied!" )
2206 self.handle.sendline( "" )
2207 self.handle.expect( "\$" )
2208 return main.TRUE
2209
2210 except pexpect.EOF:
2211 main.log.error( self.name + ": EOF exception found" )
2212 main.log.error( self.name + ": " + self.handle.before )
2213 main.cleanup()
2214 main.exit()
2215 except pexpect.TIMEOUT:
2216 main.log.error( self.name + ": TIMEOUT exception found" )
2217 main.log.error( self.name + ": " + self.handle.before )
2218 main.cleanup()
2219 main.exit()
cameron@onlab.us78b89652015-07-08 15:21:03 -07002220
2221 def jvmSet(self, memory=8):
2222
2223 import os
2224
2225 homeDir = os.path.expanduser('~')
2226 filename = "/onos/tools/package/bin/onos-service"
2227
2228 serviceConfig = open(homeDir + filename, 'w+')
2229 serviceConfig.write("#!/bin/bash\n ")
2230 serviceConfig.write("#------------------------------------- \n ")
2231 serviceConfig.write("# Starts ONOS Apache Karaf container\n ")
2232 serviceConfig.write("#------------------------------------- \n ")
2233 serviceConfig.write("#export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-7-openjdk-amd64/}\n ")
2234 serviceConfig.write("""export JAVA_OPTS="${JAVA_OPTS:--Xms""" + str(memory) + "G -Xmx" + str(memory) + """G}" \n """)
2235 serviceConfig.write("[ -d $ONOS_HOME ] && cd $ONOS_HOME || ONOS_HOME=$(dirname $0)/..\n")
2236 serviceConfig.write("""${ONOS_HOME}/apache-karaf-$KARAF_VERSION/bin/karaf "$@" \n """)
2237 serviceConfig.close()
2238
2239 def createDBFile(self, testData):
2240
2241 filename = main.TEST + "DB"
2242 DBString = ""
2243
2244 for item in testData:
2245 if type(item) is string:
2246 item = "'" + item + "'"
2247 if testData.index(item) < len(testData-1):
2248 item += ","
2249 DBString += str(item)
2250
2251 DBFile = open(filename, "a")
2252 DBFile.write(DBString)
2253 DBFile.close()
2254
2255 def verifySummary(self, ONOSIp,*deviceCount):
2256
2257 self.handle.sendline("onos " + ONOSIp + " summary")
2258 self.handle.expect(":~")
2259
2260 summaryStr = self.handle.before
2261 print "\nSummary\n==============\n" + summaryStr + "\n\n"
2262
2263 #passed = "SCC(s)=1" in summaryStr
2264 #if deviceCount:
2265 # passed = "devices=" + str(deviceCount) + "," not in summaryStr
2266
2267
2268 if "SCC(s)=1," in summaryStr:
2269 passed = True
2270 print("Summary is verifed")
2271 else:
2272 print("Summary failed")
2273
2274 if deviceCount:
2275 print" ============================="
2276 checkStr = "devices=" + str(deviceCount[0]) + ","
2277 print "Checkstr: " + checkStr
2278 if checkStr not in summaryStr:
2279 passed = False
2280 print("Device count failed")
2281 else:
2282 print "device count verified"
2283
2284 return passed