blob: 1aed954305966ac507c338cee034e933f1c82901 [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
Jon Hall05b2b432014-10-08 19:53:25 -040028
kelvin8ec71442015-01-15 16:57:00 -080029class OnosDriver( CLI ):
Jon Hall05b2b432014-10-08 19:53:25 -040030
kelvin8ec71442015-01-15 16:57:00 -080031 def __init__( self ):
32 """
33 Initialize client
34 """
Jon Hallefbd9792015-03-05 16:11:36 -080035 self.name = None
36 self.home = None
37 self.handle = None
Jon Hall6c44c0b2016-04-20 15:21:00 -070038 self.nicAddr = None
kelvin8ec71442015-01-15 16:57:00 -080039 super( CLI, self ).__init__()
40
41 def connect( self, **connectargs ):
42 """
Jon Hall05b2b432014-10-08 19:53:25 -040043 Creates ssh handle for ONOS "bench".
kelvin-onlaba4074292015-07-09 15:19:49 -070044 NOTE:
45 The ip_address would come from the topo file using the host tag, the
46 value can be an environment variable as well as a "localhost" to get
47 the ip address needed to ssh to the "bench"
kelvin8ec71442015-01-15 16:57:00 -080048 """
Jon Hall05b2b432014-10-08 19:53:25 -040049 try:
50 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080051 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us3b087132015-03-11 15:00:08 -070052 self.home = "~/onos"
Jon Hall05b2b432014-10-08 19:53:25 -040053 for key in self.options:
54 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080055 self.home = self.options[ 'home' ]
Jon Hall05b2b432014-10-08 19:53:25 -040056 break
Jon Hall274b6642015-02-17 11:57:17 -080057 if self.home is None or self.home == "":
Jon Halle94919c2015-03-23 11:42:57 -070058 self.home = "~/onos"
Jon Hall21270ac2015-02-16 17:59:55 -080059
kelvin8ec71442015-01-15 16:57:00 -080060 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070061
kelvin-onlabc2b79102015-07-14 11:41:20 -070062 # The 'nodes' tag is optional and it is not required in .topo file
kelvin-onlaba4074292015-07-09 15:19:49 -070063 for key in self.options:
64 if key == "nodes":
kelvin-onlabc2b79102015-07-14 11:41:20 -070065 # Maximum number of ONOS nodes to run, if there is any
kelvin-onlaba4074292015-07-09 15:19:49 -070066 self.maxNodes = int( self.options[ 'nodes' ] )
67 break
68 self.maxNodes = None
69
kelvin-onlabc2b79102015-07-14 11:41:20 -070070 if self.maxNodes == None or self.maxNodes == "":
71 self.maxNodes = 100
kelvin-onlaba4074292015-07-09 15:19:49 -070072
kelvin-onlabc2b79102015-07-14 11:41:20 -070073
74 # Grabs all OC environment variables based on max number of nodes
kelvin-onlaba4074292015-07-09 15:19:49 -070075 self.onosIps = {} # Dictionary of all possible ONOS ip
76
77 try:
78 if self.maxNodes:
kelvin-onlaba4074292015-07-09 15:19:49 -070079 for i in range( self.maxNodes ):
80 envString = "OC" + str( i + 1 )
kelvin-onlabc2b79102015-07-14 11:41:20 -070081 # If there is no more OC# then break the loop
82 if os.getenv( envString ):
83 self.onosIps[ envString ] = os.getenv( envString )
84 else:
85 self.maxNodes = len( self.onosIps )
86 main.log.info( self.name +
87 ": Created cluster data with " +
88 str( self.maxNodes ) +
89 " maximum number" +
90 " of nodes" )
91 break
kelvin-onlaba4074292015-07-09 15:19:49 -070092
93 if not self.onosIps:
94 main.log.info( "Could not read any environment variable"
95 + " please load a cell file with all" +
96 " onos IP" )
Jon Hall5cf14d52015-07-16 12:15:19 -070097 self.maxNodes = None
kelvin-onlaba4074292015-07-09 15:19:49 -070098 else:
99 main.log.info( self.name + ": Found " +
100 str( self.onosIps.values() ) +
101 " ONOS IPs" )
kelvin-onlaba4074292015-07-09 15:19:49 -0700102 except KeyError:
103 main.log.info( "Invalid environment variable" )
104 except Exception as inst:
105 main.log.error( "Uncaught exception: " + str( inst ) )
106
107 try:
108 if os.getenv( str( self.ip_address ) ) != None:
109 self.ip_address = os.getenv( str( self.ip_address ) )
110 else:
111 main.log.info( self.name +
112 ": Trying to connect to " +
113 self.ip_address )
kelvin-onlaba4074292015-07-09 15:19:49 -0700114 except KeyError:
115 main.log.info( "Invalid host name," +
116 " connecting to local host instead" )
117 self.ip_address = 'localhost'
118 except Exception as inst:
119 main.log.error( "Uncaught exception: " + str( inst ) )
120
kelvin8ec71442015-01-15 16:57:00 -0800121 self.handle = super( OnosDriver, self ).connect(
122 user_name=self.user_name,
kelvin-onlab08679eb2015-01-21 16:11:48 -0800123 ip_address=self.ip_address,
kelvin-onlabd3b64892015-01-20 13:26:24 -0800124 port=self.port,
125 pwd=self.pwd,
126 home=self.home )
Jon Hall05b2b432014-10-08 19:53:25 -0400127
Jon Hall05b2b432014-10-08 19:53:25 -0400128 if self.handle:
Jon Hall0fc0d452015-07-14 09:49:58 -0700129 self.handle.sendline( "cd " + self.home )
130 self.handle.expect( "\$" )
Jon Hall05b2b432014-10-08 19:53:25 -0400131 return self.handle
kelvin8ec71442015-01-15 16:57:00 -0800132 else:
Jon Hall0fc0d452015-07-14 09:49:58 -0700133 main.log.info( "Failed to create ONOS handle" )
Jon Hall05b2b432014-10-08 19:53:25 -0400134 return main.FALSE
135 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800136 main.log.error( self.name + ": EOF exception found" )
137 main.log.error( self.name + ": " + self.handle.before )
Jon Hall05b2b432014-10-08 19:53:25 -0400138 main.cleanup()
139 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800140 except Exception:
141 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall05b2b432014-10-08 19:53:25 -0400142 main.cleanup()
143 main.exit()
144
kelvin8ec71442015-01-15 16:57:00 -0800145 def disconnect( self ):
146 """
Jon Hall05b2b432014-10-08 19:53:25 -0400147 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800148 """
Jon Halld61331b2015-02-17 16:35:47 -0800149 response = main.TRUE
Jon Hall05b2b432014-10-08 19:53:25 -0400150 try:
Jon Hall61282e32015-03-19 11:34:11 -0700151 if self.handle:
152 self.handle.sendline( "" )
153 self.handle.expect( "\$" )
154 self.handle.sendline( "exit" )
155 self.handle.expect( "closed" )
Jon Hall05b2b432014-10-08 19:53:25 -0400156 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800157 main.log.error( self.name + ": EOF exception found" )
158 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700159 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700160 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700161 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800162 except Exception:
163 main.log.exception( self.name + ": Connection failed to the host" )
Jon Hall05b2b432014-10-08 19:53:25 -0400164 response = main.FALSE
165 return response
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400166
andrew@onlab.usaee415a2015-06-05 14:38:58 -0400167 def getEpochMs( self ):
168 """
169 Returns milliseconds since epoch
Jon Hall4ba53f02015-07-29 13:07:41 -0700170
171 When checking multiple nodes in a for loop,
172 around a hundred milliseconds of difference (ascending) is
173 generally acceptable due to calltime of the function.
174 Few seconds, however, is not and it means clocks
175 are off sync.
andrew@onlab.usaee415a2015-06-05 14:38:58 -0400176 """
177 try:
178 self.handle.sendline( 'date +%s.%N' )
179 self.handle.expect( 'date \+\%s\.\%N' )
180 self.handle.expect( '\$' )
181 epochMs = self.handle.before
182 return epochMs
183 except Exception:
184 main.log.exception( 'Uncaught exception getting epoch time' )
185 main.cleanup()
186 main.exit()
187
Jon Hall6c44c0b2016-04-20 15:21:00 -0700188 def onosPackage( self, opTimeout=180 ):
kelvin8ec71442015-01-15 16:57:00 -0800189 """
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400190 Produce a self-contained tar.gz file that can be deployed
Jon Hall64af8502015-12-15 10:09:33 -0800191 and executed on any platform with Java 8 JRE.
kelvin8ec71442015-01-15 16:57:00 -0800192 """
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400193 try:
Jon Hall64af8502015-12-15 10:09:33 -0800194 ret = main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800195 self.handle.sendline( "onos-package" )
196 self.handle.expect( "onos-package" )
Jon Hall96451092016-05-04 09:42:30 -0700197 while True:
198 i = self.handle.expect( [ "Downloading",
199 "Unknown options",
200 "No such file or directory",
201 "tar.gz",
202 "\$" ],
203 opTimeout )
204 handle = str( self.handle.before + self.handle.after )
205 if i == 0:
206 # Give more time to download the file
207 continue # expect again
208 elif i == 1:
209 # Incorrect usage
210 main.log.error( "onos-package does not recognize the given options" )
211 ret = main.FALSE
212 continue # expect again
213 elif i == 2:
214 # File(s) not found
215 main.log.error( "onos-package could not find a file or directory" )
216 ret = main.FALSE
217 continue # expect again
218 elif i == 3:
219 # tar.gz
220 continue # expect again
221 elif i == 4:
222 # Prompt returned
223 break
Jon Hallc6793552016-01-19 14:18:37 -0800224 main.log.info( "onos-package command returned: " + handle )
kelvin8ec71442015-01-15 16:57:00 -0800225 # As long as the sendline does not time out,
226 # return true. However, be careful to interpret
227 # the results of the onos-package command return
Jon Hall64af8502015-12-15 10:09:33 -0800228 return ret
229 except pexpect.TIMEOUT:
230 main.log.exception( self.name + ": TIMEOUT exception found in onosPackage" )
231 main.log.error( self.name + ": " + self.handle.before )
232 return main.FALSE
andrewonlab7735d852014-10-09 13:02:47 -0400233 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800234 main.log.error( self.name + ": EOF exception found" )
235 main.log.error( self.name + ": " + self.handle.before )
Jon Hall64af8502015-12-15 10:09:33 -0800236 main.cleanup()
237 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800238 except Exception:
239 main.log.exception( "Failed to package ONOS" )
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400240 main.cleanup()
241 main.exit()
242
kelvin-onlabd3b64892015-01-20 13:26:24 -0800243 def onosBuild( self ):
kelvin8ec71442015-01-15 16:57:00 -0800244 """
andrewonlab8790abb2014-11-06 13:51:54 -0500245 Use the pre defined script to build onos via mvn
kelvin8ec71442015-01-15 16:57:00 -0800246 """
andrewonlab8790abb2014-11-06 13:51:54 -0500247 try:
kelvin8ec71442015-01-15 16:57:00 -0800248 self.handle.sendline( "onos-build" )
249 self.handle.expect( "onos-build" )
250 i = self.handle.expect( [
kelvin-onlabd3b64892015-01-20 13:26:24 -0800251 "BUILD SUCCESS",
252 "ERROR",
253 "BUILD FAILED" ],
254 timeout=120 )
kelvin8ec71442015-01-15 16:57:00 -0800255 handle = str( self.handle.before )
Jon Hall3b489db2015-10-05 14:38:37 -0700256 self.handle.expect( "\$" )
andrewonlab8790abb2014-11-06 13:51:54 -0500257
kelvin8ec71442015-01-15 16:57:00 -0800258 main.log.info( "onos-build command returned: " +
259 handle )
andrewonlab8790abb2014-11-06 13:51:54 -0500260
261 if i == 0:
262 return main.TRUE
263 else:
264 return handle
265
266 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800267 main.log.error( self.name + ": EOF exception found" )
268 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -0800269 except Exception:
270 main.log.exception( "Failed to build ONOS" )
andrewonlab8790abb2014-11-06 13:51:54 -0500271 main.cleanup()
272 main.exit()
273
shahshreya9f531fe2015-06-10 12:03:51 -0700274 def cleanInstall( self, skipTest=False, mciTimeout=600 ):
kelvin8ec71442015-01-15 16:57:00 -0800275 """
276 Runs mvn clean install in the root of the ONOS directory.
277 This will clean all ONOS artifacts then compile each module
shahshreya9f531fe2015-06-10 12:03:51 -0700278 Optional:
279 skipTest - Does "-DskipTests -Dcheckstyle.skip -U -T 1C" which
280 skip the test. This will make the building faster.
281 Disregarding the credibility of the build
kelvin8ec71442015-01-15 16:57:00 -0800282 Returns: main.TRUE on success
Jon Hallde9d9aa2014-10-08 20:36:02 -0400283 On Failure, exits the test
kelvin8ec71442015-01-15 16:57:00 -0800284 """
Jon Hallde9d9aa2014-10-08 20:36:02 -0400285 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800286 main.log.info( "Running 'mvn clean install' on " +
287 str( self.name ) +
kelvin8ec71442015-01-15 16:57:00 -0800288 ". This may take some time." )
289 self.handle.sendline( "cd " + self.home )
290 self.handle.expect( "\$" )
Jon Hallea7818b2014-10-09 14:30:59 -0400291
kelvin8ec71442015-01-15 16:57:00 -0800292 self.handle.sendline( "" )
293 self.handle.expect( "\$" )
shahshreya9f531fe2015-06-10 12:03:51 -0700294
295 if not skipTest:
296 self.handle.sendline( "mvn clean install" )
297 self.handle.expect( "mvn clean install" )
298 else:
299 self.handle.sendline( "mvn clean install -DskipTests" +
300 " -Dcheckstyle.skip -U -T 1C" )
301 self.handle.expect( "mvn clean install -DskipTests" +
302 " -Dcheckstyle.skip -U -T 1C" )
kelvin8ec71442015-01-15 16:57:00 -0800303 while True:
304 i = self.handle.expect( [
Jon Hall274b6642015-02-17 11:57:17 -0800305 'There\sis\sinsufficient\smemory\sfor\sthe\sJava\s' +
Jon Hallefbd9792015-03-05 16:11:36 -0800306 'Runtime\sEnvironment\sto\scontinue',
Jon Hallde9d9aa2014-10-08 20:36:02 -0400307 'BUILD\sFAILURE',
308 'BUILD\sSUCCESS',
Jon Halle94919c2015-03-23 11:42:57 -0700309 'onos\$', #TODO: fix this to be more generic?
Jon Hallde9d9aa2014-10-08 20:36:02 -0400310 'ONOS\$',
pingping-lin57a56ce2015-05-20 16:43:48 -0700311 pexpect.TIMEOUT ], mciTimeout )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400312 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800313 main.log.error( self.name + ":There is insufficient memory \
314 for the Java Runtime Environment to continue." )
315 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400316 main.cleanup()
317 main.exit()
318 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800319 main.log.error( self.name + ": Build failure!" )
320 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400321 main.cleanup()
322 main.exit()
323 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800324 main.log.info( self.name + ": Build success!" )
Jon Halle94919c2015-03-23 11:42:57 -0700325 elif i == 3 or i == 4:
kelvin8ec71442015-01-15 16:57:00 -0800326 main.log.info( self.name + ": Build complete" )
327 # Print the build time
Jon Hallf8ef52c2014-10-09 19:37:33 -0400328 for line in self.handle.before.splitlines():
329 if "Total time:" in line:
kelvin8ec71442015-01-15 16:57:00 -0800330 main.log.info( line )
331 self.handle.sendline( "" )
332 self.handle.expect( "\$", timeout=60 )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400333 return main.TRUE
Jon Halle94919c2015-03-23 11:42:57 -0700334 elif i == 5:
kelvin8ec71442015-01-15 16:57:00 -0800335 main.log.error(
336 self.name +
337 ": mvn clean install TIMEOUT!" )
338 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400339 main.cleanup()
340 main.exit()
341 else:
Jon Hall274b6642015-02-17 11:57:17 -0800342 main.log.error( self.name + ": unexpected response from " +
Jon Hallefbd9792015-03-05 16:11:36 -0800343 "mvn clean install" )
kelvin8ec71442015-01-15 16:57:00 -0800344 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400345 main.cleanup()
346 main.exit()
347 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800348 main.log.error( self.name + ": EOF exception found" )
349 main.log.error( self.name + ": " + self.handle.before )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400350 main.cleanup()
351 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800352 except Exception:
353 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400354 main.cleanup()
355 main.exit()
Jon Hallacabffd2014-10-09 12:36:53 -0400356
Jon Hall61282e32015-03-19 11:34:11 -0700357 def gitPull( self, comp1="", fastForward=True ):
kelvin8ec71442015-01-15 16:57:00 -0800358 """
Jon Hallacabffd2014-10-09 12:36:53 -0400359 Assumes that "git pull" works without login
Jon Hall47a93fb2015-01-06 16:46:06 -0800360
Jon Hall61282e32015-03-19 11:34:11 -0700361 If the fastForward boolean is set to true, only git pulls that can
362 be fast forwarded will be performed. IE if you have not local commits
363 in your branch.
364
Jon Hallacabffd2014-10-09 12:36:53 -0400365 This function will perform a git pull on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800366 If used as gitPull( "NODE" ) it will do git pull + NODE. This is
Jon Hallacabffd2014-10-09 12:36:53 -0400367 for the purpose of pulling from other nodes if necessary.
368
Jon Hall47a93fb2015-01-06 16:46:06 -0800369 Otherwise, this function will perform a git pull in the
Jon Hallacabffd2014-10-09 12:36:53 -0400370 ONOS repository. If it has any problems, it will return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -0800371 If it successfully does a gitPull, it will return a 1 ( main.TRUE )
Shreya Shahee15f6c2014-10-28 18:12:30 -0400372 If it has no updates, it will return 3.
Jon Hallacabffd2014-10-09 12:36:53 -0400373
kelvin8ec71442015-01-15 16:57:00 -0800374 """
Jon Hallacabffd2014-10-09 12:36:53 -0400375 try:
kelvin8ec71442015-01-15 16:57:00 -0800376 self.handle.sendline( "cd " + self.home )
kelvin-onlaba1484582015-02-02 15:46:20 -0800377 self.handle.expect( self.home + "\$" )
Jon Hall61282e32015-03-19 11:34:11 -0700378 cmd = "git pull"
379 if comp1 != "":
380 cmd += ' ' + comp1
381 if fastForward:
382 cmd += ' ' + " --ff-only"
383 self.handle.sendline( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800384 i = self.handle.expect(
385 [
386 'fatal',
387 'Username\sfor\s(.*):\s',
388 '\sfile(s*) changed,\s',
389 'Already up-to-date',
390 'Aborting',
391 'You\sare\snot\scurrently\son\sa\sbranch',
Jon Hall274b6642015-02-17 11:57:17 -0800392 'You asked me to pull without telling me which branch you',
393 'Pull is not possible because you have unmerged files',
Jon Hall61282e32015-03-19 11:34:11 -0700394 'Please enter a commit message to explain why this merge',
395 'Found a swap file by the name',
396 'Please, commit your changes before you can merge.',
kelvin-onlabd3b64892015-01-20 13:26:24 -0800397 pexpect.TIMEOUT ],
398 timeout=300 )
kelvin8ec71442015-01-15 16:57:00 -0800399 if i == 0:
Jon Hall61282e32015-03-19 11:34:11 -0700400 main.log.error( self.name + ": Git pull had some issue" )
401 output = self.handle.after
402 self.handle.expect( '\$' )
403 output += self.handle.before
404 main.log.warn( output )
Jon Hallacabffd2014-10-09 12:36:53 -0400405 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800406 elif i == 1:
407 main.log.error(
408 self.name +
409 ": Git Pull Asking for username. " )
Jon Hallacabffd2014-10-09 12:36:53 -0400410 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800411 elif i == 2:
412 main.log.info(
413 self.name +
414 ": Git Pull - pulling repository now" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800415 self.handle.expect( self.home + "\$", 120 )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800416 # So that only when git pull is done, we do mvn clean compile
417 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800418 elif i == 3:
419 main.log.info( self.name + ": Git Pull - Already up to date" )
Jon Hall47a93fb2015-01-06 16:46:06 -0800420 return i
kelvin8ec71442015-01-15 16:57:00 -0800421 elif i == 4:
422 main.log.info(
423 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800424 ": Git Pull - Aborting..." +
425 "Are there conflicting git files?" )
Jon Hallacabffd2014-10-09 12:36:53 -0400426 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800427 elif i == 5:
428 main.log.info(
429 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800430 ": Git Pull - You are not currently " +
431 "on a branch so git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400432 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800433 elif i == 6:
434 main.log.info(
435 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800436 ": Git Pull - You have not configured an upstream " +
437 "branch to pull from. Git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400438 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800439 elif i == 7:
440 main.log.info(
441 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800442 ": Git Pull - Pull is not possible because " +
443 "you have unmerged files." )
Jon Hallacabffd2014-10-09 12:36:53 -0400444 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800445 elif i == 8:
Jon Hall61282e32015-03-19 11:34:11 -0700446 # NOTE: abandoning test since we can't reliably handle this
447 # there could be different default text editors and we
448 # also don't know if we actually want to make the commit
449 main.log.error( "Git pull resulted in a merge commit message" +
450 ". Exiting test!" )
451 main.cleanup()
452 main.exit()
453 elif i == 9: # Merge commit message but swap file exists
454 main.log.error( "Git pull resulted in a merge commit message" +
455 " but a swap file exists." )
456 try:
457 self.handle.send( 'A' ) # Abort
458 self.handle.expect( "\$" )
459 return main.ERROR
460 except Exception:
461 main.log.exception( "Couldn't exit editor prompt!")
462 main.cleanup()
463 main.exit()
464 elif i == 10: # In the middle of a merge commit
465 main.log.error( "Git branch is in the middle of a merge. " )
466 main.log.warn( self.handle.before + self.handle.after )
467 return main.ERROR
468 elif i == 11:
kelvin8ec71442015-01-15 16:57:00 -0800469 main.log.error( self.name + ": Git Pull - TIMEOUT" )
470 main.log.error(
471 self.name + " Response was: " + str(
472 self.handle.before ) )
Jon Hallacabffd2014-10-09 12:36:53 -0400473 return main.ERROR
474 else:
kelvin8ec71442015-01-15 16:57:00 -0800475 main.log.error(
476 self.name +
477 ": Git Pull - Unexpected response, check for pull errors" )
Jon Hallacabffd2014-10-09 12:36:53 -0400478 return main.ERROR
479 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800480 main.log.error( self.name + ": EOF exception found" )
481 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400482 main.cleanup()
483 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800484 except Exception:
485 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400486 main.cleanup()
487 main.exit()
488
kelvin-onlabd3b64892015-01-20 13:26:24 -0800489 def gitCheckout( self, branch="master" ):
kelvin8ec71442015-01-15 16:57:00 -0800490 """
Jon Hallacabffd2014-10-09 12:36:53 -0400491 Assumes that "git pull" works without login
kelvin8ec71442015-01-15 16:57:00 -0800492
Jon Hallacabffd2014-10-09 12:36:53 -0400493 This function will perform a git git checkout on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800494 If used as gitCheckout( "branch" ) it will do git checkout
495 of the "branch".
Jon Hallacabffd2014-10-09 12:36:53 -0400496
497 Otherwise, this function will perform a git checkout of the master
kelvin8ec71442015-01-15 16:57:00 -0800498 branch of the ONOS repository. If it has any problems, it will return
499 main.ERROR.
500 If the branch was already the specified branch, or the git checkout was
Jon Hallacabffd2014-10-09 12:36:53 -0400501 successful then the function will return main.TRUE.
502
kelvin8ec71442015-01-15 16:57:00 -0800503 """
Jon Hallacabffd2014-10-09 12:36:53 -0400504 try:
kelvin8ec71442015-01-15 16:57:00 -0800505 self.handle.sendline( "cd " + self.home )
kelvin-onlaba1484582015-02-02 15:46:20 -0800506 self.handle.expect( self.home + "\$" )
Jon Hall274b6642015-02-17 11:57:17 -0800507 main.log.info( self.name +
508 ": Checking out git branch/ref: " + branch + "..." )
kelvin8ec71442015-01-15 16:57:00 -0800509 cmd = "git checkout " + branch
510 self.handle.sendline( cmd )
511 self.handle.expect( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800512 i = self.handle.expect(
Jon Hall274b6642015-02-17 11:57:17 -0800513 [ 'fatal',
Jon Hall61282e32015-03-19 11:34:11 -0700514 'Username for (.*): ',
515 'Already on \'',
Jon Hall7a8354f2015-06-10 15:37:00 -0700516 'Switched to (a new )?branch \'' + str( branch ),
Jon Hall274b6642015-02-17 11:57:17 -0800517 pexpect.TIMEOUT,
518 'error: Your local changes to the following files' +
Jon Hallefbd9792015-03-05 16:11:36 -0800519 'would be overwritten by checkout:',
Jon Hall274b6642015-02-17 11:57:17 -0800520 'error: you need to resolve your current index first',
521 "You are in 'detached HEAD' state.",
522 "HEAD is now at " ],
kelvin-onlabd3b64892015-01-20 13:26:24 -0800523 timeout=60 )
kelvin8ec71442015-01-15 16:57:00 -0800524 if i == 0:
525 main.log.error(
526 self.name +
527 ": Git checkout had some issue..." )
528 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400529 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800530 elif i == 1:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800531 main.log.error(
532 self.name +
533 ": Git checkout asking for username." +
534 " Please configure your local git repository to be able " +
535 "to access your remote repository passwordlessly" )
Jon Hall274b6642015-02-17 11:57:17 -0800536 # TODO add support for authenticating
Jon Hallacabffd2014-10-09 12:36:53 -0400537 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800538 elif i == 2:
539 main.log.info(
540 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800541 ": Git Checkout %s : Already on this branch" % branch )
kelvin-onlaba1484582015-02-02 15:46:20 -0800542 self.handle.expect( self.home + "\$" )
kelvin8ec71442015-01-15 16:57:00 -0800543 # main.log.info( "DEBUG: after checkout cmd = "+
544 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400545 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800546 elif i == 3:
547 main.log.info(
548 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800549 ": Git checkout %s - Switched to this branch" % branch )
kelvin-onlaba1484582015-02-02 15:46:20 -0800550 self.handle.expect( self.home + "\$" )
kelvin8ec71442015-01-15 16:57:00 -0800551 # main.log.info( "DEBUG: after checkout cmd = "+
552 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400553 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800554 elif i == 4:
555 main.log.error( self.name + ": Git Checkout- TIMEOUT" )
556 main.log.error(
Jon Hall274b6642015-02-17 11:57:17 -0800557 self.name + " Response was: " + str( self.handle.before ) )
Jon Hallacabffd2014-10-09 12:36:53 -0400558 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800559 elif i == 5:
560 self.handle.expect( "Aborting" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800561 main.log.error(
562 self.name +
563 ": Git checkout error: \n" +
Jon Hall274b6642015-02-17 11:57:17 -0800564 "Your local changes to the following files would" +
565 " be overwritten by checkout:" +
566 str( self.handle.before ) )
kelvin-onlaba1484582015-02-02 15:46:20 -0800567 self.handle.expect( self.home + "\$" )
Jon Hall81e29af2014-11-04 20:41:23 -0500568 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800569 elif i == 6:
Jon Hall274b6642015-02-17 11:57:17 -0800570 main.log.error(
571 self.name +
572 ": Git checkout error: \n" +
573 "You need to resolve your current index first:" +
574 str( self.handle.before ) )
kelvin-onlaba1484582015-02-02 15:46:20 -0800575 self.handle.expect( self.home + "\$" )
Jon Hall81e29af2014-11-04 20:41:23 -0500576 return main.ERROR
Jon Hall274b6642015-02-17 11:57:17 -0800577 elif i == 7:
578 main.log.info(
579 self.name +
580 ": Git checkout " + str( branch ) +
581 " - You are in 'detached HEAD' state. HEAD is now at " +
582 str( branch ) )
583 self.handle.expect( self.home + "\$" )
584 return main.TRUE
585 elif i == 8: # Already in detached HEAD on the specified commit
586 main.log.info(
587 self.name +
588 ": Git Checkout %s : Already on commit" % branch )
589 self.handle.expect( self.home + "\$" )
590 return main.TRUE
Jon Hallacabffd2014-10-09 12:36:53 -0400591 else:
kelvin8ec71442015-01-15 16:57:00 -0800592 main.log.error(
593 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800594 ": Git Checkout - Unexpected response, " +
595 "check for pull errors" )
kelvin8ec71442015-01-15 16:57:00 -0800596 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400597 return main.ERROR
598
599 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800600 main.log.error( self.name + ": EOF exception found" )
601 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400602 main.cleanup()
603 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800604 except Exception:
605 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400606 main.cleanup()
607 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400608
pingping-lin6d23d9e2015-02-02 16:54:24 -0800609 def getBranchName( self ):
pingping-linf30cf272015-05-29 15:54:07 -0700610 main.log.info( "self.home = " )
611 main.log.info( self.home )
pingping-lin6d23d9e2015-02-02 16:54:24 -0800612 self.handle.sendline( "cd " + self.home )
pingping-lin9bf3d8f2015-05-29 16:05:28 -0700613 self.handle.expect( self.home + "\$" )
pingping-lin6d23d9e2015-02-02 16:54:24 -0800614 self.handle.sendline( "git name-rev --name-only HEAD" )
615 self.handle.expect( "git name-rev --name-only HEAD" )
616 self.handle.expect( "\$" )
617
618 lines = self.handle.before.splitlines()
619 if lines[1] == "master":
620 return "master"
621 elif lines[1] == "onos-1.0":
622 return "onos-1.0"
623 else:
624 main.log.info( lines[1] )
625 return "unexpected ONOS branch for SDN-IP test"
626
kelvin-onlabd3b64892015-01-20 13:26:24 -0800627 def getVersion( self, report=False ):
kelvin8ec71442015-01-15 16:57:00 -0800628 """
Jon Hall274b6642015-02-17 11:57:17 -0800629 Writes the COMMIT number to the report to be parsed
Jon Hallefbd9792015-03-05 16:11:36 -0800630 by Jenkins data collector.
kelvin8ec71442015-01-15 16:57:00 -0800631 """
Jon Hall45ec0922014-10-10 19:33:49 -0400632 try:
kelvin8ec71442015-01-15 16:57:00 -0800633 self.handle.sendline( "" )
634 self.handle.expect( "\$" )
635 self.handle.sendline(
636 "cd " +
637 self.home +
Jon Hall274b6642015-02-17 11:57:17 -0800638 "; git log -1 --pretty=fuller --decorate=short | grep -A 6 " +
639 " \"commit\" --color=never" )
kelvin8ec71442015-01-15 16:57:00 -0800640 # NOTE: for some reason there are backspaces inserted in this
641 # phrase when run from Jenkins on some tests
642 self.handle.expect( "never" )
643 self.handle.expect( "\$" )
644 response = ( self.name + ": \n" + str(
645 self.handle.before + self.handle.after ) )
646 self.handle.sendline( "cd " + self.home )
647 self.handle.expect( "\$" )
648 lines = response.splitlines()
Jon Hall45ec0922014-10-10 19:33:49 -0400649 for line in lines:
Jon Hallfd191202014-11-07 18:36:09 -0500650 print line
651 if report:
pingping-lin763ee042015-05-20 17:45:30 -0700652 main.log.wiki( "<blockquote>" )
kelvin8ec71442015-01-15 16:57:00 -0800653 for line in lines[ 2:-1 ]:
654 # Bracket replacement is for Wiki-compliant
655 # formatting. '<' or '>' are interpreted
656 # as xml specific tags that cause errors
657 line = line.replace( "<", "[" )
658 line = line.replace( ">", "]" )
pingping-lin763ee042015-05-20 17:45:30 -0700659 #main.log.wiki( "\t" + line )
660 main.log.wiki( line + "<br /> " )
661 main.log.summary( line )
662 main.log.wiki( "</blockquote>" )
663 main.log.summary("\n")
kelvin8ec71442015-01-15 16:57:00 -0800664 return lines[ 2 ]
Jon Hall45ec0922014-10-10 19:33:49 -0400665 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800666 main.log.error( self.name + ": EOF exception found" )
667 main.log.error( self.name + ": " + self.handle.before )
Jon Hall45ec0922014-10-10 19:33:49 -0400668 main.cleanup()
669 main.exit()
Jon Hall368769f2014-11-19 15:43:35 -0800670 except pexpect.TIMEOUT:
kelvin8ec71442015-01-15 16:57:00 -0800671 main.log.error( self.name + ": TIMEOUT exception found" )
672 main.log.error( self.name + ": " + self.handle.before )
Jon Hall368769f2014-11-19 15:43:35 -0800673 main.cleanup()
674 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800675 except Exception:
676 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall45ec0922014-10-10 19:33:49 -0400677 main.cleanup()
678 main.exit()
679
kelvin-onlabd3b64892015-01-20 13:26:24 -0800680 def createCellFile( self, benchIp, fileName, mnIpAddrs,
Flavio Castrocc38a542016-03-03 13:15:46 -0800681 appString, onosIpAddrs, onosUser="sdn" ):
kelvin8ec71442015-01-15 16:57:00 -0800682 """
andrewonlab94282092014-10-10 13:00:11 -0400683 Creates a cell file based on arguments
684 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800685 * Bench IP address ( benchIp )
andrewonlab94282092014-10-10 13:00:11 -0400686 - Needed to copy the cell file over
kelvin-onlabd3b64892015-01-20 13:26:24 -0800687 * File name of the cell file ( fileName )
688 * Mininet IP address ( mnIpAddrs )
kelvin8ec71442015-01-15 16:57:00 -0800689 - Note that only 1 ip address is
andrewonlab94282092014-10-10 13:00:11 -0400690 supported currently
kelvin-onlabd3b64892015-01-20 13:26:24 -0800691 * ONOS IP addresses ( onosIpAddrs )
andrewonlab94282092014-10-10 13:00:11 -0400692 - Must be passed in as last arguments
Flavio Castrocc38a542016-03-03 13:15:46 -0800693 * ONOS USER (onosUser)
694 - optional argument to set ONOS_USER environment variable
kelvin8ec71442015-01-15 16:57:00 -0800695
andrewonlab94282092014-10-10 13:00:11 -0400696 NOTE: Assumes cells are located at:
697 ~/<self.home>/tools/test/cells/
kelvin8ec71442015-01-15 16:57:00 -0800698 """
699 # Variable initialization
Jon Hall6801cda2015-07-15 14:13:45 -0700700 cellDirectory = self.home + "/tools/test/cells/"
kelvin8ec71442015-01-15 16:57:00 -0800701 # We want to create the cell file in the dependencies directory
702 # of TestON first, then copy over to ONOS bench
kelvin-onlabd3b64892015-01-20 13:26:24 -0800703 tempDirectory = "/tmp/"
kelvin8ec71442015-01-15 16:57:00 -0800704 # Create the cell file in the directory for writing ( w+ )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800705 cellFile = open( tempDirectory + fileName, 'w+' )
Jon Hall6801cda2015-07-15 14:13:45 -0700706 if isinstance( onosIpAddrs, types.StringType ):
707 onosIpAddrs = [ onosIpAddrs ]
kelvin8ec71442015-01-15 16:57:00 -0800708
cameron@onlab.us75900962015-03-30 13:22:49 -0700709 # App string is hardcoded environment variables
kelvin8ec71442015-01-15 16:57:00 -0800710 # That you may wish to use by default on startup.
cameron@onlab.us75900962015-03-30 13:22:49 -0700711 # Note that you may not want certain apps listed
kelvin8ec71442015-01-15 16:57:00 -0800712 # on here.
cameron@onlab.us75900962015-03-30 13:22:49 -0700713 appString = "export ONOS_APPS=" + appString
Flavio Castrocc38a542016-03-03 13:15:46 -0800714 onosGroup = "export ONOS_GROUP=" + onosUser
715 onosUser = "export ONOS_USER=" + onosUser
kelvin-onlabd3b64892015-01-20 13:26:24 -0800716 mnString = "export OCN="
kelvin-onlabf70fd542015-05-07 18:41:40 -0700717 if mnIpAddrs == "":
718 mnString = ""
kelvin-onlabd3b64892015-01-20 13:26:24 -0800719 onosString = "export OC"
720 tempCount = 1
kelvin8ec71442015-01-15 16:57:00 -0800721
kelvin-onlabd3b64892015-01-20 13:26:24 -0800722 # Create ONOSNIC ip address prefix
kelvin-onlaba4074292015-07-09 15:19:49 -0700723 tempOnosIp = str( onosIpAddrs[ 0 ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800724 tempList = []
725 tempList = tempOnosIp.split( "." )
kelvin8ec71442015-01-15 16:57:00 -0800726 # Omit last element of list to format for NIC
kelvin-onlabd3b64892015-01-20 13:26:24 -0800727 tempList = tempList[ :-1 ]
kelvin8ec71442015-01-15 16:57:00 -0800728 # Structure the nic string ip
kelvin-onlabd3b64892015-01-20 13:26:24 -0800729 nicAddr = ".".join( tempList ) + ".*"
Jon Hall6c44c0b2016-04-20 15:21:00 -0700730 self.nicAddr = nicAddr
kelvin-onlabd3b64892015-01-20 13:26:24 -0800731 onosNicString = "export ONOS_NIC=" + nicAddr
andrewonlab94282092014-10-10 13:00:11 -0400732
733 try:
kelvin8ec71442015-01-15 16:57:00 -0800734 # Start writing to file
kelvin-onlabd3b64892015-01-20 13:26:24 -0800735 cellFile.write( onosNicString + "\n" )
andrewonlab94282092014-10-10 13:00:11 -0400736
kelvin-onlabd3b64892015-01-20 13:26:24 -0800737 for arg in onosIpAddrs:
738 # For each argument in onosIpAddrs, write to file
kelvin8ec71442015-01-15 16:57:00 -0800739 # Output should look like the following:
andrewonlabd4940492014-10-24 12:21:27 -0400740 # export OC1="10.128.20.11"
741 # export OC2="10.128.20.12"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800742 cellFile.write( onosString + str( tempCount ) +
Jon Hall6f665652015-09-18 10:08:07 -0700743 "=\"" + arg + "\"\n" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800744 tempCount = tempCount + 1
kelvin8ec71442015-01-15 16:57:00 -0800745
Jon Hall6f665652015-09-18 10:08:07 -0700746 cellFile.write( "export OCI=$OC1\n" )
747 cellFile.write( mnString + "\"" + mnIpAddrs + "\"\n" )
cameron@onlab.us75900962015-03-30 13:22:49 -0700748 cellFile.write( appString + "\n" )
Flavio Castrocc38a542016-03-03 13:15:46 -0800749 cellFile.write( onosGroup + "\n" )
750 cellFile.write( onosUser + "\n" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800751 cellFile.close()
andrewonlab94282092014-10-10 13:00:11 -0400752
kelvin8ec71442015-01-15 16:57:00 -0800753 # We use os.system to send the command to TestON cluster
754 # to account for the case in which TestON is not located
755 # on the same cluster as the ONOS bench
756 # Note that even if TestON is located on the same cluster
757 # as ONOS bench, you must setup passwordless ssh
758 # between TestON and ONOS bench in order to automate the test.
kelvin-onlabc2b79102015-07-14 11:41:20 -0700759 os.system( "scp " + tempDirectory + fileName + " " +
760 self.user_name + "@" + self.ip_address + ":" + cellDirectory )
andrewonlab94282092014-10-10 13:00:11 -0400761
andrewonlab2a6c9342014-10-16 13:40:15 -0400762 return main.TRUE
763
andrewonlab94282092014-10-10 13:00:11 -0400764 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800765 main.log.error( self.name + ": EOF exception found" )
766 main.log.error( self.name + ": " + self.handle.before )
andrewonlab94282092014-10-10 13:00:11 -0400767 main.cleanup()
768 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800769 except Exception:
770 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab94282092014-10-10 13:00:11 -0400771 main.cleanup()
772 main.exit()
773
kelvin-onlabd3b64892015-01-20 13:26:24 -0800774 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800775 """
andrewonlab95ca1462014-10-09 14:04:24 -0400776 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800777 """
Hari Krishna03f530e2015-07-10 17:28:27 -0700778 import re
andrewonlab95ca1462014-10-09 14:04:24 -0400779 try:
780 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800781 main.log.error( "Must define cellname" )
andrewonlab95ca1462014-10-09 14:04:24 -0400782 main.cleanup()
783 main.exit()
784 else:
kelvin8ec71442015-01-15 16:57:00 -0800785 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800786 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800787 # Note that this variable name is subject to change
andrewonlab95ca1462014-10-09 14:04:24 -0400788 # and that this driver will have to change accordingly
Jon Hall3b489db2015-10-05 14:38:37 -0700789 self.handle.expect( str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800790 handleBefore = self.handle.before
791 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800792 # Get the rest of the handle
Jon Hall3b489db2015-10-05 14:38:37 -0700793 self.handle.expect( "\$" )
Jon Hall439c8912016-04-15 02:22:03 -0700794 time.sleep(10)
kelvin-onlabd3b64892015-01-20 13:26:24 -0800795 handleMore = self.handle.before
andrewonlab95ca1462014-10-09 14:04:24 -0400796
Hari Krishna03f530e2015-07-10 17:28:27 -0700797 cell_result = handleBefore + handleAfter + handleMore
suibin zhang116647a2016-05-06 16:30:09 -0700798 #print cell_result
Hari Krishna03f530e2015-07-10 17:28:27 -0700799 if( re.search( "No such cell", cell_result ) ):
800 main.log.error( "Cell call returned: " + handleBefore +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800801 handleAfter + handleMore )
Hari Krishna03f530e2015-07-10 17:28:27 -0700802 main.cleanup()
803 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400804 return main.TRUE
andrewonlab95ca1462014-10-09 14:04:24 -0400805 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800806 main.log.error( self.name + ": EOF exception found" )
807 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ca1462014-10-09 14:04:24 -0400808 main.cleanup()
809 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800810 except Exception:
811 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ca1462014-10-09 14:04:24 -0400812 main.cleanup()
813 main.exit()
814
kelvin-onlabd3b64892015-01-20 13:26:24 -0800815 def verifyCell( self ):
kelvin8ec71442015-01-15 16:57:00 -0800816 """
andrewonlabc03bf6c2014-10-09 14:56:18 -0400817 Calls 'onos-verify-cell' to check for cell installation
kelvin8ec71442015-01-15 16:57:00 -0800818 """
819 # TODO: Add meaningful expect value
andrewonlab8d0d7d72014-10-09 16:33:15 -0400820
andrewonlabc03bf6c2014-10-09 14:56:18 -0400821 try:
kelvin8ec71442015-01-15 16:57:00 -0800822 # Clean handle by sending empty and expecting $
823 self.handle.sendline( "" )
824 self.handle.expect( "\$" )
825 self.handle.sendline( "onos-verify-cell" )
826 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800827 handleBefore = self.handle.before
828 handleAfter = self.handle.after
kelvin-onlabd3b64892015-01-20 13:26:24 -0800829 main.log.info( "Verify cell returned: " + handleBefore +
Jon Hall3b489db2015-10-05 14:38:37 -0700830 handleAfter )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400831 return main.TRUE
Jon Halla5cb6172015-02-23 09:28:28 -0800832 except pexpect.ExceptionPexpect as e:
Jon Hall3b489db2015-10-05 14:38:37 -0700833 main.log.exception( self.name + ": Pexpect exception found: " )
kelvin8ec71442015-01-15 16:57:00 -0800834 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -0400835 main.cleanup()
836 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800837 except Exception:
838 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400839 main.cleanup()
840 main.exit()
841
jenkins1e99e7b2015-04-02 18:15:39 -0700842 def onosCfgSet( self, ONOSIp, configName, configParam ):
843 """
844 Uses 'onos <node-ip> cfg set' to change a parameter value of an
Jon Hall4ba53f02015-07-29 13:07:41 -0700845 application.
846
jenkins1e99e7b2015-04-02 18:15:39 -0700847 ex)
848 onos 10.0.0.1 cfg set org.onosproject.myapp appSetting 1
jenkins1e99e7b2015-04-02 18:15:39 -0700849 ONOSIp = '10.0.0.1'
850 configName = 'org.onosproject.myapp'
851 configParam = 'appSetting 1'
jenkins1e99e7b2015-04-02 18:15:39 -0700852 """
Jon Hall72280bc2016-01-25 14:29:05 -0800853 try:
854 cfgStr = "onos {} cfg set {} {}".format( ONOSIp,
855 configName,
856 configParam )
857 self.handle.sendline( "" )
858 self.handle.expect( ":~" )
859 self.handle.sendline( cfgStr )
860 self.handle.expect("cfg set")
861 self.handle.expect( ":~" )
jenkins1e99e7b2015-04-02 18:15:39 -0700862
Jon Hall72280bc2016-01-25 14:29:05 -0800863 paramValue = configParam.split(" ")[1]
864 paramName = configParam.split(" ")[0]
Jon Hall4ba53f02015-07-29 13:07:41 -0700865
Jon Hall72280bc2016-01-25 14:29:05 -0800866 checkStr = 'onos {} cfg get " {} {} " '.format( ONOSIp, configName, paramName )
Jon Hall4ba53f02015-07-29 13:07:41 -0700867
Jon Hall72280bc2016-01-25 14:29:05 -0800868 self.handle.sendline( checkStr )
869 self.handle.expect( ":~" )
jenkins1e99e7b2015-04-02 18:15:39 -0700870
Jon Hall72280bc2016-01-25 14:29:05 -0800871 if "value=" + paramValue + "," in self.handle.before:
872 main.log.info("cfg " + configName + " successfully set to " + configParam)
873 return main.TRUE
874 except pexpect.ExceptionPexpect as e:
875 main.log.exception( self.name + ": Pexpect exception found: " )
876 main.log.error( self.name + ": " + self.handle.before )
877 main.cleanup()
878 main.exit()
879 except Exception:
880 main.log.exception( self.name + ": Uncaught exception!" )
881 main.cleanup()
882 main.exit()
Jon Hall4ba53f02015-07-29 13:07:41 -0700883
kelvin-onlabd3b64892015-01-20 13:26:24 -0800884 def onosCli( self, ONOSIp, cmdstr ):
kelvin8ec71442015-01-15 16:57:00 -0800885 """
andrewonlab05e362f2014-10-10 00:40:57 -0400886 Uses 'onos' command to send various ONOS CLI arguments.
887 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800888 * ONOSIp: specify the ip of the cell machine
andrewonlab94282092014-10-10 13:00:11 -0400889 * cmdstr: specify the command string to send
kelvin8ec71442015-01-15 16:57:00 -0800890
891 This function is intended to expose the entire karaf
andrewonlab6e20c342014-10-10 18:08:48 -0400892 CLI commands for ONOS. Try to use this function first
893 before attempting to write a ONOS CLI specific driver
kelvin8ec71442015-01-15 16:57:00 -0800894 function.
895 You can see a list of available 'cmdstr' arguments
andrewonlab6e20c342014-10-10 18:08:48 -0400896 by starting onos, and typing in 'onos' to enter the
897 onos> CLI. Then, type 'help' to see the list of
kelvin8ec71442015-01-15 16:57:00 -0800898 available commands.
899 """
andrewonlab05e362f2014-10-10 00:40:57 -0400900 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800901 if not ONOSIp:
kelvin8ec71442015-01-15 16:57:00 -0800902 main.log.error( "You must specify the IP address" )
andrewonlab05e362f2014-10-10 00:40:57 -0400903 return main.FALSE
904 if not cmdstr:
kelvin8ec71442015-01-15 16:57:00 -0800905 main.log.error( "You must specify the command string" )
andrewonlab05e362f2014-10-10 00:40:57 -0400906 return main.FALSE
907
kelvin8ec71442015-01-15 16:57:00 -0800908 cmdstr = str( cmdstr )
909 self.handle.sendline( "" )
910 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400911
kelvin-onlabd3b64892015-01-20 13:26:24 -0800912 self.handle.sendline( "onos -w " + ONOSIp + " " + cmdstr )
kelvin8ec71442015-01-15 16:57:00 -0800913 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400914
kelvin-onlabd3b64892015-01-20 13:26:24 -0800915 handleBefore = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -0800916 main.log.info( "Command sent successfully" )
kelvin8ec71442015-01-15 16:57:00 -0800917 # Obtain return handle that consists of result from
918 # the onos command. The string may need to be
919 # configured further.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800920 returnString = handleBefore
kelvin-onlabd3b64892015-01-20 13:26:24 -0800921 return returnString
andrewonlab05e362f2014-10-10 00:40:57 -0400922 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800923 main.log.error( self.name + ": EOF exception found" )
924 main.log.error( self.name + ": " + self.handle.before )
andrewonlab05e362f2014-10-10 00:40:57 -0400925 main.cleanup()
926 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800927 except Exception:
928 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab05e362f2014-10-10 00:40:57 -0400929 main.cleanup()
930 main.exit()
Jon Hall7993bfc2014-10-09 16:30:14 -0400931
kelvin-onlabd3b64892015-01-20 13:26:24 -0800932 def onosInstall( self, options="-f", node="" ):
kelvin8ec71442015-01-15 16:57:00 -0800933 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400934 Installs ONOS bits on the designated cell machine.
kelvin8ec71442015-01-15 16:57:00 -0800935 If -f option is provided, it also forces an uninstall.
936 Presently, install also includes onos-push-bits and
Jon Hall7993bfc2014-10-09 16:30:14 -0400937 onos-config within.
kelvin8ec71442015-01-15 16:57:00 -0800938 The node option allows you to selectively only push the jar
Jon Hall7993bfc2014-10-09 16:30:14 -0400939 files to certain onos nodes
940
941 Returns: main.TRUE on success and main.FALSE on failure
kelvin8ec71442015-01-15 16:57:00 -0800942 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400943 try:
andrewonlab114768a2014-11-14 12:44:44 -0500944 if options:
kelvin8ec71442015-01-15 16:57:00 -0800945 self.handle.sendline( "onos-install " + options + " " + node )
andrewonlab114768a2014-11-14 12:44:44 -0500946 else:
kelvin8ec71442015-01-15 16:57:00 -0800947 self.handle.sendline( "onos-install " + node )
948 self.handle.expect( "onos-install " )
949 # NOTE: this timeout may need to change depending on the network
950 # and size of ONOS
951 i = self.handle.expect( [ "Network\sis\sunreachable",
kelvin-onlabd3b64892015-01-20 13:26:24 -0800952 "onos\sstart/running,\sprocess",
kelvin8ec71442015-01-15 16:57:00 -0800953 "ONOS\sis\salready\sinstalled",
Jeremyc72b2582016-02-26 18:27:38 -0800954 "already\sup-to-date",
955 "\$",
Jon Hall6c44c0b2016-04-20 15:21:00 -0700956 pexpect.TIMEOUT ], timeout=180 )
Jon Hall7993bfc2014-10-09 16:30:14 -0400957 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800958 main.log.warn( "Network is unreachable" )
Jon Hall3b489db2015-10-05 14:38:37 -0700959 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400960 return main.FALSE
961 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800962 main.log.info(
963 "ONOS was installed on " +
964 node +
965 " and started" )
Jon Hall3b489db2015-10-05 14:38:37 -0700966 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400967 return main.TRUE
andrewonlabd9a73a72014-11-14 17:28:21 -0500968 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800969 main.log.info( "ONOS is already installed on " + node )
Jon Hall3b489db2015-10-05 14:38:37 -0700970 self.handle.expect( "\$" )
andrewonlabd9a73a72014-11-14 17:28:21 -0500971 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800972 elif i == 3:
Jeremyc72b2582016-02-26 18:27:38 -0800973 main.log.info( "ONOS is already installed on " + node )
974 self.handle.expect( "\$" )
975 return main.TRUE
976 elif i == 4:
977 main.log.info( "ONOS was installed on " + node )
978 return main.TRUE
979 elif i == 5:
kelvin8ec71442015-01-15 16:57:00 -0800980 main.log.info(
981 "Installation of ONOS on " +
982 node +
983 " timed out" )
Jon Hall3b489db2015-10-05 14:38:37 -0700984 self.handle.expect( "\$" )
Jon Hall53c5e662016-04-13 16:06:56 -0700985 main.log.warn( self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -0400986 return main.FALSE
andrewonlabc03bf6c2014-10-09 14:56:18 -0400987 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800988 main.log.error( self.name + ": EOF exception found" )
989 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400990 main.cleanup()
991 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800992 except Exception:
993 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400994 main.cleanup()
995 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400996
kelvin-onlabd3b64892015-01-20 13:26:24 -0800997 def onosStart( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800998 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400999 Calls onos command: 'onos-service [<node-ip>] start'
andrewonlabe8e56fd2014-10-09 17:12:44 -04001000 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -08001001 """
andrewonlab8d0d7d72014-10-09 16:33:15 -04001002 try:
kelvin8ec71442015-01-15 16:57:00 -08001003 self.handle.sendline( "" )
1004 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001005 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001006 " start" )
1007 i = self.handle.expect( [
andrewonlab8d0d7d72014-10-09 16:33:15 -04001008 "Job\sis\salready\srunning",
1009 "start/running",
Jeremyd0e9a6d2016-03-02 11:28:52 -08001010 "\$",
andrewonlab8d0d7d72014-10-09 16:33:15 -04001011 "Unknown\sinstance",
Jeremy Songster14c13572016-04-21 17:34:03 -07001012 pexpect.TIMEOUT ], timeout=180 )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001013 if i == 0:
Jon Halleab7a242016-03-04 10:20:43 -08001014 self.handle.expect( "\$" )
kelvin8ec71442015-01-15 16:57:00 -08001015 main.log.info( "Service is already running" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001016 return main.TRUE
1017 elif i == 1:
Jon Halleab7a242016-03-04 10:20:43 -08001018 self.handle.expect( "\$" )
kelvin8ec71442015-01-15 16:57:00 -08001019 main.log.info( "ONOS service started" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001020 return main.TRUE
Jeremyd0e9a6d2016-03-02 11:28:52 -08001021 elif i == 2:
1022 main.log.info( "ONOS service started" )
1023 return main.TRUE
andrewonlab8d0d7d72014-10-09 16:33:15 -04001024 else:
Jon Halleab7a242016-03-04 10:20:43 -08001025 self.handle.expect( "\$" )
kelvin8ec71442015-01-15 16:57:00 -08001026 main.log.error( "ONOS service failed to start" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001027 main.cleanup()
1028 main.exit()
andrewonlab8d0d7d72014-10-09 16:33:15 -04001029 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001030 main.log.error( self.name + ": EOF exception found" )
1031 main.log.error( self.name + ": " + self.handle.before )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001032 main.cleanup()
1033 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001034 except Exception:
1035 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001036 main.cleanup()
1037 main.exit()
1038
kelvin-onlabd3b64892015-01-20 13:26:24 -08001039 def onosStop( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001040 """
andrewonlab2b30bd32014-10-09 16:48:55 -04001041 Calls onos command: 'onos-service [<node-ip>] stop'
andrewonlabe8e56fd2014-10-09 17:12:44 -04001042 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -08001043 """
andrewonlab2b30bd32014-10-09 16:48:55 -04001044 try:
kelvin8ec71442015-01-15 16:57:00 -08001045 self.handle.sendline( "" )
1046 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001047 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001048 " stop" )
1049 i = self.handle.expect( [
andrewonlab2b30bd32014-10-09 16:48:55 -04001050 "stop/waiting",
Jon Hall61282e32015-03-19 11:34:11 -07001051 "Could not resolve hostname",
andrewonlab2b30bd32014-10-09 16:48:55 -04001052 "Unknown\sinstance",
YPZhang77badfc2016-03-09 10:28:59 -08001053 "\$",
Jeremy Songster14c13572016-04-21 17:34:03 -07001054 pexpect.TIMEOUT ], timeout=180 )
andrewonlab2b30bd32014-10-09 16:48:55 -04001055 if i == 0:
YPZhang77badfc2016-03-09 10:28:59 -08001056 self.handle.expect( "\$" )
kelvin8ec71442015-01-15 16:57:00 -08001057 main.log.info( "ONOS service stopped" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001058 return main.TRUE
1059 elif i == 1:
YPZhang77badfc2016-03-09 10:28:59 -08001060 self.handle.expect( "\$" )
Jon Hall65844a32015-03-09 19:09:37 -07001061 main.log.info( "onosStop() Unknown ONOS instance specified: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001062 str( nodeIp ) )
andrewonlab2b30bd32014-10-09 16:48:55 -04001063 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -07001064 elif i == 2:
YPZhang77badfc2016-03-09 10:28:59 -08001065 self.handle.expect( "\$" )
Jon Hall61282e32015-03-19 11:34:11 -07001066 main.log.warn( "ONOS wasn't running" )
1067 return main.TRUE
YPZhang77badfc2016-03-09 10:28:59 -08001068 elif i == 3:
1069 main.log.info( "ONOS service stopped" )
1070 return main.TRUE
andrewonlab2b30bd32014-10-09 16:48:55 -04001071 else:
kelvin8ec71442015-01-15 16:57:00 -08001072 main.log.error( "ONOS service failed to stop" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001073 return main.FALSE
andrewonlab2b30bd32014-10-09 16:48:55 -04001074 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001075 main.log.error( self.name + ": EOF exception found" )
1076 main.log.error( self.name + ": " + self.handle.before )
andrewonlab2b30bd32014-10-09 16:48:55 -04001077 main.cleanup()
1078 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001079 except Exception:
1080 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001081 main.cleanup()
1082 main.exit()
kelvin8ec71442015-01-15 16:57:00 -08001083
kelvin-onlabd3b64892015-01-20 13:26:24 -08001084 def onosUninstall( self, nodeIp="" ):
kelvin8ec71442015-01-15 16:57:00 -08001085 """
andrewonlabc8d47972014-10-09 16:52:36 -04001086 Calls the command: 'onos-uninstall'
kelvin8ec71442015-01-15 16:57:00 -08001087 Uninstalls ONOS from the designated cell machine, stopping
andrewonlabe8e56fd2014-10-09 17:12:44 -04001088 if needed
kelvin8ec71442015-01-15 16:57:00 -08001089 """
andrewonlabc8d47972014-10-09 16:52:36 -04001090 try:
kelvin8ec71442015-01-15 16:57:00 -08001091 self.handle.sendline( "" )
Jeremy Songster14c13572016-04-21 17:34:03 -07001092 self.handle.expect( "\$", timeout=180 )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001093 self.handle.sendline( "onos-uninstall " + str( nodeIp ) )
Jeremy Songster14c13572016-04-21 17:34:03 -07001094 self.handle.expect( "\$", timeout=180 )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001095 main.log.info( "ONOS " + nodeIp + " was uninstalled" )
kelvin8ec71442015-01-15 16:57:00 -08001096 # onos-uninstall command does not return any text
andrewonlabc8d47972014-10-09 16:52:36 -04001097 return main.TRUE
pingping-lin763ee042015-05-20 17:45:30 -07001098 except pexpect.TIMEOUT:
1099 main.log.exception( self.name + ": Timeout in onosUninstall" )
1100 return main.FALSE
andrewonlabc8d47972014-10-09 16:52:36 -04001101 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001102 main.log.error( self.name + ": EOF exception found" )
1103 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc8d47972014-10-09 16:52:36 -04001104 main.cleanup()
1105 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001106 except Exception:
1107 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc8d47972014-10-09 16:52:36 -04001108 main.cleanup()
1109 main.exit()
andrewonlab2b30bd32014-10-09 16:48:55 -04001110
kelvin-onlabd3b64892015-01-20 13:26:24 -08001111 def onosDie( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001112 """
andrewonlabaedc8332014-12-04 12:43:03 -05001113 Issues the command 'onos-die <node-ip>'
1114 This command calls onos-kill and also stops the node
kelvin8ec71442015-01-15 16:57:00 -08001115 """
andrewonlabaedc8332014-12-04 12:43:03 -05001116 try:
kelvin8ec71442015-01-15 16:57:00 -08001117 self.handle.sendline( "" )
1118 self.handle.expect( "\$" )
Jeremyf0aecdb2016-03-30 13:19:57 -07001119 cmdStr = "onos-die " + str( nodeIp )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001120 self.handle.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -08001121 i = self.handle.expect( [
andrewonlabaedc8332014-12-04 12:43:03 -05001122 "Killing\sONOS",
1123 "ONOS\sprocess\sis\snot\srunning",
Jeremy Songster14c13572016-04-21 17:34:03 -07001124 pexpect.TIMEOUT ], timeout=60 )
andrewonlabaedc8332014-12-04 12:43:03 -05001125 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001126 main.log.info( "ONOS instance " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001127 " was killed and stopped" )
Jon Hall53c5e662016-04-13 16:06:56 -07001128 self.handle.sendline( "" )
1129 self.handle.expect( "\$" )
andrewonlabaedc8332014-12-04 12:43:03 -05001130 return main.TRUE
1131 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001132 main.log.info( "ONOS process was not running" )
Jon Hall53c5e662016-04-13 16:06:56 -07001133 self.handle.sendline( "" )
1134 self.handle.expect( "\$" )
andrewonlabaedc8332014-12-04 12:43:03 -05001135 return main.FALSE
1136 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001137 main.log.error( self.name + ": EOF exception found" )
1138 main.log.error( self.name + ": " + self.handle.before )
andrewonlabaedc8332014-12-04 12:43:03 -05001139 main.cleanup()
1140 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001141 except Exception:
1142 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabaedc8332014-12-04 12:43:03 -05001143 main.cleanup()
1144 main.exit()
1145
kelvin-onlabd3b64892015-01-20 13:26:24 -08001146 def onosKill( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001147 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001148 Calls the command: 'onos-kill [<node-ip>]'
1149 "Remotely, and unceremoniously kills the ONOS instance running on
1150 the specified cell machine" - Tom V
kelvin8ec71442015-01-15 16:57:00 -08001151 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001152 try:
kelvin8ec71442015-01-15 16:57:00 -08001153 self.handle.sendline( "" )
1154 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001155 self.handle.sendline( "onos-kill " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -08001156 i = self.handle.expect( [
andrewonlabe8e56fd2014-10-09 17:12:44 -04001157 "\$",
1158 "No\sroute\sto\shost",
1159 "password:",
Jeremy Songster14c13572016-04-21 17:34:03 -07001160 pexpect.TIMEOUT ], timeout=60 )
kelvin8ec71442015-01-15 16:57:00 -08001161
andrewonlabe8e56fd2014-10-09 17:12:44 -04001162 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001163 main.log.info(
1164 "ONOS instance " + str(
kelvin-onlabd3b64892015-01-20 13:26:24 -08001165 nodeIp ) + " was killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001166 return main.TRUE
1167 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001168 main.log.info( "No route to host" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001169 return main.FALSE
1170 elif i == 2:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001171 main.log.info(
1172 "Passwordless login for host: " +
1173 str( nodeIp ) +
1174 " not configured" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001175 return main.FALSE
1176 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001177 main.log.info( "ONOS instance was not killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001178 return main.FALSE
kelvin8ec71442015-01-15 16:57:00 -08001179
andrewonlabe8e56fd2014-10-09 17:12:44 -04001180 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001181 main.log.error( self.name + ": EOF exception found" )
1182 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001183 main.cleanup()
1184 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001185 except Exception:
1186 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001187 main.cleanup()
1188 main.exit()
1189
kelvin-onlabd3b64892015-01-20 13:26:24 -08001190 def onosRemoveRaftLogs( self ):
kelvin8ec71442015-01-15 16:57:00 -08001191 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001192 Removes Raft / Copy cat files from ONOS to ensure
Jon Hallfcc88622014-11-25 13:09:54 -05001193 a cleaner environment.
1194
andrewonlab19fbdca2014-11-14 12:55:59 -05001195 Description:
Jon Hallfcc88622014-11-25 13:09:54 -05001196 Stops all ONOS defined in the cell,
andrewonlab19fbdca2014-11-14 12:55:59 -05001197 wipes the raft / copycat log files
kelvin8ec71442015-01-15 16:57:00 -08001198 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001199 try:
kelvin8ec71442015-01-15 16:57:00 -08001200 self.handle.sendline( "" )
1201 self.handle.expect( "\$" )
1202 self.handle.sendline( "onos-remove-raft-logs" )
1203 # Sometimes this command hangs
1204 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
1205 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001206 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001207 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
1208 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001209 if i == 1:
1210 return main.FALSE
andrewonlab19fbdca2014-11-14 12:55:59 -05001211 return main.TRUE
andrewonlab19fbdca2014-11-14 12:55:59 -05001212 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001213 main.log.error( self.name + ": EOF exception found" )
1214 main.log.error( self.name + ": " + self.handle.before )
andrewonlab19fbdca2014-11-14 12:55:59 -05001215 main.cleanup()
1216 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001217 except Exception:
1218 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab19fbdca2014-11-14 12:55:59 -05001219 main.cleanup()
1220 main.exit()
Jon Hallfcc88622014-11-25 13:09:54 -05001221
kelvin-onlabd3b64892015-01-20 13:26:24 -08001222 def onosStartNetwork( self, mntopo ):
kelvin8ec71442015-01-15 16:57:00 -08001223 """
1224 Calls the command 'onos-start-network [ <mininet-topo> ]
1225 "remotely starts the specified topology on the cell's
andrewonlab94282092014-10-10 13:00:11 -04001226 mininet machine against all controllers configured in the
kelvin8ec71442015-01-15 16:57:00 -08001227 cell."
andrewonlab94282092014-10-10 13:00:11 -04001228 * Specify mininet topology file name for mntopo
1229 * Topo files should be placed at:
1230 ~/<your-onos-directory>/tools/test/topos
kelvin8ec71442015-01-15 16:57:00 -08001231
andrewonlab94282092014-10-10 13:00:11 -04001232 NOTE: This function will take you to the mininet prompt
kelvin8ec71442015-01-15 16:57:00 -08001233 """
andrewonlab94282092014-10-10 13:00:11 -04001234 try:
1235 if not mntopo:
kelvin8ec71442015-01-15 16:57:00 -08001236 main.log.error( "You must specify a topo file to execute" )
andrewonlab94282092014-10-10 13:00:11 -04001237 return main.FALSE
andrewonlab94282092014-10-10 13:00:11 -04001238
kelvin8ec71442015-01-15 16:57:00 -08001239 mntopo = str( mntopo )
1240 self.handle.sendline( "" )
1241 self.handle.expect( "\$" )
andrewonlab94282092014-10-10 13:00:11 -04001242
kelvin8ec71442015-01-15 16:57:00 -08001243 self.handle.sendline( "onos-start-network " + mntopo )
1244 self.handle.expect( "mininet>" )
1245 main.log.info( "Network started, entered mininet prompt" )
1246
1247 # TODO: Think about whether return is necessary or not
andrewonlab94282092014-10-10 13:00:11 -04001248
1249 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001250 main.log.error( self.name + ": EOF exception found" )
1251 main.log.error( self.name + ": " + self.handle.before )
andrewonlab94282092014-10-10 13:00:11 -04001252 main.cleanup()
1253 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001254 except Exception:
1255 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab94282092014-10-10 13:00:11 -04001256 main.cleanup()
1257 main.exit()
1258
Jeremy Songster14c13572016-04-21 17:34:03 -07001259 def isup( self, node="", timeout=240 ):
kelvin8ec71442015-01-15 16:57:00 -08001260 """
1261 Run's onos-wait-for-start which only returns once ONOS is at run
Cameron Franke9c94fb02015-01-21 10:20:20 -08001262 level 100(ready for use)
andrewonlab8d0d7d72014-10-09 16:33:15 -04001263
Jon Hall7993bfc2014-10-09 16:30:14 -04001264 Returns: main.TRUE if ONOS is running and main.FALSE on timeout
kelvin8ec71442015-01-15 16:57:00 -08001265 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001266 try:
Jon Hall3b489db2015-10-05 14:38:37 -07001267 self.handle.sendline( "onos-wait-for-start " + node )
1268 self.handle.expect( "onos-wait-for-start" )
kelvin8ec71442015-01-15 16:57:00 -08001269 # NOTE: this timeout is arbitrary"
Cameron Franke9c94fb02015-01-21 10:20:20 -08001270 i = self.handle.expect(["\$", pexpect.TIMEOUT], timeout)
Jon Hall7993bfc2014-10-09 16:30:14 -04001271 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001272 main.log.info( self.name + ": " + node + " is up" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001273 return main.TRUE
1274 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001275 # NOTE: since this function won't return until ONOS is ready,
Jon Hall7993bfc2014-10-09 16:30:14 -04001276 # we will kill it on timeout
kelvin8ec71442015-01-15 16:57:00 -08001277 main.log.error( "ONOS has not started yet" )
1278 self.handle.send( "\x03" ) # Control-C
1279 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001280 return main.FALSE
1281 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001282 main.log.error( self.name + ": EOF exception found" )
1283 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -04001284 main.cleanup()
1285 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001286 except Exception:
1287 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001288 main.cleanup()
1289 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001290
kelvin-onlabd3b64892015-01-20 13:26:24 -08001291 def pushTestIntentsShell(
1292 self,
1293 dpidSrc,
1294 dpidDst,
1295 numIntents,
1296 dirFile,
1297 onosIp,
1298 numMult="",
1299 appId="",
1300 report=True,
1301 options="" ):
kelvin8ec71442015-01-15 16:57:00 -08001302 """
andrewonlabb66dfa12014-12-02 15:51:10 -05001303 Description:
kelvin8ec71442015-01-15 16:57:00 -08001304 Use the linux prompt to push test intents to
andrewonlabb66dfa12014-12-02 15:51:10 -05001305 better parallelize the results than the CLI
1306 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001307 * dpidSrc: specify source dpid
1308 * dpidDst: specify destination dpid
1309 * numIntents: specify number of intents to push
1310 * dirFile: specify directory and file name to save
andrewonlabb66dfa12014-12-02 15:51:10 -05001311 results
kelvin-onlabd3b64892015-01-20 13:26:24 -08001312 * onosIp: specify the IP of ONOS to install on
kelvin8ec71442015-01-15 16:57:00 -08001313 NOTE:
andrewonlabb66dfa12014-12-02 15:51:10 -05001314 You must invoke this command at linux shell prompt
kelvin8ec71442015-01-15 16:57:00 -08001315 """
1316 try:
1317 # Create the string to sendline
andrewonlabaedc8332014-12-04 12:43:03 -05001318 if options:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001319 baseCmd = "onos " + str( onosIp ) + " push-test-intents " +\
kelvin8ec71442015-01-15 16:57:00 -08001320 options + " "
andrewonlabaedc8332014-12-04 12:43:03 -05001321 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001322 baseCmd = "onos " + str( onosIp ) + " push-test-intents "
kelvin8ec71442015-01-15 16:57:00 -08001323
kelvin-onlabd3b64892015-01-20 13:26:24 -08001324 addDpid = baseCmd + str( dpidSrc ) + " " + str( dpidDst )
1325 if not numMult:
1326 addIntents = addDpid + " " + str( numIntents )
1327 elif numMult:
1328 addIntents = addDpid + " " + str( numIntents ) + " " +\
1329 str( numMult )
1330 if appId:
1331 addApp = addIntents + " " + str( appId )
andrewonlabb66dfa12014-12-02 15:51:10 -05001332 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001333 addApp = addIntents
andrewonlabb66dfa12014-12-02 15:51:10 -05001334
andrewonlabaedc8332014-12-04 12:43:03 -05001335 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001336 sendCmd = addApp + " > " + str( dirFile ) + " &"
andrewonlabaedc8332014-12-04 12:43:03 -05001337 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001338 sendCmd = addApp + " &"
1339 main.log.info( "Send cmd: " + sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001340
kelvin-onlabd3b64892015-01-20 13:26:24 -08001341 self.handle.sendline( sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001342
1343 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001344 main.log.error( self.name + ": EOF exception found" )
1345 main.log.error( self.name + ": " + self.handle.before )
andrewonlabb66dfa12014-12-02 15:51:10 -05001346 main.cleanup()
1347 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001348 except Exception:
1349 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabb66dfa12014-12-02 15:51:10 -05001350 main.cleanup()
kelvin8ec71442015-01-15 16:57:00 -08001351 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001352
kelvin-onlabd3b64892015-01-20 13:26:24 -08001353 def tsharkPcap( self, interface, dirFile ):
kelvin8ec71442015-01-15 16:57:00 -08001354 """
andrewonlab970399c2014-11-07 13:09:32 -05001355 Capture all packet activity and store in specified
1356 directory/file
1357
1358 Required:
1359 * interface: interface to capture
1360 * dir: directory/filename to store pcap
kelvin8ec71442015-01-15 16:57:00 -08001361 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001362 try:
1363 self.handle.sendline( "" )
1364 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001365
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001366 self.handle.sendline( "tshark -i " + str( interface ) + " -t e -w " + str( dirFile ) + " &" )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001367 self.handle.sendline( "\n" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001368 self.handle.expect( "Capturing on" )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001369 self.handle.sendline( "\n" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001370 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001371
Jon Hallfebb1c72015-03-05 13:30:09 -08001372 main.log.info( "Tshark started capturing files on " +
1373 str( interface ) + " and saving to directory: " +
1374 str( dirFile ) )
1375 except pexpect.EOF:
1376 main.log.error( self.name + ": EOF exception found" )
1377 main.log.error( self.name + ": " + self.handle.before )
1378 main.cleanup()
1379 main.exit()
1380 except Exception:
1381 main.log.exception( self.name + ": Uncaught exception!" )
1382 main.cleanup()
1383 main.exit()
Shreya Shaha73aaad2014-10-27 18:03:09 -04001384
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001385 def onosTopoCfg( self, onosIp, jsonFile ):
kelvin8ec71442015-01-15 16:57:00 -08001386 """
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001387 Description:
1388 Execute onos-topo-cfg command
1389 Required:
1390 onosIp - IP of the onos node you want to send the json to
1391 jsonFile - File path of the json file
1392 Return:
1393 Returns main.TRUE if the command is successfull; Returns
1394 main.FALSE if there was an error
kelvin8ec71442015-01-15 16:57:00 -08001395 """
shahshreyae6c7cf42014-11-26 16:39:01 -08001396 try:
kelvin8ec71442015-01-15 16:57:00 -08001397 self.handle.sendline( "" )
1398 self.handle.expect( "\$" )
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001399 cmd = "onos-topo-cfg "
1400 self.handle.sendline( cmd + str( onosIp ) + " " + jsonFile )
1401 handle = self.handle.before
1402 print handle
1403 if "Error" in handle:
1404 main.log.error( self.name + ": " + self.handle.before )
1405 return main.FALSE
1406 else:
1407 self.handle.expect( "\$" )
1408 return main.TRUE
1409
Jon Hallfebb1c72015-03-05 13:30:09 -08001410 except pexpect.EOF:
1411 main.log.error( self.name + ": EOF exception found" )
1412 main.log.error( self.name + ": " + self.handle.before )
1413 main.cleanup()
1414 main.exit()
1415 except Exception:
1416 main.log.exception( self.name + ": Uncaught exception!" )
1417 main.cleanup()
1418 main.exit()
kelvin8ec71442015-01-15 16:57:00 -08001419
jenkins1e99e7b2015-04-02 18:15:39 -07001420 def tsharkGrep( self, grep, directory, interface='eth0', grepOptions='' ):
kelvin8ec71442015-01-15 16:57:00 -08001421 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001422 Required:
kelvin8ec71442015-01-15 16:57:00 -08001423 * grep string
andrewonlabba44bcf2014-10-16 16:54:41 -04001424 * directory to store results
1425 Optional:
1426 * interface - default: eth0
Jon Hall4ba53f02015-07-29 13:07:41 -07001427 * grepOptions - options for grep
andrewonlabba44bcf2014-10-16 16:54:41 -04001428 Description:
1429 Uses tshark command to grep specific group of packets
1430 and stores the results to specified directory.
kelvin8ec71442015-01-15 16:57:00 -08001431 The timestamp is hardcoded to be in epoch
1432 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001433 try:
1434 self.handle.sendline( "" )
1435 self.handle.expect( "\$" )
1436 self.handle.sendline( "" )
jenkins1e99e7b2015-04-02 18:15:39 -07001437 if grepOptions:
1438 grepStr = "grep "+str(grepOptions)
1439 else:
1440 grepStr = "grep"
Jon Hall4ba53f02015-07-29 13:07:41 -07001441
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001442 cmd = (
1443 "sudo tshark -i " +
Jon Hallfebb1c72015-03-05 13:30:09 -08001444 str( interface ) +
jenkins1e99e7b2015-04-02 18:15:39 -07001445 " -t e | " +
1446 grepStr + " --line-buffered \"" +
Jon Hallfebb1c72015-03-05 13:30:09 -08001447 str(grep) +
1448 "\" >" +
1449 directory +
1450 " &" )
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001451 self.handle.sendline(cmd)
1452 main.log.info(cmd)
Jon Hallfebb1c72015-03-05 13:30:09 -08001453 self.handle.expect( "Capturing on" )
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001454 self.handle.sendline( "\n" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001455 self.handle.expect( "\$" )
1456 except pexpect.EOF:
1457 main.log.error( self.name + ": EOF exception found" )
1458 main.log.error( self.name + ": " + self.handle.before )
1459 main.cleanup()
1460 main.exit()
1461 except Exception:
1462 main.log.exception( self.name + ": Uncaught exception!" )
1463 main.cleanup()
1464 main.exit()
1465
kelvin-onlabd3b64892015-01-20 13:26:24 -08001466 def tsharkStop( self ):
kelvin8ec71442015-01-15 16:57:00 -08001467 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001468 Removes wireshark files from /tmp and kills all tshark processes
kelvin8ec71442015-01-15 16:57:00 -08001469 """
1470 # Remove all pcap from previous captures
Jon Hallfebb1c72015-03-05 13:30:09 -08001471 try:
1472 self.execute( cmd="sudo rm /tmp/wireshark*" )
1473 self.handle.sendline( "" )
Jon Hallefbd9792015-03-05 16:11:36 -08001474 self.handle.sendline( "sudo kill -9 `ps -ef | grep \"tshark -i\"" +
1475 " | grep -v grep | awk '{print $2}'`" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001476 self.handle.sendline( "" )
1477 main.log.info( "Tshark stopped" )
1478 except pexpect.EOF:
1479 main.log.error( self.name + ": EOF exception found" )
1480 main.log.error( self.name + ": " + self.handle.before )
1481 main.cleanup()
1482 main.exit()
1483 except Exception:
1484 main.log.exception( self.name + ": Uncaught exception!" )
1485 main.cleanup()
1486 main.exit()
1487
kelvin8ec71442015-01-15 16:57:00 -08001488 def ptpd( self, args ):
1489 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001490 Initiate ptp with user-specified args.
1491 Required:
1492 * args: specify string of args after command
1493 'sudo ptpd'
kelvin8ec71442015-01-15 16:57:00 -08001494 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001495 try:
kelvin8ec71442015-01-15 16:57:00 -08001496 self.handle.sendline( "sudo ptpd " + str( args ) )
1497 i = self.handle.expect( [
andrewonlab0c38a4a2014-10-28 18:35:35 -04001498 "Multiple",
1499 "Error",
kelvin8ec71442015-01-15 16:57:00 -08001500 "\$" ] )
1501 self.handle.expect( "\$" )
andrewonlabba44bcf2014-10-16 16:54:41 -04001502
andrewonlab0c38a4a2014-10-28 18:35:35 -04001503 if i == 0:
1504 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001505 main.log.info( "ptpd returned an error: " +
1506 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001507 return handle
1508 elif i == 1:
1509 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001510 main.log.error( "ptpd returned an error: " +
1511 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001512 return handle
1513 else:
1514 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -08001515
andrewonlab0c38a4a2014-10-28 18:35:35 -04001516 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001517 main.log.error( self.name + ": EOF exception found" )
1518 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001519 main.cleanup()
1520 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001521 except Exception:
1522 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001523 main.cleanup()
1524 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001525
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001526 def dumpFlows(self,ONOSIp, destDir, filename="flows" ):
1527 """
1528 Dump Flow Tables to a desired directory.
1529 For debugging purposes, you may want to use
1530 this function to capture flows at a given point in time.
1531 Localtime will be attached to the filename
1532
1533 Required:
1534 * ONOSIp: the IP of the target ONOS instance
1535 * destDir: specify directory to copy to.
1536 ex ) /tmp/
1537 Optional:
1538 * fileName: Name of the file
1539 """
1540
1541 localtime = time.strftime( '%x %X' )
1542 localtime = localtime.replace( "/", "" )
1543 localtime = localtime.replace( " ", "_" )
1544 localtime = localtime.replace( ":", "" )
1545 if destDir[ -1: ] != "/":
1546 destDir += "/"
1547 cmd="flows > "+ str( destDir ) + str( filename ) + localtime
1548 return self.onosCli(ONOSIp,cmd)
1549
kelvin-onlabd3b64892015-01-20 13:26:24 -08001550 def cpLogsToDir( self, logToCopy,
Jon Hallefbd9792015-03-05 16:11:36 -08001551 destDir, copyFileName="" ):
kelvin8ec71442015-01-15 16:57:00 -08001552 """
1553 Copies logs to a desired directory.
andrewonlab5d7a8f32014-11-10 13:07:56 -05001554 Current implementation of ONOS deletes its karaf
1555 logs on every iteration. For debugging purposes,
kelvin8ec71442015-01-15 16:57:00 -08001556 you may want to use this function to capture
1557 certain karaf logs. ( or any other logs if needed )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001558 Localtime will be attached to the filename
1559
1560 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001561 * logToCopy: specify directory and log name to
andrewonlab5d7a8f32014-11-10 13:07:56 -05001562 copy.
kelvin8ec71442015-01-15 16:57:00 -08001563 ex ) /opt/onos/log/karaf.log.1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001564 For copying multiple files, leave copyFileName
1565 empty and only specify destDir -
kelvin8ec71442015-01-15 16:57:00 -08001566 ex ) /opt/onos/log/karaf*
kelvin-onlabd3b64892015-01-20 13:26:24 -08001567 * destDir: specify directory to copy to.
kelvin8ec71442015-01-15 16:57:00 -08001568 ex ) /tmp/
1569 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001570 * copyFileName: If you want to rename the log
1571 file, specify copyFileName. This will not work
andrewonlab5d7a8f32014-11-10 13:07:56 -05001572 with multiple file copying
kelvin8ec71442015-01-15 16:57:00 -08001573 """
andrewonlab5d7a8f32014-11-10 13:07:56 -05001574 try:
kelvin8ec71442015-01-15 16:57:00 -08001575 localtime = time.strftime( '%x %X' )
1576 localtime = localtime.replace( "/", "" )
1577 localtime = localtime.replace( " ", "_" )
1578 localtime = localtime.replace( ":", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001579 if destDir[ -1: ] != "/":
1580 destDir += "/"
andrewonlab5d7a8f32014-11-10 13:07:56 -05001581
kelvin-onlabd3b64892015-01-20 13:26:24 -08001582 if copyFileName:
Jon Hallfebb1c72015-03-05 13:30:09 -08001583 self.handle.sendline( "cp " + str( logToCopy ) + " " +
1584 str( destDir ) + str( copyFileName ) +
1585 localtime )
kelvin8ec71442015-01-15 16:57:00 -08001586 self.handle.expect( "cp" )
1587 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001588 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001589 self.handle.sendline( "cp " + str( logToCopy ) +
1590 " " + str( destDir ) )
kelvin8ec71442015-01-15 16:57:00 -08001591 self.handle.expect( "cp" )
1592 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001593
kelvin8ec71442015-01-15 16:57:00 -08001594 return self.handle.before
1595
1596 except pexpect.EOF:
1597 main.log.error( "Copying files failed" )
1598 main.log.error( self.name + ": EOF exception found" )
1599 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001600 except Exception:
1601 main.log.exception( "Copying files failed" )
1602
Jon Hall16b72c42015-05-20 10:23:36 -07001603 def checkLogs( self, onosIp, restart=False):
kelvin8ec71442015-01-15 16:57:00 -08001604 """
Jon Hall94fd0472014-12-08 11:52:42 -08001605 runs onos-check-logs on the given onos node
Jon Hall80daded2015-05-27 16:07:00 -07001606 If restart is True, use the old version of onos-check-logs which
1607 does not print the full stacktrace, but shows the entire log file,
1608 including across restarts
Jon Hall94fd0472014-12-08 11:52:42 -08001609 returns the response
kelvin8ec71442015-01-15 16:57:00 -08001610 """
Jon Hall94fd0472014-12-08 11:52:42 -08001611 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001612 cmd = "onos-check-logs " + str( onosIp )
Jon Hall16b72c42015-05-20 10:23:36 -07001613 if restart:
1614 cmd += " old"
kelvin8ec71442015-01-15 16:57:00 -08001615 self.handle.sendline( cmd )
1616 self.handle.expect( cmd )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001617 self.handle.expect( "\$ " )
Jon Hall94fd0472014-12-08 11:52:42 -08001618 response = self.handle.before
1619 return response
1620 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001621 main.log.error( "Lost ssh connection" )
1622 main.log.error( self.name + ": EOF exception found" )
1623 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001624 except Exception:
1625 main.log.exception( self.name + ": Uncaught exception!" )
1626 main.cleanup()
1627 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -08001628
kelvin-onlabd3b64892015-01-20 13:26:24 -08001629 def onosStatus( self, node="" ):
kelvin8ec71442015-01-15 16:57:00 -08001630 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001631 Calls onos command: 'onos-service [<node-ip>] status'
kelvin8ec71442015-01-15 16:57:00 -08001632 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001633 try:
kelvin8ec71442015-01-15 16:57:00 -08001634 self.handle.sendline( "" )
1635 self.handle.expect( "\$" )
1636 self.handle.sendline( "onos-service " + str( node ) +
1637 " status" )
1638 i = self.handle.expect( [
You Wangef1e6572016-03-08 12:53:18 -08001639 "start/running",
You Wang7bd83062016-03-01 11:50:00 -08001640 "Running ...",
You Wangef1e6572016-03-08 12:53:18 -08001641 "stop/waiting",
You Wang7bd83062016-03-01 11:50:00 -08001642 "Not Running ...",
kelvin8ec71442015-01-15 16:57:00 -08001643 pexpect.TIMEOUT ], timeout=120 )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001644
You Wangef1e6572016-03-08 12:53:18 -08001645 if i == 0 or i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001646 main.log.info( "ONOS is running" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001647 return main.TRUE
You Wangef1e6572016-03-08 12:53:18 -08001648 elif i == 2 or i == 3:
kelvin8ec71442015-01-15 16:57:00 -08001649 main.log.info( "ONOS is stopped" )
kelvin8ec71442015-01-15 16:57:00 -08001650 main.log.error( "ONOS service failed to check the status" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001651 main.cleanup()
1652 main.exit()
1653 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001654 main.log.error( self.name + ": EOF exception found" )
1655 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001656 main.cleanup()
1657 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001658 except Exception:
1659 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001660 main.cleanup()
1661 main.exit()
Jon Hall21270ac2015-02-16 17:59:55 -08001662
Jon Hall63604932015-02-26 17:09:50 -08001663 def setIpTables( self, ip, port='', action='add', packet_type='',
1664 direction='INPUT', rule='DROP', states=True ):
Jon Hallefbd9792015-03-05 16:11:36 -08001665 """
Jon Hall21270ac2015-02-16 17:59:55 -08001666 Description:
1667 add or remove iptables rule to DROP (default) packets from
1668 specific IP and PORT
1669 Usage:
1670 * specify action ('add' or 'remove')
1671 when removing, pass in the same argument as you would add. It will
1672 delete that specific rule.
1673 * specify the ip to block
1674 * specify the destination port to block (defaults to all ports)
1675 * optional packet type to block (default tcp)
1676 * optional iptables rule (default DROP)
1677 * optional direction to block (default 'INPUT')
Jon Hall63604932015-02-26 17:09:50 -08001678 * States boolean toggles adding all supported tcp states to the
1679 firewall rule
Jon Hall21270ac2015-02-16 17:59:55 -08001680 Returns:
1681 main.TRUE on success or
1682 main.FALSE if given invalid input or
1683 main.ERROR if there is an error in response from iptables
1684 WARNING:
1685 * This function uses root privilege iptables command which may result
1686 in unwanted network errors. USE WITH CAUTION
Jon Hallefbd9792015-03-05 16:11:36 -08001687 """
Jon Hall21270ac2015-02-16 17:59:55 -08001688
1689 # NOTE*********
1690 # The strict checking methods of this driver function is intentional
1691 # to discourage any misuse or error of iptables, which can cause
1692 # severe network errors
1693 # *************
1694
1695 # NOTE: Sleep needed to give some time for rule to be added and
1696 # registered to the instance. If you are calling this function
1697 # multiple times this sleep will prevent any errors.
1698 # DO NOT REMOVE
Jon Hall63604932015-02-26 17:09:50 -08001699 # time.sleep( 5 )
Jon Hall21270ac2015-02-16 17:59:55 -08001700 try:
1701 # input validation
1702 action_type = action.lower()
1703 rule = rule.upper()
1704 direction = direction.upper()
1705 if action_type != 'add' and action_type != 'remove':
1706 main.log.error( "Invalid action type. Use 'add' or "
1707 "'remove' table rule" )
1708 if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
1709 # NOTE Currently only supports rules DROP, ACCEPT, and LOG
1710 main.log.error( "Invalid rule. Valid rules are 'DROP' or "
1711 "'ACCEPT' or 'LOG' only." )
1712 if direction != 'INPUT' and direction != 'OUTPUT':
1713 # NOTE currently only supports rules INPUT and OUPTUT
1714 main.log.error( "Invalid rule. Valid directions are"
1715 " 'OUTPUT' or 'INPUT'" )
1716 return main.FALSE
1717 return main.FALSE
1718 return main.FALSE
1719 if action_type == 'add':
1720 # -A is the 'append' action of iptables
1721 actionFlag = '-A'
1722 elif action_type == 'remove':
1723 # -D is the 'delete' rule of iptables
1724 actionFlag = '-D'
1725 self.handle.sendline( "" )
1726 self.handle.expect( "\$" )
1727 cmd = "sudo iptables " + actionFlag + " " +\
1728 direction +\
Jon Hall21270ac2015-02-16 17:59:55 -08001729 " -s " + str( ip )
Jon Hall63604932015-02-26 17:09:50 -08001730 # " -p " + str( packet_type ) +\
1731 if packet_type:
1732 cmd += " -p " + str( packet_type )
Jon Hall21270ac2015-02-16 17:59:55 -08001733 if port:
1734 cmd += " --dport " + str( port )
Jon Hall63604932015-02-26 17:09:50 -08001735 if states:
1736 cmd += " -m state --state="
1737 #FIXME- Allow user to configure which states to block
1738 cmd += "INVALID,ESTABLISHED,NEW,RELATED,UNTRACKED"
Jon Hall21270ac2015-02-16 17:59:55 -08001739 cmd += " -j " + str( rule )
1740
1741 self.handle.sendline( cmd )
1742 self.handle.expect( "\$" )
1743 main.log.warn( self.handle.before )
1744
1745 info_string = "On " + str( self.name )
1746 info_string += " " + str( action_type )
1747 info_string += " iptable rule [ "
1748 info_string += " IP: " + str( ip )
1749 info_string += " Port: " + str( port )
1750 info_string += " Rule: " + str( rule )
1751 info_string += " Direction: " + str( direction ) + " ]"
1752 main.log.info( info_string )
1753 return main.TRUE
1754 except pexpect.TIMEOUT:
1755 main.log.exception( self.name + ": Timeout exception in "
1756 "setIpTables function" )
1757 return main.ERROR
1758 except pexpect.EOF:
1759 main.log.error( self.name + ": EOF exception found" )
1760 main.log.error( self.name + ": " + self.handle.before )
1761 main.cleanup()
1762 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001763 except Exception:
1764 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall21270ac2015-02-16 17:59:55 -08001765 main.cleanup()
1766 main.exit()
1767
Jon Hall0468b042015-02-19 19:08:21 -08001768 def detailed_status(self, log_filename):
Jon Hallefbd9792015-03-05 16:11:36 -08001769 """
Jon Hall0468b042015-02-19 19:08:21 -08001770 This method is used by STS to check the status of the controller
1771 Reports RUNNING, STARTING, STOPPED, FROZEN, ERROR (and reason)
Jon Hallefbd9792015-03-05 16:11:36 -08001772 """
Jon Hall0468b042015-02-19 19:08:21 -08001773 import re
1774 try:
1775 self.handle.sendline( "" )
1776 self.handle.expect( "\$" )
1777 self.handle.sendline( "cd " + self.home )
1778 self.handle.expect( "\$" )
1779 self.handle.sendline( "service onos status" )
1780 self.handle.expect( "\$" )
1781 response = self.handle.before
1782 if re.search( "onos start/running", response ):
1783 # onos start/running, process 10457
1784 return 'RUNNING'
1785 # FIXME: Implement this case
1786 # elif re.search( pattern, response ):
1787 # return 'STARTING'
1788 elif re.search( "onos stop/", response ):
1789 # onos stop/waiting
1790 # FIXME handle this differently?: onos stop/pre-stop
1791 return 'STOPPED'
1792 # FIXME: Implement this case
1793 # elif re.search( pattern, response ):
1794 # return 'FROZEN'
1795 else:
1796 main.log.warn( self.name +
Jon Hallefbd9792015-03-05 16:11:36 -08001797 " WARNING: status received unknown response" )
Jon Hall0468b042015-02-19 19:08:21 -08001798 main.log.warn( response )
1799 return 'ERROR', "Unknown response: %s" % response
1800 except pexpect.TIMEOUT:
1801 main.log.exception( self.name + ": Timeout exception in "
1802 "setIpTables function" )
1803 return 'ERROR', "Pexpect Timeout"
1804 except pexpect.EOF:
1805 main.log.error( self.name + ": EOF exception found" )
1806 main.log.error( self.name + ": " + self.handle.before )
1807 main.cleanup()
1808 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001809 except Exception:
1810 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall0468b042015-02-19 19:08:21 -08001811 main.cleanup()
1812 main.exit()
1813
andrew@onlab.us3b087132015-03-11 15:00:08 -07001814 def createLinkGraphFile( self, benchIp, ONOSIpList, deviceCount):
1815 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07001816 Create/formats the LinkGraph.cfg file based on arguments
1817 -only creates a linear topology and connects islands
1818 -evenly distributes devices
andrew@onlab.us3b087132015-03-11 15:00:08 -07001819 -must be called by ONOSbench
1820
Jon Hall4ba53f02015-07-29 13:07:41 -07001821 ONOSIpList - list of all of the node IPs to be used
1822
1823 deviceCount - number of switches to be assigned
andrew@onlab.us3b087132015-03-11 15:00:08 -07001824 '''
1825 main.log.step("Creating link graph configuration file." )
1826 linkGraphPath = self.home + "/tools/package/etc/linkGraph.cfg"
Jon Hall4ba53f02015-07-29 13:07:41 -07001827 tempFile = "/tmp/linkGraph.cfg"
andrew@onlab.us3b087132015-03-11 15:00:08 -07001828
1829 linkGraph = open(tempFile, 'w+')
1830 linkGraph.write("# NullLinkProvider topology description (config file).\n")
1831 linkGraph.write("# The NodeId is only added if the destination is another node's device.\n")
1832 linkGraph.write("# Bugs: Comments cannot be appended to a line to be read.\n")
Jon Hall4ba53f02015-07-29 13:07:41 -07001833
andrew@onlab.us3b087132015-03-11 15:00:08 -07001834 clusterCount = len(ONOSIpList)
Jon Hall4ba53f02015-07-29 13:07:41 -07001835
1836 if type(deviceCount) is int or type(deviceCount) is str:
andrew@onlab.us3b087132015-03-11 15:00:08 -07001837 deviceCount = int(deviceCount)
1838 switchList = [0]*(clusterCount+1)
1839 baselineSwitchCount = deviceCount/clusterCount
Jon Hall4ba53f02015-07-29 13:07:41 -07001840
andrew@onlab.us3b087132015-03-11 15:00:08 -07001841 for node in range(1, clusterCount + 1):
1842 switchList[node] = baselineSwitchCount
1843
1844 for node in range(1, (deviceCount%clusterCount)+1):
1845 switchList[node] += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07001846
andrew@onlab.us3b087132015-03-11 15:00:08 -07001847 if type(deviceCount) is list:
1848 main.log.info("Using provided device distribution")
1849 switchList = [0]
1850 for i in deviceCount:
1851 switchList.append(int(i))
1852
1853 tempList = ['0']
1854 tempList.extend(ONOSIpList)
1855 ONOSIpList = tempList
1856
1857 myPort = 6
1858 lastSwitch = 0
1859 for node in range(1, clusterCount+1):
1860 if switchList[node] == 0:
1861 continue
1862
1863 linkGraph.write("graph " + ONOSIpList[node] + " {\n")
Jon Hall4ba53f02015-07-29 13:07:41 -07001864
andrew@onlab.us3b087132015-03-11 15:00:08 -07001865 if node > 1:
1866 #connect to last device on previous node
Jon Hall4ba53f02015-07-29 13:07:41 -07001867 line = ("\t0:5 -> " + str(lastSwitch) + ":6:" + lastIp + "\n") #ONOSIpList[node-1]
1868 linkGraph.write(line)
1869
1870 lastSwitch = 0
1871 for switch in range (0, switchList[node]-1):
andrew@onlab.us3b087132015-03-11 15:00:08 -07001872 line = ""
1873 line = ("\t" + str(switch) + ":" + str(myPort))
1874 line += " -- "
1875 line += (str(switch+1) + ":" + str(myPort-1) + "\n")
1876 linkGraph.write(line)
Jon Hall4ba53f02015-07-29 13:07:41 -07001877 lastSwitch = switch+1
andrew@onlab.us3b087132015-03-11 15:00:08 -07001878 lastIp = ONOSIpList[node]
Jon Hall4ba53f02015-07-29 13:07:41 -07001879
andrew@onlab.us3b087132015-03-11 15:00:08 -07001880 #lastSwitch += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07001881 if node < (clusterCount):
andrew@onlab.us3b087132015-03-11 15:00:08 -07001882 #connect to first device on the next node
Jon Hall4ba53f02015-07-29 13:07:41 -07001883 line = ("\t" + str(lastSwitch) + ":6 -> 0:5:" + ONOSIpList[node+1] + "\n")
andrew@onlab.us3b087132015-03-11 15:00:08 -07001884 linkGraph.write(line)
Jon Hall4ba53f02015-07-29 13:07:41 -07001885
andrew@onlab.us3b087132015-03-11 15:00:08 -07001886 linkGraph.write("}\n")
1887 linkGraph.close()
1888
1889 #SCP
Jon Hall4ba53f02015-07-29 13:07:41 -07001890 os.system( "scp " + tempFile + " " + self.user_name + "@" + benchIp + ":" + linkGraphPath)
andrew@onlab.us3b087132015-03-11 15:00:08 -07001891 main.log.info("linkGraph.cfg creation complete")
1892
cameron@onlab.us75900962015-03-30 13:22:49 -07001893 def configNullDev( self, ONOSIpList, deviceCount, numPorts=10):
Jon Hall4ba53f02015-07-29 13:07:41 -07001894
andrew@onlab.us3b087132015-03-11 15:00:08 -07001895 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07001896 ONOSIpList = list of Ip addresses of nodes switches will be devided amongst
1897 deviceCount = number of switches to distribute, or list of values to use as custom distribution
cameron@onlab.us75900962015-03-30 13:22:49 -07001898 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 -07001899 '''
1900
cameron@onlab.us75900962015-03-30 13:22:49 -07001901 main.log.step("Configuring Null Device Provider" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07001902 clusterCount = len(ONOSIpList)
1903
Jon Hall4ba53f02015-07-29 13:07:41 -07001904 try:
1905
cameron@onlab.us75900962015-03-30 13:22:49 -07001906 if type(deviceCount) is int or type(deviceCount) is str:
1907 main.log.step("Creating device distribution")
1908 deviceCount = int(deviceCount)
1909 switchList = [0]*(clusterCount+1)
1910 baselineSwitchCount = deviceCount/clusterCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001911
cameron@onlab.us75900962015-03-30 13:22:49 -07001912 for node in range(1, clusterCount + 1):
1913 switchList[node] = baselineSwitchCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001914
cameron@onlab.us75900962015-03-30 13:22:49 -07001915 for node in range(1, (deviceCount%clusterCount)+1):
1916 switchList[node] += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07001917
1918 if type(deviceCount) is list:
1919 main.log.info("Using provided device distribution")
1920
1921 if len(deviceCount) == clusterCount:
cameron@onlab.us75900962015-03-30 13:22:49 -07001922 switchList = ['0']
1923 switchList.extend(deviceCount)
Jon Hall4ba53f02015-07-29 13:07:41 -07001924
1925 if len(deviceCount) == (clusterCount + 1):
1926 if deviceCount[0] == '0' or deviceCount[0] == 0:
cameron@onlab.us75900962015-03-30 13:22:49 -07001927 switchList = deviceCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001928
cameron@onlab.us75900962015-03-30 13:22:49 -07001929 assert len(switchList) == (clusterCount + 1)
Jon Hall4ba53f02015-07-29 13:07:41 -07001930
cameron@onlab.us75900962015-03-30 13:22:49 -07001931 except AssertionError:
Jon Hall4ba53f02015-07-29 13:07:41 -07001932 main.log.error( "Bad device/Ip list match")
cameron@onlab.us75900962015-03-30 13:22:49 -07001933 except TypeError:
1934 main.log.exception( self.name + ": Object not as expected" )
1935 return None
Jon Hall77ba41c2015-04-06 10:25:40 -07001936 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07001937 main.log.exception( self.name + ": Uncaught exception!" )
1938 main.cleanup()
1939 main.exit()
1940
andrew@onlab.us3b087132015-03-11 15:00:08 -07001941
1942 ONOSIp = [0]
1943 ONOSIp.extend(ONOSIpList)
Jon Hall4ba53f02015-07-29 13:07:41 -07001944
andrew@onlab.us3b087132015-03-11 15:00:08 -07001945 devicesString = "devConfigs = "
1946 for node in range(1, len(ONOSIp)):
1947 devicesString += (ONOSIp[node] + ":" + str(switchList[node] ))
1948 if node < clusterCount:
1949 devicesString += (",")
Jon Hall4ba53f02015-07-29 13:07:41 -07001950
1951 try:
cameron@onlab.us75900962015-03-30 13:22:49 -07001952 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider devConfigs " + devicesString )
1953 self.handle.expect(":~")
1954 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider numPorts " + str(numPorts) )
1955 self.handle.expect(":~")
andrew@onlab.us3b087132015-03-11 15:00:08 -07001956
cameron@onlab.us75900962015-03-30 13:22:49 -07001957 for i in range(10):
1958 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.device.impl.NullDeviceProvider")
1959 self.handle.expect(":~")
1960 verification = self.handle.before
1961 if (" value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification:
1962 break
1963 else:
1964 time.sleep(1)
andrew@onlab.us3b087132015-03-11 15:00:08 -07001965
cameron@onlab.us2cc8bf12015-04-02 14:12:30 -07001966 assert ("value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification
Jon Hall4ba53f02015-07-29 13:07:41 -07001967
cameron@onlab.us75900962015-03-30 13:22:49 -07001968 except AssertionError:
1969 main.log.error("Incorrect Config settings: " + verification)
Jon Hall77ba41c2015-04-06 10:25:40 -07001970 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07001971 main.log.exception( self.name + ": Uncaught exception!" )
1972 main.cleanup()
1973 main.exit()
1974
Jon Hall4ba53f02015-07-29 13:07:41 -07001975 def configNullLink( self,fileName="/opt/onos/apache-karaf-3.0.3/etc/linkGraph.cfg", eventRate=0):
andrew@onlab.us3b087132015-03-11 15:00:08 -07001976 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07001977 fileName default is currently the same as the default on ONOS, specify alternate file if
cameron@onlab.us75900962015-03-30 13:22:49 -07001978 you want to use a different topology file than linkGraph.cfg
andrew@onlab.us3b087132015-03-11 15:00:08 -07001979 '''
1980
Jon Hall4ba53f02015-07-29 13:07:41 -07001981
1982 try:
1983 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider eventRate " + str(eventRate))
1984 self.handle.expect(":~")
cameron@onlab.us75900962015-03-30 13:22:49 -07001985 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider cfgFile " + fileName )
1986 self.handle.expect(":~")
Jon Hall4ba53f02015-07-29 13:07:41 -07001987
1988 for i in range(10):
1989 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.link.impl.NullLinkProvider")
cameron@onlab.us75900962015-03-30 13:22:49 -07001990 self.handle.expect(":~")
1991 verification = self.handle.before
Jon Hall4ba53f02015-07-29 13:07:41 -07001992 if (" value=" + str(eventRate)) in verification and (" value=" + fileName) in verification:
cameron@onlab.us75900962015-03-30 13:22:49 -07001993 break
Jon Hall4ba53f02015-07-29 13:07:41 -07001994 else:
cameron@onlab.us75900962015-03-30 13:22:49 -07001995 time.sleep(1)
Jon Hall4ba53f02015-07-29 13:07:41 -07001996
cameron@onlab.us75900962015-03-30 13:22:49 -07001997 assert ("value=" + str(eventRate)) in verification and (" value=" + fileName) in verification
Jon Hall4ba53f02015-07-29 13:07:41 -07001998
cameron@onlab.us75900962015-03-30 13:22:49 -07001999 except pexpect.EOF:
2000 main.log.error( self.name + ": EOF exception found" )
2001 main.log.error( self.name + ": " + self.handle.before )
2002 main.cleanup()
2003 main.exit()
cameron@onlab.us75900962015-03-30 13:22:49 -07002004 except AssertionError:
2005 main.log.info("Settings did not post to ONOS")
Jon Hall4ba53f02015-07-29 13:07:41 -07002006 main.log.error(varification)
Jon Hall77ba41c2015-04-06 10:25:40 -07002007 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002008 main.log.exception( self.name + ": Uncaught exception!" )
2009 main.log.error(varification)
2010 main.cleanup()
2011 main.exit()
andrew@onlab.us3b087132015-03-11 15:00:08 -07002012
kelvin-onlaba4074292015-07-09 15:19:49 -07002013 def getOnosIps( self ):
2014 """
2015 Get all onos IPs stored in
2016 """
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002017
kelvin-onlaba4074292015-07-09 15:19:49 -07002018 return sorted( self.onosIps.values() )
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002019
kelvin-onlaba4074292015-07-09 15:19:49 -07002020 def logReport( self, nodeIp, searchTerms, outputMode="s" ):
Jon Hallb4242222016-01-25 17:07:04 -08002021 """
2022 Searches the latest ONOS log file for the given search terms and
2023 prints the total occurances of each term. Returns to combined total of
2024 all occurances.
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002025
Jon Hallb4242222016-01-25 17:07:04 -08002026 Arguments:
2027 * nodeIp - The ip of the ONOS node where the log is located
2028 * searchTerms - A string to grep for or a list of strings to grep
2029 for in the ONOS log. Will print out the number of
2030 occurances for each term.
2031 Optional Arguments:
2032 * outputMode - 's' or 'd'. If 'd' will print the last 5 lines
2033 containing each search term as well as the total
2034 number of occurances of each term. Defaults to 's',
2035 which prints the simple output of just the number
2036 of occurances for each term.
2037 """
2038 try:
2039 main.log.info( " Log Report for {} ".format( nodeIp ).center( 70, '=' ) )
2040 if type( searchTerms ) is str:
2041 searchTerms = [searchTerms]
2042 numTerms = len( searchTerms )
2043 outputMode = outputMode.lower()
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002044
Jon Hallb4242222016-01-25 17:07:04 -08002045 totalHits = 0
2046 logLines = []
2047 for termIndex in range( numTerms ):
2048 term = searchTerms[termIndex]
2049 logLines.append( [term] )
2050 cmd = "onos-ssh " + nodeIp + " cat /opt/onos/log/karaf.log | grep " + term
2051 self.handle.sendline( cmd )
2052 self.handle.expect( ":~" )
2053 before = self.handle.before.splitlines()
2054 count = 0
2055 for line in before:
2056 if term in line and "grep" not in line:
2057 count += 1
2058 if before.index( line ) > ( len( before ) - 7 ):
2059 logLines[termIndex].append( line )
2060 main.log.info( "{}: {}".format( term, count ) )
2061 totalHits += count
2062 if termIndex == numTerms - 1:
2063 print "\n"
2064 if outputMode != "s":
2065 outputString = ""
2066 for term in logLines:
2067 outputString = term[0] + ": \n"
2068 for line in range( 1, len( term ) ):
2069 outputString += ( "\t" + term[line] + "\n" )
2070 if outputString != ( term[0] + ": \n" ):
2071 main.log.info( outputString )
2072 main.log.info( "=" * 70 )
2073 return totalHits
2074 except pexpect.EOF:
2075 main.log.error( self.name + ": EOF exception found" )
2076 main.log.error( self.name + ": " + self.handle.before )
2077 main.cleanup()
2078 main.exit()
2079 except pexpect.TIMEOUT:
2080 main.log.error( self.name + ": TIMEOUT exception found" )
2081 main.log.error( self.name + ": " + self.handle.before )
2082 main.cleanup()
2083 main.exit()
2084 except Exception:
2085 main.log.exception( self.name + ": Uncaught exception!" )
2086 main.cleanup()
2087 main.exit()
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002088
2089 def copyMininetFile( self, fileName, localPath, userName, ip,
2090 mnPath='~/mininet/custom/', timeout = 60 ):
2091 """
2092 Description:
2093 Copy mininet topology file from dependency folder in the test folder
2094 and paste it to the mininet machine's mininet/custom folder
2095 Required:
2096 fileName - Name of the topology file to copy
2097 localPath - File path of the mininet topology file
2098 userName - User name of the mininet machine to send the file to
2099 ip - Ip address of the mininet machine
2100 Optional:
2101 mnPath - of the mininet directory to send the file to
2102 Return:
2103 Return main.TRUE if successfully copied the file otherwise
2104 return main.FALSE
2105 """
2106
2107 try:
2108 cmd = "scp " + localPath + fileName + " " + userName + "@" + \
2109 str( ip ) + ":" + mnPath + fileName
2110
2111 self.handle.sendline( "" )
2112 self.handle.expect( "\$" )
2113
2114 main.log.info( self.name + ": Execute: " + cmd )
2115
2116 self.handle.sendline( cmd )
2117
2118 i = self.handle.expect( [ 'No such file',
2119 "100%",
2120 pexpect.TIMEOUT ] )
2121
2122 if i == 0:
2123 main.log.error( self.name + ": File " + fileName +
2124 " does not exist!" )
2125 return main.FALSE
2126
2127 if i == 1:
2128 main.log.info( self.name + ": File " + fileName +
2129 " has been copied!" )
2130 self.handle.sendline( "" )
2131 self.handle.expect( "\$" )
2132 return main.TRUE
2133
2134 except pexpect.EOF:
2135 main.log.error( self.name + ": EOF exception found" )
2136 main.log.error( self.name + ": " + self.handle.before )
2137 main.cleanup()
2138 main.exit()
2139 except pexpect.TIMEOUT:
2140 main.log.error( self.name + ": TIMEOUT exception found" )
2141 main.log.error( self.name + ": " + self.handle.before )
2142 main.cleanup()
2143 main.exit()
cameron@onlab.us78b89652015-07-08 15:21:03 -07002144
2145 def jvmSet(self, memory=8):
Jon Hall4ba53f02015-07-29 13:07:41 -07002146
cameron@onlab.us78b89652015-07-08 15:21:03 -07002147 import os
2148
2149 homeDir = os.path.expanduser('~')
2150 filename = "/onos/tools/package/bin/onos-service"
2151
2152 serviceConfig = open(homeDir + filename, 'w+')
2153 serviceConfig.write("#!/bin/bash\n ")
2154 serviceConfig.write("#------------------------------------- \n ")
2155 serviceConfig.write("# Starts ONOS Apache Karaf container\n ")
2156 serviceConfig.write("#------------------------------------- \n ")
2157 serviceConfig.write("#export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-7-openjdk-amd64/}\n ")
2158 serviceConfig.write("""export JAVA_OPTS="${JAVA_OPTS:--Xms""" + str(memory) + "G -Xmx" + str(memory) + """G}" \n """)
2159 serviceConfig.write("[ -d $ONOS_HOME ] && cd $ONOS_HOME || ONOS_HOME=$(dirname $0)/..\n")
2160 serviceConfig.write("""${ONOS_HOME}/apache-karaf-$KARAF_VERSION/bin/karaf "$@" \n """)
2161 serviceConfig.close()
2162
Jon Hall6c44c0b2016-04-20 15:21:00 -07002163 def createDBFile( self, testData ):
Jon Hall4ba53f02015-07-29 13:07:41 -07002164
cameron@onlab.us78b89652015-07-08 15:21:03 -07002165 filename = main.TEST + "DB"
2166 DBString = ""
Jon Hall4ba53f02015-07-29 13:07:41 -07002167
cameron@onlab.us78b89652015-07-08 15:21:03 -07002168 for item in testData:
Jon Hall6c44c0b2016-04-20 15:21:00 -07002169 if type( item ) is string:
cameron@onlab.us78b89652015-07-08 15:21:03 -07002170 item = "'" + item + "'"
Jon Hall6c44c0b2016-04-20 15:21:00 -07002171 if testData.index( item ) < len( testData - 1 ):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002172 item += ","
Jon Hall6c44c0b2016-04-20 15:21:00 -07002173 DBString += str( item )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002174
Jon Hall6c44c0b2016-04-20 15:21:00 -07002175 DBFile = open( filename, "a" )
2176 DBFile.write( DBString )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002177 DBFile.close()
2178
Jon Hall6c44c0b2016-04-20 15:21:00 -07002179 def verifySummary( self, ONOSIp, *deviceCount ):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002180
Jon Hall6c44c0b2016-04-20 15:21:00 -07002181 self.handle.sendline( "onos " + ONOSIp + " summary" )
2182 self.handle.expect( ":~" )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002183
2184 summaryStr = self.handle.before
2185 print "\nSummary\n==============\n" + summaryStr + "\n\n"
2186
2187 #passed = "SCC(s)=1" in summaryStr
2188 #if deviceCount:
2189 # passed = "devices=" + str(deviceCount) + "," not in summaryStr
2190
GlennRC772363b2015-08-25 13:05:57 -07002191 passed = False
cameron@onlab.us78b89652015-07-08 15:21:03 -07002192 if "SCC(s)=1," in summaryStr:
2193 passed = True
Jon Hall6c44c0b2016-04-20 15:21:00 -07002194 print "Summary is verifed"
Jon Hall4ba53f02015-07-29 13:07:41 -07002195 else:
Jon Hall6c44c0b2016-04-20 15:21:00 -07002196 print "Summary failed"
cameron@onlab.us78b89652015-07-08 15:21:03 -07002197
2198 if deviceCount:
2199 print" ============================="
Jon Hall6c44c0b2016-04-20 15:21:00 -07002200 checkStr = "devices=" + str( deviceCount[0] ) + ","
cameron@onlab.us78b89652015-07-08 15:21:03 -07002201 print "Checkstr: " + checkStr
2202 if checkStr not in summaryStr:
2203 passed = False
Jon Hall6c44c0b2016-04-20 15:21:00 -07002204 print "Device count failed"
Jon Hall4ba53f02015-07-29 13:07:41 -07002205 else:
2206 print "device count verified"
cameron@onlab.us78b89652015-07-08 15:21:03 -07002207
2208 return passed
Jon Hall6c44c0b2016-04-20 15:21:00 -07002209
2210 def getIpAddr( self ):
2211 """
2212 Update self.ip_address with numerical ip address. If multiple IP's are
2213 located on the device, will attempt to use self.nicAddr to choose the
2214 right one. Defaults to 127.0.0.1 if no other address is found or cannot
2215 determine the correct address.
2216
2217 ONLY WORKS WITH IPV4 ADDRESSES
2218 """
2219 try:
2220 localhost = "127.0.0.1"
2221 ipPat = "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"
2222 pattern = re.compile( ipPat )
2223 match = re.search( pattern, self.ip_address )
2224 if self.nicAddr:
2225 nicPat = self.nicAddr.replace( ".", "\." ).replace( "\*", r"\d{1,3}" )
2226 nicPat = re.compile( nicPat )
2227 else:
2228 nicPat = None
2229 # IF self.ip_address is an ip address and matches
2230 # self.nicAddr: return self.ip_address
2231 if match:
2232 curIp = match.group(0)
2233 if nicPat:
2234 nicMatch = re.search( nicPat, curIp )
2235 if nicMatch:
2236 return self.ip_address
2237 # ELSE: attempt to get correct address.
2238 raw = subprocess.check_output( "ifconfig")
2239 ifPat = re.compile( "inet addr:({})".format( ipPat ) )
2240 ips = re.findall( ifPat, raw )
2241 if nicPat:
2242 for ip in ips:
2243 curMatch = re.search( nicPat, ip )
2244 if curMatch:
2245 self.ip_address = ip
2246 return ip
2247 else:
2248 tmpList = [ ip for ip in ips if ip is not localhost ]
2249 if len(tmpList) == 1:
2250 curIp = tmpList[0]
2251 self.ip_address = curIp
2252 return curIp
2253 return localhost
2254 except Exception:
2255 main.log.exception( "Uncaught exception" )
suibin zhang116647a2016-05-06 16:30:09 -07002256
2257 def startBasicONOS(self, nodeList, opSleep = 60, onosStartupSleep = 60):
2258
2259 '''
2260 Start onos cluster with defined nodes, but only with drivers app
2261
2262 '''
2263 import time
2264
2265 self.createCellFile( self.ip_address,
2266 "temp",
2267 self.ip_address,
2268 "drivers",
2269 nodeList )
2270
2271 main.log.info( self.name + ": Apply cell to environment" )
2272 cellResult = self.setCell( "temp" )
2273 verifyResult = self.verifyCell()
2274
2275 main.log.info( self.name + ": Creating ONOS package" )
2276 packageResult = self.onosPackage( opTimeout=opSleep )
2277
2278 main.log.info( self.name + ": Installing ONOS package" )
2279 for nd in nodeList:
2280 self.onosInstall( node=nd )
2281
2282 main.log.info( self.name + ": Starting ONOS service" )
2283 time.sleep( onosStartupSleep )
2284
2285 onosStatus = True
2286 for nd in nodeList:
2287 onosStatus = onosStatus & self.isup( node = nd )
2288 #print "onosStatus is: " + str( onosStatus )
2289
2290 return main.TRUE if onosStatus else main.FALSE
2291