blob: d948748976266f59ffd32bbf9f338f77cf7b771f [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 Hall74645422019-06-06 23:58:06 +0000132
Jon Hall05b2b432014-10-08 19:53:25 -0400133 if self.handle:
Jon Hall0fc0d452015-07-14 09:49:58 -0700134 self.handle.sendline( "cd " + self.home )
Jon Hall4b668212019-06-17 11:08:49 -0700135 self.handle.expect( "cd " + self.home )
Devin Limc20e79a2017-06-07 10:29:57 -0700136 self.handle.expect( self.prompt )
Jon Hall05b2b432014-10-08 19:53:25 -0400137 return self.handle
kelvin8ec71442015-01-15 16:57:00 -0800138 else:
Jon Hall0fc0d452015-07-14 09:49:58 -0700139 main.log.info( "Failed to create ONOS handle" )
Jon Hall05b2b432014-10-08 19:53:25 -0400140 return main.FALSE
141 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800142 main.log.error( self.name + ": EOF exception found" )
143 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700144 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800145 except Exception:
146 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700147 main.cleanAndExit()
Jon Hall05b2b432014-10-08 19:53:25 -0400148
kelvin8ec71442015-01-15 16:57:00 -0800149 def disconnect( self ):
150 """
Jon Hall05b2b432014-10-08 19:53:25 -0400151 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800152 """
Jon Halld61331b2015-02-17 16:35:47 -0800153 response = main.TRUE
Jon Hall05b2b432014-10-08 19:53:25 -0400154 try:
Jon Hall61282e32015-03-19 11:34:11 -0700155 if self.handle:
156 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -0700157 self.handle.expect( self.prompt )
Jon Hall61282e32015-03-19 11:34:11 -0700158 self.handle.sendline( "exit" )
159 self.handle.expect( "closed" )
Jon Hall05b2b432014-10-08 19:53:25 -0400160 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800161 main.log.error( self.name + ": EOF exception found" )
162 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700163 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700164 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700165 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800166 except Exception:
167 main.log.exception( self.name + ": Connection failed to the host" )
Jon Hall05b2b432014-10-08 19:53:25 -0400168 response = main.FALSE
169 return response
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400170
andrew@onlab.usaee415a2015-06-05 14:38:58 -0400171 def getEpochMs( self ):
172 """
173 Returns milliseconds since epoch
Jon Hall4ba53f02015-07-29 13:07:41 -0700174
175 When checking multiple nodes in a for loop,
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000176 around a hundred milliseconds of difference (ascending) is
Jon Hall4ba53f02015-07-29 13:07:41 -0700177 generally acceptable due to calltime of the function.
178 Few seconds, however, is not and it means clocks
179 are off sync.
andrew@onlab.usaee415a2015-06-05 14:38:58 -0400180 """
181 try:
182 self.handle.sendline( 'date +%s.%N' )
183 self.handle.expect( 'date \+\%s\.\%N' )
Devin Limdc78e202017-06-09 18:30:07 -0700184 self.handle.expect( self.prompt )
andrew@onlab.usaee415a2015-06-05 14:38:58 -0400185 epochMs = self.handle.before
186 return epochMs
187 except Exception:
188 main.log.exception( 'Uncaught exception getting epoch time' )
Devin Lim44075962017-08-11 10:56:37 -0700189 main.cleanAndExit()
andrew@onlab.usaee415a2015-06-05 14:38:58 -0400190
Jon Hall6c44c0b2016-04-20 15:21:00 -0700191 def onosPackage( self, opTimeout=180 ):
kelvin8ec71442015-01-15 16:57:00 -0800192 """
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400193 Produce a self-contained tar.gz file that can be deployed
Jon Hall64af8502015-12-15 10:09:33 -0800194 and executed on any platform with Java 8 JRE.
kelvin8ec71442015-01-15 16:57:00 -0800195 """
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400196 try:
Jon Hall64af8502015-12-15 10:09:33 -0800197 ret = main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800198 self.handle.sendline( "onos-package" )
199 self.handle.expect( "onos-package" )
Jon Hall96451092016-05-04 09:42:30 -0700200 while True:
201 i = self.handle.expect( [ "Downloading",
202 "Unknown options",
203 "No such file or directory",
204 "tar.gz",
Devin Limc20e79a2017-06-07 10:29:57 -0700205 self.prompt ],
Jon Hall96451092016-05-04 09:42:30 -0700206 opTimeout )
207 handle = str( self.handle.before + self.handle.after )
208 if i == 0:
209 # Give more time to download the file
210 continue # expect again
211 elif i == 1:
212 # Incorrect usage
213 main.log.error( "onos-package does not recognize the given options" )
214 ret = main.FALSE
215 continue # expect again
216 elif i == 2:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000217 # File(s) not found
Jon Hall96451092016-05-04 09:42:30 -0700218 main.log.error( "onos-package could not find a file or directory" )
219 ret = main.FALSE
220 continue # expect again
221 elif i == 3:
222 # tar.gz
223 continue # expect again
224 elif i == 4:
225 # Prompt returned
226 break
Jon Hallc6793552016-01-19 14:18:37 -0800227 main.log.info( "onos-package command returned: " + handle )
kelvin8ec71442015-01-15 16:57:00 -0800228 # As long as the sendline does not time out,
229 # return true. However, be careful to interpret
230 # the results of the onos-package command return
Jon Hall64af8502015-12-15 10:09:33 -0800231 return ret
232 except pexpect.TIMEOUT:
233 main.log.exception( self.name + ": TIMEOUT exception found in onosPackage" )
234 main.log.error( self.name + ": " + self.handle.before )
You Wang141b43b2018-06-26 16:50:18 -0700235 self.handle.send( "\x03" ) # Control-C
236 self.handle.expect( self.prompt )
Jon Hall64af8502015-12-15 10:09:33 -0800237 return main.FALSE
andrewonlab7735d852014-10-09 13:02:47 -0400238 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800239 main.log.error( self.name + ": EOF exception found" )
240 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700241 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800242 except Exception:
243 main.log.exception( "Failed to package ONOS" )
Devin Lim44075962017-08-11 10:56:37 -0700244 main.cleanAndExit()
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400245
kelvin-onlabd3b64892015-01-20 13:26:24 -0800246 def onosBuild( self ):
kelvin8ec71442015-01-15 16:57:00 -0800247 """
andrewonlab8790abb2014-11-06 13:51:54 -0500248 Use the pre defined script to build onos via mvn
kelvin8ec71442015-01-15 16:57:00 -0800249 """
andrewonlab8790abb2014-11-06 13:51:54 -0500250 try:
kelvin8ec71442015-01-15 16:57:00 -0800251 self.handle.sendline( "onos-build" )
252 self.handle.expect( "onos-build" )
253 i = self.handle.expect( [
kelvin-onlabd3b64892015-01-20 13:26:24 -0800254 "BUILD SUCCESS",
255 "ERROR",
256 "BUILD FAILED" ],
257 timeout=120 )
kelvin8ec71442015-01-15 16:57:00 -0800258 handle = str( self.handle.before )
Devin Limc20e79a2017-06-07 10:29:57 -0700259 self.handle.expect( self.prompt )
andrewonlab8790abb2014-11-06 13:51:54 -0500260
kelvin8ec71442015-01-15 16:57:00 -0800261 main.log.info( "onos-build command returned: " +
262 handle )
andrewonlab8790abb2014-11-06 13:51:54 -0500263
264 if i == 0:
265 return main.TRUE
266 else:
267 return handle
268
269 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800270 main.log.error( self.name + ": EOF exception found" )
271 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -0800272 except Exception:
273 main.log.exception( "Failed to build ONOS" )
Devin Lim44075962017-08-11 10:56:37 -0700274 main.cleanAndExit()
andrewonlab8790abb2014-11-06 13:51:54 -0500275
shahshreya9f531fe2015-06-10 12:03:51 -0700276 def cleanInstall( self, skipTest=False, mciTimeout=600 ):
kelvin8ec71442015-01-15 16:57:00 -0800277 """
278 Runs mvn clean install in the root of the ONOS directory.
279 This will clean all ONOS artifacts then compile each module
shahshreya9f531fe2015-06-10 12:03:51 -0700280 Optional:
281 skipTest - Does "-DskipTests -Dcheckstyle.skip -U -T 1C" which
282 skip the test. This will make the building faster.
283 Disregarding the credibility of the build
kelvin8ec71442015-01-15 16:57:00 -0800284 Returns: main.TRUE on success
Jon Hallde9d9aa2014-10-08 20:36:02 -0400285 On Failure, exits the test
kelvin8ec71442015-01-15 16:57:00 -0800286 """
Jon Hallde9d9aa2014-10-08 20:36:02 -0400287 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800288 main.log.info( "Running 'mvn clean install' on " +
289 str( self.name ) +
kelvin8ec71442015-01-15 16:57:00 -0800290 ". This may take some time." )
291 self.handle.sendline( "cd " + self.home )
Devin Limc20e79a2017-06-07 10:29:57 -0700292 self.handle.expect( self.prompt )
Jon Hallea7818b2014-10-09 14:30:59 -0400293
kelvin8ec71442015-01-15 16:57:00 -0800294 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -0700295 self.handle.expect( self.prompt )
shahshreya9f531fe2015-06-10 12:03:51 -0700296
297 if not skipTest:
298 self.handle.sendline( "mvn clean install" )
299 self.handle.expect( "mvn clean install" )
300 else:
301 self.handle.sendline( "mvn clean install -DskipTests" +
302 " -Dcheckstyle.skip -U -T 1C" )
303 self.handle.expect( "mvn clean install -DskipTests" +
304 " -Dcheckstyle.skip -U -T 1C" )
kelvin8ec71442015-01-15 16:57:00 -0800305 while True:
306 i = self.handle.expect( [
Jon Hall274b6642015-02-17 11:57:17 -0800307 'There\sis\sinsufficient\smemory\sfor\sthe\sJava\s' +
Jon Hallefbd9792015-03-05 16:11:36 -0800308 'Runtime\sEnvironment\sto\scontinue',
Jon Hallde9d9aa2014-10-08 20:36:02 -0400309 'BUILD\sFAILURE',
310 'BUILD\sSUCCESS',
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700311 'onos' + self.prompt, # TODO: fix this to be more generic?
Devin Limdc78e202017-06-09 18:30:07 -0700312 'ONOS' + self.prompt,
pingping-lin57a56ce2015-05-20 16:43:48 -0700313 pexpect.TIMEOUT ], mciTimeout )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400314 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800315 main.log.error( self.name + ":There is insufficient memory \
316 for the Java Runtime Environment to continue." )
317 # return main.FALSE
Devin Lim44075962017-08-11 10:56:37 -0700318
319 main.cleanAndExit()
Jon Hallde9d9aa2014-10-08 20:36:02 -0400320 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800321 main.log.error( self.name + ": Build failure!" )
322 # return main.FALSE
Devin Lim44075962017-08-11 10:56:37 -0700323
324 main.cleanAndExit()
Jon Hallde9d9aa2014-10-08 20:36:02 -0400325 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800326 main.log.info( self.name + ": Build success!" )
Jon Halle94919c2015-03-23 11:42:57 -0700327 elif i == 3 or i == 4:
kelvin8ec71442015-01-15 16:57:00 -0800328 main.log.info( self.name + ": Build complete" )
329 # Print the build time
Jon Hallf8ef52c2014-10-09 19:37:33 -0400330 for line in self.handle.before.splitlines():
331 if "Total time:" in line:
kelvin8ec71442015-01-15 16:57:00 -0800332 main.log.info( line )
333 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -0700334 self.handle.expect( self.prompt, timeout=60 )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400335 return main.TRUE
Jon Halle94919c2015-03-23 11:42:57 -0700336 elif i == 5:
kelvin8ec71442015-01-15 16:57:00 -0800337 main.log.error(
338 self.name +
339 ": mvn clean install TIMEOUT!" )
340 # return main.FALSE
Devin Lim44075962017-08-11 10:56:37 -0700341
342 main.cleanAndExit()
Jon Hallde9d9aa2014-10-08 20:36:02 -0400343 else:
Jon Hall274b6642015-02-17 11:57:17 -0800344 main.log.error( self.name + ": unexpected response from " +
Jon Hallefbd9792015-03-05 16:11:36 -0800345 "mvn clean install" )
kelvin8ec71442015-01-15 16:57:00 -0800346 # return main.FALSE
Devin Lim44075962017-08-11 10:56:37 -0700347
348 main.cleanAndExit()
Jon Hallde9d9aa2014-10-08 20:36:02 -0400349 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800350 main.log.error( self.name + ": EOF exception found" )
351 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700352 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800353 except Exception:
354 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700355 main.cleanAndExit()
Jon Hallacabffd2014-10-09 12:36:53 -0400356
Jon Hall3576f572016-08-23 10:01:07 -0700357 def buckBuild( self, timeout=180 ):
358 """
359 Build onos using buck.
360 """
361 try:
362 ret = main.TRUE
363 self.handle.sendline( "buck build onos" )
364 self.handle.expect( "buck build onos" )
365 output = ""
366 while True:
367 i = self.handle.expect( [ "This does not appear to be the root of a Buck project.",
368 "\n",
369 "BUILD FAILED",
Jon Halld9066132018-03-01 14:52:53 -0800370 "no buck in",
Devin Limc20e79a2017-06-07 10:29:57 -0700371 self.prompt ],
Jon Hall3576f572016-08-23 10:01:07 -0700372 timeout=timeout )
373 output += str( self.handle.before + self.handle.after )
374 if i == 0:
375 main.log.error( "Wrong location" )
376 ret = main.FALSE
377 elif i == 1:
378 # end of a line, buck is still printing output
379 pass
380 elif i == 2:
381 # Build failed
382 main.log.error( "Build failed" )
383 ret = main.FALSE
384 elif i == 3:
Jon Halld9066132018-03-01 14:52:53 -0800385 main.log.error( "Could not find buck in your PATH." )
386 ret = main.FALSE
387 elif i == 4:
Jon Hall3576f572016-08-23 10:01:07 -0700388 # Prompt returned
389 break
390 main.log.debug( output )
391 return ret
392 except pexpect.TIMEOUT:
393 main.log.exception( self.name + ": TIMEOUT exception found" )
394 main.log.error( self.name + ": " + self.handle.before )
You Wang141b43b2018-06-26 16:50:18 -0700395 self.handle.send( "\x03" ) # Control-C
396 self.handle.expect( self.prompt )
Jon Hall3576f572016-08-23 10:01:07 -0700397 return main.FALSE
398 except pexpect.EOF:
399 main.log.error( self.name + ": EOF exception found" )
400 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700401 main.cleanAndExit()
Jon Hall3576f572016-08-23 10:01:07 -0700402 except Exception:
403 main.log.exception( "Failed to build and package ONOS" )
Devin Lim44075962017-08-11 10:56:37 -0700404 main.cleanAndExit()
Jon Hall3576f572016-08-23 10:01:07 -0700405
You Wangd54c7052018-08-07 16:06:27 -0700406 def bazelBuild( self, timeout=180 ):
407 """
408 Build onos using bazel.
409 """
410 try:
411 ret = main.TRUE
412 self.handle.sendline( "bazel build onos" )
413 self.handle.expect( "bazel build onos" )
414 output = ""
415 while True:
416 i = self.handle.expect( [ "command is only supported from within a workspace",
417 "\n",
418 "FAILED",
419 "ERROR",
420 "command not found",
421 self.prompt ],
422 timeout=timeout )
423 output += str( self.handle.before + self.handle.after )
424 if i == 0:
425 main.log.error( "Please run the build from root of ONOS project" )
426 ret = main.FALSE
427 elif i == 1:
428 # end of a line, buck is still printing output
429 pass
430 elif i == 2:
431 # Build failed
432 main.log.error( "Build failed" )
433 ret = main.FALSE
434 elif i == 3:
435 # Build failed
436 main.log.error( "Build failed" )
437 ret = main.FALSE
438 elif i == 4:
439 main.log.error( "Command not found" )
440 ret = main.FALSE
441 elif i == 5:
442 # Prompt returned
443 break
444 main.log.debug( output )
445 return ret
446 except pexpect.TIMEOUT:
447 main.log.exception( self.name + ": TIMEOUT exception found" )
448 main.log.error( self.name + ": " + self.handle.before )
449 self.handle.send( "\x03" ) # Control-C
450 self.handle.expect( self.prompt )
451 return main.FALSE
452 except pexpect.EOF:
453 main.log.error( self.name + ": EOF exception found" )
454 main.log.error( self.name + ": " + self.handle.before )
455 main.cleanAndExit()
456 except Exception:
457 main.log.exception( "Failed to build and package ONOS" )
458 main.cleanAndExit()
459
Jon Hall61282e32015-03-19 11:34:11 -0700460 def gitPull( self, comp1="", fastForward=True ):
kelvin8ec71442015-01-15 16:57:00 -0800461 """
Jon Hallacabffd2014-10-09 12:36:53 -0400462 Assumes that "git pull" works without login
Jon Hall47a93fb2015-01-06 16:46:06 -0800463
Jon Hall61282e32015-03-19 11:34:11 -0700464 If the fastForward boolean is set to true, only git pulls that can
465 be fast forwarded will be performed. IE if you have not local commits
466 in your branch.
467
Jon Hallacabffd2014-10-09 12:36:53 -0400468 This function will perform a git pull on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800469 If used as gitPull( "NODE" ) it will do git pull + NODE. This is
Jon Hallacabffd2014-10-09 12:36:53 -0400470 for the purpose of pulling from other nodes if necessary.
471
Jon Hall47a93fb2015-01-06 16:46:06 -0800472 Otherwise, this function will perform a git pull in the
Jon Hallacabffd2014-10-09 12:36:53 -0400473 ONOS repository. If it has any problems, it will return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -0800474 If it successfully does a gitPull, it will return a 1 ( main.TRUE )
Shreya Shahee15f6c2014-10-28 18:12:30 -0400475 If it has no updates, it will return 3.
Jon Hallacabffd2014-10-09 12:36:53 -0400476
kelvin8ec71442015-01-15 16:57:00 -0800477 """
Jon Hallacabffd2014-10-09 12:36:53 -0400478 try:
kelvin8ec71442015-01-15 16:57:00 -0800479 self.handle.sendline( "cd " + self.home )
Devin Limc20e79a2017-06-07 10:29:57 -0700480 self.handle.expect( self.prompt )
Jon Hall61282e32015-03-19 11:34:11 -0700481 cmd = "git pull"
482 if comp1 != "":
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700483 cmd += ' ' + comp1
Jon Hall61282e32015-03-19 11:34:11 -0700484 if fastForward:
485 cmd += ' ' + " --ff-only"
486 self.handle.sendline( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800487 i = self.handle.expect(
488 [
489 'fatal',
490 'Username\sfor\s(.*):\s',
491 '\sfile(s*) changed,\s',
492 'Already up-to-date',
493 'Aborting',
494 'You\sare\snot\scurrently\son\sa\sbranch',
Jon Hall274b6642015-02-17 11:57:17 -0800495 'You asked me to pull without telling me which branch you',
496 'Pull is not possible because you have unmerged files',
Jon Hall61282e32015-03-19 11:34:11 -0700497 'Please enter a commit message to explain why this merge',
498 'Found a swap file by the name',
499 'Please, commit your changes before you can merge.',
kelvin-onlabd3b64892015-01-20 13:26:24 -0800500 pexpect.TIMEOUT ],
501 timeout=300 )
kelvin8ec71442015-01-15 16:57:00 -0800502 if i == 0:
Jon Hall61282e32015-03-19 11:34:11 -0700503 main.log.error( self.name + ": Git pull had some issue" )
504 output = self.handle.after
Devin Limdc78e202017-06-09 18:30:07 -0700505 self.handle.expect( self.prompt )
Jon Hall61282e32015-03-19 11:34:11 -0700506 output += self.handle.before
507 main.log.warn( output )
Jon Hallacabffd2014-10-09 12:36:53 -0400508 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800509 elif i == 1:
510 main.log.error(
511 self.name +
512 ": Git Pull Asking for username. " )
Jon Hallacabffd2014-10-09 12:36:53 -0400513 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800514 elif i == 2:
515 main.log.info(
516 self.name +
517 ": Git Pull - pulling repository now" )
Devin Limc20e79a2017-06-07 10:29:57 -0700518 self.handle.expect( self.prompt, 120 )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800519 # So that only when git pull is done, we do mvn clean compile
520 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800521 elif i == 3:
522 main.log.info( self.name + ": Git Pull - Already up to date" )
Devin Limc20e79a2017-06-07 10:29:57 -0700523 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800524 elif i == 4:
525 main.log.info(
526 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800527 ": Git Pull - Aborting..." +
528 "Are there conflicting git files?" )
Jon Hallacabffd2014-10-09 12:36:53 -0400529 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800530 elif i == 5:
531 main.log.info(
532 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800533 ": Git Pull - You are not currently " +
534 "on a branch so git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400535 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800536 elif i == 6:
537 main.log.info(
538 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800539 ": Git Pull - You have not configured an upstream " +
540 "branch to pull from. Git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400541 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800542 elif i == 7:
543 main.log.info(
544 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800545 ": Git Pull - Pull is not possible because " +
546 "you have unmerged files." )
Jon Hallacabffd2014-10-09 12:36:53 -0400547 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800548 elif i == 8:
Jon Hall61282e32015-03-19 11:34:11 -0700549 # NOTE: abandoning test since we can't reliably handle this
550 # there could be different default text editors and we
551 # also don't know if we actually want to make the commit
552 main.log.error( "Git pull resulted in a merge commit message" +
553 ". Exiting test!" )
Devin Lim44075962017-08-11 10:56:37 -0700554
555 main.cleanAndExit()
Jon Hall61282e32015-03-19 11:34:11 -0700556 elif i == 9: # Merge commit message but swap file exists
557 main.log.error( "Git pull resulted in a merge commit message" +
558 " but a swap file exists." )
559 try:
560 self.handle.send( 'A' ) # Abort
Devin Limc20e79a2017-06-07 10:29:57 -0700561 self.handle.expect( self.prompt )
Jon Hall61282e32015-03-19 11:34:11 -0700562 return main.ERROR
563 except Exception:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700564 main.log.exception( "Couldn't exit editor prompt!" )
Devin Lim44075962017-08-11 10:56:37 -0700565
566 main.cleanAndExit()
Jon Hall61282e32015-03-19 11:34:11 -0700567 elif i == 10: # In the middle of a merge commit
568 main.log.error( "Git branch is in the middle of a merge. " )
569 main.log.warn( self.handle.before + self.handle.after )
570 return main.ERROR
571 elif i == 11:
kelvin8ec71442015-01-15 16:57:00 -0800572 main.log.error( self.name + ": Git Pull - TIMEOUT" )
573 main.log.error(
574 self.name + " Response was: " + str(
575 self.handle.before ) )
You Wang141b43b2018-06-26 16:50:18 -0700576 self.handle.send( "\x03" ) # Control-C
577 self.handle.expect( self.prompt )
Jon Hallacabffd2014-10-09 12:36:53 -0400578 return main.ERROR
579 else:
kelvin8ec71442015-01-15 16:57:00 -0800580 main.log.error(
581 self.name +
582 ": Git Pull - Unexpected response, check for pull errors" )
Jon Hallacabffd2014-10-09 12:36:53 -0400583 return main.ERROR
584 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800585 main.log.error( self.name + ": EOF exception found" )
586 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700587 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800588 except Exception:
589 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700590 main.cleanAndExit()
Jon Hallacabffd2014-10-09 12:36:53 -0400591
kelvin-onlabd3b64892015-01-20 13:26:24 -0800592 def gitCheckout( self, branch="master" ):
kelvin8ec71442015-01-15 16:57:00 -0800593 """
Jon Hallacabffd2014-10-09 12:36:53 -0400594 Assumes that "git pull" works without login
kelvin8ec71442015-01-15 16:57:00 -0800595
Jon Hallacabffd2014-10-09 12:36:53 -0400596 This function will perform a git git checkout on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800597 If used as gitCheckout( "branch" ) it will do git checkout
598 of the "branch".
Jon Hallacabffd2014-10-09 12:36:53 -0400599
600 Otherwise, this function will perform a git checkout of the master
kelvin8ec71442015-01-15 16:57:00 -0800601 branch of the ONOS repository. If it has any problems, it will return
602 main.ERROR.
603 If the branch was already the specified branch, or the git checkout was
Jon Hallacabffd2014-10-09 12:36:53 -0400604 successful then the function will return main.TRUE.
605
kelvin8ec71442015-01-15 16:57:00 -0800606 """
Jon Hallacabffd2014-10-09 12:36:53 -0400607 try:
kelvin8ec71442015-01-15 16:57:00 -0800608 self.handle.sendline( "cd " + self.home )
Devin Limc20e79a2017-06-07 10:29:57 -0700609 self.handle.expect( self.prompt )
Jon Hall274b6642015-02-17 11:57:17 -0800610 main.log.info( self.name +
611 ": Checking out git branch/ref: " + branch + "..." )
kelvin8ec71442015-01-15 16:57:00 -0800612 cmd = "git checkout " + branch
613 self.handle.sendline( cmd )
614 self.handle.expect( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800615 i = self.handle.expect(
Jon Hall274b6642015-02-17 11:57:17 -0800616 [ 'fatal',
Jon Hall61282e32015-03-19 11:34:11 -0700617 'Username for (.*): ',
618 'Already on \'',
Jon Hall7a8354f2015-06-10 15:37:00 -0700619 'Switched to (a new )?branch \'' + str( branch ),
Jon Hall274b6642015-02-17 11:57:17 -0800620 pexpect.TIMEOUT,
621 'error: Your local changes to the following files' +
Jon Hallefbd9792015-03-05 16:11:36 -0800622 'would be overwritten by checkout:',
Jon Hall274b6642015-02-17 11:57:17 -0800623 'error: you need to resolve your current index first',
624 "You are in 'detached HEAD' state.",
625 "HEAD is now at " ],
kelvin-onlabd3b64892015-01-20 13:26:24 -0800626 timeout=60 )
kelvin8ec71442015-01-15 16:57:00 -0800627 if i == 0:
628 main.log.error(
629 self.name +
630 ": Git checkout had some issue..." )
631 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400632 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800633 elif i == 1:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800634 main.log.error(
635 self.name +
636 ": Git checkout asking for username." +
637 " Please configure your local git repository to be able " +
638 "to access your remote repository passwordlessly" )
Jon Hall274b6642015-02-17 11:57:17 -0800639 # TODO add support for authenticating
Jon Hallacabffd2014-10-09 12:36:53 -0400640 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800641 elif i == 2:
642 main.log.info(
643 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800644 ": Git Checkout %s : Already on this branch" % branch )
Devin Limc20e79a2017-06-07 10:29:57 -0700645 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -0800646 # main.log.info( "DEBUG: after checkout cmd = "+
647 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400648 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800649 elif i == 3:
650 main.log.info(
651 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800652 ": Git checkout %s - Switched to this branch" % branch )
Devin Limc20e79a2017-06-07 10:29:57 -0700653 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -0800654 # main.log.info( "DEBUG: after checkout cmd = "+
655 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400656 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800657 elif i == 4:
658 main.log.error( self.name + ": Git Checkout- TIMEOUT" )
659 main.log.error(
Jon Hall274b6642015-02-17 11:57:17 -0800660 self.name + " Response was: " + str( self.handle.before ) )
You Wang141b43b2018-06-26 16:50:18 -0700661 self.handle.send( "\x03" ) # Control-C
662 self.handle.expect( self.prompt )
Jon Hallacabffd2014-10-09 12:36:53 -0400663 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800664 elif i == 5:
665 self.handle.expect( "Aborting" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800666 main.log.error(
667 self.name +
668 ": Git checkout error: \n" +
Jon Hall274b6642015-02-17 11:57:17 -0800669 "Your local changes to the following files would" +
670 " be overwritten by checkout:" +
671 str( self.handle.before ) )
Devin Limc20e79a2017-06-07 10:29:57 -0700672 self.handle.expect( self.prompt )
Jon Hall81e29af2014-11-04 20:41:23 -0500673 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800674 elif i == 6:
Jon Hall274b6642015-02-17 11:57:17 -0800675 main.log.error(
676 self.name +
677 ": Git checkout error: \n" +
678 "You need to resolve your current index first:" +
679 str( self.handle.before ) )
Devin Limc20e79a2017-06-07 10:29:57 -0700680 self.handle.expect( self.prompt )
Jon Hall81e29af2014-11-04 20:41:23 -0500681 return main.ERROR
Jon Hall274b6642015-02-17 11:57:17 -0800682 elif i == 7:
683 main.log.info(
684 self.name +
685 ": Git checkout " + str( branch ) +
686 " - You are in 'detached HEAD' state. HEAD is now at " +
687 str( branch ) )
Devin Limc20e79a2017-06-07 10:29:57 -0700688 self.handle.expect( self.prompt )
Jon Hall274b6642015-02-17 11:57:17 -0800689 return main.TRUE
690 elif i == 8: # Already in detached HEAD on the specified commit
691 main.log.info(
692 self.name +
693 ": Git Checkout %s : Already on commit" % branch )
Devin Limc20e79a2017-06-07 10:29:57 -0700694 self.handle.expect( self.prompt )
Jon Hall274b6642015-02-17 11:57:17 -0800695 return main.TRUE
Jon Hallacabffd2014-10-09 12:36:53 -0400696 else:
kelvin8ec71442015-01-15 16:57:00 -0800697 main.log.error(
698 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800699 ": Git Checkout - Unexpected response, " +
700 "check for pull errors" )
kelvin8ec71442015-01-15 16:57:00 -0800701 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400702 return main.ERROR
703
704 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800705 main.log.error( self.name + ": EOF exception found" )
706 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700707 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800708 except Exception:
709 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700710 main.cleanAndExit()
andrewonlab95ca1462014-10-09 14:04:24 -0400711
pingping-lin6d23d9e2015-02-02 16:54:24 -0800712 def getBranchName( self ):
You Wang9cdf9a22017-05-01 13:44:18 -0700713 import re
714 try:
Jon Hall3e6edb32018-08-21 16:20:30 -0700715 main.log.info( self.name + " home is " + self.home )
You Wang9cdf9a22017-05-01 13:44:18 -0700716 self.handle.sendline( "cd " + self.home )
Devin Limc20e79a2017-06-07 10:29:57 -0700717 self.handle.expect( self.prompt )
You Wang9cdf9a22017-05-01 13:44:18 -0700718 self.handle.sendline( "git name-rev --name-only HEAD" )
719 self.handle.expect( "git name-rev --name-only HEAD" )
Devin Limc20e79a2017-06-07 10:29:57 -0700720 self.handle.expect( self.prompt )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700721 lines = self.handle.before.splitlines()
722 if lines[ 1 ] == "master" or re.search( "^onos-\d+(\.\d+)+$", lines[ 1 ] ):
723 return lines[ 1 ]
You Wang9cdf9a22017-05-01 13:44:18 -0700724 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700725 main.log.info( lines[ 1 ] )
You Wang9cdf9a22017-05-01 13:44:18 -0700726 return "unexpected ONOS branch"
727 except pexpect.EOF:
728 main.log.error( self.name + ": EOF exception found" )
729 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700730 main.cleanAndExit()
You Wang9cdf9a22017-05-01 13:44:18 -0700731 except pexpect.TIMEOUT:
732 main.log.error( self.name + ": TIMEOUT exception found" )
733 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700734 main.cleanAndExit()
You Wang9cdf9a22017-05-01 13:44:18 -0700735 except Exception:
736 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700737 main.cleanAndExit()
pingping-lin6d23d9e2015-02-02 16:54:24 -0800738
kelvin-onlabd3b64892015-01-20 13:26:24 -0800739 def getVersion( self, report=False ):
kelvin8ec71442015-01-15 16:57:00 -0800740 """
Jon Hall274b6642015-02-17 11:57:17 -0800741 Writes the COMMIT number to the report to be parsed
Jon Hallefbd9792015-03-05 16:11:36 -0800742 by Jenkins data collector.
kelvin8ec71442015-01-15 16:57:00 -0800743 """
Jon Hall45ec0922014-10-10 19:33:49 -0400744 try:
kelvin8ec71442015-01-15 16:57:00 -0800745 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -0700746 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -0800747 self.handle.sendline(
748 "cd " +
749 self.home +
Jon Hall274b6642015-02-17 11:57:17 -0800750 "; git log -1 --pretty=fuller --decorate=short | grep -A 6 " +
751 " \"commit\" --color=never" )
kelvin8ec71442015-01-15 16:57:00 -0800752 # NOTE: for some reason there are backspaces inserted in this
753 # phrase when run from Jenkins on some tests
754 self.handle.expect( "never" )
Devin Limc20e79a2017-06-07 10:29:57 -0700755 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -0800756 response = ( self.name + ": \n" + str(
757 self.handle.before + self.handle.after ) )
758 self.handle.sendline( "cd " + self.home )
Devin Limc20e79a2017-06-07 10:29:57 -0700759 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -0800760 lines = response.splitlines()
Jon Hall45ec0922014-10-10 19:33:49 -0400761 for line in lines:
Jon Hallfd191202014-11-07 18:36:09 -0500762 print line
763 if report:
pingping-lin763ee042015-05-20 17:45:30 -0700764 main.log.wiki( "<blockquote>" )
kelvin8ec71442015-01-15 16:57:00 -0800765 for line in lines[ 2:-1 ]:
766 # Bracket replacement is for Wiki-compliant
767 # formatting. '<' or '>' are interpreted
768 # as xml specific tags that cause errors
769 line = line.replace( "<", "[" )
770 line = line.replace( ">", "]" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700771 # main.log.wiki( "\t" + line )
pingping-lin763ee042015-05-20 17:45:30 -0700772 main.log.wiki( line + "<br /> " )
773 main.log.summary( line )
774 main.log.wiki( "</blockquote>" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700775 main.log.summary( "\n" )
kelvin8ec71442015-01-15 16:57:00 -0800776 return lines[ 2 ]
Jon Hall45ec0922014-10-10 19:33:49 -0400777 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800778 main.log.error( self.name + ": EOF exception found" )
779 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700780 main.cleanAndExit()
Jon Hall368769f2014-11-19 15:43:35 -0800781 except pexpect.TIMEOUT:
kelvin8ec71442015-01-15 16:57:00 -0800782 main.log.error( self.name + ": TIMEOUT exception found" )
783 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700784 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800785 except Exception:
786 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700787 main.cleanAndExit()
Jon Hall45ec0922014-10-10 19:33:49 -0400788
kelvin-onlabd3b64892015-01-20 13:26:24 -0800789 def createCellFile( self, benchIp, fileName, mnIpAddrs,
Jon Hall3e6edb32018-08-21 16:20:30 -0700790 appString, onosIpAddrs, atomixIps,
791 onosUser="sdn", useSSH=True ):
kelvin8ec71442015-01-15 16:57:00 -0800792 """
andrewonlab94282092014-10-10 13:00:11 -0400793 Creates a cell file based on arguments
794 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800795 * Bench IP address ( benchIp )
andrewonlab94282092014-10-10 13:00:11 -0400796 - Needed to copy the cell file over
kelvin-onlabd3b64892015-01-20 13:26:24 -0800797 * File name of the cell file ( fileName )
798 * Mininet IP address ( mnIpAddrs )
kelvin8ec71442015-01-15 16:57:00 -0800799 - Note that only 1 ip address is
andrewonlab94282092014-10-10 13:00:11 -0400800 supported currently
kelvin-onlabd3b64892015-01-20 13:26:24 -0800801 * ONOS IP addresses ( onosIpAddrs )
andrewonlab94282092014-10-10 13:00:11 -0400802 - Must be passed in as last arguments
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000803 * ONOS USER (onosUser)
Flavio Castrocc38a542016-03-03 13:15:46 -0800804 - optional argument to set ONOS_USER environment variable
kelvin8ec71442015-01-15 16:57:00 -0800805
andrewonlab94282092014-10-10 13:00:11 -0400806 NOTE: Assumes cells are located at:
807 ~/<self.home>/tools/test/cells/
kelvin8ec71442015-01-15 16:57:00 -0800808 """
andrewonlab94282092014-10-10 13:00:11 -0400809 try:
Devin Lim461f0872017-06-05 16:49:33 -0700810
Jon Hall2c8959e2016-12-16 12:17:34 -0800811 # Variable initialization
812 cellDirectory = self.home + "/tools/test/cells/"
813 # We want to create the cell file in the dependencies directory
814 # of TestON first, then copy over to ONOS bench
815 tempDirectory = "/tmp/"
816 # Create the cell file in the directory for writing ( w+ )
817 cellFile = open( tempDirectory + fileName, 'w+' )
818 if isinstance( onosIpAddrs, types.StringType ):
819 onosIpAddrs = [ onosIpAddrs ]
Jon Hall3e6edb32018-08-21 16:20:30 -0700820 if isinstance( atomixIps, types.StringType ):
821 atomixIps = [ atomixIps ]
Jon Hall2c8959e2016-12-16 12:17:34 -0800822
823 # App string is hardcoded environment variables
824 # That you may wish to use by default on startup.
825 # Note that you may not want certain apps listed
826 # on here.
827 appString = "export ONOS_APPS=" + appString
828 onosGroup = "export ONOS_GROUP=" + onosUser
829 onosUser = "export ONOS_USER=" + onosUser
830 if useSSH:
831 onosUseSSH = "export ONOS_USE_SSH=true"
832 mnString = "export OCN="
833 if mnIpAddrs == "":
834 mnString = ""
835 onosString = "export OC"
Jon Hall3e6edb32018-08-21 16:20:30 -0700836 atomixString = "export OCC"
Jon Hall2c8959e2016-12-16 12:17:34 -0800837
838 # Create ONOSNIC ip address prefix
839 tempOnosIp = str( onosIpAddrs[ 0 ] )
840 tempList = []
841 tempList = tempOnosIp.split( "." )
842 # Omit last element of list to format for NIC
843 tempList = tempList[ :-1 ]
844 # Structure the nic string ip
845 nicAddr = ".".join( tempList ) + ".*"
846 self.nicAddr = nicAddr
847 onosNicString = "export ONOS_NIC=" + nicAddr
848
kelvin8ec71442015-01-15 16:57:00 -0800849 # Start writing to file
kelvin-onlabd3b64892015-01-20 13:26:24 -0800850 cellFile.write( onosNicString + "\n" )
andrewonlab94282092014-10-10 13:00:11 -0400851
Jon Hall3e6edb32018-08-21 16:20:30 -0700852 onosIndex = 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800853 for arg in onosIpAddrs:
854 # For each argument in onosIpAddrs, write to file
kelvin8ec71442015-01-15 16:57:00 -0800855 # Output should look like the following:
andrewonlabd4940492014-10-24 12:21:27 -0400856 # export OC1="10.128.20.11"
857 # export OC2="10.128.20.12"
Jon Hall3e6edb32018-08-21 16:20:30 -0700858 cellFile.write( onosString + str( onosIndex ) +
Jon Hall6f665652015-09-18 10:08:07 -0700859 "=\"" + arg + "\"\n" )
Jon Hall3e6edb32018-08-21 16:20:30 -0700860 onosIndex = onosIndex + 1
861
862 atomixIndex = 1
863 for ip in atomixIps:
864 cellFile.write( atomixString + str( atomixIndex ) +
865 "=\"" + ip + "\"\n" )
866 atomixIndex += 1
kelvin8ec71442015-01-15 16:57:00 -0800867
Jon Hall6f665652015-09-18 10:08:07 -0700868 cellFile.write( "export OCI=$OC1\n" )
Jon Hallab611372018-02-21 15:26:05 -0800869 if mnString:
870 cellFile.write( mnString + "\"" + str( mnIpAddrs ) + "\"\n" )
cameron@onlab.us75900962015-03-30 13:22:49 -0700871 cellFile.write( appString + "\n" )
Flavio Castrocc38a542016-03-03 13:15:46 -0800872 cellFile.write( onosGroup + "\n" )
873 cellFile.write( onosUser + "\n" )
Pier88189b62016-09-07 17:01:53 -0700874 if useSSH:
875 cellFile.write( onosUseSSH + "\n" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800876 cellFile.close()
andrewonlab94282092014-10-10 13:00:11 -0400877
kelvin8ec71442015-01-15 16:57:00 -0800878 # We use os.system to send the command to TestON cluster
879 # to account for the case in which TestON is not located
880 # on the same cluster as the ONOS bench
881 # Note that even if TestON is located on the same cluster
882 # as ONOS bench, you must setup passwordless ssh
883 # between TestON and ONOS bench in order to automate the test.
kelvin-onlabc2b79102015-07-14 11:41:20 -0700884 os.system( "scp " + tempDirectory + fileName + " " +
885 self.user_name + "@" + self.ip_address + ":" + cellDirectory )
andrewonlab94282092014-10-10 13:00:11 -0400886
andrewonlab2a6c9342014-10-16 13:40:15 -0400887 return main.TRUE
888
andrewonlab94282092014-10-10 13:00:11 -0400889 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800890 main.log.error( self.name + ": EOF exception found" )
891 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700892 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800893 except Exception:
894 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700895 main.cleanAndExit()
andrewonlab94282092014-10-10 13:00:11 -0400896
kelvin-onlabd3b64892015-01-20 13:26:24 -0800897 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800898 """
andrewonlab95ca1462014-10-09 14:04:24 -0400899 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800900 """
andrewonlab95ca1462014-10-09 14:04:24 -0400901 try:
902 if not cellname:
You Wang1cdc5f52017-12-19 16:47:51 -0800903 main.log.error( self.name + ": Must define cellname" )
Devin Lim44075962017-08-11 10:56:37 -0700904 main.cleanAndExit()
andrewonlab95ca1462014-10-09 14:04:24 -0400905 else:
kelvin8ec71442015-01-15 16:57:00 -0800906 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800907 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800908 # Note that this variable name is subject to change
andrewonlab95ca1462014-10-09 14:04:24 -0400909 # and that this driver will have to change accordingly
Jon Hall3b489db2015-10-05 14:38:37 -0700910 self.handle.expect( str( cellname ) )
Jon Hallab611372018-02-21 15:26:05 -0800911 response = self.handle.before + self.handle.after
You Wang1cdc5f52017-12-19 16:47:51 -0800912 i = self.handle.expect( [ "No such cell",
Jon Hallab611372018-02-21 15:26:05 -0800913 "command not found",
914 self.prompt ], timeout=10 )
915 response += self.handle.before + self.handle.after
You Wang1cdc5f52017-12-19 16:47:51 -0800916 if i == 0:
Jon Hallab611372018-02-21 15:26:05 -0800917 main.log.error( self.name + ": No such cell. Response: " + str( response ) )
You Wang1cdc5f52017-12-19 16:47:51 -0800918 main.cleanAndExit()
919 elif i == 1:
Jon Hallab611372018-02-21 15:26:05 -0800920 main.log.error( self.name + ": Error setting cell. Response: " + str( response ) )
921 main.cleanAndExit()
You Wang1cdc5f52017-12-19 16:47:51 -0800922 elif i == 2:
Jon Hallab611372018-02-21 15:26:05 -0800923 main.log.info( self.name + ": Successfully set cell: " + str( response ) )
andrewonlab95ca1462014-10-09 14:04:24 -0400924 return main.TRUE
You Wang1cdc5f52017-12-19 16:47:51 -0800925 except pexpect.TIMEOUT:
926 main.log.error( self.name + ": TIMEOUT exception found" )
927 main.log.error( self.name + ": " + self.handle.before )
928 main.cleanAndExit()
andrewonlab95ca1462014-10-09 14:04:24 -0400929 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800930 main.log.error( self.name + ": EOF exception found" )
931 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700932 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800933 except Exception:
934 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700935 main.cleanAndExit()
andrewonlab95ca1462014-10-09 14:04:24 -0400936
kelvin-onlabd3b64892015-01-20 13:26:24 -0800937 def verifyCell( self ):
kelvin8ec71442015-01-15 16:57:00 -0800938 """
andrewonlabc03bf6c2014-10-09 14:56:18 -0400939 Calls 'onos-verify-cell' to check for cell installation
kelvin8ec71442015-01-15 16:57:00 -0800940 """
941 # TODO: Add meaningful expect value
andrewonlab8d0d7d72014-10-09 16:33:15 -0400942
andrewonlabc03bf6c2014-10-09 14:56:18 -0400943 try:
kelvin8ec71442015-01-15 16:57:00 -0800944 # Clean handle by sending empty and expecting $
945 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -0700946 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -0800947 self.handle.sendline( "onos-verify-cell" )
Devin Limc20e79a2017-06-07 10:29:57 -0700948 self.handle.expect( self.prompt )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800949 handleBefore = self.handle.before
950 handleAfter = self.handle.after
kelvin-onlabd3b64892015-01-20 13:26:24 -0800951 main.log.info( "Verify cell returned: " + handleBefore +
Jon Hall3b489db2015-10-05 14:38:37 -0700952 handleAfter )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400953 return main.TRUE
Jon Hall3e6edb32018-08-21 16:20:30 -0700954 except pexpect.ExceptionPexpect:
Jon Hall3b489db2015-10-05 14:38:37 -0700955 main.log.exception( self.name + ": Pexpect exception found: " )
kelvin8ec71442015-01-15 16:57:00 -0800956 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700957 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800958 except Exception:
959 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700960 main.cleanAndExit()
Jon Hall7993bfc2014-10-09 16:30:14 -0400961
jenkins1e99e7b2015-04-02 18:15:39 -0700962 def onosCfgSet( self, ONOSIp, configName, configParam ):
963 """
964 Uses 'onos <node-ip> cfg set' to change a parameter value of an
Jon Hall4ba53f02015-07-29 13:07:41 -0700965 application.
966
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000967 ex)
jenkins1e99e7b2015-04-02 18:15:39 -0700968 onos 10.0.0.1 cfg set org.onosproject.myapp appSetting 1
jenkins1e99e7b2015-04-02 18:15:39 -0700969 ONOSIp = '10.0.0.1'
970 configName = 'org.onosproject.myapp'
971 configParam = 'appSetting 1'
jenkins1e99e7b2015-04-02 18:15:39 -0700972 """
Jon Hall72280bc2016-01-25 14:29:05 -0800973 try:
974 cfgStr = "onos {} cfg set {} {}".format( ONOSIp,
975 configName,
976 configParam )
977 self.handle.sendline( "" )
978 self.handle.expect( ":~" )
979 self.handle.sendline( cfgStr )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700980 self.handle.expect( "cfg set" )
Jon Hall72280bc2016-01-25 14:29:05 -0800981 self.handle.expect( ":~" )
jenkins1e99e7b2015-04-02 18:15:39 -0700982
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700983 paramValue = configParam.split( " " )[ 1 ]
984 paramName = configParam.split( " " )[ 0 ]
Jon Hall4ba53f02015-07-29 13:07:41 -0700985
Jon Hall72280bc2016-01-25 14:29:05 -0800986 checkStr = 'onos {} cfg get " {} {} " '.format( ONOSIp, configName, paramName )
Jon Hall4ba53f02015-07-29 13:07:41 -0700987
Jon Hall72280bc2016-01-25 14:29:05 -0800988 self.handle.sendline( checkStr )
989 self.handle.expect( ":~" )
jenkins1e99e7b2015-04-02 18:15:39 -0700990
Jon Hall72280bc2016-01-25 14:29:05 -0800991 if "value=" + paramValue + "," in self.handle.before:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700992 main.log.info( "cfg " + configName + " successfully set to " + configParam )
Jon Hall72280bc2016-01-25 14:29:05 -0800993 return main.TRUE
Jon Hall3e6edb32018-08-21 16:20:30 -0700994 except pexpect.ExceptionPexpect:
Jon Hall72280bc2016-01-25 14:29:05 -0800995 main.log.exception( self.name + ": Pexpect exception found: " )
996 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700997 main.cleanAndExit()
Jon Hall72280bc2016-01-25 14:29:05 -0800998 except Exception:
999 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001000 main.cleanAndExit()
Jon Hall4ba53f02015-07-29 13:07:41 -07001001
You Wang54b1d672018-06-11 16:44:13 -07001002 def onosCli( self, ONOSIp, cmdstr, timeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -08001003 """
andrewonlab05e362f2014-10-10 00:40:57 -04001004 Uses 'onos' command to send various ONOS CLI arguments.
1005 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001006 * ONOSIp: specify the ip of the cell machine
andrewonlab94282092014-10-10 13:00:11 -04001007 * cmdstr: specify the command string to send
You Wang54b1d672018-06-11 16:44:13 -07001008 Optional:
1009 * timeout: pexpect timeout for running the command
kelvin8ec71442015-01-15 16:57:00 -08001010
1011 This function is intended to expose the entire karaf
andrewonlab6e20c342014-10-10 18:08:48 -04001012 CLI commands for ONOS. Try to use this function first
1013 before attempting to write a ONOS CLI specific driver
kelvin8ec71442015-01-15 16:57:00 -08001014 function.
1015 You can see a list of available 'cmdstr' arguments
andrewonlab6e20c342014-10-10 18:08:48 -04001016 by starting onos, and typing in 'onos' to enter the
1017 onos> CLI. Then, type 'help' to see the list of
kelvin8ec71442015-01-15 16:57:00 -08001018 available commands.
1019 """
andrewonlab05e362f2014-10-10 00:40:57 -04001020 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001021 if not ONOSIp:
kelvin8ec71442015-01-15 16:57:00 -08001022 main.log.error( "You must specify the IP address" )
andrewonlab05e362f2014-10-10 00:40:57 -04001023 return main.FALSE
1024 if not cmdstr:
kelvin8ec71442015-01-15 16:57:00 -08001025 main.log.error( "You must specify the command string" )
andrewonlab05e362f2014-10-10 00:40:57 -04001026 return main.FALSE
1027
kelvin8ec71442015-01-15 16:57:00 -08001028 cmdstr = str( cmdstr )
1029 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001030 self.handle.expect( self.prompt )
andrewonlab05e362f2014-10-10 00:40:57 -04001031
You Wangdd3dae52018-02-15 13:31:25 -08001032 self.handle.sendline( "onos-wait-for-start " + ONOSIp )
1033 self.handle.expect( self.prompt )
1034
1035 self.handle.sendline( "onos " + ONOSIp + " " + cmdstr )
You Wang54b1d672018-06-11 16:44:13 -07001036 i = self.handle.expect( [ self.prompt, pexpect.TIMEOUT ], timeout=timeout )
1037 if i == 0:
1038 handleBefore = self.handle.before
1039 main.log.info( "Command sent successfully" )
1040 # Obtain return handle that consists of result from
1041 # the onos command. The string may need to be
1042 # configured further.
1043 returnString = handleBefore
1044 return returnString
1045 elif i == 1:
1046 main.log.error( self.name + ": Timeout when sending " + cmdstr )
You Wang141b43b2018-06-26 16:50:18 -07001047 self.handle.send( "\x03" ) # Control-C
You Wang54b1d672018-06-11 16:44:13 -07001048 self.handle.expect( self.prompt )
1049 return main.FALSE
You Wangd66de192018-04-30 17:30:12 -07001050 except pexpect.TIMEOUT:
1051 main.log.exception( self.name + ": Timeout when sending " + cmdstr )
1052 return main.FALSE
andrewonlab05e362f2014-10-10 00:40:57 -04001053 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001054 main.log.error( self.name + ": EOF exception found" )
1055 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001056 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001057 except Exception:
1058 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001059 main.cleanAndExit()
Jon Hall7993bfc2014-10-09 16:30:14 -04001060
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001061 def onosSecureSSH( self, userName="onos", userPWD="rocks", node="" ):
Pier88189b62016-09-07 17:01:53 -07001062 """
1063 Enables secure access to ONOS console
1064 by removing default users & keys.
1065
1066 onos-secure-ssh -u onos -p rocks node
1067
1068 Returns: main.TRUE on success and main.FALSE on failure
1069 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001070
Pier88189b62016-09-07 17:01:53 -07001071 try:
Chiyu Chengef109502016-11-21 15:51:38 -08001072 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001073 self.handle.expect( self.prompt )
Pier88189b62016-09-07 17:01:53 -07001074 self.handle.sendline( " onos-secure-ssh -u " + userName + " -p " + userPWD + " " + node )
1075
1076 # NOTE: this timeout may need to change depending on the network
1077 # and size of ONOS
1078 # TODO: Handle the other possible error
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001079 i = self.handle.expect( [ "Network\sis\sunreachable",
1080 self.prompt,
1081 pexpect.TIMEOUT ], timeout=180 )
Pier88189b62016-09-07 17:01:53 -07001082 if i == 0:
1083 # can't reach ONOS node
Jon Hall3e6edb32018-08-21 16:20:30 -07001084 main.log.warn( self.name + ": Network is unreachable" )
Devin Limc20e79a2017-06-07 10:29:57 -07001085 self.handle.expect( self.prompt )
Pier88189b62016-09-07 17:01:53 -07001086 return main.FALSE
1087 elif i == 1:
1088 # Process started
Jon Hall3e6edb32018-08-21 16:20:30 -07001089 main.log.info( self.name + ": Secure SSH performed on " + node )
Pier88189b62016-09-07 17:01:53 -07001090 return main.TRUE
Jon Hall3e6edb32018-08-21 16:20:30 -07001091 elif i == 2:
1092 # timeout
1093 main.log.error( self.name + ": Failed to secure ssh on " + node )
1094 main.log.debug( self.handle.before )
Pier88189b62016-09-07 17:01:53 -07001095 except pexpect.EOF:
1096 main.log.error( self.name + ": EOF exception found" )
1097 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001098 main.cleanAndExit()
Pier88189b62016-09-07 17:01:53 -07001099 except Exception:
1100 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001101 main.cleanAndExit()
Pier88189b62016-09-07 17:01:53 -07001102
kelvin-onlabd3b64892015-01-20 13:26:24 -08001103 def onosInstall( self, options="-f", node="" ):
kelvin8ec71442015-01-15 16:57:00 -08001104 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001105 Installs ONOS bits on the designated cell machine.
kelvin8ec71442015-01-15 16:57:00 -08001106 If -f option is provided, it also forces an uninstall.
1107 Presently, install also includes onos-push-bits and
Jon Hall7993bfc2014-10-09 16:30:14 -04001108 onos-config within.
kelvin8ec71442015-01-15 16:57:00 -08001109 The node option allows you to selectively only push the jar
Jon Hall7993bfc2014-10-09 16:30:14 -04001110 files to certain onos nodes
1111
1112 Returns: main.TRUE on success and main.FALSE on failure
kelvin8ec71442015-01-15 16:57:00 -08001113 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001114 try:
andrewonlab114768a2014-11-14 12:44:44 -05001115 if options:
kelvin8ec71442015-01-15 16:57:00 -08001116 self.handle.sendline( "onos-install " + options + " " + node )
andrewonlab114768a2014-11-14 12:44:44 -05001117 else:
kelvin8ec71442015-01-15 16:57:00 -08001118 self.handle.sendline( "onos-install " + node )
1119 self.handle.expect( "onos-install " )
1120 # NOTE: this timeout may need to change depending on the network
1121 # and size of ONOS
1122 i = self.handle.expect( [ "Network\sis\sunreachable",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001123 "onos\sstart/running,\sprocess",
kelvin8ec71442015-01-15 16:57:00 -08001124 "ONOS\sis\salready\sinstalled",
Jon Hall3576f572016-08-23 10:01:07 -07001125 "does not exist",
Devin Limc20e79a2017-06-07 10:29:57 -07001126 self.prompt,
Jon Hall6c44c0b2016-04-20 15:21:00 -07001127 pexpect.TIMEOUT ], timeout=180 )
Jon Hall7993bfc2014-10-09 16:30:14 -04001128 if i == 0:
Jon Hall3576f572016-08-23 10:01:07 -07001129 # can't reach ONOS node
kelvin8ec71442015-01-15 16:57:00 -08001130 main.log.warn( "Network is unreachable" )
Devin Limc20e79a2017-06-07 10:29:57 -07001131 self.handle.expect( self.prompt )
Jon Hall7993bfc2014-10-09 16:30:14 -04001132 return main.FALSE
1133 elif i == 1:
Jon Hall3576f572016-08-23 10:01:07 -07001134 # Process started
kelvin8ec71442015-01-15 16:57:00 -08001135 main.log.info(
1136 "ONOS was installed on " +
1137 node +
1138 " and started" )
Devin Limc20e79a2017-06-07 10:29:57 -07001139 self.handle.expect( self.prompt )
Jon Hall7993bfc2014-10-09 16:30:14 -04001140 return main.TRUE
You Wangd65ba842018-08-14 11:20:59 -07001141 elif i == 2:
Jon Hall3576f572016-08-23 10:01:07 -07001142 # same bits are already on ONOS node
Jeremyc72b2582016-02-26 18:27:38 -08001143 main.log.info( "ONOS is already installed on " + node )
Devin Limc20e79a2017-06-07 10:29:57 -07001144 self.handle.expect( self.prompt )
Jeremyc72b2582016-02-26 18:27:38 -08001145 return main.TRUE
You Wangd65ba842018-08-14 11:20:59 -07001146 elif i == 3:
Jon Hall3576f572016-08-23 10:01:07 -07001147 # onos not packaged
1148 main.log.error( "ONOS package not found." )
Devin Limc20e79a2017-06-07 10:29:57 -07001149 self.handle.expect( self.prompt )
Jon Hall3576f572016-08-23 10:01:07 -07001150 return main.FALSE
You Wangd65ba842018-08-14 11:20:59 -07001151 elif i == 4:
Jon Hall3576f572016-08-23 10:01:07 -07001152 # prompt
Jon Hall3e6edb32018-08-21 16:20:30 -07001153 main.log.info( "ONOS was installed on {} {}.".format( node,
1154 "but not started" if 'n' in options else "and started" ) )
Jeremyc72b2582016-02-26 18:27:38 -08001155 return main.TRUE
You Wangd65ba842018-08-14 11:20:59 -07001156 elif i == 5:
Jon Hall3576f572016-08-23 10:01:07 -07001157 # timeout
kelvin8ec71442015-01-15 16:57:00 -08001158 main.log.info(
1159 "Installation of ONOS on " +
1160 node +
1161 " timed out" )
Devin Limc20e79a2017-06-07 10:29:57 -07001162 self.handle.expect( self.prompt )
Jon Hall53c5e662016-04-13 16:06:56 -07001163 main.log.warn( self.handle.before )
You Wang141b43b2018-06-26 16:50:18 -07001164 self.handle.send( "\x03" ) # Control-C
1165 self.handle.expect( self.prompt )
Jon Hall7993bfc2014-10-09 16:30:14 -04001166 return main.FALSE
andrewonlabc03bf6c2014-10-09 14:56:18 -04001167 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001168 main.log.error( self.name + ": EOF exception found" )
1169 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001170 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001171 except Exception:
1172 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001173 main.cleanAndExit()
andrewonlab95ca1462014-10-09 14:04:24 -04001174
kelvin-onlabd3b64892015-01-20 13:26:24 -08001175 def onosStart( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001176 """
andrewonlab8d0d7d72014-10-09 16:33:15 -04001177 Calls onos command: 'onos-service [<node-ip>] start'
andrewonlabe8e56fd2014-10-09 17:12:44 -04001178 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -08001179 """
andrewonlab8d0d7d72014-10-09 16:33:15 -04001180 try:
kelvin8ec71442015-01-15 16:57:00 -08001181 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001182 self.handle.expect( self.prompt )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001183 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001184 " start" )
1185 i = self.handle.expect( [
andrewonlab8d0d7d72014-10-09 16:33:15 -04001186 "Job\sis\salready\srunning",
1187 "start/running",
Devin Limc20e79a2017-06-07 10:29:57 -07001188 self.prompt,
andrewonlab8d0d7d72014-10-09 16:33:15 -04001189 "Unknown\sinstance",
Jeremy Songster14c13572016-04-21 17:34:03 -07001190 pexpect.TIMEOUT ], timeout=180 )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001191 if i == 0:
Devin Limc20e79a2017-06-07 10:29:57 -07001192 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -08001193 main.log.info( "Service is already running" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001194 return main.TRUE
1195 elif i == 1:
Devin Limc20e79a2017-06-07 10:29:57 -07001196 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -08001197 main.log.info( "ONOS service started" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001198 return main.TRUE
Jeremyd0e9a6d2016-03-02 11:28:52 -08001199 elif i == 2:
1200 main.log.info( "ONOS service started" )
1201 return main.TRUE
andrewonlab8d0d7d72014-10-09 16:33:15 -04001202 else:
Devin Limc20e79a2017-06-07 10:29:57 -07001203 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -08001204 main.log.error( "ONOS service failed to start" )
Devin Lim44075962017-08-11 10:56:37 -07001205
1206 main.cleanAndExit()
andrewonlab8d0d7d72014-10-09 16:33:15 -04001207 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001208 main.log.error( self.name + ": EOF exception found" )
1209 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001210 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001211 except Exception:
1212 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001213 main.cleanAndExit()
andrewonlab8d0d7d72014-10-09 16:33:15 -04001214
kelvin-onlabd3b64892015-01-20 13:26:24 -08001215 def onosStop( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001216 """
andrewonlab2b30bd32014-10-09 16:48:55 -04001217 Calls onos command: 'onos-service [<node-ip>] stop'
andrewonlabe8e56fd2014-10-09 17:12:44 -04001218 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -08001219 """
andrewonlab2b30bd32014-10-09 16:48:55 -04001220 try:
kelvin8ec71442015-01-15 16:57:00 -08001221 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001222 self.handle.expect( self.prompt )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001223 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001224 " stop" )
1225 i = self.handle.expect( [
andrewonlab2b30bd32014-10-09 16:48:55 -04001226 "stop/waiting",
Jon Hall61282e32015-03-19 11:34:11 -07001227 "Could not resolve hostname",
andrewonlab2b30bd32014-10-09 16:48:55 -04001228 "Unknown\sinstance",
Devin Limc20e79a2017-06-07 10:29:57 -07001229 self.prompt,
Jeremy Songster14c13572016-04-21 17:34:03 -07001230 pexpect.TIMEOUT ], timeout=180 )
andrewonlab2b30bd32014-10-09 16:48:55 -04001231 if i == 0:
Devin Limc20e79a2017-06-07 10:29:57 -07001232 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -08001233 main.log.info( "ONOS service stopped" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001234 return main.TRUE
1235 elif i == 1:
Devin Limc20e79a2017-06-07 10:29:57 -07001236 self.handle.expect( self.prompt )
Jon Hall65844a32015-03-09 19:09:37 -07001237 main.log.info( "onosStop() Unknown ONOS instance specified: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001238 str( nodeIp ) )
andrewonlab2b30bd32014-10-09 16:48:55 -04001239 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -07001240 elif i == 2:
Devin Limc20e79a2017-06-07 10:29:57 -07001241 self.handle.expect( self.prompt )
Jon Hall61282e32015-03-19 11:34:11 -07001242 main.log.warn( "ONOS wasn't running" )
1243 return main.TRUE
YPZhang77badfc2016-03-09 10:28:59 -08001244 elif i == 3:
1245 main.log.info( "ONOS service stopped" )
1246 return main.TRUE
andrewonlab2b30bd32014-10-09 16:48:55 -04001247 else:
kelvin8ec71442015-01-15 16:57:00 -08001248 main.log.error( "ONOS service failed to stop" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001249 return main.FALSE
andrewonlab2b30bd32014-10-09 16:48:55 -04001250 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001251 main.log.error( self.name + ": EOF exception found" )
1252 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001253 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001254 except Exception:
1255 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001256 main.cleanAndExit()
kelvin8ec71442015-01-15 16:57:00 -08001257
kelvin-onlabd3b64892015-01-20 13:26:24 -08001258 def onosUninstall( self, nodeIp="" ):
kelvin8ec71442015-01-15 16:57:00 -08001259 """
andrewonlabc8d47972014-10-09 16:52:36 -04001260 Calls the command: 'onos-uninstall'
kelvin8ec71442015-01-15 16:57:00 -08001261 Uninstalls ONOS from the designated cell machine, stopping
andrewonlabe8e56fd2014-10-09 17:12:44 -04001262 if needed
kelvin8ec71442015-01-15 16:57:00 -08001263 """
andrewonlabc8d47972014-10-09 16:52:36 -04001264 try:
kelvin8ec71442015-01-15 16:57:00 -08001265 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001266 self.handle.expect( self.prompt, timeout=180 )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001267 self.handle.sendline( "onos-uninstall " + str( nodeIp ) )
Devin Limc20e79a2017-06-07 10:29:57 -07001268 self.handle.expect( self.prompt, timeout=180 )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001269 main.log.info( "ONOS " + nodeIp + " was uninstalled" )
kelvin8ec71442015-01-15 16:57:00 -08001270 # onos-uninstall command does not return any text
andrewonlabc8d47972014-10-09 16:52:36 -04001271 return main.TRUE
pingping-lin763ee042015-05-20 17:45:30 -07001272 except pexpect.TIMEOUT:
1273 main.log.exception( self.name + ": Timeout in onosUninstall" )
You Wang141b43b2018-06-26 16:50:18 -07001274 self.handle.send( "\x03" ) # Control-C
1275 self.handle.expect( self.prompt )
pingping-lin763ee042015-05-20 17:45:30 -07001276 return main.FALSE
andrewonlabc8d47972014-10-09 16:52:36 -04001277 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001278 main.log.error( self.name + ": EOF exception found" )
1279 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001280 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001281 except Exception:
1282 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001283 main.cleanAndExit()
andrewonlab2b30bd32014-10-09 16:48:55 -04001284
kelvin-onlabd3b64892015-01-20 13:26:24 -08001285 def onosDie( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001286 """
andrewonlabaedc8332014-12-04 12:43:03 -05001287 Issues the command 'onos-die <node-ip>'
1288 This command calls onos-kill and also stops the node
kelvin8ec71442015-01-15 16:57:00 -08001289 """
andrewonlabaedc8332014-12-04 12:43:03 -05001290 try:
kelvin8ec71442015-01-15 16:57:00 -08001291 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001292 self.handle.expect( self.prompt )
Jeremyf0aecdb2016-03-30 13:19:57 -07001293 cmdStr = "onos-die " + str( nodeIp )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001294 self.handle.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -08001295 i = self.handle.expect( [
andrewonlabaedc8332014-12-04 12:43:03 -05001296 "Killing\sONOS",
1297 "ONOS\sprocess\sis\snot\srunning",
Jeremy Songster14c13572016-04-21 17:34:03 -07001298 pexpect.TIMEOUT ], timeout=60 )
andrewonlabaedc8332014-12-04 12:43:03 -05001299 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001300 main.log.info( "ONOS instance " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001301 " was killed and stopped" )
Jon Hall53c5e662016-04-13 16:06:56 -07001302 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001303 self.handle.expect( self.prompt )
andrewonlabaedc8332014-12-04 12:43:03 -05001304 return main.TRUE
1305 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001306 main.log.info( "ONOS process was not running" )
Jon Hall53c5e662016-04-13 16:06:56 -07001307 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001308 self.handle.expect( self.prompt )
andrewonlabaedc8332014-12-04 12:43:03 -05001309 return main.FALSE
1310 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001311 main.log.error( self.name + ": EOF exception found" )
1312 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001313 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001314 except Exception:
1315 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001316 main.cleanAndExit()
andrewonlabaedc8332014-12-04 12:43:03 -05001317
kelvin-onlabd3b64892015-01-20 13:26:24 -08001318 def onosKill( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001319 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001320 Calls the command: 'onos-kill [<node-ip>]'
1321 "Remotely, and unceremoniously kills the ONOS instance running on
1322 the specified cell machine" - Tom V
kelvin8ec71442015-01-15 16:57:00 -08001323 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001324 try:
kelvin8ec71442015-01-15 16:57:00 -08001325 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001326 self.handle.expect( self.prompt )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001327 self.handle.sendline( "onos-kill " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -08001328 i = self.handle.expect( [
Devin Limc20e79a2017-06-07 10:29:57 -07001329 self.prompt,
andrewonlabe8e56fd2014-10-09 17:12:44 -04001330 "No\sroute\sto\shost",
1331 "password:",
Jeremy Songster14c13572016-04-21 17:34:03 -07001332 pexpect.TIMEOUT ], timeout=60 )
kelvin8ec71442015-01-15 16:57:00 -08001333
andrewonlabe8e56fd2014-10-09 17:12:44 -04001334 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001335 main.log.info(
1336 "ONOS instance " + str(
kelvin-onlabd3b64892015-01-20 13:26:24 -08001337 nodeIp ) + " was killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001338 return main.TRUE
1339 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001340 main.log.info( "No route to host" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001341 return main.FALSE
1342 elif i == 2:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001343 main.log.info(
1344 "Passwordless login for host: " +
1345 str( nodeIp ) +
1346 " not configured" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001347 return main.FALSE
1348 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001349 main.log.info( "ONOS instance was not killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001350 return main.FALSE
kelvin8ec71442015-01-15 16:57:00 -08001351
andrewonlabe8e56fd2014-10-09 17:12:44 -04001352 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001353 main.log.error( self.name + ": EOF exception found" )
1354 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001355 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001356 except Exception:
1357 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001358 main.cleanAndExit()
andrewonlabe8e56fd2014-10-09 17:12:44 -04001359
kelvin-onlabd3b64892015-01-20 13:26:24 -08001360 def onosRemoveRaftLogs( self ):
kelvin8ec71442015-01-15 16:57:00 -08001361 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001362 Removes Raft / Copy cat files from ONOS to ensure
Jon Hallfcc88622014-11-25 13:09:54 -05001363 a cleaner environment.
1364
andrewonlab19fbdca2014-11-14 12:55:59 -05001365 Description:
Jon Hallfcc88622014-11-25 13:09:54 -05001366 Stops all ONOS defined in the cell,
andrewonlab19fbdca2014-11-14 12:55:59 -05001367 wipes the raft / copycat log files
kelvin8ec71442015-01-15 16:57:00 -08001368 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001369 try:
kelvin8ec71442015-01-15 16:57:00 -08001370 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001371 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -08001372 self.handle.sendline( "onos-remove-raft-logs" )
1373 # Sometimes this command hangs
Devin Limc20e79a2017-06-07 10:29:57 -07001374 i = self.handle.expect( [ self.prompt, pexpect.TIMEOUT ],
kelvin8ec71442015-01-15 16:57:00 -08001375 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001376 if i == 1:
Devin Limc20e79a2017-06-07 10:29:57 -07001377 i = self.handle.expect( [ self.prompt, pexpect.TIMEOUT ],
kelvin8ec71442015-01-15 16:57:00 -08001378 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001379 if i == 1:
1380 return main.FALSE
andrewonlab19fbdca2014-11-14 12:55:59 -05001381 return main.TRUE
andrewonlab19fbdca2014-11-14 12:55:59 -05001382 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001383 main.log.error( self.name + ": EOF exception found" )
1384 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001385 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001386 except Exception:
1387 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001388 main.cleanAndExit()
Jon Hallfcc88622014-11-25 13:09:54 -05001389
kelvin-onlabd3b64892015-01-20 13:26:24 -08001390 def onosStartNetwork( self, mntopo ):
kelvin8ec71442015-01-15 16:57:00 -08001391 """
1392 Calls the command 'onos-start-network [ <mininet-topo> ]
1393 "remotely starts the specified topology on the cell's
andrewonlab94282092014-10-10 13:00:11 -04001394 mininet machine against all controllers configured in the
kelvin8ec71442015-01-15 16:57:00 -08001395 cell."
andrewonlab94282092014-10-10 13:00:11 -04001396 * Specify mininet topology file name for mntopo
1397 * Topo files should be placed at:
1398 ~/<your-onos-directory>/tools/test/topos
kelvin8ec71442015-01-15 16:57:00 -08001399
andrewonlab94282092014-10-10 13:00:11 -04001400 NOTE: This function will take you to the mininet prompt
kelvin8ec71442015-01-15 16:57:00 -08001401 """
andrewonlab94282092014-10-10 13:00:11 -04001402 try:
1403 if not mntopo:
kelvin8ec71442015-01-15 16:57:00 -08001404 main.log.error( "You must specify a topo file to execute" )
andrewonlab94282092014-10-10 13:00:11 -04001405 return main.FALSE
andrewonlab94282092014-10-10 13:00:11 -04001406
kelvin8ec71442015-01-15 16:57:00 -08001407 mntopo = str( mntopo )
1408 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001409 self.handle.expect( self.prompt )
andrewonlab94282092014-10-10 13:00:11 -04001410
kelvin8ec71442015-01-15 16:57:00 -08001411 self.handle.sendline( "onos-start-network " + mntopo )
1412 self.handle.expect( "mininet>" )
1413 main.log.info( "Network started, entered mininet prompt" )
1414
1415 # TODO: Think about whether return is necessary or not
andrewonlab94282092014-10-10 13:00:11 -04001416
1417 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001418 main.log.error( self.name + ": EOF exception found" )
1419 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001420 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001421 except Exception:
1422 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001423 main.cleanAndExit()
andrewonlab94282092014-10-10 13:00:11 -04001424
Jeremy Songster14c13572016-04-21 17:34:03 -07001425 def isup( self, node="", timeout=240 ):
kelvin8ec71442015-01-15 16:57:00 -08001426 """
1427 Run's onos-wait-for-start which only returns once ONOS is at run
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001428 level 100(ready for use)
andrewonlab8d0d7d72014-10-09 16:33:15 -04001429
Jon Hall7993bfc2014-10-09 16:30:14 -04001430 Returns: main.TRUE if ONOS is running and main.FALSE on timeout
kelvin8ec71442015-01-15 16:57:00 -08001431 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001432 try:
Jon Hall3b489db2015-10-05 14:38:37 -07001433 self.handle.sendline( "onos-wait-for-start " + node )
1434 self.handle.expect( "onos-wait-for-start" )
kelvin8ec71442015-01-15 16:57:00 -08001435 # NOTE: this timeout is arbitrary"
Jon Hallcababf72018-02-05 12:05:19 -08001436 i = self.handle.expect( [ self.prompt, pexpect.TIMEOUT, "Password:" ], timeout )
Jon Hall7993bfc2014-10-09 16:30:14 -04001437 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001438 main.log.info( self.name + ": " + node + " is up" )
You Wangb65f2e92018-12-21 11:31:34 -08001439 # FIXME: for now we sleep 5s for CLI to become ready
1440 time.sleep( 5 )
Jon Hall7993bfc2014-10-09 16:30:14 -04001441 return main.TRUE
Jon Hallcababf72018-02-05 12:05:19 -08001442 elif i == 1 or i == 2:
kelvin8ec71442015-01-15 16:57:00 -08001443 # NOTE: since this function won't return until ONOS is ready,
Jon Hall7993bfc2014-10-09 16:30:14 -04001444 # we will kill it on timeout
Jon Hallcababf72018-02-05 12:05:19 -08001445 if i == 1:
Jon Hall3e6edb32018-08-21 16:20:30 -07001446 main.log.error( "{}: ONOS {} has not started yet".format( self.name, node ) )
Jon Hallcababf72018-02-05 12:05:19 -08001447 elif i == 2:
Jon Hall3e6edb32018-08-21 16:20:30 -07001448 main.log.error( "{}: Cannot login to ONOS CLI {}, try using onos-secure-ssh".format( self.name, node ) )
kelvin8ec71442015-01-15 16:57:00 -08001449 self.handle.send( "\x03" ) # Control-C
Devin Limc20e79a2017-06-07 10:29:57 -07001450 self.handle.expect( self.prompt )
Jon Hall7993bfc2014-10-09 16:30:14 -04001451 return main.FALSE
1452 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001453 main.log.error( self.name + ": EOF exception found" )
1454 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001455 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001456 except Exception:
1457 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001458 main.cleanAndExit()
andrewonlab05e362f2014-10-10 00:40:57 -04001459
Devin Lim142b5342017-07-20 15:22:39 -07001460 def preventAutoRespawn( self ):
1461 """
1462 Description:
1463 This will prevent ONOSservice to automatically
1464 respawn.
1465 """
1466 try:
1467 self.handle.sendline( "sed -i -e 's/^respawn$/#respawn/g' tools/package/init/onos.conf" )
1468 self.handle.expect( "\$" ) # $ from the command
1469 self.handle.sendline( "sed -i -e 's/^Restart=always/Restart=no/g' tools/package/init/onos.service" )
1470 self.handle.expect( "\$" ) # $ from the command
1471 self.handle.expect( "\$" ) # $ from the prompt
1472 except pexpect.EOF:
1473 main.log.error( self.name + ": EOF exception found" )
1474 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001475 main.cleanAndExit()
Devin Lim142b5342017-07-20 15:22:39 -07001476 except Exception:
1477 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001478 main.cleanAndExit()
Devin Lim142b5342017-07-20 15:22:39 -07001479
kelvin-onlabd3b64892015-01-20 13:26:24 -08001480 def pushTestIntentsShell(
1481 self,
1482 dpidSrc,
1483 dpidDst,
1484 numIntents,
1485 dirFile,
1486 onosIp,
1487 numMult="",
1488 appId="",
1489 report=True,
1490 options="" ):
kelvin8ec71442015-01-15 16:57:00 -08001491 """
andrewonlabb66dfa12014-12-02 15:51:10 -05001492 Description:
kelvin8ec71442015-01-15 16:57:00 -08001493 Use the linux prompt to push test intents to
andrewonlabb66dfa12014-12-02 15:51:10 -05001494 better parallelize the results than the CLI
1495 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001496 * dpidSrc: specify source dpid
1497 * dpidDst: specify destination dpid
1498 * numIntents: specify number of intents to push
1499 * dirFile: specify directory and file name to save
andrewonlabb66dfa12014-12-02 15:51:10 -05001500 results
kelvin-onlabd3b64892015-01-20 13:26:24 -08001501 * onosIp: specify the IP of ONOS to install on
kelvin8ec71442015-01-15 16:57:00 -08001502 NOTE:
andrewonlabb66dfa12014-12-02 15:51:10 -05001503 You must invoke this command at linux shell prompt
kelvin8ec71442015-01-15 16:57:00 -08001504 """
1505 try:
1506 # Create the string to sendline
andrewonlabaedc8332014-12-04 12:43:03 -05001507 if options:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001508 baseCmd = "onos " + str( onosIp ) + " push-test-intents " +\
kelvin8ec71442015-01-15 16:57:00 -08001509 options + " "
andrewonlabaedc8332014-12-04 12:43:03 -05001510 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001511 baseCmd = "onos " + str( onosIp ) + " push-test-intents "
kelvin8ec71442015-01-15 16:57:00 -08001512
kelvin-onlabd3b64892015-01-20 13:26:24 -08001513 addDpid = baseCmd + str( dpidSrc ) + " " + str( dpidDst )
1514 if not numMult:
1515 addIntents = addDpid + " " + str( numIntents )
1516 elif numMult:
1517 addIntents = addDpid + " " + str( numIntents ) + " " +\
1518 str( numMult )
1519 if appId:
1520 addApp = addIntents + " " + str( appId )
andrewonlabb66dfa12014-12-02 15:51:10 -05001521 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001522 addApp = addIntents
andrewonlabb66dfa12014-12-02 15:51:10 -05001523
andrewonlabaedc8332014-12-04 12:43:03 -05001524 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001525 sendCmd = addApp + " > " + str( dirFile ) + " &"
andrewonlabaedc8332014-12-04 12:43:03 -05001526 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001527 sendCmd = addApp + " &"
1528 main.log.info( "Send cmd: " + sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001529
kelvin-onlabd3b64892015-01-20 13:26:24 -08001530 self.handle.sendline( sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001531
1532 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001533 main.log.error( self.name + ": EOF exception found" )
1534 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001535 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001536 except Exception:
1537 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001538 main.cleanAndExit()
andrewonlab05e362f2014-10-10 00:40:57 -04001539
kelvin-onlabd3b64892015-01-20 13:26:24 -08001540 def tsharkPcap( self, interface, dirFile ):
kelvin8ec71442015-01-15 16:57:00 -08001541 """
andrewonlab970399c2014-11-07 13:09:32 -05001542 Capture all packet activity and store in specified
1543 directory/file
1544
1545 Required:
1546 * interface: interface to capture
1547 * dir: directory/filename to store pcap
kelvin8ec71442015-01-15 16:57:00 -08001548 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001549 try:
1550 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001551 self.handle.expect( self.prompt )
andrewonlab970399c2014-11-07 13:09:32 -05001552
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001553 self.handle.sendline( "tshark -i " + str( interface ) + " -t e -w " + str( dirFile ) + " &" )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001554 self.handle.sendline( "\n" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001555 self.handle.expect( "Capturing on" )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001556 self.handle.sendline( "\n" )
Devin Limc20e79a2017-06-07 10:29:57 -07001557 self.handle.expect( self.prompt )
andrewonlab970399c2014-11-07 13:09:32 -05001558
Jon Hallfebb1c72015-03-05 13:30:09 -08001559 main.log.info( "Tshark started capturing files on " +
1560 str( interface ) + " and saving to directory: " +
1561 str( dirFile ) )
1562 except pexpect.EOF:
1563 main.log.error( self.name + ": EOF exception found" )
1564 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001565 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001566 except Exception:
1567 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001568 main.cleanAndExit()
Shreya Shaha73aaad2014-10-27 18:03:09 -04001569
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001570 def onosTopoCfg( self, onosIp, jsonFile ):
kelvin8ec71442015-01-15 16:57:00 -08001571 """
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001572 Description:
1573 Execute onos-topo-cfg command
1574 Required:
1575 onosIp - IP of the onos node you want to send the json to
1576 jsonFile - File path of the json file
1577 Return:
1578 Returns main.TRUE if the command is successfull; Returns
1579 main.FALSE if there was an error
kelvin8ec71442015-01-15 16:57:00 -08001580 """
shahshreyae6c7cf42014-11-26 16:39:01 -08001581 try:
kelvin8ec71442015-01-15 16:57:00 -08001582 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001583 self.handle.expect( self.prompt )
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001584 cmd = "onos-topo-cfg "
1585 self.handle.sendline( cmd + str( onosIp ) + " " + jsonFile )
1586 handle = self.handle.before
1587 print handle
1588 if "Error" in handle:
1589 main.log.error( self.name + ": " + self.handle.before )
1590 return main.FALSE
1591 else:
Devin Limc20e79a2017-06-07 10:29:57 -07001592 self.handle.expect( self.prompt )
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001593 return main.TRUE
1594
Jon Hallfebb1c72015-03-05 13:30:09 -08001595 except pexpect.EOF:
1596 main.log.error( self.name + ": EOF exception found" )
1597 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001598 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001599 except Exception:
1600 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001601 main.cleanAndExit()
kelvin8ec71442015-01-15 16:57:00 -08001602
jenkins1e99e7b2015-04-02 18:15:39 -07001603 def tsharkGrep( self, grep, directory, interface='eth0', grepOptions='' ):
kelvin8ec71442015-01-15 16:57:00 -08001604 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001605 Required:
kelvin8ec71442015-01-15 16:57:00 -08001606 * grep string
andrewonlabba44bcf2014-10-16 16:54:41 -04001607 * directory to store results
1608 Optional:
1609 * interface - default: eth0
Jon Hall4ba53f02015-07-29 13:07:41 -07001610 * grepOptions - options for grep
andrewonlabba44bcf2014-10-16 16:54:41 -04001611 Description:
1612 Uses tshark command to grep specific group of packets
1613 and stores the results to specified directory.
kelvin8ec71442015-01-15 16:57:00 -08001614 The timestamp is hardcoded to be in epoch
1615 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001616 try:
1617 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001618 self.handle.expect( self.prompt )
Jon Hallfebb1c72015-03-05 13:30:09 -08001619 self.handle.sendline( "" )
jenkins1e99e7b2015-04-02 18:15:39 -07001620 if grepOptions:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001621 grepStr = "grep " + str( grepOptions )
jenkins1e99e7b2015-04-02 18:15:39 -07001622 else:
1623 grepStr = "grep"
Jon Hall4ba53f02015-07-29 13:07:41 -07001624
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001625 cmd = (
1626 "sudo tshark -i " +
Jon Hallfebb1c72015-03-05 13:30:09 -08001627 str( interface ) +
jenkins1e99e7b2015-04-02 18:15:39 -07001628 " -t e | " +
1629 grepStr + " --line-buffered \"" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001630 str( grep ) +
Jon Hallfebb1c72015-03-05 13:30:09 -08001631 "\" >" +
1632 directory +
1633 " &" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001634 self.handle.sendline( cmd )
1635 main.log.info( cmd )
Jon Hallfebb1c72015-03-05 13:30:09 -08001636 self.handle.expect( "Capturing on" )
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001637 self.handle.sendline( "\n" )
Devin Limc20e79a2017-06-07 10:29:57 -07001638 self.handle.expect( self.prompt )
Jon Hallfebb1c72015-03-05 13:30:09 -08001639 except pexpect.EOF:
1640 main.log.error( self.name + ": EOF exception found" )
1641 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001642 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001643 except Exception:
1644 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001645 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001646
kelvin-onlabd3b64892015-01-20 13:26:24 -08001647 def tsharkStop( self ):
kelvin8ec71442015-01-15 16:57:00 -08001648 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001649 Removes wireshark files from /tmp and kills all tshark processes
kelvin8ec71442015-01-15 16:57:00 -08001650 """
1651 # Remove all pcap from previous captures
Jon Hallfebb1c72015-03-05 13:30:09 -08001652 try:
1653 self.execute( cmd="sudo rm /tmp/wireshark*" )
1654 self.handle.sendline( "" )
Jon Hallefbd9792015-03-05 16:11:36 -08001655 self.handle.sendline( "sudo kill -9 `ps -ef | grep \"tshark -i\"" +
1656 " | grep -v grep | awk '{print $2}'`" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001657 self.handle.sendline( "" )
1658 main.log.info( "Tshark stopped" )
1659 except pexpect.EOF:
1660 main.log.error( self.name + ": EOF exception found" )
1661 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001662 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001663 except Exception:
1664 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001665 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001666
kelvin8ec71442015-01-15 16:57:00 -08001667 def ptpd( self, args ):
1668 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001669 Initiate ptp with user-specified args.
1670 Required:
1671 * args: specify string of args after command
1672 'sudo ptpd'
kelvin8ec71442015-01-15 16:57:00 -08001673 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001674 try:
kelvin8ec71442015-01-15 16:57:00 -08001675 self.handle.sendline( "sudo ptpd " + str( args ) )
1676 i = self.handle.expect( [
andrewonlab0c38a4a2014-10-28 18:35:35 -04001677 "Multiple",
1678 "Error",
Devin Limc20e79a2017-06-07 10:29:57 -07001679 self.prompt ] )
1680 self.handle.expect( self.prompt )
andrewonlabba44bcf2014-10-16 16:54:41 -04001681
andrewonlab0c38a4a2014-10-28 18:35:35 -04001682 if i == 0:
1683 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001684 main.log.info( "ptpd returned an error: " +
1685 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001686 return handle
1687 elif i == 1:
1688 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001689 main.log.error( "ptpd returned an error: " +
1690 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001691 return handle
1692 else:
1693 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -08001694
andrewonlab0c38a4a2014-10-28 18:35:35 -04001695 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001696 main.log.error( self.name + ": EOF exception found" )
1697 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001698 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001699 except Exception:
1700 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001701 main.cleanAndExit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001702
You Wang54b1d672018-06-11 16:44:13 -07001703 def dumpONOSCmd( self, ONOSIp, CMD, destDir, filename, options="", timeout=60 ):
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001704 """
Pier50f0bc62016-09-07 17:53:40 -07001705 Dump Cmd to a desired directory.
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001706 For debugging purposes, you may want to use
Pier50f0bc62016-09-07 17:53:40 -07001707 this function to capture Cmd at a given point in time.
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001708 Localtime will be attached to the filename
1709
1710 Required:
1711 * ONOSIp: the IP of the target ONOS instance
Pier50f0bc62016-09-07 17:53:40 -07001712 * CMD: the command to dump;
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001713 * destDir: specify directory to copy to.
1714 ex ) /tmp/
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001715 * fileName: Name of the file
You Wang54b1d672018-06-11 16:44:13 -07001716 Optional:
Pier50f0bc62016-09-07 17:53:40 -07001717 * options: Options for ONOS command
You Wang54b1d672018-06-11 16:44:13 -07001718 * timeout: pexpect timeout for running the ONOS command
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001719 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001720
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001721 localtime = time.strftime( '%x %X' )
1722 localtime = localtime.replace( "/", "" )
1723 localtime = localtime.replace( " ", "_" )
1724 localtime = localtime.replace( ":", "" )
1725 if destDir[ -1: ] != "/":
1726 destDir += "/"
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001727 cmd = CMD + " " + options + " > " + str( destDir ) + str( filename ) + localtime
You Wang54b1d672018-06-11 16:44:13 -07001728 return self.onosCli( ONOSIp, cmd, timeout=timeout )
Flavio Castrob7718952016-05-18 08:53:41 -07001729
kelvin-onlabd3b64892015-01-20 13:26:24 -08001730 def cpLogsToDir( self, logToCopy,
Jon Hallefbd9792015-03-05 16:11:36 -08001731 destDir, copyFileName="" ):
kelvin8ec71442015-01-15 16:57:00 -08001732 """
1733 Copies logs to a desired directory.
andrewonlab5d7a8f32014-11-10 13:07:56 -05001734 Current implementation of ONOS deletes its karaf
1735 logs on every iteration. For debugging purposes,
kelvin8ec71442015-01-15 16:57:00 -08001736 you may want to use this function to capture
1737 certain karaf logs. ( or any other logs if needed )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001738 Localtime will be attached to the filename
1739
1740 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001741 * logToCopy: specify directory and log name to
andrewonlab5d7a8f32014-11-10 13:07:56 -05001742 copy.
kelvin8ec71442015-01-15 16:57:00 -08001743 ex ) /opt/onos/log/karaf.log.1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001744 For copying multiple files, leave copyFileName
1745 empty and only specify destDir -
kelvin8ec71442015-01-15 16:57:00 -08001746 ex ) /opt/onos/log/karaf*
kelvin-onlabd3b64892015-01-20 13:26:24 -08001747 * destDir: specify directory to copy to.
kelvin8ec71442015-01-15 16:57:00 -08001748 ex ) /tmp/
1749 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001750 * copyFileName: If you want to rename the log
1751 file, specify copyFileName. This will not work
andrewonlab5d7a8f32014-11-10 13:07:56 -05001752 with multiple file copying
kelvin8ec71442015-01-15 16:57:00 -08001753 """
andrewonlab5d7a8f32014-11-10 13:07:56 -05001754 try:
Flavio Castro09ab59d2016-05-25 17:01:35 -07001755 localtime = time.strftime( '%H %M' )
kelvin8ec71442015-01-15 16:57:00 -08001756 localtime = localtime.replace( "/", "" )
1757 localtime = localtime.replace( " ", "_" )
1758 localtime = localtime.replace( ":", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001759 if destDir[ -1: ] != "/":
1760 destDir += "/"
andrewonlab5d7a8f32014-11-10 13:07:56 -05001761
kelvin-onlabd3b64892015-01-20 13:26:24 -08001762 if copyFileName:
Jon Hallfebb1c72015-03-05 13:30:09 -08001763 self.handle.sendline( "cp " + str( logToCopy ) + " " +
1764 str( destDir ) + str( copyFileName ) +
1765 localtime )
kelvin8ec71442015-01-15 16:57:00 -08001766 self.handle.expect( "cp" )
Devin Limc20e79a2017-06-07 10:29:57 -07001767 self.handle.expect( self.prompt )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001768 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001769 self.handle.sendline( "cp " + str( logToCopy ) +
1770 " " + str( destDir ) )
kelvin8ec71442015-01-15 16:57:00 -08001771 self.handle.expect( "cp" )
Devin Limc20e79a2017-06-07 10:29:57 -07001772 self.handle.expect( self.prompt )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001773
kelvin8ec71442015-01-15 16:57:00 -08001774 return self.handle.before
1775
1776 except pexpect.EOF:
1777 main.log.error( "Copying files failed" )
1778 main.log.error( self.name + ": EOF exception found" )
1779 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001780 except Exception:
1781 main.log.exception( "Copying files failed" )
1782
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001783 def checkLogs( self, onosIp, restart=False ):
kelvin8ec71442015-01-15 16:57:00 -08001784 """
Jon Hall94fd0472014-12-08 11:52:42 -08001785 runs onos-check-logs on the given onos node
Jon Hall80daded2015-05-27 16:07:00 -07001786 If restart is True, use the old version of onos-check-logs which
1787 does not print the full stacktrace, but shows the entire log file,
1788 including across restarts
Jon Hall94fd0472014-12-08 11:52:42 -08001789 returns the response
kelvin8ec71442015-01-15 16:57:00 -08001790 """
Jon Hall94fd0472014-12-08 11:52:42 -08001791 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001792 cmd = "onos-check-logs " + str( onosIp )
Jon Hall16b72c42015-05-20 10:23:36 -07001793 if restart:
1794 cmd += " old"
kelvin8ec71442015-01-15 16:57:00 -08001795 self.handle.sendline( cmd )
1796 self.handle.expect( cmd )
Devin Limdc78e202017-06-09 18:30:07 -07001797 self.handle.expect( self.prompt + " " )
Jon Hall94fd0472014-12-08 11:52:42 -08001798 response = self.handle.before
1799 return response
1800 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001801 main.log.error( "Lost ssh connection" )
1802 main.log.error( self.name + ": EOF exception found" )
1803 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001804 except Exception:
1805 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001806 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001807
kelvin-onlabd3b64892015-01-20 13:26:24 -08001808 def onosStatus( self, node="" ):
kelvin8ec71442015-01-15 16:57:00 -08001809 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001810 Calls onos command: 'onos-service [<node-ip>] status'
kelvin8ec71442015-01-15 16:57:00 -08001811 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001812 try:
kelvin8ec71442015-01-15 16:57:00 -08001813 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001814 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -08001815 self.handle.sendline( "onos-service " + str( node ) +
1816 " status" )
1817 i = self.handle.expect( [
You Wangef1e6572016-03-08 12:53:18 -08001818 "start/running",
You Wang7bd83062016-03-01 11:50:00 -08001819 "Running ...",
You Wangef1e6572016-03-08 12:53:18 -08001820 "stop/waiting",
You Wang7bd83062016-03-01 11:50:00 -08001821 "Not Running ...",
kelvin8ec71442015-01-15 16:57:00 -08001822 pexpect.TIMEOUT ], timeout=120 )
YPZhangfebf7302016-05-24 16:45:56 -07001823 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001824 self.handle.expect( self.prompt )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001825
You Wangef1e6572016-03-08 12:53:18 -08001826 if i == 0 or i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001827 main.log.info( "ONOS is running" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001828 return main.TRUE
You Wangef1e6572016-03-08 12:53:18 -08001829 elif i == 2 or i == 3:
kelvin8ec71442015-01-15 16:57:00 -08001830 main.log.info( "ONOS is stopped" )
kelvin8ec71442015-01-15 16:57:00 -08001831 main.log.error( "ONOS service failed to check the status" )
Devin Lim44075962017-08-11 10:56:37 -07001832
1833 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001834 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001835 main.log.error( self.name + ": EOF exception found" )
1836 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001837 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001838 except Exception:
1839 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001840 main.cleanAndExit()
Jon Hall21270ac2015-02-16 17:59:55 -08001841
Jon Hall63604932015-02-26 17:09:50 -08001842 def setIpTables( self, ip, port='', action='add', packet_type='',
1843 direction='INPUT', rule='DROP', states=True ):
Jon Hallefbd9792015-03-05 16:11:36 -08001844 """
Jon Hall21270ac2015-02-16 17:59:55 -08001845 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001846 add or remove iptables rule to DROP (default) packets from
Jon Hall21270ac2015-02-16 17:59:55 -08001847 specific IP and PORT
1848 Usage:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001849 * specify action ('add' or 'remove')
Jon Hall21270ac2015-02-16 17:59:55 -08001850 when removing, pass in the same argument as you would add. It will
1851 delete that specific rule.
1852 * specify the ip to block
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001853 * specify the destination port to block (defaults to all ports)
1854 * optional packet type to block (default tcp)
1855 * optional iptables rule (default DROP)
1856 * optional direction to block (default 'INPUT')
Jon Hall63604932015-02-26 17:09:50 -08001857 * States boolean toggles adding all supported tcp states to the
1858 firewall rule
Jon Hall21270ac2015-02-16 17:59:55 -08001859 Returns:
1860 main.TRUE on success or
1861 main.FALSE if given invalid input or
1862 main.ERROR if there is an error in response from iptables
1863 WARNING:
1864 * This function uses root privilege iptables command which may result
1865 in unwanted network errors. USE WITH CAUTION
Jon Hallefbd9792015-03-05 16:11:36 -08001866 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001867
Jon Hall21270ac2015-02-16 17:59:55 -08001868 # NOTE*********
1869 # The strict checking methods of this driver function is intentional
1870 # to discourage any misuse or error of iptables, which can cause
1871 # severe network errors
1872 # *************
1873
1874 # NOTE: Sleep needed to give some time for rule to be added and
1875 # registered to the instance. If you are calling this function
1876 # multiple times this sleep will prevent any errors.
1877 # DO NOT REMOVE
Jon Hall63604932015-02-26 17:09:50 -08001878 # time.sleep( 5 )
Jon Hall21270ac2015-02-16 17:59:55 -08001879 try:
1880 # input validation
1881 action_type = action.lower()
1882 rule = rule.upper()
1883 direction = direction.upper()
1884 if action_type != 'add' and action_type != 'remove':
1885 main.log.error( "Invalid action type. Use 'add' or "
1886 "'remove' table rule" )
1887 if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
1888 # NOTE Currently only supports rules DROP, ACCEPT, and LOG
1889 main.log.error( "Invalid rule. Valid rules are 'DROP' or "
1890 "'ACCEPT' or 'LOG' only." )
1891 if direction != 'INPUT' and direction != 'OUTPUT':
1892 # NOTE currently only supports rules INPUT and OUPTUT
1893 main.log.error( "Invalid rule. Valid directions are"
1894 " 'OUTPUT' or 'INPUT'" )
1895 return main.FALSE
1896 return main.FALSE
1897 return main.FALSE
1898 if action_type == 'add':
1899 # -A is the 'append' action of iptables
1900 actionFlag = '-A'
1901 elif action_type == 'remove':
1902 # -D is the 'delete' rule of iptables
1903 actionFlag = '-D'
1904 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001905 self.handle.expect( self.prompt )
Jon Hall21270ac2015-02-16 17:59:55 -08001906 cmd = "sudo iptables " + actionFlag + " " +\
1907 direction +\
Jon Hall21270ac2015-02-16 17:59:55 -08001908 " -s " + str( ip )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001909 # " -p " + str( packet_type ) +\
Jon Hall63604932015-02-26 17:09:50 -08001910 if packet_type:
1911 cmd += " -p " + str( packet_type )
Jon Hall21270ac2015-02-16 17:59:55 -08001912 if port:
1913 cmd += " --dport " + str( port )
Jon Hall63604932015-02-26 17:09:50 -08001914 if states:
1915 cmd += " -m state --state="
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001916 # FIXME- Allow user to configure which states to block
Jon Hall63604932015-02-26 17:09:50 -08001917 cmd += "INVALID,ESTABLISHED,NEW,RELATED,UNTRACKED"
Jon Hall21270ac2015-02-16 17:59:55 -08001918 cmd += " -j " + str( rule )
1919
1920 self.handle.sendline( cmd )
Devin Limc20e79a2017-06-07 10:29:57 -07001921 self.handle.expect( self.prompt )
Jon Hall21270ac2015-02-16 17:59:55 -08001922 main.log.warn( self.handle.before )
1923
1924 info_string = "On " + str( self.name )
1925 info_string += " " + str( action_type )
1926 info_string += " iptable rule [ "
1927 info_string += " IP: " + str( ip )
1928 info_string += " Port: " + str( port )
1929 info_string += " Rule: " + str( rule )
1930 info_string += " Direction: " + str( direction ) + " ]"
1931 main.log.info( info_string )
1932 return main.TRUE
1933 except pexpect.TIMEOUT:
1934 main.log.exception( self.name + ": Timeout exception in "
1935 "setIpTables function" )
You Wang141b43b2018-06-26 16:50:18 -07001936 self.handle.send( "\x03" ) # Control-C
1937 self.handle.expect( self.prompt )
Jon Hall21270ac2015-02-16 17:59:55 -08001938 return main.ERROR
1939 except pexpect.EOF:
1940 main.log.error( self.name + ": EOF exception found" )
1941 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001942 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001943 except Exception:
1944 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001945 main.cleanAndExit()
Jon Hall21270ac2015-02-16 17:59:55 -08001946
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001947 def detailed_status( self, log_filename ):
Jon Hallefbd9792015-03-05 16:11:36 -08001948 """
Jon Hall0468b042015-02-19 19:08:21 -08001949 This method is used by STS to check the status of the controller
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001950 Reports RUNNING, STARTING, STOPPED, FROZEN, ERROR (and reason)
Jon Hallefbd9792015-03-05 16:11:36 -08001951 """
Jon Hall0468b042015-02-19 19:08:21 -08001952 import re
1953 try:
1954 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001955 self.handle.expect( self.prompt )
Jon Hall0468b042015-02-19 19:08:21 -08001956 self.handle.sendline( "cd " + self.home )
Devin Limc20e79a2017-06-07 10:29:57 -07001957 self.handle.expect( self.prompt )
Jon Hall0468b042015-02-19 19:08:21 -08001958 self.handle.sendline( "service onos status" )
Devin Limc20e79a2017-06-07 10:29:57 -07001959 self.handle.expect( self.prompt )
Jon Hall0468b042015-02-19 19:08:21 -08001960 response = self.handle.before
1961 if re.search( "onos start/running", response ):
1962 # onos start/running, process 10457
1963 return 'RUNNING'
1964 # FIXME: Implement this case
1965 # elif re.search( pattern, response ):
1966 # return 'STARTING'
1967 elif re.search( "onos stop/", response ):
1968 # onos stop/waiting
1969 # FIXME handle this differently?: onos stop/pre-stop
1970 return 'STOPPED'
1971 # FIXME: Implement this case
1972 # elif re.search( pattern, response ):
1973 # return 'FROZEN'
1974 else:
1975 main.log.warn( self.name +
Jon Hallefbd9792015-03-05 16:11:36 -08001976 " WARNING: status received unknown response" )
Jon Hall0468b042015-02-19 19:08:21 -08001977 main.log.warn( response )
1978 return 'ERROR', "Unknown response: %s" % response
1979 except pexpect.TIMEOUT:
1980 main.log.exception( self.name + ": Timeout exception in "
1981 "setIpTables function" )
You Wang141b43b2018-06-26 16:50:18 -07001982 self.handle.send( "\x03" ) # Control-C
1983 self.handle.expect( self.prompt )
Jon Hall0468b042015-02-19 19:08:21 -08001984 return 'ERROR', "Pexpect Timeout"
1985 except pexpect.EOF:
1986 main.log.error( self.name + ": EOF exception found" )
1987 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001988 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001989 except Exception:
1990 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001991 main.cleanAndExit()
Jon Hall0468b042015-02-19 19:08:21 -08001992
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001993 def createLinkGraphFile( self, benchIp, ONOSIpList, deviceCount ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001994 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07001995 Create/formats the LinkGraph.cfg file based on arguments
1996 -only creates a linear topology and connects islands
1997 -evenly distributes devices
andrew@onlab.us3b087132015-03-11 15:00:08 -07001998 -must be called by ONOSbench
1999
Jon Hall4ba53f02015-07-29 13:07:41 -07002000 ONOSIpList - list of all of the node IPs to be used
2001
2002 deviceCount - number of switches to be assigned
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002003 '''
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002004 main.log.info( "Creating link graph configuration file." )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002005 linkGraphPath = self.home + "/tools/package/etc/linkGraph.cfg"
Jon Hall4ba53f02015-07-29 13:07:41 -07002006 tempFile = "/tmp/linkGraph.cfg"
andrew@onlab.us3b087132015-03-11 15:00:08 -07002007
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002008 linkGraph = open( tempFile, 'w+' )
2009 linkGraph.write( "# NullLinkProvider topology description (config file).\n" )
2010 linkGraph.write( "# The NodeId is only added if the destination is another node's device.\n" )
2011 linkGraph.write( "# Bugs: Comments cannot be appended to a line to be read.\n" )
Jon Hall4ba53f02015-07-29 13:07:41 -07002012
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002013 clusterCount = len( ONOSIpList )
Jon Hall4ba53f02015-07-29 13:07:41 -07002014
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002015 if isinstance( deviceCount, int ) or isinstance( deviceCount, str ):
2016 deviceCount = int( deviceCount )
2017 switchList = [ 0 ]*( clusterCount+1 )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002018 baselineSwitchCount = deviceCount/clusterCount
Jon Hall4ba53f02015-07-29 13:07:41 -07002019
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002020 for node in range( 1, clusterCount + 1 ):
2021 switchList[ node ] = baselineSwitchCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07002022
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002023 for node in range( 1, ( deviceCount % clusterCount )+1 ):
2024 switchList[ node ] += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07002025
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002026 if isinstance( deviceCount, list ):
2027 main.log.info( "Using provided device distribution" )
2028 switchList = [ 0 ]
andrew@onlab.us3b087132015-03-11 15:00:08 -07002029 for i in deviceCount:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002030 switchList.append( int( i ) )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002031
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002032 tempList = [ '0' ]
2033 tempList.extend( ONOSIpList )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002034 ONOSIpList = tempList
2035
2036 myPort = 6
2037 lastSwitch = 0
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002038 for node in range( 1, clusterCount+1 ):
2039 if switchList[ node ] == 0:
andrew@onlab.us3b087132015-03-11 15:00:08 -07002040 continue
2041
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002042 linkGraph.write( "graph " + ONOSIpList[ node ] + " {\n" )
Jon Hall4ba53f02015-07-29 13:07:41 -07002043
andrew@onlab.us3b087132015-03-11 15:00:08 -07002044 if node > 1:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002045 # connect to last device on previous node
2046 line = ( "\t0:5 -> " + str( lastSwitch ) + ":6:" + lastIp + "\n" ) # ONOSIpList[node-1]
2047 linkGraph.write( line )
Jon Hall4ba53f02015-07-29 13:07:41 -07002048
2049 lastSwitch = 0
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002050 for switch in range( 0, switchList[ node ]-1 ):
andrew@onlab.us3b087132015-03-11 15:00:08 -07002051 line = ""
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002052 line = ( "\t" + str( switch ) + ":" + str( myPort ) )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002053 line += " -- "
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002054 line += ( str( switch+1 ) + ":" + str( myPort-1 ) + "\n" )
2055 linkGraph.write( line )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002056 lastSwitch = switch+1
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002057 lastIp = ONOSIpList[ node ]
Jon Hall4ba53f02015-07-29 13:07:41 -07002058
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002059 # lastSwitch += 1
2060 if node < ( clusterCount ):
2061 # connect to first device on the next node
2062 line = ( "\t" + str( lastSwitch ) + ":6 -> 0:5:" + ONOSIpList[ node+1 ] + "\n" )
2063 linkGraph.write( line )
Jon Hall4ba53f02015-07-29 13:07:41 -07002064
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002065 linkGraph.write( "}\n" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002066 linkGraph.close()
2067
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002068 # SCP
2069 os.system( "scp " + tempFile + " " + self.user_name + "@" + benchIp + ":" + linkGraphPath )
2070 main.log.info( "linkGraph.cfg creation complete" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002071
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002072 def configNullDev( self, ONOSIpList, deviceCount, numPorts=10 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002073 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07002074 ONOSIpList = list of Ip addresses of nodes switches will be devided amongst
2075 deviceCount = number of switches to distribute, or list of values to use as custom distribution
cameron@onlab.us75900962015-03-30 13:22:49 -07002076 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 +00002077 '''
2078
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002079 main.log.info( "Configuring Null Device Provider" )
2080 clusterCount = len( ONOSIpList )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002081
Jon Hall4ba53f02015-07-29 13:07:41 -07002082 try:
2083
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002084 if isinstance( deviceCount, int ) or isinstance( deviceCount, str ):
2085 main.log.info( "Creating device distribution" )
2086 deviceCount = int( deviceCount )
2087 switchList = [ 0 ]*( clusterCount+1 )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002088 baselineSwitchCount = deviceCount/clusterCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07002089
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002090 for node in range( 1, clusterCount + 1 ):
2091 switchList[ node ] = baselineSwitchCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07002092
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002093 for node in range( 1, ( deviceCount % clusterCount )+1 ):
2094 switchList[ node ] += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07002095
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002096 if isinstance( deviceCount, list ):
2097 main.log.info( "Using provided device distribution" )
Jon Hall4ba53f02015-07-29 13:07:41 -07002098
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002099 if len( deviceCount ) == clusterCount:
2100 switchList = [ '0' ]
2101 switchList.extend( deviceCount )
Jon Hall4ba53f02015-07-29 13:07:41 -07002102
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002103 if len( deviceCount ) == ( clusterCount + 1 ):
2104 if deviceCount[ 0 ] == '0' or deviceCount[ 0 ] == 0:
cameron@onlab.us75900962015-03-30 13:22:49 -07002105 switchList = deviceCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07002106
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002107 assert len( switchList ) == ( clusterCount + 1 )
Jon Hall4ba53f02015-07-29 13:07:41 -07002108
cameron@onlab.us75900962015-03-30 13:22:49 -07002109 except AssertionError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002110 main.log.error( "Bad device/Ip list match" )
cameron@onlab.us75900962015-03-30 13:22:49 -07002111 except TypeError:
2112 main.log.exception( self.name + ": Object not as expected" )
2113 return None
Jon Hall77ba41c2015-04-06 10:25:40 -07002114 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002115 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002116 main.cleanAndExit()
cameron@onlab.us75900962015-03-30 13:22:49 -07002117
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002118 ONOSIp = [ 0 ]
2119 ONOSIp.extend( ONOSIpList )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002120
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002121 devicesString = "devConfigs = "
2122 for node in range( 1, len( ONOSIp ) ):
2123 devicesString += ( ONOSIp[ node ] + ":" + str( switchList[ node ] ) )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002124 if node < clusterCount:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002125 devicesString += ( "," )
Jon Hall4ba53f02015-07-29 13:07:41 -07002126
2127 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002128 self.handle.sendline( "onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider devConfigs " + devicesString )
2129 self.handle.expect( ":~" )
2130 self.handle.sendline( "onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider numPorts " + str( numPorts ) )
2131 self.handle.expect( ":~" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002132
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002133 for i in range( 10 ):
2134 self.handle.sendline( "onos $OC1 cfg get org.onosproject.provider.nil.device.impl.NullDeviceProvider" )
2135 self.handle.expect( ":~" )
cameron@onlab.us75900962015-03-30 13:22:49 -07002136 verification = self.handle.before
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002137 if ( " value=" + str( numPorts ) ) in verification and ( " value=" + devicesString ) in verification:
cameron@onlab.us75900962015-03-30 13:22:49 -07002138 break
2139 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002140 time.sleep( 1 )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002141
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002142 assert ( "value=" + str( numPorts ) ) in verification and ( " value=" + devicesString ) in verification
Jon Hall4ba53f02015-07-29 13:07:41 -07002143
cameron@onlab.us75900962015-03-30 13:22:49 -07002144 except AssertionError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002145 main.log.error( "Incorrect Config settings: " + verification )
Jon Hall77ba41c2015-04-06 10:25:40 -07002146 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002147 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002148 main.cleanAndExit()
cameron@onlab.us75900962015-03-30 13:22:49 -07002149
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002150 def configNullLink( self, fileName="/opt/onos/apache-karaf-3.0.3/etc/linkGraph.cfg", eventRate=0 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002151 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07002152 fileName default is currently the same as the default on ONOS, specify alternate file if
cameron@onlab.us75900962015-03-30 13:22:49 -07002153 you want to use a different topology file than linkGraph.cfg
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002154 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07002155
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002156 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002157 self.handle.sendline( "onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider eventRate " + str( eventRate ) )
2158 self.handle.expect( ":~" )
2159 self.handle.sendline( "onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider cfgFile " + fileName )
2160 self.handle.expect( ":~" )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002161
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002162 for i in range( 10 ):
2163 self.handle.sendline( "onos $OC1 cfg get org.onosproject.provider.nil.link.impl.NullLinkProvider" )
2164 self.handle.expect( ":~" )
cameron@onlab.us75900962015-03-30 13:22:49 -07002165 verification = self.handle.before
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002166 if ( " value=" + str( eventRate ) ) in verification and ( " value=" + fileName ) in verification:
cameron@onlab.us75900962015-03-30 13:22:49 -07002167 break
Jon Hall4ba53f02015-07-29 13:07:41 -07002168 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002169 time.sleep( 1 )
Jon Hall4ba53f02015-07-29 13:07:41 -07002170
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002171 assert ( "value=" + str( eventRate ) ) in verification and ( " value=" + fileName ) in verification
Jon Hall4ba53f02015-07-29 13:07:41 -07002172
cameron@onlab.us75900962015-03-30 13:22:49 -07002173 except pexpect.EOF:
2174 main.log.error( self.name + ": EOF exception found" )
2175 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002176 main.cleanAndExit()
cameron@onlab.us75900962015-03-30 13:22:49 -07002177 except AssertionError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002178 main.log.info( "Settings did not post to ONOS" )
Jon Hall3e6edb32018-08-21 16:20:30 -07002179 main.log.error( verification )
Jon Hall77ba41c2015-04-06 10:25:40 -07002180 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002181 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall3e6edb32018-08-21 16:20:30 -07002182 main.log.error( verification )
Devin Lim44075962017-08-11 10:56:37 -07002183 main.cleanAndExit()
andrew@onlab.us3b087132015-03-11 15:00:08 -07002184
kelvin-onlaba4074292015-07-09 15:19:49 -07002185 def getOnosIps( self ):
2186 """
2187 Get all onos IPs stored in
2188 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002189
kelvin-onlaba4074292015-07-09 15:19:49 -07002190 return sorted( self.onosIps.values() )
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002191
Chiyu Chengec63bde2016-11-17 18:11:36 -08002192 def listLog( self, nodeIp ):
2193 """
2194 Get a list of all the karaf log names
2195 """
2196 try:
2197 cmd = "onos-ssh " + nodeIp + " ls -tr /opt/onos/log"
2198 self.handle.sendline( cmd )
2199 self.handle.expect( ":~" )
2200 before = self.handle.before.splitlines()
2201 logNames = []
2202 for word in before:
2203 if 'karaf.log' in word:
2204 logNames.append( word )
2205 return logNames
2206 except pexpect.EOF:
2207 main.log.error( self.name + ": EOF exception found" )
2208 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002209 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08002210 except pexpect.TIMEOUT:
2211 main.log.error( self.name + ": TIMEOUT exception found" )
2212 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002213 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08002214 except Exception:
2215 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002216 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08002217
Pratik Parab3b2ab5a2017-02-14 13:15:14 -08002218 def logReport( self, nodeIp, searchTerms, outputMode="s", startStr=None, endStr=None ):
Jon Hallb4242222016-01-25 17:07:04 -08002219 """
2220 Searches the latest ONOS log file for the given search terms and
2221 prints the total occurances of each term. Returns to combined total of
2222 all occurances.
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002223
Jon Hallb4242222016-01-25 17:07:04 -08002224 Arguments:
2225 * nodeIp - The ip of the ONOS node where the log is located
2226 * searchTerms - A string to grep for or a list of strings to grep
2227 for in the ONOS log. Will print out the number of
2228 occurances for each term.
2229 Optional Arguments:
2230 * outputMode - 's' or 'd'. If 'd' will print the last 5 lines
2231 containing each search term as well as the total
2232 number of occurances of each term. Defaults to 's',
2233 which prints the simple output of just the number
2234 of occurances for each term.
Pratik Parab3b2ab5a2017-02-14 13:15:14 -08002235 * startStr - the start string to be given to stream editor command
2236 as the start point for extraction of data
2237 * endStr - the end string to be given to stream editor command as
2238 the end point for extraction of data
Jon Hallb4242222016-01-25 17:07:04 -08002239 """
2240 try:
2241 main.log.info( " Log Report for {} ".format( nodeIp ).center( 70, '=' ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002242 if isinstance( searchTerms, str ):
2243 searchTerms = [ searchTerms ]
Jon Hallb4242222016-01-25 17:07:04 -08002244 numTerms = len( searchTerms )
2245 outputMode = outputMode.lower()
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002246
Jon Hallb4242222016-01-25 17:07:04 -08002247 totalHits = 0
2248 logLines = []
2249 for termIndex in range( numTerms ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002250 term = searchTerms[ termIndex ]
2251 logLines.append( [ term ] )
Pratik Parab3b2ab5a2017-02-14 13:15:14 -08002252 if startStr and endStr:
2253 cmd = "onos-ssh {} \"sed -n '/{}/,/{}/p' /opt/onos/log/karaf.log | grep {}\"".format( nodeIp,
2254 startStr,
2255 endStr,
2256 term )
2257 else:
2258 cmd = "onos-ssh {} cat /opt/onos/log/karaf.log | grep {}".format( nodeIp,
2259 term )
Jon Hallb4242222016-01-25 17:07:04 -08002260 self.handle.sendline( cmd )
2261 self.handle.expect( ":~" )
2262 before = self.handle.before.splitlines()
2263 count = 0
2264 for line in before:
2265 if term in line and "grep" not in line:
2266 count += 1
2267 if before.index( line ) > ( len( before ) - 7 ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002268 logLines[ termIndex ].append( line )
Jon Hallb4242222016-01-25 17:07:04 -08002269 main.log.info( "{}: {}".format( term, count ) )
2270 totalHits += count
2271 if termIndex == numTerms - 1:
2272 print "\n"
2273 if outputMode != "s":
2274 outputString = ""
2275 for term in logLines:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002276 outputString = term[ 0 ] + ": \n"
Jon Hallb4242222016-01-25 17:07:04 -08002277 for line in range( 1, len( term ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002278 outputString += ( "\t" + term[ line ] + "\n" )
2279 if outputString != ( term[ 0 ] + ": \n" ):
Jon Hallb4242222016-01-25 17:07:04 -08002280 main.log.info( outputString )
2281 main.log.info( "=" * 70 )
2282 return totalHits
2283 except pexpect.EOF:
2284 main.log.error( self.name + ": EOF exception found" )
2285 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002286 main.cleanAndExit()
Jon Hallb4242222016-01-25 17:07:04 -08002287 except pexpect.TIMEOUT:
2288 main.log.error( self.name + ": TIMEOUT exception found" )
2289 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002290 main.cleanAndExit()
Jon Hallb4242222016-01-25 17:07:04 -08002291 except Exception:
2292 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002293 main.cleanAndExit()
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002294
2295 def copyMininetFile( self, fileName, localPath, userName, ip,
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002296 mnPath='~/mininet/custom/', timeout = 60 ):
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002297 """
2298 Description:
2299 Copy mininet topology file from dependency folder in the test folder
2300 and paste it to the mininet machine's mininet/custom folder
2301 Required:
2302 fileName - Name of the topology file to copy
2303 localPath - File path of the mininet topology file
2304 userName - User name of the mininet machine to send the file to
2305 ip - Ip address of the mininet machine
2306 Optional:
2307 mnPath - of the mininet directory to send the file to
2308 Return:
2309 Return main.TRUE if successfully copied the file otherwise
2310 return main.FALSE
2311 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002312
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002313 try:
2314 cmd = "scp " + localPath + fileName + " " + userName + "@" + \
2315 str( ip ) + ":" + mnPath + fileName
2316
2317 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07002318 self.handle.expect( self.prompt )
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002319
2320 main.log.info( self.name + ": Execute: " + cmd )
2321
2322 self.handle.sendline( cmd )
2323
2324 i = self.handle.expect( [ 'No such file',
2325 "100%",
2326 pexpect.TIMEOUT ] )
2327
2328 if i == 0:
2329 main.log.error( self.name + ": File " + fileName +
2330 " does not exist!" )
2331 return main.FALSE
2332
2333 if i == 1:
2334 main.log.info( self.name + ": File " + fileName +
2335 " has been copied!" )
2336 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07002337 self.handle.expect( self.prompt )
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002338 return main.TRUE
2339
2340 except pexpect.EOF:
2341 main.log.error( self.name + ": EOF exception found" )
2342 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002343 main.cleanAndExit()
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002344 except pexpect.TIMEOUT:
2345 main.log.error( self.name + ": TIMEOUT exception found" )
2346 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002347 main.cleanAndExit()
cameron@onlab.us78b89652015-07-08 15:21:03 -07002348
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002349 def jvmSet( self, memory=8 ):
Jon Hall4ba53f02015-07-29 13:07:41 -07002350
cameron@onlab.us78b89652015-07-08 15:21:03 -07002351 import os
2352
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002353 homeDir = os.path.expanduser( '~' )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002354 filename = "/onos/tools/package/bin/onos-service"
2355
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002356 serviceConfig = open( homeDir + filename, 'w+' )
2357 serviceConfig.write( "#!/bin/bash\n " )
2358 serviceConfig.write( "#------------------------------------- \n " )
2359 serviceConfig.write( "# Starts ONOS Apache Karaf container\n " )
2360 serviceConfig.write( "#------------------------------------- \n " )
2361 serviceConfig.write( "#export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-7-openjdk-amd64/}\n " )
2362 serviceConfig.write( """export JAVA_OPTS="${JAVA_OPTS:--Xms""" + str( memory ) + "G -Xmx" + str( memory ) + """G}" \n """ )
2363 serviceConfig.write( "[ -d $ONOS_HOME ] && cd $ONOS_HOME || ONOS_HOME=$(dirname $0)/..\n" )
2364 serviceConfig.write( """${ONOS_HOME}/apache-karaf-$KARAF_VERSION/bin/karaf "$@" \n """ )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002365 serviceConfig.close()
2366
Jon Hall6c44c0b2016-04-20 15:21:00 -07002367 def createDBFile( self, testData ):
Jon Hall4ba53f02015-07-29 13:07:41 -07002368
cameron@onlab.us78b89652015-07-08 15:21:03 -07002369 filename = main.TEST + "DB"
2370 DBString = ""
Jon Hall4ba53f02015-07-29 13:07:41 -07002371
cameron@onlab.us78b89652015-07-08 15:21:03 -07002372 for item in testData:
Jon Hall3e6edb32018-08-21 16:20:30 -07002373 if isinstance( item, str ):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002374 item = "'" + item + "'"
Jon Hall6c44c0b2016-04-20 15:21:00 -07002375 if testData.index( item ) < len( testData - 1 ):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002376 item += ","
Jon Hall6c44c0b2016-04-20 15:21:00 -07002377 DBString += str( item )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002378
Jon Hall6c44c0b2016-04-20 15:21:00 -07002379 DBFile = open( filename, "a" )
2380 DBFile.write( DBString )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002381 DBFile.close()
2382
Jon Hall6c44c0b2016-04-20 15:21:00 -07002383 def verifySummary( self, ONOSIp, *deviceCount ):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002384
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002385 self.handle.sendline( "onos " + ONOSIp + " summary" )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002386 self.handle.expect( ":~" )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002387
2388 summaryStr = self.handle.before
2389 print "\nSummary\n==============\n" + summaryStr + "\n\n"
2390
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002391 # passed = "SCC(s)=1" in summaryStr
2392 # if deviceCount:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002393 # passed = "devices=" + str(deviceCount) + "," not in summaryStr
cameron@onlab.us78b89652015-07-08 15:21:03 -07002394
GlennRC772363b2015-08-25 13:05:57 -07002395 passed = False
cameron@onlab.us78b89652015-07-08 15:21:03 -07002396 if "SCC(s)=1," in summaryStr:
2397 passed = True
Jon Hall6c44c0b2016-04-20 15:21:00 -07002398 print "Summary is verifed"
Jon Hall4ba53f02015-07-29 13:07:41 -07002399 else:
Jon Hall6c44c0b2016-04-20 15:21:00 -07002400 print "Summary failed"
cameron@onlab.us78b89652015-07-08 15:21:03 -07002401
2402 if deviceCount:
2403 print" ============================="
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002404 checkStr = "devices=" + str( deviceCount[ 0 ] ) + ","
cameron@onlab.us78b89652015-07-08 15:21:03 -07002405 print "Checkstr: " + checkStr
2406 if checkStr not in summaryStr:
2407 passed = False
Jon Hall6c44c0b2016-04-20 15:21:00 -07002408 print "Device count failed"
Jon Hall4ba53f02015-07-29 13:07:41 -07002409 else:
2410 print "device count verified"
cameron@onlab.us78b89652015-07-08 15:21:03 -07002411
2412 return passed
Jon Hall6c44c0b2016-04-20 15:21:00 -07002413
Jon Hall8f6d4622016-05-23 15:27:18 -07002414 def getIpAddr( self, iface=None ):
Jon Hall6c44c0b2016-04-20 15:21:00 -07002415 """
2416 Update self.ip_address with numerical ip address. If multiple IP's are
2417 located on the device, will attempt to use self.nicAddr to choose the
2418 right one. Defaults to 127.0.0.1 if no other address is found or cannot
2419 determine the correct address.
2420
2421 ONLY WORKS WITH IPV4 ADDRESSES
2422 """
2423 try:
Jon Hall8f6d4622016-05-23 15:27:18 -07002424 LOCALHOST = "127.0.0.1"
Jon Hall6c44c0b2016-04-20 15:21:00 -07002425 ipPat = "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"
2426 pattern = re.compile( ipPat )
2427 match = re.search( pattern, self.ip_address )
2428 if self.nicAddr:
2429 nicPat = self.nicAddr.replace( ".", "\." ).replace( "\*", r"\d{1,3}" )
2430 nicPat = re.compile( nicPat )
2431 else:
2432 nicPat = None
2433 # IF self.ip_address is an ip address and matches
2434 # self.nicAddr: return self.ip_address
2435 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002436 curIp = match.group( 0 )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002437 if nicPat:
2438 nicMatch = re.search( nicPat, curIp )
2439 if nicMatch:
2440 return self.ip_address
Jon Hall8f6d4622016-05-23 15:27:18 -07002441 # ELSE: IF iface, return ip of interface
2442 cmd = "ifconfig"
2443 ifPat = re.compile( "inet addr:({})".format( ipPat ) )
2444 if iface:
2445 cmd += " " + str( iface )
2446 raw = subprocess.check_output( cmd.split() )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002447 ifPat = re.compile( "inet addr:({})".format( ipPat ) )
2448 ips = re.findall( ifPat, raw )
Jon Hall8f6d4622016-05-23 15:27:18 -07002449 if iface:
2450 if ips:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002451 ip = ips[ 0 ]
Jon Hall8f6d4622016-05-23 15:27:18 -07002452 self.ip_address = ip
2453 return ip
2454 else:
2455 main.log.error( "Error finding ip, ifconfig output:".format( raw ) )
2456 # ELSE: attempt to get address matching nicPat.
Jon Hall6c44c0b2016-04-20 15:21:00 -07002457 if nicPat:
2458 for ip in ips:
2459 curMatch = re.search( nicPat, ip )
2460 if curMatch:
2461 self.ip_address = ip
2462 return ip
Jon Hall8f6d4622016-05-23 15:27:18 -07002463 else: # If only one non-localhost ip, return that
2464 tmpList = [ ip for ip in ips if ip is not LOCALHOST ]
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002465 if len( tmpList ) == 1:
2466 curIp = tmpList[ 0 ]
Jon Hall6c44c0b2016-04-20 15:21:00 -07002467 self.ip_address = curIp
2468 return curIp
Jon Hall8f6d4622016-05-23 15:27:18 -07002469 # Either no non-localhost IPs, or more than 1
Jon Hallebccd352016-05-20 15:17:17 -07002470 main.log.warn( "getIpAddr failed to find a public IP address" )
Jon Hall8f6d4622016-05-23 15:27:18 -07002471 return LOCALHOST
Jon Halle1790952016-05-23 15:51:46 -07002472 except subprocess.CalledProcessError:
Jon Hall8f6d4622016-05-23 15:27:18 -07002473 main.log.exception( "Error executing ifconfig" )
2474 except IndexError:
2475 main.log.exception( "Error getting IP Address" )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002476 except Exception:
2477 main.log.exception( "Uncaught exception" )
suibin zhang116647a2016-05-06 16:30:09 -07002478
Devin Lim461f0872017-06-05 16:49:33 -07002479 def startBasicONOS( self, nodeList, opSleep=60, onosStartupSleep=30, onosUser="sdn" ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002480 '''
suibin zhang116647a2016-05-06 16:30:09 -07002481 Start onos cluster with defined nodes, but only with drivers app
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002482 '''
suibin zhang116647a2016-05-06 16:30:09 -07002483 import time
2484
2485 self.createCellFile( self.ip_address,
Jon Hall3e6edb32018-08-21 16:20:30 -07002486 "temp",
2487 self.ip_address,
2488 "drivers",
2489 nodeList,
2490 nodeList,
2491 onosUser=onosUser )
suibin zhang116647a2016-05-06 16:30:09 -07002492
2493 main.log.info( self.name + ": Apply cell to environment" )
2494 cellResult = self.setCell( "temp" )
2495 verifyResult = self.verifyCell()
2496
2497 main.log.info( self.name + ": Creating ONOS package" )
You Wangd1bcaca2016-10-24 15:23:26 -07002498 packageResult = self.buckBuild( timeout=opSleep )
suibin zhang116647a2016-05-06 16:30:09 -07002499
You Wangc669d212017-01-25 11:09:48 -08002500 main.log.info( self.name + ": Uninstalling ONOS" )
2501 for nd in nodeList:
2502 self.onosUninstall( nodeIp=nd )
2503
suibin zhang116647a2016-05-06 16:30:09 -07002504 main.log.info( self.name + ": Installing ONOS package" )
2505 for nd in nodeList:
You Wangc669d212017-01-25 11:09:48 -08002506 self.onosInstall( node=nd )
2507
2508 main.log.info( self.name + ": Set up ONOS secure SSH" )
2509 for nd in nodeList:
2510 self.onosSecureSSH( node=nd )
suibin zhang116647a2016-05-06 16:30:09 -07002511
2512 main.log.info( self.name + ": Starting ONOS service" )
2513 time.sleep( onosStartupSleep )
2514
2515 onosStatus = True
2516 for nd in nodeList:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002517 onosStatus = onosStatus & self.isup( node = nd )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002518 # print "onosStatus is: " + str( onosStatus )
suibin zhang116647a2016-05-06 16:30:09 -07002519
2520 return main.TRUE if onosStatus else main.FALSE
2521
Devin Lim02075272017-07-10 15:33:21 -07002522 def onosNetCfg( self, controllerIp, path, fileName ):
Jeremy Songster5665f1b2016-06-20 14:38:22 -07002523 """
2524 Push a specified json file to ONOS through the onos-netcfg service
2525
2526 Required:
Devin Lim02075272017-07-10 15:33:21 -07002527 controllerIp - the Ip of the ONOS node in the cluster
Jeremy Songster5665f1b2016-06-20 14:38:22 -07002528 path - the location of the file to be sent
2529 fileName - name of the json file to be sent
2530
2531 Returns main.TRUE on successfully sending json file, and main.FALSE if
2532 there is an error.
2533 """
2534 try:
Devin Lim02075272017-07-10 15:33:21 -07002535 cmd = "onos-netcfg {0} {1}{2}".format( controllerIp, path, fileName )
2536 main.log.info( "Sending: " + cmd )
2537 main.ONOSbench.handle.sendline( cmd )
Jeremy Ronquillo3008aa32017-07-07 15:38:57 -07002538 main.ONOSbench.handle.expect( self.prompt )
Devin Lim02075272017-07-10 15:33:21 -07002539 handle = self.handle.before
Jeremy Ronquillo3008aa32017-07-07 15:38:57 -07002540 if "Error" in handle or "No such file or directory" in handle or "curl: " in handle:
2541 main.log.error( self.name + ": " + handle + self.handle.after )
Devin Lim02075272017-07-10 15:33:21 -07002542 return main.FALSE
Devin Lim752dd7b2017-06-27 14:40:03 -07002543 return main.TRUE
Jeremy Songster5665f1b2016-06-20 14:38:22 -07002544 except pexpect.EOF:
2545 main.log.error( self.name + ": EOF exception found" )
2546 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002547 main.cleanAndExit()
Jeremy Songster5665f1b2016-06-20 14:38:22 -07002548 except Exception:
2549 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002550 main.cleanAndExit()
Devin Lim3ebd5e72017-11-14 10:38:00 -08002551
2552 def formCluster( self, onosIPs ):
2553 """
2554 From ONOS cluster for IP addresses in onosIPs list
2555 """
2556 try:
2557 onosIPs = " ".join( onosIPs )
2558 command = "onos-form-cluster {}".format( onosIPs )
2559 main.log.info( "Sending: " + command )
2560 self.handle.sendline( "" )
2561 self.handle.expect( self.prompt )
2562 self.handle.sendline( command )
2563 self.handle.expect( self.prompt )
2564 handle = self.handle.before
2565 main.log.debug( handle )
2566 assert handle is not None, "Error in sendline"
2567 assert "Command not found:" not in handle, handle
2568 assert "Error" not in handle, handle
2569 assert "Exception:" not in handle, handle
2570 assert "curl:" not in handle, handle
2571 return main.TRUE
2572 except AssertionError:
2573 main.log.exception( "{} Error in onos-form-cluster output:".format( self.name ) )
2574 return main.FALSE
2575 except TypeError:
2576 main.log.exception( self.name + ": Object not as expected" )
2577 return main.FALSE
2578 except pexpect.EOF:
2579 main.log.error( self.name + ": EOF exception found" )
2580 main.log.error( self.name + ": " + self.handle.before )
2581 main.cleanAndExit()
2582 except Exception:
2583 main.log.exception( self.name + ": Uncaught exception!" )
2584 main.cleanAndExit()
Jon Hall7ce46ea2018-02-05 12:20:59 -08002585
2586 def backupData( self, location ):
2587 """
2588 Backs up ONOS data and logs to a given location. Returns main.FALSE
2589 if there is an error executing the command, and main.TRUE otherwise.
2590 required arguments:
2591 loaction - The file path to save the backup to
2592 """
2593 try:
2594 cmd = "/opt/onos/bin/onos-backup " + str( location )
2595 self.handle.sendline( cmd )
2596 self.handle.expect( self.prompt )
2597 handle = self.handle.before
2598 main.log.debug( handle )
2599 assert handle is not None, "Error in sendline"
2600 assert "Command not found:" not in handle, handle
2601 assert "Error" not in handle, handle
2602 assert "Exception:" not in handle, handle
2603 return main.TRUE
2604 except AssertionError:
2605 main.log.exception( "{} Error in onos-backup output:".format( self.name ) )
2606 return main.FALSE
2607 except TypeError:
2608 main.log.exception( self.name + ": Object not as expected" )
2609 return main.FALSE
2610 except pexpect.EOF:
2611 main.log.error( self.name + ": EOF exception found" )
2612 main.log.error( self.name + ": " + self.handle.before )
2613 main.cleanAndExit()
2614 except Exception:
2615 main.log.exception( self.name + ": Uncaught exception!" )
2616 main.cleanAndExit()
2617
2618 def restoreData( self, location ):
2619 """
2620 Restores ONOS data and logs from a given location. Returns main.FALSE
2621 if there is an error executing the command, and main.TRUE otherwise.
2622 required arguments:
2623 loaction - The file path of a backup file
2624 """
2625 try:
2626 cmd = "/opt/onos/bin/onos-restore " + str( location )
2627 self.handle.sendline( cmd )
2628 self.handle.expect( self.prompt )
2629 handle = self.handle.before
2630 main.log.debug( handle )
2631 assert handle is not None, "Error in sendline"
2632 assert "Command not found:" not in handle, handle
2633 assert "Error" not in handle, handle
2634 assert "Exception:" not in handle, handle
2635 return main.TRUE
2636 except AssertionError:
2637 main.log.exception( "{} Error in onos-restore output:".format( self.name ) )
2638 return main.FALSE
2639 except TypeError:
2640 main.log.exception( self.name + ": Object not as expected" )
2641 return main.FALSE
2642 except pexpect.EOF:
2643 main.log.error( self.name + ": EOF exception found" )
2644 main.log.error( self.name + ": " + self.handle.before )
2645 main.cleanAndExit()
2646 except Exception:
2647 main.log.exception( self.name + ": Uncaught exception!" )
2648 main.cleanAndExit()
You Wang5df1c6d2018-04-06 18:02:02 -07002649
You Wang5ac7db72018-07-17 11:17:52 -07002650 def onosDiagnostics( self, onosIPs, dstDir, suffix, timeout=300 ):
You Wang5df1c6d2018-04-06 18:02:02 -07002651 """
2652 Run onos-diagnostics with given ONOS instance IPs and save output to dstDir
2653 with suffix specified E.g. onos-diags-suffix.tar.gz
Jon Hall0e240372018-05-02 11:21:57 -07002654 required arguments:
You Wang5df1c6d2018-04-06 18:02:02 -07002655 onosIPs - list of ONOS IPs for collecting diags
2656 dstDir - diags file will be saved under the directory specified
2657 suffix - diags file will be named with the suffix specified
2658 returns:
2659 main.FALSE if there's an error executing the command, and main.TRUE otherwise
2660 """
2661 try:
2662 cmd = "onos-diagnostics"
2663 assert isinstance( onosIPs, list )
2664 for ip in onosIPs:
2665 cmd += " " + str( ip )
2666 self.handle.sendline( cmd )
You Wang5ac7db72018-07-17 11:17:52 -07002667 self.handle.expect( self.prompt, timeout=timeout )
You Wang5df1c6d2018-04-06 18:02:02 -07002668 handle = self.handle.before
2669 main.log.debug( handle )
2670 assert handle is not None, "Error in sendline"
2671 assert "Command not found:" not in handle, handle
2672 assert "Exception:" not in handle, handle
2673 # Rename and move diags file to dstDir from /tmp
2674 if dstDir[ -1: ] != "/":
2675 dstDir += "/"
2676 self.handle.sendline( "mv /tmp/onos-diags.tar.gz " + str( dstDir ) + "onos-diags" + str( suffix ) + ".tar.gz" )
2677 self.handle.expect( self.prompt )
2678 handle = self.handle.before
2679 main.log.debug( handle )
2680 assert handle is not None, "Error in sendline"
2681 assert "No such file or directory" not in handle, handle
2682 return main.TRUE
2683 except AssertionError:
2684 main.log.exception( "{} Error in onos-diagnostics output:".format( self.name ) )
2685 return main.FALSE
2686 except TypeError:
2687 main.log.exception( self.name + ": Object not as expected" )
2688 return main.FALSE
You Wang223faa32018-06-21 10:45:47 -07002689 except pexpect.TIMEOUT:
2690 main.log.exception( self.name + ": TIMEOUT exception found in onosDiagnostics" )
2691 main.log.error( self.name + ": " + self.handle.before )
You Wangb65d2372018-08-17 15:37:59 -07002692 self.exitFromCmd( self.prompt, 100 )
You Wang223faa32018-06-21 10:45:47 -07002693 return main.FALSE
You Wang5df1c6d2018-04-06 18:02:02 -07002694 except pexpect.EOF:
2695 main.log.error( self.name + ": EOF exception found" )
2696 main.log.error( self.name + ": " + self.handle.before )
2697 main.cleanAndExit()
2698 except Exception:
2699 main.log.exception( self.name + ": Uncaught exception!" )
2700 main.cleanAndExit()
Jon Hall0e240372018-05-02 11:21:57 -07002701
2702 def onosPower( self, onosIP, toggle, userName=None ):
2703 """
2704 Run onos-power script to tell the cell warden to simulate a power faulure
2705 for the given container.
2706 required :
2707 onosIP - ONOS node IP
2708 toggle - either "off" or "on", used to indicate whether
2709 the node should be powered off or on
2710 returns:
2711 main.FALSE if there's an error executing the command, and main.TRUE otherwise
2712 """
2713 try:
2714 cmd = "onos-power {} {}".format( onosIP, toggle )
2715 if userName:
2716 cmd += " {}".format( userName )
2717 self.handle.sendline( cmd )
2718 self.handle.expect( self.prompt )
2719 handle = self.handle.before
2720 main.log.debug( handle )
2721 assert handle is not None, "Error in sendline"
2722 assert "Command not found:" not in handle, handle
2723 assert "Exception:" not in handle, handle
2724 assert "usage:" not in handle, handle
2725 return main.TRUE
2726 except AssertionError:
2727 main.log.exception( "{} Error in onos-power output:".format( self.name ) )
2728 return main.FALSE
2729 except TypeError:
2730 main.log.exception( self.name + ": Object not as expected" )
2731 return main.FALSE
2732 except pexpect.EOF:
2733 main.log.error( self.name + ": EOF exception found" )
2734 main.log.error( self.name + ": " + self.handle.before )
2735 main.cleanAndExit()
2736 except Exception:
2737 main.log.exception( self.name + ": Uncaught exception!" )
2738 main.cleanAndExit()
You Wangf9d95be2018-08-01 14:35:37 -07002739
2740 def atomixKill( self, nodeIp ):
2741 """
2742 Calls the command: 'atomix-kill [<node-ip>]'
2743 Kills the Atomix instance running on the specified node
2744 """
2745 try:
2746 self.handle.sendline( "" )
2747 self.handle.expect( self.prompt )
2748 self.handle.sendline( "atomix-kill " + str( nodeIp ) )
2749 i = self.handle.expect( [
2750 self.prompt,
2751 "No\sroute\sto\shost",
2752 "password:",
2753 pexpect.TIMEOUT ], timeout=60 )
2754
2755 if i == 0:
2756 main.log.info( "Atomix instance " + str( nodeIp ) + " was killed" )
2757 return main.TRUE
2758 elif i == 1:
2759 main.log.info( "No route to host" )
2760 return main.FALSE
2761 elif i == 2:
2762 main.log.info( "Passwordless login for host: " + str( nodeIp ) + " not configured" )
2763 return main.FALSE
2764 else:
2765 main.log.info( "Atomix instance was not killed" )
2766 return main.FALSE
2767
2768 except pexpect.EOF:
2769 main.log.error( self.name + ": EOF exception found" )
2770 main.log.error( self.name + ": " + self.handle.before )
2771 main.cleanAndExit()
2772 except Exception:
2773 main.log.exception( self.name + ": Uncaught exception!" )
2774 main.cleanAndExit()
2775
2776 def atomixUninstall( self, nodeIp="" ):
2777 """
2778 Calls the command: 'atomix-uninstall'
2779 Uninstalls Atomix from the designated node, stopping if needed
2780 """
2781 try:
2782 self.handle.sendline( "" )
2783 self.handle.expect( self.prompt, timeout=180 )
2784 self.handle.sendline( "atomix-uninstall " + str( nodeIp ) )
2785 self.handle.expect( self.prompt, timeout=180 )
2786 main.log.info( "Atomix " + nodeIp + " was uninstalled" )
2787 # onos-uninstall command does not return any text
2788 return main.TRUE
2789 except pexpect.TIMEOUT:
2790 main.log.exception( self.name + ": Timeout in atomixUninstall" )
2791 self.handle.send( "\x03" ) # Control-C
2792 self.handle.expect( self.prompt )
2793 return main.FALSE
2794 except pexpect.EOF:
2795 main.log.error( self.name + ": EOF exception found" )
2796 main.log.error( self.name + ": " + self.handle.before )
2797 main.cleanAndExit()
2798 except Exception:
2799 main.log.exception( self.name + ": Uncaught exception!" )
2800 main.cleanAndExit()
2801
2802 def atomixInstall( self, options="", node="" ):
2803 """
2804 Installs Atomix on the designated nodes.
2805 Returns: main.TRUE on success and main.FALSE on failure
2806 """
2807 try:
2808 if options:
2809 self.handle.sendline( "atomix-install " + options + " " + node )
2810 else:
2811 self.handle.sendline( "atomix-install " + node )
2812 self.handle.expect( "atomix-install " )
2813 i = self.handle.expect( [ "Network\sis\sunreachable",
2814 "is already installed",
2815 "saved",
2816 self.prompt,
2817 pexpect.TIMEOUT ], timeout=180 )
2818 if i == 0:
2819 # can't reach ONOS node
Jon Hall3e6edb32018-08-21 16:20:30 -07002820 main.log.warn( self.name + ": Network is unreachable" )
You Wangf9d95be2018-08-01 14:35:37 -07002821 self.handle.expect( self.prompt )
2822 return main.FALSE
2823 elif i == 1:
2824 # same bits are already on Atomix node
Jon Hall3e6edb32018-08-21 16:20:30 -07002825 main.log.info( self.name + ": Atomix is already installed on " + node )
You Wangf9d95be2018-08-01 14:35:37 -07002826 self.handle.expect( self.prompt )
2827 return main.TRUE
Jon Hallb685a1c2018-10-30 15:17:01 -07002828 elif i == 2:
Jon Hall3e6edb32018-08-21 16:20:30 -07002829 main.log.info( self.name + ": Atomix was installed on " + node )
You Wangf9d95be2018-08-01 14:35:37 -07002830 self.handle.expect( self.prompt )
2831 return main.TRUE
Jon Hallb685a1c2018-10-30 15:17:01 -07002832 elif i == 3:
2833 self.handle.sendline( "echo Return code: $?" )
2834 self.handle.expect( "\$\?" )
2835 self.handle.expect( self.prompt )
Jon Hallb685a1c2018-10-30 15:17:01 -07002836 match = re.search( "Return code: (\d+)", self.handle.before )
2837 if match:
2838 exitCode = int( match.group( 1 ) )
2839 else:
2840 # Didn't match pattern
2841 main.log.error( "Could not parse exit code of atomix-install" )
Jon Hall5e1469a2018-11-01 13:55:53 -07002842 main.log.debug( self.handle.before + self.handle.before )
Jon Hallb685a1c2018-10-30 15:17:01 -07002843 return main.FALSE
2844 if exitCode == 0:
2845 return main.TRUE
2846 else:
Jon Hall5e1469a2018-11-01 13:55:53 -07002847 main.log.error( "Unsuccessful exit code of atomix-install" )
2848 main.log.debug( self.handle.before + self.handle.before )
Jon Hallb685a1c2018-10-30 15:17:01 -07002849 return main.FALSE
You Wangf9d95be2018-08-01 14:35:37 -07002850 elif i == 4:
2851 # timeout
Jon Hall3e6edb32018-08-21 16:20:30 -07002852 main.log.info( self.name + ": Installation of Atomix on " + node + " timed out" )
You Wangf9d95be2018-08-01 14:35:37 -07002853 self.handle.expect( self.prompt )
2854 main.log.warn( self.handle.before )
2855 self.handle.send( "\x03" ) # Control-C
2856 self.handle.expect( self.prompt )
2857 return main.FALSE
2858 except pexpect.EOF:
2859 main.log.error( self.name + ": EOF exception found" )
2860 main.log.error( self.name + ": " + self.handle.before )
2861 main.cleanAndExit()
2862 except Exception:
2863 main.log.exception( self.name + ": Uncaught exception!" )
2864 main.cleanAndExit()