blob: 6e4c71d95f9e93ae82c42f7d1515fa6961a8eb14 [file] [log] [blame]
Jon Hall05b2b432014-10-08 19:53:25 -04001#!/usr/bin/env python
andrewonlabe8e56fd2014-10-09 17:12:44 -04002
kelvin8ec71442015-01-15 16:57:00 -08003"""
Jeremy Ronquilloec916a42018-02-02 13:05:57 -08004Copyright 2014 Open Networking Foundation (ONF)
5
kelvin8ec71442015-01-15 16:57:00 -08006This driver interacts with ONOS bench, the OSGi platform
7that configures the ONOS nodes. ( aka ONOS-next )
andrewonlabe8e56fd2014-10-09 17:12:44 -04008
kelvin8ec71442015-01-15 16:57:00 -08009Please follow the coding style demonstrated by existing
andrewonlabe8e56fd2014-10-09 17:12:44 -040010functions and document properly.
11
12If you are a contributor to the driver, please
13list your email here for future contact:
14
15jhall@onlab.us
16andrew@onlab.us
17
18OCT 9 2014
Jeremy Songsterae01bba2016-07-11 15:39:17 -070019Modified 2016 by ON.Lab
20
21Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
22the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
23or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
andrewonlabe8e56fd2014-10-09 17:12:44 -040024
kelvin8ec71442015-01-15 16:57:00 -080025"""
Jon Hall05b2b432014-10-08 19:53:25 -040026import time
Jon Hall6801cda2015-07-15 14:13:45 -070027import types
Jon Hall05b2b432014-10-08 19:53:25 -040028import pexpect
kelvin-onlaba4074292015-07-09 15:19:49 -070029import os
Jon Hall6c44c0b2016-04-20 15:21:00 -070030import re
31import subprocess
Jon Hall05b2b432014-10-08 19:53:25 -040032from drivers.common.clidriver import CLI
33
kelvin8ec71442015-01-15 16:57:00 -080034class OnosDriver( CLI ):
Jon Hall05b2b432014-10-08 19:53:25 -040035
kelvin8ec71442015-01-15 16:57:00 -080036 def __init__( self ):
37 """
38 Initialize client
39 """
Jon Hallefbd9792015-03-05 16:11:36 -080040 self.name = None
41 self.home = None
42 self.handle = None
Jon Hall6c44c0b2016-04-20 15:21:00 -070043 self.nicAddr = None
Devin Limdc78e202017-06-09 18:30:07 -070044 super( OnosDriver, self ).__init__()
kelvin8ec71442015-01-15 16:57:00 -080045
46 def connect( self, **connectargs ):
47 """
Jon Hall05b2b432014-10-08 19:53:25 -040048 Creates ssh handle for ONOS "bench".
kelvin-onlaba4074292015-07-09 15:19:49 -070049 NOTE:
50 The ip_address would come from the topo file using the host tag, the
51 value can be an environment variable as well as a "localhost" to get
52 the ip address needed to ssh to the "bench"
kelvin8ec71442015-01-15 16:57:00 -080053 """
Jon Hall05b2b432014-10-08 19:53:25 -040054 try:
Devin Limdc78e202017-06-09 18:30:07 -070055
Jon Hall05b2b432014-10-08 19:53:25 -040056 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080057 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us3b087132015-03-11 15:00:08 -070058 self.home = "~/onos"
Jon Hall05b2b432014-10-08 19:53:25 -040059 for key in self.options:
60 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080061 self.home = self.options[ 'home' ]
Jon Hall05b2b432014-10-08 19:53:25 -040062 break
Jon Hall274b6642015-02-17 11:57:17 -080063 if self.home is None or self.home == "":
Jon Halle94919c2015-03-23 11:42:57 -070064 self.home = "~/onos"
Jon Hall21270ac2015-02-16 17:59:55 -080065
kelvin8ec71442015-01-15 16:57:00 -080066 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070067
kelvin-onlabc2b79102015-07-14 11:41:20 -070068 # The 'nodes' tag is optional and it is not required in .topo file
kelvin-onlaba4074292015-07-09 15:19:49 -070069 for key in self.options:
70 if key == "nodes":
kelvin-onlabc2b79102015-07-14 11:41:20 -070071 # Maximum number of ONOS nodes to run, if there is any
kelvin-onlaba4074292015-07-09 15:19:49 -070072 self.maxNodes = int( self.options[ 'nodes' ] )
73 break
74 self.maxNodes = None
75
Jeremy Ronquillo82705492017-10-18 14:19:55 -070076 if self.maxNodes is None or self.maxNodes == "":
kelvin-onlabc2b79102015-07-14 11:41:20 -070077 self.maxNodes = 100
kelvin-onlaba4074292015-07-09 15:19:49 -070078
kelvin-onlabc2b79102015-07-14 11:41:20 -070079 # Grabs all OC environment variables based on max number of nodes
kelvin-onlaba4074292015-07-09 15:19:49 -070080 self.onosIps = {} # Dictionary of all possible ONOS ip
81
82 try:
83 if self.maxNodes:
kelvin-onlaba4074292015-07-09 15:19:49 -070084 for i in range( self.maxNodes ):
85 envString = "OC" + str( i + 1 )
kelvin-onlabc2b79102015-07-14 11:41:20 -070086 # If there is no more OC# then break the loop
87 if os.getenv( envString ):
88 self.onosIps[ envString ] = os.getenv( envString )
89 else:
90 self.maxNodes = len( self.onosIps )
91 main.log.info( self.name +
92 ": Created cluster data with " +
93 str( self.maxNodes ) +
94 " maximum number" +
95 " of nodes" )
96 break
kelvin-onlaba4074292015-07-09 15:19:49 -070097
98 if not self.onosIps:
99 main.log.info( "Could not read any environment variable"
100 + " please load a cell file with all" +
101 " onos IP" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700102 self.maxNodes = None
kelvin-onlaba4074292015-07-09 15:19:49 -0700103 else:
104 main.log.info( self.name + ": Found " +
105 str( self.onosIps.values() ) +
106 " ONOS IPs" )
kelvin-onlaba4074292015-07-09 15:19:49 -0700107 except KeyError:
108 main.log.info( "Invalid environment variable" )
109 except Exception as inst:
110 main.log.error( "Uncaught exception: " + str( inst ) )
111
112 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700113 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -0700114 self.ip_address = os.getenv( str( self.ip_address ) )
115 else:
116 main.log.info( self.name +
117 ": Trying to connect to " +
118 self.ip_address )
kelvin-onlaba4074292015-07-09 15:19:49 -0700119 except KeyError:
120 main.log.info( "Invalid host name," +
121 " connecting to local host instead" )
122 self.ip_address = 'localhost'
123 except Exception as inst:
124 main.log.error( "Uncaught exception: " + str( inst ) )
125
kelvin8ec71442015-01-15 16:57:00 -0800126 self.handle = super( OnosDriver, self ).connect(
127 user_name=self.user_name,
kelvin-onlab08679eb2015-01-21 16:11:48 -0800128 ip_address=self.ip_address,
kelvin-onlabd3b64892015-01-20 13:26:24 -0800129 port=self.port,
130 pwd=self.pwd,
131 home=self.home )
Jon Hall05b2b432014-10-08 19:53:25 -0400132 if self.handle:
Jon Hall500ed642019-06-17 18:25:46 +0000133 self.handle.setwinsize( 24, 250 )
Jon Hall0fc0d452015-07-14 09:49:58 -0700134 self.handle.sendline( "cd " + self.home )
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
You Wang5bf49592020-07-08 18:47:46 -07001360 def onosAppInstall( self, nodeIp, oarFile ):
1361 """
1362 Calls the command: 'onos-app nodeIp install! oarFile'
1363 Installs an ONOS application from an oar file
1364 """
1365 try:
1366 cmd = "onos-app " + str( nodeIp ) +" install! " + str(oarFile)
1367 self.handle.sendline( cmd )
1368 self.handle.expect( self.prompt )
1369 handle = self.handle.before
1370 main.log.debug( handle )
1371 assert handle is not None, "Error in sendline"
1372 assert "Command not found:" not in handle, handle
1373 assert "error" not in handle, handle
1374 assert "usage:" not in handle, handle
1375 return main.TRUE
1376 except AssertionError:
1377 main.log.exception( "Error in onos-app output" )
1378 return main.FALSE
1379 except pexpect.TIMEOUT:
1380 main.log.exception( self.name + ": Timeout in onosAppInstall" )
1381 self.handle.send( "\x03" ) # Control-C
1382 self.handle.expect( self.prompt )
1383 return main.FALSE
1384 except pexpect.EOF:
1385 main.log.error( self.name + ": EOF exception found" )
1386 main.log.error( self.name + ": " + self.handle.before )
1387 main.cleanAndExit()
1388 except Exception:
1389 main.log.exception( self.name + ": Uncaught exception!" )
1390 main.cleanAndExit()
1391
kelvin-onlabd3b64892015-01-20 13:26:24 -08001392 def onosRemoveRaftLogs( self ):
kelvin8ec71442015-01-15 16:57:00 -08001393 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001394 Removes Raft / Copy cat files from ONOS to ensure
Jon Hallfcc88622014-11-25 13:09:54 -05001395 a cleaner environment.
1396
andrewonlab19fbdca2014-11-14 12:55:59 -05001397 Description:
Jon Hallfcc88622014-11-25 13:09:54 -05001398 Stops all ONOS defined in the cell,
andrewonlab19fbdca2014-11-14 12:55:59 -05001399 wipes the raft / copycat log files
kelvin8ec71442015-01-15 16:57:00 -08001400 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001401 try:
kelvin8ec71442015-01-15 16:57:00 -08001402 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001403 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -08001404 self.handle.sendline( "onos-remove-raft-logs" )
1405 # Sometimes this command hangs
Devin Limc20e79a2017-06-07 10:29:57 -07001406 i = self.handle.expect( [ self.prompt, pexpect.TIMEOUT ],
kelvin8ec71442015-01-15 16:57:00 -08001407 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001408 if i == 1:
Devin Limc20e79a2017-06-07 10:29:57 -07001409 i = self.handle.expect( [ self.prompt, pexpect.TIMEOUT ],
kelvin8ec71442015-01-15 16:57:00 -08001410 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001411 if i == 1:
1412 return main.FALSE
andrewonlab19fbdca2014-11-14 12:55:59 -05001413 return main.TRUE
andrewonlab19fbdca2014-11-14 12:55:59 -05001414 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001415 main.log.error( self.name + ": EOF exception found" )
1416 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001417 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001418 except Exception:
1419 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001420 main.cleanAndExit()
Jon Hallfcc88622014-11-25 13:09:54 -05001421
kelvin-onlabd3b64892015-01-20 13:26:24 -08001422 def onosStartNetwork( self, mntopo ):
kelvin8ec71442015-01-15 16:57:00 -08001423 """
1424 Calls the command 'onos-start-network [ <mininet-topo> ]
1425 "remotely starts the specified topology on the cell's
andrewonlab94282092014-10-10 13:00:11 -04001426 mininet machine against all controllers configured in the
kelvin8ec71442015-01-15 16:57:00 -08001427 cell."
andrewonlab94282092014-10-10 13:00:11 -04001428 * Specify mininet topology file name for mntopo
1429 * Topo files should be placed at:
1430 ~/<your-onos-directory>/tools/test/topos
kelvin8ec71442015-01-15 16:57:00 -08001431
andrewonlab94282092014-10-10 13:00:11 -04001432 NOTE: This function will take you to the mininet prompt
kelvin8ec71442015-01-15 16:57:00 -08001433 """
andrewonlab94282092014-10-10 13:00:11 -04001434 try:
1435 if not mntopo:
kelvin8ec71442015-01-15 16:57:00 -08001436 main.log.error( "You must specify a topo file to execute" )
andrewonlab94282092014-10-10 13:00:11 -04001437 return main.FALSE
andrewonlab94282092014-10-10 13:00:11 -04001438
kelvin8ec71442015-01-15 16:57:00 -08001439 mntopo = str( mntopo )
1440 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001441 self.handle.expect( self.prompt )
andrewonlab94282092014-10-10 13:00:11 -04001442
kelvin8ec71442015-01-15 16:57:00 -08001443 self.handle.sendline( "onos-start-network " + mntopo )
1444 self.handle.expect( "mininet>" )
1445 main.log.info( "Network started, entered mininet prompt" )
1446
1447 # TODO: Think about whether return is necessary or not
andrewonlab94282092014-10-10 13:00:11 -04001448
1449 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001450 main.log.error( self.name + ": EOF exception found" )
1451 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001452 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001453 except Exception:
1454 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001455 main.cleanAndExit()
andrewonlab94282092014-10-10 13:00:11 -04001456
Jeremy Songster14c13572016-04-21 17:34:03 -07001457 def isup( self, node="", timeout=240 ):
kelvin8ec71442015-01-15 16:57:00 -08001458 """
1459 Run's onos-wait-for-start which only returns once ONOS is at run
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001460 level 100(ready for use)
andrewonlab8d0d7d72014-10-09 16:33:15 -04001461
Jon Hall7993bfc2014-10-09 16:30:14 -04001462 Returns: main.TRUE if ONOS is running and main.FALSE on timeout
kelvin8ec71442015-01-15 16:57:00 -08001463 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001464 try:
Jon Hall3b489db2015-10-05 14:38:37 -07001465 self.handle.sendline( "onos-wait-for-start " + node )
1466 self.handle.expect( "onos-wait-for-start" )
kelvin8ec71442015-01-15 16:57:00 -08001467 # NOTE: this timeout is arbitrary"
Jon Hallcababf72018-02-05 12:05:19 -08001468 i = self.handle.expect( [ self.prompt, pexpect.TIMEOUT, "Password:" ], timeout )
Jon Hall7993bfc2014-10-09 16:30:14 -04001469 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001470 main.log.info( self.name + ": " + node + " is up" )
You Wangb65f2e92018-12-21 11:31:34 -08001471 # FIXME: for now we sleep 5s for CLI to become ready
1472 time.sleep( 5 )
Jon Hall7993bfc2014-10-09 16:30:14 -04001473 return main.TRUE
Jon Hallcababf72018-02-05 12:05:19 -08001474 elif i == 1 or i == 2:
kelvin8ec71442015-01-15 16:57:00 -08001475 # NOTE: since this function won't return until ONOS is ready,
Jon Hall7993bfc2014-10-09 16:30:14 -04001476 # we will kill it on timeout
Jon Hallcababf72018-02-05 12:05:19 -08001477 if i == 1:
Jon Hall3e6edb32018-08-21 16:20:30 -07001478 main.log.error( "{}: ONOS {} has not started yet".format( self.name, node ) )
Jon Hallcababf72018-02-05 12:05:19 -08001479 elif i == 2:
Jon Hall3e6edb32018-08-21 16:20:30 -07001480 main.log.error( "{}: Cannot login to ONOS CLI {}, try using onos-secure-ssh".format( self.name, node ) )
kelvin8ec71442015-01-15 16:57:00 -08001481 self.handle.send( "\x03" ) # Control-C
Devin Limc20e79a2017-06-07 10:29:57 -07001482 self.handle.expect( self.prompt )
Jon Hall7993bfc2014-10-09 16:30:14 -04001483 return main.FALSE
1484 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001485 main.log.error( self.name + ": EOF exception found" )
1486 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001487 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001488 except Exception:
1489 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001490 main.cleanAndExit()
andrewonlab05e362f2014-10-10 00:40:57 -04001491
Devin Lim142b5342017-07-20 15:22:39 -07001492 def preventAutoRespawn( self ):
1493 """
1494 Description:
1495 This will prevent ONOSservice to automatically
1496 respawn.
1497 """
1498 try:
1499 self.handle.sendline( "sed -i -e 's/^respawn$/#respawn/g' tools/package/init/onos.conf" )
1500 self.handle.expect( "\$" ) # $ from the command
1501 self.handle.sendline( "sed -i -e 's/^Restart=always/Restart=no/g' tools/package/init/onos.service" )
1502 self.handle.expect( "\$" ) # $ from the command
1503 self.handle.expect( "\$" ) # $ from the prompt
1504 except pexpect.EOF:
1505 main.log.error( self.name + ": EOF exception found" )
1506 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001507 main.cleanAndExit()
Devin Lim142b5342017-07-20 15:22:39 -07001508 except Exception:
1509 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001510 main.cleanAndExit()
Devin Lim142b5342017-07-20 15:22:39 -07001511
kelvin-onlabd3b64892015-01-20 13:26:24 -08001512 def pushTestIntentsShell(
1513 self,
1514 dpidSrc,
1515 dpidDst,
1516 numIntents,
1517 dirFile,
1518 onosIp,
1519 numMult="",
1520 appId="",
1521 report=True,
1522 options="" ):
kelvin8ec71442015-01-15 16:57:00 -08001523 """
andrewonlabb66dfa12014-12-02 15:51:10 -05001524 Description:
kelvin8ec71442015-01-15 16:57:00 -08001525 Use the linux prompt to push test intents to
andrewonlabb66dfa12014-12-02 15:51:10 -05001526 better parallelize the results than the CLI
1527 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001528 * dpidSrc: specify source dpid
1529 * dpidDst: specify destination dpid
1530 * numIntents: specify number of intents to push
1531 * dirFile: specify directory and file name to save
andrewonlabb66dfa12014-12-02 15:51:10 -05001532 results
kelvin-onlabd3b64892015-01-20 13:26:24 -08001533 * onosIp: specify the IP of ONOS to install on
kelvin8ec71442015-01-15 16:57:00 -08001534 NOTE:
andrewonlabb66dfa12014-12-02 15:51:10 -05001535 You must invoke this command at linux shell prompt
kelvin8ec71442015-01-15 16:57:00 -08001536 """
1537 try:
1538 # Create the string to sendline
andrewonlabaedc8332014-12-04 12:43:03 -05001539 if options:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001540 baseCmd = "onos " + str( onosIp ) + " push-test-intents " +\
kelvin8ec71442015-01-15 16:57:00 -08001541 options + " "
andrewonlabaedc8332014-12-04 12:43:03 -05001542 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001543 baseCmd = "onos " + str( onosIp ) + " push-test-intents "
kelvin8ec71442015-01-15 16:57:00 -08001544
kelvin-onlabd3b64892015-01-20 13:26:24 -08001545 addDpid = baseCmd + str( dpidSrc ) + " " + str( dpidDst )
1546 if not numMult:
1547 addIntents = addDpid + " " + str( numIntents )
1548 elif numMult:
1549 addIntents = addDpid + " " + str( numIntents ) + " " +\
1550 str( numMult )
1551 if appId:
1552 addApp = addIntents + " " + str( appId )
andrewonlabb66dfa12014-12-02 15:51:10 -05001553 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001554 addApp = addIntents
andrewonlabb66dfa12014-12-02 15:51:10 -05001555
andrewonlabaedc8332014-12-04 12:43:03 -05001556 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001557 sendCmd = addApp + " > " + str( dirFile ) + " &"
andrewonlabaedc8332014-12-04 12:43:03 -05001558 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001559 sendCmd = addApp + " &"
1560 main.log.info( "Send cmd: " + sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001561
kelvin-onlabd3b64892015-01-20 13:26:24 -08001562 self.handle.sendline( sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001563
1564 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001565 main.log.error( self.name + ": EOF exception found" )
1566 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001567 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001568 except Exception:
1569 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001570 main.cleanAndExit()
andrewonlab05e362f2014-10-10 00:40:57 -04001571
kelvin-onlabd3b64892015-01-20 13:26:24 -08001572 def tsharkPcap( self, interface, dirFile ):
kelvin8ec71442015-01-15 16:57:00 -08001573 """
andrewonlab970399c2014-11-07 13:09:32 -05001574 Capture all packet activity and store in specified
1575 directory/file
1576
1577 Required:
1578 * interface: interface to capture
1579 * dir: directory/filename to store pcap
kelvin8ec71442015-01-15 16:57:00 -08001580 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001581 try:
1582 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001583 self.handle.expect( self.prompt )
andrewonlab970399c2014-11-07 13:09:32 -05001584
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001585 self.handle.sendline( "tshark -i " + str( interface ) + " -t e -w " + str( dirFile ) + " &" )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001586 self.handle.sendline( "\n" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001587 self.handle.expect( "Capturing on" )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001588 self.handle.sendline( "\n" )
Devin Limc20e79a2017-06-07 10:29:57 -07001589 self.handle.expect( self.prompt )
andrewonlab970399c2014-11-07 13:09:32 -05001590
Jon Hallfebb1c72015-03-05 13:30:09 -08001591 main.log.info( "Tshark started capturing files on " +
1592 str( interface ) + " and saving to directory: " +
1593 str( dirFile ) )
1594 except pexpect.EOF:
1595 main.log.error( self.name + ": EOF exception found" )
1596 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001597 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001598 except Exception:
1599 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001600 main.cleanAndExit()
Shreya Shaha73aaad2014-10-27 18:03:09 -04001601
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001602 def onosTopoCfg( self, onosIp, jsonFile ):
kelvin8ec71442015-01-15 16:57:00 -08001603 """
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001604 Description:
1605 Execute onos-topo-cfg command
1606 Required:
1607 onosIp - IP of the onos node you want to send the json to
1608 jsonFile - File path of the json file
1609 Return:
1610 Returns main.TRUE if the command is successfull; Returns
1611 main.FALSE if there was an error
kelvin8ec71442015-01-15 16:57:00 -08001612 """
shahshreyae6c7cf42014-11-26 16:39:01 -08001613 try:
kelvin8ec71442015-01-15 16:57:00 -08001614 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001615 self.handle.expect( self.prompt )
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001616 cmd = "onos-topo-cfg "
1617 self.handle.sendline( cmd + str( onosIp ) + " " + jsonFile )
1618 handle = self.handle.before
1619 print handle
1620 if "Error" in handle:
1621 main.log.error( self.name + ": " + self.handle.before )
1622 return main.FALSE
1623 else:
Devin Limc20e79a2017-06-07 10:29:57 -07001624 self.handle.expect( self.prompt )
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001625 return main.TRUE
1626
Jon Hallfebb1c72015-03-05 13:30:09 -08001627 except pexpect.EOF:
1628 main.log.error( self.name + ": EOF exception found" )
1629 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001630 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001631 except Exception:
1632 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001633 main.cleanAndExit()
kelvin8ec71442015-01-15 16:57:00 -08001634
jenkins1e99e7b2015-04-02 18:15:39 -07001635 def tsharkGrep( self, grep, directory, interface='eth0', grepOptions='' ):
kelvin8ec71442015-01-15 16:57:00 -08001636 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001637 Required:
kelvin8ec71442015-01-15 16:57:00 -08001638 * grep string
andrewonlabba44bcf2014-10-16 16:54:41 -04001639 * directory to store results
1640 Optional:
1641 * interface - default: eth0
Jon Hall4ba53f02015-07-29 13:07:41 -07001642 * grepOptions - options for grep
andrewonlabba44bcf2014-10-16 16:54:41 -04001643 Description:
1644 Uses tshark command to grep specific group of packets
1645 and stores the results to specified directory.
kelvin8ec71442015-01-15 16:57:00 -08001646 The timestamp is hardcoded to be in epoch
1647 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001648 try:
1649 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001650 self.handle.expect( self.prompt )
Jon Hallfebb1c72015-03-05 13:30:09 -08001651 self.handle.sendline( "" )
jenkins1e99e7b2015-04-02 18:15:39 -07001652 if grepOptions:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001653 grepStr = "grep " + str( grepOptions )
jenkins1e99e7b2015-04-02 18:15:39 -07001654 else:
1655 grepStr = "grep"
Jon Hall4ba53f02015-07-29 13:07:41 -07001656
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001657 cmd = (
1658 "sudo tshark -i " +
Jon Hallfebb1c72015-03-05 13:30:09 -08001659 str( interface ) +
jenkins1e99e7b2015-04-02 18:15:39 -07001660 " -t e | " +
1661 grepStr + " --line-buffered \"" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001662 str( grep ) +
Jon Hallfebb1c72015-03-05 13:30:09 -08001663 "\" >" +
1664 directory +
1665 " &" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001666 self.handle.sendline( cmd )
1667 main.log.info( cmd )
Jon Hallfebb1c72015-03-05 13:30:09 -08001668 self.handle.expect( "Capturing on" )
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001669 self.handle.sendline( "\n" )
Devin Limc20e79a2017-06-07 10:29:57 -07001670 self.handle.expect( self.prompt )
Jon Hallfebb1c72015-03-05 13:30:09 -08001671 except pexpect.EOF:
1672 main.log.error( self.name + ": EOF exception found" )
1673 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001674 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001675 except Exception:
1676 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001677 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001678
kelvin-onlabd3b64892015-01-20 13:26:24 -08001679 def tsharkStop( self ):
kelvin8ec71442015-01-15 16:57:00 -08001680 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001681 Removes wireshark files from /tmp and kills all tshark processes
kelvin8ec71442015-01-15 16:57:00 -08001682 """
1683 # Remove all pcap from previous captures
Jon Hallfebb1c72015-03-05 13:30:09 -08001684 try:
1685 self.execute( cmd="sudo rm /tmp/wireshark*" )
1686 self.handle.sendline( "" )
Jon Hallefbd9792015-03-05 16:11:36 -08001687 self.handle.sendline( "sudo kill -9 `ps -ef | grep \"tshark -i\"" +
1688 " | grep -v grep | awk '{print $2}'`" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001689 self.handle.sendline( "" )
1690 main.log.info( "Tshark stopped" )
1691 except pexpect.EOF:
1692 main.log.error( self.name + ": EOF exception found" )
1693 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001694 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001695 except Exception:
1696 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001697 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001698
kelvin8ec71442015-01-15 16:57:00 -08001699 def ptpd( self, args ):
1700 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001701 Initiate ptp with user-specified args.
1702 Required:
1703 * args: specify string of args after command
1704 'sudo ptpd'
kelvin8ec71442015-01-15 16:57:00 -08001705 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001706 try:
kelvin8ec71442015-01-15 16:57:00 -08001707 self.handle.sendline( "sudo ptpd " + str( args ) )
1708 i = self.handle.expect( [
andrewonlab0c38a4a2014-10-28 18:35:35 -04001709 "Multiple",
1710 "Error",
Devin Limc20e79a2017-06-07 10:29:57 -07001711 self.prompt ] )
1712 self.handle.expect( self.prompt )
andrewonlabba44bcf2014-10-16 16:54:41 -04001713
andrewonlab0c38a4a2014-10-28 18:35:35 -04001714 if i == 0:
1715 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001716 main.log.info( "ptpd returned an error: " +
1717 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001718 return handle
1719 elif i == 1:
1720 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001721 main.log.error( "ptpd returned an error: " +
1722 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001723 return handle
1724 else:
1725 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -08001726
andrewonlab0c38a4a2014-10-28 18:35:35 -04001727 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001728 main.log.error( self.name + ": EOF exception found" )
1729 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001730 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001731 except Exception:
1732 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001733 main.cleanAndExit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001734
You Wang54b1d672018-06-11 16:44:13 -07001735 def dumpONOSCmd( self, ONOSIp, CMD, destDir, filename, options="", timeout=60 ):
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001736 """
Pier50f0bc62016-09-07 17:53:40 -07001737 Dump Cmd to a desired directory.
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001738 For debugging purposes, you may want to use
Pier50f0bc62016-09-07 17:53:40 -07001739 this function to capture Cmd at a given point in time.
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001740 Localtime will be attached to the filename
1741
1742 Required:
1743 * ONOSIp: the IP of the target ONOS instance
Pier50f0bc62016-09-07 17:53:40 -07001744 * CMD: the command to dump;
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001745 * destDir: specify directory to copy to.
1746 ex ) /tmp/
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001747 * fileName: Name of the file
You Wang54b1d672018-06-11 16:44:13 -07001748 Optional:
Pier50f0bc62016-09-07 17:53:40 -07001749 * options: Options for ONOS command
You Wang54b1d672018-06-11 16:44:13 -07001750 * timeout: pexpect timeout for running the ONOS command
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001751 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001752
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001753 localtime = time.strftime( '%x %X' )
1754 localtime = localtime.replace( "/", "" )
1755 localtime = localtime.replace( " ", "_" )
1756 localtime = localtime.replace( ":", "" )
1757 if destDir[ -1: ] != "/":
1758 destDir += "/"
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001759 cmd = CMD + " " + options + " > " + str( destDir ) + str( filename ) + localtime
You Wang54b1d672018-06-11 16:44:13 -07001760 return self.onosCli( ONOSIp, cmd, timeout=timeout )
Flavio Castrob7718952016-05-18 08:53:41 -07001761
kelvin-onlabd3b64892015-01-20 13:26:24 -08001762 def cpLogsToDir( self, logToCopy,
Jon Hallefbd9792015-03-05 16:11:36 -08001763 destDir, copyFileName="" ):
kelvin8ec71442015-01-15 16:57:00 -08001764 """
1765 Copies logs to a desired directory.
andrewonlab5d7a8f32014-11-10 13:07:56 -05001766 Current implementation of ONOS deletes its karaf
1767 logs on every iteration. For debugging purposes,
kelvin8ec71442015-01-15 16:57:00 -08001768 you may want to use this function to capture
1769 certain karaf logs. ( or any other logs if needed )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001770 Localtime will be attached to the filename
1771
1772 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001773 * logToCopy: specify directory and log name to
andrewonlab5d7a8f32014-11-10 13:07:56 -05001774 copy.
kelvin8ec71442015-01-15 16:57:00 -08001775 ex ) /opt/onos/log/karaf.log.1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001776 For copying multiple files, leave copyFileName
1777 empty and only specify destDir -
kelvin8ec71442015-01-15 16:57:00 -08001778 ex ) /opt/onos/log/karaf*
kelvin-onlabd3b64892015-01-20 13:26:24 -08001779 * destDir: specify directory to copy to.
kelvin8ec71442015-01-15 16:57:00 -08001780 ex ) /tmp/
1781 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001782 * copyFileName: If you want to rename the log
1783 file, specify copyFileName. This will not work
andrewonlab5d7a8f32014-11-10 13:07:56 -05001784 with multiple file copying
kelvin8ec71442015-01-15 16:57:00 -08001785 """
andrewonlab5d7a8f32014-11-10 13:07:56 -05001786 try:
Flavio Castro09ab59d2016-05-25 17:01:35 -07001787 localtime = time.strftime( '%H %M' )
kelvin8ec71442015-01-15 16:57:00 -08001788 localtime = localtime.replace( "/", "" )
1789 localtime = localtime.replace( " ", "_" )
1790 localtime = localtime.replace( ":", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001791 if destDir[ -1: ] != "/":
1792 destDir += "/"
andrewonlab5d7a8f32014-11-10 13:07:56 -05001793
kelvin-onlabd3b64892015-01-20 13:26:24 -08001794 if copyFileName:
Jon Hallfebb1c72015-03-05 13:30:09 -08001795 self.handle.sendline( "cp " + str( logToCopy ) + " " +
1796 str( destDir ) + str( copyFileName ) +
1797 localtime )
kelvin8ec71442015-01-15 16:57:00 -08001798 self.handle.expect( "cp" )
Devin Limc20e79a2017-06-07 10:29:57 -07001799 self.handle.expect( self.prompt )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001800 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001801 self.handle.sendline( "cp " + str( logToCopy ) +
1802 " " + str( destDir ) )
kelvin8ec71442015-01-15 16:57:00 -08001803 self.handle.expect( "cp" )
Devin Limc20e79a2017-06-07 10:29:57 -07001804 self.handle.expect( self.prompt )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001805
kelvin8ec71442015-01-15 16:57:00 -08001806 return self.handle.before
1807
1808 except pexpect.EOF:
1809 main.log.error( "Copying files failed" )
1810 main.log.error( self.name + ": EOF exception found" )
1811 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001812 except Exception:
1813 main.log.exception( "Copying files failed" )
1814
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001815 def checkLogs( self, onosIp, restart=False ):
kelvin8ec71442015-01-15 16:57:00 -08001816 """
Jon Hall94fd0472014-12-08 11:52:42 -08001817 runs onos-check-logs on the given onos node
Jon Hall80daded2015-05-27 16:07:00 -07001818 If restart is True, use the old version of onos-check-logs which
1819 does not print the full stacktrace, but shows the entire log file,
1820 including across restarts
Jon Hall94fd0472014-12-08 11:52:42 -08001821 returns the response
kelvin8ec71442015-01-15 16:57:00 -08001822 """
Jon Hall94fd0472014-12-08 11:52:42 -08001823 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001824 cmd = "onos-check-logs " + str( onosIp )
Jon Hall16b72c42015-05-20 10:23:36 -07001825 if restart:
1826 cmd += " old"
kelvin8ec71442015-01-15 16:57:00 -08001827 self.handle.sendline( cmd )
1828 self.handle.expect( cmd )
Devin Limdc78e202017-06-09 18:30:07 -07001829 self.handle.expect( self.prompt + " " )
Jon Hall94fd0472014-12-08 11:52:42 -08001830 response = self.handle.before
1831 return response
1832 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001833 main.log.error( "Lost ssh connection" )
1834 main.log.error( self.name + ": EOF exception found" )
1835 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001836 except Exception:
1837 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001838 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001839
kelvin-onlabd3b64892015-01-20 13:26:24 -08001840 def onosStatus( self, node="" ):
kelvin8ec71442015-01-15 16:57:00 -08001841 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001842 Calls onos command: 'onos-service [<node-ip>] status'
kelvin8ec71442015-01-15 16:57:00 -08001843 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001844 try:
kelvin8ec71442015-01-15 16:57:00 -08001845 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001846 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -08001847 self.handle.sendline( "onos-service " + str( node ) +
1848 " status" )
1849 i = self.handle.expect( [
You Wangef1e6572016-03-08 12:53:18 -08001850 "start/running",
You Wang7bd83062016-03-01 11:50:00 -08001851 "Running ...",
You Wangef1e6572016-03-08 12:53:18 -08001852 "stop/waiting",
You Wang7bd83062016-03-01 11:50:00 -08001853 "Not Running ...",
kelvin8ec71442015-01-15 16:57:00 -08001854 pexpect.TIMEOUT ], timeout=120 )
YPZhangfebf7302016-05-24 16:45:56 -07001855 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001856 self.handle.expect( self.prompt )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001857
You Wangef1e6572016-03-08 12:53:18 -08001858 if i == 0 or i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001859 main.log.info( "ONOS is running" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001860 return main.TRUE
You Wangef1e6572016-03-08 12:53:18 -08001861 elif i == 2 or i == 3:
kelvin8ec71442015-01-15 16:57:00 -08001862 main.log.info( "ONOS is stopped" )
kelvin8ec71442015-01-15 16:57:00 -08001863 main.log.error( "ONOS service failed to check the status" )
Devin Lim44075962017-08-11 10:56:37 -07001864
1865 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001866 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001867 main.log.error( self.name + ": EOF exception found" )
1868 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001869 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001870 except Exception:
1871 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001872 main.cleanAndExit()
Jon Hall21270ac2015-02-16 17:59:55 -08001873
Jon Hall63604932015-02-26 17:09:50 -08001874 def setIpTables( self, ip, port='', action='add', packet_type='',
1875 direction='INPUT', rule='DROP', states=True ):
Jon Hallefbd9792015-03-05 16:11:36 -08001876 """
Jon Hall21270ac2015-02-16 17:59:55 -08001877 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001878 add or remove iptables rule to DROP (default) packets from
Jon Hall21270ac2015-02-16 17:59:55 -08001879 specific IP and PORT
1880 Usage:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001881 * specify action ('add' or 'remove')
Jon Hall21270ac2015-02-16 17:59:55 -08001882 when removing, pass in the same argument as you would add. It will
1883 delete that specific rule.
1884 * specify the ip to block
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001885 * specify the destination port to block (defaults to all ports)
1886 * optional packet type to block (default tcp)
1887 * optional iptables rule (default DROP)
1888 * optional direction to block (default 'INPUT')
Jon Hall63604932015-02-26 17:09:50 -08001889 * States boolean toggles adding all supported tcp states to the
1890 firewall rule
Jon Hall21270ac2015-02-16 17:59:55 -08001891 Returns:
1892 main.TRUE on success or
1893 main.FALSE if given invalid input or
1894 main.ERROR if there is an error in response from iptables
1895 WARNING:
1896 * This function uses root privilege iptables command which may result
1897 in unwanted network errors. USE WITH CAUTION
Jon Hallefbd9792015-03-05 16:11:36 -08001898 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001899
Jon Hall21270ac2015-02-16 17:59:55 -08001900 # NOTE*********
1901 # The strict checking methods of this driver function is intentional
1902 # to discourage any misuse or error of iptables, which can cause
1903 # severe network errors
1904 # *************
1905
1906 # NOTE: Sleep needed to give some time for rule to be added and
1907 # registered to the instance. If you are calling this function
1908 # multiple times this sleep will prevent any errors.
1909 # DO NOT REMOVE
Jon Hall63604932015-02-26 17:09:50 -08001910 # time.sleep( 5 )
Jon Hall21270ac2015-02-16 17:59:55 -08001911 try:
1912 # input validation
1913 action_type = action.lower()
1914 rule = rule.upper()
1915 direction = direction.upper()
1916 if action_type != 'add' and action_type != 'remove':
1917 main.log.error( "Invalid action type. Use 'add' or "
1918 "'remove' table rule" )
1919 if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
1920 # NOTE Currently only supports rules DROP, ACCEPT, and LOG
1921 main.log.error( "Invalid rule. Valid rules are 'DROP' or "
1922 "'ACCEPT' or 'LOG' only." )
1923 if direction != 'INPUT' and direction != 'OUTPUT':
1924 # NOTE currently only supports rules INPUT and OUPTUT
1925 main.log.error( "Invalid rule. Valid directions are"
1926 " 'OUTPUT' or 'INPUT'" )
1927 return main.FALSE
1928 return main.FALSE
1929 return main.FALSE
1930 if action_type == 'add':
1931 # -A is the 'append' action of iptables
1932 actionFlag = '-A'
1933 elif action_type == 'remove':
1934 # -D is the 'delete' rule of iptables
1935 actionFlag = '-D'
1936 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001937 self.handle.expect( self.prompt )
Jon Hall21270ac2015-02-16 17:59:55 -08001938 cmd = "sudo iptables " + actionFlag + " " +\
1939 direction +\
Jon Hall21270ac2015-02-16 17:59:55 -08001940 " -s " + str( ip )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001941 # " -p " + str( packet_type ) +\
Jon Hall63604932015-02-26 17:09:50 -08001942 if packet_type:
1943 cmd += " -p " + str( packet_type )
Jon Hall21270ac2015-02-16 17:59:55 -08001944 if port:
1945 cmd += " --dport " + str( port )
Jon Hall63604932015-02-26 17:09:50 -08001946 if states:
1947 cmd += " -m state --state="
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001948 # FIXME- Allow user to configure which states to block
Jon Hall63604932015-02-26 17:09:50 -08001949 cmd += "INVALID,ESTABLISHED,NEW,RELATED,UNTRACKED"
Jon Hall21270ac2015-02-16 17:59:55 -08001950 cmd += " -j " + str( rule )
1951
1952 self.handle.sendline( cmd )
Devin Limc20e79a2017-06-07 10:29:57 -07001953 self.handle.expect( self.prompt )
Jon Hall21270ac2015-02-16 17:59:55 -08001954 main.log.warn( self.handle.before )
1955
1956 info_string = "On " + str( self.name )
1957 info_string += " " + str( action_type )
1958 info_string += " iptable rule [ "
1959 info_string += " IP: " + str( ip )
1960 info_string += " Port: " + str( port )
1961 info_string += " Rule: " + str( rule )
1962 info_string += " Direction: " + str( direction ) + " ]"
1963 main.log.info( info_string )
1964 return main.TRUE
1965 except pexpect.TIMEOUT:
1966 main.log.exception( self.name + ": Timeout exception in "
1967 "setIpTables function" )
You Wang141b43b2018-06-26 16:50:18 -07001968 self.handle.send( "\x03" ) # Control-C
1969 self.handle.expect( self.prompt )
Jon Hall21270ac2015-02-16 17:59:55 -08001970 return main.ERROR
1971 except pexpect.EOF:
1972 main.log.error( self.name + ": EOF exception found" )
1973 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001974 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001975 except Exception:
1976 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001977 main.cleanAndExit()
Jon Hall21270ac2015-02-16 17:59:55 -08001978
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001979 def detailed_status( self, log_filename ):
Jon Hallefbd9792015-03-05 16:11:36 -08001980 """
Jon Hall0468b042015-02-19 19:08:21 -08001981 This method is used by STS to check the status of the controller
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001982 Reports RUNNING, STARTING, STOPPED, FROZEN, ERROR (and reason)
Jon Hallefbd9792015-03-05 16:11:36 -08001983 """
Jon Hall0468b042015-02-19 19:08:21 -08001984 import re
1985 try:
1986 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001987 self.handle.expect( self.prompt )
Jon Hall0468b042015-02-19 19:08:21 -08001988 self.handle.sendline( "cd " + self.home )
Devin Limc20e79a2017-06-07 10:29:57 -07001989 self.handle.expect( self.prompt )
Jon Hall0468b042015-02-19 19:08:21 -08001990 self.handle.sendline( "service onos status" )
Devin Limc20e79a2017-06-07 10:29:57 -07001991 self.handle.expect( self.prompt )
Jon Hall0468b042015-02-19 19:08:21 -08001992 response = self.handle.before
1993 if re.search( "onos start/running", response ):
1994 # onos start/running, process 10457
1995 return 'RUNNING'
1996 # FIXME: Implement this case
1997 # elif re.search( pattern, response ):
1998 # return 'STARTING'
1999 elif re.search( "onos stop/", response ):
2000 # onos stop/waiting
2001 # FIXME handle this differently?: onos stop/pre-stop
2002 return 'STOPPED'
2003 # FIXME: Implement this case
2004 # elif re.search( pattern, response ):
2005 # return 'FROZEN'
2006 else:
2007 main.log.warn( self.name +
Jon Hallefbd9792015-03-05 16:11:36 -08002008 " WARNING: status received unknown response" )
Jon Hall0468b042015-02-19 19:08:21 -08002009 main.log.warn( response )
2010 return 'ERROR', "Unknown response: %s" % response
2011 except pexpect.TIMEOUT:
2012 main.log.exception( self.name + ": Timeout exception in "
2013 "setIpTables function" )
You Wang141b43b2018-06-26 16:50:18 -07002014 self.handle.send( "\x03" ) # Control-C
2015 self.handle.expect( self.prompt )
Jon Hall0468b042015-02-19 19:08:21 -08002016 return 'ERROR', "Pexpect Timeout"
2017 except pexpect.EOF:
2018 main.log.error( self.name + ": EOF exception found" )
2019 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002020 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002021 except Exception:
2022 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002023 main.cleanAndExit()
Jon Hall0468b042015-02-19 19:08:21 -08002024
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002025 def createLinkGraphFile( self, benchIp, ONOSIpList, deviceCount ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002026 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07002027 Create/formats the LinkGraph.cfg file based on arguments
2028 -only creates a linear topology and connects islands
2029 -evenly distributes devices
andrew@onlab.us3b087132015-03-11 15:00:08 -07002030 -must be called by ONOSbench
2031
Jon Hall4ba53f02015-07-29 13:07:41 -07002032 ONOSIpList - list of all of the node IPs to be used
2033
2034 deviceCount - number of switches to be assigned
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002035 '''
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002036 main.log.info( "Creating link graph configuration file." )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002037 linkGraphPath = self.home + "/tools/package/etc/linkGraph.cfg"
Jon Hall4ba53f02015-07-29 13:07:41 -07002038 tempFile = "/tmp/linkGraph.cfg"
andrew@onlab.us3b087132015-03-11 15:00:08 -07002039
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002040 linkGraph = open( tempFile, 'w+' )
2041 linkGraph.write( "# NullLinkProvider topology description (config file).\n" )
2042 linkGraph.write( "# The NodeId is only added if the destination is another node's device.\n" )
2043 linkGraph.write( "# Bugs: Comments cannot be appended to a line to be read.\n" )
Jon Hall4ba53f02015-07-29 13:07:41 -07002044
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002045 clusterCount = len( ONOSIpList )
Jon Hall4ba53f02015-07-29 13:07:41 -07002046
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002047 if isinstance( deviceCount, int ) or isinstance( deviceCount, str ):
2048 deviceCount = int( deviceCount )
2049 switchList = [ 0 ]*( clusterCount+1 )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002050 baselineSwitchCount = deviceCount/clusterCount
Jon Hall4ba53f02015-07-29 13:07:41 -07002051
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002052 for node in range( 1, clusterCount + 1 ):
2053 switchList[ node ] = baselineSwitchCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07002054
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002055 for node in range( 1, ( deviceCount % clusterCount )+1 ):
2056 switchList[ node ] += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07002057
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002058 if isinstance( deviceCount, list ):
2059 main.log.info( "Using provided device distribution" )
2060 switchList = [ 0 ]
andrew@onlab.us3b087132015-03-11 15:00:08 -07002061 for i in deviceCount:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002062 switchList.append( int( i ) )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002063
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002064 tempList = [ '0' ]
2065 tempList.extend( ONOSIpList )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002066 ONOSIpList = tempList
2067
2068 myPort = 6
2069 lastSwitch = 0
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002070 for node in range( 1, clusterCount+1 ):
2071 if switchList[ node ] == 0:
andrew@onlab.us3b087132015-03-11 15:00:08 -07002072 continue
2073
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002074 linkGraph.write( "graph " + ONOSIpList[ node ] + " {\n" )
Jon Hall4ba53f02015-07-29 13:07:41 -07002075
andrew@onlab.us3b087132015-03-11 15:00:08 -07002076 if node > 1:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002077 # connect to last device on previous node
2078 line = ( "\t0:5 -> " + str( lastSwitch ) + ":6:" + lastIp + "\n" ) # ONOSIpList[node-1]
2079 linkGraph.write( line )
Jon Hall4ba53f02015-07-29 13:07:41 -07002080
2081 lastSwitch = 0
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002082 for switch in range( 0, switchList[ node ]-1 ):
andrew@onlab.us3b087132015-03-11 15:00:08 -07002083 line = ""
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002084 line = ( "\t" + str( switch ) + ":" + str( myPort ) )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002085 line += " -- "
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002086 line += ( str( switch+1 ) + ":" + str( myPort-1 ) + "\n" )
2087 linkGraph.write( line )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002088 lastSwitch = switch+1
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002089 lastIp = ONOSIpList[ node ]
Jon Hall4ba53f02015-07-29 13:07:41 -07002090
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002091 # lastSwitch += 1
2092 if node < ( clusterCount ):
2093 # connect to first device on the next node
2094 line = ( "\t" + str( lastSwitch ) + ":6 -> 0:5:" + ONOSIpList[ node+1 ] + "\n" )
2095 linkGraph.write( line )
Jon Hall4ba53f02015-07-29 13:07:41 -07002096
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002097 linkGraph.write( "}\n" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002098 linkGraph.close()
2099
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002100 # SCP
2101 os.system( "scp " + tempFile + " " + self.user_name + "@" + benchIp + ":" + linkGraphPath )
2102 main.log.info( "linkGraph.cfg creation complete" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002103
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002104 def configNullDev( self, ONOSIpList, deviceCount, numPorts=10 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002105 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07002106 ONOSIpList = list of Ip addresses of nodes switches will be devided amongst
2107 deviceCount = number of switches to distribute, or list of values to use as custom distribution
cameron@onlab.us75900962015-03-30 13:22:49 -07002108 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 +00002109 '''
2110
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002111 main.log.info( "Configuring Null Device Provider" )
2112 clusterCount = len( ONOSIpList )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002113
Jon Hall4ba53f02015-07-29 13:07:41 -07002114 try:
2115
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002116 if isinstance( deviceCount, int ) or isinstance( deviceCount, str ):
2117 main.log.info( "Creating device distribution" )
2118 deviceCount = int( deviceCount )
2119 switchList = [ 0 ]*( clusterCount+1 )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002120 baselineSwitchCount = deviceCount/clusterCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07002121
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002122 for node in range( 1, clusterCount + 1 ):
2123 switchList[ node ] = baselineSwitchCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07002124
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002125 for node in range( 1, ( deviceCount % clusterCount )+1 ):
2126 switchList[ node ] += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07002127
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002128 if isinstance( deviceCount, list ):
2129 main.log.info( "Using provided device distribution" )
Jon Hall4ba53f02015-07-29 13:07:41 -07002130
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002131 if len( deviceCount ) == clusterCount:
2132 switchList = [ '0' ]
2133 switchList.extend( deviceCount )
Jon Hall4ba53f02015-07-29 13:07:41 -07002134
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002135 if len( deviceCount ) == ( clusterCount + 1 ):
2136 if deviceCount[ 0 ] == '0' or deviceCount[ 0 ] == 0:
cameron@onlab.us75900962015-03-30 13:22:49 -07002137 switchList = deviceCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07002138
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002139 assert len( switchList ) == ( clusterCount + 1 )
Jon Hall4ba53f02015-07-29 13:07:41 -07002140
cameron@onlab.us75900962015-03-30 13:22:49 -07002141 except AssertionError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002142 main.log.error( "Bad device/Ip list match" )
cameron@onlab.us75900962015-03-30 13:22:49 -07002143 except TypeError:
2144 main.log.exception( self.name + ": Object not as expected" )
2145 return None
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 ONOSIp = [ 0 ]
2151 ONOSIp.extend( ONOSIpList )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002152
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002153 devicesString = "devConfigs = "
2154 for node in range( 1, len( ONOSIp ) ):
2155 devicesString += ( ONOSIp[ node ] + ":" + str( switchList[ node ] ) )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002156 if node < clusterCount:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002157 devicesString += ( "," )
Jon Hall4ba53f02015-07-29 13:07:41 -07002158
2159 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002160 self.handle.sendline( "onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider devConfigs " + devicesString )
2161 self.handle.expect( ":~" )
2162 self.handle.sendline( "onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider numPorts " + str( numPorts ) )
2163 self.handle.expect( ":~" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002164
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002165 for i in range( 10 ):
2166 self.handle.sendline( "onos $OC1 cfg get org.onosproject.provider.nil.device.impl.NullDeviceProvider" )
2167 self.handle.expect( ":~" )
cameron@onlab.us75900962015-03-30 13:22:49 -07002168 verification = self.handle.before
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002169 if ( " value=" + str( numPorts ) ) in verification and ( " value=" + devicesString ) in verification:
cameron@onlab.us75900962015-03-30 13:22:49 -07002170 break
2171 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002172 time.sleep( 1 )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002173
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002174 assert ( "value=" + str( numPorts ) ) in verification and ( " value=" + devicesString ) in verification
Jon Hall4ba53f02015-07-29 13:07:41 -07002175
cameron@onlab.us75900962015-03-30 13:22:49 -07002176 except AssertionError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002177 main.log.error( "Incorrect Config settings: " + verification )
Jon Hall77ba41c2015-04-06 10:25:40 -07002178 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002179 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002180 main.cleanAndExit()
cameron@onlab.us75900962015-03-30 13:22:49 -07002181
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002182 def configNullLink( self, fileName="/opt/onos/apache-karaf-3.0.3/etc/linkGraph.cfg", eventRate=0 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002183 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07002184 fileName default is currently the same as the default on ONOS, specify alternate file if
cameron@onlab.us75900962015-03-30 13:22:49 -07002185 you want to use a different topology file than linkGraph.cfg
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002186 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07002187
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002188 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002189 self.handle.sendline( "onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider eventRate " + str( eventRate ) )
2190 self.handle.expect( ":~" )
2191 self.handle.sendline( "onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider cfgFile " + fileName )
2192 self.handle.expect( ":~" )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002193
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002194 for i in range( 10 ):
2195 self.handle.sendline( "onos $OC1 cfg get org.onosproject.provider.nil.link.impl.NullLinkProvider" )
2196 self.handle.expect( ":~" )
cameron@onlab.us75900962015-03-30 13:22:49 -07002197 verification = self.handle.before
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002198 if ( " value=" + str( eventRate ) ) in verification and ( " value=" + fileName ) in verification:
cameron@onlab.us75900962015-03-30 13:22:49 -07002199 break
Jon Hall4ba53f02015-07-29 13:07:41 -07002200 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002201 time.sleep( 1 )
Jon Hall4ba53f02015-07-29 13:07:41 -07002202
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002203 assert ( "value=" + str( eventRate ) ) in verification and ( " value=" + fileName ) in verification
Jon Hall4ba53f02015-07-29 13:07:41 -07002204
cameron@onlab.us75900962015-03-30 13:22:49 -07002205 except pexpect.EOF:
2206 main.log.error( self.name + ": EOF exception found" )
2207 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002208 main.cleanAndExit()
cameron@onlab.us75900962015-03-30 13:22:49 -07002209 except AssertionError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002210 main.log.info( "Settings did not post to ONOS" )
Jon Hall3e6edb32018-08-21 16:20:30 -07002211 main.log.error( verification )
Jon Hall77ba41c2015-04-06 10:25:40 -07002212 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002213 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall3e6edb32018-08-21 16:20:30 -07002214 main.log.error( verification )
Devin Lim44075962017-08-11 10:56:37 -07002215 main.cleanAndExit()
andrew@onlab.us3b087132015-03-11 15:00:08 -07002216
kelvin-onlaba4074292015-07-09 15:19:49 -07002217 def getOnosIps( self ):
2218 """
2219 Get all onos IPs stored in
2220 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002221
kelvin-onlaba4074292015-07-09 15:19:49 -07002222 return sorted( self.onosIps.values() )
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002223
Chiyu Chengec63bde2016-11-17 18:11:36 -08002224 def listLog( self, nodeIp ):
2225 """
2226 Get a list of all the karaf log names
2227 """
2228 try:
2229 cmd = "onos-ssh " + nodeIp + " ls -tr /opt/onos/log"
2230 self.handle.sendline( cmd )
2231 self.handle.expect( ":~" )
2232 before = self.handle.before.splitlines()
2233 logNames = []
2234 for word in before:
2235 if 'karaf.log' in word:
2236 logNames.append( word )
2237 return logNames
2238 except pexpect.EOF:
2239 main.log.error( self.name + ": EOF exception found" )
2240 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002241 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08002242 except pexpect.TIMEOUT:
2243 main.log.error( self.name + ": TIMEOUT exception found" )
2244 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002245 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08002246 except Exception:
2247 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002248 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08002249
Pratik Parab3b2ab5a2017-02-14 13:15:14 -08002250 def logReport( self, nodeIp, searchTerms, outputMode="s", startStr=None, endStr=None ):
Jon Hallb4242222016-01-25 17:07:04 -08002251 """
2252 Searches the latest ONOS log file for the given search terms and
2253 prints the total occurances of each term. Returns to combined total of
2254 all occurances.
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002255
Jon Hallb4242222016-01-25 17:07:04 -08002256 Arguments:
2257 * nodeIp - The ip of the ONOS node where the log is located
2258 * searchTerms - A string to grep for or a list of strings to grep
2259 for in the ONOS log. Will print out the number of
2260 occurances for each term.
2261 Optional Arguments:
2262 * outputMode - 's' or 'd'. If 'd' will print the last 5 lines
2263 containing each search term as well as the total
2264 number of occurances of each term. Defaults to 's',
2265 which prints the simple output of just the number
2266 of occurances for each term.
Pratik Parab3b2ab5a2017-02-14 13:15:14 -08002267 * startStr - the start string to be given to stream editor command
2268 as the start point for extraction of data
2269 * endStr - the end string to be given to stream editor command as
2270 the end point for extraction of data
Jon Hallb4242222016-01-25 17:07:04 -08002271 """
2272 try:
2273 main.log.info( " Log Report for {} ".format( nodeIp ).center( 70, '=' ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002274 if isinstance( searchTerms, str ):
2275 searchTerms = [ searchTerms ]
Jon Hallb4242222016-01-25 17:07:04 -08002276 numTerms = len( searchTerms )
2277 outputMode = outputMode.lower()
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002278
Jon Hallb4242222016-01-25 17:07:04 -08002279 totalHits = 0
2280 logLines = []
2281 for termIndex in range( numTerms ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002282 term = searchTerms[ termIndex ]
2283 logLines.append( [ term ] )
Pratik Parab3b2ab5a2017-02-14 13:15:14 -08002284 if startStr and endStr:
2285 cmd = "onos-ssh {} \"sed -n '/{}/,/{}/p' /opt/onos/log/karaf.log | grep {}\"".format( nodeIp,
2286 startStr,
2287 endStr,
2288 term )
2289 else:
2290 cmd = "onos-ssh {} cat /opt/onos/log/karaf.log | grep {}".format( nodeIp,
2291 term )
Jon Hallb4242222016-01-25 17:07:04 -08002292 self.handle.sendline( cmd )
2293 self.handle.expect( ":~" )
2294 before = self.handle.before.splitlines()
2295 count = 0
2296 for line in before:
2297 if term in line and "grep" not in line:
2298 count += 1
2299 if before.index( line ) > ( len( before ) - 7 ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002300 logLines[ termIndex ].append( line )
Jon Hallb4242222016-01-25 17:07:04 -08002301 main.log.info( "{}: {}".format( term, count ) )
2302 totalHits += count
2303 if termIndex == numTerms - 1:
2304 print "\n"
2305 if outputMode != "s":
2306 outputString = ""
2307 for term in logLines:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002308 outputString = term[ 0 ] + ": \n"
Jon Hallb4242222016-01-25 17:07:04 -08002309 for line in range( 1, len( term ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002310 outputString += ( "\t" + term[ line ] + "\n" )
2311 if outputString != ( term[ 0 ] + ": \n" ):
Jon Hallb4242222016-01-25 17:07:04 -08002312 main.log.info( outputString )
2313 main.log.info( "=" * 70 )
2314 return totalHits
2315 except pexpect.EOF:
2316 main.log.error( self.name + ": EOF exception found" )
2317 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002318 main.cleanAndExit()
Jon Hallb4242222016-01-25 17:07:04 -08002319 except pexpect.TIMEOUT:
2320 main.log.error( self.name + ": TIMEOUT exception found" )
2321 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002322 main.cleanAndExit()
Jon Hallb4242222016-01-25 17:07:04 -08002323 except Exception:
2324 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002325 main.cleanAndExit()
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002326
2327 def copyMininetFile( self, fileName, localPath, userName, ip,
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002328 mnPath='~/mininet/custom/', timeout = 60 ):
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002329 """
2330 Description:
2331 Copy mininet topology file from dependency folder in the test folder
2332 and paste it to the mininet machine's mininet/custom folder
2333 Required:
2334 fileName - Name of the topology file to copy
2335 localPath - File path of the mininet topology file
2336 userName - User name of the mininet machine to send the file to
2337 ip - Ip address of the mininet machine
2338 Optional:
2339 mnPath - of the mininet directory to send the file to
2340 Return:
2341 Return main.TRUE if successfully copied the file otherwise
2342 return main.FALSE
2343 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002344
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002345 try:
2346 cmd = "scp " + localPath + fileName + " " + userName + "@" + \
2347 str( ip ) + ":" + mnPath + fileName
2348
2349 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07002350 self.handle.expect( self.prompt )
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002351
2352 main.log.info( self.name + ": Execute: " + cmd )
2353
2354 self.handle.sendline( cmd )
2355
2356 i = self.handle.expect( [ 'No such file',
2357 "100%",
2358 pexpect.TIMEOUT ] )
2359
2360 if i == 0:
2361 main.log.error( self.name + ": File " + fileName +
2362 " does not exist!" )
2363 return main.FALSE
2364
2365 if i == 1:
2366 main.log.info( self.name + ": File " + fileName +
2367 " has been copied!" )
2368 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07002369 self.handle.expect( self.prompt )
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002370 return main.TRUE
2371
2372 except pexpect.EOF:
2373 main.log.error( self.name + ": EOF exception found" )
2374 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002375 main.cleanAndExit()
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002376 except pexpect.TIMEOUT:
2377 main.log.error( self.name + ": TIMEOUT exception found" )
2378 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002379 main.cleanAndExit()
cameron@onlab.us78b89652015-07-08 15:21:03 -07002380
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002381 def jvmSet( self, memory=8 ):
Jon Hall4ba53f02015-07-29 13:07:41 -07002382
cameron@onlab.us78b89652015-07-08 15:21:03 -07002383 import os
2384
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002385 homeDir = os.path.expanduser( '~' )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002386 filename = "/onos/tools/package/bin/onos-service"
2387
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002388 serviceConfig = open( homeDir + filename, 'w+' )
2389 serviceConfig.write( "#!/bin/bash\n " )
2390 serviceConfig.write( "#------------------------------------- \n " )
2391 serviceConfig.write( "# Starts ONOS Apache Karaf container\n " )
2392 serviceConfig.write( "#------------------------------------- \n " )
2393 serviceConfig.write( "#export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-7-openjdk-amd64/}\n " )
2394 serviceConfig.write( """export JAVA_OPTS="${JAVA_OPTS:--Xms""" + str( memory ) + "G -Xmx" + str( memory ) + """G}" \n """ )
2395 serviceConfig.write( "[ -d $ONOS_HOME ] && cd $ONOS_HOME || ONOS_HOME=$(dirname $0)/..\n" )
2396 serviceConfig.write( """${ONOS_HOME}/apache-karaf-$KARAF_VERSION/bin/karaf "$@" \n """ )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002397 serviceConfig.close()
2398
Jon Hall6c44c0b2016-04-20 15:21:00 -07002399 def createDBFile( self, testData ):
Jon Hall4ba53f02015-07-29 13:07:41 -07002400
cameron@onlab.us78b89652015-07-08 15:21:03 -07002401 filename = main.TEST + "DB"
2402 DBString = ""
Jon Hall4ba53f02015-07-29 13:07:41 -07002403
cameron@onlab.us78b89652015-07-08 15:21:03 -07002404 for item in testData:
Jon Hall3e6edb32018-08-21 16:20:30 -07002405 if isinstance( item, str ):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002406 item = "'" + item + "'"
Jon Hall6c44c0b2016-04-20 15:21:00 -07002407 if testData.index( item ) < len( testData - 1 ):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002408 item += ","
Jon Hall6c44c0b2016-04-20 15:21:00 -07002409 DBString += str( item )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002410
Jon Hall6c44c0b2016-04-20 15:21:00 -07002411 DBFile = open( filename, "a" )
2412 DBFile.write( DBString )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002413 DBFile.close()
2414
Jon Hall6c44c0b2016-04-20 15:21:00 -07002415 def verifySummary( self, ONOSIp, *deviceCount ):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002416
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002417 self.handle.sendline( "onos " + ONOSIp + " summary" )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002418 self.handle.expect( ":~" )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002419
2420 summaryStr = self.handle.before
2421 print "\nSummary\n==============\n" + summaryStr + "\n\n"
2422
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002423 # passed = "SCC(s)=1" in summaryStr
2424 # if deviceCount:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002425 # passed = "devices=" + str(deviceCount) + "," not in summaryStr
cameron@onlab.us78b89652015-07-08 15:21:03 -07002426
GlennRC772363b2015-08-25 13:05:57 -07002427 passed = False
cameron@onlab.us78b89652015-07-08 15:21:03 -07002428 if "SCC(s)=1," in summaryStr:
2429 passed = True
Jon Hall6c44c0b2016-04-20 15:21:00 -07002430 print "Summary is verifed"
Jon Hall4ba53f02015-07-29 13:07:41 -07002431 else:
Jon Hall6c44c0b2016-04-20 15:21:00 -07002432 print "Summary failed"
cameron@onlab.us78b89652015-07-08 15:21:03 -07002433
2434 if deviceCount:
2435 print" ============================="
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002436 checkStr = "devices=" + str( deviceCount[ 0 ] ) + ","
cameron@onlab.us78b89652015-07-08 15:21:03 -07002437 print "Checkstr: " + checkStr
2438 if checkStr not in summaryStr:
2439 passed = False
Jon Hall6c44c0b2016-04-20 15:21:00 -07002440 print "Device count failed"
Jon Hall4ba53f02015-07-29 13:07:41 -07002441 else:
2442 print "device count verified"
cameron@onlab.us78b89652015-07-08 15:21:03 -07002443
2444 return passed
Jon Hall6c44c0b2016-04-20 15:21:00 -07002445
Jon Hall8f6d4622016-05-23 15:27:18 -07002446 def getIpAddr( self, iface=None ):
Jon Hall6c44c0b2016-04-20 15:21:00 -07002447 """
2448 Update self.ip_address with numerical ip address. If multiple IP's are
2449 located on the device, will attempt to use self.nicAddr to choose the
2450 right one. Defaults to 127.0.0.1 if no other address is found or cannot
2451 determine the correct address.
2452
2453 ONLY WORKS WITH IPV4 ADDRESSES
2454 """
2455 try:
Jon Hall8f6d4622016-05-23 15:27:18 -07002456 LOCALHOST = "127.0.0.1"
Jon Hall6c44c0b2016-04-20 15:21:00 -07002457 ipPat = "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"
2458 pattern = re.compile( ipPat )
2459 match = re.search( pattern, self.ip_address )
2460 if self.nicAddr:
2461 nicPat = self.nicAddr.replace( ".", "\." ).replace( "\*", r"\d{1,3}" )
2462 nicPat = re.compile( nicPat )
2463 else:
2464 nicPat = None
2465 # IF self.ip_address is an ip address and matches
2466 # self.nicAddr: return self.ip_address
2467 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002468 curIp = match.group( 0 )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002469 if nicPat:
2470 nicMatch = re.search( nicPat, curIp )
2471 if nicMatch:
2472 return self.ip_address
Jon Hall8f6d4622016-05-23 15:27:18 -07002473 # ELSE: IF iface, return ip of interface
2474 cmd = "ifconfig"
2475 ifPat = re.compile( "inet addr:({})".format( ipPat ) )
2476 if iface:
2477 cmd += " " + str( iface )
2478 raw = subprocess.check_output( cmd.split() )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002479 ifPat = re.compile( "inet addr:({})".format( ipPat ) )
2480 ips = re.findall( ifPat, raw )
Jon Hall8f6d4622016-05-23 15:27:18 -07002481 if iface:
2482 if ips:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002483 ip = ips[ 0 ]
Jon Hall8f6d4622016-05-23 15:27:18 -07002484 self.ip_address = ip
2485 return ip
2486 else:
2487 main.log.error( "Error finding ip, ifconfig output:".format( raw ) )
2488 # ELSE: attempt to get address matching nicPat.
Jon Hall6c44c0b2016-04-20 15:21:00 -07002489 if nicPat:
2490 for ip in ips:
2491 curMatch = re.search( nicPat, ip )
2492 if curMatch:
2493 self.ip_address = ip
2494 return ip
Jon Hall8f6d4622016-05-23 15:27:18 -07002495 else: # If only one non-localhost ip, return that
2496 tmpList = [ ip for ip in ips if ip is not LOCALHOST ]
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002497 if len( tmpList ) == 1:
2498 curIp = tmpList[ 0 ]
Jon Hall6c44c0b2016-04-20 15:21:00 -07002499 self.ip_address = curIp
2500 return curIp
Jon Hall8f6d4622016-05-23 15:27:18 -07002501 # Either no non-localhost IPs, or more than 1
Jon Hallebccd352016-05-20 15:17:17 -07002502 main.log.warn( "getIpAddr failed to find a public IP address" )
Jon Hall8f6d4622016-05-23 15:27:18 -07002503 return LOCALHOST
Jon Halle1790952016-05-23 15:51:46 -07002504 except subprocess.CalledProcessError:
Jon Hall8f6d4622016-05-23 15:27:18 -07002505 main.log.exception( "Error executing ifconfig" )
2506 except IndexError:
2507 main.log.exception( "Error getting IP Address" )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002508 except Exception:
2509 main.log.exception( "Uncaught exception" )
suibin zhang116647a2016-05-06 16:30:09 -07002510
Devin Lim461f0872017-06-05 16:49:33 -07002511 def startBasicONOS( self, nodeList, opSleep=60, onosStartupSleep=30, onosUser="sdn" ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002512 '''
suibin zhang116647a2016-05-06 16:30:09 -07002513 Start onos cluster with defined nodes, but only with drivers app
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002514 '''
suibin zhang116647a2016-05-06 16:30:09 -07002515 import time
2516
2517 self.createCellFile( self.ip_address,
Jon Hall3e6edb32018-08-21 16:20:30 -07002518 "temp",
2519 self.ip_address,
2520 "drivers",
2521 nodeList,
2522 nodeList,
2523 onosUser=onosUser )
suibin zhang116647a2016-05-06 16:30:09 -07002524
2525 main.log.info( self.name + ": Apply cell to environment" )
2526 cellResult = self.setCell( "temp" )
2527 verifyResult = self.verifyCell()
2528
2529 main.log.info( self.name + ": Creating ONOS package" )
You Wangd1bcaca2016-10-24 15:23:26 -07002530 packageResult = self.buckBuild( timeout=opSleep )
suibin zhang116647a2016-05-06 16:30:09 -07002531
You Wangc669d212017-01-25 11:09:48 -08002532 main.log.info( self.name + ": Uninstalling ONOS" )
2533 for nd in nodeList:
2534 self.onosUninstall( nodeIp=nd )
2535
suibin zhang116647a2016-05-06 16:30:09 -07002536 main.log.info( self.name + ": Installing ONOS package" )
2537 for nd in nodeList:
You Wangc669d212017-01-25 11:09:48 -08002538 self.onosInstall( node=nd )
2539
2540 main.log.info( self.name + ": Set up ONOS secure SSH" )
2541 for nd in nodeList:
2542 self.onosSecureSSH( node=nd )
suibin zhang116647a2016-05-06 16:30:09 -07002543
2544 main.log.info( self.name + ": Starting ONOS service" )
2545 time.sleep( onosStartupSleep )
2546
2547 onosStatus = True
2548 for nd in nodeList:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002549 onosStatus = onosStatus & self.isup( node = nd )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002550 # print "onosStatus is: " + str( onosStatus )
suibin zhang116647a2016-05-06 16:30:09 -07002551
2552 return main.TRUE if onosStatus else main.FALSE
2553
Devin Lim02075272017-07-10 15:33:21 -07002554 def onosNetCfg( self, controllerIp, path, fileName ):
Jeremy Songster5665f1b2016-06-20 14:38:22 -07002555 """
2556 Push a specified json file to ONOS through the onos-netcfg service
2557
2558 Required:
Devin Lim02075272017-07-10 15:33:21 -07002559 controllerIp - the Ip of the ONOS node in the cluster
Jeremy Songster5665f1b2016-06-20 14:38:22 -07002560 path - the location of the file to be sent
2561 fileName - name of the json file to be sent
2562
2563 Returns main.TRUE on successfully sending json file, and main.FALSE if
2564 there is an error.
2565 """
2566 try:
Devin Lim02075272017-07-10 15:33:21 -07002567 cmd = "onos-netcfg {0} {1}{2}".format( controllerIp, path, fileName )
2568 main.log.info( "Sending: " + cmd )
2569 main.ONOSbench.handle.sendline( cmd )
Jeremy Ronquillo3008aa32017-07-07 15:38:57 -07002570 main.ONOSbench.handle.expect( self.prompt )
Devin Lim02075272017-07-10 15:33:21 -07002571 handle = self.handle.before
Jeremy Ronquillo3008aa32017-07-07 15:38:57 -07002572 if "Error" in handle or "No such file or directory" in handle or "curl: " in handle:
2573 main.log.error( self.name + ": " + handle + self.handle.after )
Devin Lim02075272017-07-10 15:33:21 -07002574 return main.FALSE
Devin Lim752dd7b2017-06-27 14:40:03 -07002575 return main.TRUE
Jeremy Songster5665f1b2016-06-20 14:38:22 -07002576 except pexpect.EOF:
2577 main.log.error( self.name + ": EOF exception found" )
2578 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002579 main.cleanAndExit()
Jeremy Songster5665f1b2016-06-20 14:38:22 -07002580 except Exception:
2581 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002582 main.cleanAndExit()
Devin Lim3ebd5e72017-11-14 10:38:00 -08002583
2584 def formCluster( self, onosIPs ):
2585 """
2586 From ONOS cluster for IP addresses in onosIPs list
2587 """
2588 try:
2589 onosIPs = " ".join( onosIPs )
2590 command = "onos-form-cluster {}".format( onosIPs )
2591 main.log.info( "Sending: " + command )
2592 self.handle.sendline( "" )
2593 self.handle.expect( self.prompt )
2594 self.handle.sendline( command )
2595 self.handle.expect( self.prompt )
2596 handle = self.handle.before
2597 main.log.debug( handle )
2598 assert handle is not None, "Error in sendline"
2599 assert "Command not found:" not in handle, handle
2600 assert "Error" not in handle, handle
2601 assert "Exception:" not in handle, handle
2602 assert "curl:" not in handle, handle
2603 return main.TRUE
2604 except AssertionError:
2605 main.log.exception( "{} Error in onos-form-cluster 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()
Jon Hall7ce46ea2018-02-05 12:20:59 -08002617
2618 def backupData( self, location ):
2619 """
2620 Backs up ONOS data and logs to 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 to save the backup to
2624 """
2625 try:
2626 cmd = "/opt/onos/bin/onos-backup " + 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-backup 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()
2649
2650 def restoreData( self, location ):
2651 """
2652 Restores ONOS data and logs from a given location. Returns main.FALSE
2653 if there is an error executing the command, and main.TRUE otherwise.
2654 required arguments:
2655 loaction - The file path of a backup file
2656 """
2657 try:
2658 cmd = "/opt/onos/bin/onos-restore " + str( location )
2659 self.handle.sendline( cmd )
2660 self.handle.expect( self.prompt )
2661 handle = self.handle.before
2662 main.log.debug( handle )
2663 assert handle is not None, "Error in sendline"
2664 assert "Command not found:" not in handle, handle
2665 assert "Error" not in handle, handle
2666 assert "Exception:" not in handle, handle
2667 return main.TRUE
2668 except AssertionError:
2669 main.log.exception( "{} Error in onos-restore output:".format( self.name ) )
2670 return main.FALSE
2671 except TypeError:
2672 main.log.exception( self.name + ": Object not as expected" )
2673 return main.FALSE
2674 except pexpect.EOF:
2675 main.log.error( self.name + ": EOF exception found" )
2676 main.log.error( self.name + ": " + self.handle.before )
2677 main.cleanAndExit()
2678 except Exception:
2679 main.log.exception( self.name + ": Uncaught exception!" )
2680 main.cleanAndExit()
You Wang5df1c6d2018-04-06 18:02:02 -07002681
You Wang5ac7db72018-07-17 11:17:52 -07002682 def onosDiagnostics( self, onosIPs, dstDir, suffix, timeout=300 ):
You Wang5df1c6d2018-04-06 18:02:02 -07002683 """
2684 Run onos-diagnostics with given ONOS instance IPs and save output to dstDir
2685 with suffix specified E.g. onos-diags-suffix.tar.gz
Jon Hall0e240372018-05-02 11:21:57 -07002686 required arguments:
You Wang5df1c6d2018-04-06 18:02:02 -07002687 onosIPs - list of ONOS IPs for collecting diags
2688 dstDir - diags file will be saved under the directory specified
2689 suffix - diags file will be named with the suffix specified
2690 returns:
2691 main.FALSE if there's an error executing the command, and main.TRUE otherwise
2692 """
2693 try:
2694 cmd = "onos-diagnostics"
2695 assert isinstance( onosIPs, list )
2696 for ip in onosIPs:
2697 cmd += " " + str( ip )
2698 self.handle.sendline( cmd )
You Wang5ac7db72018-07-17 11:17:52 -07002699 self.handle.expect( self.prompt, timeout=timeout )
You Wang5df1c6d2018-04-06 18:02:02 -07002700 handle = self.handle.before
2701 main.log.debug( handle )
2702 assert handle is not None, "Error in sendline"
2703 assert "Command not found:" not in handle, handle
2704 assert "Exception:" not in handle, handle
2705 # Rename and move diags file to dstDir from /tmp
2706 if dstDir[ -1: ] != "/":
2707 dstDir += "/"
2708 self.handle.sendline( "mv /tmp/onos-diags.tar.gz " + str( dstDir ) + "onos-diags" + str( suffix ) + ".tar.gz" )
2709 self.handle.expect( self.prompt )
2710 handle = self.handle.before
2711 main.log.debug( handle )
2712 assert handle is not None, "Error in sendline"
2713 assert "No such file or directory" not in handle, handle
2714 return main.TRUE
2715 except AssertionError:
2716 main.log.exception( "{} Error in onos-diagnostics output:".format( self.name ) )
2717 return main.FALSE
2718 except TypeError:
2719 main.log.exception( self.name + ": Object not as expected" )
2720 return main.FALSE
You Wang223faa32018-06-21 10:45:47 -07002721 except pexpect.TIMEOUT:
2722 main.log.exception( self.name + ": TIMEOUT exception found in onosDiagnostics" )
2723 main.log.error( self.name + ": " + self.handle.before )
You Wangb65d2372018-08-17 15:37:59 -07002724 self.exitFromCmd( self.prompt, 100 )
You Wang223faa32018-06-21 10:45:47 -07002725 return main.FALSE
You Wang5df1c6d2018-04-06 18:02:02 -07002726 except pexpect.EOF:
2727 main.log.error( self.name + ": EOF exception found" )
2728 main.log.error( self.name + ": " + self.handle.before )
2729 main.cleanAndExit()
2730 except Exception:
2731 main.log.exception( self.name + ": Uncaught exception!" )
2732 main.cleanAndExit()
Jon Hall0e240372018-05-02 11:21:57 -07002733
2734 def onosPower( self, onosIP, toggle, userName=None ):
2735 """
2736 Run onos-power script to tell the cell warden to simulate a power faulure
2737 for the given container.
2738 required :
2739 onosIP - ONOS node IP
2740 toggle - either "off" or "on", used to indicate whether
2741 the node should be powered off or on
2742 returns:
2743 main.FALSE if there's an error executing the command, and main.TRUE otherwise
2744 """
2745 try:
2746 cmd = "onos-power {} {}".format( onosIP, toggle )
2747 if userName:
2748 cmd += " {}".format( userName )
2749 self.handle.sendline( cmd )
2750 self.handle.expect( self.prompt )
2751 handle = self.handle.before
2752 main.log.debug( handle )
2753 assert handle is not None, "Error in sendline"
2754 assert "Command not found:" not in handle, handle
2755 assert "Exception:" not in handle, handle
2756 assert "usage:" not in handle, handle
2757 return main.TRUE
2758 except AssertionError:
2759 main.log.exception( "{} Error in onos-power output:".format( self.name ) )
2760 return main.FALSE
2761 except TypeError:
2762 main.log.exception( self.name + ": Object not as expected" )
2763 return main.FALSE
2764 except pexpect.EOF:
2765 main.log.error( self.name + ": EOF exception found" )
2766 main.log.error( self.name + ": " + self.handle.before )
2767 main.cleanAndExit()
2768 except Exception:
2769 main.log.exception( self.name + ": Uncaught exception!" )
2770 main.cleanAndExit()
You Wangf9d95be2018-08-01 14:35:37 -07002771
2772 def atomixKill( self, nodeIp ):
2773 """
2774 Calls the command: 'atomix-kill [<node-ip>]'
2775 Kills the Atomix instance running on the specified node
2776 """
2777 try:
2778 self.handle.sendline( "" )
2779 self.handle.expect( self.prompt )
2780 self.handle.sendline( "atomix-kill " + str( nodeIp ) )
2781 i = self.handle.expect( [
2782 self.prompt,
2783 "No\sroute\sto\shost",
2784 "password:",
2785 pexpect.TIMEOUT ], timeout=60 )
2786
2787 if i == 0:
2788 main.log.info( "Atomix instance " + str( nodeIp ) + " was killed" )
2789 return main.TRUE
2790 elif i == 1:
2791 main.log.info( "No route to host" )
2792 return main.FALSE
2793 elif i == 2:
2794 main.log.info( "Passwordless login for host: " + str( nodeIp ) + " not configured" )
2795 return main.FALSE
2796 else:
2797 main.log.info( "Atomix instance was not killed" )
2798 return main.FALSE
2799
2800 except pexpect.EOF:
2801 main.log.error( self.name + ": EOF exception found" )
2802 main.log.error( self.name + ": " + self.handle.before )
2803 main.cleanAndExit()
2804 except Exception:
2805 main.log.exception( self.name + ": Uncaught exception!" )
2806 main.cleanAndExit()
2807
2808 def atomixUninstall( self, nodeIp="" ):
2809 """
2810 Calls the command: 'atomix-uninstall'
2811 Uninstalls Atomix from the designated node, stopping if needed
2812 """
2813 try:
2814 self.handle.sendline( "" )
2815 self.handle.expect( self.prompt, timeout=180 )
2816 self.handle.sendline( "atomix-uninstall " + str( nodeIp ) )
2817 self.handle.expect( self.prompt, timeout=180 )
2818 main.log.info( "Atomix " + nodeIp + " was uninstalled" )
2819 # onos-uninstall command does not return any text
2820 return main.TRUE
2821 except pexpect.TIMEOUT:
2822 main.log.exception( self.name + ": Timeout in atomixUninstall" )
2823 self.handle.send( "\x03" ) # Control-C
2824 self.handle.expect( self.prompt )
2825 return main.FALSE
2826 except pexpect.EOF:
2827 main.log.error( self.name + ": EOF exception found" )
2828 main.log.error( self.name + ": " + self.handle.before )
2829 main.cleanAndExit()
2830 except Exception:
2831 main.log.exception( self.name + ": Uncaught exception!" )
2832 main.cleanAndExit()
2833
2834 def atomixInstall( self, options="", node="" ):
2835 """
2836 Installs Atomix on the designated nodes.
2837 Returns: main.TRUE on success and main.FALSE on failure
2838 """
2839 try:
2840 if options:
2841 self.handle.sendline( "atomix-install " + options + " " + node )
2842 else:
2843 self.handle.sendline( "atomix-install " + node )
2844 self.handle.expect( "atomix-install " )
2845 i = self.handle.expect( [ "Network\sis\sunreachable",
2846 "is already installed",
2847 "saved",
2848 self.prompt,
2849 pexpect.TIMEOUT ], timeout=180 )
2850 if i == 0:
2851 # can't reach ONOS node
Jon Hall3e6edb32018-08-21 16:20:30 -07002852 main.log.warn( self.name + ": Network is unreachable" )
You Wangf9d95be2018-08-01 14:35:37 -07002853 self.handle.expect( self.prompt )
2854 return main.FALSE
2855 elif i == 1:
2856 # same bits are already on Atomix node
Jon Hall3e6edb32018-08-21 16:20:30 -07002857 main.log.info( self.name + ": Atomix is already installed on " + node )
You Wangf9d95be2018-08-01 14:35:37 -07002858 self.handle.expect( self.prompt )
2859 return main.TRUE
Jon Hallb685a1c2018-10-30 15:17:01 -07002860 elif i == 2:
Jon Hall3e6edb32018-08-21 16:20:30 -07002861 main.log.info( self.name + ": Atomix was installed on " + node )
You Wangf9d95be2018-08-01 14:35:37 -07002862 self.handle.expect( self.prompt )
2863 return main.TRUE
Jon Hallb685a1c2018-10-30 15:17:01 -07002864 elif i == 3:
2865 self.handle.sendline( "echo Return code: $?" )
2866 self.handle.expect( "\$\?" )
2867 self.handle.expect( self.prompt )
Jon Hallb685a1c2018-10-30 15:17:01 -07002868 match = re.search( "Return code: (\d+)", self.handle.before )
2869 if match:
2870 exitCode = int( match.group( 1 ) )
2871 else:
2872 # Didn't match pattern
2873 main.log.error( "Could not parse exit code of atomix-install" )
Jon Hall5e1469a2018-11-01 13:55:53 -07002874 main.log.debug( self.handle.before + self.handle.before )
Jon Hallb685a1c2018-10-30 15:17:01 -07002875 return main.FALSE
2876 if exitCode == 0:
2877 return main.TRUE
2878 else:
Jon Hall5e1469a2018-11-01 13:55:53 -07002879 main.log.error( "Unsuccessful exit code of atomix-install" )
2880 main.log.debug( self.handle.before + self.handle.before )
Jon Hallb685a1c2018-10-30 15:17:01 -07002881 return main.FALSE
You Wangf9d95be2018-08-01 14:35:37 -07002882 elif i == 4:
2883 # timeout
Jon Hall3e6edb32018-08-21 16:20:30 -07002884 main.log.info( self.name + ": Installation of Atomix on " + node + " timed out" )
You Wangf9d95be2018-08-01 14:35:37 -07002885 self.handle.expect( self.prompt )
2886 main.log.warn( self.handle.before )
2887 self.handle.send( "\x03" ) # Control-C
2888 self.handle.expect( self.prompt )
2889 return main.FALSE
2890 except pexpect.EOF:
2891 main.log.error( self.name + ": EOF exception found" )
2892 main.log.error( self.name + ": " + self.handle.before )
2893 main.cleanAndExit()
2894 except Exception:
2895 main.log.exception( self.name + ": Uncaught exception!" )
2896 main.cleanAndExit()