blob: 3c8d4846d9420cefb0f8e81d6e4231f9db2a165d [file] [log] [blame]
Jon Hall05b2b432014-10-08 19:53:25 -04001#!/usr/bin/env python
andrewonlabe8e56fd2014-10-09 17:12:44 -04002
kelvin8ec71442015-01-15 16:57:00 -08003"""
4This driver interacts with ONOS bench, the OSGi platform
5that configures the ONOS nodes. ( aka ONOS-next )
andrewonlabe8e56fd2014-10-09 17:12:44 -04006
kelvin8ec71442015-01-15 16:57:00 -08007Please follow the coding style demonstrated by existing
andrewonlabe8e56fd2014-10-09 17:12:44 -04008functions and document properly.
9
10If you are a contributor to the driver, please
11list your email here for future contact:
12
13jhall@onlab.us
14andrew@onlab.us
15
16OCT 9 2014
17
kelvin8ec71442015-01-15 16:57:00 -080018"""
Jon Hall05b2b432014-10-08 19:53:25 -040019import time
Jon Hall6801cda2015-07-15 14:13:45 -070020import types
Jon Hall05b2b432014-10-08 19:53:25 -040021import pexpect
kelvin-onlaba4074292015-07-09 15:19:49 -070022import os
Jon Hall6c44c0b2016-04-20 15:21:00 -070023import re
24import subprocess
pingping-lin6d23d9e2015-02-02 16:54:24 -080025from requests.models import Response
Jon Hall05b2b432014-10-08 19:53:25 -040026from drivers.common.clidriver import CLI
27
kelvin8ec71442015-01-15 16:57:00 -080028class OnosDriver( CLI ):
Jon Hall05b2b432014-10-08 19:53:25 -040029
kelvin8ec71442015-01-15 16:57:00 -080030 def __init__( self ):
31 """
32 Initialize client
33 """
Jon Hallefbd9792015-03-05 16:11:36 -080034 self.name = None
35 self.home = None
36 self.handle = None
Jon Hall6c44c0b2016-04-20 15:21:00 -070037 self.nicAddr = None
kelvin8ec71442015-01-15 16:57:00 -080038 super( CLI, self ).__init__()
39
40 def connect( self, **connectargs ):
41 """
Jon Hall05b2b432014-10-08 19:53:25 -040042 Creates ssh handle for ONOS "bench".
kelvin-onlaba4074292015-07-09 15:19:49 -070043 NOTE:
44 The ip_address would come from the topo file using the host tag, the
45 value can be an environment variable as well as a "localhost" to get
46 the ip address needed to ssh to the "bench"
kelvin8ec71442015-01-15 16:57:00 -080047 """
Jon Hall05b2b432014-10-08 19:53:25 -040048 try:
49 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080050 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us3b087132015-03-11 15:00:08 -070051 self.home = "~/onos"
Jon Hall05b2b432014-10-08 19:53:25 -040052 for key in self.options:
53 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080054 self.home = self.options[ 'home' ]
Jon Hall05b2b432014-10-08 19:53:25 -040055 break
Jon Hall274b6642015-02-17 11:57:17 -080056 if self.home is None or self.home == "":
Jon Halle94919c2015-03-23 11:42:57 -070057 self.home = "~/onos"
Jon Hall21270ac2015-02-16 17:59:55 -080058
kelvin8ec71442015-01-15 16:57:00 -080059 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070060
kelvin-onlabc2b79102015-07-14 11:41:20 -070061 # The 'nodes' tag is optional and it is not required in .topo file
kelvin-onlaba4074292015-07-09 15:19:49 -070062 for key in self.options:
63 if key == "nodes":
kelvin-onlabc2b79102015-07-14 11:41:20 -070064 # Maximum number of ONOS nodes to run, if there is any
kelvin-onlaba4074292015-07-09 15:19:49 -070065 self.maxNodes = int( self.options[ 'nodes' ] )
66 break
67 self.maxNodes = None
68
kelvin-onlabc2b79102015-07-14 11:41:20 -070069 if self.maxNodes == None or self.maxNodes == "":
70 self.maxNodes = 100
kelvin-onlaba4074292015-07-09 15:19:49 -070071
kelvin-onlabc2b79102015-07-14 11:41:20 -070072
73 # Grabs all OC environment variables based on max number of nodes
kelvin-onlaba4074292015-07-09 15:19:49 -070074 self.onosIps = {} # Dictionary of all possible ONOS ip
75
76 try:
77 if self.maxNodes:
kelvin-onlaba4074292015-07-09 15:19:49 -070078 for i in range( self.maxNodes ):
79 envString = "OC" + str( i + 1 )
kelvin-onlabc2b79102015-07-14 11:41:20 -070080 # If there is no more OC# then break the loop
81 if os.getenv( envString ):
82 self.onosIps[ envString ] = os.getenv( envString )
83 else:
84 self.maxNodes = len( self.onosIps )
85 main.log.info( self.name +
86 ": Created cluster data with " +
87 str( self.maxNodes ) +
88 " maximum number" +
89 " of nodes" )
90 break
kelvin-onlaba4074292015-07-09 15:19:49 -070091
92 if not self.onosIps:
93 main.log.info( "Could not read any environment variable"
94 + " please load a cell file with all" +
95 " onos IP" )
Jon Hall5cf14d52015-07-16 12:15:19 -070096 self.maxNodes = None
kelvin-onlaba4074292015-07-09 15:19:49 -070097 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
Jon Hall4ba53f02015-07-29 13:07:41 -0700169
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.
andrew@onlab.usaee415a2015-06-05 14:38:58 -0400175 """
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
Jon Hall6c44c0b2016-04-20 15:21:00 -0700187 def onosPackage( self, opTimeout=180 ):
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
Jon Hall64af8502015-12-15 10:09:33 -0800190 and executed on any platform with Java 8 JRE.
kelvin8ec71442015-01-15 16:57:00 -0800191 """
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400192 try:
Jon Hall64af8502015-12-15 10:09:33 -0800193 ret = main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800194 self.handle.sendline( "onos-package" )
195 self.handle.expect( "onos-package" )
Jon Hall96451092016-05-04 09:42:30 -0700196 while True:
197 i = self.handle.expect( [ "Downloading",
198 "Unknown options",
199 "No such file or directory",
200 "tar.gz",
201 "\$" ],
202 opTimeout )
203 handle = str( self.handle.before + self.handle.after )
204 if i == 0:
205 # Give more time to download the file
206 continue # expect again
207 elif i == 1:
208 # Incorrect usage
209 main.log.error( "onos-package does not recognize the given options" )
210 ret = main.FALSE
211 continue # expect again
212 elif i == 2:
213 # File(s) not found
214 main.log.error( "onos-package could not find a file or directory" )
215 ret = main.FALSE
216 continue # expect again
217 elif i == 3:
218 # tar.gz
219 continue # expect again
220 elif i == 4:
221 # Prompt returned
222 break
Jon Hallc6793552016-01-19 14:18:37 -0800223 main.log.info( "onos-package command returned: " + handle )
kelvin8ec71442015-01-15 16:57:00 -0800224 # As long as the sendline does not time out,
225 # return true. However, be careful to interpret
226 # the results of the onos-package command return
Jon Hall64af8502015-12-15 10:09:33 -0800227 return ret
228 except pexpect.TIMEOUT:
229 main.log.exception( self.name + ": TIMEOUT exception found in onosPackage" )
230 main.log.error( self.name + ": " + self.handle.before )
231 return main.FALSE
andrewonlab7735d852014-10-09 13:02:47 -0400232 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800233 main.log.error( self.name + ": EOF exception found" )
234 main.log.error( self.name + ": " + self.handle.before )
Jon Hall64af8502015-12-15 10:09:33 -0800235 main.cleanup()
236 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800237 except Exception:
238 main.log.exception( "Failed to package ONOS" )
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400239 main.cleanup()
240 main.exit()
241
kelvin-onlabd3b64892015-01-20 13:26:24 -0800242 def onosBuild( self ):
kelvin8ec71442015-01-15 16:57:00 -0800243 """
andrewonlab8790abb2014-11-06 13:51:54 -0500244 Use the pre defined script to build onos via mvn
kelvin8ec71442015-01-15 16:57:00 -0800245 """
andrewonlab8790abb2014-11-06 13:51:54 -0500246 try:
kelvin8ec71442015-01-15 16:57:00 -0800247 self.handle.sendline( "onos-build" )
248 self.handle.expect( "onos-build" )
249 i = self.handle.expect( [
kelvin-onlabd3b64892015-01-20 13:26:24 -0800250 "BUILD SUCCESS",
251 "ERROR",
252 "BUILD FAILED" ],
253 timeout=120 )
kelvin8ec71442015-01-15 16:57:00 -0800254 handle = str( self.handle.before )
Jon Hall3b489db2015-10-05 14:38:37 -0700255 self.handle.expect( "\$" )
andrewonlab8790abb2014-11-06 13:51:54 -0500256
kelvin8ec71442015-01-15 16:57:00 -0800257 main.log.info( "onos-build command returned: " +
258 handle )
andrewonlab8790abb2014-11-06 13:51:54 -0500259
260 if i == 0:
261 return main.TRUE
262 else:
263 return handle
264
265 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800266 main.log.error( self.name + ": EOF exception found" )
267 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -0800268 except Exception:
269 main.log.exception( "Failed to build ONOS" )
andrewonlab8790abb2014-11-06 13:51:54 -0500270 main.cleanup()
271 main.exit()
272
shahshreya9f531fe2015-06-10 12:03:51 -0700273 def cleanInstall( self, skipTest=False, mciTimeout=600 ):
kelvin8ec71442015-01-15 16:57:00 -0800274 """
275 Runs mvn clean install in the root of the ONOS directory.
276 This will clean all ONOS artifacts then compile each module
shahshreya9f531fe2015-06-10 12:03:51 -0700277 Optional:
278 skipTest - Does "-DskipTests -Dcheckstyle.skip -U -T 1C" which
279 skip the test. This will make the building faster.
280 Disregarding the credibility of the build
kelvin8ec71442015-01-15 16:57:00 -0800281 Returns: main.TRUE on success
Jon Hallde9d9aa2014-10-08 20:36:02 -0400282 On Failure, exits the test
kelvin8ec71442015-01-15 16:57:00 -0800283 """
Jon Hallde9d9aa2014-10-08 20:36:02 -0400284 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800285 main.log.info( "Running 'mvn clean install' on " +
286 str( self.name ) +
kelvin8ec71442015-01-15 16:57:00 -0800287 ". This may take some time." )
288 self.handle.sendline( "cd " + self.home )
289 self.handle.expect( "\$" )
Jon Hallea7818b2014-10-09 14:30:59 -0400290
kelvin8ec71442015-01-15 16:57:00 -0800291 self.handle.sendline( "" )
292 self.handle.expect( "\$" )
shahshreya9f531fe2015-06-10 12:03:51 -0700293
294 if not skipTest:
295 self.handle.sendline( "mvn clean install" )
296 self.handle.expect( "mvn clean install" )
297 else:
298 self.handle.sendline( "mvn clean install -DskipTests" +
299 " -Dcheckstyle.skip -U -T 1C" )
300 self.handle.expect( "mvn clean install -DskipTests" +
301 " -Dcheckstyle.skip -U -T 1C" )
kelvin8ec71442015-01-15 16:57:00 -0800302 while True:
303 i = self.handle.expect( [
Jon Hall274b6642015-02-17 11:57:17 -0800304 'There\sis\sinsufficient\smemory\sfor\sthe\sJava\s' +
Jon Hallefbd9792015-03-05 16:11:36 -0800305 'Runtime\sEnvironment\sto\scontinue',
Jon Hallde9d9aa2014-10-08 20:36:02 -0400306 'BUILD\sFAILURE',
307 'BUILD\sSUCCESS',
Jon Halle94919c2015-03-23 11:42:57 -0700308 'onos\$', #TODO: fix this to be more generic?
Jon Hallde9d9aa2014-10-08 20:36:02 -0400309 'ONOS\$',
pingping-lin57a56ce2015-05-20 16:43:48 -0700310 pexpect.TIMEOUT ], mciTimeout )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400311 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800312 main.log.error( self.name + ":There is insufficient memory \
313 for the Java Runtime Environment to continue." )
314 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400315 main.cleanup()
316 main.exit()
317 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800318 main.log.error( self.name + ": Build failure!" )
319 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400320 main.cleanup()
321 main.exit()
322 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800323 main.log.info( self.name + ": Build success!" )
Jon Halle94919c2015-03-23 11:42:57 -0700324 elif i == 3 or i == 4:
kelvin8ec71442015-01-15 16:57:00 -0800325 main.log.info( self.name + ": Build complete" )
326 # Print the build time
Jon Hallf8ef52c2014-10-09 19:37:33 -0400327 for line in self.handle.before.splitlines():
328 if "Total time:" in line:
kelvin8ec71442015-01-15 16:57:00 -0800329 main.log.info( line )
330 self.handle.sendline( "" )
331 self.handle.expect( "\$", timeout=60 )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400332 return main.TRUE
Jon Halle94919c2015-03-23 11:42:57 -0700333 elif i == 5:
kelvin8ec71442015-01-15 16:57:00 -0800334 main.log.error(
335 self.name +
336 ": mvn clean install TIMEOUT!" )
337 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400338 main.cleanup()
339 main.exit()
340 else:
Jon Hall274b6642015-02-17 11:57:17 -0800341 main.log.error( self.name + ": unexpected response from " +
Jon Hallefbd9792015-03-05 16:11:36 -0800342 "mvn clean install" )
kelvin8ec71442015-01-15 16:57:00 -0800343 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400344 main.cleanup()
345 main.exit()
346 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800347 main.log.error( self.name + ": EOF exception found" )
348 main.log.error( self.name + ": " + self.handle.before )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400349 main.cleanup()
350 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800351 except Exception:
352 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400353 main.cleanup()
354 main.exit()
Jon Hallacabffd2014-10-09 12:36:53 -0400355
Jon Hall61282e32015-03-19 11:34:11 -0700356 def gitPull( self, comp1="", fastForward=True ):
kelvin8ec71442015-01-15 16:57:00 -0800357 """
Jon Hallacabffd2014-10-09 12:36:53 -0400358 Assumes that "git pull" works without login
Jon Hall47a93fb2015-01-06 16:46:06 -0800359
Jon Hall61282e32015-03-19 11:34:11 -0700360 If the fastForward boolean is set to true, only git pulls that can
361 be fast forwarded will be performed. IE if you have not local commits
362 in your branch.
363
Jon Hallacabffd2014-10-09 12:36:53 -0400364 This function will perform a git pull on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800365 If used as gitPull( "NODE" ) it will do git pull + NODE. This is
Jon Hallacabffd2014-10-09 12:36:53 -0400366 for the purpose of pulling from other nodes if necessary.
367
Jon Hall47a93fb2015-01-06 16:46:06 -0800368 Otherwise, this function will perform a git pull in the
Jon Hallacabffd2014-10-09 12:36:53 -0400369 ONOS repository. If it has any problems, it will return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -0800370 If it successfully does a gitPull, it will return a 1 ( main.TRUE )
Shreya Shahee15f6c2014-10-28 18:12:30 -0400371 If it has no updates, it will return 3.
Jon Hallacabffd2014-10-09 12:36:53 -0400372
kelvin8ec71442015-01-15 16:57:00 -0800373 """
Jon Hallacabffd2014-10-09 12:36:53 -0400374 try:
kelvin8ec71442015-01-15 16:57:00 -0800375 self.handle.sendline( "cd " + self.home )
kelvin-onlaba1484582015-02-02 15:46:20 -0800376 self.handle.expect( self.home + "\$" )
Jon Hall61282e32015-03-19 11:34:11 -0700377 cmd = "git pull"
378 if comp1 != "":
379 cmd += ' ' + comp1
380 if fastForward:
381 cmd += ' ' + " --ff-only"
382 self.handle.sendline( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800383 i = self.handle.expect(
384 [
385 'fatal',
386 'Username\sfor\s(.*):\s',
387 '\sfile(s*) changed,\s',
388 'Already up-to-date',
389 'Aborting',
390 'You\sare\snot\scurrently\son\sa\sbranch',
Jon Hall274b6642015-02-17 11:57:17 -0800391 'You asked me to pull without telling me which branch you',
392 'Pull is not possible because you have unmerged files',
Jon Hall61282e32015-03-19 11:34:11 -0700393 'Please enter a commit message to explain why this merge',
394 'Found a swap file by the name',
395 'Please, commit your changes before you can merge.',
kelvin-onlabd3b64892015-01-20 13:26:24 -0800396 pexpect.TIMEOUT ],
397 timeout=300 )
kelvin8ec71442015-01-15 16:57:00 -0800398 if i == 0:
Jon Hall61282e32015-03-19 11:34:11 -0700399 main.log.error( self.name + ": Git pull had some issue" )
400 output = self.handle.after
401 self.handle.expect( '\$' )
402 output += self.handle.before
403 main.log.warn( output )
Jon Hallacabffd2014-10-09 12:36:53 -0400404 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800405 elif i == 1:
406 main.log.error(
407 self.name +
408 ": Git Pull Asking for username. " )
Jon Hallacabffd2014-10-09 12:36:53 -0400409 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800410 elif i == 2:
411 main.log.info(
412 self.name +
413 ": Git Pull - pulling repository now" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800414 self.handle.expect( self.home + "\$", 120 )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800415 # So that only when git pull is done, we do mvn clean compile
416 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800417 elif i == 3:
418 main.log.info( self.name + ": Git Pull - Already up to date" )
Jon Hall47a93fb2015-01-06 16:46:06 -0800419 return i
kelvin8ec71442015-01-15 16:57:00 -0800420 elif i == 4:
421 main.log.info(
422 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800423 ": Git Pull - Aborting..." +
424 "Are there conflicting git files?" )
Jon Hallacabffd2014-10-09 12:36:53 -0400425 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800426 elif i == 5:
427 main.log.info(
428 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800429 ": Git Pull - You are not currently " +
430 "on a branch so git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400431 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800432 elif i == 6:
433 main.log.info(
434 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800435 ": Git Pull - You have not configured an upstream " +
436 "branch to pull from. Git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400437 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800438 elif i == 7:
439 main.log.info(
440 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800441 ": Git Pull - Pull is not possible because " +
442 "you have unmerged files." )
Jon Hallacabffd2014-10-09 12:36:53 -0400443 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800444 elif i == 8:
Jon Hall61282e32015-03-19 11:34:11 -0700445 # NOTE: abandoning test since we can't reliably handle this
446 # there could be different default text editors and we
447 # also don't know if we actually want to make the commit
448 main.log.error( "Git pull resulted in a merge commit message" +
449 ". Exiting test!" )
450 main.cleanup()
451 main.exit()
452 elif i == 9: # Merge commit message but swap file exists
453 main.log.error( "Git pull resulted in a merge commit message" +
454 " but a swap file exists." )
455 try:
456 self.handle.send( 'A' ) # Abort
457 self.handle.expect( "\$" )
458 return main.ERROR
459 except Exception:
460 main.log.exception( "Couldn't exit editor prompt!")
461 main.cleanup()
462 main.exit()
463 elif i == 10: # In the middle of a merge commit
464 main.log.error( "Git branch is in the middle of a merge. " )
465 main.log.warn( self.handle.before + self.handle.after )
466 return main.ERROR
467 elif i == 11:
kelvin8ec71442015-01-15 16:57:00 -0800468 main.log.error( self.name + ": Git Pull - TIMEOUT" )
469 main.log.error(
470 self.name + " Response was: " + str(
471 self.handle.before ) )
Jon Hallacabffd2014-10-09 12:36:53 -0400472 return main.ERROR
473 else:
kelvin8ec71442015-01-15 16:57:00 -0800474 main.log.error(
475 self.name +
476 ": Git Pull - Unexpected response, check for pull errors" )
Jon Hallacabffd2014-10-09 12:36:53 -0400477 return main.ERROR
478 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800479 main.log.error( self.name + ": EOF exception found" )
480 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400481 main.cleanup()
482 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800483 except Exception:
484 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400485 main.cleanup()
486 main.exit()
487
kelvin-onlabd3b64892015-01-20 13:26:24 -0800488 def gitCheckout( self, branch="master" ):
kelvin8ec71442015-01-15 16:57:00 -0800489 """
Jon Hallacabffd2014-10-09 12:36:53 -0400490 Assumes that "git pull" works without login
kelvin8ec71442015-01-15 16:57:00 -0800491
Jon Hallacabffd2014-10-09 12:36:53 -0400492 This function will perform a git git checkout on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800493 If used as gitCheckout( "branch" ) it will do git checkout
494 of the "branch".
Jon Hallacabffd2014-10-09 12:36:53 -0400495
496 Otherwise, this function will perform a git checkout of the master
kelvin8ec71442015-01-15 16:57:00 -0800497 branch of the ONOS repository. If it has any problems, it will return
498 main.ERROR.
499 If the branch was already the specified branch, or the git checkout was
Jon Hallacabffd2014-10-09 12:36:53 -0400500 successful then the function will return main.TRUE.
501
kelvin8ec71442015-01-15 16:57:00 -0800502 """
Jon Hallacabffd2014-10-09 12:36:53 -0400503 try:
kelvin8ec71442015-01-15 16:57:00 -0800504 self.handle.sendline( "cd " + self.home )
kelvin-onlaba1484582015-02-02 15:46:20 -0800505 self.handle.expect( self.home + "\$" )
Jon Hall274b6642015-02-17 11:57:17 -0800506 main.log.info( self.name +
507 ": Checking out git branch/ref: " + branch + "..." )
kelvin8ec71442015-01-15 16:57:00 -0800508 cmd = "git checkout " + branch
509 self.handle.sendline( cmd )
510 self.handle.expect( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800511 i = self.handle.expect(
Jon Hall274b6642015-02-17 11:57:17 -0800512 [ 'fatal',
Jon Hall61282e32015-03-19 11:34:11 -0700513 'Username for (.*): ',
514 'Already on \'',
Jon Hall7a8354f2015-06-10 15:37:00 -0700515 'Switched to (a new )?branch \'' + str( branch ),
Jon Hall274b6642015-02-17 11:57:17 -0800516 pexpect.TIMEOUT,
517 'error: Your local changes to the following files' +
Jon Hallefbd9792015-03-05 16:11:36 -0800518 'would be overwritten by checkout:',
Jon Hall274b6642015-02-17 11:57:17 -0800519 'error: you need to resolve your current index first',
520 "You are in 'detached HEAD' state.",
521 "HEAD is now at " ],
kelvin-onlabd3b64892015-01-20 13:26:24 -0800522 timeout=60 )
kelvin8ec71442015-01-15 16:57:00 -0800523 if i == 0:
524 main.log.error(
525 self.name +
526 ": Git checkout had some issue..." )
527 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400528 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800529 elif i == 1:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800530 main.log.error(
531 self.name +
532 ": Git checkout asking for username." +
533 " Please configure your local git repository to be able " +
534 "to access your remote repository passwordlessly" )
Jon Hall274b6642015-02-17 11:57:17 -0800535 # TODO add support for authenticating
Jon Hallacabffd2014-10-09 12:36:53 -0400536 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800537 elif i == 2:
538 main.log.info(
539 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800540 ": Git Checkout %s : Already on this branch" % branch )
kelvin-onlaba1484582015-02-02 15:46:20 -0800541 self.handle.expect( self.home + "\$" )
kelvin8ec71442015-01-15 16:57:00 -0800542 # main.log.info( "DEBUG: after checkout cmd = "+
543 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400544 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800545 elif i == 3:
546 main.log.info(
547 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800548 ": Git checkout %s - Switched to this branch" % branch )
kelvin-onlaba1484582015-02-02 15:46:20 -0800549 self.handle.expect( self.home + "\$" )
kelvin8ec71442015-01-15 16:57:00 -0800550 # main.log.info( "DEBUG: after checkout cmd = "+
551 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400552 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800553 elif i == 4:
554 main.log.error( self.name + ": Git Checkout- TIMEOUT" )
555 main.log.error(
Jon Hall274b6642015-02-17 11:57:17 -0800556 self.name + " Response was: " + str( self.handle.before ) )
Jon Hallacabffd2014-10-09 12:36:53 -0400557 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800558 elif i == 5:
559 self.handle.expect( "Aborting" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800560 main.log.error(
561 self.name +
562 ": Git checkout error: \n" +
Jon Hall274b6642015-02-17 11:57:17 -0800563 "Your local changes to the following files would" +
564 " be overwritten by checkout:" +
565 str( self.handle.before ) )
kelvin-onlaba1484582015-02-02 15:46:20 -0800566 self.handle.expect( self.home + "\$" )
Jon Hall81e29af2014-11-04 20:41:23 -0500567 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800568 elif i == 6:
Jon Hall274b6642015-02-17 11:57:17 -0800569 main.log.error(
570 self.name +
571 ": Git checkout error: \n" +
572 "You need to resolve your current index first:" +
573 str( self.handle.before ) )
kelvin-onlaba1484582015-02-02 15:46:20 -0800574 self.handle.expect( self.home + "\$" )
Jon Hall81e29af2014-11-04 20:41:23 -0500575 return main.ERROR
Jon Hall274b6642015-02-17 11:57:17 -0800576 elif i == 7:
577 main.log.info(
578 self.name +
579 ": Git checkout " + str( branch ) +
580 " - You are in 'detached HEAD' state. HEAD is now at " +
581 str( branch ) )
582 self.handle.expect( self.home + "\$" )
583 return main.TRUE
584 elif i == 8: # Already in detached HEAD on the specified commit
585 main.log.info(
586 self.name +
587 ": Git Checkout %s : Already on commit" % branch )
588 self.handle.expect( self.home + "\$" )
589 return main.TRUE
Jon Hallacabffd2014-10-09 12:36:53 -0400590 else:
kelvin8ec71442015-01-15 16:57:00 -0800591 main.log.error(
592 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800593 ": Git Checkout - Unexpected response, " +
594 "check for pull errors" )
kelvin8ec71442015-01-15 16:57:00 -0800595 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400596 return main.ERROR
597
598 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800599 main.log.error( self.name + ": EOF exception found" )
600 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400601 main.cleanup()
602 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800603 except Exception:
604 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400605 main.cleanup()
606 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400607
pingping-lin6d23d9e2015-02-02 16:54:24 -0800608 def getBranchName( self ):
pingping-linf30cf272015-05-29 15:54:07 -0700609 main.log.info( "self.home = " )
610 main.log.info( self.home )
pingping-lin6d23d9e2015-02-02 16:54:24 -0800611 self.handle.sendline( "cd " + self.home )
pingping-lin9bf3d8f2015-05-29 16:05:28 -0700612 self.handle.expect( self.home + "\$" )
pingping-lin6d23d9e2015-02-02 16:54:24 -0800613 self.handle.sendline( "git name-rev --name-only HEAD" )
614 self.handle.expect( "git name-rev --name-only HEAD" )
615 self.handle.expect( "\$" )
616
617 lines = self.handle.before.splitlines()
618 if lines[1] == "master":
619 return "master"
620 elif lines[1] == "onos-1.0":
621 return "onos-1.0"
622 else:
623 main.log.info( lines[1] )
624 return "unexpected ONOS branch for SDN-IP test"
625
kelvin-onlabd3b64892015-01-20 13:26:24 -0800626 def getVersion( self, report=False ):
kelvin8ec71442015-01-15 16:57:00 -0800627 """
Jon Hall274b6642015-02-17 11:57:17 -0800628 Writes the COMMIT number to the report to be parsed
Jon Hallefbd9792015-03-05 16:11:36 -0800629 by Jenkins data collector.
kelvin8ec71442015-01-15 16:57:00 -0800630 """
Jon Hall45ec0922014-10-10 19:33:49 -0400631 try:
kelvin8ec71442015-01-15 16:57:00 -0800632 self.handle.sendline( "" )
633 self.handle.expect( "\$" )
634 self.handle.sendline(
635 "cd " +
636 self.home +
Jon Hall274b6642015-02-17 11:57:17 -0800637 "; git log -1 --pretty=fuller --decorate=short | grep -A 6 " +
638 " \"commit\" --color=never" )
kelvin8ec71442015-01-15 16:57:00 -0800639 # NOTE: for some reason there are backspaces inserted in this
640 # phrase when run from Jenkins on some tests
641 self.handle.expect( "never" )
642 self.handle.expect( "\$" )
643 response = ( self.name + ": \n" + str(
644 self.handle.before + self.handle.after ) )
645 self.handle.sendline( "cd " + self.home )
646 self.handle.expect( "\$" )
647 lines = response.splitlines()
Jon Hall45ec0922014-10-10 19:33:49 -0400648 for line in lines:
Jon Hallfd191202014-11-07 18:36:09 -0500649 print line
650 if report:
pingping-lin763ee042015-05-20 17:45:30 -0700651 main.log.wiki( "<blockquote>" )
kelvin8ec71442015-01-15 16:57:00 -0800652 for line in lines[ 2:-1 ]:
653 # Bracket replacement is for Wiki-compliant
654 # formatting. '<' or '>' are interpreted
655 # as xml specific tags that cause errors
656 line = line.replace( "<", "[" )
657 line = line.replace( ">", "]" )
pingping-lin763ee042015-05-20 17:45:30 -0700658 #main.log.wiki( "\t" + line )
659 main.log.wiki( line + "<br /> " )
660 main.log.summary( line )
661 main.log.wiki( "</blockquote>" )
662 main.log.summary("\n")
kelvin8ec71442015-01-15 16:57:00 -0800663 return lines[ 2 ]
Jon Hall45ec0922014-10-10 19:33:49 -0400664 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800665 main.log.error( self.name + ": EOF exception found" )
666 main.log.error( self.name + ": " + self.handle.before )
Jon Hall45ec0922014-10-10 19:33:49 -0400667 main.cleanup()
668 main.exit()
Jon Hall368769f2014-11-19 15:43:35 -0800669 except pexpect.TIMEOUT:
kelvin8ec71442015-01-15 16:57:00 -0800670 main.log.error( self.name + ": TIMEOUT exception found" )
671 main.log.error( self.name + ": " + self.handle.before )
Jon Hall368769f2014-11-19 15:43:35 -0800672 main.cleanup()
673 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800674 except Exception:
675 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall45ec0922014-10-10 19:33:49 -0400676 main.cleanup()
677 main.exit()
678
kelvin-onlabd3b64892015-01-20 13:26:24 -0800679 def createCellFile( self, benchIp, fileName, mnIpAddrs,
Flavio Castrocc38a542016-03-03 13:15:46 -0800680 appString, onosIpAddrs, onosUser="sdn" ):
kelvin8ec71442015-01-15 16:57:00 -0800681 """
andrewonlab94282092014-10-10 13:00:11 -0400682 Creates a cell file based on arguments
683 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800684 * Bench IP address ( benchIp )
andrewonlab94282092014-10-10 13:00:11 -0400685 - Needed to copy the cell file over
kelvin-onlabd3b64892015-01-20 13:26:24 -0800686 * File name of the cell file ( fileName )
687 * Mininet IP address ( mnIpAddrs )
kelvin8ec71442015-01-15 16:57:00 -0800688 - Note that only 1 ip address is
andrewonlab94282092014-10-10 13:00:11 -0400689 supported currently
kelvin-onlabd3b64892015-01-20 13:26:24 -0800690 * ONOS IP addresses ( onosIpAddrs )
andrewonlab94282092014-10-10 13:00:11 -0400691 - Must be passed in as last arguments
Flavio Castrocc38a542016-03-03 13:15:46 -0800692 * ONOS USER (onosUser)
693 - optional argument to set ONOS_USER environment variable
kelvin8ec71442015-01-15 16:57:00 -0800694
andrewonlab94282092014-10-10 13:00:11 -0400695 NOTE: Assumes cells are located at:
696 ~/<self.home>/tools/test/cells/
kelvin8ec71442015-01-15 16:57:00 -0800697 """
698 # Variable initialization
Jon Hall6801cda2015-07-15 14:13:45 -0700699 cellDirectory = self.home + "/tools/test/cells/"
kelvin8ec71442015-01-15 16:57:00 -0800700 # We want to create the cell file in the dependencies directory
701 # of TestON first, then copy over to ONOS bench
kelvin-onlabd3b64892015-01-20 13:26:24 -0800702 tempDirectory = "/tmp/"
kelvin8ec71442015-01-15 16:57:00 -0800703 # Create the cell file in the directory for writing ( w+ )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800704 cellFile = open( tempDirectory + fileName, 'w+' )
Jon Hall6801cda2015-07-15 14:13:45 -0700705 if isinstance( onosIpAddrs, types.StringType ):
706 onosIpAddrs = [ onosIpAddrs ]
kelvin8ec71442015-01-15 16:57:00 -0800707
cameron@onlab.us75900962015-03-30 13:22:49 -0700708 # App string is hardcoded environment variables
kelvin8ec71442015-01-15 16:57:00 -0800709 # That you may wish to use by default on startup.
cameron@onlab.us75900962015-03-30 13:22:49 -0700710 # Note that you may not want certain apps listed
kelvin8ec71442015-01-15 16:57:00 -0800711 # on here.
cameron@onlab.us75900962015-03-30 13:22:49 -0700712 appString = "export ONOS_APPS=" + appString
Flavio Castrocc38a542016-03-03 13:15:46 -0800713 onosGroup = "export ONOS_GROUP=" + onosUser
714 onosUser = "export ONOS_USER=" + onosUser
kelvin-onlabd3b64892015-01-20 13:26:24 -0800715 mnString = "export OCN="
kelvin-onlabf70fd542015-05-07 18:41:40 -0700716 if mnIpAddrs == "":
717 mnString = ""
kelvin-onlabd3b64892015-01-20 13:26:24 -0800718 onosString = "export OC"
719 tempCount = 1
kelvin8ec71442015-01-15 16:57:00 -0800720
kelvin-onlabd3b64892015-01-20 13:26:24 -0800721 # Create ONOSNIC ip address prefix
kelvin-onlaba4074292015-07-09 15:19:49 -0700722 tempOnosIp = str( onosIpAddrs[ 0 ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800723 tempList = []
724 tempList = tempOnosIp.split( "." )
kelvin8ec71442015-01-15 16:57:00 -0800725 # Omit last element of list to format for NIC
kelvin-onlabd3b64892015-01-20 13:26:24 -0800726 tempList = tempList[ :-1 ]
kelvin8ec71442015-01-15 16:57:00 -0800727 # Structure the nic string ip
kelvin-onlabd3b64892015-01-20 13:26:24 -0800728 nicAddr = ".".join( tempList ) + ".*"
Jon Hall6c44c0b2016-04-20 15:21:00 -0700729 self.nicAddr = nicAddr
kelvin-onlabd3b64892015-01-20 13:26:24 -0800730 onosNicString = "export ONOS_NIC=" + nicAddr
andrewonlab94282092014-10-10 13:00:11 -0400731
732 try:
kelvin8ec71442015-01-15 16:57:00 -0800733 # Start writing to file
kelvin-onlabd3b64892015-01-20 13:26:24 -0800734 cellFile.write( onosNicString + "\n" )
andrewonlab94282092014-10-10 13:00:11 -0400735
kelvin-onlabd3b64892015-01-20 13:26:24 -0800736 for arg in onosIpAddrs:
737 # For each argument in onosIpAddrs, write to file
kelvin8ec71442015-01-15 16:57:00 -0800738 # Output should look like the following:
andrewonlabd4940492014-10-24 12:21:27 -0400739 # export OC1="10.128.20.11"
740 # export OC2="10.128.20.12"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800741 cellFile.write( onosString + str( tempCount ) +
Jon Hall6f665652015-09-18 10:08:07 -0700742 "=\"" + arg + "\"\n" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800743 tempCount = tempCount + 1
kelvin8ec71442015-01-15 16:57:00 -0800744
Jon Hall6f665652015-09-18 10:08:07 -0700745 cellFile.write( "export OCI=$OC1\n" )
746 cellFile.write( mnString + "\"" + mnIpAddrs + "\"\n" )
cameron@onlab.us75900962015-03-30 13:22:49 -0700747 cellFile.write( appString + "\n" )
Flavio Castrocc38a542016-03-03 13:15:46 -0800748 cellFile.write( onosGroup + "\n" )
749 cellFile.write( onosUser + "\n" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800750 cellFile.close()
andrewonlab94282092014-10-10 13:00:11 -0400751
kelvin8ec71442015-01-15 16:57:00 -0800752 # We use os.system to send the command to TestON cluster
753 # to account for the case in which TestON is not located
754 # on the same cluster as the ONOS bench
755 # Note that even if TestON is located on the same cluster
756 # as ONOS bench, you must setup passwordless ssh
757 # between TestON and ONOS bench in order to automate the test.
kelvin-onlabc2b79102015-07-14 11:41:20 -0700758 os.system( "scp " + tempDirectory + fileName + " " +
759 self.user_name + "@" + self.ip_address + ":" + cellDirectory )
andrewonlab94282092014-10-10 13:00:11 -0400760
andrewonlab2a6c9342014-10-16 13:40:15 -0400761 return main.TRUE
762
andrewonlab94282092014-10-10 13:00:11 -0400763 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800764 main.log.error( self.name + ": EOF exception found" )
765 main.log.error( self.name + ": " + self.handle.before )
andrewonlab94282092014-10-10 13:00:11 -0400766 main.cleanup()
767 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800768 except Exception:
769 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab94282092014-10-10 13:00:11 -0400770 main.cleanup()
771 main.exit()
772
kelvin-onlabd3b64892015-01-20 13:26:24 -0800773 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800774 """
andrewonlab95ca1462014-10-09 14:04:24 -0400775 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800776 """
Hari Krishna03f530e2015-07-10 17:28:27 -0700777 import re
andrewonlab95ca1462014-10-09 14:04:24 -0400778 try:
779 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800780 main.log.error( "Must define cellname" )
andrewonlab95ca1462014-10-09 14:04:24 -0400781 main.cleanup()
782 main.exit()
783 else:
kelvin8ec71442015-01-15 16:57:00 -0800784 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800785 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800786 # Note that this variable name is subject to change
andrewonlab95ca1462014-10-09 14:04:24 -0400787 # and that this driver will have to change accordingly
Jon Hall3b489db2015-10-05 14:38:37 -0700788 self.handle.expect( str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800789 handleBefore = self.handle.before
790 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800791 # Get the rest of the handle
Jon Hall3b489db2015-10-05 14:38:37 -0700792 self.handle.expect( "\$" )
Jon Hall439c8912016-04-15 02:22:03 -0700793 time.sleep(10)
kelvin-onlabd3b64892015-01-20 13:26:24 -0800794 handleMore = self.handle.before
andrewonlab95ca1462014-10-09 14:04:24 -0400795
Hari Krishna03f530e2015-07-10 17:28:27 -0700796 cell_result = handleBefore + handleAfter + handleMore
suibin zhang116647a2016-05-06 16:30:09 -0700797 #print cell_result
Hari Krishna03f530e2015-07-10 17:28:27 -0700798 if( re.search( "No such cell", cell_result ) ):
799 main.log.error( "Cell call returned: " + handleBefore +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800800 handleAfter + handleMore )
Hari Krishna03f530e2015-07-10 17:28:27 -0700801 main.cleanup()
802 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400803 return main.TRUE
andrewonlab95ca1462014-10-09 14:04:24 -0400804 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800805 main.log.error( self.name + ": EOF exception found" )
806 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ca1462014-10-09 14:04:24 -0400807 main.cleanup()
808 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800809 except Exception:
810 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ca1462014-10-09 14:04:24 -0400811 main.cleanup()
812 main.exit()
813
kelvin-onlabd3b64892015-01-20 13:26:24 -0800814 def verifyCell( self ):
kelvin8ec71442015-01-15 16:57:00 -0800815 """
andrewonlabc03bf6c2014-10-09 14:56:18 -0400816 Calls 'onos-verify-cell' to check for cell installation
kelvin8ec71442015-01-15 16:57:00 -0800817 """
818 # TODO: Add meaningful expect value
andrewonlab8d0d7d72014-10-09 16:33:15 -0400819
andrewonlabc03bf6c2014-10-09 14:56:18 -0400820 try:
kelvin8ec71442015-01-15 16:57:00 -0800821 # Clean handle by sending empty and expecting $
822 self.handle.sendline( "" )
823 self.handle.expect( "\$" )
824 self.handle.sendline( "onos-verify-cell" )
825 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800826 handleBefore = self.handle.before
827 handleAfter = self.handle.after
kelvin-onlabd3b64892015-01-20 13:26:24 -0800828 main.log.info( "Verify cell returned: " + handleBefore +
Jon Hall3b489db2015-10-05 14:38:37 -0700829 handleAfter )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400830 return main.TRUE
Jon Halla5cb6172015-02-23 09:28:28 -0800831 except pexpect.ExceptionPexpect as e:
Jon Hall3b489db2015-10-05 14:38:37 -0700832 main.log.exception( self.name + ": Pexpect exception found: " )
kelvin8ec71442015-01-15 16:57:00 -0800833 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -0400834 main.cleanup()
835 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800836 except Exception:
837 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400838 main.cleanup()
839 main.exit()
840
jenkins1e99e7b2015-04-02 18:15:39 -0700841 def onosCfgSet( self, ONOSIp, configName, configParam ):
842 """
843 Uses 'onos <node-ip> cfg set' to change a parameter value of an
Jon Hall4ba53f02015-07-29 13:07:41 -0700844 application.
845
jenkins1e99e7b2015-04-02 18:15:39 -0700846 ex)
847 onos 10.0.0.1 cfg set org.onosproject.myapp appSetting 1
jenkins1e99e7b2015-04-02 18:15:39 -0700848 ONOSIp = '10.0.0.1'
849 configName = 'org.onosproject.myapp'
850 configParam = 'appSetting 1'
jenkins1e99e7b2015-04-02 18:15:39 -0700851 """
Jon Hall72280bc2016-01-25 14:29:05 -0800852 try:
853 cfgStr = "onos {} cfg set {} {}".format( ONOSIp,
854 configName,
855 configParam )
856 self.handle.sendline( "" )
857 self.handle.expect( ":~" )
858 self.handle.sendline( cfgStr )
859 self.handle.expect("cfg set")
860 self.handle.expect( ":~" )
jenkins1e99e7b2015-04-02 18:15:39 -0700861
Jon Hall72280bc2016-01-25 14:29:05 -0800862 paramValue = configParam.split(" ")[1]
863 paramName = configParam.split(" ")[0]
Jon Hall4ba53f02015-07-29 13:07:41 -0700864
Jon Hall72280bc2016-01-25 14:29:05 -0800865 checkStr = 'onos {} cfg get " {} {} " '.format( ONOSIp, configName, paramName )
Jon Hall4ba53f02015-07-29 13:07:41 -0700866
Jon Hall72280bc2016-01-25 14:29:05 -0800867 self.handle.sendline( checkStr )
868 self.handle.expect( ":~" )
jenkins1e99e7b2015-04-02 18:15:39 -0700869
Jon Hall72280bc2016-01-25 14:29:05 -0800870 if "value=" + paramValue + "," in self.handle.before:
871 main.log.info("cfg " + configName + " successfully set to " + configParam)
872 return main.TRUE
873 except pexpect.ExceptionPexpect as e:
874 main.log.exception( self.name + ": Pexpect exception found: " )
875 main.log.error( self.name + ": " + self.handle.before )
876 main.cleanup()
877 main.exit()
878 except Exception:
879 main.log.exception( self.name + ": Uncaught exception!" )
880 main.cleanup()
881 main.exit()
Jon Hall4ba53f02015-07-29 13:07:41 -0700882
kelvin-onlabd3b64892015-01-20 13:26:24 -0800883 def onosCli( self, ONOSIp, cmdstr ):
kelvin8ec71442015-01-15 16:57:00 -0800884 """
andrewonlab05e362f2014-10-10 00:40:57 -0400885 Uses 'onos' command to send various ONOS CLI arguments.
886 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800887 * ONOSIp: specify the ip of the cell machine
andrewonlab94282092014-10-10 13:00:11 -0400888 * cmdstr: specify the command string to send
kelvin8ec71442015-01-15 16:57:00 -0800889
890 This function is intended to expose the entire karaf
andrewonlab6e20c342014-10-10 18:08:48 -0400891 CLI commands for ONOS. Try to use this function first
892 before attempting to write a ONOS CLI specific driver
kelvin8ec71442015-01-15 16:57:00 -0800893 function.
894 You can see a list of available 'cmdstr' arguments
andrewonlab6e20c342014-10-10 18:08:48 -0400895 by starting onos, and typing in 'onos' to enter the
896 onos> CLI. Then, type 'help' to see the list of
kelvin8ec71442015-01-15 16:57:00 -0800897 available commands.
898 """
andrewonlab05e362f2014-10-10 00:40:57 -0400899 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800900 if not ONOSIp:
kelvin8ec71442015-01-15 16:57:00 -0800901 main.log.error( "You must specify the IP address" )
andrewonlab05e362f2014-10-10 00:40:57 -0400902 return main.FALSE
903 if not cmdstr:
kelvin8ec71442015-01-15 16:57:00 -0800904 main.log.error( "You must specify the command string" )
andrewonlab05e362f2014-10-10 00:40:57 -0400905 return main.FALSE
906
kelvin8ec71442015-01-15 16:57:00 -0800907 cmdstr = str( cmdstr )
908 self.handle.sendline( "" )
909 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400910
kelvin-onlabd3b64892015-01-20 13:26:24 -0800911 self.handle.sendline( "onos -w " + ONOSIp + " " + cmdstr )
kelvin8ec71442015-01-15 16:57:00 -0800912 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400913
kelvin-onlabd3b64892015-01-20 13:26:24 -0800914 handleBefore = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -0800915 main.log.info( "Command sent successfully" )
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
kelvin-onlabd3b64892015-01-20 13:26:24 -0800920 return returnString
andrewonlab05e362f2014-10-10 00:40:57 -0400921 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800922 main.log.error( self.name + ": EOF exception found" )
923 main.log.error( self.name + ": " + self.handle.before )
andrewonlab05e362f2014-10-10 00:40:57 -0400924 main.cleanup()
925 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800926 except Exception:
927 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab05e362f2014-10-10 00:40:57 -0400928 main.cleanup()
929 main.exit()
Jon Hall7993bfc2014-10-09 16:30:14 -0400930
kelvin-onlabd3b64892015-01-20 13:26:24 -0800931 def onosInstall( self, options="-f", node="" ):
kelvin8ec71442015-01-15 16:57:00 -0800932 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400933 Installs ONOS bits on the designated cell machine.
kelvin8ec71442015-01-15 16:57:00 -0800934 If -f option is provided, it also forces an uninstall.
935 Presently, install also includes onos-push-bits and
Jon Hall7993bfc2014-10-09 16:30:14 -0400936 onos-config within.
kelvin8ec71442015-01-15 16:57:00 -0800937 The node option allows you to selectively only push the jar
Jon Hall7993bfc2014-10-09 16:30:14 -0400938 files to certain onos nodes
939
940 Returns: main.TRUE on success and main.FALSE on failure
kelvin8ec71442015-01-15 16:57:00 -0800941 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400942 try:
andrewonlab114768a2014-11-14 12:44:44 -0500943 if options:
kelvin8ec71442015-01-15 16:57:00 -0800944 self.handle.sendline( "onos-install " + options + " " + node )
andrewonlab114768a2014-11-14 12:44:44 -0500945 else:
kelvin8ec71442015-01-15 16:57:00 -0800946 self.handle.sendline( "onos-install " + node )
947 self.handle.expect( "onos-install " )
948 # NOTE: this timeout may need to change depending on the network
949 # and size of ONOS
950 i = self.handle.expect( [ "Network\sis\sunreachable",
kelvin-onlabd3b64892015-01-20 13:26:24 -0800951 "onos\sstart/running,\sprocess",
kelvin8ec71442015-01-15 16:57:00 -0800952 "ONOS\sis\salready\sinstalled",
Jeremyc72b2582016-02-26 18:27:38 -0800953 "already\sup-to-date",
954 "\$",
Jon Hall6c44c0b2016-04-20 15:21:00 -0700955 pexpect.TIMEOUT ], timeout=180 )
Jon Hall7993bfc2014-10-09 16:30:14 -0400956 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800957 main.log.warn( "Network is unreachable" )
Jon Hall3b489db2015-10-05 14:38:37 -0700958 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400959 return main.FALSE
960 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800961 main.log.info(
962 "ONOS was installed on " +
963 node +
964 " and started" )
Jon Hall3b489db2015-10-05 14:38:37 -0700965 self.handle.expect( "\$" )
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 )
Jon Hall3b489db2015-10-05 14:38:37 -0700969 self.handle.expect( "\$" )
andrewonlabd9a73a72014-11-14 17:28:21 -0500970 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800971 elif i == 3:
Jeremyc72b2582016-02-26 18:27:38 -0800972 main.log.info( "ONOS is already installed on " + node )
973 self.handle.expect( "\$" )
974 return main.TRUE
975 elif i == 4:
976 main.log.info( "ONOS was installed on " + node )
977 return main.TRUE
978 elif i == 5:
kelvin8ec71442015-01-15 16:57:00 -0800979 main.log.info(
980 "Installation of ONOS on " +
981 node +
982 " timed out" )
Jon Hall3b489db2015-10-05 14:38:37 -0700983 self.handle.expect( "\$" )
Jon Hall53c5e662016-04-13 16:06:56 -0700984 main.log.warn( self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -0400985 return main.FALSE
andrewonlabc03bf6c2014-10-09 14:56:18 -0400986 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800987 main.log.error( self.name + ": EOF exception found" )
988 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400989 main.cleanup()
990 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800991 except Exception:
992 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400993 main.cleanup()
994 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400995
kelvin-onlabd3b64892015-01-20 13:26:24 -0800996 def onosStart( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800997 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400998 Calls onos command: 'onos-service [<node-ip>] start'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400999 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -08001000 """
andrewonlab8d0d7d72014-10-09 16:33:15 -04001001 try:
kelvin8ec71442015-01-15 16:57:00 -08001002 self.handle.sendline( "" )
1003 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001004 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001005 " start" )
1006 i = self.handle.expect( [
andrewonlab8d0d7d72014-10-09 16:33:15 -04001007 "Job\sis\salready\srunning",
1008 "start/running",
Jeremyd0e9a6d2016-03-02 11:28:52 -08001009 "\$",
andrewonlab8d0d7d72014-10-09 16:33:15 -04001010 "Unknown\sinstance",
Jeremy Songster14c13572016-04-21 17:34:03 -07001011 pexpect.TIMEOUT ], timeout=180 )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001012 if i == 0:
Jon Halleab7a242016-03-04 10:20:43 -08001013 self.handle.expect( "\$" )
kelvin8ec71442015-01-15 16:57:00 -08001014 main.log.info( "Service is already running" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001015 return main.TRUE
1016 elif i == 1:
Jon Halleab7a242016-03-04 10:20:43 -08001017 self.handle.expect( "\$" )
kelvin8ec71442015-01-15 16:57:00 -08001018 main.log.info( "ONOS service started" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001019 return main.TRUE
Jeremyd0e9a6d2016-03-02 11:28:52 -08001020 elif i == 2:
1021 main.log.info( "ONOS service started" )
1022 return main.TRUE
andrewonlab8d0d7d72014-10-09 16:33:15 -04001023 else:
Jon Halleab7a242016-03-04 10:20:43 -08001024 self.handle.expect( "\$" )
kelvin8ec71442015-01-15 16:57:00 -08001025 main.log.error( "ONOS service failed to start" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001026 main.cleanup()
1027 main.exit()
andrewonlab8d0d7d72014-10-09 16:33:15 -04001028 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001029 main.log.error( self.name + ": EOF exception found" )
1030 main.log.error( self.name + ": " + self.handle.before )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001031 main.cleanup()
1032 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001033 except Exception:
1034 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001035 main.cleanup()
1036 main.exit()
1037
kelvin-onlabd3b64892015-01-20 13:26:24 -08001038 def onosStop( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001039 """
andrewonlab2b30bd32014-10-09 16:48:55 -04001040 Calls onos command: 'onos-service [<node-ip>] stop'
andrewonlabe8e56fd2014-10-09 17:12:44 -04001041 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -08001042 """
andrewonlab2b30bd32014-10-09 16:48:55 -04001043 try:
kelvin8ec71442015-01-15 16:57:00 -08001044 self.handle.sendline( "" )
1045 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001046 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001047 " stop" )
1048 i = self.handle.expect( [
andrewonlab2b30bd32014-10-09 16:48:55 -04001049 "stop/waiting",
Jon Hall61282e32015-03-19 11:34:11 -07001050 "Could not resolve hostname",
andrewonlab2b30bd32014-10-09 16:48:55 -04001051 "Unknown\sinstance",
YPZhang77badfc2016-03-09 10:28:59 -08001052 "\$",
Jeremy Songster14c13572016-04-21 17:34:03 -07001053 pexpect.TIMEOUT ], timeout=180 )
andrewonlab2b30bd32014-10-09 16:48:55 -04001054 if i == 0:
YPZhang77badfc2016-03-09 10:28:59 -08001055 self.handle.expect( "\$" )
kelvin8ec71442015-01-15 16:57:00 -08001056 main.log.info( "ONOS service stopped" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001057 return main.TRUE
1058 elif i == 1:
YPZhang77badfc2016-03-09 10:28:59 -08001059 self.handle.expect( "\$" )
Jon Hall65844a32015-03-09 19:09:37 -07001060 main.log.info( "onosStop() Unknown ONOS instance specified: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001061 str( nodeIp ) )
andrewonlab2b30bd32014-10-09 16:48:55 -04001062 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -07001063 elif i == 2:
YPZhang77badfc2016-03-09 10:28:59 -08001064 self.handle.expect( "\$" )
Jon Hall61282e32015-03-19 11:34:11 -07001065 main.log.warn( "ONOS wasn't running" )
1066 return main.TRUE
YPZhang77badfc2016-03-09 10:28:59 -08001067 elif i == 3:
1068 main.log.info( "ONOS service stopped" )
1069 return main.TRUE
andrewonlab2b30bd32014-10-09 16:48:55 -04001070 else:
kelvin8ec71442015-01-15 16:57:00 -08001071 main.log.error( "ONOS service failed to stop" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001072 return main.FALSE
andrewonlab2b30bd32014-10-09 16:48:55 -04001073 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001074 main.log.error( self.name + ": EOF exception found" )
1075 main.log.error( self.name + ": " + self.handle.before )
andrewonlab2b30bd32014-10-09 16:48:55 -04001076 main.cleanup()
1077 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001078 except Exception:
1079 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001080 main.cleanup()
1081 main.exit()
kelvin8ec71442015-01-15 16:57:00 -08001082
kelvin-onlabd3b64892015-01-20 13:26:24 -08001083 def onosUninstall( self, nodeIp="" ):
kelvin8ec71442015-01-15 16:57:00 -08001084 """
andrewonlabc8d47972014-10-09 16:52:36 -04001085 Calls the command: 'onos-uninstall'
kelvin8ec71442015-01-15 16:57:00 -08001086 Uninstalls ONOS from the designated cell machine, stopping
andrewonlabe8e56fd2014-10-09 17:12:44 -04001087 if needed
kelvin8ec71442015-01-15 16:57:00 -08001088 """
andrewonlabc8d47972014-10-09 16:52:36 -04001089 try:
kelvin8ec71442015-01-15 16:57:00 -08001090 self.handle.sendline( "" )
Jeremy Songster14c13572016-04-21 17:34:03 -07001091 self.handle.expect( "\$", timeout=180 )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001092 self.handle.sendline( "onos-uninstall " + str( nodeIp ) )
Jeremy Songster14c13572016-04-21 17:34:03 -07001093 self.handle.expect( "\$", timeout=180 )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001094 main.log.info( "ONOS " + nodeIp + " was uninstalled" )
kelvin8ec71442015-01-15 16:57:00 -08001095 # onos-uninstall command does not return any text
andrewonlabc8d47972014-10-09 16:52:36 -04001096 return main.TRUE
pingping-lin763ee042015-05-20 17:45:30 -07001097 except pexpect.TIMEOUT:
1098 main.log.exception( self.name + ": Timeout in onosUninstall" )
1099 return main.FALSE
andrewonlabc8d47972014-10-09 16:52:36 -04001100 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001101 main.log.error( self.name + ": EOF exception found" )
1102 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc8d47972014-10-09 16:52:36 -04001103 main.cleanup()
1104 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001105 except Exception:
1106 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc8d47972014-10-09 16:52:36 -04001107 main.cleanup()
1108 main.exit()
andrewonlab2b30bd32014-10-09 16:48:55 -04001109
kelvin-onlabd3b64892015-01-20 13:26:24 -08001110 def onosDie( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001111 """
andrewonlabaedc8332014-12-04 12:43:03 -05001112 Issues the command 'onos-die <node-ip>'
1113 This command calls onos-kill and also stops the node
kelvin8ec71442015-01-15 16:57:00 -08001114 """
andrewonlabaedc8332014-12-04 12:43:03 -05001115 try:
kelvin8ec71442015-01-15 16:57:00 -08001116 self.handle.sendline( "" )
1117 self.handle.expect( "\$" )
Jeremyf0aecdb2016-03-30 13:19:57 -07001118 cmdStr = "onos-die " + str( nodeIp )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001119 self.handle.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -08001120 i = self.handle.expect( [
andrewonlabaedc8332014-12-04 12:43:03 -05001121 "Killing\sONOS",
1122 "ONOS\sprocess\sis\snot\srunning",
Jeremy Songster14c13572016-04-21 17:34:03 -07001123 pexpect.TIMEOUT ], timeout=60 )
andrewonlabaedc8332014-12-04 12:43:03 -05001124 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001125 main.log.info( "ONOS instance " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001126 " was killed and stopped" )
Jon Hall53c5e662016-04-13 16:06:56 -07001127 self.handle.sendline( "" )
1128 self.handle.expect( "\$" )
andrewonlabaedc8332014-12-04 12:43:03 -05001129 return main.TRUE
1130 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001131 main.log.info( "ONOS process was not running" )
Jon Hall53c5e662016-04-13 16:06:56 -07001132 self.handle.sendline( "" )
1133 self.handle.expect( "\$" )
andrewonlabaedc8332014-12-04 12:43:03 -05001134 return main.FALSE
1135 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001136 main.log.error( self.name + ": EOF exception found" )
1137 main.log.error( self.name + ": " + self.handle.before )
andrewonlabaedc8332014-12-04 12:43:03 -05001138 main.cleanup()
1139 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001140 except Exception:
1141 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabaedc8332014-12-04 12:43:03 -05001142 main.cleanup()
1143 main.exit()
1144
kelvin-onlabd3b64892015-01-20 13:26:24 -08001145 def onosKill( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001146 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001147 Calls the command: 'onos-kill [<node-ip>]'
1148 "Remotely, and unceremoniously kills the ONOS instance running on
1149 the specified cell machine" - Tom V
kelvin8ec71442015-01-15 16:57:00 -08001150 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001151 try:
kelvin8ec71442015-01-15 16:57:00 -08001152 self.handle.sendline( "" )
1153 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001154 self.handle.sendline( "onos-kill " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -08001155 i = self.handle.expect( [
andrewonlabe8e56fd2014-10-09 17:12:44 -04001156 "\$",
1157 "No\sroute\sto\shost",
1158 "password:",
Jeremy Songster14c13572016-04-21 17:34:03 -07001159 pexpect.TIMEOUT ], timeout=60 )
kelvin8ec71442015-01-15 16:57:00 -08001160
andrewonlabe8e56fd2014-10-09 17:12:44 -04001161 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001162 main.log.info(
1163 "ONOS instance " + str(
kelvin-onlabd3b64892015-01-20 13:26:24 -08001164 nodeIp ) + " was killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001165 return main.TRUE
1166 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001167 main.log.info( "No route to host" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001168 return main.FALSE
1169 elif i == 2:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001170 main.log.info(
1171 "Passwordless login for host: " +
1172 str( nodeIp ) +
1173 " not configured" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001174 return main.FALSE
1175 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001176 main.log.info( "ONOS instance was not killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001177 return main.FALSE
kelvin8ec71442015-01-15 16:57:00 -08001178
andrewonlabe8e56fd2014-10-09 17:12:44 -04001179 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001180 main.log.error( self.name + ": EOF exception found" )
1181 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001182 main.cleanup()
1183 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001184 except Exception:
1185 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001186 main.cleanup()
1187 main.exit()
1188
kelvin-onlabd3b64892015-01-20 13:26:24 -08001189 def onosRemoveRaftLogs( self ):
kelvin8ec71442015-01-15 16:57:00 -08001190 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001191 Removes Raft / Copy cat files from ONOS to ensure
Jon Hallfcc88622014-11-25 13:09:54 -05001192 a cleaner environment.
1193
andrewonlab19fbdca2014-11-14 12:55:59 -05001194 Description:
Jon Hallfcc88622014-11-25 13:09:54 -05001195 Stops all ONOS defined in the cell,
andrewonlab19fbdca2014-11-14 12:55:59 -05001196 wipes the raft / copycat log files
kelvin8ec71442015-01-15 16:57:00 -08001197 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001198 try:
kelvin8ec71442015-01-15 16:57:00 -08001199 self.handle.sendline( "" )
1200 self.handle.expect( "\$" )
1201 self.handle.sendline( "onos-remove-raft-logs" )
1202 # Sometimes this command hangs
1203 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
1204 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001205 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001206 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
1207 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001208 if i == 1:
1209 return main.FALSE
andrewonlab19fbdca2014-11-14 12:55:59 -05001210 return main.TRUE
andrewonlab19fbdca2014-11-14 12:55:59 -05001211 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001212 main.log.error( self.name + ": EOF exception found" )
1213 main.log.error( self.name + ": " + self.handle.before )
andrewonlab19fbdca2014-11-14 12:55:59 -05001214 main.cleanup()
1215 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001216 except Exception:
1217 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab19fbdca2014-11-14 12:55:59 -05001218 main.cleanup()
1219 main.exit()
Jon Hallfcc88622014-11-25 13:09:54 -05001220
kelvin-onlabd3b64892015-01-20 13:26:24 -08001221 def onosStartNetwork( self, mntopo ):
kelvin8ec71442015-01-15 16:57:00 -08001222 """
1223 Calls the command 'onos-start-network [ <mininet-topo> ]
1224 "remotely starts the specified topology on the cell's
andrewonlab94282092014-10-10 13:00:11 -04001225 mininet machine against all controllers configured in the
kelvin8ec71442015-01-15 16:57:00 -08001226 cell."
andrewonlab94282092014-10-10 13:00:11 -04001227 * Specify mininet topology file name for mntopo
1228 * Topo files should be placed at:
1229 ~/<your-onos-directory>/tools/test/topos
kelvin8ec71442015-01-15 16:57:00 -08001230
andrewonlab94282092014-10-10 13:00:11 -04001231 NOTE: This function will take you to the mininet prompt
kelvin8ec71442015-01-15 16:57:00 -08001232 """
andrewonlab94282092014-10-10 13:00:11 -04001233 try:
1234 if not mntopo:
kelvin8ec71442015-01-15 16:57:00 -08001235 main.log.error( "You must specify a topo file to execute" )
andrewonlab94282092014-10-10 13:00:11 -04001236 return main.FALSE
andrewonlab94282092014-10-10 13:00:11 -04001237
kelvin8ec71442015-01-15 16:57:00 -08001238 mntopo = str( mntopo )
1239 self.handle.sendline( "" )
1240 self.handle.expect( "\$" )
andrewonlab94282092014-10-10 13:00:11 -04001241
kelvin8ec71442015-01-15 16:57:00 -08001242 self.handle.sendline( "onos-start-network " + mntopo )
1243 self.handle.expect( "mininet>" )
1244 main.log.info( "Network started, entered mininet prompt" )
1245
1246 # TODO: Think about whether return is necessary or not
andrewonlab94282092014-10-10 13:00:11 -04001247
1248 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001249 main.log.error( self.name + ": EOF exception found" )
1250 main.log.error( self.name + ": " + self.handle.before )
andrewonlab94282092014-10-10 13:00:11 -04001251 main.cleanup()
1252 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001253 except Exception:
1254 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab94282092014-10-10 13:00:11 -04001255 main.cleanup()
1256 main.exit()
1257
Jeremy Songster14c13572016-04-21 17:34:03 -07001258 def isup( self, node="", timeout=240 ):
kelvin8ec71442015-01-15 16:57:00 -08001259 """
1260 Run's onos-wait-for-start which only returns once ONOS is at run
Cameron Franke9c94fb02015-01-21 10:20:20 -08001261 level 100(ready for use)
andrewonlab8d0d7d72014-10-09 16:33:15 -04001262
Jon Hall7993bfc2014-10-09 16:30:14 -04001263 Returns: main.TRUE if ONOS is running and main.FALSE on timeout
kelvin8ec71442015-01-15 16:57:00 -08001264 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001265 try:
Jon Hall3b489db2015-10-05 14:38:37 -07001266 self.handle.sendline( "onos-wait-for-start " + node )
1267 self.handle.expect( "onos-wait-for-start" )
kelvin8ec71442015-01-15 16:57:00 -08001268 # NOTE: this timeout is arbitrary"
Cameron Franke9c94fb02015-01-21 10:20:20 -08001269 i = self.handle.expect(["\$", pexpect.TIMEOUT], timeout)
Jon Hall7993bfc2014-10-09 16:30:14 -04001270 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001271 main.log.info( self.name + ": " + node + " is up" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001272 return main.TRUE
1273 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001274 # NOTE: since this function won't return until ONOS is ready,
Jon Hall7993bfc2014-10-09 16:30:14 -04001275 # we will kill it on timeout
kelvin8ec71442015-01-15 16:57:00 -08001276 main.log.error( "ONOS has not started yet" )
1277 self.handle.send( "\x03" ) # Control-C
1278 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001279 return main.FALSE
1280 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001281 main.log.error( self.name + ": EOF exception found" )
1282 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -04001283 main.cleanup()
1284 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001285 except Exception:
1286 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001287 main.cleanup()
1288 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001289
kelvin-onlabd3b64892015-01-20 13:26:24 -08001290 def pushTestIntentsShell(
1291 self,
1292 dpidSrc,
1293 dpidDst,
1294 numIntents,
1295 dirFile,
1296 onosIp,
1297 numMult="",
1298 appId="",
1299 report=True,
1300 options="" ):
kelvin8ec71442015-01-15 16:57:00 -08001301 """
andrewonlabb66dfa12014-12-02 15:51:10 -05001302 Description:
kelvin8ec71442015-01-15 16:57:00 -08001303 Use the linux prompt to push test intents to
andrewonlabb66dfa12014-12-02 15:51:10 -05001304 better parallelize the results than the CLI
1305 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001306 * dpidSrc: specify source dpid
1307 * dpidDst: specify destination dpid
1308 * numIntents: specify number of intents to push
1309 * dirFile: specify directory and file name to save
andrewonlabb66dfa12014-12-02 15:51:10 -05001310 results
kelvin-onlabd3b64892015-01-20 13:26:24 -08001311 * onosIp: specify the IP of ONOS to install on
kelvin8ec71442015-01-15 16:57:00 -08001312 NOTE:
andrewonlabb66dfa12014-12-02 15:51:10 -05001313 You must invoke this command at linux shell prompt
kelvin8ec71442015-01-15 16:57:00 -08001314 """
1315 try:
1316 # Create the string to sendline
andrewonlabaedc8332014-12-04 12:43:03 -05001317 if options:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001318 baseCmd = "onos " + str( onosIp ) + " push-test-intents " +\
kelvin8ec71442015-01-15 16:57:00 -08001319 options + " "
andrewonlabaedc8332014-12-04 12:43:03 -05001320 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001321 baseCmd = "onos " + str( onosIp ) + " push-test-intents "
kelvin8ec71442015-01-15 16:57:00 -08001322
kelvin-onlabd3b64892015-01-20 13:26:24 -08001323 addDpid = baseCmd + str( dpidSrc ) + " " + str( dpidDst )
1324 if not numMult:
1325 addIntents = addDpid + " " + str( numIntents )
1326 elif numMult:
1327 addIntents = addDpid + " " + str( numIntents ) + " " +\
1328 str( numMult )
1329 if appId:
1330 addApp = addIntents + " " + str( appId )
andrewonlabb66dfa12014-12-02 15:51:10 -05001331 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001332 addApp = addIntents
andrewonlabb66dfa12014-12-02 15:51:10 -05001333
andrewonlabaedc8332014-12-04 12:43:03 -05001334 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001335 sendCmd = addApp + " > " + str( dirFile ) + " &"
andrewonlabaedc8332014-12-04 12:43:03 -05001336 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001337 sendCmd = addApp + " &"
1338 main.log.info( "Send cmd: " + sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001339
kelvin-onlabd3b64892015-01-20 13:26:24 -08001340 self.handle.sendline( sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001341
1342 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001343 main.log.error( self.name + ": EOF exception found" )
1344 main.log.error( self.name + ": " + self.handle.before )
andrewonlabb66dfa12014-12-02 15:51:10 -05001345 main.cleanup()
1346 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001347 except Exception:
1348 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabb66dfa12014-12-02 15:51:10 -05001349 main.cleanup()
kelvin8ec71442015-01-15 16:57:00 -08001350 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001351
kelvin-onlabd3b64892015-01-20 13:26:24 -08001352 def tsharkPcap( self, interface, dirFile ):
kelvin8ec71442015-01-15 16:57:00 -08001353 """
andrewonlab970399c2014-11-07 13:09:32 -05001354 Capture all packet activity and store in specified
1355 directory/file
1356
1357 Required:
1358 * interface: interface to capture
1359 * dir: directory/filename to store pcap
kelvin8ec71442015-01-15 16:57:00 -08001360 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001361 try:
1362 self.handle.sendline( "" )
1363 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001364
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001365 self.handle.sendline( "tshark -i " + str( interface ) + " -t e -w " + str( dirFile ) + " &" )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001366 self.handle.sendline( "\n" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001367 self.handle.expect( "Capturing on" )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001368 self.handle.sendline( "\n" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001369 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001370
Jon Hallfebb1c72015-03-05 13:30:09 -08001371 main.log.info( "Tshark started capturing files on " +
1372 str( interface ) + " and saving to directory: " +
1373 str( dirFile ) )
1374 except pexpect.EOF:
1375 main.log.error( self.name + ": EOF exception found" )
1376 main.log.error( self.name + ": " + self.handle.before )
1377 main.cleanup()
1378 main.exit()
1379 except Exception:
1380 main.log.exception( self.name + ": Uncaught exception!" )
1381 main.cleanup()
1382 main.exit()
Shreya Shaha73aaad2014-10-27 18:03:09 -04001383
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001384 def onosTopoCfg( self, onosIp, jsonFile ):
kelvin8ec71442015-01-15 16:57:00 -08001385 """
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001386 Description:
1387 Execute onos-topo-cfg command
1388 Required:
1389 onosIp - IP of the onos node you want to send the json to
1390 jsonFile - File path of the json file
1391 Return:
1392 Returns main.TRUE if the command is successfull; Returns
1393 main.FALSE if there was an error
kelvin8ec71442015-01-15 16:57:00 -08001394 """
shahshreyae6c7cf42014-11-26 16:39:01 -08001395 try:
kelvin8ec71442015-01-15 16:57:00 -08001396 self.handle.sendline( "" )
1397 self.handle.expect( "\$" )
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001398 cmd = "onos-topo-cfg "
1399 self.handle.sendline( cmd + str( onosIp ) + " " + jsonFile )
1400 handle = self.handle.before
1401 print handle
1402 if "Error" in handle:
1403 main.log.error( self.name + ": " + self.handle.before )
1404 return main.FALSE
1405 else:
1406 self.handle.expect( "\$" )
1407 return main.TRUE
1408
Jon Hallfebb1c72015-03-05 13:30:09 -08001409 except pexpect.EOF:
1410 main.log.error( self.name + ": EOF exception found" )
1411 main.log.error( self.name + ": " + self.handle.before )
1412 main.cleanup()
1413 main.exit()
1414 except Exception:
1415 main.log.exception( self.name + ": Uncaught exception!" )
1416 main.cleanup()
1417 main.exit()
kelvin8ec71442015-01-15 16:57:00 -08001418
jenkins1e99e7b2015-04-02 18:15:39 -07001419 def tsharkGrep( self, grep, directory, interface='eth0', grepOptions='' ):
kelvin8ec71442015-01-15 16:57:00 -08001420 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001421 Required:
kelvin8ec71442015-01-15 16:57:00 -08001422 * grep string
andrewonlabba44bcf2014-10-16 16:54:41 -04001423 * directory to store results
1424 Optional:
1425 * interface - default: eth0
Jon Hall4ba53f02015-07-29 13:07:41 -07001426 * grepOptions - options for grep
andrewonlabba44bcf2014-10-16 16:54:41 -04001427 Description:
1428 Uses tshark command to grep specific group of packets
1429 and stores the results to specified directory.
kelvin8ec71442015-01-15 16:57:00 -08001430 The timestamp is hardcoded to be in epoch
1431 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001432 try:
1433 self.handle.sendline( "" )
1434 self.handle.expect( "\$" )
1435 self.handle.sendline( "" )
jenkins1e99e7b2015-04-02 18:15:39 -07001436 if grepOptions:
1437 grepStr = "grep "+str(grepOptions)
1438 else:
1439 grepStr = "grep"
Jon Hall4ba53f02015-07-29 13:07:41 -07001440
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001441 cmd = (
1442 "sudo tshark -i " +
Jon Hallfebb1c72015-03-05 13:30:09 -08001443 str( interface ) +
jenkins1e99e7b2015-04-02 18:15:39 -07001444 " -t e | " +
1445 grepStr + " --line-buffered \"" +
Jon Hallfebb1c72015-03-05 13:30:09 -08001446 str(grep) +
1447 "\" >" +
1448 directory +
1449 " &" )
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001450 self.handle.sendline(cmd)
1451 main.log.info(cmd)
Jon Hallfebb1c72015-03-05 13:30:09 -08001452 self.handle.expect( "Capturing on" )
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001453 self.handle.sendline( "\n" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001454 self.handle.expect( "\$" )
1455 except pexpect.EOF:
1456 main.log.error( self.name + ": EOF exception found" )
1457 main.log.error( self.name + ": " + self.handle.before )
1458 main.cleanup()
1459 main.exit()
1460 except Exception:
1461 main.log.exception( self.name + ": Uncaught exception!" )
1462 main.cleanup()
1463 main.exit()
1464
kelvin-onlabd3b64892015-01-20 13:26:24 -08001465 def tsharkStop( self ):
kelvin8ec71442015-01-15 16:57:00 -08001466 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001467 Removes wireshark files from /tmp and kills all tshark processes
kelvin8ec71442015-01-15 16:57:00 -08001468 """
1469 # Remove all pcap from previous captures
Jon Hallfebb1c72015-03-05 13:30:09 -08001470 try:
1471 self.execute( cmd="sudo rm /tmp/wireshark*" )
1472 self.handle.sendline( "" )
Jon Hallefbd9792015-03-05 16:11:36 -08001473 self.handle.sendline( "sudo kill -9 `ps -ef | grep \"tshark -i\"" +
1474 " | grep -v grep | awk '{print $2}'`" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001475 self.handle.sendline( "" )
1476 main.log.info( "Tshark stopped" )
1477 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()
1486
kelvin8ec71442015-01-15 16:57:00 -08001487 def ptpd( self, args ):
1488 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001489 Initiate ptp with user-specified args.
1490 Required:
1491 * args: specify string of args after command
1492 'sudo ptpd'
kelvin8ec71442015-01-15 16:57:00 -08001493 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001494 try:
kelvin8ec71442015-01-15 16:57:00 -08001495 self.handle.sendline( "sudo ptpd " + str( args ) )
1496 i = self.handle.expect( [
andrewonlab0c38a4a2014-10-28 18:35:35 -04001497 "Multiple",
1498 "Error",
kelvin8ec71442015-01-15 16:57:00 -08001499 "\$" ] )
1500 self.handle.expect( "\$" )
andrewonlabba44bcf2014-10-16 16:54:41 -04001501
andrewonlab0c38a4a2014-10-28 18:35:35 -04001502 if i == 0:
1503 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001504 main.log.info( "ptpd returned an error: " +
1505 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001506 return handle
1507 elif i == 1:
1508 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001509 main.log.error( "ptpd returned an error: " +
1510 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001511 return handle
1512 else:
1513 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -08001514
andrewonlab0c38a4a2014-10-28 18:35:35 -04001515 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001516 main.log.error( self.name + ": EOF exception found" )
1517 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001518 main.cleanup()
1519 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001520 except Exception:
1521 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001522 main.cleanup()
1523 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001524
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001525 def dumpFlows(self,ONOSIp, destDir, filename="flows" ):
1526 """
1527 Dump Flow Tables to a desired directory.
1528 For debugging purposes, you may want to use
1529 this function to capture flows at a given point in time.
1530 Localtime will be attached to the filename
1531
1532 Required:
1533 * ONOSIp: the IP of the target ONOS instance
1534 * destDir: specify directory to copy to.
1535 ex ) /tmp/
1536 Optional:
1537 * fileName: Name of the file
1538 """
1539
1540 localtime = time.strftime( '%x %X' )
1541 localtime = localtime.replace( "/", "" )
1542 localtime = localtime.replace( " ", "_" )
1543 localtime = localtime.replace( ":", "" )
1544 if destDir[ -1: ] != "/":
1545 destDir += "/"
1546 cmd="flows > "+ str( destDir ) + str( filename ) + localtime
1547 return self.onosCli(ONOSIp,cmd)
1548
Flavio Castrob7718952016-05-18 08:53:41 -07001549 def dumpGroups(self,ONOSIp, destDir, filename="groups" ):
1550 """
1551 Dump Group Tables to a desired directory.
1552 For debugging purposes, you may want to use
1553 this function to capture groups at a given point in time.
1554 Localtime will be attached to the filename
1555
1556 Required:
1557 * ONOSIp: the IP of the target ONOS instance
1558 * destDir: specify directory to copy to.
1559 ex ) /tmp/
1560 Optional:
1561 * fileName: Name of the file
1562 """
1563
Flavio Castro09ab59d2016-05-25 17:01:35 -07001564 localtime = time.strftime( '%H %M' )
Flavio Castrob7718952016-05-18 08:53:41 -07001565 localtime = localtime.replace( "/", "" )
1566 localtime = localtime.replace( " ", "_" )
1567 localtime = localtime.replace( ":", "" )
1568 if destDir[ -1: ] != "/":
1569 destDir += "/"
1570 cmd="groups > "+ str( destDir ) + str( filename ) + localtime
1571 return self.onosCli(ONOSIp,cmd)
1572
kelvin-onlabd3b64892015-01-20 13:26:24 -08001573 def cpLogsToDir( self, logToCopy,
Jon Hallefbd9792015-03-05 16:11:36 -08001574 destDir, copyFileName="" ):
kelvin8ec71442015-01-15 16:57:00 -08001575 """
1576 Copies logs to a desired directory.
andrewonlab5d7a8f32014-11-10 13:07:56 -05001577 Current implementation of ONOS deletes its karaf
1578 logs on every iteration. For debugging purposes,
kelvin8ec71442015-01-15 16:57:00 -08001579 you may want to use this function to capture
1580 certain karaf logs. ( or any other logs if needed )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001581 Localtime will be attached to the filename
1582
1583 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001584 * logToCopy: specify directory and log name to
andrewonlab5d7a8f32014-11-10 13:07:56 -05001585 copy.
kelvin8ec71442015-01-15 16:57:00 -08001586 ex ) /opt/onos/log/karaf.log.1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001587 For copying multiple files, leave copyFileName
1588 empty and only specify destDir -
kelvin8ec71442015-01-15 16:57:00 -08001589 ex ) /opt/onos/log/karaf*
kelvin-onlabd3b64892015-01-20 13:26:24 -08001590 * destDir: specify directory to copy to.
kelvin8ec71442015-01-15 16:57:00 -08001591 ex ) /tmp/
1592 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001593 * copyFileName: If you want to rename the log
1594 file, specify copyFileName. This will not work
andrewonlab5d7a8f32014-11-10 13:07:56 -05001595 with multiple file copying
kelvin8ec71442015-01-15 16:57:00 -08001596 """
andrewonlab5d7a8f32014-11-10 13:07:56 -05001597 try:
Flavio Castro09ab59d2016-05-25 17:01:35 -07001598 localtime = time.strftime( '%H %M' )
kelvin8ec71442015-01-15 16:57:00 -08001599 localtime = localtime.replace( "/", "" )
1600 localtime = localtime.replace( " ", "_" )
1601 localtime = localtime.replace( ":", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001602 if destDir[ -1: ] != "/":
1603 destDir += "/"
andrewonlab5d7a8f32014-11-10 13:07:56 -05001604
kelvin-onlabd3b64892015-01-20 13:26:24 -08001605 if copyFileName:
Jon Hallfebb1c72015-03-05 13:30:09 -08001606 self.handle.sendline( "cp " + str( logToCopy ) + " " +
1607 str( destDir ) + str( copyFileName ) +
1608 localtime )
kelvin8ec71442015-01-15 16:57:00 -08001609 self.handle.expect( "cp" )
1610 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001611 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001612 self.handle.sendline( "cp " + str( logToCopy ) +
1613 " " + str( destDir ) )
kelvin8ec71442015-01-15 16:57:00 -08001614 self.handle.expect( "cp" )
1615 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001616
kelvin8ec71442015-01-15 16:57:00 -08001617 return self.handle.before
1618
1619 except pexpect.EOF:
1620 main.log.error( "Copying files failed" )
1621 main.log.error( self.name + ": EOF exception found" )
1622 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001623 except Exception:
1624 main.log.exception( "Copying files failed" )
1625
Jon Hall16b72c42015-05-20 10:23:36 -07001626 def checkLogs( self, onosIp, restart=False):
kelvin8ec71442015-01-15 16:57:00 -08001627 """
Jon Hall94fd0472014-12-08 11:52:42 -08001628 runs onos-check-logs on the given onos node
Jon Hall80daded2015-05-27 16:07:00 -07001629 If restart is True, use the old version of onos-check-logs which
1630 does not print the full stacktrace, but shows the entire log file,
1631 including across restarts
Jon Hall94fd0472014-12-08 11:52:42 -08001632 returns the response
kelvin8ec71442015-01-15 16:57:00 -08001633 """
Jon Hall94fd0472014-12-08 11:52:42 -08001634 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001635 cmd = "onos-check-logs " + str( onosIp )
Jon Hall16b72c42015-05-20 10:23:36 -07001636 if restart:
1637 cmd += " old"
kelvin8ec71442015-01-15 16:57:00 -08001638 self.handle.sendline( cmd )
1639 self.handle.expect( cmd )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001640 self.handle.expect( "\$ " )
Jon Hall94fd0472014-12-08 11:52:42 -08001641 response = self.handle.before
1642 return response
1643 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001644 main.log.error( "Lost ssh connection" )
1645 main.log.error( self.name + ": EOF exception found" )
1646 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001647 except Exception:
1648 main.log.exception( self.name + ": Uncaught exception!" )
1649 main.cleanup()
1650 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -08001651
kelvin-onlabd3b64892015-01-20 13:26:24 -08001652 def onosStatus( self, node="" ):
kelvin8ec71442015-01-15 16:57:00 -08001653 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001654 Calls onos command: 'onos-service [<node-ip>] status'
kelvin8ec71442015-01-15 16:57:00 -08001655 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001656 try:
kelvin8ec71442015-01-15 16:57:00 -08001657 self.handle.sendline( "" )
1658 self.handle.expect( "\$" )
1659 self.handle.sendline( "onos-service " + str( node ) +
1660 " status" )
1661 i = self.handle.expect( [
You Wangef1e6572016-03-08 12:53:18 -08001662 "start/running",
You Wang7bd83062016-03-01 11:50:00 -08001663 "Running ...",
You Wangef1e6572016-03-08 12:53:18 -08001664 "stop/waiting",
You Wang7bd83062016-03-01 11:50:00 -08001665 "Not Running ...",
kelvin8ec71442015-01-15 16:57:00 -08001666 pexpect.TIMEOUT ], timeout=120 )
YPZhangfebf7302016-05-24 16:45:56 -07001667 self.handle.sendline( "" )
1668 self.handle.expect( "\$" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001669
You Wangef1e6572016-03-08 12:53:18 -08001670 if i == 0 or i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001671 main.log.info( "ONOS is running" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001672 return main.TRUE
You Wangef1e6572016-03-08 12:53:18 -08001673 elif i == 2 or i == 3:
kelvin8ec71442015-01-15 16:57:00 -08001674 main.log.info( "ONOS is stopped" )
kelvin8ec71442015-01-15 16:57:00 -08001675 main.log.error( "ONOS service failed to check the status" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001676 main.cleanup()
1677 main.exit()
1678 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001679 main.log.error( self.name + ": EOF exception found" )
1680 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001681 main.cleanup()
1682 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001683 except Exception:
1684 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001685 main.cleanup()
1686 main.exit()
Jon Hall21270ac2015-02-16 17:59:55 -08001687
Jon Hall63604932015-02-26 17:09:50 -08001688 def setIpTables( self, ip, port='', action='add', packet_type='',
1689 direction='INPUT', rule='DROP', states=True ):
Jon Hallefbd9792015-03-05 16:11:36 -08001690 """
Jon Hall21270ac2015-02-16 17:59:55 -08001691 Description:
1692 add or remove iptables rule to DROP (default) packets from
1693 specific IP and PORT
1694 Usage:
1695 * specify action ('add' or 'remove')
1696 when removing, pass in the same argument as you would add. It will
1697 delete that specific rule.
1698 * specify the ip to block
1699 * specify the destination port to block (defaults to all ports)
1700 * optional packet type to block (default tcp)
1701 * optional iptables rule (default DROP)
1702 * optional direction to block (default 'INPUT')
Jon Hall63604932015-02-26 17:09:50 -08001703 * States boolean toggles adding all supported tcp states to the
1704 firewall rule
Jon Hall21270ac2015-02-16 17:59:55 -08001705 Returns:
1706 main.TRUE on success or
1707 main.FALSE if given invalid input or
1708 main.ERROR if there is an error in response from iptables
1709 WARNING:
1710 * This function uses root privilege iptables command which may result
1711 in unwanted network errors. USE WITH CAUTION
Jon Hallefbd9792015-03-05 16:11:36 -08001712 """
Jon Hall21270ac2015-02-16 17:59:55 -08001713
1714 # NOTE*********
1715 # The strict checking methods of this driver function is intentional
1716 # to discourage any misuse or error of iptables, which can cause
1717 # severe network errors
1718 # *************
1719
1720 # NOTE: Sleep needed to give some time for rule to be added and
1721 # registered to the instance. If you are calling this function
1722 # multiple times this sleep will prevent any errors.
1723 # DO NOT REMOVE
Jon Hall63604932015-02-26 17:09:50 -08001724 # time.sleep( 5 )
Jon Hall21270ac2015-02-16 17:59:55 -08001725 try:
1726 # input validation
1727 action_type = action.lower()
1728 rule = rule.upper()
1729 direction = direction.upper()
1730 if action_type != 'add' and action_type != 'remove':
1731 main.log.error( "Invalid action type. Use 'add' or "
1732 "'remove' table rule" )
1733 if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
1734 # NOTE Currently only supports rules DROP, ACCEPT, and LOG
1735 main.log.error( "Invalid rule. Valid rules are 'DROP' or "
1736 "'ACCEPT' or 'LOG' only." )
1737 if direction != 'INPUT' and direction != 'OUTPUT':
1738 # NOTE currently only supports rules INPUT and OUPTUT
1739 main.log.error( "Invalid rule. Valid directions are"
1740 " 'OUTPUT' or 'INPUT'" )
1741 return main.FALSE
1742 return main.FALSE
1743 return main.FALSE
1744 if action_type == 'add':
1745 # -A is the 'append' action of iptables
1746 actionFlag = '-A'
1747 elif action_type == 'remove':
1748 # -D is the 'delete' rule of iptables
1749 actionFlag = '-D'
1750 self.handle.sendline( "" )
1751 self.handle.expect( "\$" )
1752 cmd = "sudo iptables " + actionFlag + " " +\
1753 direction +\
Jon Hall21270ac2015-02-16 17:59:55 -08001754 " -s " + str( ip )
Jon Hall63604932015-02-26 17:09:50 -08001755 # " -p " + str( packet_type ) +\
1756 if packet_type:
1757 cmd += " -p " + str( packet_type )
Jon Hall21270ac2015-02-16 17:59:55 -08001758 if port:
1759 cmd += " --dport " + str( port )
Jon Hall63604932015-02-26 17:09:50 -08001760 if states:
1761 cmd += " -m state --state="
1762 #FIXME- Allow user to configure which states to block
1763 cmd += "INVALID,ESTABLISHED,NEW,RELATED,UNTRACKED"
Jon Hall21270ac2015-02-16 17:59:55 -08001764 cmd += " -j " + str( rule )
1765
1766 self.handle.sendline( cmd )
1767 self.handle.expect( "\$" )
1768 main.log.warn( self.handle.before )
1769
1770 info_string = "On " + str( self.name )
1771 info_string += " " + str( action_type )
1772 info_string += " iptable rule [ "
1773 info_string += " IP: " + str( ip )
1774 info_string += " Port: " + str( port )
1775 info_string += " Rule: " + str( rule )
1776 info_string += " Direction: " + str( direction ) + " ]"
1777 main.log.info( info_string )
1778 return main.TRUE
1779 except pexpect.TIMEOUT:
1780 main.log.exception( self.name + ": Timeout exception in "
1781 "setIpTables function" )
1782 return main.ERROR
1783 except pexpect.EOF:
1784 main.log.error( self.name + ": EOF exception found" )
1785 main.log.error( self.name + ": " + self.handle.before )
1786 main.cleanup()
1787 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001788 except Exception:
1789 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall21270ac2015-02-16 17:59:55 -08001790 main.cleanup()
1791 main.exit()
1792
Jon Hall0468b042015-02-19 19:08:21 -08001793 def detailed_status(self, log_filename):
Jon Hallefbd9792015-03-05 16:11:36 -08001794 """
Jon Hall0468b042015-02-19 19:08:21 -08001795 This method is used by STS to check the status of the controller
1796 Reports RUNNING, STARTING, STOPPED, FROZEN, ERROR (and reason)
Jon Hallefbd9792015-03-05 16:11:36 -08001797 """
Jon Hall0468b042015-02-19 19:08:21 -08001798 import re
1799 try:
1800 self.handle.sendline( "" )
1801 self.handle.expect( "\$" )
1802 self.handle.sendline( "cd " + self.home )
1803 self.handle.expect( "\$" )
1804 self.handle.sendline( "service onos status" )
1805 self.handle.expect( "\$" )
1806 response = self.handle.before
1807 if re.search( "onos start/running", response ):
1808 # onos start/running, process 10457
1809 return 'RUNNING'
1810 # FIXME: Implement this case
1811 # elif re.search( pattern, response ):
1812 # return 'STARTING'
1813 elif re.search( "onos stop/", response ):
1814 # onos stop/waiting
1815 # FIXME handle this differently?: onos stop/pre-stop
1816 return 'STOPPED'
1817 # FIXME: Implement this case
1818 # elif re.search( pattern, response ):
1819 # return 'FROZEN'
1820 else:
1821 main.log.warn( self.name +
Jon Hallefbd9792015-03-05 16:11:36 -08001822 " WARNING: status received unknown response" )
Jon Hall0468b042015-02-19 19:08:21 -08001823 main.log.warn( response )
1824 return 'ERROR', "Unknown response: %s" % response
1825 except pexpect.TIMEOUT:
1826 main.log.exception( self.name + ": Timeout exception in "
1827 "setIpTables function" )
1828 return 'ERROR', "Pexpect Timeout"
1829 except pexpect.EOF:
1830 main.log.error( self.name + ": EOF exception found" )
1831 main.log.error( self.name + ": " + self.handle.before )
1832 main.cleanup()
1833 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001834 except Exception:
1835 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall0468b042015-02-19 19:08:21 -08001836 main.cleanup()
1837 main.exit()
1838
andrew@onlab.us3b087132015-03-11 15:00:08 -07001839 def createLinkGraphFile( self, benchIp, ONOSIpList, deviceCount):
1840 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07001841 Create/formats the LinkGraph.cfg file based on arguments
1842 -only creates a linear topology and connects islands
1843 -evenly distributes devices
andrew@onlab.us3b087132015-03-11 15:00:08 -07001844 -must be called by ONOSbench
1845
Jon Hall4ba53f02015-07-29 13:07:41 -07001846 ONOSIpList - list of all of the node IPs to be used
1847
1848 deviceCount - number of switches to be assigned
andrew@onlab.us3b087132015-03-11 15:00:08 -07001849 '''
Jon Hall6509dbf2016-06-21 17:01:17 -07001850 main.log.info("Creating link graph configuration file." )
andrew@onlab.us3b087132015-03-11 15:00:08 -07001851 linkGraphPath = self.home + "/tools/package/etc/linkGraph.cfg"
Jon Hall4ba53f02015-07-29 13:07:41 -07001852 tempFile = "/tmp/linkGraph.cfg"
andrew@onlab.us3b087132015-03-11 15:00:08 -07001853
1854 linkGraph = open(tempFile, 'w+')
1855 linkGraph.write("# NullLinkProvider topology description (config file).\n")
1856 linkGraph.write("# The NodeId is only added if the destination is another node's device.\n")
1857 linkGraph.write("# Bugs: Comments cannot be appended to a line to be read.\n")
Jon Hall4ba53f02015-07-29 13:07:41 -07001858
andrew@onlab.us3b087132015-03-11 15:00:08 -07001859 clusterCount = len(ONOSIpList)
Jon Hall4ba53f02015-07-29 13:07:41 -07001860
1861 if type(deviceCount) is int or type(deviceCount) is str:
andrew@onlab.us3b087132015-03-11 15:00:08 -07001862 deviceCount = int(deviceCount)
1863 switchList = [0]*(clusterCount+1)
1864 baselineSwitchCount = deviceCount/clusterCount
Jon Hall4ba53f02015-07-29 13:07:41 -07001865
andrew@onlab.us3b087132015-03-11 15:00:08 -07001866 for node in range(1, clusterCount + 1):
1867 switchList[node] = baselineSwitchCount
1868
1869 for node in range(1, (deviceCount%clusterCount)+1):
1870 switchList[node] += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07001871
andrew@onlab.us3b087132015-03-11 15:00:08 -07001872 if type(deviceCount) is list:
1873 main.log.info("Using provided device distribution")
1874 switchList = [0]
1875 for i in deviceCount:
1876 switchList.append(int(i))
1877
1878 tempList = ['0']
1879 tempList.extend(ONOSIpList)
1880 ONOSIpList = tempList
1881
1882 myPort = 6
1883 lastSwitch = 0
1884 for node in range(1, clusterCount+1):
1885 if switchList[node] == 0:
1886 continue
1887
1888 linkGraph.write("graph " + ONOSIpList[node] + " {\n")
Jon Hall4ba53f02015-07-29 13:07:41 -07001889
andrew@onlab.us3b087132015-03-11 15:00:08 -07001890 if node > 1:
1891 #connect to last device on previous node
Jon Hall4ba53f02015-07-29 13:07:41 -07001892 line = ("\t0:5 -> " + str(lastSwitch) + ":6:" + lastIp + "\n") #ONOSIpList[node-1]
1893 linkGraph.write(line)
1894
1895 lastSwitch = 0
1896 for switch in range (0, switchList[node]-1):
andrew@onlab.us3b087132015-03-11 15:00:08 -07001897 line = ""
1898 line = ("\t" + str(switch) + ":" + str(myPort))
1899 line += " -- "
1900 line += (str(switch+1) + ":" + str(myPort-1) + "\n")
1901 linkGraph.write(line)
Jon Hall4ba53f02015-07-29 13:07:41 -07001902 lastSwitch = switch+1
andrew@onlab.us3b087132015-03-11 15:00:08 -07001903 lastIp = ONOSIpList[node]
Jon Hall4ba53f02015-07-29 13:07:41 -07001904
andrew@onlab.us3b087132015-03-11 15:00:08 -07001905 #lastSwitch += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07001906 if node < (clusterCount):
andrew@onlab.us3b087132015-03-11 15:00:08 -07001907 #connect to first device on the next node
Jon Hall4ba53f02015-07-29 13:07:41 -07001908 line = ("\t" + str(lastSwitch) + ":6 -> 0:5:" + ONOSIpList[node+1] + "\n")
andrew@onlab.us3b087132015-03-11 15:00:08 -07001909 linkGraph.write(line)
Jon Hall4ba53f02015-07-29 13:07:41 -07001910
andrew@onlab.us3b087132015-03-11 15:00:08 -07001911 linkGraph.write("}\n")
1912 linkGraph.close()
1913
1914 #SCP
Jon Hall4ba53f02015-07-29 13:07:41 -07001915 os.system( "scp " + tempFile + " " + self.user_name + "@" + benchIp + ":" + linkGraphPath)
andrew@onlab.us3b087132015-03-11 15:00:08 -07001916 main.log.info("linkGraph.cfg creation complete")
1917
cameron@onlab.us75900962015-03-30 13:22:49 -07001918 def configNullDev( self, ONOSIpList, deviceCount, numPorts=10):
Jon Hall4ba53f02015-07-29 13:07:41 -07001919
andrew@onlab.us3b087132015-03-11 15:00:08 -07001920 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07001921 ONOSIpList = list of Ip addresses of nodes switches will be devided amongst
1922 deviceCount = number of switches to distribute, or list of values to use as custom distribution
cameron@onlab.us75900962015-03-30 13:22:49 -07001923 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 -07001924 '''
1925
Jon Hall6509dbf2016-06-21 17:01:17 -07001926 main.log.info("Configuring Null Device Provider" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07001927 clusterCount = len(ONOSIpList)
1928
Jon Hall4ba53f02015-07-29 13:07:41 -07001929 try:
1930
cameron@onlab.us75900962015-03-30 13:22:49 -07001931 if type(deviceCount) is int or type(deviceCount) is str:
Jon Hall6509dbf2016-06-21 17:01:17 -07001932 main.log.info("Creating device distribution")
cameron@onlab.us75900962015-03-30 13:22:49 -07001933 deviceCount = int(deviceCount)
1934 switchList = [0]*(clusterCount+1)
1935 baselineSwitchCount = deviceCount/clusterCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001936
cameron@onlab.us75900962015-03-30 13:22:49 -07001937 for node in range(1, clusterCount + 1):
1938 switchList[node] = baselineSwitchCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001939
cameron@onlab.us75900962015-03-30 13:22:49 -07001940 for node in range(1, (deviceCount%clusterCount)+1):
1941 switchList[node] += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07001942
1943 if type(deviceCount) is list:
1944 main.log.info("Using provided device distribution")
1945
1946 if len(deviceCount) == clusterCount:
cameron@onlab.us75900962015-03-30 13:22:49 -07001947 switchList = ['0']
1948 switchList.extend(deviceCount)
Jon Hall4ba53f02015-07-29 13:07:41 -07001949
1950 if len(deviceCount) == (clusterCount + 1):
1951 if deviceCount[0] == '0' or deviceCount[0] == 0:
cameron@onlab.us75900962015-03-30 13:22:49 -07001952 switchList = deviceCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001953
cameron@onlab.us75900962015-03-30 13:22:49 -07001954 assert len(switchList) == (clusterCount + 1)
Jon Hall4ba53f02015-07-29 13:07:41 -07001955
cameron@onlab.us75900962015-03-30 13:22:49 -07001956 except AssertionError:
Jon Hall4ba53f02015-07-29 13:07:41 -07001957 main.log.error( "Bad device/Ip list match")
cameron@onlab.us75900962015-03-30 13:22:49 -07001958 except TypeError:
1959 main.log.exception( self.name + ": Object not as expected" )
1960 return None
Jon Hall77ba41c2015-04-06 10:25:40 -07001961 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07001962 main.log.exception( self.name + ": Uncaught exception!" )
1963 main.cleanup()
1964 main.exit()
1965
andrew@onlab.us3b087132015-03-11 15:00:08 -07001966
1967 ONOSIp = [0]
1968 ONOSIp.extend(ONOSIpList)
Jon Hall4ba53f02015-07-29 13:07:41 -07001969
andrew@onlab.us3b087132015-03-11 15:00:08 -07001970 devicesString = "devConfigs = "
1971 for node in range(1, len(ONOSIp)):
1972 devicesString += (ONOSIp[node] + ":" + str(switchList[node] ))
1973 if node < clusterCount:
1974 devicesString += (",")
Jon Hall4ba53f02015-07-29 13:07:41 -07001975
1976 try:
cameron@onlab.us75900962015-03-30 13:22:49 -07001977 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider devConfigs " + devicesString )
1978 self.handle.expect(":~")
1979 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider numPorts " + str(numPorts) )
1980 self.handle.expect(":~")
andrew@onlab.us3b087132015-03-11 15:00:08 -07001981
cameron@onlab.us75900962015-03-30 13:22:49 -07001982 for i in range(10):
1983 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.device.impl.NullDeviceProvider")
1984 self.handle.expect(":~")
1985 verification = self.handle.before
1986 if (" value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification:
1987 break
1988 else:
1989 time.sleep(1)
andrew@onlab.us3b087132015-03-11 15:00:08 -07001990
cameron@onlab.us2cc8bf12015-04-02 14:12:30 -07001991 assert ("value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification
Jon Hall4ba53f02015-07-29 13:07:41 -07001992
cameron@onlab.us75900962015-03-30 13:22:49 -07001993 except AssertionError:
1994 main.log.error("Incorrect Config settings: " + verification)
Jon Hall77ba41c2015-04-06 10:25:40 -07001995 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07001996 main.log.exception( self.name + ": Uncaught exception!" )
1997 main.cleanup()
1998 main.exit()
1999
Jon Hall4ba53f02015-07-29 13:07:41 -07002000 def configNullLink( self,fileName="/opt/onos/apache-karaf-3.0.3/etc/linkGraph.cfg", eventRate=0):
andrew@onlab.us3b087132015-03-11 15:00:08 -07002001 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07002002 fileName default is currently the same as the default on ONOS, specify alternate file if
cameron@onlab.us75900962015-03-30 13:22:49 -07002003 you want to use a different topology file than linkGraph.cfg
andrew@onlab.us3b087132015-03-11 15:00:08 -07002004 '''
2005
Jon Hall4ba53f02015-07-29 13:07:41 -07002006
2007 try:
2008 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider eventRate " + str(eventRate))
2009 self.handle.expect(":~")
cameron@onlab.us75900962015-03-30 13:22:49 -07002010 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider cfgFile " + fileName )
2011 self.handle.expect(":~")
Jon Hall4ba53f02015-07-29 13:07:41 -07002012
2013 for i in range(10):
2014 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.link.impl.NullLinkProvider")
cameron@onlab.us75900962015-03-30 13:22:49 -07002015 self.handle.expect(":~")
2016 verification = self.handle.before
Jon Hall4ba53f02015-07-29 13:07:41 -07002017 if (" value=" + str(eventRate)) in verification and (" value=" + fileName) in verification:
cameron@onlab.us75900962015-03-30 13:22:49 -07002018 break
Jon Hall4ba53f02015-07-29 13:07:41 -07002019 else:
cameron@onlab.us75900962015-03-30 13:22:49 -07002020 time.sleep(1)
Jon Hall4ba53f02015-07-29 13:07:41 -07002021
cameron@onlab.us75900962015-03-30 13:22:49 -07002022 assert ("value=" + str(eventRate)) in verification and (" value=" + fileName) in verification
Jon Hall4ba53f02015-07-29 13:07:41 -07002023
cameron@onlab.us75900962015-03-30 13:22:49 -07002024 except pexpect.EOF:
2025 main.log.error( self.name + ": EOF exception found" )
2026 main.log.error( self.name + ": " + self.handle.before )
2027 main.cleanup()
2028 main.exit()
cameron@onlab.us75900962015-03-30 13:22:49 -07002029 except AssertionError:
2030 main.log.info("Settings did not post to ONOS")
Jon Hall4ba53f02015-07-29 13:07:41 -07002031 main.log.error(varification)
Jon Hall77ba41c2015-04-06 10:25:40 -07002032 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002033 main.log.exception( self.name + ": Uncaught exception!" )
2034 main.log.error(varification)
2035 main.cleanup()
2036 main.exit()
andrew@onlab.us3b087132015-03-11 15:00:08 -07002037
kelvin-onlaba4074292015-07-09 15:19:49 -07002038 def getOnosIps( self ):
2039 """
2040 Get all onos IPs stored in
2041 """
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002042
kelvin-onlaba4074292015-07-09 15:19:49 -07002043 return sorted( self.onosIps.values() )
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002044
kelvin-onlaba4074292015-07-09 15:19:49 -07002045 def logReport( self, nodeIp, searchTerms, outputMode="s" ):
Jon Hallb4242222016-01-25 17:07:04 -08002046 """
2047 Searches the latest ONOS log file for the given search terms and
2048 prints the total occurances of each term. Returns to combined total of
2049 all occurances.
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002050
Jon Hallb4242222016-01-25 17:07:04 -08002051 Arguments:
2052 * nodeIp - The ip of the ONOS node where the log is located
2053 * searchTerms - A string to grep for or a list of strings to grep
2054 for in the ONOS log. Will print out the number of
2055 occurances for each term.
2056 Optional Arguments:
2057 * outputMode - 's' or 'd'. If 'd' will print the last 5 lines
2058 containing each search term as well as the total
2059 number of occurances of each term. Defaults to 's',
2060 which prints the simple output of just the number
2061 of occurances for each term.
2062 """
2063 try:
2064 main.log.info( " Log Report for {} ".format( nodeIp ).center( 70, '=' ) )
2065 if type( searchTerms ) is str:
2066 searchTerms = [searchTerms]
2067 numTerms = len( searchTerms )
2068 outputMode = outputMode.lower()
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002069
Jon Hallb4242222016-01-25 17:07:04 -08002070 totalHits = 0
2071 logLines = []
2072 for termIndex in range( numTerms ):
2073 term = searchTerms[termIndex]
2074 logLines.append( [term] )
2075 cmd = "onos-ssh " + nodeIp + " cat /opt/onos/log/karaf.log | grep " + term
2076 self.handle.sendline( cmd )
2077 self.handle.expect( ":~" )
2078 before = self.handle.before.splitlines()
2079 count = 0
2080 for line in before:
2081 if term in line and "grep" not in line:
2082 count += 1
2083 if before.index( line ) > ( len( before ) - 7 ):
2084 logLines[termIndex].append( line )
2085 main.log.info( "{}: {}".format( term, count ) )
2086 totalHits += count
2087 if termIndex == numTerms - 1:
2088 print "\n"
2089 if outputMode != "s":
2090 outputString = ""
2091 for term in logLines:
2092 outputString = term[0] + ": \n"
2093 for line in range( 1, len( term ) ):
2094 outputString += ( "\t" + term[line] + "\n" )
2095 if outputString != ( term[0] + ": \n" ):
2096 main.log.info( outputString )
2097 main.log.info( "=" * 70 )
2098 return totalHits
2099 except pexpect.EOF:
2100 main.log.error( self.name + ": EOF exception found" )
2101 main.log.error( self.name + ": " + self.handle.before )
2102 main.cleanup()
2103 main.exit()
2104 except pexpect.TIMEOUT:
2105 main.log.error( self.name + ": TIMEOUT exception found" )
2106 main.log.error( self.name + ": " + self.handle.before )
2107 main.cleanup()
2108 main.exit()
2109 except Exception:
2110 main.log.exception( self.name + ": Uncaught exception!" )
2111 main.cleanup()
2112 main.exit()
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002113
2114 def copyMininetFile( self, fileName, localPath, userName, ip,
2115 mnPath='~/mininet/custom/', timeout = 60 ):
2116 """
2117 Description:
2118 Copy mininet topology file from dependency folder in the test folder
2119 and paste it to the mininet machine's mininet/custom folder
2120 Required:
2121 fileName - Name of the topology file to copy
2122 localPath - File path of the mininet topology file
2123 userName - User name of the mininet machine to send the file to
2124 ip - Ip address of the mininet machine
2125 Optional:
2126 mnPath - of the mininet directory to send the file to
2127 Return:
2128 Return main.TRUE if successfully copied the file otherwise
2129 return main.FALSE
2130 """
2131
2132 try:
2133 cmd = "scp " + localPath + fileName + " " + userName + "@" + \
2134 str( ip ) + ":" + mnPath + fileName
2135
2136 self.handle.sendline( "" )
2137 self.handle.expect( "\$" )
2138
2139 main.log.info( self.name + ": Execute: " + cmd )
2140
2141 self.handle.sendline( cmd )
2142
2143 i = self.handle.expect( [ 'No such file',
2144 "100%",
2145 pexpect.TIMEOUT ] )
2146
2147 if i == 0:
2148 main.log.error( self.name + ": File " + fileName +
2149 " does not exist!" )
2150 return main.FALSE
2151
2152 if i == 1:
2153 main.log.info( self.name + ": File " + fileName +
2154 " has been copied!" )
2155 self.handle.sendline( "" )
2156 self.handle.expect( "\$" )
2157 return main.TRUE
2158
2159 except pexpect.EOF:
2160 main.log.error( self.name + ": EOF exception found" )
2161 main.log.error( self.name + ": " + self.handle.before )
2162 main.cleanup()
2163 main.exit()
2164 except pexpect.TIMEOUT:
2165 main.log.error( self.name + ": TIMEOUT exception found" )
2166 main.log.error( self.name + ": " + self.handle.before )
2167 main.cleanup()
2168 main.exit()
cameron@onlab.us78b89652015-07-08 15:21:03 -07002169
2170 def jvmSet(self, memory=8):
Jon Hall4ba53f02015-07-29 13:07:41 -07002171
cameron@onlab.us78b89652015-07-08 15:21:03 -07002172 import os
2173
2174 homeDir = os.path.expanduser('~')
2175 filename = "/onos/tools/package/bin/onos-service"
2176
2177 serviceConfig = open(homeDir + filename, 'w+')
2178 serviceConfig.write("#!/bin/bash\n ")
2179 serviceConfig.write("#------------------------------------- \n ")
2180 serviceConfig.write("# Starts ONOS Apache Karaf container\n ")
2181 serviceConfig.write("#------------------------------------- \n ")
2182 serviceConfig.write("#export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-7-openjdk-amd64/}\n ")
2183 serviceConfig.write("""export JAVA_OPTS="${JAVA_OPTS:--Xms""" + str(memory) + "G -Xmx" + str(memory) + """G}" \n """)
2184 serviceConfig.write("[ -d $ONOS_HOME ] && cd $ONOS_HOME || ONOS_HOME=$(dirname $0)/..\n")
2185 serviceConfig.write("""${ONOS_HOME}/apache-karaf-$KARAF_VERSION/bin/karaf "$@" \n """)
2186 serviceConfig.close()
2187
Jon Hall6c44c0b2016-04-20 15:21:00 -07002188 def createDBFile( self, testData ):
Jon Hall4ba53f02015-07-29 13:07:41 -07002189
cameron@onlab.us78b89652015-07-08 15:21:03 -07002190 filename = main.TEST + "DB"
2191 DBString = ""
Jon Hall4ba53f02015-07-29 13:07:41 -07002192
cameron@onlab.us78b89652015-07-08 15:21:03 -07002193 for item in testData:
Jon Hall6c44c0b2016-04-20 15:21:00 -07002194 if type( item ) is string:
cameron@onlab.us78b89652015-07-08 15:21:03 -07002195 item = "'" + item + "'"
Jon Hall6c44c0b2016-04-20 15:21:00 -07002196 if testData.index( item ) < len( testData - 1 ):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002197 item += ","
Jon Hall6c44c0b2016-04-20 15:21:00 -07002198 DBString += str( item )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002199
Jon Hall6c44c0b2016-04-20 15:21:00 -07002200 DBFile = open( filename, "a" )
2201 DBFile.write( DBString )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002202 DBFile.close()
2203
Jon Hall6c44c0b2016-04-20 15:21:00 -07002204 def verifySummary( self, ONOSIp, *deviceCount ):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002205
Jon Hall6c44c0b2016-04-20 15:21:00 -07002206 self.handle.sendline( "onos " + ONOSIp + " summary" )
2207 self.handle.expect( ":~" )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002208
2209 summaryStr = self.handle.before
2210 print "\nSummary\n==============\n" + summaryStr + "\n\n"
2211
2212 #passed = "SCC(s)=1" in summaryStr
2213 #if deviceCount:
2214 # passed = "devices=" + str(deviceCount) + "," not in summaryStr
2215
GlennRC772363b2015-08-25 13:05:57 -07002216 passed = False
cameron@onlab.us78b89652015-07-08 15:21:03 -07002217 if "SCC(s)=1," in summaryStr:
2218 passed = True
Jon Hall6c44c0b2016-04-20 15:21:00 -07002219 print "Summary is verifed"
Jon Hall4ba53f02015-07-29 13:07:41 -07002220 else:
Jon Hall6c44c0b2016-04-20 15:21:00 -07002221 print "Summary failed"
cameron@onlab.us78b89652015-07-08 15:21:03 -07002222
2223 if deviceCount:
2224 print" ============================="
Jon Hall6c44c0b2016-04-20 15:21:00 -07002225 checkStr = "devices=" + str( deviceCount[0] ) + ","
cameron@onlab.us78b89652015-07-08 15:21:03 -07002226 print "Checkstr: " + checkStr
2227 if checkStr not in summaryStr:
2228 passed = False
Jon Hall6c44c0b2016-04-20 15:21:00 -07002229 print "Device count failed"
Jon Hall4ba53f02015-07-29 13:07:41 -07002230 else:
2231 print "device count verified"
cameron@onlab.us78b89652015-07-08 15:21:03 -07002232
2233 return passed
Jon Hall6c44c0b2016-04-20 15:21:00 -07002234
Jon Hall8f6d4622016-05-23 15:27:18 -07002235 def getIpAddr( self, iface=None ):
Jon Hall6c44c0b2016-04-20 15:21:00 -07002236 """
2237 Update self.ip_address with numerical ip address. If multiple IP's are
2238 located on the device, will attempt to use self.nicAddr to choose the
2239 right one. Defaults to 127.0.0.1 if no other address is found or cannot
2240 determine the correct address.
2241
2242 ONLY WORKS WITH IPV4 ADDRESSES
2243 """
2244 try:
Jon Hall8f6d4622016-05-23 15:27:18 -07002245 LOCALHOST = "127.0.0.1"
Jon Hall6c44c0b2016-04-20 15:21:00 -07002246 ipPat = "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"
2247 pattern = re.compile( ipPat )
2248 match = re.search( pattern, self.ip_address )
2249 if self.nicAddr:
2250 nicPat = self.nicAddr.replace( ".", "\." ).replace( "\*", r"\d{1,3}" )
2251 nicPat = re.compile( nicPat )
2252 else:
2253 nicPat = None
2254 # IF self.ip_address is an ip address and matches
2255 # self.nicAddr: return self.ip_address
2256 if match:
2257 curIp = match.group(0)
2258 if nicPat:
2259 nicMatch = re.search( nicPat, curIp )
2260 if nicMatch:
2261 return self.ip_address
Jon Hall8f6d4622016-05-23 15:27:18 -07002262 # ELSE: IF iface, return ip of interface
2263 cmd = "ifconfig"
2264 ifPat = re.compile( "inet addr:({})".format( ipPat ) )
2265 if iface:
2266 cmd += " " + str( iface )
2267 raw = subprocess.check_output( cmd.split() )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002268 ifPat = re.compile( "inet addr:({})".format( ipPat ) )
2269 ips = re.findall( ifPat, raw )
Jon Hall8f6d4622016-05-23 15:27:18 -07002270 if iface:
2271 if ips:
2272 ip = ips[0]
2273 self.ip_address = ip
2274 return ip
2275 else:
2276 main.log.error( "Error finding ip, ifconfig output:".format( raw ) )
2277 # ELSE: attempt to get address matching nicPat.
Jon Hall6c44c0b2016-04-20 15:21:00 -07002278 if nicPat:
2279 for ip in ips:
2280 curMatch = re.search( nicPat, ip )
2281 if curMatch:
2282 self.ip_address = ip
2283 return ip
Jon Hall8f6d4622016-05-23 15:27:18 -07002284 else: # If only one non-localhost ip, return that
2285 tmpList = [ ip for ip in ips if ip is not LOCALHOST ]
Jon Hall6c44c0b2016-04-20 15:21:00 -07002286 if len(tmpList) == 1:
2287 curIp = tmpList[0]
2288 self.ip_address = curIp
2289 return curIp
Jon Hall8f6d4622016-05-23 15:27:18 -07002290 # Either no non-localhost IPs, or more than 1
Jon Hallebccd352016-05-20 15:17:17 -07002291 main.log.warn( "getIpAddr failed to find a public IP address" )
Jon Hall8f6d4622016-05-23 15:27:18 -07002292 return LOCALHOST
Jon Halle1790952016-05-23 15:51:46 -07002293 except subprocess.CalledProcessError:
Jon Hall8f6d4622016-05-23 15:27:18 -07002294 main.log.exception( "Error executing ifconfig" )
2295 except IndexError:
2296 main.log.exception( "Error getting IP Address" )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002297 except Exception:
2298 main.log.exception( "Uncaught exception" )
suibin zhang116647a2016-05-06 16:30:09 -07002299
2300 def startBasicONOS(self, nodeList, opSleep = 60, onosStartupSleep = 60):
2301
2302 '''
2303 Start onos cluster with defined nodes, but only with drivers app
2304
2305 '''
2306 import time
2307
2308 self.createCellFile( self.ip_address,
2309 "temp",
2310 self.ip_address,
2311 "drivers",
2312 nodeList )
2313
2314 main.log.info( self.name + ": Apply cell to environment" )
2315 cellResult = self.setCell( "temp" )
2316 verifyResult = self.verifyCell()
2317
2318 main.log.info( self.name + ": Creating ONOS package" )
2319 packageResult = self.onosPackage( opTimeout=opSleep )
2320
2321 main.log.info( self.name + ": Installing ONOS package" )
2322 for nd in nodeList:
2323 self.onosInstall( node=nd )
2324
2325 main.log.info( self.name + ": Starting ONOS service" )
2326 time.sleep( onosStartupSleep )
2327
2328 onosStatus = True
2329 for nd in nodeList:
2330 onosStatus = onosStatus & self.isup( node = nd )
2331 #print "onosStatus is: " + str( onosStatus )
2332
2333 return main.TRUE if onosStatus else main.FALSE
2334