blob: c03556916be35574b2246cd438c3ebf614c7223f [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 if self.handle:
Jon Hall500ed642019-06-17 18:25:46 +0000133 self.handle.setwinsize( 24, 250 )
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" )
You Wangb65f2e92018-12-21 11:31:34 -08001438 # FIXME: for now we sleep 5s for CLI to become ready
1439 time.sleep( 5 )
Jon Hall7993bfc2014-10-09 16:30:14 -04001440 return main.TRUE
Jon Hallcababf72018-02-05 12:05:19 -08001441 elif i == 1 or i == 2:
kelvin8ec71442015-01-15 16:57:00 -08001442 # NOTE: since this function won't return until ONOS is ready,
Jon Hall7993bfc2014-10-09 16:30:14 -04001443 # we will kill it on timeout
Jon Hallcababf72018-02-05 12:05:19 -08001444 if i == 1:
Jon Hall3e6edb32018-08-21 16:20:30 -07001445 main.log.error( "{}: ONOS {} has not started yet".format( self.name, node ) )
Jon Hallcababf72018-02-05 12:05:19 -08001446 elif i == 2:
Jon Hall3e6edb32018-08-21 16:20:30 -07001447 main.log.error( "{}: Cannot login to ONOS CLI {}, try using onos-secure-ssh".format( self.name, node ) )
kelvin8ec71442015-01-15 16:57:00 -08001448 self.handle.send( "\x03" ) # Control-C
Devin Limc20e79a2017-06-07 10:29:57 -07001449 self.handle.expect( self.prompt )
Jon Hall7993bfc2014-10-09 16:30:14 -04001450 return main.FALSE
1451 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001452 main.log.error( self.name + ": EOF exception found" )
1453 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001454 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001455 except Exception:
1456 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001457 main.cleanAndExit()
andrewonlab05e362f2014-10-10 00:40:57 -04001458
Devin Lim142b5342017-07-20 15:22:39 -07001459 def preventAutoRespawn( self ):
1460 """
1461 Description:
1462 This will prevent ONOSservice to automatically
1463 respawn.
1464 """
1465 try:
1466 self.handle.sendline( "sed -i -e 's/^respawn$/#respawn/g' tools/package/init/onos.conf" )
1467 self.handle.expect( "\$" ) # $ from the command
1468 self.handle.sendline( "sed -i -e 's/^Restart=always/Restart=no/g' tools/package/init/onos.service" )
1469 self.handle.expect( "\$" ) # $ from the command
1470 self.handle.expect( "\$" ) # $ from the prompt
1471 except pexpect.EOF:
1472 main.log.error( self.name + ": EOF exception found" )
1473 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001474 main.cleanAndExit()
Devin Lim142b5342017-07-20 15:22:39 -07001475 except Exception:
1476 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001477 main.cleanAndExit()
Devin Lim142b5342017-07-20 15:22:39 -07001478
kelvin-onlabd3b64892015-01-20 13:26:24 -08001479 def pushTestIntentsShell(
1480 self,
1481 dpidSrc,
1482 dpidDst,
1483 numIntents,
1484 dirFile,
1485 onosIp,
1486 numMult="",
1487 appId="",
1488 report=True,
1489 options="" ):
kelvin8ec71442015-01-15 16:57:00 -08001490 """
andrewonlabb66dfa12014-12-02 15:51:10 -05001491 Description:
kelvin8ec71442015-01-15 16:57:00 -08001492 Use the linux prompt to push test intents to
andrewonlabb66dfa12014-12-02 15:51:10 -05001493 better parallelize the results than the CLI
1494 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001495 * dpidSrc: specify source dpid
1496 * dpidDst: specify destination dpid
1497 * numIntents: specify number of intents to push
1498 * dirFile: specify directory and file name to save
andrewonlabb66dfa12014-12-02 15:51:10 -05001499 results
kelvin-onlabd3b64892015-01-20 13:26:24 -08001500 * onosIp: specify the IP of ONOS to install on
kelvin8ec71442015-01-15 16:57:00 -08001501 NOTE:
andrewonlabb66dfa12014-12-02 15:51:10 -05001502 You must invoke this command at linux shell prompt
kelvin8ec71442015-01-15 16:57:00 -08001503 """
1504 try:
1505 # Create the string to sendline
andrewonlabaedc8332014-12-04 12:43:03 -05001506 if options:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001507 baseCmd = "onos " + str( onosIp ) + " push-test-intents " +\
kelvin8ec71442015-01-15 16:57:00 -08001508 options + " "
andrewonlabaedc8332014-12-04 12:43:03 -05001509 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001510 baseCmd = "onos " + str( onosIp ) + " push-test-intents "
kelvin8ec71442015-01-15 16:57:00 -08001511
kelvin-onlabd3b64892015-01-20 13:26:24 -08001512 addDpid = baseCmd + str( dpidSrc ) + " " + str( dpidDst )
1513 if not numMult:
1514 addIntents = addDpid + " " + str( numIntents )
1515 elif numMult:
1516 addIntents = addDpid + " " + str( numIntents ) + " " +\
1517 str( numMult )
1518 if appId:
1519 addApp = addIntents + " " + str( appId )
andrewonlabb66dfa12014-12-02 15:51:10 -05001520 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001521 addApp = addIntents
andrewonlabb66dfa12014-12-02 15:51:10 -05001522
andrewonlabaedc8332014-12-04 12:43:03 -05001523 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001524 sendCmd = addApp + " > " + str( dirFile ) + " &"
andrewonlabaedc8332014-12-04 12:43:03 -05001525 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001526 sendCmd = addApp + " &"
1527 main.log.info( "Send cmd: " + sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001528
kelvin-onlabd3b64892015-01-20 13:26:24 -08001529 self.handle.sendline( sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001530
1531 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001532 main.log.error( self.name + ": EOF exception found" )
1533 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001534 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001535 except Exception:
1536 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001537 main.cleanAndExit()
andrewonlab05e362f2014-10-10 00:40:57 -04001538
kelvin-onlabd3b64892015-01-20 13:26:24 -08001539 def tsharkPcap( self, interface, dirFile ):
kelvin8ec71442015-01-15 16:57:00 -08001540 """
andrewonlab970399c2014-11-07 13:09:32 -05001541 Capture all packet activity and store in specified
1542 directory/file
1543
1544 Required:
1545 * interface: interface to capture
1546 * dir: directory/filename to store pcap
kelvin8ec71442015-01-15 16:57:00 -08001547 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001548 try:
1549 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001550 self.handle.expect( self.prompt )
andrewonlab970399c2014-11-07 13:09:32 -05001551
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001552 self.handle.sendline( "tshark -i " + str( interface ) + " -t e -w " + str( dirFile ) + " &" )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001553 self.handle.sendline( "\n" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001554 self.handle.expect( "Capturing on" )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001555 self.handle.sendline( "\n" )
Devin Limc20e79a2017-06-07 10:29:57 -07001556 self.handle.expect( self.prompt )
andrewonlab970399c2014-11-07 13:09:32 -05001557
Jon Hallfebb1c72015-03-05 13:30:09 -08001558 main.log.info( "Tshark started capturing files on " +
1559 str( interface ) + " and saving to directory: " +
1560 str( dirFile ) )
1561 except pexpect.EOF:
1562 main.log.error( self.name + ": EOF exception found" )
1563 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001564 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001565 except Exception:
1566 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001567 main.cleanAndExit()
Shreya Shaha73aaad2014-10-27 18:03:09 -04001568
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001569 def onosTopoCfg( self, onosIp, jsonFile ):
kelvin8ec71442015-01-15 16:57:00 -08001570 """
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001571 Description:
1572 Execute onos-topo-cfg command
1573 Required:
1574 onosIp - IP of the onos node you want to send the json to
1575 jsonFile - File path of the json file
1576 Return:
1577 Returns main.TRUE if the command is successfull; Returns
1578 main.FALSE if there was an error
kelvin8ec71442015-01-15 16:57:00 -08001579 """
shahshreyae6c7cf42014-11-26 16:39:01 -08001580 try:
kelvin8ec71442015-01-15 16:57:00 -08001581 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001582 self.handle.expect( self.prompt )
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001583 cmd = "onos-topo-cfg "
1584 self.handle.sendline( cmd + str( onosIp ) + " " + jsonFile )
1585 handle = self.handle.before
1586 print handle
1587 if "Error" in handle:
1588 main.log.error( self.name + ": " + self.handle.before )
1589 return main.FALSE
1590 else:
Devin Limc20e79a2017-06-07 10:29:57 -07001591 self.handle.expect( self.prompt )
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001592 return main.TRUE
1593
Jon Hallfebb1c72015-03-05 13:30:09 -08001594 except pexpect.EOF:
1595 main.log.error( self.name + ": EOF exception found" )
1596 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001597 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001598 except Exception:
1599 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001600 main.cleanAndExit()
kelvin8ec71442015-01-15 16:57:00 -08001601
jenkins1e99e7b2015-04-02 18:15:39 -07001602 def tsharkGrep( self, grep, directory, interface='eth0', grepOptions='' ):
kelvin8ec71442015-01-15 16:57:00 -08001603 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001604 Required:
kelvin8ec71442015-01-15 16:57:00 -08001605 * grep string
andrewonlabba44bcf2014-10-16 16:54:41 -04001606 * directory to store results
1607 Optional:
1608 * interface - default: eth0
Jon Hall4ba53f02015-07-29 13:07:41 -07001609 * grepOptions - options for grep
andrewonlabba44bcf2014-10-16 16:54:41 -04001610 Description:
1611 Uses tshark command to grep specific group of packets
1612 and stores the results to specified directory.
kelvin8ec71442015-01-15 16:57:00 -08001613 The timestamp is hardcoded to be in epoch
1614 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001615 try:
1616 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001617 self.handle.expect( self.prompt )
Jon Hallfebb1c72015-03-05 13:30:09 -08001618 self.handle.sendline( "" )
jenkins1e99e7b2015-04-02 18:15:39 -07001619 if grepOptions:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001620 grepStr = "grep " + str( grepOptions )
jenkins1e99e7b2015-04-02 18:15:39 -07001621 else:
1622 grepStr = "grep"
Jon Hall4ba53f02015-07-29 13:07:41 -07001623
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001624 cmd = (
1625 "sudo tshark -i " +
Jon Hallfebb1c72015-03-05 13:30:09 -08001626 str( interface ) +
jenkins1e99e7b2015-04-02 18:15:39 -07001627 " -t e | " +
1628 grepStr + " --line-buffered \"" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001629 str( grep ) +
Jon Hallfebb1c72015-03-05 13:30:09 -08001630 "\" >" +
1631 directory +
1632 " &" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001633 self.handle.sendline( cmd )
1634 main.log.info( cmd )
Jon Hallfebb1c72015-03-05 13:30:09 -08001635 self.handle.expect( "Capturing on" )
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001636 self.handle.sendline( "\n" )
Devin Limc20e79a2017-06-07 10:29:57 -07001637 self.handle.expect( self.prompt )
Jon Hallfebb1c72015-03-05 13:30:09 -08001638 except pexpect.EOF:
1639 main.log.error( self.name + ": EOF exception found" )
1640 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001641 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001642 except Exception:
1643 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001644 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001645
kelvin-onlabd3b64892015-01-20 13:26:24 -08001646 def tsharkStop( self ):
kelvin8ec71442015-01-15 16:57:00 -08001647 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001648 Removes wireshark files from /tmp and kills all tshark processes
kelvin8ec71442015-01-15 16:57:00 -08001649 """
1650 # Remove all pcap from previous captures
Jon Hallfebb1c72015-03-05 13:30:09 -08001651 try:
1652 self.execute( cmd="sudo rm /tmp/wireshark*" )
1653 self.handle.sendline( "" )
Jon Hallefbd9792015-03-05 16:11:36 -08001654 self.handle.sendline( "sudo kill -9 `ps -ef | grep \"tshark -i\"" +
1655 " | grep -v grep | awk '{print $2}'`" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001656 self.handle.sendline( "" )
1657 main.log.info( "Tshark stopped" )
1658 except pexpect.EOF:
1659 main.log.error( self.name + ": EOF exception found" )
1660 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001661 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001662 except Exception:
1663 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001664 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001665
kelvin8ec71442015-01-15 16:57:00 -08001666 def ptpd( self, args ):
1667 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001668 Initiate ptp with user-specified args.
1669 Required:
1670 * args: specify string of args after command
1671 'sudo ptpd'
kelvin8ec71442015-01-15 16:57:00 -08001672 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001673 try:
kelvin8ec71442015-01-15 16:57:00 -08001674 self.handle.sendline( "sudo ptpd " + str( args ) )
1675 i = self.handle.expect( [
andrewonlab0c38a4a2014-10-28 18:35:35 -04001676 "Multiple",
1677 "Error",
Devin Limc20e79a2017-06-07 10:29:57 -07001678 self.prompt ] )
1679 self.handle.expect( self.prompt )
andrewonlabba44bcf2014-10-16 16:54:41 -04001680
andrewonlab0c38a4a2014-10-28 18:35:35 -04001681 if i == 0:
1682 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001683 main.log.info( "ptpd returned an error: " +
1684 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001685 return handle
1686 elif i == 1:
1687 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001688 main.log.error( "ptpd returned an error: " +
1689 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001690 return handle
1691 else:
1692 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -08001693
andrewonlab0c38a4a2014-10-28 18:35:35 -04001694 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001695 main.log.error( self.name + ": EOF exception found" )
1696 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001697 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001698 except Exception:
1699 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001700 main.cleanAndExit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001701
You Wang54b1d672018-06-11 16:44:13 -07001702 def dumpONOSCmd( self, ONOSIp, CMD, destDir, filename, options="", timeout=60 ):
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001703 """
Pier50f0bc62016-09-07 17:53:40 -07001704 Dump Cmd to a desired directory.
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001705 For debugging purposes, you may want to use
Pier50f0bc62016-09-07 17:53:40 -07001706 this function to capture Cmd at a given point in time.
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001707 Localtime will be attached to the filename
1708
1709 Required:
1710 * ONOSIp: the IP of the target ONOS instance
Pier50f0bc62016-09-07 17:53:40 -07001711 * CMD: the command to dump;
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001712 * destDir: specify directory to copy to.
1713 ex ) /tmp/
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001714 * fileName: Name of the file
You Wang54b1d672018-06-11 16:44:13 -07001715 Optional:
Pier50f0bc62016-09-07 17:53:40 -07001716 * options: Options for ONOS command
You Wang54b1d672018-06-11 16:44:13 -07001717 * timeout: pexpect timeout for running the ONOS command
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001718 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001719
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001720 localtime = time.strftime( '%x %X' )
1721 localtime = localtime.replace( "/", "" )
1722 localtime = localtime.replace( " ", "_" )
1723 localtime = localtime.replace( ":", "" )
1724 if destDir[ -1: ] != "/":
1725 destDir += "/"
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001726 cmd = CMD + " " + options + " > " + str( destDir ) + str( filename ) + localtime
You Wang54b1d672018-06-11 16:44:13 -07001727 return self.onosCli( ONOSIp, cmd, timeout=timeout )
Flavio Castrob7718952016-05-18 08:53:41 -07001728
kelvin-onlabd3b64892015-01-20 13:26:24 -08001729 def cpLogsToDir( self, logToCopy,
Jon Hallefbd9792015-03-05 16:11:36 -08001730 destDir, copyFileName="" ):
kelvin8ec71442015-01-15 16:57:00 -08001731 """
1732 Copies logs to a desired directory.
andrewonlab5d7a8f32014-11-10 13:07:56 -05001733 Current implementation of ONOS deletes its karaf
1734 logs on every iteration. For debugging purposes,
kelvin8ec71442015-01-15 16:57:00 -08001735 you may want to use this function to capture
1736 certain karaf logs. ( or any other logs if needed )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001737 Localtime will be attached to the filename
1738
1739 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001740 * logToCopy: specify directory and log name to
andrewonlab5d7a8f32014-11-10 13:07:56 -05001741 copy.
kelvin8ec71442015-01-15 16:57:00 -08001742 ex ) /opt/onos/log/karaf.log.1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001743 For copying multiple files, leave copyFileName
1744 empty and only specify destDir -
kelvin8ec71442015-01-15 16:57:00 -08001745 ex ) /opt/onos/log/karaf*
kelvin-onlabd3b64892015-01-20 13:26:24 -08001746 * destDir: specify directory to copy to.
kelvin8ec71442015-01-15 16:57:00 -08001747 ex ) /tmp/
1748 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001749 * copyFileName: If you want to rename the log
1750 file, specify copyFileName. This will not work
andrewonlab5d7a8f32014-11-10 13:07:56 -05001751 with multiple file copying
kelvin8ec71442015-01-15 16:57:00 -08001752 """
andrewonlab5d7a8f32014-11-10 13:07:56 -05001753 try:
Flavio Castro09ab59d2016-05-25 17:01:35 -07001754 localtime = time.strftime( '%H %M' )
kelvin8ec71442015-01-15 16:57:00 -08001755 localtime = localtime.replace( "/", "" )
1756 localtime = localtime.replace( " ", "_" )
1757 localtime = localtime.replace( ":", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001758 if destDir[ -1: ] != "/":
1759 destDir += "/"
andrewonlab5d7a8f32014-11-10 13:07:56 -05001760
kelvin-onlabd3b64892015-01-20 13:26:24 -08001761 if copyFileName:
Jon Hallfebb1c72015-03-05 13:30:09 -08001762 self.handle.sendline( "cp " + str( logToCopy ) + " " +
1763 str( destDir ) + str( copyFileName ) +
1764 localtime )
kelvin8ec71442015-01-15 16:57:00 -08001765 self.handle.expect( "cp" )
Devin Limc20e79a2017-06-07 10:29:57 -07001766 self.handle.expect( self.prompt )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001767 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001768 self.handle.sendline( "cp " + str( logToCopy ) +
1769 " " + str( destDir ) )
kelvin8ec71442015-01-15 16:57:00 -08001770 self.handle.expect( "cp" )
Devin Limc20e79a2017-06-07 10:29:57 -07001771 self.handle.expect( self.prompt )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001772
kelvin8ec71442015-01-15 16:57:00 -08001773 return self.handle.before
1774
1775 except pexpect.EOF:
1776 main.log.error( "Copying files failed" )
1777 main.log.error( self.name + ": EOF exception found" )
1778 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001779 except Exception:
1780 main.log.exception( "Copying files failed" )
1781
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001782 def checkLogs( self, onosIp, restart=False ):
kelvin8ec71442015-01-15 16:57:00 -08001783 """
Jon Hall94fd0472014-12-08 11:52:42 -08001784 runs onos-check-logs on the given onos node
Jon Hall80daded2015-05-27 16:07:00 -07001785 If restart is True, use the old version of onos-check-logs which
1786 does not print the full stacktrace, but shows the entire log file,
1787 including across restarts
Jon Hall94fd0472014-12-08 11:52:42 -08001788 returns the response
kelvin8ec71442015-01-15 16:57:00 -08001789 """
Jon Hall94fd0472014-12-08 11:52:42 -08001790 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001791 cmd = "onos-check-logs " + str( onosIp )
Jon Hall16b72c42015-05-20 10:23:36 -07001792 if restart:
1793 cmd += " old"
kelvin8ec71442015-01-15 16:57:00 -08001794 self.handle.sendline( cmd )
1795 self.handle.expect( cmd )
Devin Limdc78e202017-06-09 18:30:07 -07001796 self.handle.expect( self.prompt + " " )
Jon Hall94fd0472014-12-08 11:52:42 -08001797 response = self.handle.before
1798 return response
1799 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001800 main.log.error( "Lost ssh connection" )
1801 main.log.error( self.name + ": EOF exception found" )
1802 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001803 except Exception:
1804 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001805 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001806
kelvin-onlabd3b64892015-01-20 13:26:24 -08001807 def onosStatus( self, node="" ):
kelvin8ec71442015-01-15 16:57:00 -08001808 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001809 Calls onos command: 'onos-service [<node-ip>] status'
kelvin8ec71442015-01-15 16:57:00 -08001810 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001811 try:
kelvin8ec71442015-01-15 16:57:00 -08001812 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001813 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -08001814 self.handle.sendline( "onos-service " + str( node ) +
1815 " status" )
1816 i = self.handle.expect( [
You Wangef1e6572016-03-08 12:53:18 -08001817 "start/running",
You Wang7bd83062016-03-01 11:50:00 -08001818 "Running ...",
You Wangef1e6572016-03-08 12:53:18 -08001819 "stop/waiting",
You Wang7bd83062016-03-01 11:50:00 -08001820 "Not Running ...",
kelvin8ec71442015-01-15 16:57:00 -08001821 pexpect.TIMEOUT ], timeout=120 )
YPZhangfebf7302016-05-24 16:45:56 -07001822 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001823 self.handle.expect( self.prompt )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001824
You Wangef1e6572016-03-08 12:53:18 -08001825 if i == 0 or i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001826 main.log.info( "ONOS is running" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001827 return main.TRUE
You Wangef1e6572016-03-08 12:53:18 -08001828 elif i == 2 or i == 3:
kelvin8ec71442015-01-15 16:57:00 -08001829 main.log.info( "ONOS is stopped" )
kelvin8ec71442015-01-15 16:57:00 -08001830 main.log.error( "ONOS service failed to check the status" )
Devin Lim44075962017-08-11 10:56:37 -07001831
1832 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001833 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001834 main.log.error( self.name + ": EOF exception found" )
1835 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001836 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001837 except Exception:
1838 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001839 main.cleanAndExit()
Jon Hall21270ac2015-02-16 17:59:55 -08001840
Jon Hall63604932015-02-26 17:09:50 -08001841 def setIpTables( self, ip, port='', action='add', packet_type='',
1842 direction='INPUT', rule='DROP', states=True ):
Jon Hallefbd9792015-03-05 16:11:36 -08001843 """
Jon Hall21270ac2015-02-16 17:59:55 -08001844 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001845 add or remove iptables rule to DROP (default) packets from
Jon Hall21270ac2015-02-16 17:59:55 -08001846 specific IP and PORT
1847 Usage:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001848 * specify action ('add' or 'remove')
Jon Hall21270ac2015-02-16 17:59:55 -08001849 when removing, pass in the same argument as you would add. It will
1850 delete that specific rule.
1851 * specify the ip to block
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001852 * specify the destination port to block (defaults to all ports)
1853 * optional packet type to block (default tcp)
1854 * optional iptables rule (default DROP)
1855 * optional direction to block (default 'INPUT')
Jon Hall63604932015-02-26 17:09:50 -08001856 * States boolean toggles adding all supported tcp states to the
1857 firewall rule
Jon Hall21270ac2015-02-16 17:59:55 -08001858 Returns:
1859 main.TRUE on success or
1860 main.FALSE if given invalid input or
1861 main.ERROR if there is an error in response from iptables
1862 WARNING:
1863 * This function uses root privilege iptables command which may result
1864 in unwanted network errors. USE WITH CAUTION
Jon Hallefbd9792015-03-05 16:11:36 -08001865 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001866
Jon Hall21270ac2015-02-16 17:59:55 -08001867 # NOTE*********
1868 # The strict checking methods of this driver function is intentional
1869 # to discourage any misuse or error of iptables, which can cause
1870 # severe network errors
1871 # *************
1872
1873 # NOTE: Sleep needed to give some time for rule to be added and
1874 # registered to the instance. If you are calling this function
1875 # multiple times this sleep will prevent any errors.
1876 # DO NOT REMOVE
Jon Hall63604932015-02-26 17:09:50 -08001877 # time.sleep( 5 )
Jon Hall21270ac2015-02-16 17:59:55 -08001878 try:
1879 # input validation
1880 action_type = action.lower()
1881 rule = rule.upper()
1882 direction = direction.upper()
1883 if action_type != 'add' and action_type != 'remove':
1884 main.log.error( "Invalid action type. Use 'add' or "
1885 "'remove' table rule" )
1886 if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
1887 # NOTE Currently only supports rules DROP, ACCEPT, and LOG
1888 main.log.error( "Invalid rule. Valid rules are 'DROP' or "
1889 "'ACCEPT' or 'LOG' only." )
1890 if direction != 'INPUT' and direction != 'OUTPUT':
1891 # NOTE currently only supports rules INPUT and OUPTUT
1892 main.log.error( "Invalid rule. Valid directions are"
1893 " 'OUTPUT' or 'INPUT'" )
1894 return main.FALSE
1895 return main.FALSE
1896 return main.FALSE
1897 if action_type == 'add':
1898 # -A is the 'append' action of iptables
1899 actionFlag = '-A'
1900 elif action_type == 'remove':
1901 # -D is the 'delete' rule of iptables
1902 actionFlag = '-D'
1903 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001904 self.handle.expect( self.prompt )
Jon Hall21270ac2015-02-16 17:59:55 -08001905 cmd = "sudo iptables " + actionFlag + " " +\
1906 direction +\
Jon Hall21270ac2015-02-16 17:59:55 -08001907 " -s " + str( ip )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001908 # " -p " + str( packet_type ) +\
Jon Hall63604932015-02-26 17:09:50 -08001909 if packet_type:
1910 cmd += " -p " + str( packet_type )
Jon Hall21270ac2015-02-16 17:59:55 -08001911 if port:
1912 cmd += " --dport " + str( port )
Jon Hall63604932015-02-26 17:09:50 -08001913 if states:
1914 cmd += " -m state --state="
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001915 # FIXME- Allow user to configure which states to block
Jon Hall63604932015-02-26 17:09:50 -08001916 cmd += "INVALID,ESTABLISHED,NEW,RELATED,UNTRACKED"
Jon Hall21270ac2015-02-16 17:59:55 -08001917 cmd += " -j " + str( rule )
1918
1919 self.handle.sendline( cmd )
Devin Limc20e79a2017-06-07 10:29:57 -07001920 self.handle.expect( self.prompt )
Jon Hall21270ac2015-02-16 17:59:55 -08001921 main.log.warn( self.handle.before )
1922
1923 info_string = "On " + str( self.name )
1924 info_string += " " + str( action_type )
1925 info_string += " iptable rule [ "
1926 info_string += " IP: " + str( ip )
1927 info_string += " Port: " + str( port )
1928 info_string += " Rule: " + str( rule )
1929 info_string += " Direction: " + str( direction ) + " ]"
1930 main.log.info( info_string )
1931 return main.TRUE
1932 except pexpect.TIMEOUT:
1933 main.log.exception( self.name + ": Timeout exception in "
1934 "setIpTables function" )
You Wang141b43b2018-06-26 16:50:18 -07001935 self.handle.send( "\x03" ) # Control-C
1936 self.handle.expect( self.prompt )
Jon Hall21270ac2015-02-16 17:59:55 -08001937 return main.ERROR
1938 except pexpect.EOF:
1939 main.log.error( self.name + ": EOF exception found" )
1940 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001941 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001942 except Exception:
1943 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001944 main.cleanAndExit()
Jon Hall21270ac2015-02-16 17:59:55 -08001945
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001946 def detailed_status( self, log_filename ):
Jon Hallefbd9792015-03-05 16:11:36 -08001947 """
Jon Hall0468b042015-02-19 19:08:21 -08001948 This method is used by STS to check the status of the controller
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001949 Reports RUNNING, STARTING, STOPPED, FROZEN, ERROR (and reason)
Jon Hallefbd9792015-03-05 16:11:36 -08001950 """
Jon Hall0468b042015-02-19 19:08:21 -08001951 import re
1952 try:
1953 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001954 self.handle.expect( self.prompt )
Jon Hall0468b042015-02-19 19:08:21 -08001955 self.handle.sendline( "cd " + self.home )
Devin Limc20e79a2017-06-07 10:29:57 -07001956 self.handle.expect( self.prompt )
Jon Hall0468b042015-02-19 19:08:21 -08001957 self.handle.sendline( "service onos status" )
Devin Limc20e79a2017-06-07 10:29:57 -07001958 self.handle.expect( self.prompt )
Jon Hall0468b042015-02-19 19:08:21 -08001959 response = self.handle.before
1960 if re.search( "onos start/running", response ):
1961 # onos start/running, process 10457
1962 return 'RUNNING'
1963 # FIXME: Implement this case
1964 # elif re.search( pattern, response ):
1965 # return 'STARTING'
1966 elif re.search( "onos stop/", response ):
1967 # onos stop/waiting
1968 # FIXME handle this differently?: onos stop/pre-stop
1969 return 'STOPPED'
1970 # FIXME: Implement this case
1971 # elif re.search( pattern, response ):
1972 # return 'FROZEN'
1973 else:
1974 main.log.warn( self.name +
Jon Hallefbd9792015-03-05 16:11:36 -08001975 " WARNING: status received unknown response" )
Jon Hall0468b042015-02-19 19:08:21 -08001976 main.log.warn( response )
1977 return 'ERROR', "Unknown response: %s" % response
1978 except pexpect.TIMEOUT:
1979 main.log.exception( self.name + ": Timeout exception in "
1980 "setIpTables function" )
You Wang141b43b2018-06-26 16:50:18 -07001981 self.handle.send( "\x03" ) # Control-C
1982 self.handle.expect( self.prompt )
Jon Hall0468b042015-02-19 19:08:21 -08001983 return 'ERROR', "Pexpect Timeout"
1984 except pexpect.EOF:
1985 main.log.error( self.name + ": EOF exception found" )
1986 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001987 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001988 except Exception:
1989 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001990 main.cleanAndExit()
Jon Hall0468b042015-02-19 19:08:21 -08001991
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001992 def createLinkGraphFile( self, benchIp, ONOSIpList, deviceCount ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001993 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07001994 Create/formats the LinkGraph.cfg file based on arguments
1995 -only creates a linear topology and connects islands
1996 -evenly distributes devices
andrew@onlab.us3b087132015-03-11 15:00:08 -07001997 -must be called by ONOSbench
1998
Jon Hall4ba53f02015-07-29 13:07:41 -07001999 ONOSIpList - list of all of the node IPs to be used
2000
2001 deviceCount - number of switches to be assigned
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002002 '''
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002003 main.log.info( "Creating link graph configuration file." )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002004 linkGraphPath = self.home + "/tools/package/etc/linkGraph.cfg"
Jon Hall4ba53f02015-07-29 13:07:41 -07002005 tempFile = "/tmp/linkGraph.cfg"
andrew@onlab.us3b087132015-03-11 15:00:08 -07002006
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002007 linkGraph = open( tempFile, 'w+' )
2008 linkGraph.write( "# NullLinkProvider topology description (config file).\n" )
2009 linkGraph.write( "# The NodeId is only added if the destination is another node's device.\n" )
2010 linkGraph.write( "# Bugs: Comments cannot be appended to a line to be read.\n" )
Jon Hall4ba53f02015-07-29 13:07:41 -07002011
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002012 clusterCount = len( ONOSIpList )
Jon Hall4ba53f02015-07-29 13:07:41 -07002013
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002014 if isinstance( deviceCount, int ) or isinstance( deviceCount, str ):
2015 deviceCount = int( deviceCount )
2016 switchList = [ 0 ]*( clusterCount+1 )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002017 baselineSwitchCount = deviceCount/clusterCount
Jon Hall4ba53f02015-07-29 13:07:41 -07002018
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002019 for node in range( 1, clusterCount + 1 ):
2020 switchList[ node ] = baselineSwitchCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07002021
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002022 for node in range( 1, ( deviceCount % clusterCount )+1 ):
2023 switchList[ node ] += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07002024
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002025 if isinstance( deviceCount, list ):
2026 main.log.info( "Using provided device distribution" )
2027 switchList = [ 0 ]
andrew@onlab.us3b087132015-03-11 15:00:08 -07002028 for i in deviceCount:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002029 switchList.append( int( i ) )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002030
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002031 tempList = [ '0' ]
2032 tempList.extend( ONOSIpList )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002033 ONOSIpList = tempList
2034
2035 myPort = 6
2036 lastSwitch = 0
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002037 for node in range( 1, clusterCount+1 ):
2038 if switchList[ node ] == 0:
andrew@onlab.us3b087132015-03-11 15:00:08 -07002039 continue
2040
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002041 linkGraph.write( "graph " + ONOSIpList[ node ] + " {\n" )
Jon Hall4ba53f02015-07-29 13:07:41 -07002042
andrew@onlab.us3b087132015-03-11 15:00:08 -07002043 if node > 1:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002044 # connect to last device on previous node
2045 line = ( "\t0:5 -> " + str( lastSwitch ) + ":6:" + lastIp + "\n" ) # ONOSIpList[node-1]
2046 linkGraph.write( line )
Jon Hall4ba53f02015-07-29 13:07:41 -07002047
2048 lastSwitch = 0
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002049 for switch in range( 0, switchList[ node ]-1 ):
andrew@onlab.us3b087132015-03-11 15:00:08 -07002050 line = ""
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002051 line = ( "\t" + str( switch ) + ":" + str( myPort ) )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002052 line += " -- "
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002053 line += ( str( switch+1 ) + ":" + str( myPort-1 ) + "\n" )
2054 linkGraph.write( line )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002055 lastSwitch = switch+1
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002056 lastIp = ONOSIpList[ node ]
Jon Hall4ba53f02015-07-29 13:07:41 -07002057
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002058 # lastSwitch += 1
2059 if node < ( clusterCount ):
2060 # connect to first device on the next node
2061 line = ( "\t" + str( lastSwitch ) + ":6 -> 0:5:" + ONOSIpList[ node+1 ] + "\n" )
2062 linkGraph.write( line )
Jon Hall4ba53f02015-07-29 13:07:41 -07002063
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002064 linkGraph.write( "}\n" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002065 linkGraph.close()
2066
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002067 # SCP
2068 os.system( "scp " + tempFile + " " + self.user_name + "@" + benchIp + ":" + linkGraphPath )
2069 main.log.info( "linkGraph.cfg creation complete" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002070
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002071 def configNullDev( self, ONOSIpList, deviceCount, numPorts=10 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002072 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07002073 ONOSIpList = list of Ip addresses of nodes switches will be devided amongst
2074 deviceCount = number of switches to distribute, or list of values to use as custom distribution
cameron@onlab.us75900962015-03-30 13:22:49 -07002075 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 +00002076 '''
2077
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002078 main.log.info( "Configuring Null Device Provider" )
2079 clusterCount = len( ONOSIpList )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002080
Jon Hall4ba53f02015-07-29 13:07:41 -07002081 try:
2082
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002083 if isinstance( deviceCount, int ) or isinstance( deviceCount, str ):
2084 main.log.info( "Creating device distribution" )
2085 deviceCount = int( deviceCount )
2086 switchList = [ 0 ]*( clusterCount+1 )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002087 baselineSwitchCount = deviceCount/clusterCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07002088
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002089 for node in range( 1, clusterCount + 1 ):
2090 switchList[ node ] = baselineSwitchCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07002091
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002092 for node in range( 1, ( deviceCount % clusterCount )+1 ):
2093 switchList[ node ] += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07002094
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002095 if isinstance( deviceCount, list ):
2096 main.log.info( "Using provided device distribution" )
Jon Hall4ba53f02015-07-29 13:07:41 -07002097
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002098 if len( deviceCount ) == clusterCount:
2099 switchList = [ '0' ]
2100 switchList.extend( deviceCount )
Jon Hall4ba53f02015-07-29 13:07:41 -07002101
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002102 if len( deviceCount ) == ( clusterCount + 1 ):
2103 if deviceCount[ 0 ] == '0' or deviceCount[ 0 ] == 0:
cameron@onlab.us75900962015-03-30 13:22:49 -07002104 switchList = deviceCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07002105
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002106 assert len( switchList ) == ( clusterCount + 1 )
Jon Hall4ba53f02015-07-29 13:07:41 -07002107
cameron@onlab.us75900962015-03-30 13:22:49 -07002108 except AssertionError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002109 main.log.error( "Bad device/Ip list match" )
cameron@onlab.us75900962015-03-30 13:22:49 -07002110 except TypeError:
2111 main.log.exception( self.name + ": Object not as expected" )
2112 return None
Jon Hall77ba41c2015-04-06 10:25:40 -07002113 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002114 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002115 main.cleanAndExit()
cameron@onlab.us75900962015-03-30 13:22:49 -07002116
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002117 ONOSIp = [ 0 ]
2118 ONOSIp.extend( ONOSIpList )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002119
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002120 devicesString = "devConfigs = "
2121 for node in range( 1, len( ONOSIp ) ):
2122 devicesString += ( ONOSIp[ node ] + ":" + str( switchList[ node ] ) )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002123 if node < clusterCount:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002124 devicesString += ( "," )
Jon Hall4ba53f02015-07-29 13:07:41 -07002125
2126 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002127 self.handle.sendline( "onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider devConfigs " + devicesString )
2128 self.handle.expect( ":~" )
2129 self.handle.sendline( "onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider numPorts " + str( numPorts ) )
2130 self.handle.expect( ":~" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002131
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002132 for i in range( 10 ):
2133 self.handle.sendline( "onos $OC1 cfg get org.onosproject.provider.nil.device.impl.NullDeviceProvider" )
2134 self.handle.expect( ":~" )
cameron@onlab.us75900962015-03-30 13:22:49 -07002135 verification = self.handle.before
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002136 if ( " value=" + str( numPorts ) ) in verification and ( " value=" + devicesString ) in verification:
cameron@onlab.us75900962015-03-30 13:22:49 -07002137 break
2138 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002139 time.sleep( 1 )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002140
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002141 assert ( "value=" + str( numPorts ) ) in verification and ( " value=" + devicesString ) in verification
Jon Hall4ba53f02015-07-29 13:07:41 -07002142
cameron@onlab.us75900962015-03-30 13:22:49 -07002143 except AssertionError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002144 main.log.error( "Incorrect Config settings: " + verification )
Jon Hall77ba41c2015-04-06 10:25:40 -07002145 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002146 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002147 main.cleanAndExit()
cameron@onlab.us75900962015-03-30 13:22:49 -07002148
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002149 def configNullLink( self, fileName="/opt/onos/apache-karaf-3.0.3/etc/linkGraph.cfg", eventRate=0 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002150 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07002151 fileName default is currently the same as the default on ONOS, specify alternate file if
cameron@onlab.us75900962015-03-30 13:22:49 -07002152 you want to use a different topology file than linkGraph.cfg
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002153 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07002154
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002155 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002156 self.handle.sendline( "onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider eventRate " + str( eventRate ) )
2157 self.handle.expect( ":~" )
2158 self.handle.sendline( "onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider cfgFile " + fileName )
2159 self.handle.expect( ":~" )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002160
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002161 for i in range( 10 ):
2162 self.handle.sendline( "onos $OC1 cfg get org.onosproject.provider.nil.link.impl.NullLinkProvider" )
2163 self.handle.expect( ":~" )
cameron@onlab.us75900962015-03-30 13:22:49 -07002164 verification = self.handle.before
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002165 if ( " value=" + str( eventRate ) ) in verification and ( " value=" + fileName ) in verification:
cameron@onlab.us75900962015-03-30 13:22:49 -07002166 break
Jon Hall4ba53f02015-07-29 13:07:41 -07002167 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002168 time.sleep( 1 )
Jon Hall4ba53f02015-07-29 13:07:41 -07002169
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002170 assert ( "value=" + str( eventRate ) ) in verification and ( " value=" + fileName ) in verification
Jon Hall4ba53f02015-07-29 13:07:41 -07002171
cameron@onlab.us75900962015-03-30 13:22:49 -07002172 except pexpect.EOF:
2173 main.log.error( self.name + ": EOF exception found" )
2174 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002175 main.cleanAndExit()
cameron@onlab.us75900962015-03-30 13:22:49 -07002176 except AssertionError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002177 main.log.info( "Settings did not post to ONOS" )
Jon Hall3e6edb32018-08-21 16:20:30 -07002178 main.log.error( verification )
Jon Hall77ba41c2015-04-06 10:25:40 -07002179 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002180 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall3e6edb32018-08-21 16:20:30 -07002181 main.log.error( verification )
Devin Lim44075962017-08-11 10:56:37 -07002182 main.cleanAndExit()
andrew@onlab.us3b087132015-03-11 15:00:08 -07002183
kelvin-onlaba4074292015-07-09 15:19:49 -07002184 def getOnosIps( self ):
2185 """
2186 Get all onos IPs stored in
2187 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002188
kelvin-onlaba4074292015-07-09 15:19:49 -07002189 return sorted( self.onosIps.values() )
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002190
Chiyu Chengec63bde2016-11-17 18:11:36 -08002191 def listLog( self, nodeIp ):
2192 """
2193 Get a list of all the karaf log names
2194 """
2195 try:
2196 cmd = "onos-ssh " + nodeIp + " ls -tr /opt/onos/log"
2197 self.handle.sendline( cmd )
2198 self.handle.expect( ":~" )
2199 before = self.handle.before.splitlines()
2200 logNames = []
2201 for word in before:
2202 if 'karaf.log' in word:
2203 logNames.append( word )
2204 return logNames
2205 except pexpect.EOF:
2206 main.log.error( self.name + ": EOF exception found" )
2207 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002208 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08002209 except pexpect.TIMEOUT:
2210 main.log.error( self.name + ": TIMEOUT exception found" )
2211 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002212 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08002213 except Exception:
2214 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002215 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08002216
Pratik Parab3b2ab5a2017-02-14 13:15:14 -08002217 def logReport( self, nodeIp, searchTerms, outputMode="s", startStr=None, endStr=None ):
Jon Hallb4242222016-01-25 17:07:04 -08002218 """
2219 Searches the latest ONOS log file for the given search terms and
2220 prints the total occurances of each term. Returns to combined total of
2221 all occurances.
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002222
Jon Hallb4242222016-01-25 17:07:04 -08002223 Arguments:
2224 * nodeIp - The ip of the ONOS node where the log is located
2225 * searchTerms - A string to grep for or a list of strings to grep
2226 for in the ONOS log. Will print out the number of
2227 occurances for each term.
2228 Optional Arguments:
2229 * outputMode - 's' or 'd'. If 'd' will print the last 5 lines
2230 containing each search term as well as the total
2231 number of occurances of each term. Defaults to 's',
2232 which prints the simple output of just the number
2233 of occurances for each term.
Pratik Parab3b2ab5a2017-02-14 13:15:14 -08002234 * startStr - the start string to be given to stream editor command
2235 as the start point for extraction of data
2236 * endStr - the end string to be given to stream editor command as
2237 the end point for extraction of data
Jon Hallb4242222016-01-25 17:07:04 -08002238 """
2239 try:
2240 main.log.info( " Log Report for {} ".format( nodeIp ).center( 70, '=' ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002241 if isinstance( searchTerms, str ):
2242 searchTerms = [ searchTerms ]
Jon Hallb4242222016-01-25 17:07:04 -08002243 numTerms = len( searchTerms )
2244 outputMode = outputMode.lower()
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002245
Jon Hallb4242222016-01-25 17:07:04 -08002246 totalHits = 0
2247 logLines = []
2248 for termIndex in range( numTerms ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002249 term = searchTerms[ termIndex ]
2250 logLines.append( [ term ] )
Pratik Parab3b2ab5a2017-02-14 13:15:14 -08002251 if startStr and endStr:
2252 cmd = "onos-ssh {} \"sed -n '/{}/,/{}/p' /opt/onos/log/karaf.log | grep {}\"".format( nodeIp,
2253 startStr,
2254 endStr,
2255 term )
2256 else:
2257 cmd = "onos-ssh {} cat /opt/onos/log/karaf.log | grep {}".format( nodeIp,
2258 term )
Jon Hallb4242222016-01-25 17:07:04 -08002259 self.handle.sendline( cmd )
2260 self.handle.expect( ":~" )
2261 before = self.handle.before.splitlines()
2262 count = 0
2263 for line in before:
2264 if term in line and "grep" not in line:
2265 count += 1
2266 if before.index( line ) > ( len( before ) - 7 ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002267 logLines[ termIndex ].append( line )
Jon Hallb4242222016-01-25 17:07:04 -08002268 main.log.info( "{}: {}".format( term, count ) )
2269 totalHits += count
2270 if termIndex == numTerms - 1:
2271 print "\n"
2272 if outputMode != "s":
2273 outputString = ""
2274 for term in logLines:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002275 outputString = term[ 0 ] + ": \n"
Jon Hallb4242222016-01-25 17:07:04 -08002276 for line in range( 1, len( term ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002277 outputString += ( "\t" + term[ line ] + "\n" )
2278 if outputString != ( term[ 0 ] + ": \n" ):
Jon Hallb4242222016-01-25 17:07:04 -08002279 main.log.info( outputString )
2280 main.log.info( "=" * 70 )
2281 return totalHits
2282 except pexpect.EOF:
2283 main.log.error( self.name + ": EOF exception found" )
2284 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002285 main.cleanAndExit()
Jon Hallb4242222016-01-25 17:07:04 -08002286 except pexpect.TIMEOUT:
2287 main.log.error( self.name + ": TIMEOUT exception found" )
2288 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002289 main.cleanAndExit()
Jon Hallb4242222016-01-25 17:07:04 -08002290 except Exception:
2291 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002292 main.cleanAndExit()
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002293
2294 def copyMininetFile( self, fileName, localPath, userName, ip,
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002295 mnPath='~/mininet/custom/', timeout = 60 ):
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002296 """
2297 Description:
2298 Copy mininet topology file from dependency folder in the test folder
2299 and paste it to the mininet machine's mininet/custom folder
2300 Required:
2301 fileName - Name of the topology file to copy
2302 localPath - File path of the mininet topology file
2303 userName - User name of the mininet machine to send the file to
2304 ip - Ip address of the mininet machine
2305 Optional:
2306 mnPath - of the mininet directory to send the file to
2307 Return:
2308 Return main.TRUE if successfully copied the file otherwise
2309 return main.FALSE
2310 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002311
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002312 try:
2313 cmd = "scp " + localPath + fileName + " " + userName + "@" + \
2314 str( ip ) + ":" + mnPath + fileName
2315
2316 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07002317 self.handle.expect( self.prompt )
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002318
2319 main.log.info( self.name + ": Execute: " + cmd )
2320
2321 self.handle.sendline( cmd )
2322
2323 i = self.handle.expect( [ 'No such file',
2324 "100%",
2325 pexpect.TIMEOUT ] )
2326
2327 if i == 0:
2328 main.log.error( self.name + ": File " + fileName +
2329 " does not exist!" )
2330 return main.FALSE
2331
2332 if i == 1:
2333 main.log.info( self.name + ": File " + fileName +
2334 " has been copied!" )
2335 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07002336 self.handle.expect( self.prompt )
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002337 return main.TRUE
2338
2339 except pexpect.EOF:
2340 main.log.error( self.name + ": EOF exception found" )
2341 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002342 main.cleanAndExit()
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002343 except pexpect.TIMEOUT:
2344 main.log.error( self.name + ": TIMEOUT exception found" )
2345 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002346 main.cleanAndExit()
cameron@onlab.us78b89652015-07-08 15:21:03 -07002347
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002348 def jvmSet( self, memory=8 ):
Jon Hall4ba53f02015-07-29 13:07:41 -07002349
cameron@onlab.us78b89652015-07-08 15:21:03 -07002350 import os
2351
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002352 homeDir = os.path.expanduser( '~' )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002353 filename = "/onos/tools/package/bin/onos-service"
2354
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002355 serviceConfig = open( homeDir + filename, 'w+' )
2356 serviceConfig.write( "#!/bin/bash\n " )
2357 serviceConfig.write( "#------------------------------------- \n " )
2358 serviceConfig.write( "# Starts ONOS Apache Karaf container\n " )
2359 serviceConfig.write( "#------------------------------------- \n " )
2360 serviceConfig.write( "#export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-7-openjdk-amd64/}\n " )
2361 serviceConfig.write( """export JAVA_OPTS="${JAVA_OPTS:--Xms""" + str( memory ) + "G -Xmx" + str( memory ) + """G}" \n """ )
2362 serviceConfig.write( "[ -d $ONOS_HOME ] && cd $ONOS_HOME || ONOS_HOME=$(dirname $0)/..\n" )
2363 serviceConfig.write( """${ONOS_HOME}/apache-karaf-$KARAF_VERSION/bin/karaf "$@" \n """ )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002364 serviceConfig.close()
2365
Jon Hall6c44c0b2016-04-20 15:21:00 -07002366 def createDBFile( self, testData ):
Jon Hall4ba53f02015-07-29 13:07:41 -07002367
cameron@onlab.us78b89652015-07-08 15:21:03 -07002368 filename = main.TEST + "DB"
2369 DBString = ""
Jon Hall4ba53f02015-07-29 13:07:41 -07002370
cameron@onlab.us78b89652015-07-08 15:21:03 -07002371 for item in testData:
Jon Hall3e6edb32018-08-21 16:20:30 -07002372 if isinstance( item, str ):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002373 item = "'" + item + "'"
Jon Hall6c44c0b2016-04-20 15:21:00 -07002374 if testData.index( item ) < len( testData - 1 ):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002375 item += ","
Jon Hall6c44c0b2016-04-20 15:21:00 -07002376 DBString += str( item )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002377
Jon Hall6c44c0b2016-04-20 15:21:00 -07002378 DBFile = open( filename, "a" )
2379 DBFile.write( DBString )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002380 DBFile.close()
2381
Jon Hall6c44c0b2016-04-20 15:21:00 -07002382 def verifySummary( self, ONOSIp, *deviceCount ):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002383
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002384 self.handle.sendline( "onos " + ONOSIp + " summary" )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002385 self.handle.expect( ":~" )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002386
2387 summaryStr = self.handle.before
2388 print "\nSummary\n==============\n" + summaryStr + "\n\n"
2389
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002390 # passed = "SCC(s)=1" in summaryStr
2391 # if deviceCount:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002392 # passed = "devices=" + str(deviceCount) + "," not in summaryStr
cameron@onlab.us78b89652015-07-08 15:21:03 -07002393
GlennRC772363b2015-08-25 13:05:57 -07002394 passed = False
cameron@onlab.us78b89652015-07-08 15:21:03 -07002395 if "SCC(s)=1," in summaryStr:
2396 passed = True
Jon Hall6c44c0b2016-04-20 15:21:00 -07002397 print "Summary is verifed"
Jon Hall4ba53f02015-07-29 13:07:41 -07002398 else:
Jon Hall6c44c0b2016-04-20 15:21:00 -07002399 print "Summary failed"
cameron@onlab.us78b89652015-07-08 15:21:03 -07002400
2401 if deviceCount:
2402 print" ============================="
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002403 checkStr = "devices=" + str( deviceCount[ 0 ] ) + ","
cameron@onlab.us78b89652015-07-08 15:21:03 -07002404 print "Checkstr: " + checkStr
2405 if checkStr not in summaryStr:
2406 passed = False
Jon Hall6c44c0b2016-04-20 15:21:00 -07002407 print "Device count failed"
Jon Hall4ba53f02015-07-29 13:07:41 -07002408 else:
2409 print "device count verified"
cameron@onlab.us78b89652015-07-08 15:21:03 -07002410
2411 return passed
Jon Hall6c44c0b2016-04-20 15:21:00 -07002412
Jon Hall8f6d4622016-05-23 15:27:18 -07002413 def getIpAddr( self, iface=None ):
Jon Hall6c44c0b2016-04-20 15:21:00 -07002414 """
2415 Update self.ip_address with numerical ip address. If multiple IP's are
2416 located on the device, will attempt to use self.nicAddr to choose the
2417 right one. Defaults to 127.0.0.1 if no other address is found or cannot
2418 determine the correct address.
2419
2420 ONLY WORKS WITH IPV4 ADDRESSES
2421 """
2422 try:
Jon Hall8f6d4622016-05-23 15:27:18 -07002423 LOCALHOST = "127.0.0.1"
Jon Hall6c44c0b2016-04-20 15:21:00 -07002424 ipPat = "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"
2425 pattern = re.compile( ipPat )
2426 match = re.search( pattern, self.ip_address )
2427 if self.nicAddr:
2428 nicPat = self.nicAddr.replace( ".", "\." ).replace( "\*", r"\d{1,3}" )
2429 nicPat = re.compile( nicPat )
2430 else:
2431 nicPat = None
2432 # IF self.ip_address is an ip address and matches
2433 # self.nicAddr: return self.ip_address
2434 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002435 curIp = match.group( 0 )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002436 if nicPat:
2437 nicMatch = re.search( nicPat, curIp )
2438 if nicMatch:
2439 return self.ip_address
Jon Hall8f6d4622016-05-23 15:27:18 -07002440 # ELSE: IF iface, return ip of interface
2441 cmd = "ifconfig"
2442 ifPat = re.compile( "inet addr:({})".format( ipPat ) )
2443 if iface:
2444 cmd += " " + str( iface )
2445 raw = subprocess.check_output( cmd.split() )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002446 ifPat = re.compile( "inet addr:({})".format( ipPat ) )
2447 ips = re.findall( ifPat, raw )
Jon Hall8f6d4622016-05-23 15:27:18 -07002448 if iface:
2449 if ips:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002450 ip = ips[ 0 ]
Jon Hall8f6d4622016-05-23 15:27:18 -07002451 self.ip_address = ip
2452 return ip
2453 else:
2454 main.log.error( "Error finding ip, ifconfig output:".format( raw ) )
2455 # ELSE: attempt to get address matching nicPat.
Jon Hall6c44c0b2016-04-20 15:21:00 -07002456 if nicPat:
2457 for ip in ips:
2458 curMatch = re.search( nicPat, ip )
2459 if curMatch:
2460 self.ip_address = ip
2461 return ip
Jon Hall8f6d4622016-05-23 15:27:18 -07002462 else: # If only one non-localhost ip, return that
2463 tmpList = [ ip for ip in ips if ip is not LOCALHOST ]
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002464 if len( tmpList ) == 1:
2465 curIp = tmpList[ 0 ]
Jon Hall6c44c0b2016-04-20 15:21:00 -07002466 self.ip_address = curIp
2467 return curIp
Jon Hall8f6d4622016-05-23 15:27:18 -07002468 # Either no non-localhost IPs, or more than 1
Jon Hallebccd352016-05-20 15:17:17 -07002469 main.log.warn( "getIpAddr failed to find a public IP address" )
Jon Hall8f6d4622016-05-23 15:27:18 -07002470 return LOCALHOST
Jon Halle1790952016-05-23 15:51:46 -07002471 except subprocess.CalledProcessError:
Jon Hall8f6d4622016-05-23 15:27:18 -07002472 main.log.exception( "Error executing ifconfig" )
2473 except IndexError:
2474 main.log.exception( "Error getting IP Address" )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002475 except Exception:
2476 main.log.exception( "Uncaught exception" )
suibin zhang116647a2016-05-06 16:30:09 -07002477
Devin Lim461f0872017-06-05 16:49:33 -07002478 def startBasicONOS( self, nodeList, opSleep=60, onosStartupSleep=30, onosUser="sdn" ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002479 '''
suibin zhang116647a2016-05-06 16:30:09 -07002480 Start onos cluster with defined nodes, but only with drivers app
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002481 '''
suibin zhang116647a2016-05-06 16:30:09 -07002482 import time
2483
2484 self.createCellFile( self.ip_address,
Jon Hall3e6edb32018-08-21 16:20:30 -07002485 "temp",
2486 self.ip_address,
2487 "drivers",
2488 nodeList,
2489 nodeList,
2490 onosUser=onosUser )
suibin zhang116647a2016-05-06 16:30:09 -07002491
2492 main.log.info( self.name + ": Apply cell to environment" )
2493 cellResult = self.setCell( "temp" )
2494 verifyResult = self.verifyCell()
2495
2496 main.log.info( self.name + ": Creating ONOS package" )
You Wangd1bcaca2016-10-24 15:23:26 -07002497 packageResult = self.buckBuild( timeout=opSleep )
suibin zhang116647a2016-05-06 16:30:09 -07002498
You Wangc669d212017-01-25 11:09:48 -08002499 main.log.info( self.name + ": Uninstalling ONOS" )
2500 for nd in nodeList:
2501 self.onosUninstall( nodeIp=nd )
2502
suibin zhang116647a2016-05-06 16:30:09 -07002503 main.log.info( self.name + ": Installing ONOS package" )
2504 for nd in nodeList:
You Wangc669d212017-01-25 11:09:48 -08002505 self.onosInstall( node=nd )
2506
2507 main.log.info( self.name + ": Set up ONOS secure SSH" )
2508 for nd in nodeList:
2509 self.onosSecureSSH( node=nd )
suibin zhang116647a2016-05-06 16:30:09 -07002510
2511 main.log.info( self.name + ": Starting ONOS service" )
2512 time.sleep( onosStartupSleep )
2513
2514 onosStatus = True
2515 for nd in nodeList:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002516 onosStatus = onosStatus & self.isup( node = nd )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002517 # print "onosStatus is: " + str( onosStatus )
suibin zhang116647a2016-05-06 16:30:09 -07002518
2519 return main.TRUE if onosStatus else main.FALSE
2520
Devin Lim02075272017-07-10 15:33:21 -07002521 def onosNetCfg( self, controllerIp, path, fileName ):
Jeremy Songster5665f1b2016-06-20 14:38:22 -07002522 """
2523 Push a specified json file to ONOS through the onos-netcfg service
2524
2525 Required:
Devin Lim02075272017-07-10 15:33:21 -07002526 controllerIp - the Ip of the ONOS node in the cluster
Jeremy Songster5665f1b2016-06-20 14:38:22 -07002527 path - the location of the file to be sent
2528 fileName - name of the json file to be sent
2529
2530 Returns main.TRUE on successfully sending json file, and main.FALSE if
2531 there is an error.
2532 """
2533 try:
Devin Lim02075272017-07-10 15:33:21 -07002534 cmd = "onos-netcfg {0} {1}{2}".format( controllerIp, path, fileName )
2535 main.log.info( "Sending: " + cmd )
2536 main.ONOSbench.handle.sendline( cmd )
Jeremy Ronquillo3008aa32017-07-07 15:38:57 -07002537 main.ONOSbench.handle.expect( self.prompt )
Devin Lim02075272017-07-10 15:33:21 -07002538 handle = self.handle.before
Jeremy Ronquillo3008aa32017-07-07 15:38:57 -07002539 if "Error" in handle or "No such file or directory" in handle or "curl: " in handle:
2540 main.log.error( self.name + ": " + handle + self.handle.after )
Devin Lim02075272017-07-10 15:33:21 -07002541 return main.FALSE
Devin Lim752dd7b2017-06-27 14:40:03 -07002542 return main.TRUE
Jeremy Songster5665f1b2016-06-20 14:38:22 -07002543 except pexpect.EOF:
2544 main.log.error( self.name + ": EOF exception found" )
2545 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002546 main.cleanAndExit()
Jeremy Songster5665f1b2016-06-20 14:38:22 -07002547 except Exception:
2548 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002549 main.cleanAndExit()
Devin Lim3ebd5e72017-11-14 10:38:00 -08002550
2551 def formCluster( self, onosIPs ):
2552 """
2553 From ONOS cluster for IP addresses in onosIPs list
2554 """
2555 try:
2556 onosIPs = " ".join( onosIPs )
2557 command = "onos-form-cluster {}".format( onosIPs )
2558 main.log.info( "Sending: " + command )
2559 self.handle.sendline( "" )
2560 self.handle.expect( self.prompt )
2561 self.handle.sendline( command )
2562 self.handle.expect( self.prompt )
2563 handle = self.handle.before
2564 main.log.debug( handle )
2565 assert handle is not None, "Error in sendline"
2566 assert "Command not found:" not in handle, handle
2567 assert "Error" not in handle, handle
2568 assert "Exception:" not in handle, handle
2569 assert "curl:" not in handle, handle
2570 return main.TRUE
2571 except AssertionError:
2572 main.log.exception( "{} Error in onos-form-cluster output:".format( self.name ) )
2573 return main.FALSE
2574 except TypeError:
2575 main.log.exception( self.name + ": Object not as expected" )
2576 return main.FALSE
2577 except pexpect.EOF:
2578 main.log.error( self.name + ": EOF exception found" )
2579 main.log.error( self.name + ": " + self.handle.before )
2580 main.cleanAndExit()
2581 except Exception:
2582 main.log.exception( self.name + ": Uncaught exception!" )
2583 main.cleanAndExit()
Jon Hall7ce46ea2018-02-05 12:20:59 -08002584
2585 def backupData( self, location ):
2586 """
2587 Backs up ONOS data and logs to a given location. Returns main.FALSE
2588 if there is an error executing the command, and main.TRUE otherwise.
2589 required arguments:
2590 loaction - The file path to save the backup to
2591 """
2592 try:
2593 cmd = "/opt/onos/bin/onos-backup " + str( location )
2594 self.handle.sendline( cmd )
2595 self.handle.expect( self.prompt )
2596 handle = self.handle.before
2597 main.log.debug( handle )
2598 assert handle is not None, "Error in sendline"
2599 assert "Command not found:" not in handle, handle
2600 assert "Error" not in handle, handle
2601 assert "Exception:" not in handle, handle
2602 return main.TRUE
2603 except AssertionError:
2604 main.log.exception( "{} Error in onos-backup output:".format( self.name ) )
2605 return main.FALSE
2606 except TypeError:
2607 main.log.exception( self.name + ": Object not as expected" )
2608 return main.FALSE
2609 except pexpect.EOF:
2610 main.log.error( self.name + ": EOF exception found" )
2611 main.log.error( self.name + ": " + self.handle.before )
2612 main.cleanAndExit()
2613 except Exception:
2614 main.log.exception( self.name + ": Uncaught exception!" )
2615 main.cleanAndExit()
2616
2617 def restoreData( self, location ):
2618 """
2619 Restores ONOS data and logs from a given location. Returns main.FALSE
2620 if there is an error executing the command, and main.TRUE otherwise.
2621 required arguments:
2622 loaction - The file path of a backup file
2623 """
2624 try:
2625 cmd = "/opt/onos/bin/onos-restore " + str( location )
2626 self.handle.sendline( cmd )
2627 self.handle.expect( self.prompt )
2628 handle = self.handle.before
2629 main.log.debug( handle )
2630 assert handle is not None, "Error in sendline"
2631 assert "Command not found:" not in handle, handle
2632 assert "Error" not in handle, handle
2633 assert "Exception:" not in handle, handle
2634 return main.TRUE
2635 except AssertionError:
2636 main.log.exception( "{} Error in onos-restore output:".format( self.name ) )
2637 return main.FALSE
2638 except TypeError:
2639 main.log.exception( self.name + ": Object not as expected" )
2640 return main.FALSE
2641 except pexpect.EOF:
2642 main.log.error( self.name + ": EOF exception found" )
2643 main.log.error( self.name + ": " + self.handle.before )
2644 main.cleanAndExit()
2645 except Exception:
2646 main.log.exception( self.name + ": Uncaught exception!" )
2647 main.cleanAndExit()
You Wang5df1c6d2018-04-06 18:02:02 -07002648
You Wang5ac7db72018-07-17 11:17:52 -07002649 def onosDiagnostics( self, onosIPs, dstDir, suffix, timeout=300 ):
You Wang5df1c6d2018-04-06 18:02:02 -07002650 """
2651 Run onos-diagnostics with given ONOS instance IPs and save output to dstDir
2652 with suffix specified E.g. onos-diags-suffix.tar.gz
Jon Hall0e240372018-05-02 11:21:57 -07002653 required arguments:
You Wang5df1c6d2018-04-06 18:02:02 -07002654 onosIPs - list of ONOS IPs for collecting diags
2655 dstDir - diags file will be saved under the directory specified
2656 suffix - diags file will be named with the suffix specified
2657 returns:
2658 main.FALSE if there's an error executing the command, and main.TRUE otherwise
2659 """
2660 try:
2661 cmd = "onos-diagnostics"
2662 assert isinstance( onosIPs, list )
2663 for ip in onosIPs:
2664 cmd += " " + str( ip )
2665 self.handle.sendline( cmd )
You Wang5ac7db72018-07-17 11:17:52 -07002666 self.handle.expect( self.prompt, timeout=timeout )
You Wang5df1c6d2018-04-06 18:02:02 -07002667 handle = self.handle.before
2668 main.log.debug( handle )
2669 assert handle is not None, "Error in sendline"
2670 assert "Command not found:" not in handle, handle
2671 assert "Exception:" not in handle, handle
2672 # Rename and move diags file to dstDir from /tmp
2673 if dstDir[ -1: ] != "/":
2674 dstDir += "/"
2675 self.handle.sendline( "mv /tmp/onos-diags.tar.gz " + str( dstDir ) + "onos-diags" + str( suffix ) + ".tar.gz" )
2676 self.handle.expect( self.prompt )
2677 handle = self.handle.before
2678 main.log.debug( handle )
2679 assert handle is not None, "Error in sendline"
2680 assert "No such file or directory" not in handle, handle
2681 return main.TRUE
2682 except AssertionError:
2683 main.log.exception( "{} Error in onos-diagnostics output:".format( self.name ) )
2684 return main.FALSE
2685 except TypeError:
2686 main.log.exception( self.name + ": Object not as expected" )
2687 return main.FALSE
You Wang223faa32018-06-21 10:45:47 -07002688 except pexpect.TIMEOUT:
2689 main.log.exception( self.name + ": TIMEOUT exception found in onosDiagnostics" )
2690 main.log.error( self.name + ": " + self.handle.before )
You Wangb65d2372018-08-17 15:37:59 -07002691 self.exitFromCmd( self.prompt, 100 )
You Wang223faa32018-06-21 10:45:47 -07002692 return main.FALSE
You Wang5df1c6d2018-04-06 18:02:02 -07002693 except pexpect.EOF:
2694 main.log.error( self.name + ": EOF exception found" )
2695 main.log.error( self.name + ": " + self.handle.before )
2696 main.cleanAndExit()
2697 except Exception:
2698 main.log.exception( self.name + ": Uncaught exception!" )
2699 main.cleanAndExit()
Jon Hall0e240372018-05-02 11:21:57 -07002700
2701 def onosPower( self, onosIP, toggle, userName=None ):
2702 """
2703 Run onos-power script to tell the cell warden to simulate a power faulure
2704 for the given container.
2705 required :
2706 onosIP - ONOS node IP
2707 toggle - either "off" or "on", used to indicate whether
2708 the node should be powered off or on
2709 returns:
2710 main.FALSE if there's an error executing the command, and main.TRUE otherwise
2711 """
2712 try:
2713 cmd = "onos-power {} {}".format( onosIP, toggle )
2714 if userName:
2715 cmd += " {}".format( userName )
2716 self.handle.sendline( cmd )
2717 self.handle.expect( self.prompt )
2718 handle = self.handle.before
2719 main.log.debug( handle )
2720 assert handle is not None, "Error in sendline"
2721 assert "Command not found:" not in handle, handle
2722 assert "Exception:" not in handle, handle
2723 assert "usage:" not in handle, handle
2724 return main.TRUE
2725 except AssertionError:
2726 main.log.exception( "{} Error in onos-power output:".format( self.name ) )
2727 return main.FALSE
2728 except TypeError:
2729 main.log.exception( self.name + ": Object not as expected" )
2730 return main.FALSE
2731 except pexpect.EOF:
2732 main.log.error( self.name + ": EOF exception found" )
2733 main.log.error( self.name + ": " + self.handle.before )
2734 main.cleanAndExit()
2735 except Exception:
2736 main.log.exception( self.name + ": Uncaught exception!" )
2737 main.cleanAndExit()
You Wangf9d95be2018-08-01 14:35:37 -07002738
2739 def atomixKill( self, nodeIp ):
2740 """
2741 Calls the command: 'atomix-kill [<node-ip>]'
2742 Kills the Atomix instance running on the specified node
2743 """
2744 try:
2745 self.handle.sendline( "" )
2746 self.handle.expect( self.prompt )
2747 self.handle.sendline( "atomix-kill " + str( nodeIp ) )
2748 i = self.handle.expect( [
2749 self.prompt,
2750 "No\sroute\sto\shost",
2751 "password:",
2752 pexpect.TIMEOUT ], timeout=60 )
2753
2754 if i == 0:
2755 main.log.info( "Atomix instance " + str( nodeIp ) + " was killed" )
2756 return main.TRUE
2757 elif i == 1:
2758 main.log.info( "No route to host" )
2759 return main.FALSE
2760 elif i == 2:
2761 main.log.info( "Passwordless login for host: " + str( nodeIp ) + " not configured" )
2762 return main.FALSE
2763 else:
2764 main.log.info( "Atomix instance was not killed" )
2765 return main.FALSE
2766
2767 except pexpect.EOF:
2768 main.log.error( self.name + ": EOF exception found" )
2769 main.log.error( self.name + ": " + self.handle.before )
2770 main.cleanAndExit()
2771 except Exception:
2772 main.log.exception( self.name + ": Uncaught exception!" )
2773 main.cleanAndExit()
2774
2775 def atomixUninstall( self, nodeIp="" ):
2776 """
2777 Calls the command: 'atomix-uninstall'
2778 Uninstalls Atomix from the designated node, stopping if needed
2779 """
2780 try:
2781 self.handle.sendline( "" )
2782 self.handle.expect( self.prompt, timeout=180 )
2783 self.handle.sendline( "atomix-uninstall " + str( nodeIp ) )
2784 self.handle.expect( self.prompt, timeout=180 )
2785 main.log.info( "Atomix " + nodeIp + " was uninstalled" )
2786 # onos-uninstall command does not return any text
2787 return main.TRUE
2788 except pexpect.TIMEOUT:
2789 main.log.exception( self.name + ": Timeout in atomixUninstall" )
2790 self.handle.send( "\x03" ) # Control-C
2791 self.handle.expect( self.prompt )
2792 return main.FALSE
2793 except pexpect.EOF:
2794 main.log.error( self.name + ": EOF exception found" )
2795 main.log.error( self.name + ": " + self.handle.before )
2796 main.cleanAndExit()
2797 except Exception:
2798 main.log.exception( self.name + ": Uncaught exception!" )
2799 main.cleanAndExit()
2800
2801 def atomixInstall( self, options="", node="" ):
2802 """
2803 Installs Atomix on the designated nodes.
2804 Returns: main.TRUE on success and main.FALSE on failure
2805 """
2806 try:
2807 if options:
2808 self.handle.sendline( "atomix-install " + options + " " + node )
2809 else:
2810 self.handle.sendline( "atomix-install " + node )
2811 self.handle.expect( "atomix-install " )
2812 i = self.handle.expect( [ "Network\sis\sunreachable",
2813 "is already installed",
2814 "saved",
2815 self.prompt,
2816 pexpect.TIMEOUT ], timeout=180 )
2817 if i == 0:
2818 # can't reach ONOS node
Jon Hall3e6edb32018-08-21 16:20:30 -07002819 main.log.warn( self.name + ": Network is unreachable" )
You Wangf9d95be2018-08-01 14:35:37 -07002820 self.handle.expect( self.prompt )
2821 return main.FALSE
2822 elif i == 1:
2823 # same bits are already on Atomix node
Jon Hall3e6edb32018-08-21 16:20:30 -07002824 main.log.info( self.name + ": Atomix is already installed on " + node )
You Wangf9d95be2018-08-01 14:35:37 -07002825 self.handle.expect( self.prompt )
2826 return main.TRUE
Jon Hallb685a1c2018-10-30 15:17:01 -07002827 elif i == 2:
Jon Hall3e6edb32018-08-21 16:20:30 -07002828 main.log.info( self.name + ": Atomix was installed on " + node )
You Wangf9d95be2018-08-01 14:35:37 -07002829 self.handle.expect( self.prompt )
2830 return main.TRUE
Jon Hallb685a1c2018-10-30 15:17:01 -07002831 elif i == 3:
2832 self.handle.sendline( "echo Return code: $?" )
2833 self.handle.expect( "\$\?" )
2834 self.handle.expect( self.prompt )
Jon Hallb685a1c2018-10-30 15:17:01 -07002835 match = re.search( "Return code: (\d+)", self.handle.before )
2836 if match:
2837 exitCode = int( match.group( 1 ) )
2838 else:
2839 # Didn't match pattern
2840 main.log.error( "Could not parse exit code of atomix-install" )
Jon Hall5e1469a2018-11-01 13:55:53 -07002841 main.log.debug( self.handle.before + self.handle.before )
Jon Hallb685a1c2018-10-30 15:17:01 -07002842 return main.FALSE
2843 if exitCode == 0:
2844 return main.TRUE
2845 else:
Jon Hall5e1469a2018-11-01 13:55:53 -07002846 main.log.error( "Unsuccessful exit code of atomix-install" )
2847 main.log.debug( self.handle.before + self.handle.before )
Jon Hallb685a1c2018-10-30 15:17:01 -07002848 return main.FALSE
You Wangf9d95be2018-08-01 14:35:37 -07002849 elif i == 4:
2850 # timeout
Jon Hall3e6edb32018-08-21 16:20:30 -07002851 main.log.info( self.name + ": Installation of Atomix on " + node + " timed out" )
You Wangf9d95be2018-08-01 14:35:37 -07002852 self.handle.expect( self.prompt )
2853 main.log.warn( self.handle.before )
2854 self.handle.send( "\x03" ) # Control-C
2855 self.handle.expect( self.prompt )
2856 return main.FALSE
2857 except pexpect.EOF:
2858 main.log.error( self.name + ": EOF exception found" )
2859 main.log.error( self.name + ": " + self.handle.before )
2860 main.cleanAndExit()
2861 except Exception:
2862 main.log.exception( self.name + ": Uncaught exception!" )
2863 main.cleanAndExit()