blob: a2fade7ab5c0fca539c4d74c4476a06fdd1bb73b [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
Jon Hall9b0de1f2020-08-24 15:38:04 -070042 self.maxNodes = None
43 self.karafUser = None
44 self.karafPass = None
45 self.webUser = None
46 self.webPass = None
Jon Hallefbd9792015-03-05 16:11:36 -080047 self.handle = None
Jon Hall6c44c0b2016-04-20 15:21:00 -070048 self.nicAddr = None
Devin Limdc78e202017-06-09 18:30:07 -070049 super( OnosDriver, self ).__init__()
kelvin8ec71442015-01-15 16:57:00 -080050
51 def connect( self, **connectargs ):
52 """
Jon Hall05b2b432014-10-08 19:53:25 -040053 Creates ssh handle for ONOS "bench".
kelvin-onlaba4074292015-07-09 15:19:49 -070054 NOTE:
55 The ip_address would come from the topo file using the host tag, the
56 value can be an environment variable as well as a "localhost" to get
57 the ip address needed to ssh to the "bench"
kelvin8ec71442015-01-15 16:57:00 -080058 """
Jon Hall05b2b432014-10-08 19:53:25 -040059 try:
Devin Limdc78e202017-06-09 18:30:07 -070060
Jon Hall05b2b432014-10-08 19:53:25 -040061 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080062 vars( self )[ key ] = connectargs[ key ]
kelvin8ec71442015-01-15 16:57:00 -080063 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070064
kelvin-onlabc2b79102015-07-14 11:41:20 -070065 # The 'nodes' tag is optional and it is not required in .topo file
kelvin-onlaba4074292015-07-09 15:19:49 -070066 for key in self.options:
Jon Hall9b0de1f2020-08-24 15:38:04 -070067 if key == "home":
Jon Halle37bd1f2020-09-10 12:16:41 -070068 self.home = self.options[ key ]
Jon Hall9b0de1f2020-08-24 15:38:04 -070069 elif key == "nodes":
kelvin-onlabc2b79102015-07-14 11:41:20 -070070 # Maximum number of ONOS nodes to run, if there is any
Jon Halle37bd1f2020-09-10 12:16:41 -070071 self.maxNodes = int( self.options[ key ] )
Jon Hall9b0de1f2020-08-24 15:38:04 -070072 elif key == "web_user":
73 self.webUser = self.options[ key ]
74 elif key == "web_pass":
75 self.webPass = self.options[ key ]
kelvin-onlaba4074292015-07-09 15:19:49 -070076
Jon Hall9b0de1f2020-08-24 15:38:04 -070077 self.home = self.checkOptions( self.home, "~/onos" )
78 self.maxNodes = self.checkOptions( self.maxNodes, 100 )
79 self.karafUser = self.checkOptions( self.karafUser, self.user_name )
80 self.karafPass = self.checkOptions( self.karafPass, self.pwd )
81 self.webUser = self.checkOptions( self.webUser, "onos" )
82 self.webPass = self.checkOptions( self.webPass, "rocks" )
kelvin-onlaba4074292015-07-09 15:19:49 -070083
kelvin-onlabc2b79102015-07-14 11:41:20 -070084 # Grabs all OC environment variables based on max number of nodes
kelvin-onlaba4074292015-07-09 15:19:49 -070085 self.onosIps = {} # Dictionary of all possible ONOS ip
86
87 try:
88 if self.maxNodes:
kelvin-onlaba4074292015-07-09 15:19:49 -070089 for i in range( self.maxNodes ):
90 envString = "OC" + str( i + 1 )
kelvin-onlabc2b79102015-07-14 11:41:20 -070091 # If there is no more OC# then break the loop
92 if os.getenv( envString ):
93 self.onosIps[ envString ] = os.getenv( envString )
94 else:
95 self.maxNodes = len( self.onosIps )
96 main.log.info( self.name +
97 ": Created cluster data with " +
98 str( self.maxNodes ) +
99 " maximum number" +
100 " of nodes" )
101 break
kelvin-onlaba4074292015-07-09 15:19:49 -0700102
103 if not self.onosIps:
Jon Hall3c0114c2020-08-11 15:07:42 -0700104 main.log.info( self.name + ": Could not read any environment variable"
kelvin-onlaba4074292015-07-09 15:19:49 -0700105 + " please load a cell file with all" +
106 " onos IP" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700107 self.maxNodes = None
kelvin-onlaba4074292015-07-09 15:19:49 -0700108 else:
109 main.log.info( self.name + ": Found " +
110 str( self.onosIps.values() ) +
111 " ONOS IPs" )
kelvin-onlaba4074292015-07-09 15:19:49 -0700112 except KeyError:
Jon Hall3c0114c2020-08-11 15:07:42 -0700113 main.log.info( self.name + ": Invalid environment variable" )
kelvin-onlaba4074292015-07-09 15:19:49 -0700114 except Exception as inst:
115 main.log.error( "Uncaught exception: " + str( inst ) )
116
117 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700118 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -0700119 self.ip_address = os.getenv( str( self.ip_address ) )
120 else:
121 main.log.info( self.name +
122 ": Trying to connect to " +
123 self.ip_address )
kelvin-onlaba4074292015-07-09 15:19:49 -0700124 except KeyError:
Jon Hall3c0114c2020-08-11 15:07:42 -0700125 main.log.info( self.name + ": Invalid host name," +
kelvin-onlaba4074292015-07-09 15:19:49 -0700126 " connecting to local host instead" )
127 self.ip_address = 'localhost'
128 except Exception as inst:
129 main.log.error( "Uncaught exception: " + str( inst ) )
130
kelvin8ec71442015-01-15 16:57:00 -0800131 self.handle = super( OnosDriver, self ).connect(
132 user_name=self.user_name,
kelvin-onlab08679eb2015-01-21 16:11:48 -0800133 ip_address=self.ip_address,
kelvin-onlabd3b64892015-01-20 13:26:24 -0800134 port=self.port,
135 pwd=self.pwd,
136 home=self.home )
Jon Hall05b2b432014-10-08 19:53:25 -0400137 if self.handle:
Jon Hall500ed642019-06-17 18:25:46 +0000138 self.handle.setwinsize( 24, 250 )
Jon Hall0fc0d452015-07-14 09:49:58 -0700139 self.handle.sendline( "cd " + self.home )
Jon Hall4b668212019-06-17 11:08:49 -0700140 self.handle.expect( "cd " + self.home )
Devin Limc20e79a2017-06-07 10:29:57 -0700141 self.handle.expect( self.prompt )
Jon Hall05b2b432014-10-08 19:53:25 -0400142 return self.handle
kelvin8ec71442015-01-15 16:57:00 -0800143 else:
Jon Hall3c0114c2020-08-11 15:07:42 -0700144 main.log.info( self.name + ": Failed to create ONOS handle" )
Jon Hall05b2b432014-10-08 19:53:25 -0400145 return main.FALSE
146 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800147 main.log.error( self.name + ": EOF exception found" )
148 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700149 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800150 except Exception:
151 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700152 main.cleanAndExit()
Jon Hall05b2b432014-10-08 19:53:25 -0400153
kelvin8ec71442015-01-15 16:57:00 -0800154 def disconnect( self ):
155 """
Jon Hall05b2b432014-10-08 19:53:25 -0400156 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800157 """
Jon Halld61331b2015-02-17 16:35:47 -0800158 response = main.TRUE
Jon Hall05b2b432014-10-08 19:53:25 -0400159 try:
Jon Hall61282e32015-03-19 11:34:11 -0700160 if self.handle:
161 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -0700162 self.handle.expect( self.prompt )
Jon Hall61282e32015-03-19 11:34:11 -0700163 self.handle.sendline( "exit" )
164 self.handle.expect( "closed" )
Jon Hall05b2b432014-10-08 19:53:25 -0400165 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800166 main.log.error( self.name + ": EOF exception found" )
167 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700168 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700169 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700170 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800171 except Exception:
172 main.log.exception( self.name + ": Connection failed to the host" )
Jon Hall05b2b432014-10-08 19:53:25 -0400173 response = main.FALSE
174 return response
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400175
andrew@onlab.usaee415a2015-06-05 14:38:58 -0400176 def getEpochMs( self ):
177 """
178 Returns milliseconds since epoch
Jon Hall4ba53f02015-07-29 13:07:41 -0700179
180 When checking multiple nodes in a for loop,
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000181 around a hundred milliseconds of difference (ascending) is
Jon Hall4ba53f02015-07-29 13:07:41 -0700182 generally acceptable due to calltime of the function.
183 Few seconds, however, is not and it means clocks
184 are off sync.
andrew@onlab.usaee415a2015-06-05 14:38:58 -0400185 """
186 try:
187 self.handle.sendline( 'date +%s.%N' )
188 self.handle.expect( 'date \+\%s\.\%N' )
Devin Limdc78e202017-06-09 18:30:07 -0700189 self.handle.expect( self.prompt )
andrew@onlab.usaee415a2015-06-05 14:38:58 -0400190 epochMs = self.handle.before
191 return epochMs
192 except Exception:
193 main.log.exception( 'Uncaught exception getting epoch time' )
Devin Lim44075962017-08-11 10:56:37 -0700194 main.cleanAndExit()
andrew@onlab.usaee415a2015-06-05 14:38:58 -0400195
Jon Hall6c44c0b2016-04-20 15:21:00 -0700196 def onosPackage( self, opTimeout=180 ):
kelvin8ec71442015-01-15 16:57:00 -0800197 """
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400198 Produce a self-contained tar.gz file that can be deployed
Jon Hall64af8502015-12-15 10:09:33 -0800199 and executed on any platform with Java 8 JRE.
kelvin8ec71442015-01-15 16:57:00 -0800200 """
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400201 try:
Jon Hall64af8502015-12-15 10:09:33 -0800202 ret = main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800203 self.handle.sendline( "onos-package" )
204 self.handle.expect( "onos-package" )
Jon Hall96451092016-05-04 09:42:30 -0700205 while True:
206 i = self.handle.expect( [ "Downloading",
207 "Unknown options",
208 "No such file or directory",
209 "tar.gz",
Devin Limc20e79a2017-06-07 10:29:57 -0700210 self.prompt ],
Jon Hall96451092016-05-04 09:42:30 -0700211 opTimeout )
212 handle = str( self.handle.before + self.handle.after )
213 if i == 0:
214 # Give more time to download the file
215 continue # expect again
216 elif i == 1:
217 # Incorrect usage
218 main.log.error( "onos-package does not recognize the given options" )
219 ret = main.FALSE
220 continue # expect again
221 elif i == 2:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000222 # File(s) not found
Jon Hall96451092016-05-04 09:42:30 -0700223 main.log.error( "onos-package could not find a file or directory" )
224 ret = main.FALSE
225 continue # expect again
226 elif i == 3:
227 # tar.gz
228 continue # expect again
229 elif i == 4:
230 # Prompt returned
231 break
Jon Hall3c0114c2020-08-11 15:07:42 -0700232 main.log.info( self.name + ": onos-package command returned: " + handle )
kelvin8ec71442015-01-15 16:57:00 -0800233 # As long as the sendline does not time out,
234 # return true. However, be careful to interpret
235 # the results of the onos-package command return
Jon Hall64af8502015-12-15 10:09:33 -0800236 return ret
237 except pexpect.TIMEOUT:
238 main.log.exception( self.name + ": TIMEOUT exception found in onosPackage" )
239 main.log.error( self.name + ": " + self.handle.before )
You Wang141b43b2018-06-26 16:50:18 -0700240 self.handle.send( "\x03" ) # Control-C
241 self.handle.expect( self.prompt )
Jon Hall64af8502015-12-15 10:09:33 -0800242 return main.FALSE
andrewonlab7735d852014-10-09 13:02:47 -0400243 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800244 main.log.error( self.name + ": EOF exception found" )
245 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700246 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800247 except Exception:
248 main.log.exception( "Failed to package ONOS" )
Devin Lim44075962017-08-11 10:56:37 -0700249 main.cleanAndExit()
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400250
kelvin-onlabd3b64892015-01-20 13:26:24 -0800251 def onosBuild( self ):
kelvin8ec71442015-01-15 16:57:00 -0800252 """
andrewonlab8790abb2014-11-06 13:51:54 -0500253 Use the pre defined script to build onos via mvn
kelvin8ec71442015-01-15 16:57:00 -0800254 """
andrewonlab8790abb2014-11-06 13:51:54 -0500255 try:
kelvin8ec71442015-01-15 16:57:00 -0800256 self.handle.sendline( "onos-build" )
257 self.handle.expect( "onos-build" )
258 i = self.handle.expect( [
kelvin-onlabd3b64892015-01-20 13:26:24 -0800259 "BUILD SUCCESS",
260 "ERROR",
261 "BUILD FAILED" ],
262 timeout=120 )
kelvin8ec71442015-01-15 16:57:00 -0800263 handle = str( self.handle.before )
Devin Limc20e79a2017-06-07 10:29:57 -0700264 self.handle.expect( self.prompt )
andrewonlab8790abb2014-11-06 13:51:54 -0500265
Jon Hall3c0114c2020-08-11 15:07:42 -0700266 main.log.info( self.name + ": onos-build command returned: " +
kelvin8ec71442015-01-15 16:57:00 -0800267 handle )
andrewonlab8790abb2014-11-06 13:51:54 -0500268
269 if i == 0:
270 return main.TRUE
271 else:
272 return handle
273
274 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800275 main.log.error( self.name + ": EOF exception found" )
276 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -0800277 except Exception:
278 main.log.exception( "Failed to build ONOS" )
Devin Lim44075962017-08-11 10:56:37 -0700279 main.cleanAndExit()
andrewonlab8790abb2014-11-06 13:51:54 -0500280
shahshreya9f531fe2015-06-10 12:03:51 -0700281 def cleanInstall( self, skipTest=False, mciTimeout=600 ):
kelvin8ec71442015-01-15 16:57:00 -0800282 """
283 Runs mvn clean install in the root of the ONOS directory.
284 This will clean all ONOS artifacts then compile each module
shahshreya9f531fe2015-06-10 12:03:51 -0700285 Optional:
286 skipTest - Does "-DskipTests -Dcheckstyle.skip -U -T 1C" which
287 skip the test. This will make the building faster.
288 Disregarding the credibility of the build
kelvin8ec71442015-01-15 16:57:00 -0800289 Returns: main.TRUE on success
Jon Hallde9d9aa2014-10-08 20:36:02 -0400290 On Failure, exits the test
kelvin8ec71442015-01-15 16:57:00 -0800291 """
Jon Hallde9d9aa2014-10-08 20:36:02 -0400292 try:
Jon Hall3c0114c2020-08-11 15:07:42 -0700293 main.log.info( self.name + ": Running 'mvn clean install' on " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800294 str( self.name ) +
kelvin8ec71442015-01-15 16:57:00 -0800295 ". This may take some time." )
296 self.handle.sendline( "cd " + self.home )
Devin Limc20e79a2017-06-07 10:29:57 -0700297 self.handle.expect( self.prompt )
Jon Hallea7818b2014-10-09 14:30:59 -0400298
kelvin8ec71442015-01-15 16:57:00 -0800299 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -0700300 self.handle.expect( self.prompt )
shahshreya9f531fe2015-06-10 12:03:51 -0700301
302 if not skipTest:
303 self.handle.sendline( "mvn clean install" )
304 self.handle.expect( "mvn clean install" )
305 else:
306 self.handle.sendline( "mvn clean install -DskipTests" +
307 " -Dcheckstyle.skip -U -T 1C" )
308 self.handle.expect( "mvn clean install -DskipTests" +
309 " -Dcheckstyle.skip -U -T 1C" )
kelvin8ec71442015-01-15 16:57:00 -0800310 while True:
311 i = self.handle.expect( [
Jon Hall274b6642015-02-17 11:57:17 -0800312 'There\sis\sinsufficient\smemory\sfor\sthe\sJava\s' +
Jon Hallefbd9792015-03-05 16:11:36 -0800313 'Runtime\sEnvironment\sto\scontinue',
Jon Hallde9d9aa2014-10-08 20:36:02 -0400314 'BUILD\sFAILURE',
315 'BUILD\sSUCCESS',
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700316 'onos' + self.prompt, # TODO: fix this to be more generic?
Devin Limdc78e202017-06-09 18:30:07 -0700317 'ONOS' + self.prompt,
pingping-lin57a56ce2015-05-20 16:43:48 -0700318 pexpect.TIMEOUT ], mciTimeout )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400319 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800320 main.log.error( self.name + ":There is insufficient memory \
321 for the Java Runtime Environment to continue." )
322 # return main.FALSE
Devin Lim44075962017-08-11 10:56:37 -0700323
324 main.cleanAndExit()
Jon Hallde9d9aa2014-10-08 20:36:02 -0400325 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800326 main.log.error( self.name + ": Build failure!" )
327 # return main.FALSE
Devin Lim44075962017-08-11 10:56:37 -0700328
329 main.cleanAndExit()
Jon Hallde9d9aa2014-10-08 20:36:02 -0400330 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800331 main.log.info( self.name + ": Build success!" )
Jon Halle94919c2015-03-23 11:42:57 -0700332 elif i == 3 or i == 4:
kelvin8ec71442015-01-15 16:57:00 -0800333 main.log.info( self.name + ": Build complete" )
334 # Print the build time
Jon Hallf8ef52c2014-10-09 19:37:33 -0400335 for line in self.handle.before.splitlines():
336 if "Total time:" in line:
kelvin8ec71442015-01-15 16:57:00 -0800337 main.log.info( line )
338 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -0700339 self.handle.expect( self.prompt, timeout=60 )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400340 return main.TRUE
Jon Halle94919c2015-03-23 11:42:57 -0700341 elif i == 5:
kelvin8ec71442015-01-15 16:57:00 -0800342 main.log.error(
343 self.name +
344 ": mvn clean install TIMEOUT!" )
345 # return main.FALSE
Devin Lim44075962017-08-11 10:56:37 -0700346
347 main.cleanAndExit()
Jon Hallde9d9aa2014-10-08 20:36:02 -0400348 else:
Jon Hall274b6642015-02-17 11:57:17 -0800349 main.log.error( self.name + ": unexpected response from " +
Jon Hallefbd9792015-03-05 16:11:36 -0800350 "mvn clean install" )
kelvin8ec71442015-01-15 16:57:00 -0800351 # return main.FALSE
Devin Lim44075962017-08-11 10:56:37 -0700352
353 main.cleanAndExit()
Jon Hallde9d9aa2014-10-08 20:36:02 -0400354 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800355 main.log.error( self.name + ": EOF exception found" )
356 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700357 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800358 except Exception:
359 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700360 main.cleanAndExit()
Jon Hallacabffd2014-10-09 12:36:53 -0400361
Jon Hall3576f572016-08-23 10:01:07 -0700362 def buckBuild( self, timeout=180 ):
363 """
364 Build onos using buck.
365 """
366 try:
367 ret = main.TRUE
368 self.handle.sendline( "buck build onos" )
369 self.handle.expect( "buck build onos" )
370 output = ""
371 while True:
372 i = self.handle.expect( [ "This does not appear to be the root of a Buck project.",
373 "\n",
374 "BUILD FAILED",
Jon Halld9066132018-03-01 14:52:53 -0800375 "no buck in",
Devin Limc20e79a2017-06-07 10:29:57 -0700376 self.prompt ],
Jon Hall3576f572016-08-23 10:01:07 -0700377 timeout=timeout )
378 output += str( self.handle.before + self.handle.after )
379 if i == 0:
380 main.log.error( "Wrong location" )
381 ret = main.FALSE
382 elif i == 1:
383 # end of a line, buck is still printing output
384 pass
385 elif i == 2:
386 # Build failed
387 main.log.error( "Build failed" )
388 ret = main.FALSE
389 elif i == 3:
Jon Halld9066132018-03-01 14:52:53 -0800390 main.log.error( "Could not find buck in your PATH." )
391 ret = main.FALSE
392 elif i == 4:
Jon Hall3576f572016-08-23 10:01:07 -0700393 # Prompt returned
394 break
395 main.log.debug( output )
396 return ret
397 except pexpect.TIMEOUT:
398 main.log.exception( self.name + ": TIMEOUT exception found" )
399 main.log.error( self.name + ": " + self.handle.before )
You Wang141b43b2018-06-26 16:50:18 -0700400 self.handle.send( "\x03" ) # Control-C
401 self.handle.expect( self.prompt )
Jon Hall3576f572016-08-23 10:01:07 -0700402 return main.FALSE
403 except pexpect.EOF:
404 main.log.error( self.name + ": EOF exception found" )
405 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700406 main.cleanAndExit()
Jon Hall3576f572016-08-23 10:01:07 -0700407 except Exception:
408 main.log.exception( "Failed to build and package ONOS" )
Devin Lim44075962017-08-11 10:56:37 -0700409 main.cleanAndExit()
Jon Hall3576f572016-08-23 10:01:07 -0700410
You Wangd54c7052018-08-07 16:06:27 -0700411 def bazelBuild( self, timeout=180 ):
412 """
413 Build onos using bazel.
414 """
415 try:
416 ret = main.TRUE
417 self.handle.sendline( "bazel build onos" )
418 self.handle.expect( "bazel build onos" )
419 output = ""
420 while True:
421 i = self.handle.expect( [ "command is only supported from within a workspace",
422 "\n",
423 "FAILED",
424 "ERROR",
425 "command not found",
426 self.prompt ],
427 timeout=timeout )
428 output += str( self.handle.before + self.handle.after )
429 if i == 0:
430 main.log.error( "Please run the build from root of ONOS project" )
431 ret = main.FALSE
432 elif i == 1:
433 # end of a line, buck is still printing output
434 pass
435 elif i == 2:
436 # Build failed
437 main.log.error( "Build failed" )
438 ret = main.FALSE
439 elif i == 3:
440 # Build failed
441 main.log.error( "Build failed" )
442 ret = main.FALSE
443 elif i == 4:
444 main.log.error( "Command not found" )
445 ret = main.FALSE
446 elif i == 5:
447 # Prompt returned
448 break
449 main.log.debug( output )
450 return ret
451 except pexpect.TIMEOUT:
452 main.log.exception( self.name + ": TIMEOUT exception found" )
453 main.log.error( self.name + ": " + self.handle.before )
454 self.handle.send( "\x03" ) # Control-C
455 self.handle.expect( self.prompt )
456 return main.FALSE
457 except pexpect.EOF:
458 main.log.error( self.name + ": EOF exception found" )
459 main.log.error( self.name + ": " + self.handle.before )
460 main.cleanAndExit()
461 except Exception:
462 main.log.exception( "Failed to build and package ONOS" )
463 main.cleanAndExit()
464
Jon Hall61282e32015-03-19 11:34:11 -0700465 def gitPull( self, comp1="", fastForward=True ):
kelvin8ec71442015-01-15 16:57:00 -0800466 """
Jon Hallacabffd2014-10-09 12:36:53 -0400467 Assumes that "git pull" works without login
Jon Hall47a93fb2015-01-06 16:46:06 -0800468
Jon Hall61282e32015-03-19 11:34:11 -0700469 If the fastForward boolean is set to true, only git pulls that can
470 be fast forwarded will be performed. IE if you have not local commits
471 in your branch.
472
Jon Hallacabffd2014-10-09 12:36:53 -0400473 This function will perform a git pull on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800474 If used as gitPull( "NODE" ) it will do git pull + NODE. This is
Jon Hallacabffd2014-10-09 12:36:53 -0400475 for the purpose of pulling from other nodes if necessary.
476
Jon Hall47a93fb2015-01-06 16:46:06 -0800477 Otherwise, this function will perform a git pull in the
Jon Hallacabffd2014-10-09 12:36:53 -0400478 ONOS repository. If it has any problems, it will return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -0800479 If it successfully does a gitPull, it will return a 1 ( main.TRUE )
Shreya Shahee15f6c2014-10-28 18:12:30 -0400480 If it has no updates, it will return 3.
Jon Hallacabffd2014-10-09 12:36:53 -0400481
kelvin8ec71442015-01-15 16:57:00 -0800482 """
Jon Hallacabffd2014-10-09 12:36:53 -0400483 try:
kelvin8ec71442015-01-15 16:57:00 -0800484 self.handle.sendline( "cd " + self.home )
Devin Limc20e79a2017-06-07 10:29:57 -0700485 self.handle.expect( self.prompt )
Jon Hall61282e32015-03-19 11:34:11 -0700486 cmd = "git pull"
487 if comp1 != "":
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700488 cmd += ' ' + comp1
Jon Hall61282e32015-03-19 11:34:11 -0700489 if fastForward:
490 cmd += ' ' + " --ff-only"
491 self.handle.sendline( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800492 i = self.handle.expect(
493 [
494 'fatal',
495 'Username\sfor\s(.*):\s',
496 '\sfile(s*) changed,\s',
497 'Already up-to-date',
498 'Aborting',
499 'You\sare\snot\scurrently\son\sa\sbranch',
Jon Hall274b6642015-02-17 11:57:17 -0800500 'You asked me to pull without telling me which branch you',
501 'Pull is not possible because you have unmerged files',
Jon Hall61282e32015-03-19 11:34:11 -0700502 'Please enter a commit message to explain why this merge',
503 'Found a swap file by the name',
504 'Please, commit your changes before you can merge.',
kelvin-onlabd3b64892015-01-20 13:26:24 -0800505 pexpect.TIMEOUT ],
506 timeout=300 )
kelvin8ec71442015-01-15 16:57:00 -0800507 if i == 0:
Jon Hall61282e32015-03-19 11:34:11 -0700508 main.log.error( self.name + ": Git pull had some issue" )
509 output = self.handle.after
Devin Limdc78e202017-06-09 18:30:07 -0700510 self.handle.expect( self.prompt )
Jon Hall61282e32015-03-19 11:34:11 -0700511 output += self.handle.before
512 main.log.warn( output )
Jon Hallacabffd2014-10-09 12:36:53 -0400513 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800514 elif i == 1:
515 main.log.error(
516 self.name +
517 ": Git Pull Asking for username. " )
Jon Hallacabffd2014-10-09 12:36:53 -0400518 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800519 elif i == 2:
520 main.log.info(
521 self.name +
522 ": Git Pull - pulling repository now" )
Devin Limc20e79a2017-06-07 10:29:57 -0700523 self.handle.expect( self.prompt, 120 )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800524 # So that only when git pull is done, we do mvn clean compile
525 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800526 elif i == 3:
527 main.log.info( self.name + ": Git Pull - Already up to date" )
Devin Limc20e79a2017-06-07 10:29:57 -0700528 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800529 elif i == 4:
530 main.log.info(
531 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800532 ": Git Pull - Aborting..." +
533 "Are there conflicting git files?" )
Jon Hallacabffd2014-10-09 12:36:53 -0400534 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800535 elif i == 5:
536 main.log.info(
537 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800538 ": Git Pull - You are not currently " +
539 "on a branch so git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400540 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800541 elif i == 6:
542 main.log.info(
543 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800544 ": Git Pull - You have not configured an upstream " +
545 "branch to pull from. Git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400546 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800547 elif i == 7:
548 main.log.info(
549 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800550 ": Git Pull - Pull is not possible because " +
551 "you have unmerged files." )
Jon Hallacabffd2014-10-09 12:36:53 -0400552 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800553 elif i == 8:
Jon Hall61282e32015-03-19 11:34:11 -0700554 # NOTE: abandoning test since we can't reliably handle this
555 # there could be different default text editors and we
556 # also don't know if we actually want to make the commit
557 main.log.error( "Git pull resulted in a merge commit message" +
558 ". Exiting test!" )
Devin Lim44075962017-08-11 10:56:37 -0700559
560 main.cleanAndExit()
Jon Hall61282e32015-03-19 11:34:11 -0700561 elif i == 9: # Merge commit message but swap file exists
562 main.log.error( "Git pull resulted in a merge commit message" +
563 " but a swap file exists." )
564 try:
565 self.handle.send( 'A' ) # Abort
Devin Limc20e79a2017-06-07 10:29:57 -0700566 self.handle.expect( self.prompt )
Jon Hall61282e32015-03-19 11:34:11 -0700567 return main.ERROR
568 except Exception:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700569 main.log.exception( "Couldn't exit editor prompt!" )
Devin Lim44075962017-08-11 10:56:37 -0700570
571 main.cleanAndExit()
Jon Hall61282e32015-03-19 11:34:11 -0700572 elif i == 10: # In the middle of a merge commit
573 main.log.error( "Git branch is in the middle of a merge. " )
574 main.log.warn( self.handle.before + self.handle.after )
575 return main.ERROR
576 elif i == 11:
kelvin8ec71442015-01-15 16:57:00 -0800577 main.log.error( self.name + ": Git Pull - TIMEOUT" )
578 main.log.error(
579 self.name + " Response was: " + str(
580 self.handle.before ) )
You Wang141b43b2018-06-26 16:50:18 -0700581 self.handle.send( "\x03" ) # Control-C
582 self.handle.expect( self.prompt )
Jon Hallacabffd2014-10-09 12:36:53 -0400583 return main.ERROR
584 else:
kelvin8ec71442015-01-15 16:57:00 -0800585 main.log.error(
586 self.name +
587 ": Git Pull - Unexpected response, check for pull errors" )
Jon Hallacabffd2014-10-09 12:36:53 -0400588 return main.ERROR
589 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800590 main.log.error( self.name + ": EOF exception found" )
591 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700592 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800593 except Exception:
594 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700595 main.cleanAndExit()
Jon Hallacabffd2014-10-09 12:36:53 -0400596
kelvin-onlabd3b64892015-01-20 13:26:24 -0800597 def gitCheckout( self, branch="master" ):
kelvin8ec71442015-01-15 16:57:00 -0800598 """
Jon Hallacabffd2014-10-09 12:36:53 -0400599 Assumes that "git pull" works without login
kelvin8ec71442015-01-15 16:57:00 -0800600
Jon Hallacabffd2014-10-09 12:36:53 -0400601 This function will perform a git git checkout on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800602 If used as gitCheckout( "branch" ) it will do git checkout
603 of the "branch".
Jon Hallacabffd2014-10-09 12:36:53 -0400604
605 Otherwise, this function will perform a git checkout of the master
kelvin8ec71442015-01-15 16:57:00 -0800606 branch of the ONOS repository. If it has any problems, it will return
607 main.ERROR.
608 If the branch was already the specified branch, or the git checkout was
Jon Hallacabffd2014-10-09 12:36:53 -0400609 successful then the function will return main.TRUE.
610
kelvin8ec71442015-01-15 16:57:00 -0800611 """
Jon Hallacabffd2014-10-09 12:36:53 -0400612 try:
kelvin8ec71442015-01-15 16:57:00 -0800613 self.handle.sendline( "cd " + self.home )
Devin Limc20e79a2017-06-07 10:29:57 -0700614 self.handle.expect( self.prompt )
Jon Hall274b6642015-02-17 11:57:17 -0800615 main.log.info( self.name +
616 ": Checking out git branch/ref: " + branch + "..." )
kelvin8ec71442015-01-15 16:57:00 -0800617 cmd = "git checkout " + branch
618 self.handle.sendline( cmd )
619 self.handle.expect( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800620 i = self.handle.expect(
Jon Hall274b6642015-02-17 11:57:17 -0800621 [ 'fatal',
Jon Hall61282e32015-03-19 11:34:11 -0700622 'Username for (.*): ',
623 'Already on \'',
Jon Hall7a8354f2015-06-10 15:37:00 -0700624 'Switched to (a new )?branch \'' + str( branch ),
Jon Hall274b6642015-02-17 11:57:17 -0800625 pexpect.TIMEOUT,
626 'error: Your local changes to the following files' +
Jon Hallefbd9792015-03-05 16:11:36 -0800627 'would be overwritten by checkout:',
Jon Hall274b6642015-02-17 11:57:17 -0800628 'error: you need to resolve your current index first',
629 "You are in 'detached HEAD' state.",
630 "HEAD is now at " ],
kelvin-onlabd3b64892015-01-20 13:26:24 -0800631 timeout=60 )
kelvin8ec71442015-01-15 16:57:00 -0800632 if i == 0:
633 main.log.error(
634 self.name +
635 ": Git checkout had some issue..." )
636 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400637 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800638 elif i == 1:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800639 main.log.error(
640 self.name +
641 ": Git checkout asking for username." +
642 " Please configure your local git repository to be able " +
643 "to access your remote repository passwordlessly" )
Jon Hall274b6642015-02-17 11:57:17 -0800644 # TODO add support for authenticating
Jon Hallacabffd2014-10-09 12:36:53 -0400645 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800646 elif i == 2:
647 main.log.info(
648 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800649 ": Git Checkout %s : Already on this branch" % branch )
Devin Limc20e79a2017-06-07 10:29:57 -0700650 self.handle.expect( self.prompt )
Jon Hall3c0114c2020-08-11 15:07:42 -0700651 # main.log.info( self.name + ": DEBUG: after checkout cmd = "+
kelvin8ec71442015-01-15 16:57:00 -0800652 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400653 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800654 elif i == 3:
655 main.log.info(
656 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800657 ": Git checkout %s - Switched to this branch" % branch )
Devin Limc20e79a2017-06-07 10:29:57 -0700658 self.handle.expect( self.prompt )
Jon Hall3c0114c2020-08-11 15:07:42 -0700659 # main.log.info( self.name + ": DEBUG: after checkout cmd = "+
kelvin8ec71442015-01-15 16:57:00 -0800660 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400661 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800662 elif i == 4:
663 main.log.error( self.name + ": Git Checkout- TIMEOUT" )
664 main.log.error(
Jon Hall274b6642015-02-17 11:57:17 -0800665 self.name + " Response was: " + str( self.handle.before ) )
You Wang141b43b2018-06-26 16:50:18 -0700666 self.handle.send( "\x03" ) # Control-C
667 self.handle.expect( self.prompt )
Jon Hallacabffd2014-10-09 12:36:53 -0400668 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800669 elif i == 5:
670 self.handle.expect( "Aborting" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800671 main.log.error(
672 self.name +
673 ": Git checkout error: \n" +
Jon Hall274b6642015-02-17 11:57:17 -0800674 "Your local changes to the following files would" +
675 " be overwritten by checkout:" +
676 str( self.handle.before ) )
Devin Limc20e79a2017-06-07 10:29:57 -0700677 self.handle.expect( self.prompt )
Jon Hall81e29af2014-11-04 20:41:23 -0500678 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800679 elif i == 6:
Jon Hall274b6642015-02-17 11:57:17 -0800680 main.log.error(
681 self.name +
682 ": Git checkout error: \n" +
683 "You need to resolve your current index first:" +
684 str( self.handle.before ) )
Devin Limc20e79a2017-06-07 10:29:57 -0700685 self.handle.expect( self.prompt )
Jon Hall81e29af2014-11-04 20:41:23 -0500686 return main.ERROR
Jon Hall274b6642015-02-17 11:57:17 -0800687 elif i == 7:
688 main.log.info(
689 self.name +
690 ": Git checkout " + str( branch ) +
691 " - You are in 'detached HEAD' state. HEAD is now at " +
692 str( branch ) )
Devin Limc20e79a2017-06-07 10:29:57 -0700693 self.handle.expect( self.prompt )
Jon Hall274b6642015-02-17 11:57:17 -0800694 return main.TRUE
695 elif i == 8: # Already in detached HEAD on the specified commit
696 main.log.info(
697 self.name +
698 ": Git Checkout %s : Already on commit" % branch )
Devin Limc20e79a2017-06-07 10:29:57 -0700699 self.handle.expect( self.prompt )
Jon Hall274b6642015-02-17 11:57:17 -0800700 return main.TRUE
Jon Hallacabffd2014-10-09 12:36:53 -0400701 else:
kelvin8ec71442015-01-15 16:57:00 -0800702 main.log.error(
703 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800704 ": Git Checkout - Unexpected response, " +
705 "check for pull errors" )
kelvin8ec71442015-01-15 16:57:00 -0800706 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400707 return main.ERROR
708
709 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800710 main.log.error( self.name + ": EOF exception found" )
711 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700712 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800713 except Exception:
714 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700715 main.cleanAndExit()
andrewonlab95ca1462014-10-09 14:04:24 -0400716
pingping-lin6d23d9e2015-02-02 16:54:24 -0800717 def getBranchName( self ):
You Wang9cdf9a22017-05-01 13:44:18 -0700718 import re
719 try:
Jon Hall3e6edb32018-08-21 16:20:30 -0700720 main.log.info( self.name + " home is " + self.home )
You Wang9cdf9a22017-05-01 13:44:18 -0700721 self.handle.sendline( "cd " + self.home )
Devin Limc20e79a2017-06-07 10:29:57 -0700722 self.handle.expect( self.prompt )
You Wang9cdf9a22017-05-01 13:44:18 -0700723 self.handle.sendline( "git name-rev --name-only HEAD" )
724 self.handle.expect( "git name-rev --name-only HEAD" )
Devin Limc20e79a2017-06-07 10:29:57 -0700725 self.handle.expect( self.prompt )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700726 lines = self.handle.before.splitlines()
727 if lines[ 1 ] == "master" or re.search( "^onos-\d+(\.\d+)+$", lines[ 1 ] ):
728 return lines[ 1 ]
You Wang9cdf9a22017-05-01 13:44:18 -0700729 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700730 main.log.info( lines[ 1 ] )
You Wang9cdf9a22017-05-01 13:44:18 -0700731 return "unexpected ONOS branch"
732 except pexpect.EOF:
733 main.log.error( self.name + ": EOF exception found" )
734 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700735 main.cleanAndExit()
You Wang9cdf9a22017-05-01 13:44:18 -0700736 except pexpect.TIMEOUT:
737 main.log.error( self.name + ": TIMEOUT exception found" )
738 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700739 main.cleanAndExit()
You Wang9cdf9a22017-05-01 13:44:18 -0700740 except Exception:
741 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700742 main.cleanAndExit()
pingping-lin6d23d9e2015-02-02 16:54:24 -0800743
kelvin-onlabd3b64892015-01-20 13:26:24 -0800744 def getVersion( self, report=False ):
kelvin8ec71442015-01-15 16:57:00 -0800745 """
Jon Hall274b6642015-02-17 11:57:17 -0800746 Writes the COMMIT number to the report to be parsed
Jon Hallefbd9792015-03-05 16:11:36 -0800747 by Jenkins data collector.
kelvin8ec71442015-01-15 16:57:00 -0800748 """
Jon Hall45ec0922014-10-10 19:33:49 -0400749 try:
kelvin8ec71442015-01-15 16:57:00 -0800750 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -0700751 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -0800752 self.handle.sendline(
753 "cd " +
754 self.home +
Jon Hall274b6642015-02-17 11:57:17 -0800755 "; git log -1 --pretty=fuller --decorate=short | grep -A 6 " +
756 " \"commit\" --color=never" )
kelvin8ec71442015-01-15 16:57:00 -0800757 # NOTE: for some reason there are backspaces inserted in this
758 # phrase when run from Jenkins on some tests
759 self.handle.expect( "never" )
Devin Limc20e79a2017-06-07 10:29:57 -0700760 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -0800761 response = ( self.name + ": \n" + str(
762 self.handle.before + self.handle.after ) )
763 self.handle.sendline( "cd " + self.home )
Devin Limc20e79a2017-06-07 10:29:57 -0700764 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -0800765 lines = response.splitlines()
Jon Hall45ec0922014-10-10 19:33:49 -0400766 for line in lines:
Jon Hallfd191202014-11-07 18:36:09 -0500767 print line
768 if report:
pingping-lin763ee042015-05-20 17:45:30 -0700769 main.log.wiki( "<blockquote>" )
kelvin8ec71442015-01-15 16:57:00 -0800770 for line in lines[ 2:-1 ]:
771 # Bracket replacement is for Wiki-compliant
772 # formatting. '<' or '>' are interpreted
773 # as xml specific tags that cause errors
774 line = line.replace( "<", "[" )
775 line = line.replace( ">", "]" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700776 # main.log.wiki( "\t" + line )
pingping-lin763ee042015-05-20 17:45:30 -0700777 main.log.wiki( line + "<br /> " )
778 main.log.summary( line )
779 main.log.wiki( "</blockquote>" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700780 main.log.summary( "\n" )
kelvin8ec71442015-01-15 16:57:00 -0800781 return lines[ 2 ]
Jon Hall45ec0922014-10-10 19:33:49 -0400782 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800783 main.log.error( self.name + ": EOF exception found" )
784 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700785 main.cleanAndExit()
Jon Hall368769f2014-11-19 15:43:35 -0800786 except pexpect.TIMEOUT:
kelvin8ec71442015-01-15 16:57:00 -0800787 main.log.error( self.name + ": TIMEOUT exception found" )
788 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700789 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800790 except Exception:
791 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700792 main.cleanAndExit()
Jon Hall45ec0922014-10-10 19:33:49 -0400793
kelvin-onlabd3b64892015-01-20 13:26:24 -0800794 def createCellFile( self, benchIp, fileName, mnIpAddrs,
Jon Hall3e6edb32018-08-21 16:20:30 -0700795 appString, onosIpAddrs, atomixIps,
796 onosUser="sdn", useSSH=True ):
kelvin8ec71442015-01-15 16:57:00 -0800797 """
andrewonlab94282092014-10-10 13:00:11 -0400798 Creates a cell file based on arguments
799 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800800 * Bench IP address ( benchIp )
andrewonlab94282092014-10-10 13:00:11 -0400801 - Needed to copy the cell file over
kelvin-onlabd3b64892015-01-20 13:26:24 -0800802 * File name of the cell file ( fileName )
803 * Mininet IP address ( mnIpAddrs )
kelvin8ec71442015-01-15 16:57:00 -0800804 - Note that only 1 ip address is
andrewonlab94282092014-10-10 13:00:11 -0400805 supported currently
kelvin-onlabd3b64892015-01-20 13:26:24 -0800806 * ONOS IP addresses ( onosIpAddrs )
andrewonlab94282092014-10-10 13:00:11 -0400807 - Must be passed in as last arguments
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000808 * ONOS USER (onosUser)
Flavio Castrocc38a542016-03-03 13:15:46 -0800809 - optional argument to set ONOS_USER environment variable
kelvin8ec71442015-01-15 16:57:00 -0800810
andrewonlab94282092014-10-10 13:00:11 -0400811 NOTE: Assumes cells are located at:
812 ~/<self.home>/tools/test/cells/
kelvin8ec71442015-01-15 16:57:00 -0800813 """
andrewonlab94282092014-10-10 13:00:11 -0400814 try:
Devin Lim461f0872017-06-05 16:49:33 -0700815
Jon Hall2c8959e2016-12-16 12:17:34 -0800816 # Variable initialization
817 cellDirectory = self.home + "/tools/test/cells/"
818 # We want to create the cell file in the dependencies directory
819 # of TestON first, then copy over to ONOS bench
820 tempDirectory = "/tmp/"
821 # Create the cell file in the directory for writing ( w+ )
822 cellFile = open( tempDirectory + fileName, 'w+' )
823 if isinstance( onosIpAddrs, types.StringType ):
824 onosIpAddrs = [ onosIpAddrs ]
Jon Hall3e6edb32018-08-21 16:20:30 -0700825 if isinstance( atomixIps, types.StringType ):
826 atomixIps = [ atomixIps ]
Jon Hall2c8959e2016-12-16 12:17:34 -0800827
828 # App string is hardcoded environment variables
829 # That you may wish to use by default on startup.
830 # Note that you may not want certain apps listed
831 # on here.
832 appString = "export ONOS_APPS=" + appString
833 onosGroup = "export ONOS_GROUP=" + onosUser
Jon Hall9b0de1f2020-08-24 15:38:04 -0700834 onosWebUser = "export ONOS_WEB_USER=" + self.webUser
835 onosWebPass = "export ONOS_WEB_PASS=" + self.webPass
Jon Hall2c8959e2016-12-16 12:17:34 -0800836 onosUser = "export ONOS_USER=" + onosUser
837 if useSSH:
838 onosUseSSH = "export ONOS_USE_SSH=true"
839 mnString = "export OCN="
840 if mnIpAddrs == "":
841 mnString = ""
842 onosString = "export OC"
Jon Hall3e6edb32018-08-21 16:20:30 -0700843 atomixString = "export OCC"
Jon Hall2c8959e2016-12-16 12:17:34 -0800844
845 # Create ONOSNIC ip address prefix
846 tempOnosIp = str( onosIpAddrs[ 0 ] )
847 tempList = []
848 tempList = tempOnosIp.split( "." )
849 # Omit last element of list to format for NIC
850 tempList = tempList[ :-1 ]
851 # Structure the nic string ip
852 nicAddr = ".".join( tempList ) + ".*"
853 self.nicAddr = nicAddr
854 onosNicString = "export ONOS_NIC=" + nicAddr
855
kelvin8ec71442015-01-15 16:57:00 -0800856 # Start writing to file
kelvin-onlabd3b64892015-01-20 13:26:24 -0800857 cellFile.write( onosNicString + "\n" )
andrewonlab94282092014-10-10 13:00:11 -0400858
Jon Hall3e6edb32018-08-21 16:20:30 -0700859 onosIndex = 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800860 for arg in onosIpAddrs:
861 # For each argument in onosIpAddrs, write to file
kelvin8ec71442015-01-15 16:57:00 -0800862 # Output should look like the following:
andrewonlabd4940492014-10-24 12:21:27 -0400863 # export OC1="10.128.20.11"
864 # export OC2="10.128.20.12"
Jon Hall3e6edb32018-08-21 16:20:30 -0700865 cellFile.write( onosString + str( onosIndex ) +
Jon Hall6f665652015-09-18 10:08:07 -0700866 "=\"" + arg + "\"\n" )
Jon Hall3e6edb32018-08-21 16:20:30 -0700867 onosIndex = onosIndex + 1
868
869 atomixIndex = 1
870 for ip in atomixIps:
871 cellFile.write( atomixString + str( atomixIndex ) +
872 "=\"" + ip + "\"\n" )
873 atomixIndex += 1
kelvin8ec71442015-01-15 16:57:00 -0800874
Jon Hall6f665652015-09-18 10:08:07 -0700875 cellFile.write( "export OCI=$OC1\n" )
Jon Hallab611372018-02-21 15:26:05 -0800876 if mnString:
877 cellFile.write( mnString + "\"" + str( mnIpAddrs ) + "\"\n" )
cameron@onlab.us75900962015-03-30 13:22:49 -0700878 cellFile.write( appString + "\n" )
Flavio Castrocc38a542016-03-03 13:15:46 -0800879 cellFile.write( onosGroup + "\n" )
880 cellFile.write( onosUser + "\n" )
Jon Hall9b0de1f2020-08-24 15:38:04 -0700881 cellFile.write( onosWebUser + "\n" )
882 cellFile.write( onosWebPass + "\n" )
Pier88189b62016-09-07 17:01:53 -0700883 if useSSH:
884 cellFile.write( onosUseSSH + "\n" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800885 cellFile.close()
andrewonlab94282092014-10-10 13:00:11 -0400886
kelvin8ec71442015-01-15 16:57:00 -0800887 # We use os.system to send the command to TestON cluster
888 # to account for the case in which TestON is not located
889 # on the same cluster as the ONOS bench
890 # Note that even if TestON is located on the same cluster
891 # as ONOS bench, you must setup passwordless ssh
892 # between TestON and ONOS bench in order to automate the test.
kelvin-onlabc2b79102015-07-14 11:41:20 -0700893 os.system( "scp " + tempDirectory + fileName + " " +
894 self.user_name + "@" + self.ip_address + ":" + cellDirectory )
andrewonlab94282092014-10-10 13:00:11 -0400895
andrewonlab2a6c9342014-10-16 13:40:15 -0400896 return main.TRUE
897
andrewonlab94282092014-10-10 13:00:11 -0400898 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800899 main.log.error( self.name + ": EOF exception found" )
900 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700901 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800902 except Exception:
903 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700904 main.cleanAndExit()
andrewonlab94282092014-10-10 13:00:11 -0400905
kelvin-onlabd3b64892015-01-20 13:26:24 -0800906 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800907 """
andrewonlab95ca1462014-10-09 14:04:24 -0400908 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800909 """
andrewonlab95ca1462014-10-09 14:04:24 -0400910 try:
911 if not cellname:
You Wang1cdc5f52017-12-19 16:47:51 -0800912 main.log.error( self.name + ": Must define cellname" )
Devin Lim44075962017-08-11 10:56:37 -0700913 main.cleanAndExit()
andrewonlab95ca1462014-10-09 14:04:24 -0400914 else:
kelvin8ec71442015-01-15 16:57:00 -0800915 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800916 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800917 # Note that this variable name is subject to change
andrewonlab95ca1462014-10-09 14:04:24 -0400918 # and that this driver will have to change accordingly
Jon Hall3b489db2015-10-05 14:38:37 -0700919 self.handle.expect( str( cellname ) )
Jon Hallab611372018-02-21 15:26:05 -0800920 response = self.handle.before + self.handle.after
You Wang1cdc5f52017-12-19 16:47:51 -0800921 i = self.handle.expect( [ "No such cell",
Jon Hallab611372018-02-21 15:26:05 -0800922 "command not found",
923 self.prompt ], timeout=10 )
924 response += self.handle.before + self.handle.after
You Wang1cdc5f52017-12-19 16:47:51 -0800925 if i == 0:
Jon Hallab611372018-02-21 15:26:05 -0800926 main.log.error( self.name + ": No such cell. Response: " + str( response ) )
You Wang1cdc5f52017-12-19 16:47:51 -0800927 main.cleanAndExit()
928 elif i == 1:
Jon Hallab611372018-02-21 15:26:05 -0800929 main.log.error( self.name + ": Error setting cell. Response: " + str( response ) )
930 main.cleanAndExit()
You Wang1cdc5f52017-12-19 16:47:51 -0800931 elif i == 2:
Jon Hallab611372018-02-21 15:26:05 -0800932 main.log.info( self.name + ": Successfully set cell: " + str( response ) )
andrewonlab95ca1462014-10-09 14:04:24 -0400933 return main.TRUE
You Wang1cdc5f52017-12-19 16:47:51 -0800934 except pexpect.TIMEOUT:
935 main.log.error( self.name + ": TIMEOUT exception found" )
936 main.log.error( self.name + ": " + self.handle.before )
937 main.cleanAndExit()
andrewonlab95ca1462014-10-09 14:04:24 -0400938 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800939 main.log.error( self.name + ": EOF exception found" )
940 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700941 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800942 except Exception:
943 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700944 main.cleanAndExit()
andrewonlab95ca1462014-10-09 14:04:24 -0400945
kelvin-onlabd3b64892015-01-20 13:26:24 -0800946 def verifyCell( self ):
kelvin8ec71442015-01-15 16:57:00 -0800947 """
andrewonlabc03bf6c2014-10-09 14:56:18 -0400948 Calls 'onos-verify-cell' to check for cell installation
kelvin8ec71442015-01-15 16:57:00 -0800949 """
950 # TODO: Add meaningful expect value
andrewonlab8d0d7d72014-10-09 16:33:15 -0400951
andrewonlabc03bf6c2014-10-09 14:56:18 -0400952 try:
kelvin8ec71442015-01-15 16:57:00 -0800953 # Clean handle by sending empty and expecting $
954 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -0700955 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -0800956 self.handle.sendline( "onos-verify-cell" )
Devin Limc20e79a2017-06-07 10:29:57 -0700957 self.handle.expect( self.prompt )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800958 handleBefore = self.handle.before
959 handleAfter = self.handle.after
Jon Hall3c0114c2020-08-11 15:07:42 -0700960 main.log.info( self.name + ": Verify cell returned: " + handleBefore +
Jon Hall3b489db2015-10-05 14:38:37 -0700961 handleAfter )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400962 return main.TRUE
Jon Hall3e6edb32018-08-21 16:20:30 -0700963 except pexpect.ExceptionPexpect:
Jon Hall3b489db2015-10-05 14:38:37 -0700964 main.log.exception( self.name + ": Pexpect exception found: " )
kelvin8ec71442015-01-15 16:57:00 -0800965 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700966 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800967 except Exception:
968 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700969 main.cleanAndExit()
Jon Hall7993bfc2014-10-09 16:30:14 -0400970
jenkins1e99e7b2015-04-02 18:15:39 -0700971 def onosCfgSet( self, ONOSIp, configName, configParam ):
972 """
973 Uses 'onos <node-ip> cfg set' to change a parameter value of an
Jon Hall4ba53f02015-07-29 13:07:41 -0700974 application.
975
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000976 ex)
jenkins1e99e7b2015-04-02 18:15:39 -0700977 onos 10.0.0.1 cfg set org.onosproject.myapp appSetting 1
jenkins1e99e7b2015-04-02 18:15:39 -0700978 ONOSIp = '10.0.0.1'
979 configName = 'org.onosproject.myapp'
980 configParam = 'appSetting 1'
jenkins1e99e7b2015-04-02 18:15:39 -0700981 """
Jon Hall72280bc2016-01-25 14:29:05 -0800982 try:
983 cfgStr = "onos {} cfg set {} {}".format( ONOSIp,
984 configName,
985 configParam )
986 self.handle.sendline( "" )
987 self.handle.expect( ":~" )
988 self.handle.sendline( cfgStr )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700989 self.handle.expect( "cfg set" )
Jon Hall72280bc2016-01-25 14:29:05 -0800990 self.handle.expect( ":~" )
jenkins1e99e7b2015-04-02 18:15:39 -0700991
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700992 paramValue = configParam.split( " " )[ 1 ]
993 paramName = configParam.split( " " )[ 0 ]
Jon Hall4ba53f02015-07-29 13:07:41 -0700994
Jon Hall72280bc2016-01-25 14:29:05 -0800995 checkStr = 'onos {} cfg get " {} {} " '.format( ONOSIp, configName, paramName )
Jon Hall4ba53f02015-07-29 13:07:41 -0700996
Jon Hall72280bc2016-01-25 14:29:05 -0800997 self.handle.sendline( checkStr )
998 self.handle.expect( ":~" )
jenkins1e99e7b2015-04-02 18:15:39 -0700999
Jon Hall72280bc2016-01-25 14:29:05 -08001000 if "value=" + paramValue + "," in self.handle.before:
Jon Hall3c0114c2020-08-11 15:07:42 -07001001 main.log.info( self.name + ": cfg " + configName + " successfully set to " + configParam )
Jon Hall72280bc2016-01-25 14:29:05 -08001002 return main.TRUE
Jon Hall3e6edb32018-08-21 16:20:30 -07001003 except pexpect.ExceptionPexpect:
Jon Hall72280bc2016-01-25 14:29:05 -08001004 main.log.exception( self.name + ": Pexpect exception found: " )
1005 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001006 main.cleanAndExit()
Jon Hall72280bc2016-01-25 14:29:05 -08001007 except Exception:
1008 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001009 main.cleanAndExit()
Jon Hall4ba53f02015-07-29 13:07:41 -07001010
You Wang54b1d672018-06-11 16:44:13 -07001011 def onosCli( self, ONOSIp, cmdstr, timeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -08001012 """
andrewonlab05e362f2014-10-10 00:40:57 -04001013 Uses 'onos' command to send various ONOS CLI arguments.
1014 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001015 * ONOSIp: specify the ip of the cell machine
andrewonlab94282092014-10-10 13:00:11 -04001016 * cmdstr: specify the command string to send
You Wang54b1d672018-06-11 16:44:13 -07001017 Optional:
1018 * timeout: pexpect timeout for running the command
kelvin8ec71442015-01-15 16:57:00 -08001019
1020 This function is intended to expose the entire karaf
andrewonlab6e20c342014-10-10 18:08:48 -04001021 CLI commands for ONOS. Try to use this function first
1022 before attempting to write a ONOS CLI specific driver
kelvin8ec71442015-01-15 16:57:00 -08001023 function.
1024 You can see a list of available 'cmdstr' arguments
andrewonlab6e20c342014-10-10 18:08:48 -04001025 by starting onos, and typing in 'onos' to enter the
1026 onos> CLI. Then, type 'help' to see the list of
kelvin8ec71442015-01-15 16:57:00 -08001027 available commands.
1028 """
andrewonlab05e362f2014-10-10 00:40:57 -04001029 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001030 if not ONOSIp:
kelvin8ec71442015-01-15 16:57:00 -08001031 main.log.error( "You must specify the IP address" )
andrewonlab05e362f2014-10-10 00:40:57 -04001032 return main.FALSE
1033 if not cmdstr:
kelvin8ec71442015-01-15 16:57:00 -08001034 main.log.error( "You must specify the command string" )
andrewonlab05e362f2014-10-10 00:40:57 -04001035 return main.FALSE
1036
kelvin8ec71442015-01-15 16:57:00 -08001037 cmdstr = str( cmdstr )
1038 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001039 self.handle.expect( self.prompt )
andrewonlab05e362f2014-10-10 00:40:57 -04001040
You Wangdd3dae52018-02-15 13:31:25 -08001041 self.handle.sendline( "onos-wait-for-start " + ONOSIp )
Jon Hall3c0114c2020-08-11 15:07:42 -07001042 i = self.handle.expect( [ self.prompt, "Password: " ] )
1043 if i == 1:
1044 self.handle.sendline( self.pwd )
1045 self.handle.expect( self.prompt )
You Wangdd3dae52018-02-15 13:31:25 -08001046
Jon Hall3c0114c2020-08-11 15:07:42 -07001047 self.handle.sendline( "ssh -q -p 8101 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null %s %s " % ( ONOSIp, cmdstr ) )
1048 i = self.handle.expect( [ self.prompt, "Password: ", pexpect.TIMEOUT ], timeout=timeout )
1049 if i == 1:
1050 self.handle.sendline( self.pwd )
1051 i = self.handle.expect( [ self.prompt, pexpect.TIMEOUT ], timeout=timeout )
You Wang54b1d672018-06-11 16:44:13 -07001052 if i == 0:
1053 handleBefore = self.handle.before
Jon Hall3c0114c2020-08-11 15:07:42 -07001054 main.log.info( self.name + ": Command sent successfully" )
You Wang54b1d672018-06-11 16:44:13 -07001055 # Obtain return handle that consists of result from
1056 # the onos command. The string may need to be
1057 # configured further.
1058 returnString = handleBefore
1059 return returnString
1060 elif i == 1:
1061 main.log.error( self.name + ": Timeout when sending " + cmdstr )
Jon Hall3c0114c2020-08-11 15:07:42 -07001062 main.log.debug( self.handle.before )
You Wang141b43b2018-06-26 16:50:18 -07001063 self.handle.send( "\x03" ) # Control-C
You Wang54b1d672018-06-11 16:44:13 -07001064 self.handle.expect( self.prompt )
1065 return main.FALSE
You Wangd66de192018-04-30 17:30:12 -07001066 except pexpect.TIMEOUT:
1067 main.log.exception( self.name + ": Timeout when sending " + cmdstr )
1068 return main.FALSE
andrewonlab05e362f2014-10-10 00:40:57 -04001069 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001070 main.log.error( self.name + ": EOF exception found" )
1071 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001072 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001073 except Exception:
1074 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001075 main.cleanAndExit()
Jon Hall7993bfc2014-10-09 16:30:14 -04001076
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001077 def onosSecureSSH( self, userName="onos", userPWD="rocks", node="" ):
Pier88189b62016-09-07 17:01:53 -07001078 """
1079 Enables secure access to ONOS console
1080 by removing default users & keys.
1081
1082 onos-secure-ssh -u onos -p rocks node
1083
1084 Returns: main.TRUE on success and main.FALSE on failure
1085 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001086
Pier88189b62016-09-07 17:01:53 -07001087 try:
Chiyu Chengef109502016-11-21 15:51:38 -08001088 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001089 self.handle.expect( self.prompt )
Pier88189b62016-09-07 17:01:53 -07001090 self.handle.sendline( " onos-secure-ssh -u " + userName + " -p " + userPWD + " " + node )
1091
1092 # NOTE: this timeout may need to change depending on the network
1093 # and size of ONOS
1094 # TODO: Handle the other possible error
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001095 i = self.handle.expect( [ "Network\sis\sunreachable",
1096 self.prompt,
1097 pexpect.TIMEOUT ], timeout=180 )
Pier88189b62016-09-07 17:01:53 -07001098 if i == 0:
1099 # can't reach ONOS node
Jon Hall3e6edb32018-08-21 16:20:30 -07001100 main.log.warn( self.name + ": Network is unreachable" )
Devin Limc20e79a2017-06-07 10:29:57 -07001101 self.handle.expect( self.prompt )
Pier88189b62016-09-07 17:01:53 -07001102 return main.FALSE
1103 elif i == 1:
1104 # Process started
Jon Hall3e6edb32018-08-21 16:20:30 -07001105 main.log.info( self.name + ": Secure SSH performed on " + node )
Pier88189b62016-09-07 17:01:53 -07001106 return main.TRUE
Jon Hall3e6edb32018-08-21 16:20:30 -07001107 elif i == 2:
1108 # timeout
1109 main.log.error( self.name + ": Failed to secure ssh on " + node )
1110 main.log.debug( self.handle.before )
Pier88189b62016-09-07 17:01:53 -07001111 except pexpect.EOF:
1112 main.log.error( self.name + ": EOF exception found" )
1113 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001114 main.cleanAndExit()
Pier88189b62016-09-07 17:01:53 -07001115 except Exception:
1116 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001117 main.cleanAndExit()
Pier88189b62016-09-07 17:01:53 -07001118
kelvin-onlabd3b64892015-01-20 13:26:24 -08001119 def onosInstall( self, options="-f", node="" ):
kelvin8ec71442015-01-15 16:57:00 -08001120 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001121 Installs ONOS bits on the designated cell machine.
kelvin8ec71442015-01-15 16:57:00 -08001122 If -f option is provided, it also forces an uninstall.
1123 Presently, install also includes onos-push-bits and
Jon Hall7993bfc2014-10-09 16:30:14 -04001124 onos-config within.
kelvin8ec71442015-01-15 16:57:00 -08001125 The node option allows you to selectively only push the jar
Jon Hall7993bfc2014-10-09 16:30:14 -04001126 files to certain onos nodes
1127
1128 Returns: main.TRUE on success and main.FALSE on failure
kelvin8ec71442015-01-15 16:57:00 -08001129 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001130 try:
andrewonlab114768a2014-11-14 12:44:44 -05001131 if options:
kelvin8ec71442015-01-15 16:57:00 -08001132 self.handle.sendline( "onos-install " + options + " " + node )
andrewonlab114768a2014-11-14 12:44:44 -05001133 else:
kelvin8ec71442015-01-15 16:57:00 -08001134 self.handle.sendline( "onos-install " + node )
1135 self.handle.expect( "onos-install " )
1136 # NOTE: this timeout may need to change depending on the network
1137 # and size of ONOS
1138 i = self.handle.expect( [ "Network\sis\sunreachable",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001139 "onos\sstart/running,\sprocess",
kelvin8ec71442015-01-15 16:57:00 -08001140 "ONOS\sis\salready\sinstalled",
Jon Hall3576f572016-08-23 10:01:07 -07001141 "does not exist",
Devin Limc20e79a2017-06-07 10:29:57 -07001142 self.prompt,
Jon Hall6c44c0b2016-04-20 15:21:00 -07001143 pexpect.TIMEOUT ], timeout=180 )
Jon Hall7993bfc2014-10-09 16:30:14 -04001144 if i == 0:
Jon Hall3576f572016-08-23 10:01:07 -07001145 # can't reach ONOS node
kelvin8ec71442015-01-15 16:57:00 -08001146 main.log.warn( "Network is unreachable" )
Devin Limc20e79a2017-06-07 10:29:57 -07001147 self.handle.expect( self.prompt )
Jon Hall7993bfc2014-10-09 16:30:14 -04001148 return main.FALSE
1149 elif i == 1:
Jon Hall3576f572016-08-23 10:01:07 -07001150 # Process started
kelvin8ec71442015-01-15 16:57:00 -08001151 main.log.info(
1152 "ONOS was installed on " +
1153 node +
1154 " and started" )
Devin Limc20e79a2017-06-07 10:29:57 -07001155 self.handle.expect( self.prompt )
Jon Hall7993bfc2014-10-09 16:30:14 -04001156 return main.TRUE
You Wangd65ba842018-08-14 11:20:59 -07001157 elif i == 2:
Jon Hall3576f572016-08-23 10:01:07 -07001158 # same bits are already on ONOS node
Jon Hall3c0114c2020-08-11 15:07:42 -07001159 main.log.info( self.name + ": ONOS is already installed on " + node )
Devin Limc20e79a2017-06-07 10:29:57 -07001160 self.handle.expect( self.prompt )
Jeremyc72b2582016-02-26 18:27:38 -08001161 return main.TRUE
You Wangd65ba842018-08-14 11:20:59 -07001162 elif i == 3:
Jon Hall3576f572016-08-23 10:01:07 -07001163 # onos not packaged
1164 main.log.error( "ONOS package not found." )
Devin Limc20e79a2017-06-07 10:29:57 -07001165 self.handle.expect( self.prompt )
Jon Hall3576f572016-08-23 10:01:07 -07001166 return main.FALSE
You Wangd65ba842018-08-14 11:20:59 -07001167 elif i == 4:
Jon Hall3576f572016-08-23 10:01:07 -07001168 # prompt
Jon Hall3c0114c2020-08-11 15:07:42 -07001169 main.log.info( self.name + ": ONOS was installed on {} {}.".format( node,
Jon Hall3e6edb32018-08-21 16:20:30 -07001170 "but not started" if 'n' in options else "and started" ) )
Jeremyc72b2582016-02-26 18:27:38 -08001171 return main.TRUE
You Wangd65ba842018-08-14 11:20:59 -07001172 elif i == 5:
Jon Hall3576f572016-08-23 10:01:07 -07001173 # timeout
kelvin8ec71442015-01-15 16:57:00 -08001174 main.log.info(
1175 "Installation of ONOS on " +
1176 node +
1177 " timed out" )
Devin Limc20e79a2017-06-07 10:29:57 -07001178 self.handle.expect( self.prompt )
Jon Hall53c5e662016-04-13 16:06:56 -07001179 main.log.warn( self.handle.before )
You Wang141b43b2018-06-26 16:50:18 -07001180 self.handle.send( "\x03" ) # Control-C
1181 self.handle.expect( self.prompt )
Jon Hall7993bfc2014-10-09 16:30:14 -04001182 return main.FALSE
andrewonlabc03bf6c2014-10-09 14:56:18 -04001183 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001184 main.log.error( self.name + ": EOF exception found" )
1185 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001186 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001187 except Exception:
1188 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001189 main.cleanAndExit()
andrewonlab95ca1462014-10-09 14:04:24 -04001190
kelvin-onlabd3b64892015-01-20 13:26:24 -08001191 def onosStart( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001192 """
andrewonlab8d0d7d72014-10-09 16:33:15 -04001193 Calls onos command: 'onos-service [<node-ip>] start'
andrewonlabe8e56fd2014-10-09 17:12:44 -04001194 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -08001195 """
andrewonlab8d0d7d72014-10-09 16:33:15 -04001196 try:
kelvin8ec71442015-01-15 16:57:00 -08001197 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001198 self.handle.expect( self.prompt )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001199 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001200 " start" )
1201 i = self.handle.expect( [
andrewonlab8d0d7d72014-10-09 16:33:15 -04001202 "Job\sis\salready\srunning",
1203 "start/running",
Devin Limc20e79a2017-06-07 10:29:57 -07001204 self.prompt,
andrewonlab8d0d7d72014-10-09 16:33:15 -04001205 "Unknown\sinstance",
Jeremy Songster14c13572016-04-21 17:34:03 -07001206 pexpect.TIMEOUT ], timeout=180 )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001207 if i == 0:
Devin Limc20e79a2017-06-07 10:29:57 -07001208 self.handle.expect( self.prompt )
Jon Hall3c0114c2020-08-11 15:07:42 -07001209 main.log.info( self.name + ": Service is already running" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001210 return main.TRUE
1211 elif i == 1:
Devin Limc20e79a2017-06-07 10:29:57 -07001212 self.handle.expect( self.prompt )
Jon Hall3c0114c2020-08-11 15:07:42 -07001213 main.log.info( self.name + ": ONOS service started" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001214 return main.TRUE
Jeremyd0e9a6d2016-03-02 11:28:52 -08001215 elif i == 2:
Jon Hall3c0114c2020-08-11 15:07:42 -07001216 main.log.info( self.name + ": ONOS service started" )
Jeremyd0e9a6d2016-03-02 11:28:52 -08001217 return main.TRUE
andrewonlab8d0d7d72014-10-09 16:33:15 -04001218 else:
Devin Limc20e79a2017-06-07 10:29:57 -07001219 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -08001220 main.log.error( "ONOS service failed to start" )
Devin Lim44075962017-08-11 10:56:37 -07001221
1222 main.cleanAndExit()
andrewonlab8d0d7d72014-10-09 16:33:15 -04001223 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001224 main.log.error( self.name + ": EOF exception found" )
1225 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001226 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001227 except Exception:
1228 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001229 main.cleanAndExit()
andrewonlab8d0d7d72014-10-09 16:33:15 -04001230
kelvin-onlabd3b64892015-01-20 13:26:24 -08001231 def onosStop( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001232 """
andrewonlab2b30bd32014-10-09 16:48:55 -04001233 Calls onos command: 'onos-service [<node-ip>] stop'
andrewonlabe8e56fd2014-10-09 17:12:44 -04001234 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -08001235 """
andrewonlab2b30bd32014-10-09 16:48:55 -04001236 try:
kelvin8ec71442015-01-15 16:57:00 -08001237 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001238 self.handle.expect( self.prompt )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001239 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001240 " stop" )
1241 i = self.handle.expect( [
andrewonlab2b30bd32014-10-09 16:48:55 -04001242 "stop/waiting",
Jon Hall61282e32015-03-19 11:34:11 -07001243 "Could not resolve hostname",
andrewonlab2b30bd32014-10-09 16:48:55 -04001244 "Unknown\sinstance",
Devin Limc20e79a2017-06-07 10:29:57 -07001245 self.prompt,
Jeremy Songster14c13572016-04-21 17:34:03 -07001246 pexpect.TIMEOUT ], timeout=180 )
andrewonlab2b30bd32014-10-09 16:48:55 -04001247 if i == 0:
Devin Limc20e79a2017-06-07 10:29:57 -07001248 self.handle.expect( self.prompt )
Jon Hall3c0114c2020-08-11 15:07:42 -07001249 main.log.info( self.name + ": ONOS service stopped" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001250 return main.TRUE
1251 elif i == 1:
Devin Limc20e79a2017-06-07 10:29:57 -07001252 self.handle.expect( self.prompt )
Jon Hall3c0114c2020-08-11 15:07:42 -07001253 main.log.info( self.name + ": onosStop() Unknown ONOS instance specified: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001254 str( nodeIp ) )
andrewonlab2b30bd32014-10-09 16:48:55 -04001255 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -07001256 elif i == 2:
Devin Limc20e79a2017-06-07 10:29:57 -07001257 self.handle.expect( self.prompt )
Jon Hall61282e32015-03-19 11:34:11 -07001258 main.log.warn( "ONOS wasn't running" )
1259 return main.TRUE
YPZhang77badfc2016-03-09 10:28:59 -08001260 elif i == 3:
Jon Hall3c0114c2020-08-11 15:07:42 -07001261 main.log.info( self.name + ": ONOS service stopped" )
YPZhang77badfc2016-03-09 10:28:59 -08001262 return main.TRUE
andrewonlab2b30bd32014-10-09 16:48:55 -04001263 else:
kelvin8ec71442015-01-15 16:57:00 -08001264 main.log.error( "ONOS service failed to stop" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001265 return main.FALSE
andrewonlab2b30bd32014-10-09 16:48:55 -04001266 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001267 main.log.error( self.name + ": EOF exception found" )
1268 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001269 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001270 except Exception:
1271 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001272 main.cleanAndExit()
kelvin8ec71442015-01-15 16:57:00 -08001273
kelvin-onlabd3b64892015-01-20 13:26:24 -08001274 def onosUninstall( self, nodeIp="" ):
kelvin8ec71442015-01-15 16:57:00 -08001275 """
andrewonlabc8d47972014-10-09 16:52:36 -04001276 Calls the command: 'onos-uninstall'
kelvin8ec71442015-01-15 16:57:00 -08001277 Uninstalls ONOS from the designated cell machine, stopping
andrewonlabe8e56fd2014-10-09 17:12:44 -04001278 if needed
kelvin8ec71442015-01-15 16:57:00 -08001279 """
andrewonlabc8d47972014-10-09 16:52:36 -04001280 try:
kelvin8ec71442015-01-15 16:57:00 -08001281 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001282 self.handle.expect( self.prompt, timeout=180 )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001283 self.handle.sendline( "onos-uninstall " + str( nodeIp ) )
Devin Limc20e79a2017-06-07 10:29:57 -07001284 self.handle.expect( self.prompt, timeout=180 )
Jon Hall3c0114c2020-08-11 15:07:42 -07001285 main.log.info( self.name + ": ONOS " + nodeIp + " was uninstalled" )
kelvin8ec71442015-01-15 16:57:00 -08001286 # onos-uninstall command does not return any text
andrewonlabc8d47972014-10-09 16:52:36 -04001287 return main.TRUE
pingping-lin763ee042015-05-20 17:45:30 -07001288 except pexpect.TIMEOUT:
1289 main.log.exception( self.name + ": Timeout in onosUninstall" )
You Wang141b43b2018-06-26 16:50:18 -07001290 self.handle.send( "\x03" ) # Control-C
1291 self.handle.expect( self.prompt )
pingping-lin763ee042015-05-20 17:45:30 -07001292 return main.FALSE
andrewonlabc8d47972014-10-09 16:52:36 -04001293 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001294 main.log.error( self.name + ": EOF exception found" )
1295 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001296 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001297 except Exception:
1298 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001299 main.cleanAndExit()
andrewonlab2b30bd32014-10-09 16:48:55 -04001300
kelvin-onlabd3b64892015-01-20 13:26:24 -08001301 def onosDie( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001302 """
andrewonlabaedc8332014-12-04 12:43:03 -05001303 Issues the command 'onos-die <node-ip>'
1304 This command calls onos-kill and also stops the node
kelvin8ec71442015-01-15 16:57:00 -08001305 """
andrewonlabaedc8332014-12-04 12:43:03 -05001306 try:
kelvin8ec71442015-01-15 16:57:00 -08001307 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001308 self.handle.expect( self.prompt )
Jon Hall214f88b2020-09-21 10:21:42 -07001309 if self.inDocker:
1310 return self.dockerStop( self.name )
1311 else:
1312 cmdStr = "onos-die " + str( nodeIp )
1313 self.handle.sendline( cmdStr )
1314 i = self.handle.expect( [
1315 "Killing\sONOS",
1316 "ONOS\sprocess\sis\snot\srunning",
1317 pexpect.TIMEOUT ], timeout=60 )
1318 if i == 0:
1319 main.log.info( self.name + ": ONOS instance " + str( nodeIp ) +
1320 " was killed and stopped" )
1321 self.handle.sendline( "" )
1322 self.handle.expect( self.prompt )
1323 return main.TRUE
1324 elif i == 1:
1325 main.log.info( self.name + ": ONOS process was not running" )
1326 self.handle.sendline( "" )
1327 self.handle.expect( self.prompt )
1328 return main.FALSE
andrewonlabaedc8332014-12-04 12:43:03 -05001329 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001330 main.log.error( self.name + ": EOF exception found" )
1331 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001332 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001333 except Exception:
1334 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001335 main.cleanAndExit()
andrewonlabaedc8332014-12-04 12:43:03 -05001336
kelvin-onlabd3b64892015-01-20 13:26:24 -08001337 def onosKill( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001338 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001339 Calls the command: 'onos-kill [<node-ip>]'
1340 "Remotely, and unceremoniously kills the ONOS instance running on
1341 the specified cell machine" - Tom V
kelvin8ec71442015-01-15 16:57:00 -08001342 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001343 try:
kelvin8ec71442015-01-15 16:57:00 -08001344 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001345 self.handle.expect( self.prompt )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001346 self.handle.sendline( "onos-kill " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -08001347 i = self.handle.expect( [
Devin Limc20e79a2017-06-07 10:29:57 -07001348 self.prompt,
andrewonlabe8e56fd2014-10-09 17:12:44 -04001349 "No\sroute\sto\shost",
1350 "password:",
Jeremy Songster14c13572016-04-21 17:34:03 -07001351 pexpect.TIMEOUT ], timeout=60 )
kelvin8ec71442015-01-15 16:57:00 -08001352
andrewonlabe8e56fd2014-10-09 17:12:44 -04001353 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001354 main.log.info(
1355 "ONOS instance " + str(
kelvin-onlabd3b64892015-01-20 13:26:24 -08001356 nodeIp ) + " was killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001357 return main.TRUE
1358 elif i == 1:
Jon Hall3c0114c2020-08-11 15:07:42 -07001359 main.log.info( self.name + ": No route to host" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001360 return main.FALSE
1361 elif i == 2:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001362 main.log.info(
1363 "Passwordless login for host: " +
1364 str( nodeIp ) +
1365 " not configured" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001366 return main.FALSE
1367 else:
Jon Hall3c0114c2020-08-11 15:07:42 -07001368 main.log.info( self.name + ": ONOS instance was not killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001369 return main.FALSE
kelvin8ec71442015-01-15 16:57:00 -08001370
andrewonlabe8e56fd2014-10-09 17:12:44 -04001371 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001372 main.log.error( self.name + ": EOF exception found" )
1373 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001374 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001375 except Exception:
1376 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001377 main.cleanAndExit()
andrewonlabe8e56fd2014-10-09 17:12:44 -04001378
You Wang5bf49592020-07-08 18:47:46 -07001379 def onosAppInstall( self, nodeIp, oarFile ):
1380 """
Jon Hall3c0114c2020-08-11 15:07:42 -07001381 Calls the command: 'onos-app nodeIp reinstall! oarFile'
You Wang5bf49592020-07-08 18:47:46 -07001382 Installs an ONOS application from an oar file
1383 """
1384 try:
Jon Hall3c0114c2020-08-11 15:07:42 -07001385 cmd = "onos-app " + str( nodeIp ) + " reinstall! " + str( oarFile )
You Wang5bf49592020-07-08 18:47:46 -07001386 self.handle.sendline( cmd )
Jon Hall3c0114c2020-08-11 15:07:42 -07001387 i = self.handle.expect( [ "409 Conflict", self.prompt ] )
1388 if i == 0:
1389 self.handle.expect( self.prompt )
1390 time.sleep( 30 )
1391 self.handle.sendline( cmd )
You Wang5bf49592020-07-08 18:47:46 -07001392 handle = self.handle.before
Jon Hall3c0114c2020-08-11 15:07:42 -07001393 main.log.debug( "%s: %s" % ( self.name, handle ) )
You Wang5bf49592020-07-08 18:47:46 -07001394 assert handle is not None, "Error in sendline"
1395 assert "Command not found:" not in handle, handle
1396 assert "error" not in handle, handle
1397 assert "usage:" not in handle, handle
1398 return main.TRUE
1399 except AssertionError:
1400 main.log.exception( "Error in onos-app output" )
1401 return main.FALSE
1402 except pexpect.TIMEOUT:
1403 main.log.exception( self.name + ": Timeout in onosAppInstall" )
1404 self.handle.send( "\x03" ) # Control-C
1405 self.handle.expect( self.prompt )
1406 return main.FALSE
1407 except pexpect.EOF:
1408 main.log.error( self.name + ": EOF exception found" )
1409 main.log.error( self.name + ": " + self.handle.before )
1410 main.cleanAndExit()
1411 except Exception:
1412 main.log.exception( self.name + ": Uncaught exception!" )
1413 main.cleanAndExit()
1414
kelvin-onlabd3b64892015-01-20 13:26:24 -08001415 def onosRemoveRaftLogs( self ):
kelvin8ec71442015-01-15 16:57:00 -08001416 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001417 Removes Raft / Copy cat files from ONOS to ensure
Jon Hallfcc88622014-11-25 13:09:54 -05001418 a cleaner environment.
1419
andrewonlab19fbdca2014-11-14 12:55:59 -05001420 Description:
Jon Hallfcc88622014-11-25 13:09:54 -05001421 Stops all ONOS defined in the cell,
andrewonlab19fbdca2014-11-14 12:55:59 -05001422 wipes the raft / copycat log files
kelvin8ec71442015-01-15 16:57:00 -08001423 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001424 try:
kelvin8ec71442015-01-15 16:57:00 -08001425 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001426 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -08001427 self.handle.sendline( "onos-remove-raft-logs" )
1428 # Sometimes this command hangs
Devin Limc20e79a2017-06-07 10:29:57 -07001429 i = self.handle.expect( [ self.prompt, pexpect.TIMEOUT ],
kelvin8ec71442015-01-15 16:57:00 -08001430 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001431 if i == 1:
Devin Limc20e79a2017-06-07 10:29:57 -07001432 i = self.handle.expect( [ self.prompt, pexpect.TIMEOUT ],
kelvin8ec71442015-01-15 16:57:00 -08001433 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001434 if i == 1:
1435 return main.FALSE
andrewonlab19fbdca2014-11-14 12:55:59 -05001436 return main.TRUE
andrewonlab19fbdca2014-11-14 12:55:59 -05001437 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001438 main.log.error( self.name + ": EOF exception found" )
1439 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001440 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001441 except Exception:
1442 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001443 main.cleanAndExit()
Jon Hallfcc88622014-11-25 13:09:54 -05001444
kelvin-onlabd3b64892015-01-20 13:26:24 -08001445 def onosStartNetwork( self, mntopo ):
kelvin8ec71442015-01-15 16:57:00 -08001446 """
1447 Calls the command 'onos-start-network [ <mininet-topo> ]
1448 "remotely starts the specified topology on the cell's
andrewonlab94282092014-10-10 13:00:11 -04001449 mininet machine against all controllers configured in the
kelvin8ec71442015-01-15 16:57:00 -08001450 cell."
andrewonlab94282092014-10-10 13:00:11 -04001451 * Specify mininet topology file name for mntopo
1452 * Topo files should be placed at:
1453 ~/<your-onos-directory>/tools/test/topos
kelvin8ec71442015-01-15 16:57:00 -08001454
andrewonlab94282092014-10-10 13:00:11 -04001455 NOTE: This function will take you to the mininet prompt
kelvin8ec71442015-01-15 16:57:00 -08001456 """
andrewonlab94282092014-10-10 13:00:11 -04001457 try:
1458 if not mntopo:
kelvin8ec71442015-01-15 16:57:00 -08001459 main.log.error( "You must specify a topo file to execute" )
andrewonlab94282092014-10-10 13:00:11 -04001460 return main.FALSE
andrewonlab94282092014-10-10 13:00:11 -04001461
kelvin8ec71442015-01-15 16:57:00 -08001462 mntopo = str( mntopo )
1463 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001464 self.handle.expect( self.prompt )
andrewonlab94282092014-10-10 13:00:11 -04001465
kelvin8ec71442015-01-15 16:57:00 -08001466 self.handle.sendline( "onos-start-network " + mntopo )
1467 self.handle.expect( "mininet>" )
Jon Hall3c0114c2020-08-11 15:07:42 -07001468 main.log.info( self.name + ": Network started, entered mininet prompt" )
kelvin8ec71442015-01-15 16:57:00 -08001469
1470 # TODO: Think about whether return is necessary or not
andrewonlab94282092014-10-10 13:00:11 -04001471
1472 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001473 main.log.error( self.name + ": EOF exception found" )
1474 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001475 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001476 except Exception:
1477 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001478 main.cleanAndExit()
andrewonlab94282092014-10-10 13:00:11 -04001479
Jeremy Songster14c13572016-04-21 17:34:03 -07001480 def isup( self, node="", timeout=240 ):
kelvin8ec71442015-01-15 16:57:00 -08001481 """
1482 Run's onos-wait-for-start which only returns once ONOS is at run
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001483 level 100(ready for use)
andrewonlab8d0d7d72014-10-09 16:33:15 -04001484
Jon Hall7993bfc2014-10-09 16:30:14 -04001485 Returns: main.TRUE if ONOS is running and main.FALSE on timeout
kelvin8ec71442015-01-15 16:57:00 -08001486 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001487 try:
Jon Hall3b489db2015-10-05 14:38:37 -07001488 self.handle.sendline( "onos-wait-for-start " + node )
1489 self.handle.expect( "onos-wait-for-start" )
kelvin8ec71442015-01-15 16:57:00 -08001490 # NOTE: this timeout is arbitrary"
Jon Hallcababf72018-02-05 12:05:19 -08001491 i = self.handle.expect( [ self.prompt, pexpect.TIMEOUT, "Password:" ], timeout )
Jon Hall7993bfc2014-10-09 16:30:14 -04001492 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001493 main.log.info( self.name + ": " + node + " is up" )
You Wangb65f2e92018-12-21 11:31:34 -08001494 # FIXME: for now we sleep 5s for CLI to become ready
1495 time.sleep( 5 )
Jon Hall7993bfc2014-10-09 16:30:14 -04001496 return main.TRUE
Jon Hallcababf72018-02-05 12:05:19 -08001497 elif i == 1 or i == 2:
kelvin8ec71442015-01-15 16:57:00 -08001498 # NOTE: since this function won't return until ONOS is ready,
Jon Hall7993bfc2014-10-09 16:30:14 -04001499 # we will kill it on timeout
Jon Hallcababf72018-02-05 12:05:19 -08001500 if i == 1:
Jon Hall3e6edb32018-08-21 16:20:30 -07001501 main.log.error( "{}: ONOS {} has not started yet".format( self.name, node ) )
Jon Hallcababf72018-02-05 12:05:19 -08001502 elif i == 2:
Jon Hall3e6edb32018-08-21 16:20:30 -07001503 main.log.error( "{}: Cannot login to ONOS CLI {}, try using onos-secure-ssh".format( self.name, node ) )
kelvin8ec71442015-01-15 16:57:00 -08001504 self.handle.send( "\x03" ) # Control-C
Devin Limc20e79a2017-06-07 10:29:57 -07001505 self.handle.expect( self.prompt )
Jon Hall7993bfc2014-10-09 16:30:14 -04001506 return main.FALSE
1507 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001508 main.log.error( self.name + ": EOF exception found" )
1509 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001510 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001511 except Exception:
1512 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001513 main.cleanAndExit()
andrewonlab05e362f2014-10-10 00:40:57 -04001514
Devin Lim142b5342017-07-20 15:22:39 -07001515 def preventAutoRespawn( self ):
1516 """
1517 Description:
1518 This will prevent ONOSservice to automatically
1519 respawn.
1520 """
1521 try:
1522 self.handle.sendline( "sed -i -e 's/^respawn$/#respawn/g' tools/package/init/onos.conf" )
1523 self.handle.expect( "\$" ) # $ from the command
1524 self.handle.sendline( "sed -i -e 's/^Restart=always/Restart=no/g' tools/package/init/onos.service" )
1525 self.handle.expect( "\$" ) # $ from the command
1526 self.handle.expect( "\$" ) # $ from the prompt
1527 except pexpect.EOF:
1528 main.log.error( self.name + ": EOF exception found" )
1529 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001530 main.cleanAndExit()
Devin Lim142b5342017-07-20 15:22:39 -07001531 except Exception:
1532 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001533 main.cleanAndExit()
Devin Lim142b5342017-07-20 15:22:39 -07001534
kelvin-onlabd3b64892015-01-20 13:26:24 -08001535 def pushTestIntentsShell(
1536 self,
1537 dpidSrc,
1538 dpidDst,
1539 numIntents,
1540 dirFile,
1541 onosIp,
1542 numMult="",
1543 appId="",
1544 report=True,
1545 options="" ):
kelvin8ec71442015-01-15 16:57:00 -08001546 """
andrewonlabb66dfa12014-12-02 15:51:10 -05001547 Description:
kelvin8ec71442015-01-15 16:57:00 -08001548 Use the linux prompt to push test intents to
andrewonlabb66dfa12014-12-02 15:51:10 -05001549 better parallelize the results than the CLI
1550 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001551 * dpidSrc: specify source dpid
1552 * dpidDst: specify destination dpid
1553 * numIntents: specify number of intents to push
1554 * dirFile: specify directory and file name to save
andrewonlabb66dfa12014-12-02 15:51:10 -05001555 results
kelvin-onlabd3b64892015-01-20 13:26:24 -08001556 * onosIp: specify the IP of ONOS to install on
kelvin8ec71442015-01-15 16:57:00 -08001557 NOTE:
andrewonlabb66dfa12014-12-02 15:51:10 -05001558 You must invoke this command at linux shell prompt
kelvin8ec71442015-01-15 16:57:00 -08001559 """
1560 try:
1561 # Create the string to sendline
andrewonlabaedc8332014-12-04 12:43:03 -05001562 if options:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001563 baseCmd = "onos " + str( onosIp ) + " push-test-intents " +\
kelvin8ec71442015-01-15 16:57:00 -08001564 options + " "
andrewonlabaedc8332014-12-04 12:43:03 -05001565 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001566 baseCmd = "onos " + str( onosIp ) + " push-test-intents "
kelvin8ec71442015-01-15 16:57:00 -08001567
kelvin-onlabd3b64892015-01-20 13:26:24 -08001568 addDpid = baseCmd + str( dpidSrc ) + " " + str( dpidDst )
1569 if not numMult:
1570 addIntents = addDpid + " " + str( numIntents )
1571 elif numMult:
1572 addIntents = addDpid + " " + str( numIntents ) + " " +\
1573 str( numMult )
1574 if appId:
1575 addApp = addIntents + " " + str( appId )
andrewonlabb66dfa12014-12-02 15:51:10 -05001576 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001577 addApp = addIntents
andrewonlabb66dfa12014-12-02 15:51:10 -05001578
andrewonlabaedc8332014-12-04 12:43:03 -05001579 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001580 sendCmd = addApp + " > " + str( dirFile ) + " &"
andrewonlabaedc8332014-12-04 12:43:03 -05001581 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001582 sendCmd = addApp + " &"
Jon Hall3c0114c2020-08-11 15:07:42 -07001583 main.log.info( self.name + ": Send cmd: " + sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001584
kelvin-onlabd3b64892015-01-20 13:26:24 -08001585 self.handle.sendline( sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001586
1587 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001588 main.log.error( self.name + ": EOF exception found" )
1589 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001590 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001591 except Exception:
1592 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001593 main.cleanAndExit()
andrewonlab05e362f2014-10-10 00:40:57 -04001594
kelvin-onlabd3b64892015-01-20 13:26:24 -08001595 def tsharkPcap( self, interface, dirFile ):
kelvin8ec71442015-01-15 16:57:00 -08001596 """
andrewonlab970399c2014-11-07 13:09:32 -05001597 Capture all packet activity and store in specified
1598 directory/file
1599
1600 Required:
1601 * interface: interface to capture
1602 * dir: directory/filename to store pcap
kelvin8ec71442015-01-15 16:57:00 -08001603 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001604 try:
1605 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001606 self.handle.expect( self.prompt )
andrewonlab970399c2014-11-07 13:09:32 -05001607
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001608 self.handle.sendline( "tshark -i " + str( interface ) + " -t e -w " + str( dirFile ) + " &" )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001609 self.handle.sendline( "\n" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001610 self.handle.expect( "Capturing on" )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001611 self.handle.sendline( "\n" )
Devin Limc20e79a2017-06-07 10:29:57 -07001612 self.handle.expect( self.prompt )
andrewonlab970399c2014-11-07 13:09:32 -05001613
Jon Hall3c0114c2020-08-11 15:07:42 -07001614 main.log.info( self.name + ": Tshark started capturing files on " +
Jon Hallfebb1c72015-03-05 13:30:09 -08001615 str( interface ) + " and saving to directory: " +
1616 str( dirFile ) )
1617 except pexpect.EOF:
1618 main.log.error( self.name + ": EOF exception found" )
1619 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001620 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001621 except Exception:
1622 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001623 main.cleanAndExit()
Shreya Shaha73aaad2014-10-27 18:03:09 -04001624
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001625 def onosTopoCfg( self, onosIp, jsonFile ):
kelvin8ec71442015-01-15 16:57:00 -08001626 """
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001627 Description:
1628 Execute onos-topo-cfg command
1629 Required:
1630 onosIp - IP of the onos node you want to send the json to
1631 jsonFile - File path of the json file
1632 Return:
1633 Returns main.TRUE if the command is successfull; Returns
1634 main.FALSE if there was an error
kelvin8ec71442015-01-15 16:57:00 -08001635 """
shahshreyae6c7cf42014-11-26 16:39:01 -08001636 try:
kelvin8ec71442015-01-15 16:57:00 -08001637 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001638 self.handle.expect( self.prompt )
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001639 cmd = "onos-topo-cfg "
1640 self.handle.sendline( cmd + str( onosIp ) + " " + jsonFile )
1641 handle = self.handle.before
1642 print handle
1643 if "Error" in handle:
1644 main.log.error( self.name + ": " + self.handle.before )
1645 return main.FALSE
1646 else:
Devin Limc20e79a2017-06-07 10:29:57 -07001647 self.handle.expect( self.prompt )
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001648 return main.TRUE
1649
Jon Hallfebb1c72015-03-05 13:30:09 -08001650 except pexpect.EOF:
1651 main.log.error( self.name + ": EOF exception found" )
1652 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001653 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001654 except Exception:
1655 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001656 main.cleanAndExit()
kelvin8ec71442015-01-15 16:57:00 -08001657
jenkins1e99e7b2015-04-02 18:15:39 -07001658 def tsharkGrep( self, grep, directory, interface='eth0', grepOptions='' ):
kelvin8ec71442015-01-15 16:57:00 -08001659 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001660 Required:
kelvin8ec71442015-01-15 16:57:00 -08001661 * grep string
andrewonlabba44bcf2014-10-16 16:54:41 -04001662 * directory to store results
1663 Optional:
1664 * interface - default: eth0
Jon Hall4ba53f02015-07-29 13:07:41 -07001665 * grepOptions - options for grep
andrewonlabba44bcf2014-10-16 16:54:41 -04001666 Description:
1667 Uses tshark command to grep specific group of packets
1668 and stores the results to specified directory.
kelvin8ec71442015-01-15 16:57:00 -08001669 The timestamp is hardcoded to be in epoch
1670 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001671 try:
1672 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001673 self.handle.expect( self.prompt )
Jon Hallfebb1c72015-03-05 13:30:09 -08001674 self.handle.sendline( "" )
jenkins1e99e7b2015-04-02 18:15:39 -07001675 if grepOptions:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001676 grepStr = "grep " + str( grepOptions )
jenkins1e99e7b2015-04-02 18:15:39 -07001677 else:
1678 grepStr = "grep"
Jon Hall4ba53f02015-07-29 13:07:41 -07001679
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001680 cmd = (
1681 "sudo tshark -i " +
Jon Hallfebb1c72015-03-05 13:30:09 -08001682 str( interface ) +
jenkins1e99e7b2015-04-02 18:15:39 -07001683 " -t e | " +
1684 grepStr + " --line-buffered \"" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001685 str( grep ) +
Jon Hallfebb1c72015-03-05 13:30:09 -08001686 "\" >" +
1687 directory +
1688 " &" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001689 self.handle.sendline( cmd )
1690 main.log.info( cmd )
Jon Hallfebb1c72015-03-05 13:30:09 -08001691 self.handle.expect( "Capturing on" )
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001692 self.handle.sendline( "\n" )
Devin Limc20e79a2017-06-07 10:29:57 -07001693 self.handle.expect( self.prompt )
Jon Hallfebb1c72015-03-05 13:30:09 -08001694 except pexpect.EOF:
1695 main.log.error( self.name + ": EOF exception found" )
1696 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001697 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001698 except Exception:
1699 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001700 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001701
kelvin-onlabd3b64892015-01-20 13:26:24 -08001702 def tsharkStop( self ):
kelvin8ec71442015-01-15 16:57:00 -08001703 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001704 Removes wireshark files from /tmp and kills all tshark processes
kelvin8ec71442015-01-15 16:57:00 -08001705 """
1706 # Remove all pcap from previous captures
Jon Hallfebb1c72015-03-05 13:30:09 -08001707 try:
1708 self.execute( cmd="sudo rm /tmp/wireshark*" )
1709 self.handle.sendline( "" )
Jon Hallefbd9792015-03-05 16:11:36 -08001710 self.handle.sendline( "sudo kill -9 `ps -ef | grep \"tshark -i\"" +
1711 " | grep -v grep | awk '{print $2}'`" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001712 self.handle.sendline( "" )
Jon Hall3c0114c2020-08-11 15:07:42 -07001713 main.log.info( self.name + ": Tshark stopped" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001714 except pexpect.EOF:
1715 main.log.error( self.name + ": EOF exception found" )
1716 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001717 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001718 except Exception:
1719 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001720 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001721
kelvin8ec71442015-01-15 16:57:00 -08001722 def ptpd( self, args ):
1723 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001724 Initiate ptp with user-specified args.
1725 Required:
1726 * args: specify string of args after command
1727 'sudo ptpd'
kelvin8ec71442015-01-15 16:57:00 -08001728 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001729 try:
kelvin8ec71442015-01-15 16:57:00 -08001730 self.handle.sendline( "sudo ptpd " + str( args ) )
1731 i = self.handle.expect( [
andrewonlab0c38a4a2014-10-28 18:35:35 -04001732 "Multiple",
1733 "Error",
Devin Limc20e79a2017-06-07 10:29:57 -07001734 self.prompt ] )
1735 self.handle.expect( self.prompt )
andrewonlabba44bcf2014-10-16 16:54:41 -04001736
andrewonlab0c38a4a2014-10-28 18:35:35 -04001737 if i == 0:
1738 handle = self.handle.before
Jon Hall3c0114c2020-08-11 15:07:42 -07001739 main.log.info( self.name + ": ptpd returned an error: " +
kelvin8ec71442015-01-15 16:57:00 -08001740 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001741 return handle
1742 elif i == 1:
1743 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001744 main.log.error( "ptpd returned an error: " +
1745 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001746 return handle
1747 else:
1748 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -08001749
andrewonlab0c38a4a2014-10-28 18:35:35 -04001750 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001751 main.log.error( self.name + ": EOF exception found" )
1752 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001753 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001754 except Exception:
1755 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001756 main.cleanAndExit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001757
You Wang54b1d672018-06-11 16:44:13 -07001758 def dumpONOSCmd( self, ONOSIp, CMD, destDir, filename, options="", timeout=60 ):
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001759 """
Pier50f0bc62016-09-07 17:53:40 -07001760 Dump Cmd to a desired directory.
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001761 For debugging purposes, you may want to use
Pier50f0bc62016-09-07 17:53:40 -07001762 this function to capture Cmd at a given point in time.
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001763 Localtime will be attached to the filename
1764
1765 Required:
1766 * ONOSIp: the IP of the target ONOS instance
Pier50f0bc62016-09-07 17:53:40 -07001767 * CMD: the command to dump;
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001768 * destDir: specify directory to copy to.
1769 ex ) /tmp/
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001770 * fileName: Name of the file
You Wang54b1d672018-06-11 16:44:13 -07001771 Optional:
Pier50f0bc62016-09-07 17:53:40 -07001772 * options: Options for ONOS command
You Wang54b1d672018-06-11 16:44:13 -07001773 * timeout: pexpect timeout for running the ONOS command
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001774 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001775
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001776 localtime = time.strftime( '%x %X' )
1777 localtime = localtime.replace( "/", "" )
1778 localtime = localtime.replace( " ", "_" )
1779 localtime = localtime.replace( ":", "" )
1780 if destDir[ -1: ] != "/":
1781 destDir += "/"
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001782 cmd = CMD + " " + options + " > " + str( destDir ) + str( filename ) + localtime
You Wang54b1d672018-06-11 16:44:13 -07001783 return self.onosCli( ONOSIp, cmd, timeout=timeout )
Flavio Castrob7718952016-05-18 08:53:41 -07001784
kelvin-onlabd3b64892015-01-20 13:26:24 -08001785 def cpLogsToDir( self, logToCopy,
Jon Hallefbd9792015-03-05 16:11:36 -08001786 destDir, copyFileName="" ):
kelvin8ec71442015-01-15 16:57:00 -08001787 """
1788 Copies logs to a desired directory.
andrewonlab5d7a8f32014-11-10 13:07:56 -05001789 Current implementation of ONOS deletes its karaf
1790 logs on every iteration. For debugging purposes,
kelvin8ec71442015-01-15 16:57:00 -08001791 you may want to use this function to capture
1792 certain karaf logs. ( or any other logs if needed )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001793 Localtime will be attached to the filename
1794
1795 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001796 * logToCopy: specify directory and log name to
andrewonlab5d7a8f32014-11-10 13:07:56 -05001797 copy.
kelvin8ec71442015-01-15 16:57:00 -08001798 ex ) /opt/onos/log/karaf.log.1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001799 For copying multiple files, leave copyFileName
1800 empty and only specify destDir -
kelvin8ec71442015-01-15 16:57:00 -08001801 ex ) /opt/onos/log/karaf*
kelvin-onlabd3b64892015-01-20 13:26:24 -08001802 * destDir: specify directory to copy to.
kelvin8ec71442015-01-15 16:57:00 -08001803 ex ) /tmp/
1804 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001805 * copyFileName: If you want to rename the log
1806 file, specify copyFileName. This will not work
andrewonlab5d7a8f32014-11-10 13:07:56 -05001807 with multiple file copying
kelvin8ec71442015-01-15 16:57:00 -08001808 """
andrewonlab5d7a8f32014-11-10 13:07:56 -05001809 try:
Flavio Castro09ab59d2016-05-25 17:01:35 -07001810 localtime = time.strftime( '%H %M' )
kelvin8ec71442015-01-15 16:57:00 -08001811 localtime = localtime.replace( "/", "" )
1812 localtime = localtime.replace( " ", "_" )
1813 localtime = localtime.replace( ":", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001814 if destDir[ -1: ] != "/":
1815 destDir += "/"
andrewonlab5d7a8f32014-11-10 13:07:56 -05001816
kelvin-onlabd3b64892015-01-20 13:26:24 -08001817 if copyFileName:
Jon Hallfebb1c72015-03-05 13:30:09 -08001818 self.handle.sendline( "cp " + str( logToCopy ) + " " +
1819 str( destDir ) + str( copyFileName ) +
1820 localtime )
kelvin8ec71442015-01-15 16:57:00 -08001821 self.handle.expect( "cp" )
Devin Limc20e79a2017-06-07 10:29:57 -07001822 self.handle.expect( self.prompt )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001823 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001824 self.handle.sendline( "cp " + str( logToCopy ) +
1825 " " + str( destDir ) )
kelvin8ec71442015-01-15 16:57:00 -08001826 self.handle.expect( "cp" )
Devin Limc20e79a2017-06-07 10:29:57 -07001827 self.handle.expect( self.prompt )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001828
kelvin8ec71442015-01-15 16:57:00 -08001829 return self.handle.before
1830
1831 except pexpect.EOF:
1832 main.log.error( "Copying files failed" )
1833 main.log.error( self.name + ": EOF exception found" )
1834 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001835 except Exception:
1836 main.log.exception( "Copying files failed" )
1837
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001838 def checkLogs( self, onosIp, restart=False ):
kelvin8ec71442015-01-15 16:57:00 -08001839 """
Jon Hall94fd0472014-12-08 11:52:42 -08001840 runs onos-check-logs on the given onos node
Jon Hall80daded2015-05-27 16:07:00 -07001841 If restart is True, use the old version of onos-check-logs which
1842 does not print the full stacktrace, but shows the entire log file,
1843 including across restarts
Jon Hall94fd0472014-12-08 11:52:42 -08001844 returns the response
kelvin8ec71442015-01-15 16:57:00 -08001845 """
Jon Hall94fd0472014-12-08 11:52:42 -08001846 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001847 cmd = "onos-check-logs " + str( onosIp )
Jon Hall16b72c42015-05-20 10:23:36 -07001848 if restart:
1849 cmd += " old"
kelvin8ec71442015-01-15 16:57:00 -08001850 self.handle.sendline( cmd )
1851 self.handle.expect( cmd )
Devin Limdc78e202017-06-09 18:30:07 -07001852 self.handle.expect( self.prompt + " " )
Jon Hall94fd0472014-12-08 11:52:42 -08001853 response = self.handle.before
1854 return response
1855 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001856 main.log.error( "Lost ssh connection" )
1857 main.log.error( self.name + ": EOF exception found" )
1858 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001859 except Exception:
1860 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001861 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001862
kelvin-onlabd3b64892015-01-20 13:26:24 -08001863 def onosStatus( self, node="" ):
kelvin8ec71442015-01-15 16:57:00 -08001864 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001865 Calls onos command: 'onos-service [<node-ip>] status'
kelvin8ec71442015-01-15 16:57:00 -08001866 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001867 try:
kelvin8ec71442015-01-15 16:57:00 -08001868 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001869 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -08001870 self.handle.sendline( "onos-service " + str( node ) +
1871 " status" )
1872 i = self.handle.expect( [
You Wangef1e6572016-03-08 12:53:18 -08001873 "start/running",
You Wang7bd83062016-03-01 11:50:00 -08001874 "Running ...",
You Wangef1e6572016-03-08 12:53:18 -08001875 "stop/waiting",
You Wang7bd83062016-03-01 11:50:00 -08001876 "Not Running ...",
kelvin8ec71442015-01-15 16:57:00 -08001877 pexpect.TIMEOUT ], timeout=120 )
YPZhangfebf7302016-05-24 16:45:56 -07001878 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001879 self.handle.expect( self.prompt )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001880
You Wangef1e6572016-03-08 12:53:18 -08001881 if i == 0 or i == 1:
Jon Hall3c0114c2020-08-11 15:07:42 -07001882 main.log.info( self.name + ": ONOS is running" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001883 return main.TRUE
You Wangef1e6572016-03-08 12:53:18 -08001884 elif i == 2 or i == 3:
Jon Hall3c0114c2020-08-11 15:07:42 -07001885 main.log.info( self.name + ": ONOS is stopped" )
kelvin8ec71442015-01-15 16:57:00 -08001886 main.log.error( "ONOS service failed to check the status" )
Devin Lim44075962017-08-11 10:56:37 -07001887
1888 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001889 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001890 main.log.error( self.name + ": EOF exception found" )
1891 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001892 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001893 except Exception:
1894 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001895 main.cleanAndExit()
Jon Hall21270ac2015-02-16 17:59:55 -08001896
Jon Hall63604932015-02-26 17:09:50 -08001897 def setIpTables( self, ip, port='', action='add', packet_type='',
1898 direction='INPUT', rule='DROP', states=True ):
Jon Hallefbd9792015-03-05 16:11:36 -08001899 """
Jon Hall21270ac2015-02-16 17:59:55 -08001900 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001901 add or remove iptables rule to DROP (default) packets from
Jon Hall21270ac2015-02-16 17:59:55 -08001902 specific IP and PORT
1903 Usage:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001904 * specify action ('add' or 'remove')
Jon Hall21270ac2015-02-16 17:59:55 -08001905 when removing, pass in the same argument as you would add. It will
1906 delete that specific rule.
1907 * specify the ip to block
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001908 * specify the destination port to block (defaults to all ports)
1909 * optional packet type to block (default tcp)
1910 * optional iptables rule (default DROP)
1911 * optional direction to block (default 'INPUT')
Jon Hall63604932015-02-26 17:09:50 -08001912 * States boolean toggles adding all supported tcp states to the
1913 firewall rule
Jon Hall21270ac2015-02-16 17:59:55 -08001914 Returns:
1915 main.TRUE on success or
1916 main.FALSE if given invalid input or
1917 main.ERROR if there is an error in response from iptables
1918 WARNING:
1919 * This function uses root privilege iptables command which may result
1920 in unwanted network errors. USE WITH CAUTION
Jon Hallefbd9792015-03-05 16:11:36 -08001921 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001922
Jon Hall21270ac2015-02-16 17:59:55 -08001923 # NOTE*********
1924 # The strict checking methods of this driver function is intentional
1925 # to discourage any misuse or error of iptables, which can cause
1926 # severe network errors
1927 # *************
1928
1929 # NOTE: Sleep needed to give some time for rule to be added and
1930 # registered to the instance. If you are calling this function
1931 # multiple times this sleep will prevent any errors.
1932 # DO NOT REMOVE
Jon Hall63604932015-02-26 17:09:50 -08001933 # time.sleep( 5 )
Jon Hall21270ac2015-02-16 17:59:55 -08001934 try:
1935 # input validation
1936 action_type = action.lower()
1937 rule = rule.upper()
1938 direction = direction.upper()
1939 if action_type != 'add' and action_type != 'remove':
1940 main.log.error( "Invalid action type. Use 'add' or "
1941 "'remove' table rule" )
1942 if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
1943 # NOTE Currently only supports rules DROP, ACCEPT, and LOG
1944 main.log.error( "Invalid rule. Valid rules are 'DROP' or "
1945 "'ACCEPT' or 'LOG' only." )
1946 if direction != 'INPUT' and direction != 'OUTPUT':
1947 # NOTE currently only supports rules INPUT and OUPTUT
1948 main.log.error( "Invalid rule. Valid directions are"
1949 " 'OUTPUT' or 'INPUT'" )
1950 return main.FALSE
1951 return main.FALSE
1952 return main.FALSE
1953 if action_type == 'add':
1954 # -A is the 'append' action of iptables
1955 actionFlag = '-A'
1956 elif action_type == 'remove':
1957 # -D is the 'delete' rule of iptables
1958 actionFlag = '-D'
1959 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001960 self.handle.expect( self.prompt )
Jon Hall21270ac2015-02-16 17:59:55 -08001961 cmd = "sudo iptables " + actionFlag + " " +\
1962 direction +\
Jon Hall21270ac2015-02-16 17:59:55 -08001963 " -s " + str( ip )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001964 # " -p " + str( packet_type ) +\
Jon Hall63604932015-02-26 17:09:50 -08001965 if packet_type:
1966 cmd += " -p " + str( packet_type )
Jon Hall21270ac2015-02-16 17:59:55 -08001967 if port:
1968 cmd += " --dport " + str( port )
Jon Hall63604932015-02-26 17:09:50 -08001969 if states:
1970 cmd += " -m state --state="
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001971 # FIXME- Allow user to configure which states to block
Jon Hall63604932015-02-26 17:09:50 -08001972 cmd += "INVALID,ESTABLISHED,NEW,RELATED,UNTRACKED"
Jon Hall21270ac2015-02-16 17:59:55 -08001973 cmd += " -j " + str( rule )
1974
1975 self.handle.sendline( cmd )
Devin Limc20e79a2017-06-07 10:29:57 -07001976 self.handle.expect( self.prompt )
Jon Hall21270ac2015-02-16 17:59:55 -08001977 main.log.warn( self.handle.before )
1978
1979 info_string = "On " + str( self.name )
1980 info_string += " " + str( action_type )
1981 info_string += " iptable rule [ "
1982 info_string += " IP: " + str( ip )
1983 info_string += " Port: " + str( port )
1984 info_string += " Rule: " + str( rule )
1985 info_string += " Direction: " + str( direction ) + " ]"
1986 main.log.info( info_string )
1987 return main.TRUE
1988 except pexpect.TIMEOUT:
1989 main.log.exception( self.name + ": Timeout exception in "
1990 "setIpTables function" )
You Wang141b43b2018-06-26 16:50:18 -07001991 self.handle.send( "\x03" ) # Control-C
1992 self.handle.expect( self.prompt )
Jon Hall21270ac2015-02-16 17:59:55 -08001993 return main.ERROR
1994 except pexpect.EOF:
1995 main.log.error( self.name + ": EOF exception found" )
1996 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001997 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001998 except Exception:
1999 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002000 main.cleanAndExit()
Jon Hall21270ac2015-02-16 17:59:55 -08002001
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002002 def detailed_status( self, log_filename ):
Jon Hallefbd9792015-03-05 16:11:36 -08002003 """
Jon Hall0468b042015-02-19 19:08:21 -08002004 This method is used by STS to check the status of the controller
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002005 Reports RUNNING, STARTING, STOPPED, FROZEN, ERROR (and reason)
Jon Hallefbd9792015-03-05 16:11:36 -08002006 """
Jon Hall0468b042015-02-19 19:08:21 -08002007 import re
2008 try:
2009 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07002010 self.handle.expect( self.prompt )
Jon Hall0468b042015-02-19 19:08:21 -08002011 self.handle.sendline( "cd " + self.home )
Devin Limc20e79a2017-06-07 10:29:57 -07002012 self.handle.expect( self.prompt )
Jon Hall0468b042015-02-19 19:08:21 -08002013 self.handle.sendline( "service onos status" )
Devin Limc20e79a2017-06-07 10:29:57 -07002014 self.handle.expect( self.prompt )
Jon Hall0468b042015-02-19 19:08:21 -08002015 response = self.handle.before
2016 if re.search( "onos start/running", response ):
2017 # onos start/running, process 10457
2018 return 'RUNNING'
2019 # FIXME: Implement this case
2020 # elif re.search( pattern, response ):
2021 # return 'STARTING'
2022 elif re.search( "onos stop/", response ):
2023 # onos stop/waiting
2024 # FIXME handle this differently?: onos stop/pre-stop
2025 return 'STOPPED'
2026 # FIXME: Implement this case
2027 # elif re.search( pattern, response ):
2028 # return 'FROZEN'
2029 else:
2030 main.log.warn( self.name +
Jon Hallefbd9792015-03-05 16:11:36 -08002031 " WARNING: status received unknown response" )
Jon Hall0468b042015-02-19 19:08:21 -08002032 main.log.warn( response )
2033 return 'ERROR', "Unknown response: %s" % response
2034 except pexpect.TIMEOUT:
2035 main.log.exception( self.name + ": Timeout exception in "
2036 "setIpTables function" )
You Wang141b43b2018-06-26 16:50:18 -07002037 self.handle.send( "\x03" ) # Control-C
2038 self.handle.expect( self.prompt )
Jon Hall0468b042015-02-19 19:08:21 -08002039 return 'ERROR', "Pexpect Timeout"
2040 except pexpect.EOF:
2041 main.log.error( self.name + ": EOF exception found" )
2042 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002043 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002044 except Exception:
2045 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002046 main.cleanAndExit()
Jon Hall0468b042015-02-19 19:08:21 -08002047
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002048 def createLinkGraphFile( self, benchIp, ONOSIpList, deviceCount ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002049 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07002050 Create/formats the LinkGraph.cfg file based on arguments
2051 -only creates a linear topology and connects islands
2052 -evenly distributes devices
andrew@onlab.us3b087132015-03-11 15:00:08 -07002053 -must be called by ONOSbench
2054
Jon Hall4ba53f02015-07-29 13:07:41 -07002055 ONOSIpList - list of all of the node IPs to be used
2056
2057 deviceCount - number of switches to be assigned
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002058 '''
Jon Hall3c0114c2020-08-11 15:07:42 -07002059 main.log.info( self.name + ": Creating link graph configuration file." )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002060 linkGraphPath = self.home + "/tools/package/etc/linkGraph.cfg"
Jon Hall4ba53f02015-07-29 13:07:41 -07002061 tempFile = "/tmp/linkGraph.cfg"
andrew@onlab.us3b087132015-03-11 15:00:08 -07002062
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002063 linkGraph = open( tempFile, 'w+' )
2064 linkGraph.write( "# NullLinkProvider topology description (config file).\n" )
2065 linkGraph.write( "# The NodeId is only added if the destination is another node's device.\n" )
2066 linkGraph.write( "# Bugs: Comments cannot be appended to a line to be read.\n" )
Jon Hall4ba53f02015-07-29 13:07:41 -07002067
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002068 clusterCount = len( ONOSIpList )
Jon Hall4ba53f02015-07-29 13:07:41 -07002069
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002070 if isinstance( deviceCount, int ) or isinstance( deviceCount, str ):
2071 deviceCount = int( deviceCount )
2072 switchList = [ 0 ]*( clusterCount+1 )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002073 baselineSwitchCount = deviceCount/clusterCount
Jon Hall4ba53f02015-07-29 13:07:41 -07002074
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002075 for node in range( 1, clusterCount + 1 ):
2076 switchList[ node ] = baselineSwitchCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07002077
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002078 for node in range( 1, ( deviceCount % clusterCount )+1 ):
2079 switchList[ node ] += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07002080
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002081 if isinstance( deviceCount, list ):
Jon Hall3c0114c2020-08-11 15:07:42 -07002082 main.log.info( self.name + ": Using provided device distribution" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002083 switchList = [ 0 ]
andrew@onlab.us3b087132015-03-11 15:00:08 -07002084 for i in deviceCount:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002085 switchList.append( int( i ) )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002086
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002087 tempList = [ '0' ]
2088 tempList.extend( ONOSIpList )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002089 ONOSIpList = tempList
2090
2091 myPort = 6
2092 lastSwitch = 0
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002093 for node in range( 1, clusterCount+1 ):
2094 if switchList[ node ] == 0:
andrew@onlab.us3b087132015-03-11 15:00:08 -07002095 continue
2096
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002097 linkGraph.write( "graph " + ONOSIpList[ node ] + " {\n" )
Jon Hall4ba53f02015-07-29 13:07:41 -07002098
andrew@onlab.us3b087132015-03-11 15:00:08 -07002099 if node > 1:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002100 # connect to last device on previous node
2101 line = ( "\t0:5 -> " + str( lastSwitch ) + ":6:" + lastIp + "\n" ) # ONOSIpList[node-1]
2102 linkGraph.write( line )
Jon Hall4ba53f02015-07-29 13:07:41 -07002103
2104 lastSwitch = 0
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002105 for switch in range( 0, switchList[ node ]-1 ):
andrew@onlab.us3b087132015-03-11 15:00:08 -07002106 line = ""
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002107 line = ( "\t" + str( switch ) + ":" + str( myPort ) )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002108 line += " -- "
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002109 line += ( str( switch+1 ) + ":" + str( myPort-1 ) + "\n" )
2110 linkGraph.write( line )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002111 lastSwitch = switch+1
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002112 lastIp = ONOSIpList[ node ]
Jon Hall4ba53f02015-07-29 13:07:41 -07002113
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002114 # lastSwitch += 1
2115 if node < ( clusterCount ):
2116 # connect to first device on the next node
2117 line = ( "\t" + str( lastSwitch ) + ":6 -> 0:5:" + ONOSIpList[ node+1 ] + "\n" )
2118 linkGraph.write( line )
Jon Hall4ba53f02015-07-29 13:07:41 -07002119
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002120 linkGraph.write( "}\n" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002121 linkGraph.close()
2122
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002123 # SCP
2124 os.system( "scp " + tempFile + " " + self.user_name + "@" + benchIp + ":" + linkGraphPath )
Jon Hall3c0114c2020-08-11 15:07:42 -07002125 main.log.info( self.name + ": linkGraph.cfg creation complete" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002126
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002127 def configNullDev( self, ONOSIpList, deviceCount, numPorts=10 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002128 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07002129 ONOSIpList = list of Ip addresses of nodes switches will be devided amongst
2130 deviceCount = number of switches to distribute, or list of values to use as custom distribution
cameron@onlab.us75900962015-03-30 13:22:49 -07002131 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 +00002132 '''
2133
Jon Hall3c0114c2020-08-11 15:07:42 -07002134 main.log.info( self.name + ": Configuring Null Device Provider" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002135 clusterCount = len( ONOSIpList )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002136
Jon Hall4ba53f02015-07-29 13:07:41 -07002137 try:
2138
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002139 if isinstance( deviceCount, int ) or isinstance( deviceCount, str ):
Jon Hall3c0114c2020-08-11 15:07:42 -07002140 main.log.info( self.name + ": Creating device distribution" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002141 deviceCount = int( deviceCount )
2142 switchList = [ 0 ]*( clusterCount+1 )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002143 baselineSwitchCount = deviceCount/clusterCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07002144
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002145 for node in range( 1, clusterCount + 1 ):
2146 switchList[ node ] = baselineSwitchCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07002147
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002148 for node in range( 1, ( deviceCount % clusterCount )+1 ):
2149 switchList[ node ] += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07002150
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002151 if isinstance( deviceCount, list ):
Jon Hall3c0114c2020-08-11 15:07:42 -07002152 main.log.info( self.name + ": Using provided device distribution" )
Jon Hall4ba53f02015-07-29 13:07:41 -07002153
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002154 if len( deviceCount ) == clusterCount:
2155 switchList = [ '0' ]
2156 switchList.extend( deviceCount )
Jon Hall4ba53f02015-07-29 13:07:41 -07002157
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002158 if len( deviceCount ) == ( clusterCount + 1 ):
2159 if deviceCount[ 0 ] == '0' or deviceCount[ 0 ] == 0:
cameron@onlab.us75900962015-03-30 13:22:49 -07002160 switchList = deviceCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07002161
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002162 assert len( switchList ) == ( clusterCount + 1 )
Jon Hall4ba53f02015-07-29 13:07:41 -07002163
cameron@onlab.us75900962015-03-30 13:22:49 -07002164 except AssertionError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002165 main.log.error( "Bad device/Ip list match" )
cameron@onlab.us75900962015-03-30 13:22:49 -07002166 except TypeError:
2167 main.log.exception( self.name + ": Object not as expected" )
2168 return None
Jon Hall77ba41c2015-04-06 10:25:40 -07002169 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002170 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002171 main.cleanAndExit()
cameron@onlab.us75900962015-03-30 13:22:49 -07002172
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002173 ONOSIp = [ 0 ]
2174 ONOSIp.extend( ONOSIpList )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002175
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002176 devicesString = "devConfigs = "
2177 for node in range( 1, len( ONOSIp ) ):
2178 devicesString += ( ONOSIp[ node ] + ":" + str( switchList[ node ] ) )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002179 if node < clusterCount:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002180 devicesString += ( "," )
Jon Hall4ba53f02015-07-29 13:07:41 -07002181
2182 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002183 self.handle.sendline( "onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider devConfigs " + devicesString )
2184 self.handle.expect( ":~" )
2185 self.handle.sendline( "onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider numPorts " + str( numPorts ) )
2186 self.handle.expect( ":~" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002187
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002188 for i in range( 10 ):
2189 self.handle.sendline( "onos $OC1 cfg get org.onosproject.provider.nil.device.impl.NullDeviceProvider" )
2190 self.handle.expect( ":~" )
cameron@onlab.us75900962015-03-30 13:22:49 -07002191 verification = self.handle.before
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002192 if ( " value=" + str( numPorts ) ) in verification and ( " value=" + devicesString ) in verification:
cameron@onlab.us75900962015-03-30 13:22:49 -07002193 break
2194 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002195 time.sleep( 1 )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002196
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002197 assert ( "value=" + str( numPorts ) ) in verification and ( " value=" + devicesString ) in verification
Jon Hall4ba53f02015-07-29 13:07:41 -07002198
cameron@onlab.us75900962015-03-30 13:22:49 -07002199 except AssertionError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002200 main.log.error( "Incorrect Config settings: " + verification )
Jon Hall77ba41c2015-04-06 10:25:40 -07002201 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002202 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002203 main.cleanAndExit()
cameron@onlab.us75900962015-03-30 13:22:49 -07002204
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002205 def configNullLink( self, fileName="/opt/onos/apache-karaf-3.0.3/etc/linkGraph.cfg", eventRate=0 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002206 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07002207 fileName default is currently the same as the default on ONOS, specify alternate file if
cameron@onlab.us75900962015-03-30 13:22:49 -07002208 you want to use a different topology file than linkGraph.cfg
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002209 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07002210
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002211 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002212 self.handle.sendline( "onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider eventRate " + str( eventRate ) )
2213 self.handle.expect( ":~" )
2214 self.handle.sendline( "onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider cfgFile " + fileName )
2215 self.handle.expect( ":~" )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002216
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002217 for i in range( 10 ):
2218 self.handle.sendline( "onos $OC1 cfg get org.onosproject.provider.nil.link.impl.NullLinkProvider" )
2219 self.handle.expect( ":~" )
cameron@onlab.us75900962015-03-30 13:22:49 -07002220 verification = self.handle.before
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002221 if ( " value=" + str( eventRate ) ) in verification and ( " value=" + fileName ) in verification:
cameron@onlab.us75900962015-03-30 13:22:49 -07002222 break
Jon Hall4ba53f02015-07-29 13:07:41 -07002223 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002224 time.sleep( 1 )
Jon Hall4ba53f02015-07-29 13:07:41 -07002225
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002226 assert ( "value=" + str( eventRate ) ) in verification and ( " value=" + fileName ) in verification
Jon Hall4ba53f02015-07-29 13:07:41 -07002227
cameron@onlab.us75900962015-03-30 13:22:49 -07002228 except pexpect.EOF:
2229 main.log.error( self.name + ": EOF exception found" )
2230 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002231 main.cleanAndExit()
cameron@onlab.us75900962015-03-30 13:22:49 -07002232 except AssertionError:
Jon Hall3c0114c2020-08-11 15:07:42 -07002233 main.log.info( self.name + ": Settings did not post to ONOS" )
Jon Hall3e6edb32018-08-21 16:20:30 -07002234 main.log.error( verification )
Jon Hall77ba41c2015-04-06 10:25:40 -07002235 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002236 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall3e6edb32018-08-21 16:20:30 -07002237 main.log.error( verification )
Devin Lim44075962017-08-11 10:56:37 -07002238 main.cleanAndExit()
andrew@onlab.us3b087132015-03-11 15:00:08 -07002239
kelvin-onlaba4074292015-07-09 15:19:49 -07002240 def getOnosIps( self ):
2241 """
2242 Get all onos IPs stored in
2243 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002244
kelvin-onlaba4074292015-07-09 15:19:49 -07002245 return sorted( self.onosIps.values() )
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002246
Chiyu Chengec63bde2016-11-17 18:11:36 -08002247 def listLog( self, nodeIp ):
2248 """
2249 Get a list of all the karaf log names
2250 """
2251 try:
2252 cmd = "onos-ssh " + nodeIp + " ls -tr /opt/onos/log"
2253 self.handle.sendline( cmd )
2254 self.handle.expect( ":~" )
2255 before = self.handle.before.splitlines()
2256 logNames = []
2257 for word in before:
2258 if 'karaf.log' in word:
2259 logNames.append( word )
2260 return logNames
2261 except pexpect.EOF:
2262 main.log.error( self.name + ": EOF exception found" )
2263 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002264 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08002265 except pexpect.TIMEOUT:
2266 main.log.error( self.name + ": TIMEOUT exception found" )
2267 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002268 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08002269 except Exception:
2270 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002271 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08002272
Pratik Parab3b2ab5a2017-02-14 13:15:14 -08002273 def logReport( self, nodeIp, searchTerms, outputMode="s", startStr=None, endStr=None ):
Jon Hallb4242222016-01-25 17:07:04 -08002274 """
2275 Searches the latest ONOS log file for the given search terms and
2276 prints the total occurances of each term. Returns to combined total of
2277 all occurances.
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002278
Jon Hallb4242222016-01-25 17:07:04 -08002279 Arguments:
2280 * nodeIp - The ip of the ONOS node where the log is located
2281 * searchTerms - A string to grep for or a list of strings to grep
2282 for in the ONOS log. Will print out the number of
2283 occurances for each term.
2284 Optional Arguments:
2285 * outputMode - 's' or 'd'. If 'd' will print the last 5 lines
2286 containing each search term as well as the total
2287 number of occurances of each term. Defaults to 's',
2288 which prints the simple output of just the number
2289 of occurances for each term.
Pratik Parab3b2ab5a2017-02-14 13:15:14 -08002290 * startStr - the start string to be given to stream editor command
2291 as the start point for extraction of data
2292 * endStr - the end string to be given to stream editor command as
2293 the end point for extraction of data
Jon Hallb4242222016-01-25 17:07:04 -08002294 """
2295 try:
Jon Hall3c0114c2020-08-11 15:07:42 -07002296 main.log.info( self.name + ": Log Report for {} ".format( nodeIp ).center( 70, '=' ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002297 if isinstance( searchTerms, str ):
2298 searchTerms = [ searchTerms ]
Jon Hallb4242222016-01-25 17:07:04 -08002299 numTerms = len( searchTerms )
2300 outputMode = outputMode.lower()
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002301
Jon Hallb4242222016-01-25 17:07:04 -08002302 totalHits = 0
2303 logLines = []
2304 for termIndex in range( numTerms ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002305 term = searchTerms[ termIndex ]
2306 logLines.append( [ term ] )
Pratik Parab3b2ab5a2017-02-14 13:15:14 -08002307 if startStr and endStr:
2308 cmd = "onos-ssh {} \"sed -n '/{}/,/{}/p' /opt/onos/log/karaf.log | grep {}\"".format( nodeIp,
2309 startStr,
2310 endStr,
2311 term )
2312 else:
2313 cmd = "onos-ssh {} cat /opt/onos/log/karaf.log | grep {}".format( nodeIp,
2314 term )
Jon Hallb4242222016-01-25 17:07:04 -08002315 self.handle.sendline( cmd )
2316 self.handle.expect( ":~" )
2317 before = self.handle.before.splitlines()
2318 count = 0
2319 for line in before:
2320 if term in line and "grep" not in line:
2321 count += 1
2322 if before.index( line ) > ( len( before ) - 7 ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002323 logLines[ termIndex ].append( line )
Jon Hall3c0114c2020-08-11 15:07:42 -07002324 main.log.info( self.name + ": {}: {}".format( term, count ) )
Jon Hallb4242222016-01-25 17:07:04 -08002325 totalHits += count
2326 if termIndex == numTerms - 1:
2327 print "\n"
2328 if outputMode != "s":
2329 outputString = ""
2330 for term in logLines:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002331 outputString = term[ 0 ] + ": \n"
Jon Hallb4242222016-01-25 17:07:04 -08002332 for line in range( 1, len( term ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002333 outputString += ( "\t" + term[ line ] + "\n" )
2334 if outputString != ( term[ 0 ] + ": \n" ):
Jon Hallb4242222016-01-25 17:07:04 -08002335 main.log.info( outputString )
Jon Hall3c0114c2020-08-11 15:07:42 -07002336 main.log.info( self.name + ": =" * 70 )
Jon Hallb4242222016-01-25 17:07:04 -08002337 return totalHits
2338 except pexpect.EOF:
2339 main.log.error( self.name + ": EOF exception found" )
2340 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002341 main.cleanAndExit()
Jon Hallb4242222016-01-25 17:07:04 -08002342 except pexpect.TIMEOUT:
2343 main.log.error( self.name + ": TIMEOUT exception found" )
2344 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002345 main.cleanAndExit()
Jon Hallb4242222016-01-25 17:07:04 -08002346 except Exception:
2347 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002348 main.cleanAndExit()
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002349
2350 def copyMininetFile( self, fileName, localPath, userName, ip,
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002351 mnPath='~/mininet/custom/', timeout = 60 ):
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002352 """
2353 Description:
2354 Copy mininet topology file from dependency folder in the test folder
2355 and paste it to the mininet machine's mininet/custom folder
2356 Required:
2357 fileName - Name of the topology file to copy
2358 localPath - File path of the mininet topology file
2359 userName - User name of the mininet machine to send the file to
2360 ip - Ip address of the mininet machine
2361 Optional:
2362 mnPath - of the mininet directory to send the file to
2363 Return:
2364 Return main.TRUE if successfully copied the file otherwise
2365 return main.FALSE
2366 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002367
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002368 try:
2369 cmd = "scp " + localPath + fileName + " " + userName + "@" + \
2370 str( ip ) + ":" + mnPath + fileName
2371
2372 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07002373 self.handle.expect( self.prompt )
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002374
2375 main.log.info( self.name + ": Execute: " + cmd )
2376
2377 self.handle.sendline( cmd )
2378
2379 i = self.handle.expect( [ 'No such file',
2380 "100%",
2381 pexpect.TIMEOUT ] )
2382
2383 if i == 0:
2384 main.log.error( self.name + ": File " + fileName +
2385 " does not exist!" )
2386 return main.FALSE
2387
2388 if i == 1:
2389 main.log.info( self.name + ": File " + fileName +
2390 " has been copied!" )
2391 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07002392 self.handle.expect( self.prompt )
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002393 return main.TRUE
2394
2395 except pexpect.EOF:
2396 main.log.error( self.name + ": EOF exception found" )
2397 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002398 main.cleanAndExit()
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002399 except pexpect.TIMEOUT:
2400 main.log.error( self.name + ": TIMEOUT exception found" )
2401 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002402 main.cleanAndExit()
cameron@onlab.us78b89652015-07-08 15:21:03 -07002403
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002404 def jvmSet( self, memory=8 ):
Jon Hall4ba53f02015-07-29 13:07:41 -07002405
cameron@onlab.us78b89652015-07-08 15:21:03 -07002406 import os
2407
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002408 homeDir = os.path.expanduser( '~' )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002409 filename = "/onos/tools/package/bin/onos-service"
2410
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002411 serviceConfig = open( homeDir + filename, 'w+' )
2412 serviceConfig.write( "#!/bin/bash\n " )
2413 serviceConfig.write( "#------------------------------------- \n " )
2414 serviceConfig.write( "# Starts ONOS Apache Karaf container\n " )
2415 serviceConfig.write( "#------------------------------------- \n " )
2416 serviceConfig.write( "#export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-7-openjdk-amd64/}\n " )
2417 serviceConfig.write( """export JAVA_OPTS="${JAVA_OPTS:--Xms""" + str( memory ) + "G -Xmx" + str( memory ) + """G}" \n """ )
2418 serviceConfig.write( "[ -d $ONOS_HOME ] && cd $ONOS_HOME || ONOS_HOME=$(dirname $0)/..\n" )
2419 serviceConfig.write( """${ONOS_HOME}/apache-karaf-$KARAF_VERSION/bin/karaf "$@" \n """ )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002420 serviceConfig.close()
2421
Jon Hall6c44c0b2016-04-20 15:21:00 -07002422 def createDBFile( self, testData ):
Jon Hall4ba53f02015-07-29 13:07:41 -07002423
cameron@onlab.us78b89652015-07-08 15:21:03 -07002424 filename = main.TEST + "DB"
2425 DBString = ""
Jon Hall4ba53f02015-07-29 13:07:41 -07002426
cameron@onlab.us78b89652015-07-08 15:21:03 -07002427 for item in testData:
Jon Hall3e6edb32018-08-21 16:20:30 -07002428 if isinstance( item, str ):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002429 item = "'" + item + "'"
Jon Hall6c44c0b2016-04-20 15:21:00 -07002430 if testData.index( item ) < len( testData - 1 ):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002431 item += ","
Jon Hall6c44c0b2016-04-20 15:21:00 -07002432 DBString += str( item )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002433
Jon Hall6c44c0b2016-04-20 15:21:00 -07002434 DBFile = open( filename, "a" )
2435 DBFile.write( DBString )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002436 DBFile.close()
2437
Jon Hall6c44c0b2016-04-20 15:21:00 -07002438 def verifySummary( self, ONOSIp, *deviceCount ):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002439
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002440 self.handle.sendline( "onos " + ONOSIp + " summary" )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002441 self.handle.expect( ":~" )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002442
2443 summaryStr = self.handle.before
2444 print "\nSummary\n==============\n" + summaryStr + "\n\n"
2445
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002446 # passed = "SCC(s)=1" in summaryStr
2447 # if deviceCount:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002448 # passed = "devices=" + str(deviceCount) + "," not in summaryStr
cameron@onlab.us78b89652015-07-08 15:21:03 -07002449
GlennRC772363b2015-08-25 13:05:57 -07002450 passed = False
cameron@onlab.us78b89652015-07-08 15:21:03 -07002451 if "SCC(s)=1," in summaryStr:
2452 passed = True
Jon Hall6c44c0b2016-04-20 15:21:00 -07002453 print "Summary is verifed"
Jon Hall4ba53f02015-07-29 13:07:41 -07002454 else:
Jon Hall6c44c0b2016-04-20 15:21:00 -07002455 print "Summary failed"
cameron@onlab.us78b89652015-07-08 15:21:03 -07002456
2457 if deviceCount:
2458 print" ============================="
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002459 checkStr = "devices=" + str( deviceCount[ 0 ] ) + ","
cameron@onlab.us78b89652015-07-08 15:21:03 -07002460 print "Checkstr: " + checkStr
2461 if checkStr not in summaryStr:
2462 passed = False
Jon Hall6c44c0b2016-04-20 15:21:00 -07002463 print "Device count failed"
Jon Hall4ba53f02015-07-29 13:07:41 -07002464 else:
2465 print "device count verified"
cameron@onlab.us78b89652015-07-08 15:21:03 -07002466
2467 return passed
Jon Hall6c44c0b2016-04-20 15:21:00 -07002468
Jon Hall8f6d4622016-05-23 15:27:18 -07002469 def getIpAddr( self, iface=None ):
Jon Hall6c44c0b2016-04-20 15:21:00 -07002470 """
2471 Update self.ip_address with numerical ip address. If multiple IP's are
2472 located on the device, will attempt to use self.nicAddr to choose the
2473 right one. Defaults to 127.0.0.1 if no other address is found or cannot
2474 determine the correct address.
2475
2476 ONLY WORKS WITH IPV4 ADDRESSES
2477 """
2478 try:
Jon Hall8f6d4622016-05-23 15:27:18 -07002479 LOCALHOST = "127.0.0.1"
Jon Hall6c44c0b2016-04-20 15:21:00 -07002480 ipPat = "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"
2481 pattern = re.compile( ipPat )
2482 match = re.search( pattern, self.ip_address )
2483 if self.nicAddr:
2484 nicPat = self.nicAddr.replace( ".", "\." ).replace( "\*", r"\d{1,3}" )
2485 nicPat = re.compile( nicPat )
2486 else:
2487 nicPat = None
2488 # IF self.ip_address is an ip address and matches
2489 # self.nicAddr: return self.ip_address
2490 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002491 curIp = match.group( 0 )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002492 if nicPat:
2493 nicMatch = re.search( nicPat, curIp )
2494 if nicMatch:
2495 return self.ip_address
Jon Hall8f6d4622016-05-23 15:27:18 -07002496 # ELSE: IF iface, return ip of interface
2497 cmd = "ifconfig"
2498 ifPat = re.compile( "inet addr:({})".format( ipPat ) )
2499 if iface:
2500 cmd += " " + str( iface )
2501 raw = subprocess.check_output( cmd.split() )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002502 ifPat = re.compile( "inet addr:({})".format( ipPat ) )
2503 ips = re.findall( ifPat, raw )
Jon Hall8f6d4622016-05-23 15:27:18 -07002504 if iface:
2505 if ips:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002506 ip = ips[ 0 ]
Jon Hall8f6d4622016-05-23 15:27:18 -07002507 self.ip_address = ip
2508 return ip
2509 else:
2510 main.log.error( "Error finding ip, ifconfig output:".format( raw ) )
2511 # ELSE: attempt to get address matching nicPat.
Jon Hall6c44c0b2016-04-20 15:21:00 -07002512 if nicPat:
2513 for ip in ips:
2514 curMatch = re.search( nicPat, ip )
2515 if curMatch:
2516 self.ip_address = ip
2517 return ip
Jon Hall8f6d4622016-05-23 15:27:18 -07002518 else: # If only one non-localhost ip, return that
2519 tmpList = [ ip for ip in ips if ip is not LOCALHOST ]
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002520 if len( tmpList ) == 1:
2521 curIp = tmpList[ 0 ]
Jon Hall6c44c0b2016-04-20 15:21:00 -07002522 self.ip_address = curIp
2523 return curIp
Jon Hall8f6d4622016-05-23 15:27:18 -07002524 # Either no non-localhost IPs, or more than 1
Jon Hallebccd352016-05-20 15:17:17 -07002525 main.log.warn( "getIpAddr failed to find a public IP address" )
Jon Hall8f6d4622016-05-23 15:27:18 -07002526 return LOCALHOST
Jon Halle1790952016-05-23 15:51:46 -07002527 except subprocess.CalledProcessError:
Jon Hall8f6d4622016-05-23 15:27:18 -07002528 main.log.exception( "Error executing ifconfig" )
2529 except IndexError:
2530 main.log.exception( "Error getting IP Address" )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002531 except Exception:
2532 main.log.exception( "Uncaught exception" )
suibin zhang116647a2016-05-06 16:30:09 -07002533
Devin Lim461f0872017-06-05 16:49:33 -07002534 def startBasicONOS( self, nodeList, opSleep=60, onosStartupSleep=30, onosUser="sdn" ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002535 '''
suibin zhang116647a2016-05-06 16:30:09 -07002536 Start onos cluster with defined nodes, but only with drivers app
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002537 '''
suibin zhang116647a2016-05-06 16:30:09 -07002538 import time
2539
2540 self.createCellFile( self.ip_address,
Jon Hall3e6edb32018-08-21 16:20:30 -07002541 "temp",
2542 self.ip_address,
2543 "drivers",
2544 nodeList,
2545 nodeList,
2546 onosUser=onosUser )
suibin zhang116647a2016-05-06 16:30:09 -07002547
2548 main.log.info( self.name + ": Apply cell to environment" )
2549 cellResult = self.setCell( "temp" )
2550 verifyResult = self.verifyCell()
2551
2552 main.log.info( self.name + ": Creating ONOS package" )
You Wangd1bcaca2016-10-24 15:23:26 -07002553 packageResult = self.buckBuild( timeout=opSleep )
suibin zhang116647a2016-05-06 16:30:09 -07002554
You Wangc669d212017-01-25 11:09:48 -08002555 main.log.info( self.name + ": Uninstalling ONOS" )
2556 for nd in nodeList:
2557 self.onosUninstall( nodeIp=nd )
2558
suibin zhang116647a2016-05-06 16:30:09 -07002559 main.log.info( self.name + ": Installing ONOS package" )
2560 for nd in nodeList:
You Wangc669d212017-01-25 11:09:48 -08002561 self.onosInstall( node=nd )
2562
2563 main.log.info( self.name + ": Set up ONOS secure SSH" )
2564 for nd in nodeList:
2565 self.onosSecureSSH( node=nd )
suibin zhang116647a2016-05-06 16:30:09 -07002566
2567 main.log.info( self.name + ": Starting ONOS service" )
2568 time.sleep( onosStartupSleep )
2569
2570 onosStatus = True
2571 for nd in nodeList:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002572 onosStatus = onosStatus & self.isup( node = nd )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002573 # print "onosStatus is: " + str( onosStatus )
suibin zhang116647a2016-05-06 16:30:09 -07002574
2575 return main.TRUE if onosStatus else main.FALSE
2576
Jon Hall3c0114c2020-08-11 15:07:42 -07002577 def onosNetCfg( self, controllerIp, path, fileName, user=None, password=None):
Jeremy Songster5665f1b2016-06-20 14:38:22 -07002578 """
2579 Push a specified json file to ONOS through the onos-netcfg service
2580
2581 Required:
Devin Lim02075272017-07-10 15:33:21 -07002582 controllerIp - the Ip of the ONOS node in the cluster
Jeremy Songster5665f1b2016-06-20 14:38:22 -07002583 path - the location of the file to be sent
2584 fileName - name of the json file to be sent
2585
2586 Returns main.TRUE on successfully sending json file, and main.FALSE if
2587 there is an error.
2588 """
2589 try:
Jon Hall3c0114c2020-08-11 15:07:42 -07002590 cmd = "onos-netcfg "
2591 if user:
2592 cmd += "-u %s " % user
2593 if password:
2594 cmd += "-p %s " % password
2595 cmd += "{0} {1}{2}".format( controllerIp, path, fileName )
2596 main.log.info( self.name + ": Sending: " + cmd )
2597 self.handle.sendline( cmd )
2598 self.handle.expect( self.prompt )
Devin Lim02075272017-07-10 15:33:21 -07002599 handle = self.handle.before
Jon Hall3c0114c2020-08-11 15:07:42 -07002600 if "Error" in handle or\
2601 "No such file or directory" in handle or\
2602 "command not found" in handle or\
2603 "curl: " in handle:
Jeremy Ronquillo3008aa32017-07-07 15:38:57 -07002604 main.log.error( self.name + ": " + handle + self.handle.after )
Devin Lim02075272017-07-10 15:33:21 -07002605 return main.FALSE
Jon Hall3c0114c2020-08-11 15:07:42 -07002606 main.log.debug( self.name + ": " + handle )
Devin Lim752dd7b2017-06-27 14:40:03 -07002607 return main.TRUE
Jeremy Songster5665f1b2016-06-20 14:38:22 -07002608 except pexpect.EOF:
2609 main.log.error( self.name + ": EOF exception found" )
2610 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002611 main.cleanAndExit()
Jeremy Songster5665f1b2016-06-20 14:38:22 -07002612 except Exception:
2613 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002614 main.cleanAndExit()
Devin Lim3ebd5e72017-11-14 10:38:00 -08002615
2616 def formCluster( self, onosIPs ):
2617 """
2618 From ONOS cluster for IP addresses in onosIPs list
2619 """
2620 try:
2621 onosIPs = " ".join( onosIPs )
2622 command = "onos-form-cluster {}".format( onosIPs )
Jon Hall3c0114c2020-08-11 15:07:42 -07002623 main.log.info( self.name + ": Sending: " + command )
Devin Lim3ebd5e72017-11-14 10:38:00 -08002624 self.handle.sendline( "" )
2625 self.handle.expect( self.prompt )
2626 self.handle.sendline( command )
2627 self.handle.expect( self.prompt )
2628 handle = self.handle.before
2629 main.log.debug( handle )
2630 assert handle is not None, "Error in sendline"
2631 assert "Command not found:" not in handle, handle
2632 assert "Error" not in handle, handle
2633 assert "Exception:" not in handle, handle
2634 assert "curl:" not in handle, handle
2635 return main.TRUE
2636 except AssertionError:
2637 main.log.exception( "{} Error in onos-form-cluster 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()
Jon Hall7ce46ea2018-02-05 12:20:59 -08002649
2650 def backupData( self, location ):
2651 """
2652 Backs up ONOS data and logs to 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 to save the backup to
2656 """
2657 try:
2658 cmd = "/opt/onos/bin/onos-backup " + 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-backup 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()
2681
2682 def restoreData( self, location ):
2683 """
2684 Restores ONOS data and logs from a given location. Returns main.FALSE
2685 if there is an error executing the command, and main.TRUE otherwise.
2686 required arguments:
2687 loaction - The file path of a backup file
2688 """
2689 try:
2690 cmd = "/opt/onos/bin/onos-restore " + str( location )
2691 self.handle.sendline( cmd )
2692 self.handle.expect( self.prompt )
2693 handle = self.handle.before
2694 main.log.debug( handle )
2695 assert handle is not None, "Error in sendline"
2696 assert "Command not found:" not in handle, handle
2697 assert "Error" not in handle, handle
2698 assert "Exception:" not in handle, handle
2699 return main.TRUE
2700 except AssertionError:
2701 main.log.exception( "{} Error in onos-restore output:".format( self.name ) )
2702 return main.FALSE
2703 except TypeError:
2704 main.log.exception( self.name + ": Object not as expected" )
2705 return main.FALSE
2706 except pexpect.EOF:
2707 main.log.error( self.name + ": EOF exception found" )
2708 main.log.error( self.name + ": " + self.handle.before )
2709 main.cleanAndExit()
2710 except Exception:
2711 main.log.exception( self.name + ": Uncaught exception!" )
2712 main.cleanAndExit()
You Wang5df1c6d2018-04-06 18:02:02 -07002713
Jon Hall43060f62020-06-23 13:13:33 -07002714 def onosDiagnostics( self, onosIPs, dstDir, suffix, timeout=300, profile="TRELLIS_PROFILE" ):
You Wang5df1c6d2018-04-06 18:02:02 -07002715 """
2716 Run onos-diagnostics with given ONOS instance IPs and save output to dstDir
2717 with suffix specified E.g. onos-diags-suffix.tar.gz
Jon Hall0e240372018-05-02 11:21:57 -07002718 required arguments:
You Wang5df1c6d2018-04-06 18:02:02 -07002719 onosIPs - list of ONOS IPs for collecting diags
2720 dstDir - diags file will be saved under the directory specified
2721 suffix - diags file will be named with the suffix specified
2722 returns:
2723 main.FALSE if there's an error executing the command, and main.TRUE otherwise
2724 """
2725 try:
Jon Hall43060f62020-06-23 13:13:33 -07002726 self.handle.sendline( "export DIAGS_PROFILE=%s" % profile )
2727 self.handle.expect( self.prompt )
You Wang5df1c6d2018-04-06 18:02:02 -07002728 cmd = "onos-diagnostics"
2729 assert isinstance( onosIPs, list )
2730 for ip in onosIPs:
2731 cmd += " " + str( ip )
2732 self.handle.sendline( cmd )
Jon Hall9b0de1f2020-08-24 15:38:04 -07002733 i = 0
2734 while i == 0:
2735 i = self.handle.expect( [ "Password", self.prompt ], timeout=timeout )
2736 handle = self.handle.before
2737 main.log.debug( "%s: %s" % ( self.name, handle ) )
2738 if i == 0:
2739 self.handle.sendline( self.pwd )
You Wang5df1c6d2018-04-06 18:02:02 -07002740 assert handle is not None, "Error in sendline"
Jon Hall9b0de1f2020-08-24 15:38:04 -07002741 assert "The requested URL returned error" not in handle, handle
You Wang5df1c6d2018-04-06 18:02:02 -07002742 assert "Command not found:" not in handle, handle
2743 assert "Exception:" not in handle, handle
2744 # Rename and move diags file to dstDir from /tmp
2745 if dstDir[ -1: ] != "/":
2746 dstDir += "/"
2747 self.handle.sendline( "mv /tmp/onos-diags.tar.gz " + str( dstDir ) + "onos-diags" + str( suffix ) + ".tar.gz" )
2748 self.handle.expect( self.prompt )
2749 handle = self.handle.before
Jon Hall9b0de1f2020-08-24 15:38:04 -07002750 main.log.debug( "%s: %s" % ( self.name, handle ) )
You Wang5df1c6d2018-04-06 18:02:02 -07002751 assert handle is not None, "Error in sendline"
2752 assert "No such file or directory" not in handle, handle
2753 return main.TRUE
2754 except AssertionError:
2755 main.log.exception( "{} Error in onos-diagnostics output:".format( self.name ) )
2756 return main.FALSE
2757 except TypeError:
2758 main.log.exception( self.name + ": Object not as expected" )
2759 return main.FALSE
You Wang223faa32018-06-21 10:45:47 -07002760 except pexpect.TIMEOUT:
2761 main.log.exception( self.name + ": TIMEOUT exception found in onosDiagnostics" )
2762 main.log.error( self.name + ": " + self.handle.before )
You Wangb65d2372018-08-17 15:37:59 -07002763 self.exitFromCmd( self.prompt, 100 )
You Wang223faa32018-06-21 10:45:47 -07002764 return main.FALSE
You Wang5df1c6d2018-04-06 18:02:02 -07002765 except pexpect.EOF:
2766 main.log.error( self.name + ": EOF exception found" )
2767 main.log.error( self.name + ": " + self.handle.before )
2768 main.cleanAndExit()
2769 except Exception:
2770 main.log.exception( self.name + ": Uncaught exception!" )
2771 main.cleanAndExit()
Jon Hall0e240372018-05-02 11:21:57 -07002772
2773 def onosPower( self, onosIP, toggle, userName=None ):
2774 """
2775 Run onos-power script to tell the cell warden to simulate a power faulure
2776 for the given container.
2777 required :
2778 onosIP - ONOS node IP
2779 toggle - either "off" or "on", used to indicate whether
2780 the node should be powered off or on
2781 returns:
2782 main.FALSE if there's an error executing the command, and main.TRUE otherwise
2783 """
2784 try:
2785 cmd = "onos-power {} {}".format( onosIP, toggle )
2786 if userName:
2787 cmd += " {}".format( userName )
2788 self.handle.sendline( cmd )
2789 self.handle.expect( self.prompt )
2790 handle = self.handle.before
2791 main.log.debug( handle )
2792 assert handle is not None, "Error in sendline"
2793 assert "Command not found:" not in handle, handle
2794 assert "Exception:" not in handle, handle
2795 assert "usage:" not in handle, handle
2796 return main.TRUE
2797 except AssertionError:
2798 main.log.exception( "{} Error in onos-power output:".format( self.name ) )
2799 return main.FALSE
2800 except TypeError:
2801 main.log.exception( self.name + ": Object not as expected" )
2802 return main.FALSE
2803 except pexpect.EOF:
2804 main.log.error( self.name + ": EOF exception found" )
2805 main.log.error( self.name + ": " + self.handle.before )
2806 main.cleanAndExit()
2807 except Exception:
2808 main.log.exception( self.name + ": Uncaught exception!" )
2809 main.cleanAndExit()
You Wangf9d95be2018-08-01 14:35:37 -07002810
2811 def atomixKill( self, nodeIp ):
2812 """
2813 Calls the command: 'atomix-kill [<node-ip>]'
2814 Kills the Atomix instance running on the specified node
2815 """
2816 try:
2817 self.handle.sendline( "" )
2818 self.handle.expect( self.prompt )
2819 self.handle.sendline( "atomix-kill " + str( nodeIp ) )
2820 i = self.handle.expect( [
2821 self.prompt,
2822 "No\sroute\sto\shost",
2823 "password:",
2824 pexpect.TIMEOUT ], timeout=60 )
2825
2826 if i == 0:
Jon Hall3c0114c2020-08-11 15:07:42 -07002827 main.log.info( self.name + ": Atomix instance " + str( nodeIp ) + " was killed" )
You Wangf9d95be2018-08-01 14:35:37 -07002828 return main.TRUE
2829 elif i == 1:
Jon Hall3c0114c2020-08-11 15:07:42 -07002830 main.log.info( self.name + ": No route to host" )
You Wangf9d95be2018-08-01 14:35:37 -07002831 return main.FALSE
2832 elif i == 2:
Jon Hall3c0114c2020-08-11 15:07:42 -07002833 main.log.info( self.name + ": Passwordless login for host: " + str( nodeIp ) + " not configured" )
You Wangf9d95be2018-08-01 14:35:37 -07002834 return main.FALSE
2835 else:
Jon Hall3c0114c2020-08-11 15:07:42 -07002836 main.log.info( self.name + ": Atomix instance was not killed" )
You Wangf9d95be2018-08-01 14:35:37 -07002837 return main.FALSE
2838
2839 except pexpect.EOF:
2840 main.log.error( self.name + ": EOF exception found" )
2841 main.log.error( self.name + ": " + self.handle.before )
2842 main.cleanAndExit()
2843 except Exception:
2844 main.log.exception( self.name + ": Uncaught exception!" )
2845 main.cleanAndExit()
2846
2847 def atomixUninstall( self, nodeIp="" ):
2848 """
2849 Calls the command: 'atomix-uninstall'
2850 Uninstalls Atomix from the designated node, stopping if needed
2851 """
2852 try:
2853 self.handle.sendline( "" )
2854 self.handle.expect( self.prompt, timeout=180 )
2855 self.handle.sendline( "atomix-uninstall " + str( nodeIp ) )
2856 self.handle.expect( self.prompt, timeout=180 )
Jon Hall3c0114c2020-08-11 15:07:42 -07002857 main.log.info( self.name + ": Atomix " + nodeIp + " was uninstalled" )
You Wangf9d95be2018-08-01 14:35:37 -07002858 # onos-uninstall command does not return any text
2859 return main.TRUE
2860 except pexpect.TIMEOUT:
2861 main.log.exception( self.name + ": Timeout in atomixUninstall" )
2862 self.handle.send( "\x03" ) # Control-C
2863 self.handle.expect( self.prompt )
2864 return main.FALSE
2865 except pexpect.EOF:
2866 main.log.error( self.name + ": EOF exception found" )
2867 main.log.error( self.name + ": " + self.handle.before )
2868 main.cleanAndExit()
2869 except Exception:
2870 main.log.exception( self.name + ": Uncaught exception!" )
2871 main.cleanAndExit()
2872
2873 def atomixInstall( self, options="", node="" ):
2874 """
2875 Installs Atomix on the designated nodes.
2876 Returns: main.TRUE on success and main.FALSE on failure
2877 """
2878 try:
2879 if options:
2880 self.handle.sendline( "atomix-install " + options + " " + node )
2881 else:
2882 self.handle.sendline( "atomix-install " + node )
2883 self.handle.expect( "atomix-install " )
2884 i = self.handle.expect( [ "Network\sis\sunreachable",
2885 "is already installed",
2886 "saved",
2887 self.prompt,
2888 pexpect.TIMEOUT ], timeout=180 )
2889 if i == 0:
2890 # can't reach ONOS node
Jon Hall3e6edb32018-08-21 16:20:30 -07002891 main.log.warn( self.name + ": Network is unreachable" )
You Wangf9d95be2018-08-01 14:35:37 -07002892 self.handle.expect( self.prompt )
2893 return main.FALSE
2894 elif i == 1:
2895 # same bits are already on Atomix node
Jon Hall3e6edb32018-08-21 16:20:30 -07002896 main.log.info( self.name + ": Atomix is already installed on " + node )
You Wangf9d95be2018-08-01 14:35:37 -07002897 self.handle.expect( self.prompt )
2898 return main.TRUE
Jon Hallb685a1c2018-10-30 15:17:01 -07002899 elif i == 2:
Jon Hall3e6edb32018-08-21 16:20:30 -07002900 main.log.info( self.name + ": Atomix was installed on " + node )
You Wangf9d95be2018-08-01 14:35:37 -07002901 self.handle.expect( self.prompt )
2902 return main.TRUE
Jon Hallb685a1c2018-10-30 15:17:01 -07002903 elif i == 3:
2904 self.handle.sendline( "echo Return code: $?" )
2905 self.handle.expect( "\$\?" )
2906 self.handle.expect( self.prompt )
Jon Hallb685a1c2018-10-30 15:17:01 -07002907 match = re.search( "Return code: (\d+)", self.handle.before )
2908 if match:
2909 exitCode = int( match.group( 1 ) )
2910 else:
2911 # Didn't match pattern
2912 main.log.error( "Could not parse exit code of atomix-install" )
Jon Hall5e1469a2018-11-01 13:55:53 -07002913 main.log.debug( self.handle.before + self.handle.before )
Jon Hallb685a1c2018-10-30 15:17:01 -07002914 return main.FALSE
2915 if exitCode == 0:
2916 return main.TRUE
2917 else:
Jon Hall5e1469a2018-11-01 13:55:53 -07002918 main.log.error( "Unsuccessful exit code of atomix-install" )
2919 main.log.debug( self.handle.before + self.handle.before )
Jon Hallb685a1c2018-10-30 15:17:01 -07002920 return main.FALSE
You Wangf9d95be2018-08-01 14:35:37 -07002921 elif i == 4:
2922 # timeout
Jon Hall3e6edb32018-08-21 16:20:30 -07002923 main.log.info( self.name + ": Installation of Atomix on " + node + " timed out" )
You Wangf9d95be2018-08-01 14:35:37 -07002924 self.handle.expect( self.prompt )
2925 main.log.warn( self.handle.before )
2926 self.handle.send( "\x03" ) # Control-C
2927 self.handle.expect( self.prompt )
2928 return main.FALSE
2929 except pexpect.EOF:
2930 main.log.error( self.name + ": EOF exception found" )
2931 main.log.error( self.name + ": " + self.handle.before )
2932 main.cleanAndExit()
2933 except Exception:
2934 main.log.exception( self.name + ": Uncaught exception!" )
2935 main.cleanAndExit()
Jon Hall43060f62020-06-23 13:13:33 -07002936
2937 def onosFetchApp( self, url, dstPath=None ):
2938 """
2939 Fetch an external onos app
2940
2941 Required:
2942 url - url for where to download the app
2943 dstPath - where the file will be saved
2944
2945 Returns main.TRUE on successfully fetching file, and main.FALSE if
2946 there is an error.
2947 """
2948 try:
2949 cmd = "wget -q --backups=1 "
2950 if dstPath:
2951 cmd += "-P %s " % ( dstPath )
2952 cmd += str( url )
Jon Hall3c0114c2020-08-11 15:07:42 -07002953 main.log.info( self.name + ": Sending: " + cmd )
2954 self.handle.sendline( cmd )
2955 self.handle.expect( self.prompt )
Jon Hall43060f62020-06-23 13:13:33 -07002956 output = self.handle.before
2957 main.log.debug( output )
2958 if "Error" in output or "No such file or directory" in output:
2959 main.log.error( self.name + ": " + output + self.handle.after )
2960 return main.FALSE
2961 return main.TRUE
2962 except pexpect.EOF:
2963 main.log.error( self.name + ": EOF exception found" )
2964 main.log.error( self.name + ": " + self.handle.before )
2965 main.cleanAndExit()
2966 except Exception:
2967 main.log.exception( self.name + ": Uncaught exception!" )
2968 main.cleanAndExit()
2969
2970 def onosApp( self, onosIP, option, fileName, filePath='~/onos/'):
2971 """
2972 Wrapper for onos-app script
2973
2974 Required:
2975 - onosIP - The ip address of the onos instance
2976 - option - What command are we doing?
2977 [ list|install|install!|reinstall|reinstall!|activate|deactivate|uninstall ]
2978 - fileName - The name of the app file
2979 Optional Arguments:
2980 - filePath - The location of the file
2981
2982 Returns main.TRUE on successfully executing the command, and main.FALSE if
2983 there is an error.
2984 """
2985 # FIXME: Not all options may work, more testing is required, only tested with install(!)
2986 try:
2987 cmd = "onos-app %s %s %s/%s" % ( onosIP, option, filePath, fileName )
Jon Hall3c0114c2020-08-11 15:07:42 -07002988 main.log.info( self.name + ": Sending: " + cmd )
2989 self.handle.sendline( cmd )
2990 self.handle.expect( self.prompt )
Jon Hall43060f62020-06-23 13:13:33 -07002991 handle = self.handle.before
2992 main.log.debug( handle )
2993 if "Error" in handle or "usage: " in handle or "curl: " in handle:
2994 main.log.error( self.name + ": " + handle + self.handle.after )
2995 return main.FALSE
2996 return main.TRUE
2997 except pexpect.EOF:
2998 main.log.error( self.name + ": EOF exception found" )
2999 main.log.error( self.name + ": " + self.handle.before )
3000 main.cleanAndExit()
3001 except Exception:
3002 main.log.exception( self.name + ": Uncaught exception!" )
3003 main.cleanAndExit()
Jon Hall3c0114c2020-08-11 15:07:42 -07003004
3005 def makeDocker( self, path, cmd, prompt="Successfully tagged", timeout=600 ):
3006 """
3007 Build a docker image using a command, such as make
3008 Arguments:
3009 - path: a path where the script is located. will cd to path
3010 - cmd: the command to run
3011 Optional Arguments:
3012 - prompt: A custom prompt to expect after the command is finished,
3013 incase the host prompt is printed during the build
3014 - timeout: how long to wait for the build
3015 """
3016 try:
3017 main.log.warn( "%s: makeDocker()" % self.name )
3018 self.handle.sendline( "cd %s" % path )
3019 self.handle.expect( self.prompt )
3020 self.handle.sendline( cmd )
3021 self.handle.expect( prompt, timeout=timeout )
3022 fullResponse = self.handle.before
3023 tailResponse = self.handle.after
3024 # TODO: error checking, might be difficult with custom expects
3025 self.handle.expect( self.prompt )
3026 tailResponse += self.handle.before + self.handle.after
3027 fullResponse += tailResponse
3028 main.log.debug( self.name + ": " + tailResponse )
3029 self.handle.sendline( "cd %s" % self.home )
3030 self.handle.expect( self.prompt )
3031 return main.TRUE
3032 except pexpect.EOF:
3033 main.log.error( self.name + ": EOF exception found" )
3034 main.log.error( self.name + ": " + self.handle.before )
3035 main.cleanAndExit()
3036 except Exception:
3037 main.log.exception( self.name + ": Uncaught exception!" )
3038 main.log.debug( self.name + ": " + self.handle.before )
3039 main.cleanAndExit()
3040
3041 def generateOnosConfig( self, nodeIp, path="cluster.json" ):
3042 """
3043 Generate onos cluster configuration file
3044 Arguments:
3045 - nodeIp: ip of the node this file is fore
3046 Optional Arguments:
3047 - The path to save the file to
3048 """
3049 try:
3050 main.log.info( "%s: Generating onos config file for %s" % ( self.name, nodeIp ) )
3051 self.handle.sendline( "onos-gen-config %s %s" % ( nodeIp, path ) )
3052 i = self.handle.expect( [ self.prompt, "not found", "Error" ] )
3053 response = self.handle.before
3054 if i == 0:
3055 main.log.debug( "%s: %s" % ( self.name, response ) )
3056 return main.TRUE
3057 else:
3058 response += self.handle.after
3059 self.handle.expect( self.prompt )
3060 response += self.handle.before
3061 main.log.debug( "%s: %s" % ( self.name, response ) )
3062 return main.FALSE
3063 except pexpect.EOF:
3064 main.log.error( self.name + ": EOF exception found" )
3065 main.log.error( self.name + ": " + self.handle.before )
3066 main.cleanAndExit()
3067 except Exception:
3068 main.log.exception( self.name + ": Uncaught exception!" )
3069 main.log.debug( self.name + ": " + self.handle.before )
3070 main.cleanAndExit()
3071
3072 def generateAtomixConfig( self, nodeIp, path="atomix.json" ):
3073 """
3074 Generate atomix cluster configuration file
3075 Arguments:
3076 - nodeIp: ip of the node this file is fore
3077 Optional Arguments:
3078 - The path to save the file to
3079 """
3080 try:
3081 main.log.info( "%s: Generating atomix config file for %s" % ( self.name, nodeIp ) )
3082 self.handle.sendline( "atomix-gen-config %s %s" % ( nodeIp, path ) )
3083 i = self.handle.expect( [ self.prompt, "not found", "Error" ] )
3084 response = self.handle.before
3085 if i == 0:
3086 main.log.debug( "%s: %s" % ( self.name, response ) )
3087 return main.TRUE
3088 else:
3089 response += self.handle.after
3090 self.handle.expect( self.prompt )
3091 response += self.handle.before
3092 main.log.debug( "%s: %s" % ( self.name, response ) )
3093 return main.FALSE
3094 except pexpect.EOF:
3095 main.log.error( self.name + ": EOF exception found" )
3096 main.log.error( self.name + ": " + self.handle.before )
3097 main.cleanAndExit()
3098 except Exception:
3099 main.log.exception( self.name + ": Uncaught exception!" )
3100 main.log.debug( self.name + ": " + self.handle.before )
3101 main.cleanAndExit()