blob: 2593b6e907bfdc2aadafd24f659d08556d48a84c [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"""
Jeremy Ronquilloec916a42018-02-02 13:05:57 -08004Copyright 2014 Open Networking Foundation (ONF)
5
kelvin8ec71442015-01-15 16:57:00 -08006This driver interacts with ONOS bench, the OSGi platform
7that configures the ONOS nodes. ( aka ONOS-next )
andrewonlabe8e56fd2014-10-09 17:12:44 -04008
kelvin8ec71442015-01-15 16:57:00 -08009Please follow the coding style demonstrated by existing
andrewonlabe8e56fd2014-10-09 17:12:44 -040010functions and document properly.
11
12If you are a contributor to the driver, please
13list your email here for future contact:
14
15jhall@onlab.us
16andrew@onlab.us
17
18OCT 9 2014
Jeremy Songsterae01bba2016-07-11 15:39:17 -070019Modified 2016 by ON.Lab
20
21Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
22the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
23or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
andrewonlabe8e56fd2014-10-09 17:12:44 -040024
kelvin8ec71442015-01-15 16:57:00 -080025"""
Jon Hall05b2b432014-10-08 19:53:25 -040026import time
Jon Hall6801cda2015-07-15 14:13:45 -070027import types
Jon Hall05b2b432014-10-08 19:53:25 -040028import pexpect
kelvin-onlaba4074292015-07-09 15:19:49 -070029import os
Jon Hall6c44c0b2016-04-20 15:21:00 -070030import re
31import subprocess
Jon Hall05b2b432014-10-08 19:53:25 -040032from drivers.common.clidriver import CLI
33
kelvin8ec71442015-01-15 16:57:00 -080034class OnosDriver( CLI ):
Jon Hall05b2b432014-10-08 19:53:25 -040035
kelvin8ec71442015-01-15 16:57:00 -080036 def __init__( self ):
37 """
38 Initialize client
39 """
Jon Hallefbd9792015-03-05 16:11:36 -080040 self.name = None
41 self.home = None
42 self.handle = None
Jon Hall6c44c0b2016-04-20 15:21:00 -070043 self.nicAddr = None
Devin Limdc78e202017-06-09 18:30:07 -070044 super( OnosDriver, self ).__init__()
kelvin8ec71442015-01-15 16:57:00 -080045
46 def connect( self, **connectargs ):
47 """
Jon Hall05b2b432014-10-08 19:53:25 -040048 Creates ssh handle for ONOS "bench".
kelvin-onlaba4074292015-07-09 15:19:49 -070049 NOTE:
50 The ip_address would come from the topo file using the host tag, the
51 value can be an environment variable as well as a "localhost" to get
52 the ip address needed to ssh to the "bench"
kelvin8ec71442015-01-15 16:57:00 -080053 """
Jon Hall05b2b432014-10-08 19:53:25 -040054 try:
Devin Limdc78e202017-06-09 18:30:07 -070055
Jon Hall05b2b432014-10-08 19:53:25 -040056 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080057 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us3b087132015-03-11 15:00:08 -070058 self.home = "~/onos"
Jon Hall05b2b432014-10-08 19:53:25 -040059 for key in self.options:
60 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080061 self.home = self.options[ 'home' ]
Jon Hall05b2b432014-10-08 19:53:25 -040062 break
Jon Hall274b6642015-02-17 11:57:17 -080063 if self.home is None or self.home == "":
Jon Halle94919c2015-03-23 11:42:57 -070064 self.home = "~/onos"
Jon Hall21270ac2015-02-16 17:59:55 -080065
kelvin8ec71442015-01-15 16:57:00 -080066 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070067
kelvin-onlabc2b79102015-07-14 11:41:20 -070068 # The 'nodes' tag is optional and it is not required in .topo file
kelvin-onlaba4074292015-07-09 15:19:49 -070069 for key in self.options:
70 if key == "nodes":
kelvin-onlabc2b79102015-07-14 11:41:20 -070071 # Maximum number of ONOS nodes to run, if there is any
kelvin-onlaba4074292015-07-09 15:19:49 -070072 self.maxNodes = int( self.options[ 'nodes' ] )
73 break
74 self.maxNodes = None
75
Jeremy Ronquillo82705492017-10-18 14:19:55 -070076 if self.maxNodes is None or self.maxNodes == "":
kelvin-onlabc2b79102015-07-14 11:41:20 -070077 self.maxNodes = 100
kelvin-onlaba4074292015-07-09 15:19:49 -070078
kelvin-onlabc2b79102015-07-14 11:41:20 -070079 # Grabs all OC environment variables based on max number of nodes
kelvin-onlaba4074292015-07-09 15:19:49 -070080 self.onosIps = {} # Dictionary of all possible ONOS ip
81
82 try:
83 if self.maxNodes:
kelvin-onlaba4074292015-07-09 15:19:49 -070084 for i in range( self.maxNodes ):
85 envString = "OC" + str( i + 1 )
kelvin-onlabc2b79102015-07-14 11:41:20 -070086 # If there is no more OC# then break the loop
87 if os.getenv( envString ):
88 self.onosIps[ envString ] = os.getenv( envString )
89 else:
90 self.maxNodes = len( self.onosIps )
91 main.log.info( self.name +
92 ": Created cluster data with " +
93 str( self.maxNodes ) +
94 " maximum number" +
95 " of nodes" )
96 break
kelvin-onlaba4074292015-07-09 15:19:49 -070097
98 if not self.onosIps:
99 main.log.info( "Could not read any environment variable"
100 + " please load a cell file with all" +
101 " onos IP" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700102 self.maxNodes = None
kelvin-onlaba4074292015-07-09 15:19:49 -0700103 else:
104 main.log.info( self.name + ": Found " +
105 str( self.onosIps.values() ) +
106 " ONOS IPs" )
kelvin-onlaba4074292015-07-09 15:19:49 -0700107 except KeyError:
108 main.log.info( "Invalid environment variable" )
109 except Exception as inst:
110 main.log.error( "Uncaught exception: " + str( inst ) )
111
112 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700113 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -0700114 self.ip_address = os.getenv( str( self.ip_address ) )
115 else:
116 main.log.info( self.name +
117 ": Trying to connect to " +
118 self.ip_address )
kelvin-onlaba4074292015-07-09 15:19:49 -0700119 except KeyError:
120 main.log.info( "Invalid host name," +
121 " connecting to local host instead" )
122 self.ip_address = 'localhost'
123 except Exception as inst:
124 main.log.error( "Uncaught exception: " + str( inst ) )
125
kelvin8ec71442015-01-15 16:57:00 -0800126 self.handle = super( OnosDriver, self ).connect(
127 user_name=self.user_name,
kelvin-onlab08679eb2015-01-21 16:11:48 -0800128 ip_address=self.ip_address,
kelvin-onlabd3b64892015-01-20 13:26:24 -0800129 port=self.port,
130 pwd=self.pwd,
131 home=self.home )
Jon Hall05b2b432014-10-08 19:53:25 -0400132
Jon Hall05b2b432014-10-08 19:53:25 -0400133 if self.handle:
Jon Hall0fc0d452015-07-14 09:49:58 -0700134 self.handle.sendline( "cd " + self.home )
Devin Limc20e79a2017-06-07 10:29:57 -0700135 self.handle.expect( self.prompt )
Jon Hall05b2b432014-10-08 19:53:25 -0400136 return self.handle
kelvin8ec71442015-01-15 16:57:00 -0800137 else:
Jon Hall0fc0d452015-07-14 09:49:58 -0700138 main.log.info( "Failed to create ONOS handle" )
Jon Hall05b2b432014-10-08 19:53:25 -0400139 return main.FALSE
140 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800141 main.log.error( self.name + ": EOF exception found" )
142 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700143 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800144 except Exception:
145 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700146 main.cleanAndExit()
Jon Hall05b2b432014-10-08 19:53:25 -0400147
kelvin8ec71442015-01-15 16:57:00 -0800148 def disconnect( self ):
149 """
Jon Hall05b2b432014-10-08 19:53:25 -0400150 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800151 """
Jon Halld61331b2015-02-17 16:35:47 -0800152 response = main.TRUE
Jon Hall05b2b432014-10-08 19:53:25 -0400153 try:
Jon Hall61282e32015-03-19 11:34:11 -0700154 if self.handle:
155 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -0700156 self.handle.expect( self.prompt )
Jon Hall61282e32015-03-19 11:34:11 -0700157 self.handle.sendline( "exit" )
158 self.handle.expect( "closed" )
Jon Hall05b2b432014-10-08 19:53:25 -0400159 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800160 main.log.error( self.name + ": EOF exception found" )
161 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700162 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700163 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700164 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800165 except Exception:
166 main.log.exception( self.name + ": Connection failed to the host" )
Jon Hall05b2b432014-10-08 19:53:25 -0400167 response = main.FALSE
168 return response
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400169
andrew@onlab.usaee415a2015-06-05 14:38:58 -0400170 def getEpochMs( self ):
171 """
172 Returns milliseconds since epoch
Jon Hall4ba53f02015-07-29 13:07:41 -0700173
174 When checking multiple nodes in a for loop,
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000175 around a hundred milliseconds of difference (ascending) is
Jon Hall4ba53f02015-07-29 13:07:41 -0700176 generally acceptable due to calltime of the function.
177 Few seconds, however, is not and it means clocks
178 are off sync.
andrew@onlab.usaee415a2015-06-05 14:38:58 -0400179 """
180 try:
181 self.handle.sendline( 'date +%s.%N' )
182 self.handle.expect( 'date \+\%s\.\%N' )
Devin Limdc78e202017-06-09 18:30:07 -0700183 self.handle.expect( self.prompt )
andrew@onlab.usaee415a2015-06-05 14:38:58 -0400184 epochMs = self.handle.before
185 return epochMs
186 except Exception:
187 main.log.exception( 'Uncaught exception getting epoch time' )
Devin Lim44075962017-08-11 10:56:37 -0700188 main.cleanAndExit()
andrew@onlab.usaee415a2015-06-05 14:38:58 -0400189
Jon Hall6c44c0b2016-04-20 15:21:00 -0700190 def onosPackage( self, opTimeout=180 ):
kelvin8ec71442015-01-15 16:57:00 -0800191 """
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400192 Produce a self-contained tar.gz file that can be deployed
Jon Hall64af8502015-12-15 10:09:33 -0800193 and executed on any platform with Java 8 JRE.
kelvin8ec71442015-01-15 16:57:00 -0800194 """
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400195 try:
Jon Hall64af8502015-12-15 10:09:33 -0800196 ret = main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800197 self.handle.sendline( "onos-package" )
198 self.handle.expect( "onos-package" )
Jon Hall96451092016-05-04 09:42:30 -0700199 while True:
200 i = self.handle.expect( [ "Downloading",
201 "Unknown options",
202 "No such file or directory",
203 "tar.gz",
Devin Limc20e79a2017-06-07 10:29:57 -0700204 self.prompt ],
Jon Hall96451092016-05-04 09:42:30 -0700205 opTimeout )
206 handle = str( self.handle.before + self.handle.after )
207 if i == 0:
208 # Give more time to download the file
209 continue # expect again
210 elif i == 1:
211 # Incorrect usage
212 main.log.error( "onos-package does not recognize the given options" )
213 ret = main.FALSE
214 continue # expect again
215 elif i == 2:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000216 # File(s) not found
Jon Hall96451092016-05-04 09:42:30 -0700217 main.log.error( "onos-package could not find a file or directory" )
218 ret = main.FALSE
219 continue # expect again
220 elif i == 3:
221 # tar.gz
222 continue # expect again
223 elif i == 4:
224 # Prompt returned
225 break
Jon Hallc6793552016-01-19 14:18:37 -0800226 main.log.info( "onos-package command returned: " + handle )
kelvin8ec71442015-01-15 16:57:00 -0800227 # As long as the sendline does not time out,
228 # return true. However, be careful to interpret
229 # the results of the onos-package command return
Jon Hall64af8502015-12-15 10:09:33 -0800230 return ret
231 except pexpect.TIMEOUT:
232 main.log.exception( self.name + ": TIMEOUT exception found in onosPackage" )
233 main.log.error( self.name + ": " + self.handle.before )
You Wang141b43b2018-06-26 16:50:18 -0700234 self.handle.send( "\x03" ) # Control-C
235 self.handle.expect( self.prompt )
Jon Hall64af8502015-12-15 10:09:33 -0800236 return main.FALSE
andrewonlab7735d852014-10-09 13:02:47 -0400237 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800238 main.log.error( self.name + ": EOF exception found" )
239 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700240 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800241 except Exception:
242 main.log.exception( "Failed to package ONOS" )
Devin Lim44075962017-08-11 10:56:37 -0700243 main.cleanAndExit()
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400244
kelvin-onlabd3b64892015-01-20 13:26:24 -0800245 def onosBuild( self ):
kelvin8ec71442015-01-15 16:57:00 -0800246 """
andrewonlab8790abb2014-11-06 13:51:54 -0500247 Use the pre defined script to build onos via mvn
kelvin8ec71442015-01-15 16:57:00 -0800248 """
andrewonlab8790abb2014-11-06 13:51:54 -0500249 try:
kelvin8ec71442015-01-15 16:57:00 -0800250 self.handle.sendline( "onos-build" )
251 self.handle.expect( "onos-build" )
252 i = self.handle.expect( [
kelvin-onlabd3b64892015-01-20 13:26:24 -0800253 "BUILD SUCCESS",
254 "ERROR",
255 "BUILD FAILED" ],
256 timeout=120 )
kelvin8ec71442015-01-15 16:57:00 -0800257 handle = str( self.handle.before )
Devin Limc20e79a2017-06-07 10:29:57 -0700258 self.handle.expect( self.prompt )
andrewonlab8790abb2014-11-06 13:51:54 -0500259
kelvin8ec71442015-01-15 16:57:00 -0800260 main.log.info( "onos-build command returned: " +
261 handle )
andrewonlab8790abb2014-11-06 13:51:54 -0500262
263 if i == 0:
264 return main.TRUE
265 else:
266 return handle
267
268 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800269 main.log.error( self.name + ": EOF exception found" )
270 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -0800271 except Exception:
272 main.log.exception( "Failed to build ONOS" )
Devin Lim44075962017-08-11 10:56:37 -0700273 main.cleanAndExit()
andrewonlab8790abb2014-11-06 13:51:54 -0500274
shahshreya9f531fe2015-06-10 12:03:51 -0700275 def cleanInstall( self, skipTest=False, mciTimeout=600 ):
kelvin8ec71442015-01-15 16:57:00 -0800276 """
277 Runs mvn clean install in the root of the ONOS directory.
278 This will clean all ONOS artifacts then compile each module
shahshreya9f531fe2015-06-10 12:03:51 -0700279 Optional:
280 skipTest - Does "-DskipTests -Dcheckstyle.skip -U -T 1C" which
281 skip the test. This will make the building faster.
282 Disregarding the credibility of the build
kelvin8ec71442015-01-15 16:57:00 -0800283 Returns: main.TRUE on success
Jon Hallde9d9aa2014-10-08 20:36:02 -0400284 On Failure, exits the test
kelvin8ec71442015-01-15 16:57:00 -0800285 """
Jon Hallde9d9aa2014-10-08 20:36:02 -0400286 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800287 main.log.info( "Running 'mvn clean install' on " +
288 str( self.name ) +
kelvin8ec71442015-01-15 16:57:00 -0800289 ". This may take some time." )
290 self.handle.sendline( "cd " + self.home )
Devin Limc20e79a2017-06-07 10:29:57 -0700291 self.handle.expect( self.prompt )
Jon Hallea7818b2014-10-09 14:30:59 -0400292
kelvin8ec71442015-01-15 16:57:00 -0800293 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -0700294 self.handle.expect( self.prompt )
shahshreya9f531fe2015-06-10 12:03:51 -0700295
296 if not skipTest:
297 self.handle.sendline( "mvn clean install" )
298 self.handle.expect( "mvn clean install" )
299 else:
300 self.handle.sendline( "mvn clean install -DskipTests" +
301 " -Dcheckstyle.skip -U -T 1C" )
302 self.handle.expect( "mvn clean install -DskipTests" +
303 " -Dcheckstyle.skip -U -T 1C" )
kelvin8ec71442015-01-15 16:57:00 -0800304 while True:
305 i = self.handle.expect( [
Jon Hall274b6642015-02-17 11:57:17 -0800306 'There\sis\sinsufficient\smemory\sfor\sthe\sJava\s' +
Jon Hallefbd9792015-03-05 16:11:36 -0800307 'Runtime\sEnvironment\sto\scontinue',
Jon Hallde9d9aa2014-10-08 20:36:02 -0400308 'BUILD\sFAILURE',
309 'BUILD\sSUCCESS',
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700310 'onos' + self.prompt, # TODO: fix this to be more generic?
Devin Limdc78e202017-06-09 18:30:07 -0700311 'ONOS' + self.prompt,
pingping-lin57a56ce2015-05-20 16:43:48 -0700312 pexpect.TIMEOUT ], mciTimeout )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400313 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800314 main.log.error( self.name + ":There is insufficient memory \
315 for the Java Runtime Environment to continue." )
316 # return main.FALSE
Devin Lim44075962017-08-11 10:56:37 -0700317
318 main.cleanAndExit()
Jon Hallde9d9aa2014-10-08 20:36:02 -0400319 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800320 main.log.error( self.name + ": Build failure!" )
321 # return main.FALSE
Devin Lim44075962017-08-11 10:56:37 -0700322
323 main.cleanAndExit()
Jon Hallde9d9aa2014-10-08 20:36:02 -0400324 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800325 main.log.info( self.name + ": Build success!" )
Jon Halle94919c2015-03-23 11:42:57 -0700326 elif i == 3 or i == 4:
kelvin8ec71442015-01-15 16:57:00 -0800327 main.log.info( self.name + ": Build complete" )
328 # Print the build time
Jon Hallf8ef52c2014-10-09 19:37:33 -0400329 for line in self.handle.before.splitlines():
330 if "Total time:" in line:
kelvin8ec71442015-01-15 16:57:00 -0800331 main.log.info( line )
332 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -0700333 self.handle.expect( self.prompt, timeout=60 )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400334 return main.TRUE
Jon Halle94919c2015-03-23 11:42:57 -0700335 elif i == 5:
kelvin8ec71442015-01-15 16:57:00 -0800336 main.log.error(
337 self.name +
338 ": mvn clean install TIMEOUT!" )
339 # return main.FALSE
Devin Lim44075962017-08-11 10:56:37 -0700340
341 main.cleanAndExit()
Jon Hallde9d9aa2014-10-08 20:36:02 -0400342 else:
Jon Hall274b6642015-02-17 11:57:17 -0800343 main.log.error( self.name + ": unexpected response from " +
Jon Hallefbd9792015-03-05 16:11:36 -0800344 "mvn clean install" )
kelvin8ec71442015-01-15 16:57:00 -0800345 # return main.FALSE
Devin Lim44075962017-08-11 10:56:37 -0700346
347 main.cleanAndExit()
Jon Hallde9d9aa2014-10-08 20:36:02 -0400348 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800349 main.log.error( self.name + ": EOF exception found" )
350 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700351 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800352 except Exception:
353 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700354 main.cleanAndExit()
Jon Hallacabffd2014-10-09 12:36:53 -0400355
Jon Hall3576f572016-08-23 10:01:07 -0700356 def buckBuild( self, timeout=180 ):
357 """
358 Build onos using buck.
359 """
360 try:
361 ret = main.TRUE
362 self.handle.sendline( "buck build onos" )
363 self.handle.expect( "buck build onos" )
364 output = ""
365 while True:
366 i = self.handle.expect( [ "This does not appear to be the root of a Buck project.",
367 "\n",
368 "BUILD FAILED",
Jon Halld9066132018-03-01 14:52:53 -0800369 "no buck in",
Devin Limc20e79a2017-06-07 10:29:57 -0700370 self.prompt ],
Jon Hall3576f572016-08-23 10:01:07 -0700371 timeout=timeout )
372 output += str( self.handle.before + self.handle.after )
373 if i == 0:
374 main.log.error( "Wrong location" )
375 ret = main.FALSE
376 elif i == 1:
377 # end of a line, buck is still printing output
378 pass
379 elif i == 2:
380 # Build failed
381 main.log.error( "Build failed" )
382 ret = main.FALSE
383 elif i == 3:
Jon Halld9066132018-03-01 14:52:53 -0800384 main.log.error( "Could not find buck in your PATH." )
385 ret = main.FALSE
386 elif i == 4:
Jon Hall3576f572016-08-23 10:01:07 -0700387 # Prompt returned
388 break
389 main.log.debug( output )
390 return ret
391 except pexpect.TIMEOUT:
392 main.log.exception( self.name + ": TIMEOUT exception found" )
393 main.log.error( self.name + ": " + self.handle.before )
You Wang141b43b2018-06-26 16:50:18 -0700394 self.handle.send( "\x03" ) # Control-C
395 self.handle.expect( self.prompt )
Jon Hall3576f572016-08-23 10:01:07 -0700396 return main.FALSE
397 except pexpect.EOF:
398 main.log.error( self.name + ": EOF exception found" )
399 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700400 main.cleanAndExit()
Jon Hall3576f572016-08-23 10:01:07 -0700401 except Exception:
402 main.log.exception( "Failed to build and package ONOS" )
Devin Lim44075962017-08-11 10:56:37 -0700403 main.cleanAndExit()
Jon Hall3576f572016-08-23 10:01:07 -0700404
You Wangd54c7052018-08-07 16:06:27 -0700405 def bazelBuild( self, timeout=180 ):
406 """
407 Build onos using bazel.
408 """
409 try:
410 ret = main.TRUE
411 self.handle.sendline( "bazel build onos" )
412 self.handle.expect( "bazel build onos" )
413 output = ""
414 while True:
415 i = self.handle.expect( [ "command is only supported from within a workspace",
416 "\n",
417 "FAILED",
418 "ERROR",
419 "command not found",
420 self.prompt ],
421 timeout=timeout )
422 output += str( self.handle.before + self.handle.after )
423 if i == 0:
424 main.log.error( "Please run the build from root of ONOS project" )
425 ret = main.FALSE
426 elif i == 1:
427 # end of a line, buck is still printing output
428 pass
429 elif i == 2:
430 # Build failed
431 main.log.error( "Build failed" )
432 ret = main.FALSE
433 elif i == 3:
434 # Build failed
435 main.log.error( "Build failed" )
436 ret = main.FALSE
437 elif i == 4:
438 main.log.error( "Command not found" )
439 ret = main.FALSE
440 elif i == 5:
441 # Prompt returned
442 break
443 main.log.debug( output )
444 return ret
445 except pexpect.TIMEOUT:
446 main.log.exception( self.name + ": TIMEOUT exception found" )
447 main.log.error( self.name + ": " + self.handle.before )
448 self.handle.send( "\x03" ) # Control-C
449 self.handle.expect( self.prompt )
450 return main.FALSE
451 except pexpect.EOF:
452 main.log.error( self.name + ": EOF exception found" )
453 main.log.error( self.name + ": " + self.handle.before )
454 main.cleanAndExit()
455 except Exception:
456 main.log.exception( "Failed to build and package ONOS" )
457 main.cleanAndExit()
458
Jon Hall61282e32015-03-19 11:34:11 -0700459 def gitPull( self, comp1="", fastForward=True ):
kelvin8ec71442015-01-15 16:57:00 -0800460 """
Jon Hallacabffd2014-10-09 12:36:53 -0400461 Assumes that "git pull" works without login
Jon Hall47a93fb2015-01-06 16:46:06 -0800462
Jon Hall61282e32015-03-19 11:34:11 -0700463 If the fastForward boolean is set to true, only git pulls that can
464 be fast forwarded will be performed. IE if you have not local commits
465 in your branch.
466
Jon Hallacabffd2014-10-09 12:36:53 -0400467 This function will perform a git pull on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800468 If used as gitPull( "NODE" ) it will do git pull + NODE. This is
Jon Hallacabffd2014-10-09 12:36:53 -0400469 for the purpose of pulling from other nodes if necessary.
470
Jon Hall47a93fb2015-01-06 16:46:06 -0800471 Otherwise, this function will perform a git pull in the
Jon Hallacabffd2014-10-09 12:36:53 -0400472 ONOS repository. If it has any problems, it will return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -0800473 If it successfully does a gitPull, it will return a 1 ( main.TRUE )
Shreya Shahee15f6c2014-10-28 18:12:30 -0400474 If it has no updates, it will return 3.
Jon Hallacabffd2014-10-09 12:36:53 -0400475
kelvin8ec71442015-01-15 16:57:00 -0800476 """
Jon Hallacabffd2014-10-09 12:36:53 -0400477 try:
kelvin8ec71442015-01-15 16:57:00 -0800478 self.handle.sendline( "cd " + self.home )
Devin Limc20e79a2017-06-07 10:29:57 -0700479 self.handle.expect( self.prompt )
Jon Hall61282e32015-03-19 11:34:11 -0700480 cmd = "git pull"
481 if comp1 != "":
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700482 cmd += ' ' + comp1
Jon Hall61282e32015-03-19 11:34:11 -0700483 if fastForward:
484 cmd += ' ' + " --ff-only"
485 self.handle.sendline( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800486 i = self.handle.expect(
487 [
488 'fatal',
489 'Username\sfor\s(.*):\s',
490 '\sfile(s*) changed,\s',
491 'Already up-to-date',
492 'Aborting',
493 'You\sare\snot\scurrently\son\sa\sbranch',
Jon Hall274b6642015-02-17 11:57:17 -0800494 'You asked me to pull without telling me which branch you',
495 'Pull is not possible because you have unmerged files',
Jon Hall61282e32015-03-19 11:34:11 -0700496 'Please enter a commit message to explain why this merge',
497 'Found a swap file by the name',
498 'Please, commit your changes before you can merge.',
kelvin-onlabd3b64892015-01-20 13:26:24 -0800499 pexpect.TIMEOUT ],
500 timeout=300 )
kelvin8ec71442015-01-15 16:57:00 -0800501 if i == 0:
Jon Hall61282e32015-03-19 11:34:11 -0700502 main.log.error( self.name + ": Git pull had some issue" )
503 output = self.handle.after
Devin Limdc78e202017-06-09 18:30:07 -0700504 self.handle.expect( self.prompt )
Jon Hall61282e32015-03-19 11:34:11 -0700505 output += self.handle.before
506 main.log.warn( output )
Jon Hallacabffd2014-10-09 12:36:53 -0400507 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800508 elif i == 1:
509 main.log.error(
510 self.name +
511 ": Git Pull Asking for username. " )
Jon Hallacabffd2014-10-09 12:36:53 -0400512 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800513 elif i == 2:
514 main.log.info(
515 self.name +
516 ": Git Pull - pulling repository now" )
Devin Limc20e79a2017-06-07 10:29:57 -0700517 self.handle.expect( self.prompt, 120 )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800518 # So that only when git pull is done, we do mvn clean compile
519 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800520 elif i == 3:
521 main.log.info( self.name + ": Git Pull - Already up to date" )
Devin Limc20e79a2017-06-07 10:29:57 -0700522 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800523 elif i == 4:
524 main.log.info(
525 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800526 ": Git Pull - Aborting..." +
527 "Are there conflicting git files?" )
Jon Hallacabffd2014-10-09 12:36:53 -0400528 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800529 elif i == 5:
530 main.log.info(
531 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800532 ": Git Pull - You are not currently " +
533 "on a branch so git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400534 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800535 elif i == 6:
536 main.log.info(
537 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800538 ": Git Pull - You have not configured an upstream " +
539 "branch to pull from. Git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400540 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800541 elif i == 7:
542 main.log.info(
543 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800544 ": Git Pull - Pull is not possible because " +
545 "you have unmerged files." )
Jon Hallacabffd2014-10-09 12:36:53 -0400546 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800547 elif i == 8:
Jon Hall61282e32015-03-19 11:34:11 -0700548 # NOTE: abandoning test since we can't reliably handle this
549 # there could be different default text editors and we
550 # also don't know if we actually want to make the commit
551 main.log.error( "Git pull resulted in a merge commit message" +
552 ". Exiting test!" )
Devin Lim44075962017-08-11 10:56:37 -0700553
554 main.cleanAndExit()
Jon Hall61282e32015-03-19 11:34:11 -0700555 elif i == 9: # Merge commit message but swap file exists
556 main.log.error( "Git pull resulted in a merge commit message" +
557 " but a swap file exists." )
558 try:
559 self.handle.send( 'A' ) # Abort
Devin Limc20e79a2017-06-07 10:29:57 -0700560 self.handle.expect( self.prompt )
Jon Hall61282e32015-03-19 11:34:11 -0700561 return main.ERROR
562 except Exception:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700563 main.log.exception( "Couldn't exit editor prompt!" )
Devin Lim44075962017-08-11 10:56:37 -0700564
565 main.cleanAndExit()
Jon Hall61282e32015-03-19 11:34:11 -0700566 elif i == 10: # In the middle of a merge commit
567 main.log.error( "Git branch is in the middle of a merge. " )
568 main.log.warn( self.handle.before + self.handle.after )
569 return main.ERROR
570 elif i == 11:
kelvin8ec71442015-01-15 16:57:00 -0800571 main.log.error( self.name + ": Git Pull - TIMEOUT" )
572 main.log.error(
573 self.name + " Response was: " + str(
574 self.handle.before ) )
You Wang141b43b2018-06-26 16:50:18 -0700575 self.handle.send( "\x03" ) # Control-C
576 self.handle.expect( self.prompt )
Jon Hallacabffd2014-10-09 12:36:53 -0400577 return main.ERROR
578 else:
kelvin8ec71442015-01-15 16:57:00 -0800579 main.log.error(
580 self.name +
581 ": Git Pull - Unexpected response, check for pull errors" )
Jon Hallacabffd2014-10-09 12:36:53 -0400582 return main.ERROR
583 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800584 main.log.error( self.name + ": EOF exception found" )
585 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700586 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800587 except Exception:
588 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700589 main.cleanAndExit()
Jon Hallacabffd2014-10-09 12:36:53 -0400590
kelvin-onlabd3b64892015-01-20 13:26:24 -0800591 def gitCheckout( self, branch="master" ):
kelvin8ec71442015-01-15 16:57:00 -0800592 """
Jon Hallacabffd2014-10-09 12:36:53 -0400593 Assumes that "git pull" works without login
kelvin8ec71442015-01-15 16:57:00 -0800594
Jon Hallacabffd2014-10-09 12:36:53 -0400595 This function will perform a git git checkout on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800596 If used as gitCheckout( "branch" ) it will do git checkout
597 of the "branch".
Jon Hallacabffd2014-10-09 12:36:53 -0400598
599 Otherwise, this function will perform a git checkout of the master
kelvin8ec71442015-01-15 16:57:00 -0800600 branch of the ONOS repository. If it has any problems, it will return
601 main.ERROR.
602 If the branch was already the specified branch, or the git checkout was
Jon Hallacabffd2014-10-09 12:36:53 -0400603 successful then the function will return main.TRUE.
604
kelvin8ec71442015-01-15 16:57:00 -0800605 """
Jon Hallacabffd2014-10-09 12:36:53 -0400606 try:
kelvin8ec71442015-01-15 16:57:00 -0800607 self.handle.sendline( "cd " + self.home )
Devin Limc20e79a2017-06-07 10:29:57 -0700608 self.handle.expect( self.prompt )
Jon Hall274b6642015-02-17 11:57:17 -0800609 main.log.info( self.name +
610 ": Checking out git branch/ref: " + branch + "..." )
kelvin8ec71442015-01-15 16:57:00 -0800611 cmd = "git checkout " + branch
612 self.handle.sendline( cmd )
613 self.handle.expect( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800614 i = self.handle.expect(
Jon Hall274b6642015-02-17 11:57:17 -0800615 [ 'fatal',
Jon Hall61282e32015-03-19 11:34:11 -0700616 'Username for (.*): ',
617 'Already on \'',
Jon Hall7a8354f2015-06-10 15:37:00 -0700618 'Switched to (a new )?branch \'' + str( branch ),
Jon Hall274b6642015-02-17 11:57:17 -0800619 pexpect.TIMEOUT,
620 'error: Your local changes to the following files' +
Jon Hallefbd9792015-03-05 16:11:36 -0800621 'would be overwritten by checkout:',
Jon Hall274b6642015-02-17 11:57:17 -0800622 'error: you need to resolve your current index first',
623 "You are in 'detached HEAD' state.",
624 "HEAD is now at " ],
kelvin-onlabd3b64892015-01-20 13:26:24 -0800625 timeout=60 )
kelvin8ec71442015-01-15 16:57:00 -0800626 if i == 0:
627 main.log.error(
628 self.name +
629 ": Git checkout had some issue..." )
630 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400631 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800632 elif i == 1:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800633 main.log.error(
634 self.name +
635 ": Git checkout asking for username." +
636 " Please configure your local git repository to be able " +
637 "to access your remote repository passwordlessly" )
Jon Hall274b6642015-02-17 11:57:17 -0800638 # TODO add support for authenticating
Jon Hallacabffd2014-10-09 12:36:53 -0400639 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800640 elif i == 2:
641 main.log.info(
642 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800643 ": Git Checkout %s : Already on this branch" % branch )
Devin Limc20e79a2017-06-07 10:29:57 -0700644 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -0800645 # main.log.info( "DEBUG: after checkout cmd = "+
646 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400647 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800648 elif i == 3:
649 main.log.info(
650 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800651 ": Git checkout %s - Switched to this branch" % branch )
Devin Limc20e79a2017-06-07 10:29:57 -0700652 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -0800653 # main.log.info( "DEBUG: after checkout cmd = "+
654 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400655 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800656 elif i == 4:
657 main.log.error( self.name + ": Git Checkout- TIMEOUT" )
658 main.log.error(
Jon Hall274b6642015-02-17 11:57:17 -0800659 self.name + " Response was: " + str( self.handle.before ) )
You Wang141b43b2018-06-26 16:50:18 -0700660 self.handle.send( "\x03" ) # Control-C
661 self.handle.expect( self.prompt )
Jon Hallacabffd2014-10-09 12:36:53 -0400662 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800663 elif i == 5:
664 self.handle.expect( "Aborting" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800665 main.log.error(
666 self.name +
667 ": Git checkout error: \n" +
Jon Hall274b6642015-02-17 11:57:17 -0800668 "Your local changes to the following files would" +
669 " be overwritten by checkout:" +
670 str( self.handle.before ) )
Devin Limc20e79a2017-06-07 10:29:57 -0700671 self.handle.expect( self.prompt )
Jon Hall81e29af2014-11-04 20:41:23 -0500672 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800673 elif i == 6:
Jon Hall274b6642015-02-17 11:57:17 -0800674 main.log.error(
675 self.name +
676 ": Git checkout error: \n" +
677 "You need to resolve your current index first:" +
678 str( self.handle.before ) )
Devin Limc20e79a2017-06-07 10:29:57 -0700679 self.handle.expect( self.prompt )
Jon Hall81e29af2014-11-04 20:41:23 -0500680 return main.ERROR
Jon Hall274b6642015-02-17 11:57:17 -0800681 elif i == 7:
682 main.log.info(
683 self.name +
684 ": Git checkout " + str( branch ) +
685 " - You are in 'detached HEAD' state. HEAD is now at " +
686 str( branch ) )
Devin Limc20e79a2017-06-07 10:29:57 -0700687 self.handle.expect( self.prompt )
Jon Hall274b6642015-02-17 11:57:17 -0800688 return main.TRUE
689 elif i == 8: # Already in detached HEAD on the specified commit
690 main.log.info(
691 self.name +
692 ": Git Checkout %s : Already on commit" % branch )
Devin Limc20e79a2017-06-07 10:29:57 -0700693 self.handle.expect( self.prompt )
Jon Hall274b6642015-02-17 11:57:17 -0800694 return main.TRUE
Jon Hallacabffd2014-10-09 12:36:53 -0400695 else:
kelvin8ec71442015-01-15 16:57:00 -0800696 main.log.error(
697 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800698 ": Git Checkout - Unexpected response, " +
699 "check for pull errors" )
kelvin8ec71442015-01-15 16:57:00 -0800700 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400701 return main.ERROR
702
703 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800704 main.log.error( self.name + ": EOF exception found" )
705 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700706 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800707 except Exception:
708 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700709 main.cleanAndExit()
andrewonlab95ca1462014-10-09 14:04:24 -0400710
pingping-lin6d23d9e2015-02-02 16:54:24 -0800711 def getBranchName( self ):
You Wang9cdf9a22017-05-01 13:44:18 -0700712 import re
713 try:
Jon Hall3e6edb32018-08-21 16:20:30 -0700714 main.log.info( self.name + " home is " + self.home )
You Wang9cdf9a22017-05-01 13:44:18 -0700715 self.handle.sendline( "cd " + self.home )
Devin Limc20e79a2017-06-07 10:29:57 -0700716 self.handle.expect( self.prompt )
You Wang9cdf9a22017-05-01 13:44:18 -0700717 self.handle.sendline( "git name-rev --name-only HEAD" )
718 self.handle.expect( "git name-rev --name-only HEAD" )
Devin Limc20e79a2017-06-07 10:29:57 -0700719 self.handle.expect( self.prompt )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700720 lines = self.handle.before.splitlines()
721 if lines[ 1 ] == "master" or re.search( "^onos-\d+(\.\d+)+$", lines[ 1 ] ):
722 return lines[ 1 ]
You Wang9cdf9a22017-05-01 13:44:18 -0700723 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700724 main.log.info( lines[ 1 ] )
You Wang9cdf9a22017-05-01 13:44:18 -0700725 return "unexpected ONOS branch"
726 except pexpect.EOF:
727 main.log.error( self.name + ": EOF exception found" )
728 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700729 main.cleanAndExit()
You Wang9cdf9a22017-05-01 13:44:18 -0700730 except pexpect.TIMEOUT:
731 main.log.error( self.name + ": TIMEOUT exception found" )
732 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700733 main.cleanAndExit()
You Wang9cdf9a22017-05-01 13:44:18 -0700734 except Exception:
735 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700736 main.cleanAndExit()
pingping-lin6d23d9e2015-02-02 16:54:24 -0800737
kelvin-onlabd3b64892015-01-20 13:26:24 -0800738 def getVersion( self, report=False ):
kelvin8ec71442015-01-15 16:57:00 -0800739 """
Jon Hall274b6642015-02-17 11:57:17 -0800740 Writes the COMMIT number to the report to be parsed
Jon Hallefbd9792015-03-05 16:11:36 -0800741 by Jenkins data collector.
kelvin8ec71442015-01-15 16:57:00 -0800742 """
Jon Hall45ec0922014-10-10 19:33:49 -0400743 try:
kelvin8ec71442015-01-15 16:57:00 -0800744 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -0700745 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -0800746 self.handle.sendline(
747 "cd " +
748 self.home +
Jon Hall274b6642015-02-17 11:57:17 -0800749 "; git log -1 --pretty=fuller --decorate=short | grep -A 6 " +
750 " \"commit\" --color=never" )
kelvin8ec71442015-01-15 16:57:00 -0800751 # NOTE: for some reason there are backspaces inserted in this
752 # phrase when run from Jenkins on some tests
753 self.handle.expect( "never" )
Devin Limc20e79a2017-06-07 10:29:57 -0700754 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -0800755 response = ( self.name + ": \n" + str(
756 self.handle.before + self.handle.after ) )
757 self.handle.sendline( "cd " + self.home )
Devin Limc20e79a2017-06-07 10:29:57 -0700758 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -0800759 lines = response.splitlines()
Jon Hall45ec0922014-10-10 19:33:49 -0400760 for line in lines:
Jon Hallfd191202014-11-07 18:36:09 -0500761 print line
762 if report:
pingping-lin763ee042015-05-20 17:45:30 -0700763 main.log.wiki( "<blockquote>" )
kelvin8ec71442015-01-15 16:57:00 -0800764 for line in lines[ 2:-1 ]:
765 # Bracket replacement is for Wiki-compliant
766 # formatting. '<' or '>' are interpreted
767 # as xml specific tags that cause errors
768 line = line.replace( "<", "[" )
769 line = line.replace( ">", "]" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700770 # main.log.wiki( "\t" + line )
pingping-lin763ee042015-05-20 17:45:30 -0700771 main.log.wiki( line + "<br /> " )
772 main.log.summary( line )
773 main.log.wiki( "</blockquote>" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700774 main.log.summary( "\n" )
kelvin8ec71442015-01-15 16:57:00 -0800775 return lines[ 2 ]
Jon Hall45ec0922014-10-10 19:33:49 -0400776 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800777 main.log.error( self.name + ": EOF exception found" )
778 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700779 main.cleanAndExit()
Jon Hall368769f2014-11-19 15:43:35 -0800780 except pexpect.TIMEOUT:
kelvin8ec71442015-01-15 16:57:00 -0800781 main.log.error( self.name + ": TIMEOUT exception found" )
782 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700783 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800784 except Exception:
785 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700786 main.cleanAndExit()
Jon Hall45ec0922014-10-10 19:33:49 -0400787
kelvin-onlabd3b64892015-01-20 13:26:24 -0800788 def createCellFile( self, benchIp, fileName, mnIpAddrs,
Jon Hall3e6edb32018-08-21 16:20:30 -0700789 appString, onosIpAddrs, atomixIps,
790 onosUser="sdn", useSSH=True ):
kelvin8ec71442015-01-15 16:57:00 -0800791 """
andrewonlab94282092014-10-10 13:00:11 -0400792 Creates a cell file based on arguments
793 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800794 * Bench IP address ( benchIp )
andrewonlab94282092014-10-10 13:00:11 -0400795 - Needed to copy the cell file over
kelvin-onlabd3b64892015-01-20 13:26:24 -0800796 * File name of the cell file ( fileName )
797 * Mininet IP address ( mnIpAddrs )
kelvin8ec71442015-01-15 16:57:00 -0800798 - Note that only 1 ip address is
andrewonlab94282092014-10-10 13:00:11 -0400799 supported currently
kelvin-onlabd3b64892015-01-20 13:26:24 -0800800 * ONOS IP addresses ( onosIpAddrs )
andrewonlab94282092014-10-10 13:00:11 -0400801 - Must be passed in as last arguments
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000802 * ONOS USER (onosUser)
Flavio Castrocc38a542016-03-03 13:15:46 -0800803 - optional argument to set ONOS_USER environment variable
kelvin8ec71442015-01-15 16:57:00 -0800804
andrewonlab94282092014-10-10 13:00:11 -0400805 NOTE: Assumes cells are located at:
806 ~/<self.home>/tools/test/cells/
kelvin8ec71442015-01-15 16:57:00 -0800807 """
andrewonlab94282092014-10-10 13:00:11 -0400808 try:
Devin Lim461f0872017-06-05 16:49:33 -0700809
Jon Hall2c8959e2016-12-16 12:17:34 -0800810 # Variable initialization
811 cellDirectory = self.home + "/tools/test/cells/"
812 # We want to create the cell file in the dependencies directory
813 # of TestON first, then copy over to ONOS bench
814 tempDirectory = "/tmp/"
815 # Create the cell file in the directory for writing ( w+ )
816 cellFile = open( tempDirectory + fileName, 'w+' )
817 if isinstance( onosIpAddrs, types.StringType ):
818 onosIpAddrs = [ onosIpAddrs ]
Jon Hall3e6edb32018-08-21 16:20:30 -0700819 if isinstance( atomixIps, types.StringType ):
820 atomixIps = [ atomixIps ]
Jon Hall2c8959e2016-12-16 12:17:34 -0800821
822 # App string is hardcoded environment variables
823 # That you may wish to use by default on startup.
824 # Note that you may not want certain apps listed
825 # on here.
826 appString = "export ONOS_APPS=" + appString
827 onosGroup = "export ONOS_GROUP=" + onosUser
828 onosUser = "export ONOS_USER=" + onosUser
829 if useSSH:
830 onosUseSSH = "export ONOS_USE_SSH=true"
831 mnString = "export OCN="
832 if mnIpAddrs == "":
833 mnString = ""
834 onosString = "export OC"
Jon Hall3e6edb32018-08-21 16:20:30 -0700835 atomixString = "export OCC"
Jon Hall2c8959e2016-12-16 12:17:34 -0800836
837 # Create ONOSNIC ip address prefix
838 tempOnosIp = str( onosIpAddrs[ 0 ] )
839 tempList = []
840 tempList = tempOnosIp.split( "." )
841 # Omit last element of list to format for NIC
842 tempList = tempList[ :-1 ]
843 # Structure the nic string ip
844 nicAddr = ".".join( tempList ) + ".*"
845 self.nicAddr = nicAddr
846 onosNicString = "export ONOS_NIC=" + nicAddr
847
kelvin8ec71442015-01-15 16:57:00 -0800848 # Start writing to file
kelvin-onlabd3b64892015-01-20 13:26:24 -0800849 cellFile.write( onosNicString + "\n" )
andrewonlab94282092014-10-10 13:00:11 -0400850
Jon Hall3e6edb32018-08-21 16:20:30 -0700851 onosIndex = 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800852 for arg in onosIpAddrs:
853 # For each argument in onosIpAddrs, write to file
kelvin8ec71442015-01-15 16:57:00 -0800854 # Output should look like the following:
andrewonlabd4940492014-10-24 12:21:27 -0400855 # export OC1="10.128.20.11"
856 # export OC2="10.128.20.12"
Jon Hall3e6edb32018-08-21 16:20:30 -0700857 cellFile.write( onosString + str( onosIndex ) +
Jon Hall6f665652015-09-18 10:08:07 -0700858 "=\"" + arg + "\"\n" )
Jon Hall3e6edb32018-08-21 16:20:30 -0700859 onosIndex = onosIndex + 1
860
861 atomixIndex = 1
862 for ip in atomixIps:
863 cellFile.write( atomixString + str( atomixIndex ) +
864 "=\"" + ip + "\"\n" )
865 atomixIndex += 1
kelvin8ec71442015-01-15 16:57:00 -0800866
Jon Hall6f665652015-09-18 10:08:07 -0700867 cellFile.write( "export OCI=$OC1\n" )
Jon Hallab611372018-02-21 15:26:05 -0800868 if mnString:
869 cellFile.write( mnString + "\"" + str( mnIpAddrs ) + "\"\n" )
cameron@onlab.us75900962015-03-30 13:22:49 -0700870 cellFile.write( appString + "\n" )
Flavio Castrocc38a542016-03-03 13:15:46 -0800871 cellFile.write( onosGroup + "\n" )
872 cellFile.write( onosUser + "\n" )
Pier88189b62016-09-07 17:01:53 -0700873 if useSSH:
874 cellFile.write( onosUseSSH + "\n" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800875 cellFile.close()
andrewonlab94282092014-10-10 13:00:11 -0400876
kelvin8ec71442015-01-15 16:57:00 -0800877 # We use os.system to send the command to TestON cluster
878 # to account for the case in which TestON is not located
879 # on the same cluster as the ONOS bench
880 # Note that even if TestON is located on the same cluster
881 # as ONOS bench, you must setup passwordless ssh
882 # between TestON and ONOS bench in order to automate the test.
kelvin-onlabc2b79102015-07-14 11:41:20 -0700883 os.system( "scp " + tempDirectory + fileName + " " +
884 self.user_name + "@" + self.ip_address + ":" + cellDirectory )
andrewonlab94282092014-10-10 13:00:11 -0400885
andrewonlab2a6c9342014-10-16 13:40:15 -0400886 return main.TRUE
887
andrewonlab94282092014-10-10 13:00:11 -0400888 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800889 main.log.error( self.name + ": EOF exception found" )
890 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700891 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800892 except Exception:
893 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700894 main.cleanAndExit()
andrewonlab94282092014-10-10 13:00:11 -0400895
kelvin-onlabd3b64892015-01-20 13:26:24 -0800896 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800897 """
andrewonlab95ca1462014-10-09 14:04:24 -0400898 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800899 """
andrewonlab95ca1462014-10-09 14:04:24 -0400900 try:
901 if not cellname:
You Wang1cdc5f52017-12-19 16:47:51 -0800902 main.log.error( self.name + ": Must define cellname" )
Devin Lim44075962017-08-11 10:56:37 -0700903 main.cleanAndExit()
andrewonlab95ca1462014-10-09 14:04:24 -0400904 else:
kelvin8ec71442015-01-15 16:57:00 -0800905 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800906 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800907 # Note that this variable name is subject to change
andrewonlab95ca1462014-10-09 14:04:24 -0400908 # and that this driver will have to change accordingly
Jon Hall3b489db2015-10-05 14:38:37 -0700909 self.handle.expect( str( cellname ) )
Jon Hallab611372018-02-21 15:26:05 -0800910 response = self.handle.before + self.handle.after
You Wang1cdc5f52017-12-19 16:47:51 -0800911 i = self.handle.expect( [ "No such cell",
Jon Hallab611372018-02-21 15:26:05 -0800912 "command not found",
913 self.prompt ], timeout=10 )
914 response += self.handle.before + self.handle.after
You Wang1cdc5f52017-12-19 16:47:51 -0800915 if i == 0:
Jon Hallab611372018-02-21 15:26:05 -0800916 main.log.error( self.name + ": No such cell. Response: " + str( response ) )
You Wang1cdc5f52017-12-19 16:47:51 -0800917 main.cleanAndExit()
918 elif i == 1:
Jon Hallab611372018-02-21 15:26:05 -0800919 main.log.error( self.name + ": Error setting cell. Response: " + str( response ) )
920 main.cleanAndExit()
You Wang1cdc5f52017-12-19 16:47:51 -0800921 elif i == 2:
Jon Hallab611372018-02-21 15:26:05 -0800922 main.log.info( self.name + ": Successfully set cell: " + str( response ) )
andrewonlab95ca1462014-10-09 14:04:24 -0400923 return main.TRUE
You Wang1cdc5f52017-12-19 16:47:51 -0800924 except pexpect.TIMEOUT:
925 main.log.error( self.name + ": TIMEOUT exception found" )
926 main.log.error( self.name + ": " + self.handle.before )
927 main.cleanAndExit()
andrewonlab95ca1462014-10-09 14:04:24 -0400928 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800929 main.log.error( self.name + ": EOF exception found" )
930 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700931 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800932 except Exception:
933 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700934 main.cleanAndExit()
andrewonlab95ca1462014-10-09 14:04:24 -0400935
kelvin-onlabd3b64892015-01-20 13:26:24 -0800936 def verifyCell( self ):
kelvin8ec71442015-01-15 16:57:00 -0800937 """
andrewonlabc03bf6c2014-10-09 14:56:18 -0400938 Calls 'onos-verify-cell' to check for cell installation
kelvin8ec71442015-01-15 16:57:00 -0800939 """
940 # TODO: Add meaningful expect value
andrewonlab8d0d7d72014-10-09 16:33:15 -0400941
andrewonlabc03bf6c2014-10-09 14:56:18 -0400942 try:
kelvin8ec71442015-01-15 16:57:00 -0800943 # Clean handle by sending empty and expecting $
944 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -0700945 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -0800946 self.handle.sendline( "onos-verify-cell" )
Devin Limc20e79a2017-06-07 10:29:57 -0700947 self.handle.expect( self.prompt )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800948 handleBefore = self.handle.before
949 handleAfter = self.handle.after
kelvin-onlabd3b64892015-01-20 13:26:24 -0800950 main.log.info( "Verify cell returned: " + handleBefore +
Jon Hall3b489db2015-10-05 14:38:37 -0700951 handleAfter )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400952 return main.TRUE
Jon Hall3e6edb32018-08-21 16:20:30 -0700953 except pexpect.ExceptionPexpect:
Jon Hall3b489db2015-10-05 14:38:37 -0700954 main.log.exception( self.name + ": Pexpect exception found: " )
kelvin8ec71442015-01-15 16:57:00 -0800955 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700956 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800957 except Exception:
958 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700959 main.cleanAndExit()
Jon Hall7993bfc2014-10-09 16:30:14 -0400960
jenkins1e99e7b2015-04-02 18:15:39 -0700961 def onosCfgSet( self, ONOSIp, configName, configParam ):
962 """
963 Uses 'onos <node-ip> cfg set' to change a parameter value of an
Jon Hall4ba53f02015-07-29 13:07:41 -0700964 application.
965
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000966 ex)
jenkins1e99e7b2015-04-02 18:15:39 -0700967 onos 10.0.0.1 cfg set org.onosproject.myapp appSetting 1
jenkins1e99e7b2015-04-02 18:15:39 -0700968 ONOSIp = '10.0.0.1'
969 configName = 'org.onosproject.myapp'
970 configParam = 'appSetting 1'
jenkins1e99e7b2015-04-02 18:15:39 -0700971 """
Jon Hall72280bc2016-01-25 14:29:05 -0800972 try:
973 cfgStr = "onos {} cfg set {} {}".format( ONOSIp,
974 configName,
975 configParam )
976 self.handle.sendline( "" )
977 self.handle.expect( ":~" )
978 self.handle.sendline( cfgStr )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700979 self.handle.expect( "cfg set" )
Jon Hall72280bc2016-01-25 14:29:05 -0800980 self.handle.expect( ":~" )
jenkins1e99e7b2015-04-02 18:15:39 -0700981
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700982 paramValue = configParam.split( " " )[ 1 ]
983 paramName = configParam.split( " " )[ 0 ]
Jon Hall4ba53f02015-07-29 13:07:41 -0700984
Jon Hall72280bc2016-01-25 14:29:05 -0800985 checkStr = 'onos {} cfg get " {} {} " '.format( ONOSIp, configName, paramName )
Jon Hall4ba53f02015-07-29 13:07:41 -0700986
Jon Hall72280bc2016-01-25 14:29:05 -0800987 self.handle.sendline( checkStr )
988 self.handle.expect( ":~" )
jenkins1e99e7b2015-04-02 18:15:39 -0700989
Jon Hall72280bc2016-01-25 14:29:05 -0800990 if "value=" + paramValue + "," in self.handle.before:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700991 main.log.info( "cfg " + configName + " successfully set to " + configParam )
Jon Hall72280bc2016-01-25 14:29:05 -0800992 return main.TRUE
Jon Hall3e6edb32018-08-21 16:20:30 -0700993 except pexpect.ExceptionPexpect:
Jon Hall72280bc2016-01-25 14:29:05 -0800994 main.log.exception( self.name + ": Pexpect exception found: " )
995 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700996 main.cleanAndExit()
Jon Hall72280bc2016-01-25 14:29:05 -0800997 except Exception:
998 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700999 main.cleanAndExit()
Jon Hall4ba53f02015-07-29 13:07:41 -07001000
You Wang54b1d672018-06-11 16:44:13 -07001001 def onosCli( self, ONOSIp, cmdstr, timeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -08001002 """
andrewonlab05e362f2014-10-10 00:40:57 -04001003 Uses 'onos' command to send various ONOS CLI arguments.
1004 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001005 * ONOSIp: specify the ip of the cell machine
andrewonlab94282092014-10-10 13:00:11 -04001006 * cmdstr: specify the command string to send
You Wang54b1d672018-06-11 16:44:13 -07001007 Optional:
1008 * timeout: pexpect timeout for running the command
kelvin8ec71442015-01-15 16:57:00 -08001009
1010 This function is intended to expose the entire karaf
andrewonlab6e20c342014-10-10 18:08:48 -04001011 CLI commands for ONOS. Try to use this function first
1012 before attempting to write a ONOS CLI specific driver
kelvin8ec71442015-01-15 16:57:00 -08001013 function.
1014 You can see a list of available 'cmdstr' arguments
andrewonlab6e20c342014-10-10 18:08:48 -04001015 by starting onos, and typing in 'onos' to enter the
1016 onos> CLI. Then, type 'help' to see the list of
kelvin8ec71442015-01-15 16:57:00 -08001017 available commands.
1018 """
andrewonlab05e362f2014-10-10 00:40:57 -04001019 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001020 if not ONOSIp:
kelvin8ec71442015-01-15 16:57:00 -08001021 main.log.error( "You must specify the IP address" )
andrewonlab05e362f2014-10-10 00:40:57 -04001022 return main.FALSE
1023 if not cmdstr:
kelvin8ec71442015-01-15 16:57:00 -08001024 main.log.error( "You must specify the command string" )
andrewonlab05e362f2014-10-10 00:40:57 -04001025 return main.FALSE
1026
kelvin8ec71442015-01-15 16:57:00 -08001027 cmdstr = str( cmdstr )
1028 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001029 self.handle.expect( self.prompt )
andrewonlab05e362f2014-10-10 00:40:57 -04001030
You Wangdd3dae52018-02-15 13:31:25 -08001031 self.handle.sendline( "onos-wait-for-start " + ONOSIp )
1032 self.handle.expect( self.prompt )
1033
1034 self.handle.sendline( "onos " + ONOSIp + " " + cmdstr )
You Wang54b1d672018-06-11 16:44:13 -07001035 i = self.handle.expect( [ self.prompt, pexpect.TIMEOUT ], timeout=timeout )
1036 if i == 0:
1037 handleBefore = self.handle.before
1038 main.log.info( "Command sent successfully" )
1039 # Obtain return handle that consists of result from
1040 # the onos command. The string may need to be
1041 # configured further.
1042 returnString = handleBefore
1043 return returnString
1044 elif i == 1:
1045 main.log.error( self.name + ": Timeout when sending " + cmdstr )
You Wang141b43b2018-06-26 16:50:18 -07001046 self.handle.send( "\x03" ) # Control-C
You Wang54b1d672018-06-11 16:44:13 -07001047 self.handle.expect( self.prompt )
1048 return main.FALSE
You Wangd66de192018-04-30 17:30:12 -07001049 except pexpect.TIMEOUT:
1050 main.log.exception( self.name + ": Timeout when sending " + cmdstr )
1051 return main.FALSE
andrewonlab05e362f2014-10-10 00:40:57 -04001052 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001053 main.log.error( self.name + ": EOF exception found" )
1054 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001055 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001056 except Exception:
1057 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001058 main.cleanAndExit()
Jon Hall7993bfc2014-10-09 16:30:14 -04001059
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001060 def onosSecureSSH( self, userName="onos", userPWD="rocks", node="" ):
Pier88189b62016-09-07 17:01:53 -07001061 """
1062 Enables secure access to ONOS console
1063 by removing default users & keys.
1064
1065 onos-secure-ssh -u onos -p rocks node
1066
1067 Returns: main.TRUE on success and main.FALSE on failure
1068 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001069
Pier88189b62016-09-07 17:01:53 -07001070 try:
Chiyu Chengef109502016-11-21 15:51:38 -08001071 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001072 self.handle.expect( self.prompt )
Pier88189b62016-09-07 17:01:53 -07001073 self.handle.sendline( " onos-secure-ssh -u " + userName + " -p " + userPWD + " " + node )
1074
1075 # NOTE: this timeout may need to change depending on the network
1076 # and size of ONOS
1077 # TODO: Handle the other possible error
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001078 i = self.handle.expect( [ "Network\sis\sunreachable",
1079 self.prompt,
1080 pexpect.TIMEOUT ], timeout=180 )
Pier88189b62016-09-07 17:01:53 -07001081 if i == 0:
1082 # can't reach ONOS node
Jon Hall3e6edb32018-08-21 16:20:30 -07001083 main.log.warn( self.name + ": Network is unreachable" )
Devin Limc20e79a2017-06-07 10:29:57 -07001084 self.handle.expect( self.prompt )
Pier88189b62016-09-07 17:01:53 -07001085 return main.FALSE
1086 elif i == 1:
1087 # Process started
Jon Hall3e6edb32018-08-21 16:20:30 -07001088 main.log.info( self.name + ": Secure SSH performed on " + node )
Pier88189b62016-09-07 17:01:53 -07001089 return main.TRUE
Jon Hall3e6edb32018-08-21 16:20:30 -07001090 elif i == 2:
1091 # timeout
1092 main.log.error( self.name + ": Failed to secure ssh on " + node )
1093 main.log.debug( self.handle.before )
Pier88189b62016-09-07 17:01:53 -07001094 except pexpect.EOF:
1095 main.log.error( self.name + ": EOF exception found" )
1096 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001097 main.cleanAndExit()
Pier88189b62016-09-07 17:01:53 -07001098 except Exception:
1099 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001100 main.cleanAndExit()
Pier88189b62016-09-07 17:01:53 -07001101
kelvin-onlabd3b64892015-01-20 13:26:24 -08001102 def onosInstall( self, options="-f", node="" ):
kelvin8ec71442015-01-15 16:57:00 -08001103 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001104 Installs ONOS bits on the designated cell machine.
kelvin8ec71442015-01-15 16:57:00 -08001105 If -f option is provided, it also forces an uninstall.
1106 Presently, install also includes onos-push-bits and
Jon Hall7993bfc2014-10-09 16:30:14 -04001107 onos-config within.
kelvin8ec71442015-01-15 16:57:00 -08001108 The node option allows you to selectively only push the jar
Jon Hall7993bfc2014-10-09 16:30:14 -04001109 files to certain onos nodes
1110
1111 Returns: main.TRUE on success and main.FALSE on failure
kelvin8ec71442015-01-15 16:57:00 -08001112 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001113 try:
andrewonlab114768a2014-11-14 12:44:44 -05001114 if options:
kelvin8ec71442015-01-15 16:57:00 -08001115 self.handle.sendline( "onos-install " + options + " " + node )
andrewonlab114768a2014-11-14 12:44:44 -05001116 else:
kelvin8ec71442015-01-15 16:57:00 -08001117 self.handle.sendline( "onos-install " + node )
1118 self.handle.expect( "onos-install " )
1119 # NOTE: this timeout may need to change depending on the network
1120 # and size of ONOS
1121 i = self.handle.expect( [ "Network\sis\sunreachable",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001122 "onos\sstart/running,\sprocess",
kelvin8ec71442015-01-15 16:57:00 -08001123 "ONOS\sis\salready\sinstalled",
Jon Hall3576f572016-08-23 10:01:07 -07001124 "does not exist",
Devin Limc20e79a2017-06-07 10:29:57 -07001125 self.prompt,
Jon Hall6c44c0b2016-04-20 15:21:00 -07001126 pexpect.TIMEOUT ], timeout=180 )
Jon Hall7993bfc2014-10-09 16:30:14 -04001127 if i == 0:
Jon Hall3576f572016-08-23 10:01:07 -07001128 # can't reach ONOS node
kelvin8ec71442015-01-15 16:57:00 -08001129 main.log.warn( "Network is unreachable" )
Devin Limc20e79a2017-06-07 10:29:57 -07001130 self.handle.expect( self.prompt )
Jon Hall7993bfc2014-10-09 16:30:14 -04001131 return main.FALSE
1132 elif i == 1:
Jon Hall3576f572016-08-23 10:01:07 -07001133 # Process started
kelvin8ec71442015-01-15 16:57:00 -08001134 main.log.info(
1135 "ONOS was installed on " +
1136 node +
1137 " and started" )
Devin Limc20e79a2017-06-07 10:29:57 -07001138 self.handle.expect( self.prompt )
Jon Hall7993bfc2014-10-09 16:30:14 -04001139 return main.TRUE
You Wangd65ba842018-08-14 11:20:59 -07001140 elif i == 2:
Jon Hall3576f572016-08-23 10:01:07 -07001141 # same bits are already on ONOS node
Jeremyc72b2582016-02-26 18:27:38 -08001142 main.log.info( "ONOS is already installed on " + node )
Devin Limc20e79a2017-06-07 10:29:57 -07001143 self.handle.expect( self.prompt )
Jeremyc72b2582016-02-26 18:27:38 -08001144 return main.TRUE
You Wangd65ba842018-08-14 11:20:59 -07001145 elif i == 3:
Jon Hall3576f572016-08-23 10:01:07 -07001146 # onos not packaged
1147 main.log.error( "ONOS package not found." )
Devin Limc20e79a2017-06-07 10:29:57 -07001148 self.handle.expect( self.prompt )
Jon Hall3576f572016-08-23 10:01:07 -07001149 return main.FALSE
You Wangd65ba842018-08-14 11:20:59 -07001150 elif i == 4:
Jon Hall3576f572016-08-23 10:01:07 -07001151 # prompt
Jon Hall3e6edb32018-08-21 16:20:30 -07001152 main.log.info( "ONOS was installed on {} {}.".format( node,
1153 "but not started" if 'n' in options else "and started" ) )
Jeremyc72b2582016-02-26 18:27:38 -08001154 return main.TRUE
You Wangd65ba842018-08-14 11:20:59 -07001155 elif i == 5:
Jon Hall3576f572016-08-23 10:01:07 -07001156 # timeout
kelvin8ec71442015-01-15 16:57:00 -08001157 main.log.info(
1158 "Installation of ONOS on " +
1159 node +
1160 " timed out" )
Devin Limc20e79a2017-06-07 10:29:57 -07001161 self.handle.expect( self.prompt )
Jon Hall53c5e662016-04-13 16:06:56 -07001162 main.log.warn( self.handle.before )
You Wang141b43b2018-06-26 16:50:18 -07001163 self.handle.send( "\x03" ) # Control-C
1164 self.handle.expect( self.prompt )
Jon Hall7993bfc2014-10-09 16:30:14 -04001165 return main.FALSE
andrewonlabc03bf6c2014-10-09 14:56:18 -04001166 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001167 main.log.error( self.name + ": EOF exception found" )
1168 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001169 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001170 except Exception:
1171 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001172 main.cleanAndExit()
andrewonlab95ca1462014-10-09 14:04:24 -04001173
kelvin-onlabd3b64892015-01-20 13:26:24 -08001174 def onosStart( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001175 """
andrewonlab8d0d7d72014-10-09 16:33:15 -04001176 Calls onos command: 'onos-service [<node-ip>] start'
andrewonlabe8e56fd2014-10-09 17:12:44 -04001177 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -08001178 """
andrewonlab8d0d7d72014-10-09 16:33:15 -04001179 try:
kelvin8ec71442015-01-15 16:57:00 -08001180 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001181 self.handle.expect( self.prompt )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001182 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001183 " start" )
1184 i = self.handle.expect( [
andrewonlab8d0d7d72014-10-09 16:33:15 -04001185 "Job\sis\salready\srunning",
1186 "start/running",
Devin Limc20e79a2017-06-07 10:29:57 -07001187 self.prompt,
andrewonlab8d0d7d72014-10-09 16:33:15 -04001188 "Unknown\sinstance",
Jeremy Songster14c13572016-04-21 17:34:03 -07001189 pexpect.TIMEOUT ], timeout=180 )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001190 if i == 0:
Devin Limc20e79a2017-06-07 10:29:57 -07001191 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -08001192 main.log.info( "Service is already running" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001193 return main.TRUE
1194 elif i == 1:
Devin Limc20e79a2017-06-07 10:29:57 -07001195 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -08001196 main.log.info( "ONOS service started" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001197 return main.TRUE
Jeremyd0e9a6d2016-03-02 11:28:52 -08001198 elif i == 2:
1199 main.log.info( "ONOS service started" )
1200 return main.TRUE
andrewonlab8d0d7d72014-10-09 16:33:15 -04001201 else:
Devin Limc20e79a2017-06-07 10:29:57 -07001202 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -08001203 main.log.error( "ONOS service failed to start" )
Devin Lim44075962017-08-11 10:56:37 -07001204
1205 main.cleanAndExit()
andrewonlab8d0d7d72014-10-09 16:33:15 -04001206 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001207 main.log.error( self.name + ": EOF exception found" )
1208 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001209 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001210 except Exception:
1211 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001212 main.cleanAndExit()
andrewonlab8d0d7d72014-10-09 16:33:15 -04001213
kelvin-onlabd3b64892015-01-20 13:26:24 -08001214 def onosStop( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001215 """
andrewonlab2b30bd32014-10-09 16:48:55 -04001216 Calls onos command: 'onos-service [<node-ip>] stop'
andrewonlabe8e56fd2014-10-09 17:12:44 -04001217 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -08001218 """
andrewonlab2b30bd32014-10-09 16:48:55 -04001219 try:
kelvin8ec71442015-01-15 16:57:00 -08001220 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001221 self.handle.expect( self.prompt )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001222 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001223 " stop" )
1224 i = self.handle.expect( [
andrewonlab2b30bd32014-10-09 16:48:55 -04001225 "stop/waiting",
Jon Hall61282e32015-03-19 11:34:11 -07001226 "Could not resolve hostname",
andrewonlab2b30bd32014-10-09 16:48:55 -04001227 "Unknown\sinstance",
Devin Limc20e79a2017-06-07 10:29:57 -07001228 self.prompt,
Jeremy Songster14c13572016-04-21 17:34:03 -07001229 pexpect.TIMEOUT ], timeout=180 )
andrewonlab2b30bd32014-10-09 16:48:55 -04001230 if i == 0:
Devin Limc20e79a2017-06-07 10:29:57 -07001231 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -08001232 main.log.info( "ONOS service stopped" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001233 return main.TRUE
1234 elif i == 1:
Devin Limc20e79a2017-06-07 10:29:57 -07001235 self.handle.expect( self.prompt )
Jon Hall65844a32015-03-09 19:09:37 -07001236 main.log.info( "onosStop() Unknown ONOS instance specified: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001237 str( nodeIp ) )
andrewonlab2b30bd32014-10-09 16:48:55 -04001238 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -07001239 elif i == 2:
Devin Limc20e79a2017-06-07 10:29:57 -07001240 self.handle.expect( self.prompt )
Jon Hall61282e32015-03-19 11:34:11 -07001241 main.log.warn( "ONOS wasn't running" )
1242 return main.TRUE
YPZhang77badfc2016-03-09 10:28:59 -08001243 elif i == 3:
1244 main.log.info( "ONOS service stopped" )
1245 return main.TRUE
andrewonlab2b30bd32014-10-09 16:48:55 -04001246 else:
kelvin8ec71442015-01-15 16:57:00 -08001247 main.log.error( "ONOS service failed to stop" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001248 return main.FALSE
andrewonlab2b30bd32014-10-09 16:48:55 -04001249 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 )
Devin Lim44075962017-08-11 10:56:37 -07001252 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001253 except Exception:
1254 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001255 main.cleanAndExit()
kelvin8ec71442015-01-15 16:57:00 -08001256
kelvin-onlabd3b64892015-01-20 13:26:24 -08001257 def onosUninstall( self, nodeIp="" ):
kelvin8ec71442015-01-15 16:57:00 -08001258 """
andrewonlabc8d47972014-10-09 16:52:36 -04001259 Calls the command: 'onos-uninstall'
kelvin8ec71442015-01-15 16:57:00 -08001260 Uninstalls ONOS from the designated cell machine, stopping
andrewonlabe8e56fd2014-10-09 17:12:44 -04001261 if needed
kelvin8ec71442015-01-15 16:57:00 -08001262 """
andrewonlabc8d47972014-10-09 16:52:36 -04001263 try:
kelvin8ec71442015-01-15 16:57:00 -08001264 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001265 self.handle.expect( self.prompt, timeout=180 )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001266 self.handle.sendline( "onos-uninstall " + str( nodeIp ) )
Devin Limc20e79a2017-06-07 10:29:57 -07001267 self.handle.expect( self.prompt, timeout=180 )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001268 main.log.info( "ONOS " + nodeIp + " was uninstalled" )
kelvin8ec71442015-01-15 16:57:00 -08001269 # onos-uninstall command does not return any text
andrewonlabc8d47972014-10-09 16:52:36 -04001270 return main.TRUE
pingping-lin763ee042015-05-20 17:45:30 -07001271 except pexpect.TIMEOUT:
1272 main.log.exception( self.name + ": Timeout in onosUninstall" )
You Wang141b43b2018-06-26 16:50:18 -07001273 self.handle.send( "\x03" ) # Control-C
1274 self.handle.expect( self.prompt )
pingping-lin763ee042015-05-20 17:45:30 -07001275 return main.FALSE
andrewonlabc8d47972014-10-09 16:52:36 -04001276 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001277 main.log.error( self.name + ": EOF exception found" )
1278 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001279 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001280 except Exception:
1281 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001282 main.cleanAndExit()
andrewonlab2b30bd32014-10-09 16:48:55 -04001283
kelvin-onlabd3b64892015-01-20 13:26:24 -08001284 def onosDie( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001285 """
andrewonlabaedc8332014-12-04 12:43:03 -05001286 Issues the command 'onos-die <node-ip>'
1287 This command calls onos-kill and also stops the node
kelvin8ec71442015-01-15 16:57:00 -08001288 """
andrewonlabaedc8332014-12-04 12:43:03 -05001289 try:
kelvin8ec71442015-01-15 16:57:00 -08001290 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001291 self.handle.expect( self.prompt )
Jeremyf0aecdb2016-03-30 13:19:57 -07001292 cmdStr = "onos-die " + str( nodeIp )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001293 self.handle.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -08001294 i = self.handle.expect( [
andrewonlabaedc8332014-12-04 12:43:03 -05001295 "Killing\sONOS",
1296 "ONOS\sprocess\sis\snot\srunning",
Jeremy Songster14c13572016-04-21 17:34:03 -07001297 pexpect.TIMEOUT ], timeout=60 )
andrewonlabaedc8332014-12-04 12:43:03 -05001298 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001299 main.log.info( "ONOS instance " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001300 " was killed and stopped" )
Jon Hall53c5e662016-04-13 16:06:56 -07001301 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001302 self.handle.expect( self.prompt )
andrewonlabaedc8332014-12-04 12:43:03 -05001303 return main.TRUE
1304 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001305 main.log.info( "ONOS process was not running" )
Jon Hall53c5e662016-04-13 16:06:56 -07001306 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001307 self.handle.expect( self.prompt )
andrewonlabaedc8332014-12-04 12:43:03 -05001308 return main.FALSE
1309 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001310 main.log.error( self.name + ": EOF exception found" )
1311 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001312 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001313 except Exception:
1314 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001315 main.cleanAndExit()
andrewonlabaedc8332014-12-04 12:43:03 -05001316
kelvin-onlabd3b64892015-01-20 13:26:24 -08001317 def onosKill( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001318 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001319 Calls the command: 'onos-kill [<node-ip>]'
1320 "Remotely, and unceremoniously kills the ONOS instance running on
1321 the specified cell machine" - Tom V
kelvin8ec71442015-01-15 16:57:00 -08001322 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001323 try:
kelvin8ec71442015-01-15 16:57:00 -08001324 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001325 self.handle.expect( self.prompt )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001326 self.handle.sendline( "onos-kill " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -08001327 i = self.handle.expect( [
Devin Limc20e79a2017-06-07 10:29:57 -07001328 self.prompt,
andrewonlabe8e56fd2014-10-09 17:12:44 -04001329 "No\sroute\sto\shost",
1330 "password:",
Jeremy Songster14c13572016-04-21 17:34:03 -07001331 pexpect.TIMEOUT ], timeout=60 )
kelvin8ec71442015-01-15 16:57:00 -08001332
andrewonlabe8e56fd2014-10-09 17:12:44 -04001333 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001334 main.log.info(
1335 "ONOS instance " + str(
kelvin-onlabd3b64892015-01-20 13:26:24 -08001336 nodeIp ) + " was killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001337 return main.TRUE
1338 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001339 main.log.info( "No route to host" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001340 return main.FALSE
1341 elif i == 2:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001342 main.log.info(
1343 "Passwordless login for host: " +
1344 str( nodeIp ) +
1345 " not configured" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001346 return main.FALSE
1347 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001348 main.log.info( "ONOS instance was not killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001349 return main.FALSE
kelvin8ec71442015-01-15 16:57:00 -08001350
andrewonlabe8e56fd2014-10-09 17:12:44 -04001351 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001352 main.log.error( self.name + ": EOF exception found" )
1353 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001354 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001355 except Exception:
1356 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001357 main.cleanAndExit()
andrewonlabe8e56fd2014-10-09 17:12:44 -04001358
kelvin-onlabd3b64892015-01-20 13:26:24 -08001359 def onosRemoveRaftLogs( self ):
kelvin8ec71442015-01-15 16:57:00 -08001360 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001361 Removes Raft / Copy cat files from ONOS to ensure
Jon Hallfcc88622014-11-25 13:09:54 -05001362 a cleaner environment.
1363
andrewonlab19fbdca2014-11-14 12:55:59 -05001364 Description:
Jon Hallfcc88622014-11-25 13:09:54 -05001365 Stops all ONOS defined in the cell,
andrewonlab19fbdca2014-11-14 12:55:59 -05001366 wipes the raft / copycat log files
kelvin8ec71442015-01-15 16:57:00 -08001367 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001368 try:
kelvin8ec71442015-01-15 16:57:00 -08001369 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001370 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -08001371 self.handle.sendline( "onos-remove-raft-logs" )
1372 # Sometimes this command hangs
Devin Limc20e79a2017-06-07 10:29:57 -07001373 i = self.handle.expect( [ self.prompt, pexpect.TIMEOUT ],
kelvin8ec71442015-01-15 16:57:00 -08001374 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001375 if i == 1:
Devin Limc20e79a2017-06-07 10:29:57 -07001376 i = self.handle.expect( [ self.prompt, pexpect.TIMEOUT ],
kelvin8ec71442015-01-15 16:57:00 -08001377 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001378 if i == 1:
1379 return main.FALSE
andrewonlab19fbdca2014-11-14 12:55:59 -05001380 return main.TRUE
andrewonlab19fbdca2014-11-14 12:55:59 -05001381 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001382 main.log.error( self.name + ": EOF exception found" )
1383 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001384 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001385 except Exception:
1386 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001387 main.cleanAndExit()
Jon Hallfcc88622014-11-25 13:09:54 -05001388
kelvin-onlabd3b64892015-01-20 13:26:24 -08001389 def onosStartNetwork( self, mntopo ):
kelvin8ec71442015-01-15 16:57:00 -08001390 """
1391 Calls the command 'onos-start-network [ <mininet-topo> ]
1392 "remotely starts the specified topology on the cell's
andrewonlab94282092014-10-10 13:00:11 -04001393 mininet machine against all controllers configured in the
kelvin8ec71442015-01-15 16:57:00 -08001394 cell."
andrewonlab94282092014-10-10 13:00:11 -04001395 * Specify mininet topology file name for mntopo
1396 * Topo files should be placed at:
1397 ~/<your-onos-directory>/tools/test/topos
kelvin8ec71442015-01-15 16:57:00 -08001398
andrewonlab94282092014-10-10 13:00:11 -04001399 NOTE: This function will take you to the mininet prompt
kelvin8ec71442015-01-15 16:57:00 -08001400 """
andrewonlab94282092014-10-10 13:00:11 -04001401 try:
1402 if not mntopo:
kelvin8ec71442015-01-15 16:57:00 -08001403 main.log.error( "You must specify a topo file to execute" )
andrewonlab94282092014-10-10 13:00:11 -04001404 return main.FALSE
andrewonlab94282092014-10-10 13:00:11 -04001405
kelvin8ec71442015-01-15 16:57:00 -08001406 mntopo = str( mntopo )
1407 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001408 self.handle.expect( self.prompt )
andrewonlab94282092014-10-10 13:00:11 -04001409
kelvin8ec71442015-01-15 16:57:00 -08001410 self.handle.sendline( "onos-start-network " + mntopo )
1411 self.handle.expect( "mininet>" )
1412 main.log.info( "Network started, entered mininet prompt" )
1413
1414 # TODO: Think about whether return is necessary or not
andrewonlab94282092014-10-10 13:00:11 -04001415
1416 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001417 main.log.error( self.name + ": EOF exception found" )
1418 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001419 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001420 except Exception:
1421 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001422 main.cleanAndExit()
andrewonlab94282092014-10-10 13:00:11 -04001423
Jeremy Songster14c13572016-04-21 17:34:03 -07001424 def isup( self, node="", timeout=240 ):
kelvin8ec71442015-01-15 16:57:00 -08001425 """
1426 Run's onos-wait-for-start which only returns once ONOS is at run
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001427 level 100(ready for use)
andrewonlab8d0d7d72014-10-09 16:33:15 -04001428
Jon Hall7993bfc2014-10-09 16:30:14 -04001429 Returns: main.TRUE if ONOS is running and main.FALSE on timeout
kelvin8ec71442015-01-15 16:57:00 -08001430 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001431 try:
Jon Hall3b489db2015-10-05 14:38:37 -07001432 self.handle.sendline( "onos-wait-for-start " + node )
1433 self.handle.expect( "onos-wait-for-start" )
kelvin8ec71442015-01-15 16:57:00 -08001434 # NOTE: this timeout is arbitrary"
Jon Hallcababf72018-02-05 12:05:19 -08001435 i = self.handle.expect( [ self.prompt, pexpect.TIMEOUT, "Password:" ], timeout )
Jon Hall7993bfc2014-10-09 16:30:14 -04001436 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001437 main.log.info( self.name + ": " + node + " is up" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001438 return main.TRUE
Jon Hallcababf72018-02-05 12:05:19 -08001439 elif i == 1 or i == 2:
kelvin8ec71442015-01-15 16:57:00 -08001440 # NOTE: since this function won't return until ONOS is ready,
Jon Hall7993bfc2014-10-09 16:30:14 -04001441 # we will kill it on timeout
Jon Hallcababf72018-02-05 12:05:19 -08001442 if i == 1:
Jon Hall3e6edb32018-08-21 16:20:30 -07001443 main.log.error( "{}: ONOS {} has not started yet".format( self.name, node ) )
Jon Hallcababf72018-02-05 12:05:19 -08001444 elif i == 2:
Jon Hall3e6edb32018-08-21 16:20:30 -07001445 main.log.error( "{}: Cannot login to ONOS CLI {}, try using onos-secure-ssh".format( self.name, node ) )
kelvin8ec71442015-01-15 16:57:00 -08001446 self.handle.send( "\x03" ) # Control-C
Devin Limc20e79a2017-06-07 10:29:57 -07001447 self.handle.expect( self.prompt )
Jon Hall7993bfc2014-10-09 16:30:14 -04001448 return main.FALSE
1449 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001450 main.log.error( self.name + ": EOF exception found" )
1451 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001452 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001453 except Exception:
1454 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001455 main.cleanAndExit()
andrewonlab05e362f2014-10-10 00:40:57 -04001456
Devin Lim142b5342017-07-20 15:22:39 -07001457 def preventAutoRespawn( self ):
1458 """
1459 Description:
1460 This will prevent ONOSservice to automatically
1461 respawn.
1462 """
1463 try:
1464 self.handle.sendline( "sed -i -e 's/^respawn$/#respawn/g' tools/package/init/onos.conf" )
1465 self.handle.expect( "\$" ) # $ from the command
1466 self.handle.sendline( "sed -i -e 's/^Restart=always/Restart=no/g' tools/package/init/onos.service" )
1467 self.handle.expect( "\$" ) # $ from the command
1468 self.handle.expect( "\$" ) # $ from the prompt
1469 except pexpect.EOF:
1470 main.log.error( self.name + ": EOF exception found" )
1471 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001472 main.cleanAndExit()
Devin Lim142b5342017-07-20 15:22:39 -07001473 except Exception:
1474 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001475 main.cleanAndExit()
Devin Lim142b5342017-07-20 15:22:39 -07001476
kelvin-onlabd3b64892015-01-20 13:26:24 -08001477 def pushTestIntentsShell(
1478 self,
1479 dpidSrc,
1480 dpidDst,
1481 numIntents,
1482 dirFile,
1483 onosIp,
1484 numMult="",
1485 appId="",
1486 report=True,
1487 options="" ):
kelvin8ec71442015-01-15 16:57:00 -08001488 """
andrewonlabb66dfa12014-12-02 15:51:10 -05001489 Description:
kelvin8ec71442015-01-15 16:57:00 -08001490 Use the linux prompt to push test intents to
andrewonlabb66dfa12014-12-02 15:51:10 -05001491 better parallelize the results than the CLI
1492 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001493 * dpidSrc: specify source dpid
1494 * dpidDst: specify destination dpid
1495 * numIntents: specify number of intents to push
1496 * dirFile: specify directory and file name to save
andrewonlabb66dfa12014-12-02 15:51:10 -05001497 results
kelvin-onlabd3b64892015-01-20 13:26:24 -08001498 * onosIp: specify the IP of ONOS to install on
kelvin8ec71442015-01-15 16:57:00 -08001499 NOTE:
andrewonlabb66dfa12014-12-02 15:51:10 -05001500 You must invoke this command at linux shell prompt
kelvin8ec71442015-01-15 16:57:00 -08001501 """
1502 try:
1503 # Create the string to sendline
andrewonlabaedc8332014-12-04 12:43:03 -05001504 if options:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001505 baseCmd = "onos " + str( onosIp ) + " push-test-intents " +\
kelvin8ec71442015-01-15 16:57:00 -08001506 options + " "
andrewonlabaedc8332014-12-04 12:43:03 -05001507 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001508 baseCmd = "onos " + str( onosIp ) + " push-test-intents "
kelvin8ec71442015-01-15 16:57:00 -08001509
kelvin-onlabd3b64892015-01-20 13:26:24 -08001510 addDpid = baseCmd + str( dpidSrc ) + " " + str( dpidDst )
1511 if not numMult:
1512 addIntents = addDpid + " " + str( numIntents )
1513 elif numMult:
1514 addIntents = addDpid + " " + str( numIntents ) + " " +\
1515 str( numMult )
1516 if appId:
1517 addApp = addIntents + " " + str( appId )
andrewonlabb66dfa12014-12-02 15:51:10 -05001518 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001519 addApp = addIntents
andrewonlabb66dfa12014-12-02 15:51:10 -05001520
andrewonlabaedc8332014-12-04 12:43:03 -05001521 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001522 sendCmd = addApp + " > " + str( dirFile ) + " &"
andrewonlabaedc8332014-12-04 12:43:03 -05001523 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001524 sendCmd = addApp + " &"
1525 main.log.info( "Send cmd: " + sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001526
kelvin-onlabd3b64892015-01-20 13:26:24 -08001527 self.handle.sendline( sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001528
1529 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001530 main.log.error( self.name + ": EOF exception found" )
1531 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001532 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001533 except Exception:
1534 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001535 main.cleanAndExit()
andrewonlab05e362f2014-10-10 00:40:57 -04001536
kelvin-onlabd3b64892015-01-20 13:26:24 -08001537 def tsharkPcap( self, interface, dirFile ):
kelvin8ec71442015-01-15 16:57:00 -08001538 """
andrewonlab970399c2014-11-07 13:09:32 -05001539 Capture all packet activity and store in specified
1540 directory/file
1541
1542 Required:
1543 * interface: interface to capture
1544 * dir: directory/filename to store pcap
kelvin8ec71442015-01-15 16:57:00 -08001545 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001546 try:
1547 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001548 self.handle.expect( self.prompt )
andrewonlab970399c2014-11-07 13:09:32 -05001549
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001550 self.handle.sendline( "tshark -i " + str( interface ) + " -t e -w " + str( dirFile ) + " &" )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001551 self.handle.sendline( "\n" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001552 self.handle.expect( "Capturing on" )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001553 self.handle.sendline( "\n" )
Devin Limc20e79a2017-06-07 10:29:57 -07001554 self.handle.expect( self.prompt )
andrewonlab970399c2014-11-07 13:09:32 -05001555
Jon Hallfebb1c72015-03-05 13:30:09 -08001556 main.log.info( "Tshark started capturing files on " +
1557 str( interface ) + " and saving to directory: " +
1558 str( dirFile ) )
1559 except pexpect.EOF:
1560 main.log.error( self.name + ": EOF exception found" )
1561 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001562 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001563 except Exception:
1564 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001565 main.cleanAndExit()
Shreya Shaha73aaad2014-10-27 18:03:09 -04001566
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001567 def onosTopoCfg( self, onosIp, jsonFile ):
kelvin8ec71442015-01-15 16:57:00 -08001568 """
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001569 Description:
1570 Execute onos-topo-cfg command
1571 Required:
1572 onosIp - IP of the onos node you want to send the json to
1573 jsonFile - File path of the json file
1574 Return:
1575 Returns main.TRUE if the command is successfull; Returns
1576 main.FALSE if there was an error
kelvin8ec71442015-01-15 16:57:00 -08001577 """
shahshreyae6c7cf42014-11-26 16:39:01 -08001578 try:
kelvin8ec71442015-01-15 16:57:00 -08001579 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001580 self.handle.expect( self.prompt )
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001581 cmd = "onos-topo-cfg "
1582 self.handle.sendline( cmd + str( onosIp ) + " " + jsonFile )
1583 handle = self.handle.before
1584 print handle
1585 if "Error" in handle:
1586 main.log.error( self.name + ": " + self.handle.before )
1587 return main.FALSE
1588 else:
Devin Limc20e79a2017-06-07 10:29:57 -07001589 self.handle.expect( self.prompt )
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001590 return main.TRUE
1591
Jon Hallfebb1c72015-03-05 13:30:09 -08001592 except pexpect.EOF:
1593 main.log.error( self.name + ": EOF exception found" )
1594 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001595 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001596 except Exception:
1597 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001598 main.cleanAndExit()
kelvin8ec71442015-01-15 16:57:00 -08001599
jenkins1e99e7b2015-04-02 18:15:39 -07001600 def tsharkGrep( self, grep, directory, interface='eth0', grepOptions='' ):
kelvin8ec71442015-01-15 16:57:00 -08001601 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001602 Required:
kelvin8ec71442015-01-15 16:57:00 -08001603 * grep string
andrewonlabba44bcf2014-10-16 16:54:41 -04001604 * directory to store results
1605 Optional:
1606 * interface - default: eth0
Jon Hall4ba53f02015-07-29 13:07:41 -07001607 * grepOptions - options for grep
andrewonlabba44bcf2014-10-16 16:54:41 -04001608 Description:
1609 Uses tshark command to grep specific group of packets
1610 and stores the results to specified directory.
kelvin8ec71442015-01-15 16:57:00 -08001611 The timestamp is hardcoded to be in epoch
1612 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001613 try:
1614 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001615 self.handle.expect( self.prompt )
Jon Hallfebb1c72015-03-05 13:30:09 -08001616 self.handle.sendline( "" )
jenkins1e99e7b2015-04-02 18:15:39 -07001617 if grepOptions:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001618 grepStr = "grep " + str( grepOptions )
jenkins1e99e7b2015-04-02 18:15:39 -07001619 else:
1620 grepStr = "grep"
Jon Hall4ba53f02015-07-29 13:07:41 -07001621
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001622 cmd = (
1623 "sudo tshark -i " +
Jon Hallfebb1c72015-03-05 13:30:09 -08001624 str( interface ) +
jenkins1e99e7b2015-04-02 18:15:39 -07001625 " -t e | " +
1626 grepStr + " --line-buffered \"" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001627 str( grep ) +
Jon Hallfebb1c72015-03-05 13:30:09 -08001628 "\" >" +
1629 directory +
1630 " &" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001631 self.handle.sendline( cmd )
1632 main.log.info( cmd )
Jon Hallfebb1c72015-03-05 13:30:09 -08001633 self.handle.expect( "Capturing on" )
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001634 self.handle.sendline( "\n" )
Devin Limc20e79a2017-06-07 10:29:57 -07001635 self.handle.expect( self.prompt )
Jon Hallfebb1c72015-03-05 13:30:09 -08001636 except pexpect.EOF:
1637 main.log.error( self.name + ": EOF exception found" )
1638 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001639 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001640 except Exception:
1641 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001642 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001643
kelvin-onlabd3b64892015-01-20 13:26:24 -08001644 def tsharkStop( self ):
kelvin8ec71442015-01-15 16:57:00 -08001645 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001646 Removes wireshark files from /tmp and kills all tshark processes
kelvin8ec71442015-01-15 16:57:00 -08001647 """
1648 # Remove all pcap from previous captures
Jon Hallfebb1c72015-03-05 13:30:09 -08001649 try:
1650 self.execute( cmd="sudo rm /tmp/wireshark*" )
1651 self.handle.sendline( "" )
Jon Hallefbd9792015-03-05 16:11:36 -08001652 self.handle.sendline( "sudo kill -9 `ps -ef | grep \"tshark -i\"" +
1653 " | grep -v grep | awk '{print $2}'`" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001654 self.handle.sendline( "" )
1655 main.log.info( "Tshark stopped" )
1656 except pexpect.EOF:
1657 main.log.error( self.name + ": EOF exception found" )
1658 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001659 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001660 except Exception:
1661 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001662 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001663
kelvin8ec71442015-01-15 16:57:00 -08001664 def ptpd( self, args ):
1665 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001666 Initiate ptp with user-specified args.
1667 Required:
1668 * args: specify string of args after command
1669 'sudo ptpd'
kelvin8ec71442015-01-15 16:57:00 -08001670 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001671 try:
kelvin8ec71442015-01-15 16:57:00 -08001672 self.handle.sendline( "sudo ptpd " + str( args ) )
1673 i = self.handle.expect( [
andrewonlab0c38a4a2014-10-28 18:35:35 -04001674 "Multiple",
1675 "Error",
Devin Limc20e79a2017-06-07 10:29:57 -07001676 self.prompt ] )
1677 self.handle.expect( self.prompt )
andrewonlabba44bcf2014-10-16 16:54:41 -04001678
andrewonlab0c38a4a2014-10-28 18:35:35 -04001679 if i == 0:
1680 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001681 main.log.info( "ptpd returned an error: " +
1682 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001683 return handle
1684 elif i == 1:
1685 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001686 main.log.error( "ptpd returned an error: " +
1687 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001688 return handle
1689 else:
1690 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -08001691
andrewonlab0c38a4a2014-10-28 18:35:35 -04001692 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001693 main.log.error( self.name + ": EOF exception found" )
1694 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001695 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001696 except Exception:
1697 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001698 main.cleanAndExit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001699
You Wang54b1d672018-06-11 16:44:13 -07001700 def dumpONOSCmd( self, ONOSIp, CMD, destDir, filename, options="", timeout=60 ):
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001701 """
Pier50f0bc62016-09-07 17:53:40 -07001702 Dump Cmd to a desired directory.
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001703 For debugging purposes, you may want to use
Pier50f0bc62016-09-07 17:53:40 -07001704 this function to capture Cmd at a given point in time.
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001705 Localtime will be attached to the filename
1706
1707 Required:
1708 * ONOSIp: the IP of the target ONOS instance
Pier50f0bc62016-09-07 17:53:40 -07001709 * CMD: the command to dump;
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001710 * destDir: specify directory to copy to.
1711 ex ) /tmp/
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001712 * fileName: Name of the file
You Wang54b1d672018-06-11 16:44:13 -07001713 Optional:
Pier50f0bc62016-09-07 17:53:40 -07001714 * options: Options for ONOS command
You Wang54b1d672018-06-11 16:44:13 -07001715 * timeout: pexpect timeout for running the ONOS command
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001716 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001717
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001718 localtime = time.strftime( '%x %X' )
1719 localtime = localtime.replace( "/", "" )
1720 localtime = localtime.replace( " ", "_" )
1721 localtime = localtime.replace( ":", "" )
1722 if destDir[ -1: ] != "/":
1723 destDir += "/"
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001724 cmd = CMD + " " + options + " > " + str( destDir ) + str( filename ) + localtime
You Wang54b1d672018-06-11 16:44:13 -07001725 return self.onosCli( ONOSIp, cmd, timeout=timeout )
Flavio Castrob7718952016-05-18 08:53:41 -07001726
kelvin-onlabd3b64892015-01-20 13:26:24 -08001727 def cpLogsToDir( self, logToCopy,
Jon Hallefbd9792015-03-05 16:11:36 -08001728 destDir, copyFileName="" ):
kelvin8ec71442015-01-15 16:57:00 -08001729 """
1730 Copies logs to a desired directory.
andrewonlab5d7a8f32014-11-10 13:07:56 -05001731 Current implementation of ONOS deletes its karaf
1732 logs on every iteration. For debugging purposes,
kelvin8ec71442015-01-15 16:57:00 -08001733 you may want to use this function to capture
1734 certain karaf logs. ( or any other logs if needed )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001735 Localtime will be attached to the filename
1736
1737 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001738 * logToCopy: specify directory and log name to
andrewonlab5d7a8f32014-11-10 13:07:56 -05001739 copy.
kelvin8ec71442015-01-15 16:57:00 -08001740 ex ) /opt/onos/log/karaf.log.1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001741 For copying multiple files, leave copyFileName
1742 empty and only specify destDir -
kelvin8ec71442015-01-15 16:57:00 -08001743 ex ) /opt/onos/log/karaf*
kelvin-onlabd3b64892015-01-20 13:26:24 -08001744 * destDir: specify directory to copy to.
kelvin8ec71442015-01-15 16:57:00 -08001745 ex ) /tmp/
1746 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001747 * copyFileName: If you want to rename the log
1748 file, specify copyFileName. This will not work
andrewonlab5d7a8f32014-11-10 13:07:56 -05001749 with multiple file copying
kelvin8ec71442015-01-15 16:57:00 -08001750 """
andrewonlab5d7a8f32014-11-10 13:07:56 -05001751 try:
Flavio Castro09ab59d2016-05-25 17:01:35 -07001752 localtime = time.strftime( '%H %M' )
kelvin8ec71442015-01-15 16:57:00 -08001753 localtime = localtime.replace( "/", "" )
1754 localtime = localtime.replace( " ", "_" )
1755 localtime = localtime.replace( ":", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001756 if destDir[ -1: ] != "/":
1757 destDir += "/"
andrewonlab5d7a8f32014-11-10 13:07:56 -05001758
kelvin-onlabd3b64892015-01-20 13:26:24 -08001759 if copyFileName:
Jon Hallfebb1c72015-03-05 13:30:09 -08001760 self.handle.sendline( "cp " + str( logToCopy ) + " " +
1761 str( destDir ) + str( copyFileName ) +
1762 localtime )
kelvin8ec71442015-01-15 16:57:00 -08001763 self.handle.expect( "cp" )
Devin Limc20e79a2017-06-07 10:29:57 -07001764 self.handle.expect( self.prompt )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001765 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001766 self.handle.sendline( "cp " + str( logToCopy ) +
1767 " " + str( destDir ) )
kelvin8ec71442015-01-15 16:57:00 -08001768 self.handle.expect( "cp" )
Devin Limc20e79a2017-06-07 10:29:57 -07001769 self.handle.expect( self.prompt )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001770
kelvin8ec71442015-01-15 16:57:00 -08001771 return self.handle.before
1772
1773 except pexpect.EOF:
1774 main.log.error( "Copying files failed" )
1775 main.log.error( self.name + ": EOF exception found" )
1776 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001777 except Exception:
1778 main.log.exception( "Copying files failed" )
1779
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001780 def checkLogs( self, onosIp, restart=False ):
kelvin8ec71442015-01-15 16:57:00 -08001781 """
Jon Hall94fd0472014-12-08 11:52:42 -08001782 runs onos-check-logs on the given onos node
Jon Hall80daded2015-05-27 16:07:00 -07001783 If restart is True, use the old version of onos-check-logs which
1784 does not print the full stacktrace, but shows the entire log file,
1785 including across restarts
Jon Hall94fd0472014-12-08 11:52:42 -08001786 returns the response
kelvin8ec71442015-01-15 16:57:00 -08001787 """
Jon Hall94fd0472014-12-08 11:52:42 -08001788 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001789 cmd = "onos-check-logs " + str( onosIp )
Jon Hall16b72c42015-05-20 10:23:36 -07001790 if restart:
1791 cmd += " old"
kelvin8ec71442015-01-15 16:57:00 -08001792 self.handle.sendline( cmd )
1793 self.handle.expect( cmd )
Devin Limdc78e202017-06-09 18:30:07 -07001794 self.handle.expect( self.prompt + " " )
Jon Hall94fd0472014-12-08 11:52:42 -08001795 response = self.handle.before
1796 return response
1797 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001798 main.log.error( "Lost ssh connection" )
1799 main.log.error( self.name + ": EOF exception found" )
1800 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001801 except Exception:
1802 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001803 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001804
kelvin-onlabd3b64892015-01-20 13:26:24 -08001805 def onosStatus( self, node="" ):
kelvin8ec71442015-01-15 16:57:00 -08001806 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001807 Calls onos command: 'onos-service [<node-ip>] status'
kelvin8ec71442015-01-15 16:57:00 -08001808 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001809 try:
kelvin8ec71442015-01-15 16:57:00 -08001810 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001811 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -08001812 self.handle.sendline( "onos-service " + str( node ) +
1813 " status" )
1814 i = self.handle.expect( [
You Wangef1e6572016-03-08 12:53:18 -08001815 "start/running",
You Wang7bd83062016-03-01 11:50:00 -08001816 "Running ...",
You Wangef1e6572016-03-08 12:53:18 -08001817 "stop/waiting",
You Wang7bd83062016-03-01 11:50:00 -08001818 "Not Running ...",
kelvin8ec71442015-01-15 16:57:00 -08001819 pexpect.TIMEOUT ], timeout=120 )
YPZhangfebf7302016-05-24 16:45:56 -07001820 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001821 self.handle.expect( self.prompt )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001822
You Wangef1e6572016-03-08 12:53:18 -08001823 if i == 0 or i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001824 main.log.info( "ONOS is running" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001825 return main.TRUE
You Wangef1e6572016-03-08 12:53:18 -08001826 elif i == 2 or i == 3:
kelvin8ec71442015-01-15 16:57:00 -08001827 main.log.info( "ONOS is stopped" )
kelvin8ec71442015-01-15 16:57:00 -08001828 main.log.error( "ONOS service failed to check the status" )
Devin Lim44075962017-08-11 10:56:37 -07001829
1830 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001831 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001832 main.log.error( self.name + ": EOF exception found" )
1833 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001834 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001835 except Exception:
1836 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001837 main.cleanAndExit()
Jon Hall21270ac2015-02-16 17:59:55 -08001838
Jon Hall63604932015-02-26 17:09:50 -08001839 def setIpTables( self, ip, port='', action='add', packet_type='',
1840 direction='INPUT', rule='DROP', states=True ):
Jon Hallefbd9792015-03-05 16:11:36 -08001841 """
Jon Hall21270ac2015-02-16 17:59:55 -08001842 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001843 add or remove iptables rule to DROP (default) packets from
Jon Hall21270ac2015-02-16 17:59:55 -08001844 specific IP and PORT
1845 Usage:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001846 * specify action ('add' or 'remove')
Jon Hall21270ac2015-02-16 17:59:55 -08001847 when removing, pass in the same argument as you would add. It will
1848 delete that specific rule.
1849 * specify the ip to block
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001850 * specify the destination port to block (defaults to all ports)
1851 * optional packet type to block (default tcp)
1852 * optional iptables rule (default DROP)
1853 * optional direction to block (default 'INPUT')
Jon Hall63604932015-02-26 17:09:50 -08001854 * States boolean toggles adding all supported tcp states to the
1855 firewall rule
Jon Hall21270ac2015-02-16 17:59:55 -08001856 Returns:
1857 main.TRUE on success or
1858 main.FALSE if given invalid input or
1859 main.ERROR if there is an error in response from iptables
1860 WARNING:
1861 * This function uses root privilege iptables command which may result
1862 in unwanted network errors. USE WITH CAUTION
Jon Hallefbd9792015-03-05 16:11:36 -08001863 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001864
Jon Hall21270ac2015-02-16 17:59:55 -08001865 # NOTE*********
1866 # The strict checking methods of this driver function is intentional
1867 # to discourage any misuse or error of iptables, which can cause
1868 # severe network errors
1869 # *************
1870
1871 # NOTE: Sleep needed to give some time for rule to be added and
1872 # registered to the instance. If you are calling this function
1873 # multiple times this sleep will prevent any errors.
1874 # DO NOT REMOVE
Jon Hall63604932015-02-26 17:09:50 -08001875 # time.sleep( 5 )
Jon Hall21270ac2015-02-16 17:59:55 -08001876 try:
1877 # input validation
1878 action_type = action.lower()
1879 rule = rule.upper()
1880 direction = direction.upper()
1881 if action_type != 'add' and action_type != 'remove':
1882 main.log.error( "Invalid action type. Use 'add' or "
1883 "'remove' table rule" )
1884 if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
1885 # NOTE Currently only supports rules DROP, ACCEPT, and LOG
1886 main.log.error( "Invalid rule. Valid rules are 'DROP' or "
1887 "'ACCEPT' or 'LOG' only." )
1888 if direction != 'INPUT' and direction != 'OUTPUT':
1889 # NOTE currently only supports rules INPUT and OUPTUT
1890 main.log.error( "Invalid rule. Valid directions are"
1891 " 'OUTPUT' or 'INPUT'" )
1892 return main.FALSE
1893 return main.FALSE
1894 return main.FALSE
1895 if action_type == 'add':
1896 # -A is the 'append' action of iptables
1897 actionFlag = '-A'
1898 elif action_type == 'remove':
1899 # -D is the 'delete' rule of iptables
1900 actionFlag = '-D'
1901 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001902 self.handle.expect( self.prompt )
Jon Hall21270ac2015-02-16 17:59:55 -08001903 cmd = "sudo iptables " + actionFlag + " " +\
1904 direction +\
Jon Hall21270ac2015-02-16 17:59:55 -08001905 " -s " + str( ip )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001906 # " -p " + str( packet_type ) +\
Jon Hall63604932015-02-26 17:09:50 -08001907 if packet_type:
1908 cmd += " -p " + str( packet_type )
Jon Hall21270ac2015-02-16 17:59:55 -08001909 if port:
1910 cmd += " --dport " + str( port )
Jon Hall63604932015-02-26 17:09:50 -08001911 if states:
1912 cmd += " -m state --state="
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001913 # FIXME- Allow user to configure which states to block
Jon Hall63604932015-02-26 17:09:50 -08001914 cmd += "INVALID,ESTABLISHED,NEW,RELATED,UNTRACKED"
Jon Hall21270ac2015-02-16 17:59:55 -08001915 cmd += " -j " + str( rule )
1916
1917 self.handle.sendline( cmd )
Devin Limc20e79a2017-06-07 10:29:57 -07001918 self.handle.expect( self.prompt )
Jon Hall21270ac2015-02-16 17:59:55 -08001919 main.log.warn( self.handle.before )
1920
1921 info_string = "On " + str( self.name )
1922 info_string += " " + str( action_type )
1923 info_string += " iptable rule [ "
1924 info_string += " IP: " + str( ip )
1925 info_string += " Port: " + str( port )
1926 info_string += " Rule: " + str( rule )
1927 info_string += " Direction: " + str( direction ) + " ]"
1928 main.log.info( info_string )
1929 return main.TRUE
1930 except pexpect.TIMEOUT:
1931 main.log.exception( self.name + ": Timeout exception in "
1932 "setIpTables function" )
You Wang141b43b2018-06-26 16:50:18 -07001933 self.handle.send( "\x03" ) # Control-C
1934 self.handle.expect( self.prompt )
Jon Hall21270ac2015-02-16 17:59:55 -08001935 return main.ERROR
1936 except pexpect.EOF:
1937 main.log.error( self.name + ": EOF exception found" )
1938 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001939 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001940 except Exception:
1941 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001942 main.cleanAndExit()
Jon Hall21270ac2015-02-16 17:59:55 -08001943
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001944 def detailed_status( self, log_filename ):
Jon Hallefbd9792015-03-05 16:11:36 -08001945 """
Jon Hall0468b042015-02-19 19:08:21 -08001946 This method is used by STS to check the status of the controller
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001947 Reports RUNNING, STARTING, STOPPED, FROZEN, ERROR (and reason)
Jon Hallefbd9792015-03-05 16:11:36 -08001948 """
Jon Hall0468b042015-02-19 19:08:21 -08001949 import re
1950 try:
1951 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001952 self.handle.expect( self.prompt )
Jon Hall0468b042015-02-19 19:08:21 -08001953 self.handle.sendline( "cd " + self.home )
Devin Limc20e79a2017-06-07 10:29:57 -07001954 self.handle.expect( self.prompt )
Jon Hall0468b042015-02-19 19:08:21 -08001955 self.handle.sendline( "service onos status" )
Devin Limc20e79a2017-06-07 10:29:57 -07001956 self.handle.expect( self.prompt )
Jon Hall0468b042015-02-19 19:08:21 -08001957 response = self.handle.before
1958 if re.search( "onos start/running", response ):
1959 # onos start/running, process 10457
1960 return 'RUNNING'
1961 # FIXME: Implement this case
1962 # elif re.search( pattern, response ):
1963 # return 'STARTING'
1964 elif re.search( "onos stop/", response ):
1965 # onos stop/waiting
1966 # FIXME handle this differently?: onos stop/pre-stop
1967 return 'STOPPED'
1968 # FIXME: Implement this case
1969 # elif re.search( pattern, response ):
1970 # return 'FROZEN'
1971 else:
1972 main.log.warn( self.name +
Jon Hallefbd9792015-03-05 16:11:36 -08001973 " WARNING: status received unknown response" )
Jon Hall0468b042015-02-19 19:08:21 -08001974 main.log.warn( response )
1975 return 'ERROR', "Unknown response: %s" % response
1976 except pexpect.TIMEOUT:
1977 main.log.exception( self.name + ": Timeout exception in "
1978 "setIpTables function" )
You Wang141b43b2018-06-26 16:50:18 -07001979 self.handle.send( "\x03" ) # Control-C
1980 self.handle.expect( self.prompt )
Jon Hall0468b042015-02-19 19:08:21 -08001981 return 'ERROR', "Pexpect Timeout"
1982 except pexpect.EOF:
1983 main.log.error( self.name + ": EOF exception found" )
1984 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001985 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001986 except Exception:
1987 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001988 main.cleanAndExit()
Jon Hall0468b042015-02-19 19:08:21 -08001989
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001990 def createLinkGraphFile( self, benchIp, ONOSIpList, deviceCount ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001991 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07001992 Create/formats the LinkGraph.cfg file based on arguments
1993 -only creates a linear topology and connects islands
1994 -evenly distributes devices
andrew@onlab.us3b087132015-03-11 15:00:08 -07001995 -must be called by ONOSbench
1996
Jon Hall4ba53f02015-07-29 13:07:41 -07001997 ONOSIpList - list of all of the node IPs to be used
1998
1999 deviceCount - number of switches to be assigned
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002000 '''
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002001 main.log.info( "Creating link graph configuration file." )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002002 linkGraphPath = self.home + "/tools/package/etc/linkGraph.cfg"
Jon Hall4ba53f02015-07-29 13:07:41 -07002003 tempFile = "/tmp/linkGraph.cfg"
andrew@onlab.us3b087132015-03-11 15:00:08 -07002004
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002005 linkGraph = open( tempFile, 'w+' )
2006 linkGraph.write( "# NullLinkProvider topology description (config file).\n" )
2007 linkGraph.write( "# The NodeId is only added if the destination is another node's device.\n" )
2008 linkGraph.write( "# Bugs: Comments cannot be appended to a line to be read.\n" )
Jon Hall4ba53f02015-07-29 13:07:41 -07002009
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002010 clusterCount = len( ONOSIpList )
Jon Hall4ba53f02015-07-29 13:07:41 -07002011
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002012 if isinstance( deviceCount, int ) or isinstance( deviceCount, str ):
2013 deviceCount = int( deviceCount )
2014 switchList = [ 0 ]*( clusterCount+1 )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002015 baselineSwitchCount = deviceCount/clusterCount
Jon Hall4ba53f02015-07-29 13:07:41 -07002016
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002017 for node in range( 1, clusterCount + 1 ):
2018 switchList[ node ] = baselineSwitchCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07002019
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002020 for node in range( 1, ( deviceCount % clusterCount )+1 ):
2021 switchList[ node ] += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07002022
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002023 if isinstance( deviceCount, list ):
2024 main.log.info( "Using provided device distribution" )
2025 switchList = [ 0 ]
andrew@onlab.us3b087132015-03-11 15:00:08 -07002026 for i in deviceCount:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002027 switchList.append( int( i ) )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002028
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002029 tempList = [ '0' ]
2030 tempList.extend( ONOSIpList )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002031 ONOSIpList = tempList
2032
2033 myPort = 6
2034 lastSwitch = 0
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002035 for node in range( 1, clusterCount+1 ):
2036 if switchList[ node ] == 0:
andrew@onlab.us3b087132015-03-11 15:00:08 -07002037 continue
2038
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002039 linkGraph.write( "graph " + ONOSIpList[ node ] + " {\n" )
Jon Hall4ba53f02015-07-29 13:07:41 -07002040
andrew@onlab.us3b087132015-03-11 15:00:08 -07002041 if node > 1:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002042 # connect to last device on previous node
2043 line = ( "\t0:5 -> " + str( lastSwitch ) + ":6:" + lastIp + "\n" ) # ONOSIpList[node-1]
2044 linkGraph.write( line )
Jon Hall4ba53f02015-07-29 13:07:41 -07002045
2046 lastSwitch = 0
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002047 for switch in range( 0, switchList[ node ]-1 ):
andrew@onlab.us3b087132015-03-11 15:00:08 -07002048 line = ""
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002049 line = ( "\t" + str( switch ) + ":" + str( myPort ) )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002050 line += " -- "
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002051 line += ( str( switch+1 ) + ":" + str( myPort-1 ) + "\n" )
2052 linkGraph.write( line )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002053 lastSwitch = switch+1
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002054 lastIp = ONOSIpList[ node ]
Jon Hall4ba53f02015-07-29 13:07:41 -07002055
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002056 # lastSwitch += 1
2057 if node < ( clusterCount ):
2058 # connect to first device on the next node
2059 line = ( "\t" + str( lastSwitch ) + ":6 -> 0:5:" + ONOSIpList[ node+1 ] + "\n" )
2060 linkGraph.write( line )
Jon Hall4ba53f02015-07-29 13:07:41 -07002061
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002062 linkGraph.write( "}\n" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002063 linkGraph.close()
2064
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002065 # SCP
2066 os.system( "scp " + tempFile + " " + self.user_name + "@" + benchIp + ":" + linkGraphPath )
2067 main.log.info( "linkGraph.cfg creation complete" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002068
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002069 def configNullDev( self, ONOSIpList, deviceCount, numPorts=10 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002070 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07002071 ONOSIpList = list of Ip addresses of nodes switches will be devided amongst
2072 deviceCount = number of switches to distribute, or list of values to use as custom distribution
cameron@onlab.us75900962015-03-30 13:22:49 -07002073 numPorts = number of ports per device. Defaults to 10 both in this function and in ONOS. Optional arg
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002074 '''
2075
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002076 main.log.info( "Configuring Null Device Provider" )
2077 clusterCount = len( ONOSIpList )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002078
Jon Hall4ba53f02015-07-29 13:07:41 -07002079 try:
2080
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002081 if isinstance( deviceCount, int ) or isinstance( deviceCount, str ):
2082 main.log.info( "Creating device distribution" )
2083 deviceCount = int( deviceCount )
2084 switchList = [ 0 ]*( clusterCount+1 )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002085 baselineSwitchCount = deviceCount/clusterCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07002086
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002087 for node in range( 1, clusterCount + 1 ):
2088 switchList[ node ] = baselineSwitchCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07002089
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002090 for node in range( 1, ( deviceCount % clusterCount )+1 ):
2091 switchList[ node ] += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07002092
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002093 if isinstance( deviceCount, list ):
2094 main.log.info( "Using provided device distribution" )
Jon Hall4ba53f02015-07-29 13:07:41 -07002095
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002096 if len( deviceCount ) == clusterCount:
2097 switchList = [ '0' ]
2098 switchList.extend( deviceCount )
Jon Hall4ba53f02015-07-29 13:07:41 -07002099
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002100 if len( deviceCount ) == ( clusterCount + 1 ):
2101 if deviceCount[ 0 ] == '0' or deviceCount[ 0 ] == 0:
cameron@onlab.us75900962015-03-30 13:22:49 -07002102 switchList = deviceCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07002103
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002104 assert len( switchList ) == ( clusterCount + 1 )
Jon Hall4ba53f02015-07-29 13:07:41 -07002105
cameron@onlab.us75900962015-03-30 13:22:49 -07002106 except AssertionError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002107 main.log.error( "Bad device/Ip list match" )
cameron@onlab.us75900962015-03-30 13:22:49 -07002108 except TypeError:
2109 main.log.exception( self.name + ": Object not as expected" )
2110 return None
Jon Hall77ba41c2015-04-06 10:25:40 -07002111 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002112 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002113 main.cleanAndExit()
cameron@onlab.us75900962015-03-30 13:22:49 -07002114
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002115 ONOSIp = [ 0 ]
2116 ONOSIp.extend( ONOSIpList )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002117
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002118 devicesString = "devConfigs = "
2119 for node in range( 1, len( ONOSIp ) ):
2120 devicesString += ( ONOSIp[ node ] + ":" + str( switchList[ node ] ) )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002121 if node < clusterCount:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002122 devicesString += ( "," )
Jon Hall4ba53f02015-07-29 13:07:41 -07002123
2124 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002125 self.handle.sendline( "onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider devConfigs " + devicesString )
2126 self.handle.expect( ":~" )
2127 self.handle.sendline( "onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider numPorts " + str( numPorts ) )
2128 self.handle.expect( ":~" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002129
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002130 for i in range( 10 ):
2131 self.handle.sendline( "onos $OC1 cfg get org.onosproject.provider.nil.device.impl.NullDeviceProvider" )
2132 self.handle.expect( ":~" )
cameron@onlab.us75900962015-03-30 13:22:49 -07002133 verification = self.handle.before
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002134 if ( " value=" + str( numPorts ) ) in verification and ( " value=" + devicesString ) in verification:
cameron@onlab.us75900962015-03-30 13:22:49 -07002135 break
2136 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002137 time.sleep( 1 )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002138
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002139 assert ( "value=" + str( numPorts ) ) in verification and ( " value=" + devicesString ) in verification
Jon Hall4ba53f02015-07-29 13:07:41 -07002140
cameron@onlab.us75900962015-03-30 13:22:49 -07002141 except AssertionError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002142 main.log.error( "Incorrect Config settings: " + verification )
Jon Hall77ba41c2015-04-06 10:25:40 -07002143 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002144 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002145 main.cleanAndExit()
cameron@onlab.us75900962015-03-30 13:22:49 -07002146
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002147 def configNullLink( self, fileName="/opt/onos/apache-karaf-3.0.3/etc/linkGraph.cfg", eventRate=0 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002148 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07002149 fileName default is currently the same as the default on ONOS, specify alternate file if
cameron@onlab.us75900962015-03-30 13:22:49 -07002150 you want to use a different topology file than linkGraph.cfg
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002151 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07002152
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002153 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002154 self.handle.sendline( "onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider eventRate " + str( eventRate ) )
2155 self.handle.expect( ":~" )
2156 self.handle.sendline( "onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider cfgFile " + fileName )
2157 self.handle.expect( ":~" )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002158
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002159 for i in range( 10 ):
2160 self.handle.sendline( "onos $OC1 cfg get org.onosproject.provider.nil.link.impl.NullLinkProvider" )
2161 self.handle.expect( ":~" )
cameron@onlab.us75900962015-03-30 13:22:49 -07002162 verification = self.handle.before
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002163 if ( " value=" + str( eventRate ) ) in verification and ( " value=" + fileName ) in verification:
cameron@onlab.us75900962015-03-30 13:22:49 -07002164 break
Jon Hall4ba53f02015-07-29 13:07:41 -07002165 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002166 time.sleep( 1 )
Jon Hall4ba53f02015-07-29 13:07:41 -07002167
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002168 assert ( "value=" + str( eventRate ) ) in verification and ( " value=" + fileName ) in verification
Jon Hall4ba53f02015-07-29 13:07:41 -07002169
cameron@onlab.us75900962015-03-30 13:22:49 -07002170 except pexpect.EOF:
2171 main.log.error( self.name + ": EOF exception found" )
2172 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002173 main.cleanAndExit()
cameron@onlab.us75900962015-03-30 13:22:49 -07002174 except AssertionError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002175 main.log.info( "Settings did not post to ONOS" )
Jon Hall3e6edb32018-08-21 16:20:30 -07002176 main.log.error( verification )
Jon Hall77ba41c2015-04-06 10:25:40 -07002177 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002178 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall3e6edb32018-08-21 16:20:30 -07002179 main.log.error( verification )
Devin Lim44075962017-08-11 10:56:37 -07002180 main.cleanAndExit()
andrew@onlab.us3b087132015-03-11 15:00:08 -07002181
kelvin-onlaba4074292015-07-09 15:19:49 -07002182 def getOnosIps( self ):
2183 """
2184 Get all onos IPs stored in
2185 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002186
kelvin-onlaba4074292015-07-09 15:19:49 -07002187 return sorted( self.onosIps.values() )
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002188
Chiyu Chengec63bde2016-11-17 18:11:36 -08002189 def listLog( self, nodeIp ):
2190 """
2191 Get a list of all the karaf log names
2192 """
2193 try:
2194 cmd = "onos-ssh " + nodeIp + " ls -tr /opt/onos/log"
2195 self.handle.sendline( cmd )
2196 self.handle.expect( ":~" )
2197 before = self.handle.before.splitlines()
2198 logNames = []
2199 for word in before:
2200 if 'karaf.log' in word:
2201 logNames.append( word )
2202 return logNames
2203 except pexpect.EOF:
2204 main.log.error( self.name + ": EOF exception found" )
2205 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002206 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08002207 except pexpect.TIMEOUT:
2208 main.log.error( self.name + ": TIMEOUT exception found" )
2209 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002210 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08002211 except Exception:
2212 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002213 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08002214
Pratik Parab3b2ab5a2017-02-14 13:15:14 -08002215 def logReport( self, nodeIp, searchTerms, outputMode="s", startStr=None, endStr=None ):
Jon Hallb4242222016-01-25 17:07:04 -08002216 """
2217 Searches the latest ONOS log file for the given search terms and
2218 prints the total occurances of each term. Returns to combined total of
2219 all occurances.
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002220
Jon Hallb4242222016-01-25 17:07:04 -08002221 Arguments:
2222 * nodeIp - The ip of the ONOS node where the log is located
2223 * searchTerms - A string to grep for or a list of strings to grep
2224 for in the ONOS log. Will print out the number of
2225 occurances for each term.
2226 Optional Arguments:
2227 * outputMode - 's' or 'd'. If 'd' will print the last 5 lines
2228 containing each search term as well as the total
2229 number of occurances of each term. Defaults to 's',
2230 which prints the simple output of just the number
2231 of occurances for each term.
Pratik Parab3b2ab5a2017-02-14 13:15:14 -08002232 * startStr - the start string to be given to stream editor command
2233 as the start point for extraction of data
2234 * endStr - the end string to be given to stream editor command as
2235 the end point for extraction of data
Jon Hallb4242222016-01-25 17:07:04 -08002236 """
2237 try:
2238 main.log.info( " Log Report for {} ".format( nodeIp ).center( 70, '=' ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002239 if isinstance( searchTerms, str ):
2240 searchTerms = [ searchTerms ]
Jon Hallb4242222016-01-25 17:07:04 -08002241 numTerms = len( searchTerms )
2242 outputMode = outputMode.lower()
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002243
Jon Hallb4242222016-01-25 17:07:04 -08002244 totalHits = 0
2245 logLines = []
2246 for termIndex in range( numTerms ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002247 term = searchTerms[ termIndex ]
2248 logLines.append( [ term ] )
Pratik Parab3b2ab5a2017-02-14 13:15:14 -08002249 if startStr and endStr:
2250 cmd = "onos-ssh {} \"sed -n '/{}/,/{}/p' /opt/onos/log/karaf.log | grep {}\"".format( nodeIp,
2251 startStr,
2252 endStr,
2253 term )
2254 else:
2255 cmd = "onos-ssh {} cat /opt/onos/log/karaf.log | grep {}".format( nodeIp,
2256 term )
Jon Hallb4242222016-01-25 17:07:04 -08002257 self.handle.sendline( cmd )
2258 self.handle.expect( ":~" )
2259 before = self.handle.before.splitlines()
2260 count = 0
2261 for line in before:
2262 if term in line and "grep" not in line:
2263 count += 1
2264 if before.index( line ) > ( len( before ) - 7 ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002265 logLines[ termIndex ].append( line )
Jon Hallb4242222016-01-25 17:07:04 -08002266 main.log.info( "{}: {}".format( term, count ) )
2267 totalHits += count
2268 if termIndex == numTerms - 1:
2269 print "\n"
2270 if outputMode != "s":
2271 outputString = ""
2272 for term in logLines:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002273 outputString = term[ 0 ] + ": \n"
Jon Hallb4242222016-01-25 17:07:04 -08002274 for line in range( 1, len( term ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002275 outputString += ( "\t" + term[ line ] + "\n" )
2276 if outputString != ( term[ 0 ] + ": \n" ):
Jon Hallb4242222016-01-25 17:07:04 -08002277 main.log.info( outputString )
2278 main.log.info( "=" * 70 )
2279 return totalHits
2280 except pexpect.EOF:
2281 main.log.error( self.name + ": EOF exception found" )
2282 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002283 main.cleanAndExit()
Jon Hallb4242222016-01-25 17:07:04 -08002284 except pexpect.TIMEOUT:
2285 main.log.error( self.name + ": TIMEOUT exception found" )
2286 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002287 main.cleanAndExit()
Jon Hallb4242222016-01-25 17:07:04 -08002288 except Exception:
2289 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002290 main.cleanAndExit()
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002291
2292 def copyMininetFile( self, fileName, localPath, userName, ip,
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002293 mnPath='~/mininet/custom/', timeout = 60 ):
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002294 """
2295 Description:
2296 Copy mininet topology file from dependency folder in the test folder
2297 and paste it to the mininet machine's mininet/custom folder
2298 Required:
2299 fileName - Name of the topology file to copy
2300 localPath - File path of the mininet topology file
2301 userName - User name of the mininet machine to send the file to
2302 ip - Ip address of the mininet machine
2303 Optional:
2304 mnPath - of the mininet directory to send the file to
2305 Return:
2306 Return main.TRUE if successfully copied the file otherwise
2307 return main.FALSE
2308 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002309
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002310 try:
2311 cmd = "scp " + localPath + fileName + " " + userName + "@" + \
2312 str( ip ) + ":" + mnPath + fileName
2313
2314 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07002315 self.handle.expect( self.prompt )
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002316
2317 main.log.info( self.name + ": Execute: " + cmd )
2318
2319 self.handle.sendline( cmd )
2320
2321 i = self.handle.expect( [ 'No such file',
2322 "100%",
2323 pexpect.TIMEOUT ] )
2324
2325 if i == 0:
2326 main.log.error( self.name + ": File " + fileName +
2327 " does not exist!" )
2328 return main.FALSE
2329
2330 if i == 1:
2331 main.log.info( self.name + ": File " + fileName +
2332 " has been copied!" )
2333 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07002334 self.handle.expect( self.prompt )
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002335 return main.TRUE
2336
2337 except pexpect.EOF:
2338 main.log.error( self.name + ": EOF exception found" )
2339 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002340 main.cleanAndExit()
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002341 except pexpect.TIMEOUT:
2342 main.log.error( self.name + ": TIMEOUT exception found" )
2343 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002344 main.cleanAndExit()
cameron@onlab.us78b89652015-07-08 15:21:03 -07002345
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002346 def jvmSet( self, memory=8 ):
Jon Hall4ba53f02015-07-29 13:07:41 -07002347
cameron@onlab.us78b89652015-07-08 15:21:03 -07002348 import os
2349
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002350 homeDir = os.path.expanduser( '~' )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002351 filename = "/onos/tools/package/bin/onos-service"
2352
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002353 serviceConfig = open( homeDir + filename, 'w+' )
2354 serviceConfig.write( "#!/bin/bash\n " )
2355 serviceConfig.write( "#------------------------------------- \n " )
2356 serviceConfig.write( "# Starts ONOS Apache Karaf container\n " )
2357 serviceConfig.write( "#------------------------------------- \n " )
2358 serviceConfig.write( "#export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-7-openjdk-amd64/}\n " )
2359 serviceConfig.write( """export JAVA_OPTS="${JAVA_OPTS:--Xms""" + str( memory ) + "G -Xmx" + str( memory ) + """G}" \n """ )
2360 serviceConfig.write( "[ -d $ONOS_HOME ] && cd $ONOS_HOME || ONOS_HOME=$(dirname $0)/..\n" )
2361 serviceConfig.write( """${ONOS_HOME}/apache-karaf-$KARAF_VERSION/bin/karaf "$@" \n """ )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002362 serviceConfig.close()
2363
Jon Hall6c44c0b2016-04-20 15:21:00 -07002364 def createDBFile( self, testData ):
Jon Hall4ba53f02015-07-29 13:07:41 -07002365
cameron@onlab.us78b89652015-07-08 15:21:03 -07002366 filename = main.TEST + "DB"
2367 DBString = ""
Jon Hall4ba53f02015-07-29 13:07:41 -07002368
cameron@onlab.us78b89652015-07-08 15:21:03 -07002369 for item in testData:
Jon Hall3e6edb32018-08-21 16:20:30 -07002370 if isinstance( item, str ):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002371 item = "'" + item + "'"
Jon Hall6c44c0b2016-04-20 15:21:00 -07002372 if testData.index( item ) < len( testData - 1 ):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002373 item += ","
Jon Hall6c44c0b2016-04-20 15:21:00 -07002374 DBString += str( item )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002375
Jon Hall6c44c0b2016-04-20 15:21:00 -07002376 DBFile = open( filename, "a" )
2377 DBFile.write( DBString )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002378 DBFile.close()
2379
Jon Hall6c44c0b2016-04-20 15:21:00 -07002380 def verifySummary( self, ONOSIp, *deviceCount ):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002381
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002382 self.handle.sendline( "onos " + ONOSIp + " summary" )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002383 self.handle.expect( ":~" )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002384
2385 summaryStr = self.handle.before
2386 print "\nSummary\n==============\n" + summaryStr + "\n\n"
2387
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002388 # passed = "SCC(s)=1" in summaryStr
2389 # if deviceCount:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002390 # passed = "devices=" + str(deviceCount) + "," not in summaryStr
cameron@onlab.us78b89652015-07-08 15:21:03 -07002391
GlennRC772363b2015-08-25 13:05:57 -07002392 passed = False
cameron@onlab.us78b89652015-07-08 15:21:03 -07002393 if "SCC(s)=1," in summaryStr:
2394 passed = True
Jon Hall6c44c0b2016-04-20 15:21:00 -07002395 print "Summary is verifed"
Jon Hall4ba53f02015-07-29 13:07:41 -07002396 else:
Jon Hall6c44c0b2016-04-20 15:21:00 -07002397 print "Summary failed"
cameron@onlab.us78b89652015-07-08 15:21:03 -07002398
2399 if deviceCount:
2400 print" ============================="
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002401 checkStr = "devices=" + str( deviceCount[ 0 ] ) + ","
cameron@onlab.us78b89652015-07-08 15:21:03 -07002402 print "Checkstr: " + checkStr
2403 if checkStr not in summaryStr:
2404 passed = False
Jon Hall6c44c0b2016-04-20 15:21:00 -07002405 print "Device count failed"
Jon Hall4ba53f02015-07-29 13:07:41 -07002406 else:
2407 print "device count verified"
cameron@onlab.us78b89652015-07-08 15:21:03 -07002408
2409 return passed
Jon Hall6c44c0b2016-04-20 15:21:00 -07002410
Jon Hall8f6d4622016-05-23 15:27:18 -07002411 def getIpAddr( self, iface=None ):
Jon Hall6c44c0b2016-04-20 15:21:00 -07002412 """
2413 Update self.ip_address with numerical ip address. If multiple IP's are
2414 located on the device, will attempt to use self.nicAddr to choose the
2415 right one. Defaults to 127.0.0.1 if no other address is found or cannot
2416 determine the correct address.
2417
2418 ONLY WORKS WITH IPV4 ADDRESSES
2419 """
2420 try:
Jon Hall8f6d4622016-05-23 15:27:18 -07002421 LOCALHOST = "127.0.0.1"
Jon Hall6c44c0b2016-04-20 15:21:00 -07002422 ipPat = "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"
2423 pattern = re.compile( ipPat )
2424 match = re.search( pattern, self.ip_address )
2425 if self.nicAddr:
2426 nicPat = self.nicAddr.replace( ".", "\." ).replace( "\*", r"\d{1,3}" )
2427 nicPat = re.compile( nicPat )
2428 else:
2429 nicPat = None
2430 # IF self.ip_address is an ip address and matches
2431 # self.nicAddr: return self.ip_address
2432 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002433 curIp = match.group( 0 )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002434 if nicPat:
2435 nicMatch = re.search( nicPat, curIp )
2436 if nicMatch:
2437 return self.ip_address
Jon Hall8f6d4622016-05-23 15:27:18 -07002438 # ELSE: IF iface, return ip of interface
2439 cmd = "ifconfig"
2440 ifPat = re.compile( "inet addr:({})".format( ipPat ) )
2441 if iface:
2442 cmd += " " + str( iface )
2443 raw = subprocess.check_output( cmd.split() )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002444 ifPat = re.compile( "inet addr:({})".format( ipPat ) )
2445 ips = re.findall( ifPat, raw )
Jon Hall8f6d4622016-05-23 15:27:18 -07002446 if iface:
2447 if ips:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002448 ip = ips[ 0 ]
Jon Hall8f6d4622016-05-23 15:27:18 -07002449 self.ip_address = ip
2450 return ip
2451 else:
2452 main.log.error( "Error finding ip, ifconfig output:".format( raw ) )
2453 # ELSE: attempt to get address matching nicPat.
Jon Hall6c44c0b2016-04-20 15:21:00 -07002454 if nicPat:
2455 for ip in ips:
2456 curMatch = re.search( nicPat, ip )
2457 if curMatch:
2458 self.ip_address = ip
2459 return ip
Jon Hall8f6d4622016-05-23 15:27:18 -07002460 else: # If only one non-localhost ip, return that
2461 tmpList = [ ip for ip in ips if ip is not LOCALHOST ]
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002462 if len( tmpList ) == 1:
2463 curIp = tmpList[ 0 ]
Jon Hall6c44c0b2016-04-20 15:21:00 -07002464 self.ip_address = curIp
2465 return curIp
Jon Hall8f6d4622016-05-23 15:27:18 -07002466 # Either no non-localhost IPs, or more than 1
Jon Hallebccd352016-05-20 15:17:17 -07002467 main.log.warn( "getIpAddr failed to find a public IP address" )
Jon Hall8f6d4622016-05-23 15:27:18 -07002468 return LOCALHOST
Jon Halle1790952016-05-23 15:51:46 -07002469 except subprocess.CalledProcessError:
Jon Hall8f6d4622016-05-23 15:27:18 -07002470 main.log.exception( "Error executing ifconfig" )
2471 except IndexError:
2472 main.log.exception( "Error getting IP Address" )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002473 except Exception:
2474 main.log.exception( "Uncaught exception" )
suibin zhang116647a2016-05-06 16:30:09 -07002475
Devin Lim461f0872017-06-05 16:49:33 -07002476 def startBasicONOS( self, nodeList, opSleep=60, onosStartupSleep=30, onosUser="sdn" ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002477 '''
suibin zhang116647a2016-05-06 16:30:09 -07002478 Start onos cluster with defined nodes, but only with drivers app
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002479 '''
suibin zhang116647a2016-05-06 16:30:09 -07002480 import time
2481
2482 self.createCellFile( self.ip_address,
Jon Hall3e6edb32018-08-21 16:20:30 -07002483 "temp",
2484 self.ip_address,
2485 "drivers",
2486 nodeList,
2487 nodeList,
2488 onosUser=onosUser )
suibin zhang116647a2016-05-06 16:30:09 -07002489
2490 main.log.info( self.name + ": Apply cell to environment" )
2491 cellResult = self.setCell( "temp" )
2492 verifyResult = self.verifyCell()
2493
2494 main.log.info( self.name + ": Creating ONOS package" )
You Wangd1bcaca2016-10-24 15:23:26 -07002495 packageResult = self.buckBuild( timeout=opSleep )
suibin zhang116647a2016-05-06 16:30:09 -07002496
You Wangc669d212017-01-25 11:09:48 -08002497 main.log.info( self.name + ": Uninstalling ONOS" )
2498 for nd in nodeList:
2499 self.onosUninstall( nodeIp=nd )
2500
suibin zhang116647a2016-05-06 16:30:09 -07002501 main.log.info( self.name + ": Installing ONOS package" )
2502 for nd in nodeList:
You Wangc669d212017-01-25 11:09:48 -08002503 self.onosInstall( node=nd )
2504
2505 main.log.info( self.name + ": Set up ONOS secure SSH" )
2506 for nd in nodeList:
2507 self.onosSecureSSH( node=nd )
suibin zhang116647a2016-05-06 16:30:09 -07002508
2509 main.log.info( self.name + ": Starting ONOS service" )
2510 time.sleep( onosStartupSleep )
2511
2512 onosStatus = True
2513 for nd in nodeList:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002514 onosStatus = onosStatus & self.isup( node = nd )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002515 # print "onosStatus is: " + str( onosStatus )
suibin zhang116647a2016-05-06 16:30:09 -07002516
2517 return main.TRUE if onosStatus else main.FALSE
2518
Devin Lim02075272017-07-10 15:33:21 -07002519 def onosNetCfg( self, controllerIp, path, fileName ):
Jeremy Songster5665f1b2016-06-20 14:38:22 -07002520 """
2521 Push a specified json file to ONOS through the onos-netcfg service
2522
2523 Required:
Devin Lim02075272017-07-10 15:33:21 -07002524 controllerIp - the Ip of the ONOS node in the cluster
Jeremy Songster5665f1b2016-06-20 14:38:22 -07002525 path - the location of the file to be sent
2526 fileName - name of the json file to be sent
2527
2528 Returns main.TRUE on successfully sending json file, and main.FALSE if
2529 there is an error.
2530 """
2531 try:
Devin Lim02075272017-07-10 15:33:21 -07002532 cmd = "onos-netcfg {0} {1}{2}".format( controllerIp, path, fileName )
2533 main.log.info( "Sending: " + cmd )
2534 main.ONOSbench.handle.sendline( cmd )
Jeremy Ronquillo3008aa32017-07-07 15:38:57 -07002535 main.ONOSbench.handle.expect( self.prompt )
Devin Lim02075272017-07-10 15:33:21 -07002536 handle = self.handle.before
Jeremy Ronquillo3008aa32017-07-07 15:38:57 -07002537 if "Error" in handle or "No such file or directory" in handle or "curl: " in handle:
2538 main.log.error( self.name + ": " + handle + self.handle.after )
Devin Lim02075272017-07-10 15:33:21 -07002539 return main.FALSE
Devin Lim752dd7b2017-06-27 14:40:03 -07002540 return main.TRUE
Jeremy Songster5665f1b2016-06-20 14:38:22 -07002541 except pexpect.EOF:
2542 main.log.error( self.name + ": EOF exception found" )
2543 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002544 main.cleanAndExit()
Jeremy Songster5665f1b2016-06-20 14:38:22 -07002545 except Exception:
2546 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002547 main.cleanAndExit()
Devin Lim3ebd5e72017-11-14 10:38:00 -08002548
2549 def formCluster( self, onosIPs ):
2550 """
2551 From ONOS cluster for IP addresses in onosIPs list
2552 """
2553 try:
2554 onosIPs = " ".join( onosIPs )
2555 command = "onos-form-cluster {}".format( onosIPs )
2556 main.log.info( "Sending: " + command )
2557 self.handle.sendline( "" )
2558 self.handle.expect( self.prompt )
2559 self.handle.sendline( command )
2560 self.handle.expect( self.prompt )
2561 handle = self.handle.before
2562 main.log.debug( handle )
2563 assert handle is not None, "Error in sendline"
2564 assert "Command not found:" not in handle, handle
2565 assert "Error" not in handle, handle
2566 assert "Exception:" not in handle, handle
2567 assert "curl:" not in handle, handle
2568 return main.TRUE
2569 except AssertionError:
2570 main.log.exception( "{} Error in onos-form-cluster output:".format( self.name ) )
2571 return main.FALSE
2572 except TypeError:
2573 main.log.exception( self.name + ": Object not as expected" )
2574 return main.FALSE
2575 except pexpect.EOF:
2576 main.log.error( self.name + ": EOF exception found" )
2577 main.log.error( self.name + ": " + self.handle.before )
2578 main.cleanAndExit()
2579 except Exception:
2580 main.log.exception( self.name + ": Uncaught exception!" )
2581 main.cleanAndExit()
Jon Hall7ce46ea2018-02-05 12:20:59 -08002582
2583 def backupData( self, location ):
2584 """
2585 Backs up ONOS data and logs to a given location. Returns main.FALSE
2586 if there is an error executing the command, and main.TRUE otherwise.
2587 required arguments:
2588 loaction - The file path to save the backup to
2589 """
2590 try:
2591 cmd = "/opt/onos/bin/onos-backup " + str( location )
2592 self.handle.sendline( cmd )
2593 self.handle.expect( self.prompt )
2594 handle = self.handle.before
2595 main.log.debug( handle )
2596 assert handle is not None, "Error in sendline"
2597 assert "Command not found:" not in handle, handle
2598 assert "Error" not in handle, handle
2599 assert "Exception:" not in handle, handle
2600 return main.TRUE
2601 except AssertionError:
2602 main.log.exception( "{} Error in onos-backup output:".format( self.name ) )
2603 return main.FALSE
2604 except TypeError:
2605 main.log.exception( self.name + ": Object not as expected" )
2606 return main.FALSE
2607 except pexpect.EOF:
2608 main.log.error( self.name + ": EOF exception found" )
2609 main.log.error( self.name + ": " + self.handle.before )
2610 main.cleanAndExit()
2611 except Exception:
2612 main.log.exception( self.name + ": Uncaught exception!" )
2613 main.cleanAndExit()
2614
2615 def restoreData( self, location ):
2616 """
2617 Restores ONOS data and logs from a given location. Returns main.FALSE
2618 if there is an error executing the command, and main.TRUE otherwise.
2619 required arguments:
2620 loaction - The file path of a backup file
2621 """
2622 try:
2623 cmd = "/opt/onos/bin/onos-restore " + str( location )
2624 self.handle.sendline( cmd )
2625 self.handle.expect( self.prompt )
2626 handle = self.handle.before
2627 main.log.debug( handle )
2628 assert handle is not None, "Error in sendline"
2629 assert "Command not found:" not in handle, handle
2630 assert "Error" not in handle, handle
2631 assert "Exception:" not in handle, handle
2632 return main.TRUE
2633 except AssertionError:
2634 main.log.exception( "{} Error in onos-restore output:".format( self.name ) )
2635 return main.FALSE
2636 except TypeError:
2637 main.log.exception( self.name + ": Object not as expected" )
2638 return main.FALSE
2639 except pexpect.EOF:
2640 main.log.error( self.name + ": EOF exception found" )
2641 main.log.error( self.name + ": " + self.handle.before )
2642 main.cleanAndExit()
2643 except Exception:
2644 main.log.exception( self.name + ": Uncaught exception!" )
2645 main.cleanAndExit()
You Wang5df1c6d2018-04-06 18:02:02 -07002646
You Wang5ac7db72018-07-17 11:17:52 -07002647 def onosDiagnostics( self, onosIPs, dstDir, suffix, timeout=300 ):
You Wang5df1c6d2018-04-06 18:02:02 -07002648 """
2649 Run onos-diagnostics with given ONOS instance IPs and save output to dstDir
2650 with suffix specified E.g. onos-diags-suffix.tar.gz
Jon Hall0e240372018-05-02 11:21:57 -07002651 required arguments:
You Wang5df1c6d2018-04-06 18:02:02 -07002652 onosIPs - list of ONOS IPs for collecting diags
2653 dstDir - diags file will be saved under the directory specified
2654 suffix - diags file will be named with the suffix specified
2655 returns:
2656 main.FALSE if there's an error executing the command, and main.TRUE otherwise
2657 """
2658 try:
2659 cmd = "onos-diagnostics"
2660 assert isinstance( onosIPs, list )
2661 for ip in onosIPs:
2662 cmd += " " + str( ip )
2663 self.handle.sendline( cmd )
You Wang5ac7db72018-07-17 11:17:52 -07002664 self.handle.expect( self.prompt, timeout=timeout )
You Wang5df1c6d2018-04-06 18:02:02 -07002665 handle = self.handle.before
2666 main.log.debug( handle )
2667 assert handle is not None, "Error in sendline"
2668 assert "Command not found:" not in handle, handle
2669 assert "Exception:" not in handle, handle
2670 # Rename and move diags file to dstDir from /tmp
2671 if dstDir[ -1: ] != "/":
2672 dstDir += "/"
2673 self.handle.sendline( "mv /tmp/onos-diags.tar.gz " + str( dstDir ) + "onos-diags" + str( suffix ) + ".tar.gz" )
2674 self.handle.expect( self.prompt )
2675 handle = self.handle.before
2676 main.log.debug( handle )
2677 assert handle is not None, "Error in sendline"
2678 assert "No such file or directory" not in handle, handle
2679 return main.TRUE
2680 except AssertionError:
2681 main.log.exception( "{} Error in onos-diagnostics output:".format( self.name ) )
2682 return main.FALSE
2683 except TypeError:
2684 main.log.exception( self.name + ": Object not as expected" )
2685 return main.FALSE
You Wang223faa32018-06-21 10:45:47 -07002686 except pexpect.TIMEOUT:
2687 main.log.exception( self.name + ": TIMEOUT exception found in onosDiagnostics" )
2688 main.log.error( self.name + ": " + self.handle.before )
You Wangb65d2372018-08-17 15:37:59 -07002689 self.exitFromCmd( self.prompt, 100 )
You Wang223faa32018-06-21 10:45:47 -07002690 return main.FALSE
You Wang5df1c6d2018-04-06 18:02:02 -07002691 except pexpect.EOF:
2692 main.log.error( self.name + ": EOF exception found" )
2693 main.log.error( self.name + ": " + self.handle.before )
2694 main.cleanAndExit()
2695 except Exception:
2696 main.log.exception( self.name + ": Uncaught exception!" )
2697 main.cleanAndExit()
Jon Hall0e240372018-05-02 11:21:57 -07002698
2699 def onosPower( self, onosIP, toggle, userName=None ):
2700 """
2701 Run onos-power script to tell the cell warden to simulate a power faulure
2702 for the given container.
2703 required :
2704 onosIP - ONOS node IP
2705 toggle - either "off" or "on", used to indicate whether
2706 the node should be powered off or on
2707 returns:
2708 main.FALSE if there's an error executing the command, and main.TRUE otherwise
2709 """
2710 try:
2711 cmd = "onos-power {} {}".format( onosIP, toggle )
2712 if userName:
2713 cmd += " {}".format( userName )
2714 self.handle.sendline( cmd )
2715 self.handle.expect( self.prompt )
2716 handle = self.handle.before
2717 main.log.debug( handle )
2718 assert handle is not None, "Error in sendline"
2719 assert "Command not found:" not in handle, handle
2720 assert "Exception:" not in handle, handle
2721 assert "usage:" not in handle, handle
2722 return main.TRUE
2723 except AssertionError:
2724 main.log.exception( "{} Error in onos-power output:".format( self.name ) )
2725 return main.FALSE
2726 except TypeError:
2727 main.log.exception( self.name + ": Object not as expected" )
2728 return main.FALSE
2729 except pexpect.EOF:
2730 main.log.error( self.name + ": EOF exception found" )
2731 main.log.error( self.name + ": " + self.handle.before )
2732 main.cleanAndExit()
2733 except Exception:
2734 main.log.exception( self.name + ": Uncaught exception!" )
2735 main.cleanAndExit()
You Wangf9d95be2018-08-01 14:35:37 -07002736
2737 def atomixKill( self, nodeIp ):
2738 """
2739 Calls the command: 'atomix-kill [<node-ip>]'
2740 Kills the Atomix instance running on the specified node
2741 """
2742 try:
2743 self.handle.sendline( "" )
2744 self.handle.expect( self.prompt )
2745 self.handle.sendline( "atomix-kill " + str( nodeIp ) )
2746 i = self.handle.expect( [
2747 self.prompt,
2748 "No\sroute\sto\shost",
2749 "password:",
2750 pexpect.TIMEOUT ], timeout=60 )
2751
2752 if i == 0:
2753 main.log.info( "Atomix instance " + str( nodeIp ) + " was killed" )
2754 return main.TRUE
2755 elif i == 1:
2756 main.log.info( "No route to host" )
2757 return main.FALSE
2758 elif i == 2:
2759 main.log.info( "Passwordless login for host: " + str( nodeIp ) + " not configured" )
2760 return main.FALSE
2761 else:
2762 main.log.info( "Atomix instance was not killed" )
2763 return main.FALSE
2764
2765 except pexpect.EOF:
2766 main.log.error( self.name + ": EOF exception found" )
2767 main.log.error( self.name + ": " + self.handle.before )
2768 main.cleanAndExit()
2769 except Exception:
2770 main.log.exception( self.name + ": Uncaught exception!" )
2771 main.cleanAndExit()
2772
2773 def atomixUninstall( self, nodeIp="" ):
2774 """
2775 Calls the command: 'atomix-uninstall'
2776 Uninstalls Atomix from the designated node, stopping if needed
2777 """
2778 try:
2779 self.handle.sendline( "" )
2780 self.handle.expect( self.prompt, timeout=180 )
2781 self.handle.sendline( "atomix-uninstall " + str( nodeIp ) )
2782 self.handle.expect( self.prompt, timeout=180 )
2783 main.log.info( "Atomix " + nodeIp + " was uninstalled" )
2784 # onos-uninstall command does not return any text
2785 return main.TRUE
2786 except pexpect.TIMEOUT:
2787 main.log.exception( self.name + ": Timeout in atomixUninstall" )
2788 self.handle.send( "\x03" ) # Control-C
2789 self.handle.expect( self.prompt )
2790 return main.FALSE
2791 except pexpect.EOF:
2792 main.log.error( self.name + ": EOF exception found" )
2793 main.log.error( self.name + ": " + self.handle.before )
2794 main.cleanAndExit()
2795 except Exception:
2796 main.log.exception( self.name + ": Uncaught exception!" )
2797 main.cleanAndExit()
2798
2799 def atomixInstall( self, options="", node="" ):
2800 """
2801 Installs Atomix on the designated nodes.
2802 Returns: main.TRUE on success and main.FALSE on failure
2803 """
2804 try:
2805 if options:
2806 self.handle.sendline( "atomix-install " + options + " " + node )
2807 else:
2808 self.handle.sendline( "atomix-install " + node )
2809 self.handle.expect( "atomix-install " )
2810 i = self.handle.expect( [ "Network\sis\sunreachable",
2811 "is already installed",
2812 "saved",
2813 self.prompt,
2814 pexpect.TIMEOUT ], timeout=180 )
2815 if i == 0:
2816 # can't reach ONOS node
Jon Hall3e6edb32018-08-21 16:20:30 -07002817 main.log.warn( self.name + ": Network is unreachable" )
You Wangf9d95be2018-08-01 14:35:37 -07002818 self.handle.expect( self.prompt )
2819 return main.FALSE
2820 elif i == 1:
2821 # same bits are already on Atomix node
Jon Hall3e6edb32018-08-21 16:20:30 -07002822 main.log.info( self.name + ": Atomix is already installed on " + node )
You Wangf9d95be2018-08-01 14:35:37 -07002823 self.handle.expect( self.prompt )
2824 return main.TRUE
2825 elif i == 2 or i == 3:
Jon Hall3e6edb32018-08-21 16:20:30 -07002826 main.log.info( self.name + ": Atomix was installed on " + node )
You Wangf9d95be2018-08-01 14:35:37 -07002827 self.handle.expect( self.prompt )
2828 return main.TRUE
2829 elif i == 4:
2830 # timeout
Jon Hall3e6edb32018-08-21 16:20:30 -07002831 main.log.info( self.name + ": Installation of Atomix on " + node + " timed out" )
You Wangf9d95be2018-08-01 14:35:37 -07002832 self.handle.expect( self.prompt )
2833 main.log.warn( self.handle.before )
2834 self.handle.send( "\x03" ) # Control-C
2835 self.handle.expect( self.prompt )
2836 return main.FALSE
2837 except pexpect.EOF:
2838 main.log.error( self.name + ": EOF exception found" )
2839 main.log.error( self.name + ": " + self.handle.before )
2840 main.cleanAndExit()
2841 except Exception:
2842 main.log.exception( self.name + ": Uncaught exception!" )
2843 main.cleanAndExit()