blob: 18540f0b1ea96c2b6851d12a37d41b7d6732c323 [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":
68 self.home = self.options[ 'home' ]
69 elif key == "nodes":
kelvin-onlabc2b79102015-07-14 11:41:20 -070070 # Maximum number of ONOS nodes to run, if there is any
kelvin-onlaba4074292015-07-09 15:19:49 -070071 self.maxNodes = int( self.options[ 'nodes' ] )
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 )
Jeremyf0aecdb2016-03-30 13:19:57 -07001309 cmdStr = "onos-die " + str( nodeIp )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001310 self.handle.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -08001311 i = self.handle.expect( [
andrewonlabaedc8332014-12-04 12:43:03 -05001312 "Killing\sONOS",
1313 "ONOS\sprocess\sis\snot\srunning",
Jeremy Songster14c13572016-04-21 17:34:03 -07001314 pexpect.TIMEOUT ], timeout=60 )
andrewonlabaedc8332014-12-04 12:43:03 -05001315 if i == 0:
Jon Hall3c0114c2020-08-11 15:07:42 -07001316 main.log.info( self.name + ": ONOS instance " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001317 " was killed and stopped" )
Jon Hall53c5e662016-04-13 16:06:56 -07001318 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001319 self.handle.expect( self.prompt )
andrewonlabaedc8332014-12-04 12:43:03 -05001320 return main.TRUE
1321 elif i == 1:
Jon Hall3c0114c2020-08-11 15:07:42 -07001322 main.log.info( self.name + ": ONOS process was not running" )
Jon Hall53c5e662016-04-13 16:06:56 -07001323 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001324 self.handle.expect( self.prompt )
andrewonlabaedc8332014-12-04 12:43:03 -05001325 return main.FALSE
1326 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001327 main.log.error( self.name + ": EOF exception found" )
1328 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001329 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001330 except Exception:
1331 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001332 main.cleanAndExit()
andrewonlabaedc8332014-12-04 12:43:03 -05001333
kelvin-onlabd3b64892015-01-20 13:26:24 -08001334 def onosKill( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001335 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001336 Calls the command: 'onos-kill [<node-ip>]'
1337 "Remotely, and unceremoniously kills the ONOS instance running on
1338 the specified cell machine" - Tom V
kelvin8ec71442015-01-15 16:57:00 -08001339 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001340 try:
kelvin8ec71442015-01-15 16:57:00 -08001341 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001342 self.handle.expect( self.prompt )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001343 self.handle.sendline( "onos-kill " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -08001344 i = self.handle.expect( [
Devin Limc20e79a2017-06-07 10:29:57 -07001345 self.prompt,
andrewonlabe8e56fd2014-10-09 17:12:44 -04001346 "No\sroute\sto\shost",
1347 "password:",
Jeremy Songster14c13572016-04-21 17:34:03 -07001348 pexpect.TIMEOUT ], timeout=60 )
kelvin8ec71442015-01-15 16:57:00 -08001349
andrewonlabe8e56fd2014-10-09 17:12:44 -04001350 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001351 main.log.info(
1352 "ONOS instance " + str(
kelvin-onlabd3b64892015-01-20 13:26:24 -08001353 nodeIp ) + " was killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001354 return main.TRUE
1355 elif i == 1:
Jon Hall3c0114c2020-08-11 15:07:42 -07001356 main.log.info( self.name + ": No route to host" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001357 return main.FALSE
1358 elif i == 2:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001359 main.log.info(
1360 "Passwordless login for host: " +
1361 str( nodeIp ) +
1362 " not configured" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001363 return main.FALSE
1364 else:
Jon Hall3c0114c2020-08-11 15:07:42 -07001365 main.log.info( self.name + ": ONOS instance was not killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001366 return main.FALSE
kelvin8ec71442015-01-15 16:57:00 -08001367
andrewonlabe8e56fd2014-10-09 17:12:44 -04001368 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001369 main.log.error( self.name + ": EOF exception found" )
1370 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001371 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001372 except Exception:
1373 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001374 main.cleanAndExit()
andrewonlabe8e56fd2014-10-09 17:12:44 -04001375
You Wang5bf49592020-07-08 18:47:46 -07001376 def onosAppInstall( self, nodeIp, oarFile ):
1377 """
Jon Hall3c0114c2020-08-11 15:07:42 -07001378 Calls the command: 'onos-app nodeIp reinstall! oarFile'
You Wang5bf49592020-07-08 18:47:46 -07001379 Installs an ONOS application from an oar file
1380 """
1381 try:
Jon Hall3c0114c2020-08-11 15:07:42 -07001382 cmd = "onos-app " + str( nodeIp ) + " reinstall! " + str( oarFile )
You Wang5bf49592020-07-08 18:47:46 -07001383 self.handle.sendline( cmd )
Jon Hall3c0114c2020-08-11 15:07:42 -07001384 i = self.handle.expect( [ "409 Conflict", self.prompt ] )
1385 if i == 0:
1386 self.handle.expect( self.prompt )
1387 time.sleep( 30 )
1388 self.handle.sendline( cmd )
You Wang5bf49592020-07-08 18:47:46 -07001389 handle = self.handle.before
Jon Hall3c0114c2020-08-11 15:07:42 -07001390 main.log.debug( "%s: %s" % ( self.name, handle ) )
You Wang5bf49592020-07-08 18:47:46 -07001391 assert handle is not None, "Error in sendline"
1392 assert "Command not found:" not in handle, handle
1393 assert "error" not in handle, handle
1394 assert "usage:" not in handle, handle
1395 return main.TRUE
1396 except AssertionError:
1397 main.log.exception( "Error in onos-app output" )
1398 return main.FALSE
1399 except pexpect.TIMEOUT:
1400 main.log.exception( self.name + ": Timeout in onosAppInstall" )
1401 self.handle.send( "\x03" ) # Control-C
1402 self.handle.expect( self.prompt )
1403 return main.FALSE
1404 except pexpect.EOF:
1405 main.log.error( self.name + ": EOF exception found" )
1406 main.log.error( self.name + ": " + self.handle.before )
1407 main.cleanAndExit()
1408 except Exception:
1409 main.log.exception( self.name + ": Uncaught exception!" )
1410 main.cleanAndExit()
1411
kelvin-onlabd3b64892015-01-20 13:26:24 -08001412 def onosRemoveRaftLogs( self ):
kelvin8ec71442015-01-15 16:57:00 -08001413 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001414 Removes Raft / Copy cat files from ONOS to ensure
Jon Hallfcc88622014-11-25 13:09:54 -05001415 a cleaner environment.
1416
andrewonlab19fbdca2014-11-14 12:55:59 -05001417 Description:
Jon Hallfcc88622014-11-25 13:09:54 -05001418 Stops all ONOS defined in the cell,
andrewonlab19fbdca2014-11-14 12:55:59 -05001419 wipes the raft / copycat log files
kelvin8ec71442015-01-15 16:57:00 -08001420 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001421 try:
kelvin8ec71442015-01-15 16:57:00 -08001422 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001423 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -08001424 self.handle.sendline( "onos-remove-raft-logs" )
1425 # Sometimes this command hangs
Devin Limc20e79a2017-06-07 10:29:57 -07001426 i = self.handle.expect( [ self.prompt, pexpect.TIMEOUT ],
kelvin8ec71442015-01-15 16:57:00 -08001427 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001428 if i == 1:
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:
1432 return main.FALSE
andrewonlab19fbdca2014-11-14 12:55:59 -05001433 return main.TRUE
andrewonlab19fbdca2014-11-14 12:55:59 -05001434 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001435 main.log.error( self.name + ": EOF exception found" )
1436 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001437 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001438 except Exception:
1439 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001440 main.cleanAndExit()
Jon Hallfcc88622014-11-25 13:09:54 -05001441
kelvin-onlabd3b64892015-01-20 13:26:24 -08001442 def onosStartNetwork( self, mntopo ):
kelvin8ec71442015-01-15 16:57:00 -08001443 """
1444 Calls the command 'onos-start-network [ <mininet-topo> ]
1445 "remotely starts the specified topology on the cell's
andrewonlab94282092014-10-10 13:00:11 -04001446 mininet machine against all controllers configured in the
kelvin8ec71442015-01-15 16:57:00 -08001447 cell."
andrewonlab94282092014-10-10 13:00:11 -04001448 * Specify mininet topology file name for mntopo
1449 * Topo files should be placed at:
1450 ~/<your-onos-directory>/tools/test/topos
kelvin8ec71442015-01-15 16:57:00 -08001451
andrewonlab94282092014-10-10 13:00:11 -04001452 NOTE: This function will take you to the mininet prompt
kelvin8ec71442015-01-15 16:57:00 -08001453 """
andrewonlab94282092014-10-10 13:00:11 -04001454 try:
1455 if not mntopo:
kelvin8ec71442015-01-15 16:57:00 -08001456 main.log.error( "You must specify a topo file to execute" )
andrewonlab94282092014-10-10 13:00:11 -04001457 return main.FALSE
andrewonlab94282092014-10-10 13:00:11 -04001458
kelvin8ec71442015-01-15 16:57:00 -08001459 mntopo = str( mntopo )
1460 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001461 self.handle.expect( self.prompt )
andrewonlab94282092014-10-10 13:00:11 -04001462
kelvin8ec71442015-01-15 16:57:00 -08001463 self.handle.sendline( "onos-start-network " + mntopo )
1464 self.handle.expect( "mininet>" )
Jon Hall3c0114c2020-08-11 15:07:42 -07001465 main.log.info( self.name + ": Network started, entered mininet prompt" )
kelvin8ec71442015-01-15 16:57:00 -08001466
1467 # TODO: Think about whether return is necessary or not
andrewonlab94282092014-10-10 13:00:11 -04001468
1469 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001470 main.log.error( self.name + ": EOF exception found" )
1471 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001472 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001473 except Exception:
1474 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001475 main.cleanAndExit()
andrewonlab94282092014-10-10 13:00:11 -04001476
Jeremy Songster14c13572016-04-21 17:34:03 -07001477 def isup( self, node="", timeout=240 ):
kelvin8ec71442015-01-15 16:57:00 -08001478 """
1479 Run's onos-wait-for-start which only returns once ONOS is at run
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001480 level 100(ready for use)
andrewonlab8d0d7d72014-10-09 16:33:15 -04001481
Jon Hall7993bfc2014-10-09 16:30:14 -04001482 Returns: main.TRUE if ONOS is running and main.FALSE on timeout
kelvin8ec71442015-01-15 16:57:00 -08001483 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001484 try:
Jon Hall3b489db2015-10-05 14:38:37 -07001485 self.handle.sendline( "onos-wait-for-start " + node )
1486 self.handle.expect( "onos-wait-for-start" )
kelvin8ec71442015-01-15 16:57:00 -08001487 # NOTE: this timeout is arbitrary"
Jon Hallcababf72018-02-05 12:05:19 -08001488 i = self.handle.expect( [ self.prompt, pexpect.TIMEOUT, "Password:" ], timeout )
Jon Hall7993bfc2014-10-09 16:30:14 -04001489 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001490 main.log.info( self.name + ": " + node + " is up" )
You Wangb65f2e92018-12-21 11:31:34 -08001491 # FIXME: for now we sleep 5s for CLI to become ready
1492 time.sleep( 5 )
Jon Hall7993bfc2014-10-09 16:30:14 -04001493 return main.TRUE
Jon Hallcababf72018-02-05 12:05:19 -08001494 elif i == 1 or i == 2:
kelvin8ec71442015-01-15 16:57:00 -08001495 # NOTE: since this function won't return until ONOS is ready,
Jon Hall7993bfc2014-10-09 16:30:14 -04001496 # we will kill it on timeout
Jon Hallcababf72018-02-05 12:05:19 -08001497 if i == 1:
Jon Hall3e6edb32018-08-21 16:20:30 -07001498 main.log.error( "{}: ONOS {} has not started yet".format( self.name, node ) )
Jon Hallcababf72018-02-05 12:05:19 -08001499 elif i == 2:
Jon Hall3e6edb32018-08-21 16:20:30 -07001500 main.log.error( "{}: Cannot login to ONOS CLI {}, try using onos-secure-ssh".format( self.name, node ) )
kelvin8ec71442015-01-15 16:57:00 -08001501 self.handle.send( "\x03" ) # Control-C
Devin Limc20e79a2017-06-07 10:29:57 -07001502 self.handle.expect( self.prompt )
Jon Hall7993bfc2014-10-09 16:30:14 -04001503 return main.FALSE
1504 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001505 main.log.error( self.name + ": EOF exception found" )
1506 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001507 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001508 except Exception:
1509 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001510 main.cleanAndExit()
andrewonlab05e362f2014-10-10 00:40:57 -04001511
Devin Lim142b5342017-07-20 15:22:39 -07001512 def preventAutoRespawn( self ):
1513 """
1514 Description:
1515 This will prevent ONOSservice to automatically
1516 respawn.
1517 """
1518 try:
1519 self.handle.sendline( "sed -i -e 's/^respawn$/#respawn/g' tools/package/init/onos.conf" )
1520 self.handle.expect( "\$" ) # $ from the command
1521 self.handle.sendline( "sed -i -e 's/^Restart=always/Restart=no/g' tools/package/init/onos.service" )
1522 self.handle.expect( "\$" ) # $ from the command
1523 self.handle.expect( "\$" ) # $ from the prompt
1524 except pexpect.EOF:
1525 main.log.error( self.name + ": EOF exception found" )
1526 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001527 main.cleanAndExit()
Devin Lim142b5342017-07-20 15:22:39 -07001528 except Exception:
1529 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001530 main.cleanAndExit()
Devin Lim142b5342017-07-20 15:22:39 -07001531
kelvin-onlabd3b64892015-01-20 13:26:24 -08001532 def pushTestIntentsShell(
1533 self,
1534 dpidSrc,
1535 dpidDst,
1536 numIntents,
1537 dirFile,
1538 onosIp,
1539 numMult="",
1540 appId="",
1541 report=True,
1542 options="" ):
kelvin8ec71442015-01-15 16:57:00 -08001543 """
andrewonlabb66dfa12014-12-02 15:51:10 -05001544 Description:
kelvin8ec71442015-01-15 16:57:00 -08001545 Use the linux prompt to push test intents to
andrewonlabb66dfa12014-12-02 15:51:10 -05001546 better parallelize the results than the CLI
1547 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001548 * dpidSrc: specify source dpid
1549 * dpidDst: specify destination dpid
1550 * numIntents: specify number of intents to push
1551 * dirFile: specify directory and file name to save
andrewonlabb66dfa12014-12-02 15:51:10 -05001552 results
kelvin-onlabd3b64892015-01-20 13:26:24 -08001553 * onosIp: specify the IP of ONOS to install on
kelvin8ec71442015-01-15 16:57:00 -08001554 NOTE:
andrewonlabb66dfa12014-12-02 15:51:10 -05001555 You must invoke this command at linux shell prompt
kelvin8ec71442015-01-15 16:57:00 -08001556 """
1557 try:
1558 # Create the string to sendline
andrewonlabaedc8332014-12-04 12:43:03 -05001559 if options:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001560 baseCmd = "onos " + str( onosIp ) + " push-test-intents " +\
kelvin8ec71442015-01-15 16:57:00 -08001561 options + " "
andrewonlabaedc8332014-12-04 12:43:03 -05001562 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001563 baseCmd = "onos " + str( onosIp ) + " push-test-intents "
kelvin8ec71442015-01-15 16:57:00 -08001564
kelvin-onlabd3b64892015-01-20 13:26:24 -08001565 addDpid = baseCmd + str( dpidSrc ) + " " + str( dpidDst )
1566 if not numMult:
1567 addIntents = addDpid + " " + str( numIntents )
1568 elif numMult:
1569 addIntents = addDpid + " " + str( numIntents ) + " " +\
1570 str( numMult )
1571 if appId:
1572 addApp = addIntents + " " + str( appId )
andrewonlabb66dfa12014-12-02 15:51:10 -05001573 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001574 addApp = addIntents
andrewonlabb66dfa12014-12-02 15:51:10 -05001575
andrewonlabaedc8332014-12-04 12:43:03 -05001576 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001577 sendCmd = addApp + " > " + str( dirFile ) + " &"
andrewonlabaedc8332014-12-04 12:43:03 -05001578 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001579 sendCmd = addApp + " &"
Jon Hall3c0114c2020-08-11 15:07:42 -07001580 main.log.info( self.name + ": Send cmd: " + sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001581
kelvin-onlabd3b64892015-01-20 13:26:24 -08001582 self.handle.sendline( sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001583
1584 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001585 main.log.error( self.name + ": EOF exception found" )
1586 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001587 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001588 except Exception:
1589 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001590 main.cleanAndExit()
andrewonlab05e362f2014-10-10 00:40:57 -04001591
kelvin-onlabd3b64892015-01-20 13:26:24 -08001592 def tsharkPcap( self, interface, dirFile ):
kelvin8ec71442015-01-15 16:57:00 -08001593 """
andrewonlab970399c2014-11-07 13:09:32 -05001594 Capture all packet activity and store in specified
1595 directory/file
1596
1597 Required:
1598 * interface: interface to capture
1599 * dir: directory/filename to store pcap
kelvin8ec71442015-01-15 16:57:00 -08001600 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001601 try:
1602 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001603 self.handle.expect( self.prompt )
andrewonlab970399c2014-11-07 13:09:32 -05001604
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001605 self.handle.sendline( "tshark -i " + str( interface ) + " -t e -w " + str( dirFile ) + " &" )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001606 self.handle.sendline( "\n" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001607 self.handle.expect( "Capturing on" )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001608 self.handle.sendline( "\n" )
Devin Limc20e79a2017-06-07 10:29:57 -07001609 self.handle.expect( self.prompt )
andrewonlab970399c2014-11-07 13:09:32 -05001610
Jon Hall3c0114c2020-08-11 15:07:42 -07001611 main.log.info( self.name + ": Tshark started capturing files on " +
Jon Hallfebb1c72015-03-05 13:30:09 -08001612 str( interface ) + " and saving to directory: " +
1613 str( dirFile ) )
1614 except pexpect.EOF:
1615 main.log.error( self.name + ": EOF exception found" )
1616 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001617 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001618 except Exception:
1619 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001620 main.cleanAndExit()
Shreya Shaha73aaad2014-10-27 18:03:09 -04001621
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001622 def onosTopoCfg( self, onosIp, jsonFile ):
kelvin8ec71442015-01-15 16:57:00 -08001623 """
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001624 Description:
1625 Execute onos-topo-cfg command
1626 Required:
1627 onosIp - IP of the onos node you want to send the json to
1628 jsonFile - File path of the json file
1629 Return:
1630 Returns main.TRUE if the command is successfull; Returns
1631 main.FALSE if there was an error
kelvin8ec71442015-01-15 16:57:00 -08001632 """
shahshreyae6c7cf42014-11-26 16:39:01 -08001633 try:
kelvin8ec71442015-01-15 16:57:00 -08001634 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001635 self.handle.expect( self.prompt )
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001636 cmd = "onos-topo-cfg "
1637 self.handle.sendline( cmd + str( onosIp ) + " " + jsonFile )
1638 handle = self.handle.before
1639 print handle
1640 if "Error" in handle:
1641 main.log.error( self.name + ": " + self.handle.before )
1642 return main.FALSE
1643 else:
Devin Limc20e79a2017-06-07 10:29:57 -07001644 self.handle.expect( self.prompt )
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001645 return main.TRUE
1646
Jon Hallfebb1c72015-03-05 13:30:09 -08001647 except pexpect.EOF:
1648 main.log.error( self.name + ": EOF exception found" )
1649 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001650 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001651 except Exception:
1652 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001653 main.cleanAndExit()
kelvin8ec71442015-01-15 16:57:00 -08001654
jenkins1e99e7b2015-04-02 18:15:39 -07001655 def tsharkGrep( self, grep, directory, interface='eth0', grepOptions='' ):
kelvin8ec71442015-01-15 16:57:00 -08001656 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001657 Required:
kelvin8ec71442015-01-15 16:57:00 -08001658 * grep string
andrewonlabba44bcf2014-10-16 16:54:41 -04001659 * directory to store results
1660 Optional:
1661 * interface - default: eth0
Jon Hall4ba53f02015-07-29 13:07:41 -07001662 * grepOptions - options for grep
andrewonlabba44bcf2014-10-16 16:54:41 -04001663 Description:
1664 Uses tshark command to grep specific group of packets
1665 and stores the results to specified directory.
kelvin8ec71442015-01-15 16:57:00 -08001666 The timestamp is hardcoded to be in epoch
1667 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001668 try:
1669 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001670 self.handle.expect( self.prompt )
Jon Hallfebb1c72015-03-05 13:30:09 -08001671 self.handle.sendline( "" )
jenkins1e99e7b2015-04-02 18:15:39 -07001672 if grepOptions:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001673 grepStr = "grep " + str( grepOptions )
jenkins1e99e7b2015-04-02 18:15:39 -07001674 else:
1675 grepStr = "grep"
Jon Hall4ba53f02015-07-29 13:07:41 -07001676
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001677 cmd = (
1678 "sudo tshark -i " +
Jon Hallfebb1c72015-03-05 13:30:09 -08001679 str( interface ) +
jenkins1e99e7b2015-04-02 18:15:39 -07001680 " -t e | " +
1681 grepStr + " --line-buffered \"" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001682 str( grep ) +
Jon Hallfebb1c72015-03-05 13:30:09 -08001683 "\" >" +
1684 directory +
1685 " &" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001686 self.handle.sendline( cmd )
1687 main.log.info( cmd )
Jon Hallfebb1c72015-03-05 13:30:09 -08001688 self.handle.expect( "Capturing on" )
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001689 self.handle.sendline( "\n" )
Devin Limc20e79a2017-06-07 10:29:57 -07001690 self.handle.expect( self.prompt )
Jon Hallfebb1c72015-03-05 13:30:09 -08001691 except pexpect.EOF:
1692 main.log.error( self.name + ": EOF exception found" )
1693 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001694 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001695 except Exception:
1696 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001697 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001698
kelvin-onlabd3b64892015-01-20 13:26:24 -08001699 def tsharkStop( self ):
kelvin8ec71442015-01-15 16:57:00 -08001700 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001701 Removes wireshark files from /tmp and kills all tshark processes
kelvin8ec71442015-01-15 16:57:00 -08001702 """
1703 # Remove all pcap from previous captures
Jon Hallfebb1c72015-03-05 13:30:09 -08001704 try:
1705 self.execute( cmd="sudo rm /tmp/wireshark*" )
1706 self.handle.sendline( "" )
Jon Hallefbd9792015-03-05 16:11:36 -08001707 self.handle.sendline( "sudo kill -9 `ps -ef | grep \"tshark -i\"" +
1708 " | grep -v grep | awk '{print $2}'`" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001709 self.handle.sendline( "" )
Jon Hall3c0114c2020-08-11 15:07:42 -07001710 main.log.info( self.name + ": Tshark stopped" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001711 except pexpect.EOF:
1712 main.log.error( self.name + ": EOF exception found" )
1713 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001714 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001715 except Exception:
1716 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001717 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001718
kelvin8ec71442015-01-15 16:57:00 -08001719 def ptpd( self, args ):
1720 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001721 Initiate ptp with user-specified args.
1722 Required:
1723 * args: specify string of args after command
1724 'sudo ptpd'
kelvin8ec71442015-01-15 16:57:00 -08001725 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001726 try:
kelvin8ec71442015-01-15 16:57:00 -08001727 self.handle.sendline( "sudo ptpd " + str( args ) )
1728 i = self.handle.expect( [
andrewonlab0c38a4a2014-10-28 18:35:35 -04001729 "Multiple",
1730 "Error",
Devin Limc20e79a2017-06-07 10:29:57 -07001731 self.prompt ] )
1732 self.handle.expect( self.prompt )
andrewonlabba44bcf2014-10-16 16:54:41 -04001733
andrewonlab0c38a4a2014-10-28 18:35:35 -04001734 if i == 0:
1735 handle = self.handle.before
Jon Hall3c0114c2020-08-11 15:07:42 -07001736 main.log.info( self.name + ": ptpd returned an error: " +
kelvin8ec71442015-01-15 16:57:00 -08001737 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001738 return handle
1739 elif i == 1:
1740 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001741 main.log.error( "ptpd returned an error: " +
1742 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001743 return handle
1744 else:
1745 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -08001746
andrewonlab0c38a4a2014-10-28 18:35:35 -04001747 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001748 main.log.error( self.name + ": EOF exception found" )
1749 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001750 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001751 except Exception:
1752 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001753 main.cleanAndExit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001754
You Wang54b1d672018-06-11 16:44:13 -07001755 def dumpONOSCmd( self, ONOSIp, CMD, destDir, filename, options="", timeout=60 ):
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001756 """
Pier50f0bc62016-09-07 17:53:40 -07001757 Dump Cmd to a desired directory.
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001758 For debugging purposes, you may want to use
Pier50f0bc62016-09-07 17:53:40 -07001759 this function to capture Cmd at a given point in time.
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001760 Localtime will be attached to the filename
1761
1762 Required:
1763 * ONOSIp: the IP of the target ONOS instance
Pier50f0bc62016-09-07 17:53:40 -07001764 * CMD: the command to dump;
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001765 * destDir: specify directory to copy to.
1766 ex ) /tmp/
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001767 * fileName: Name of the file
You Wang54b1d672018-06-11 16:44:13 -07001768 Optional:
Pier50f0bc62016-09-07 17:53:40 -07001769 * options: Options for ONOS command
You Wang54b1d672018-06-11 16:44:13 -07001770 * timeout: pexpect timeout for running the ONOS command
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001771 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001772
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001773 localtime = time.strftime( '%x %X' )
1774 localtime = localtime.replace( "/", "" )
1775 localtime = localtime.replace( " ", "_" )
1776 localtime = localtime.replace( ":", "" )
1777 if destDir[ -1: ] != "/":
1778 destDir += "/"
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001779 cmd = CMD + " " + options + " > " + str( destDir ) + str( filename ) + localtime
You Wang54b1d672018-06-11 16:44:13 -07001780 return self.onosCli( ONOSIp, cmd, timeout=timeout )
Flavio Castrob7718952016-05-18 08:53:41 -07001781
kelvin-onlabd3b64892015-01-20 13:26:24 -08001782 def cpLogsToDir( self, logToCopy,
Jon Hallefbd9792015-03-05 16:11:36 -08001783 destDir, copyFileName="" ):
kelvin8ec71442015-01-15 16:57:00 -08001784 """
1785 Copies logs to a desired directory.
andrewonlab5d7a8f32014-11-10 13:07:56 -05001786 Current implementation of ONOS deletes its karaf
1787 logs on every iteration. For debugging purposes,
kelvin8ec71442015-01-15 16:57:00 -08001788 you may want to use this function to capture
1789 certain karaf logs. ( or any other logs if needed )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001790 Localtime will be attached to the filename
1791
1792 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001793 * logToCopy: specify directory and log name to
andrewonlab5d7a8f32014-11-10 13:07:56 -05001794 copy.
kelvin8ec71442015-01-15 16:57:00 -08001795 ex ) /opt/onos/log/karaf.log.1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001796 For copying multiple files, leave copyFileName
1797 empty and only specify destDir -
kelvin8ec71442015-01-15 16:57:00 -08001798 ex ) /opt/onos/log/karaf*
kelvin-onlabd3b64892015-01-20 13:26:24 -08001799 * destDir: specify directory to copy to.
kelvin8ec71442015-01-15 16:57:00 -08001800 ex ) /tmp/
1801 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001802 * copyFileName: If you want to rename the log
1803 file, specify copyFileName. This will not work
andrewonlab5d7a8f32014-11-10 13:07:56 -05001804 with multiple file copying
kelvin8ec71442015-01-15 16:57:00 -08001805 """
andrewonlab5d7a8f32014-11-10 13:07:56 -05001806 try:
Flavio Castro09ab59d2016-05-25 17:01:35 -07001807 localtime = time.strftime( '%H %M' )
kelvin8ec71442015-01-15 16:57:00 -08001808 localtime = localtime.replace( "/", "" )
1809 localtime = localtime.replace( " ", "_" )
1810 localtime = localtime.replace( ":", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001811 if destDir[ -1: ] != "/":
1812 destDir += "/"
andrewonlab5d7a8f32014-11-10 13:07:56 -05001813
kelvin-onlabd3b64892015-01-20 13:26:24 -08001814 if copyFileName:
Jon Hallfebb1c72015-03-05 13:30:09 -08001815 self.handle.sendline( "cp " + str( logToCopy ) + " " +
1816 str( destDir ) + str( copyFileName ) +
1817 localtime )
kelvin8ec71442015-01-15 16:57:00 -08001818 self.handle.expect( "cp" )
Devin Limc20e79a2017-06-07 10:29:57 -07001819 self.handle.expect( self.prompt )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001820 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001821 self.handle.sendline( "cp " + str( logToCopy ) +
1822 " " + str( destDir ) )
kelvin8ec71442015-01-15 16:57:00 -08001823 self.handle.expect( "cp" )
Devin Limc20e79a2017-06-07 10:29:57 -07001824 self.handle.expect( self.prompt )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001825
kelvin8ec71442015-01-15 16:57:00 -08001826 return self.handle.before
1827
1828 except pexpect.EOF:
1829 main.log.error( "Copying files failed" )
1830 main.log.error( self.name + ": EOF exception found" )
1831 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001832 except Exception:
1833 main.log.exception( "Copying files failed" )
1834
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001835 def checkLogs( self, onosIp, restart=False ):
kelvin8ec71442015-01-15 16:57:00 -08001836 """
Jon Hall94fd0472014-12-08 11:52:42 -08001837 runs onos-check-logs on the given onos node
Jon Hall80daded2015-05-27 16:07:00 -07001838 If restart is True, use the old version of onos-check-logs which
1839 does not print the full stacktrace, but shows the entire log file,
1840 including across restarts
Jon Hall94fd0472014-12-08 11:52:42 -08001841 returns the response
kelvin8ec71442015-01-15 16:57:00 -08001842 """
Jon Hall94fd0472014-12-08 11:52:42 -08001843 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001844 cmd = "onos-check-logs " + str( onosIp )
Jon Hall16b72c42015-05-20 10:23:36 -07001845 if restart:
1846 cmd += " old"
kelvin8ec71442015-01-15 16:57:00 -08001847 self.handle.sendline( cmd )
1848 self.handle.expect( cmd )
Devin Limdc78e202017-06-09 18:30:07 -07001849 self.handle.expect( self.prompt + " " )
Jon Hall94fd0472014-12-08 11:52:42 -08001850 response = self.handle.before
1851 return response
1852 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001853 main.log.error( "Lost ssh connection" )
1854 main.log.error( self.name + ": EOF exception found" )
1855 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001856 except Exception:
1857 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001858 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001859
kelvin-onlabd3b64892015-01-20 13:26:24 -08001860 def onosStatus( self, node="" ):
kelvin8ec71442015-01-15 16:57:00 -08001861 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001862 Calls onos command: 'onos-service [<node-ip>] status'
kelvin8ec71442015-01-15 16:57:00 -08001863 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001864 try:
kelvin8ec71442015-01-15 16:57:00 -08001865 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001866 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -08001867 self.handle.sendline( "onos-service " + str( node ) +
1868 " status" )
1869 i = self.handle.expect( [
You Wangef1e6572016-03-08 12:53:18 -08001870 "start/running",
You Wang7bd83062016-03-01 11:50:00 -08001871 "Running ...",
You Wangef1e6572016-03-08 12:53:18 -08001872 "stop/waiting",
You Wang7bd83062016-03-01 11:50:00 -08001873 "Not Running ...",
kelvin8ec71442015-01-15 16:57:00 -08001874 pexpect.TIMEOUT ], timeout=120 )
YPZhangfebf7302016-05-24 16:45:56 -07001875 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001876 self.handle.expect( self.prompt )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001877
You Wangef1e6572016-03-08 12:53:18 -08001878 if i == 0 or i == 1:
Jon Hall3c0114c2020-08-11 15:07:42 -07001879 main.log.info( self.name + ": ONOS is running" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001880 return main.TRUE
You Wangef1e6572016-03-08 12:53:18 -08001881 elif i == 2 or i == 3:
Jon Hall3c0114c2020-08-11 15:07:42 -07001882 main.log.info( self.name + ": ONOS is stopped" )
kelvin8ec71442015-01-15 16:57:00 -08001883 main.log.error( "ONOS service failed to check the status" )
Devin Lim44075962017-08-11 10:56:37 -07001884
1885 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001886 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001887 main.log.error( self.name + ": EOF exception found" )
1888 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001889 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001890 except Exception:
1891 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001892 main.cleanAndExit()
Jon Hall21270ac2015-02-16 17:59:55 -08001893
Jon Hall63604932015-02-26 17:09:50 -08001894 def setIpTables( self, ip, port='', action='add', packet_type='',
1895 direction='INPUT', rule='DROP', states=True ):
Jon Hallefbd9792015-03-05 16:11:36 -08001896 """
Jon Hall21270ac2015-02-16 17:59:55 -08001897 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001898 add or remove iptables rule to DROP (default) packets from
Jon Hall21270ac2015-02-16 17:59:55 -08001899 specific IP and PORT
1900 Usage:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001901 * specify action ('add' or 'remove')
Jon Hall21270ac2015-02-16 17:59:55 -08001902 when removing, pass in the same argument as you would add. It will
1903 delete that specific rule.
1904 * specify the ip to block
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001905 * specify the destination port to block (defaults to all ports)
1906 * optional packet type to block (default tcp)
1907 * optional iptables rule (default DROP)
1908 * optional direction to block (default 'INPUT')
Jon Hall63604932015-02-26 17:09:50 -08001909 * States boolean toggles adding all supported tcp states to the
1910 firewall rule
Jon Hall21270ac2015-02-16 17:59:55 -08001911 Returns:
1912 main.TRUE on success or
1913 main.FALSE if given invalid input or
1914 main.ERROR if there is an error in response from iptables
1915 WARNING:
1916 * This function uses root privilege iptables command which may result
1917 in unwanted network errors. USE WITH CAUTION
Jon Hallefbd9792015-03-05 16:11:36 -08001918 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001919
Jon Hall21270ac2015-02-16 17:59:55 -08001920 # NOTE*********
1921 # The strict checking methods of this driver function is intentional
1922 # to discourage any misuse or error of iptables, which can cause
1923 # severe network errors
1924 # *************
1925
1926 # NOTE: Sleep needed to give some time for rule to be added and
1927 # registered to the instance. If you are calling this function
1928 # multiple times this sleep will prevent any errors.
1929 # DO NOT REMOVE
Jon Hall63604932015-02-26 17:09:50 -08001930 # time.sleep( 5 )
Jon Hall21270ac2015-02-16 17:59:55 -08001931 try:
1932 # input validation
1933 action_type = action.lower()
1934 rule = rule.upper()
1935 direction = direction.upper()
1936 if action_type != 'add' and action_type != 'remove':
1937 main.log.error( "Invalid action type. Use 'add' or "
1938 "'remove' table rule" )
1939 if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
1940 # NOTE Currently only supports rules DROP, ACCEPT, and LOG
1941 main.log.error( "Invalid rule. Valid rules are 'DROP' or "
1942 "'ACCEPT' or 'LOG' only." )
1943 if direction != 'INPUT' and direction != 'OUTPUT':
1944 # NOTE currently only supports rules INPUT and OUPTUT
1945 main.log.error( "Invalid rule. Valid directions are"
1946 " 'OUTPUT' or 'INPUT'" )
1947 return main.FALSE
1948 return main.FALSE
1949 return main.FALSE
1950 if action_type == 'add':
1951 # -A is the 'append' action of iptables
1952 actionFlag = '-A'
1953 elif action_type == 'remove':
1954 # -D is the 'delete' rule of iptables
1955 actionFlag = '-D'
1956 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001957 self.handle.expect( self.prompt )
Jon Hall21270ac2015-02-16 17:59:55 -08001958 cmd = "sudo iptables " + actionFlag + " " +\
1959 direction +\
Jon Hall21270ac2015-02-16 17:59:55 -08001960 " -s " + str( ip )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001961 # " -p " + str( packet_type ) +\
Jon Hall63604932015-02-26 17:09:50 -08001962 if packet_type:
1963 cmd += " -p " + str( packet_type )
Jon Hall21270ac2015-02-16 17:59:55 -08001964 if port:
1965 cmd += " --dport " + str( port )
Jon Hall63604932015-02-26 17:09:50 -08001966 if states:
1967 cmd += " -m state --state="
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001968 # FIXME- Allow user to configure which states to block
Jon Hall63604932015-02-26 17:09:50 -08001969 cmd += "INVALID,ESTABLISHED,NEW,RELATED,UNTRACKED"
Jon Hall21270ac2015-02-16 17:59:55 -08001970 cmd += " -j " + str( rule )
1971
1972 self.handle.sendline( cmd )
Devin Limc20e79a2017-06-07 10:29:57 -07001973 self.handle.expect( self.prompt )
Jon Hall21270ac2015-02-16 17:59:55 -08001974 main.log.warn( self.handle.before )
1975
1976 info_string = "On " + str( self.name )
1977 info_string += " " + str( action_type )
1978 info_string += " iptable rule [ "
1979 info_string += " IP: " + str( ip )
1980 info_string += " Port: " + str( port )
1981 info_string += " Rule: " + str( rule )
1982 info_string += " Direction: " + str( direction ) + " ]"
1983 main.log.info( info_string )
1984 return main.TRUE
1985 except pexpect.TIMEOUT:
1986 main.log.exception( self.name + ": Timeout exception in "
1987 "setIpTables function" )
You Wang141b43b2018-06-26 16:50:18 -07001988 self.handle.send( "\x03" ) # Control-C
1989 self.handle.expect( self.prompt )
Jon Hall21270ac2015-02-16 17:59:55 -08001990 return main.ERROR
1991 except pexpect.EOF:
1992 main.log.error( self.name + ": EOF exception found" )
1993 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001994 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001995 except Exception:
1996 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001997 main.cleanAndExit()
Jon Hall21270ac2015-02-16 17:59:55 -08001998
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001999 def detailed_status( self, log_filename ):
Jon Hallefbd9792015-03-05 16:11:36 -08002000 """
Jon Hall0468b042015-02-19 19:08:21 -08002001 This method is used by STS to check the status of the controller
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002002 Reports RUNNING, STARTING, STOPPED, FROZEN, ERROR (and reason)
Jon Hallefbd9792015-03-05 16:11:36 -08002003 """
Jon Hall0468b042015-02-19 19:08:21 -08002004 import re
2005 try:
2006 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07002007 self.handle.expect( self.prompt )
Jon Hall0468b042015-02-19 19:08:21 -08002008 self.handle.sendline( "cd " + self.home )
Devin Limc20e79a2017-06-07 10:29:57 -07002009 self.handle.expect( self.prompt )
Jon Hall0468b042015-02-19 19:08:21 -08002010 self.handle.sendline( "service onos status" )
Devin Limc20e79a2017-06-07 10:29:57 -07002011 self.handle.expect( self.prompt )
Jon Hall0468b042015-02-19 19:08:21 -08002012 response = self.handle.before
2013 if re.search( "onos start/running", response ):
2014 # onos start/running, process 10457
2015 return 'RUNNING'
2016 # FIXME: Implement this case
2017 # elif re.search( pattern, response ):
2018 # return 'STARTING'
2019 elif re.search( "onos stop/", response ):
2020 # onos stop/waiting
2021 # FIXME handle this differently?: onos stop/pre-stop
2022 return 'STOPPED'
2023 # FIXME: Implement this case
2024 # elif re.search( pattern, response ):
2025 # return 'FROZEN'
2026 else:
2027 main.log.warn( self.name +
Jon Hallefbd9792015-03-05 16:11:36 -08002028 " WARNING: status received unknown response" )
Jon Hall0468b042015-02-19 19:08:21 -08002029 main.log.warn( response )
2030 return 'ERROR', "Unknown response: %s" % response
2031 except pexpect.TIMEOUT:
2032 main.log.exception( self.name + ": Timeout exception in "
2033 "setIpTables function" )
You Wang141b43b2018-06-26 16:50:18 -07002034 self.handle.send( "\x03" ) # Control-C
2035 self.handle.expect( self.prompt )
Jon Hall0468b042015-02-19 19:08:21 -08002036 return 'ERROR', "Pexpect Timeout"
2037 except pexpect.EOF:
2038 main.log.error( self.name + ": EOF exception found" )
2039 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002040 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002041 except Exception:
2042 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002043 main.cleanAndExit()
Jon Hall0468b042015-02-19 19:08:21 -08002044
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002045 def createLinkGraphFile( self, benchIp, ONOSIpList, deviceCount ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002046 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07002047 Create/formats the LinkGraph.cfg file based on arguments
2048 -only creates a linear topology and connects islands
2049 -evenly distributes devices
andrew@onlab.us3b087132015-03-11 15:00:08 -07002050 -must be called by ONOSbench
2051
Jon Hall4ba53f02015-07-29 13:07:41 -07002052 ONOSIpList - list of all of the node IPs to be used
2053
2054 deviceCount - number of switches to be assigned
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002055 '''
Jon Hall3c0114c2020-08-11 15:07:42 -07002056 main.log.info( self.name + ": Creating link graph configuration file." )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002057 linkGraphPath = self.home + "/tools/package/etc/linkGraph.cfg"
Jon Hall4ba53f02015-07-29 13:07:41 -07002058 tempFile = "/tmp/linkGraph.cfg"
andrew@onlab.us3b087132015-03-11 15:00:08 -07002059
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002060 linkGraph = open( tempFile, 'w+' )
2061 linkGraph.write( "# NullLinkProvider topology description (config file).\n" )
2062 linkGraph.write( "# The NodeId is only added if the destination is another node's device.\n" )
2063 linkGraph.write( "# Bugs: Comments cannot be appended to a line to be read.\n" )
Jon Hall4ba53f02015-07-29 13:07:41 -07002064
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002065 clusterCount = len( ONOSIpList )
Jon Hall4ba53f02015-07-29 13:07:41 -07002066
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002067 if isinstance( deviceCount, int ) or isinstance( deviceCount, str ):
2068 deviceCount = int( deviceCount )
2069 switchList = [ 0 ]*( clusterCount+1 )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002070 baselineSwitchCount = deviceCount/clusterCount
Jon Hall4ba53f02015-07-29 13:07:41 -07002071
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002072 for node in range( 1, clusterCount + 1 ):
2073 switchList[ node ] = baselineSwitchCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07002074
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002075 for node in range( 1, ( deviceCount % clusterCount )+1 ):
2076 switchList[ node ] += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07002077
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002078 if isinstance( deviceCount, list ):
Jon Hall3c0114c2020-08-11 15:07:42 -07002079 main.log.info( self.name + ": Using provided device distribution" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002080 switchList = [ 0 ]
andrew@onlab.us3b087132015-03-11 15:00:08 -07002081 for i in deviceCount:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002082 switchList.append( int( i ) )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002083
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002084 tempList = [ '0' ]
2085 tempList.extend( ONOSIpList )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002086 ONOSIpList = tempList
2087
2088 myPort = 6
2089 lastSwitch = 0
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002090 for node in range( 1, clusterCount+1 ):
2091 if switchList[ node ] == 0:
andrew@onlab.us3b087132015-03-11 15:00:08 -07002092 continue
2093
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002094 linkGraph.write( "graph " + ONOSIpList[ node ] + " {\n" )
Jon Hall4ba53f02015-07-29 13:07:41 -07002095
andrew@onlab.us3b087132015-03-11 15:00:08 -07002096 if node > 1:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002097 # connect to last device on previous node
2098 line = ( "\t0:5 -> " + str( lastSwitch ) + ":6:" + lastIp + "\n" ) # ONOSIpList[node-1]
2099 linkGraph.write( line )
Jon Hall4ba53f02015-07-29 13:07:41 -07002100
2101 lastSwitch = 0
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002102 for switch in range( 0, switchList[ node ]-1 ):
andrew@onlab.us3b087132015-03-11 15:00:08 -07002103 line = ""
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002104 line = ( "\t" + str( switch ) + ":" + str( myPort ) )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002105 line += " -- "
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002106 line += ( str( switch+1 ) + ":" + str( myPort-1 ) + "\n" )
2107 linkGraph.write( line )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002108 lastSwitch = switch+1
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002109 lastIp = ONOSIpList[ node ]
Jon Hall4ba53f02015-07-29 13:07:41 -07002110
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002111 # lastSwitch += 1
2112 if node < ( clusterCount ):
2113 # connect to first device on the next node
2114 line = ( "\t" + str( lastSwitch ) + ":6 -> 0:5:" + ONOSIpList[ node+1 ] + "\n" )
2115 linkGraph.write( line )
Jon Hall4ba53f02015-07-29 13:07:41 -07002116
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002117 linkGraph.write( "}\n" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002118 linkGraph.close()
2119
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002120 # SCP
2121 os.system( "scp " + tempFile + " " + self.user_name + "@" + benchIp + ":" + linkGraphPath )
Jon Hall3c0114c2020-08-11 15:07:42 -07002122 main.log.info( self.name + ": linkGraph.cfg creation complete" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002123
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002124 def configNullDev( self, ONOSIpList, deviceCount, numPorts=10 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002125 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07002126 ONOSIpList = list of Ip addresses of nodes switches will be devided amongst
2127 deviceCount = number of switches to distribute, or list of values to use as custom distribution
cameron@onlab.us75900962015-03-30 13:22:49 -07002128 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 +00002129 '''
2130
Jon Hall3c0114c2020-08-11 15:07:42 -07002131 main.log.info( self.name + ": Configuring Null Device Provider" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002132 clusterCount = len( ONOSIpList )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002133
Jon Hall4ba53f02015-07-29 13:07:41 -07002134 try:
2135
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002136 if isinstance( deviceCount, int ) or isinstance( deviceCount, str ):
Jon Hall3c0114c2020-08-11 15:07:42 -07002137 main.log.info( self.name + ": Creating device distribution" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002138 deviceCount = int( deviceCount )
2139 switchList = [ 0 ]*( clusterCount+1 )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002140 baselineSwitchCount = deviceCount/clusterCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07002141
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002142 for node in range( 1, clusterCount + 1 ):
2143 switchList[ node ] = baselineSwitchCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07002144
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002145 for node in range( 1, ( deviceCount % clusterCount )+1 ):
2146 switchList[ node ] += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07002147
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002148 if isinstance( deviceCount, list ):
Jon Hall3c0114c2020-08-11 15:07:42 -07002149 main.log.info( self.name + ": Using provided device distribution" )
Jon Hall4ba53f02015-07-29 13:07:41 -07002150
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002151 if len( deviceCount ) == clusterCount:
2152 switchList = [ '0' ]
2153 switchList.extend( deviceCount )
Jon Hall4ba53f02015-07-29 13:07:41 -07002154
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002155 if len( deviceCount ) == ( clusterCount + 1 ):
2156 if deviceCount[ 0 ] == '0' or deviceCount[ 0 ] == 0:
cameron@onlab.us75900962015-03-30 13:22:49 -07002157 switchList = deviceCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07002158
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002159 assert len( switchList ) == ( clusterCount + 1 )
Jon Hall4ba53f02015-07-29 13:07:41 -07002160
cameron@onlab.us75900962015-03-30 13:22:49 -07002161 except AssertionError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002162 main.log.error( "Bad device/Ip list match" )
cameron@onlab.us75900962015-03-30 13:22:49 -07002163 except TypeError:
2164 main.log.exception( self.name + ": Object not as expected" )
2165 return None
Jon Hall77ba41c2015-04-06 10:25:40 -07002166 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002167 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002168 main.cleanAndExit()
cameron@onlab.us75900962015-03-30 13:22:49 -07002169
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002170 ONOSIp = [ 0 ]
2171 ONOSIp.extend( ONOSIpList )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002172
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002173 devicesString = "devConfigs = "
2174 for node in range( 1, len( ONOSIp ) ):
2175 devicesString += ( ONOSIp[ node ] + ":" + str( switchList[ node ] ) )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002176 if node < clusterCount:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002177 devicesString += ( "," )
Jon Hall4ba53f02015-07-29 13:07:41 -07002178
2179 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002180 self.handle.sendline( "onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider devConfigs " + devicesString )
2181 self.handle.expect( ":~" )
2182 self.handle.sendline( "onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider numPorts " + str( numPorts ) )
2183 self.handle.expect( ":~" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002184
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002185 for i in range( 10 ):
2186 self.handle.sendline( "onos $OC1 cfg get org.onosproject.provider.nil.device.impl.NullDeviceProvider" )
2187 self.handle.expect( ":~" )
cameron@onlab.us75900962015-03-30 13:22:49 -07002188 verification = self.handle.before
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002189 if ( " value=" + str( numPorts ) ) in verification and ( " value=" + devicesString ) in verification:
cameron@onlab.us75900962015-03-30 13:22:49 -07002190 break
2191 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002192 time.sleep( 1 )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002193
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002194 assert ( "value=" + str( numPorts ) ) in verification and ( " value=" + devicesString ) in verification
Jon Hall4ba53f02015-07-29 13:07:41 -07002195
cameron@onlab.us75900962015-03-30 13:22:49 -07002196 except AssertionError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002197 main.log.error( "Incorrect Config settings: " + verification )
Jon Hall77ba41c2015-04-06 10:25:40 -07002198 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002199 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002200 main.cleanAndExit()
cameron@onlab.us75900962015-03-30 13:22:49 -07002201
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002202 def configNullLink( self, fileName="/opt/onos/apache-karaf-3.0.3/etc/linkGraph.cfg", eventRate=0 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002203 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07002204 fileName default is currently the same as the default on ONOS, specify alternate file if
cameron@onlab.us75900962015-03-30 13:22:49 -07002205 you want to use a different topology file than linkGraph.cfg
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002206 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07002207
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002208 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002209 self.handle.sendline( "onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider eventRate " + str( eventRate ) )
2210 self.handle.expect( ":~" )
2211 self.handle.sendline( "onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider cfgFile " + fileName )
2212 self.handle.expect( ":~" )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002213
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002214 for i in range( 10 ):
2215 self.handle.sendline( "onos $OC1 cfg get org.onosproject.provider.nil.link.impl.NullLinkProvider" )
2216 self.handle.expect( ":~" )
cameron@onlab.us75900962015-03-30 13:22:49 -07002217 verification = self.handle.before
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002218 if ( " value=" + str( eventRate ) ) in verification and ( " value=" + fileName ) in verification:
cameron@onlab.us75900962015-03-30 13:22:49 -07002219 break
Jon Hall4ba53f02015-07-29 13:07:41 -07002220 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002221 time.sleep( 1 )
Jon Hall4ba53f02015-07-29 13:07:41 -07002222
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002223 assert ( "value=" + str( eventRate ) ) in verification and ( " value=" + fileName ) in verification
Jon Hall4ba53f02015-07-29 13:07:41 -07002224
cameron@onlab.us75900962015-03-30 13:22:49 -07002225 except pexpect.EOF:
2226 main.log.error( self.name + ": EOF exception found" )
2227 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002228 main.cleanAndExit()
cameron@onlab.us75900962015-03-30 13:22:49 -07002229 except AssertionError:
Jon Hall3c0114c2020-08-11 15:07:42 -07002230 main.log.info( self.name + ": Settings did not post to ONOS" )
Jon Hall3e6edb32018-08-21 16:20:30 -07002231 main.log.error( verification )
Jon Hall77ba41c2015-04-06 10:25:40 -07002232 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002233 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall3e6edb32018-08-21 16:20:30 -07002234 main.log.error( verification )
Devin Lim44075962017-08-11 10:56:37 -07002235 main.cleanAndExit()
andrew@onlab.us3b087132015-03-11 15:00:08 -07002236
kelvin-onlaba4074292015-07-09 15:19:49 -07002237 def getOnosIps( self ):
2238 """
2239 Get all onos IPs stored in
2240 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002241
kelvin-onlaba4074292015-07-09 15:19:49 -07002242 return sorted( self.onosIps.values() )
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002243
Chiyu Chengec63bde2016-11-17 18:11:36 -08002244 def listLog( self, nodeIp ):
2245 """
2246 Get a list of all the karaf log names
2247 """
2248 try:
2249 cmd = "onos-ssh " + nodeIp + " ls -tr /opt/onos/log"
2250 self.handle.sendline( cmd )
2251 self.handle.expect( ":~" )
2252 before = self.handle.before.splitlines()
2253 logNames = []
2254 for word in before:
2255 if 'karaf.log' in word:
2256 logNames.append( word )
2257 return logNames
2258 except pexpect.EOF:
2259 main.log.error( self.name + ": EOF exception found" )
2260 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002261 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08002262 except pexpect.TIMEOUT:
2263 main.log.error( self.name + ": TIMEOUT exception found" )
2264 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002265 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08002266 except Exception:
2267 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002268 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08002269
Pratik Parab3b2ab5a2017-02-14 13:15:14 -08002270 def logReport( self, nodeIp, searchTerms, outputMode="s", startStr=None, endStr=None ):
Jon Hallb4242222016-01-25 17:07:04 -08002271 """
2272 Searches the latest ONOS log file for the given search terms and
2273 prints the total occurances of each term. Returns to combined total of
2274 all occurances.
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002275
Jon Hallb4242222016-01-25 17:07:04 -08002276 Arguments:
2277 * nodeIp - The ip of the ONOS node where the log is located
2278 * searchTerms - A string to grep for or a list of strings to grep
2279 for in the ONOS log. Will print out the number of
2280 occurances for each term.
2281 Optional Arguments:
2282 * outputMode - 's' or 'd'. If 'd' will print the last 5 lines
2283 containing each search term as well as the total
2284 number of occurances of each term. Defaults to 's',
2285 which prints the simple output of just the number
2286 of occurances for each term.
Pratik Parab3b2ab5a2017-02-14 13:15:14 -08002287 * startStr - the start string to be given to stream editor command
2288 as the start point for extraction of data
2289 * endStr - the end string to be given to stream editor command as
2290 the end point for extraction of data
Jon Hallb4242222016-01-25 17:07:04 -08002291 """
2292 try:
Jon Hall3c0114c2020-08-11 15:07:42 -07002293 main.log.info( self.name + ": Log Report for {} ".format( nodeIp ).center( 70, '=' ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002294 if isinstance( searchTerms, str ):
2295 searchTerms = [ searchTerms ]
Jon Hallb4242222016-01-25 17:07:04 -08002296 numTerms = len( searchTerms )
2297 outputMode = outputMode.lower()
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002298
Jon Hallb4242222016-01-25 17:07:04 -08002299 totalHits = 0
2300 logLines = []
2301 for termIndex in range( numTerms ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002302 term = searchTerms[ termIndex ]
2303 logLines.append( [ term ] )
Pratik Parab3b2ab5a2017-02-14 13:15:14 -08002304 if startStr and endStr:
2305 cmd = "onos-ssh {} \"sed -n '/{}/,/{}/p' /opt/onos/log/karaf.log | grep {}\"".format( nodeIp,
2306 startStr,
2307 endStr,
2308 term )
2309 else:
2310 cmd = "onos-ssh {} cat /opt/onos/log/karaf.log | grep {}".format( nodeIp,
2311 term )
Jon Hallb4242222016-01-25 17:07:04 -08002312 self.handle.sendline( cmd )
2313 self.handle.expect( ":~" )
2314 before = self.handle.before.splitlines()
2315 count = 0
2316 for line in before:
2317 if term in line and "grep" not in line:
2318 count += 1
2319 if before.index( line ) > ( len( before ) - 7 ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002320 logLines[ termIndex ].append( line )
Jon Hall3c0114c2020-08-11 15:07:42 -07002321 main.log.info( self.name + ": {}: {}".format( term, count ) )
Jon Hallb4242222016-01-25 17:07:04 -08002322 totalHits += count
2323 if termIndex == numTerms - 1:
2324 print "\n"
2325 if outputMode != "s":
2326 outputString = ""
2327 for term in logLines:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002328 outputString = term[ 0 ] + ": \n"
Jon Hallb4242222016-01-25 17:07:04 -08002329 for line in range( 1, len( term ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002330 outputString += ( "\t" + term[ line ] + "\n" )
2331 if outputString != ( term[ 0 ] + ": \n" ):
Jon Hallb4242222016-01-25 17:07:04 -08002332 main.log.info( outputString )
Jon Hall3c0114c2020-08-11 15:07:42 -07002333 main.log.info( self.name + ": =" * 70 )
Jon Hallb4242222016-01-25 17:07:04 -08002334 return totalHits
2335 except pexpect.EOF:
2336 main.log.error( self.name + ": EOF exception found" )
2337 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002338 main.cleanAndExit()
Jon Hallb4242222016-01-25 17:07:04 -08002339 except pexpect.TIMEOUT:
2340 main.log.error( self.name + ": TIMEOUT exception found" )
2341 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002342 main.cleanAndExit()
Jon Hallb4242222016-01-25 17:07:04 -08002343 except Exception:
2344 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002345 main.cleanAndExit()
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002346
2347 def copyMininetFile( self, fileName, localPath, userName, ip,
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002348 mnPath='~/mininet/custom/', timeout = 60 ):
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002349 """
2350 Description:
2351 Copy mininet topology file from dependency folder in the test folder
2352 and paste it to the mininet machine's mininet/custom folder
2353 Required:
2354 fileName - Name of the topology file to copy
2355 localPath - File path of the mininet topology file
2356 userName - User name of the mininet machine to send the file to
2357 ip - Ip address of the mininet machine
2358 Optional:
2359 mnPath - of the mininet directory to send the file to
2360 Return:
2361 Return main.TRUE if successfully copied the file otherwise
2362 return main.FALSE
2363 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002364
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002365 try:
2366 cmd = "scp " + localPath + fileName + " " + userName + "@" + \
2367 str( ip ) + ":" + mnPath + fileName
2368
2369 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07002370 self.handle.expect( self.prompt )
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002371
2372 main.log.info( self.name + ": Execute: " + cmd )
2373
2374 self.handle.sendline( cmd )
2375
2376 i = self.handle.expect( [ 'No such file',
2377 "100%",
2378 pexpect.TIMEOUT ] )
2379
2380 if i == 0:
2381 main.log.error( self.name + ": File " + fileName +
2382 " does not exist!" )
2383 return main.FALSE
2384
2385 if i == 1:
2386 main.log.info( self.name + ": File " + fileName +
2387 " has been copied!" )
2388 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07002389 self.handle.expect( self.prompt )
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002390 return main.TRUE
2391
2392 except pexpect.EOF:
2393 main.log.error( self.name + ": EOF exception found" )
2394 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002395 main.cleanAndExit()
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002396 except pexpect.TIMEOUT:
2397 main.log.error( self.name + ": TIMEOUT exception found" )
2398 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002399 main.cleanAndExit()
cameron@onlab.us78b89652015-07-08 15:21:03 -07002400
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002401 def jvmSet( self, memory=8 ):
Jon Hall4ba53f02015-07-29 13:07:41 -07002402
cameron@onlab.us78b89652015-07-08 15:21:03 -07002403 import os
2404
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002405 homeDir = os.path.expanduser( '~' )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002406 filename = "/onos/tools/package/bin/onos-service"
2407
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002408 serviceConfig = open( homeDir + filename, 'w+' )
2409 serviceConfig.write( "#!/bin/bash\n " )
2410 serviceConfig.write( "#------------------------------------- \n " )
2411 serviceConfig.write( "# Starts ONOS Apache Karaf container\n " )
2412 serviceConfig.write( "#------------------------------------- \n " )
2413 serviceConfig.write( "#export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-7-openjdk-amd64/}\n " )
2414 serviceConfig.write( """export JAVA_OPTS="${JAVA_OPTS:--Xms""" + str( memory ) + "G -Xmx" + str( memory ) + """G}" \n """ )
2415 serviceConfig.write( "[ -d $ONOS_HOME ] && cd $ONOS_HOME || ONOS_HOME=$(dirname $0)/..\n" )
2416 serviceConfig.write( """${ONOS_HOME}/apache-karaf-$KARAF_VERSION/bin/karaf "$@" \n """ )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002417 serviceConfig.close()
2418
Jon Hall6c44c0b2016-04-20 15:21:00 -07002419 def createDBFile( self, testData ):
Jon Hall4ba53f02015-07-29 13:07:41 -07002420
cameron@onlab.us78b89652015-07-08 15:21:03 -07002421 filename = main.TEST + "DB"
2422 DBString = ""
Jon Hall4ba53f02015-07-29 13:07:41 -07002423
cameron@onlab.us78b89652015-07-08 15:21:03 -07002424 for item in testData:
Jon Hall3e6edb32018-08-21 16:20:30 -07002425 if isinstance( item, str ):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002426 item = "'" + item + "'"
Jon Hall6c44c0b2016-04-20 15:21:00 -07002427 if testData.index( item ) < len( testData - 1 ):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002428 item += ","
Jon Hall6c44c0b2016-04-20 15:21:00 -07002429 DBString += str( item )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002430
Jon Hall6c44c0b2016-04-20 15:21:00 -07002431 DBFile = open( filename, "a" )
2432 DBFile.write( DBString )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002433 DBFile.close()
2434
Jon Hall6c44c0b2016-04-20 15:21:00 -07002435 def verifySummary( self, ONOSIp, *deviceCount ):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002436
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002437 self.handle.sendline( "onos " + ONOSIp + " summary" )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002438 self.handle.expect( ":~" )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002439
2440 summaryStr = self.handle.before
2441 print "\nSummary\n==============\n" + summaryStr + "\n\n"
2442
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002443 # passed = "SCC(s)=1" in summaryStr
2444 # if deviceCount:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002445 # passed = "devices=" + str(deviceCount) + "," not in summaryStr
cameron@onlab.us78b89652015-07-08 15:21:03 -07002446
GlennRC772363b2015-08-25 13:05:57 -07002447 passed = False
cameron@onlab.us78b89652015-07-08 15:21:03 -07002448 if "SCC(s)=1," in summaryStr:
2449 passed = True
Jon Hall6c44c0b2016-04-20 15:21:00 -07002450 print "Summary is verifed"
Jon Hall4ba53f02015-07-29 13:07:41 -07002451 else:
Jon Hall6c44c0b2016-04-20 15:21:00 -07002452 print "Summary failed"
cameron@onlab.us78b89652015-07-08 15:21:03 -07002453
2454 if deviceCount:
2455 print" ============================="
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002456 checkStr = "devices=" + str( deviceCount[ 0 ] ) + ","
cameron@onlab.us78b89652015-07-08 15:21:03 -07002457 print "Checkstr: " + checkStr
2458 if checkStr not in summaryStr:
2459 passed = False
Jon Hall6c44c0b2016-04-20 15:21:00 -07002460 print "Device count failed"
Jon Hall4ba53f02015-07-29 13:07:41 -07002461 else:
2462 print "device count verified"
cameron@onlab.us78b89652015-07-08 15:21:03 -07002463
2464 return passed
Jon Hall6c44c0b2016-04-20 15:21:00 -07002465
Jon Hall8f6d4622016-05-23 15:27:18 -07002466 def getIpAddr( self, iface=None ):
Jon Hall6c44c0b2016-04-20 15:21:00 -07002467 """
2468 Update self.ip_address with numerical ip address. If multiple IP's are
2469 located on the device, will attempt to use self.nicAddr to choose the
2470 right one. Defaults to 127.0.0.1 if no other address is found or cannot
2471 determine the correct address.
2472
2473 ONLY WORKS WITH IPV4 ADDRESSES
2474 """
2475 try:
Jon Hall8f6d4622016-05-23 15:27:18 -07002476 LOCALHOST = "127.0.0.1"
Jon Hall6c44c0b2016-04-20 15:21:00 -07002477 ipPat = "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"
2478 pattern = re.compile( ipPat )
2479 match = re.search( pattern, self.ip_address )
2480 if self.nicAddr:
2481 nicPat = self.nicAddr.replace( ".", "\." ).replace( "\*", r"\d{1,3}" )
2482 nicPat = re.compile( nicPat )
2483 else:
2484 nicPat = None
2485 # IF self.ip_address is an ip address and matches
2486 # self.nicAddr: return self.ip_address
2487 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002488 curIp = match.group( 0 )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002489 if nicPat:
2490 nicMatch = re.search( nicPat, curIp )
2491 if nicMatch:
2492 return self.ip_address
Jon Hall8f6d4622016-05-23 15:27:18 -07002493 # ELSE: IF iface, return ip of interface
2494 cmd = "ifconfig"
2495 ifPat = re.compile( "inet addr:({})".format( ipPat ) )
2496 if iface:
2497 cmd += " " + str( iface )
2498 raw = subprocess.check_output( cmd.split() )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002499 ifPat = re.compile( "inet addr:({})".format( ipPat ) )
2500 ips = re.findall( ifPat, raw )
Jon Hall8f6d4622016-05-23 15:27:18 -07002501 if iface:
2502 if ips:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002503 ip = ips[ 0 ]
Jon Hall8f6d4622016-05-23 15:27:18 -07002504 self.ip_address = ip
2505 return ip
2506 else:
2507 main.log.error( "Error finding ip, ifconfig output:".format( raw ) )
2508 # ELSE: attempt to get address matching nicPat.
Jon Hall6c44c0b2016-04-20 15:21:00 -07002509 if nicPat:
2510 for ip in ips:
2511 curMatch = re.search( nicPat, ip )
2512 if curMatch:
2513 self.ip_address = ip
2514 return ip
Jon Hall8f6d4622016-05-23 15:27:18 -07002515 else: # If only one non-localhost ip, return that
2516 tmpList = [ ip for ip in ips if ip is not LOCALHOST ]
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002517 if len( tmpList ) == 1:
2518 curIp = tmpList[ 0 ]
Jon Hall6c44c0b2016-04-20 15:21:00 -07002519 self.ip_address = curIp
2520 return curIp
Jon Hall8f6d4622016-05-23 15:27:18 -07002521 # Either no non-localhost IPs, or more than 1
Jon Hallebccd352016-05-20 15:17:17 -07002522 main.log.warn( "getIpAddr failed to find a public IP address" )
Jon Hall8f6d4622016-05-23 15:27:18 -07002523 return LOCALHOST
Jon Halle1790952016-05-23 15:51:46 -07002524 except subprocess.CalledProcessError:
Jon Hall8f6d4622016-05-23 15:27:18 -07002525 main.log.exception( "Error executing ifconfig" )
2526 except IndexError:
2527 main.log.exception( "Error getting IP Address" )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002528 except Exception:
2529 main.log.exception( "Uncaught exception" )
suibin zhang116647a2016-05-06 16:30:09 -07002530
Devin Lim461f0872017-06-05 16:49:33 -07002531 def startBasicONOS( self, nodeList, opSleep=60, onosStartupSleep=30, onosUser="sdn" ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002532 '''
suibin zhang116647a2016-05-06 16:30:09 -07002533 Start onos cluster with defined nodes, but only with drivers app
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002534 '''
suibin zhang116647a2016-05-06 16:30:09 -07002535 import time
2536
2537 self.createCellFile( self.ip_address,
Jon Hall3e6edb32018-08-21 16:20:30 -07002538 "temp",
2539 self.ip_address,
2540 "drivers",
2541 nodeList,
2542 nodeList,
2543 onosUser=onosUser )
suibin zhang116647a2016-05-06 16:30:09 -07002544
2545 main.log.info( self.name + ": Apply cell to environment" )
2546 cellResult = self.setCell( "temp" )
2547 verifyResult = self.verifyCell()
2548
2549 main.log.info( self.name + ": Creating ONOS package" )
You Wangd1bcaca2016-10-24 15:23:26 -07002550 packageResult = self.buckBuild( timeout=opSleep )
suibin zhang116647a2016-05-06 16:30:09 -07002551
You Wangc669d212017-01-25 11:09:48 -08002552 main.log.info( self.name + ": Uninstalling ONOS" )
2553 for nd in nodeList:
2554 self.onosUninstall( nodeIp=nd )
2555
suibin zhang116647a2016-05-06 16:30:09 -07002556 main.log.info( self.name + ": Installing ONOS package" )
2557 for nd in nodeList:
You Wangc669d212017-01-25 11:09:48 -08002558 self.onosInstall( node=nd )
2559
2560 main.log.info( self.name + ": Set up ONOS secure SSH" )
2561 for nd in nodeList:
2562 self.onosSecureSSH( node=nd )
suibin zhang116647a2016-05-06 16:30:09 -07002563
2564 main.log.info( self.name + ": Starting ONOS service" )
2565 time.sleep( onosStartupSleep )
2566
2567 onosStatus = True
2568 for nd in nodeList:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002569 onosStatus = onosStatus & self.isup( node = nd )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002570 # print "onosStatus is: " + str( onosStatus )
suibin zhang116647a2016-05-06 16:30:09 -07002571
2572 return main.TRUE if onosStatus else main.FALSE
2573
Jon Hall3c0114c2020-08-11 15:07:42 -07002574 def onosNetCfg( self, controllerIp, path, fileName, user=None, password=None):
Jeremy Songster5665f1b2016-06-20 14:38:22 -07002575 """
2576 Push a specified json file to ONOS through the onos-netcfg service
2577
2578 Required:
Devin Lim02075272017-07-10 15:33:21 -07002579 controllerIp - the Ip of the ONOS node in the cluster
Jeremy Songster5665f1b2016-06-20 14:38:22 -07002580 path - the location of the file to be sent
2581 fileName - name of the json file to be sent
2582
2583 Returns main.TRUE on successfully sending json file, and main.FALSE if
2584 there is an error.
2585 """
2586 try:
Jon Hall3c0114c2020-08-11 15:07:42 -07002587 cmd = "onos-netcfg "
2588 if user:
2589 cmd += "-u %s " % user
2590 if password:
2591 cmd += "-p %s " % password
2592 cmd += "{0} {1}{2}".format( controllerIp, path, fileName )
2593 main.log.info( self.name + ": Sending: " + cmd )
2594 self.handle.sendline( cmd )
2595 self.handle.expect( self.prompt )
Devin Lim02075272017-07-10 15:33:21 -07002596 handle = self.handle.before
Jon Hall3c0114c2020-08-11 15:07:42 -07002597 if "Error" in handle or\
2598 "No such file or directory" in handle or\
2599 "command not found" in handle or\
2600 "curl: " in handle:
Jeremy Ronquillo3008aa32017-07-07 15:38:57 -07002601 main.log.error( self.name + ": " + handle + self.handle.after )
Devin Lim02075272017-07-10 15:33:21 -07002602 return main.FALSE
Jon Hall3c0114c2020-08-11 15:07:42 -07002603 main.log.debug( self.name + ": " + handle )
Devin Lim752dd7b2017-06-27 14:40:03 -07002604 return main.TRUE
Jeremy Songster5665f1b2016-06-20 14:38:22 -07002605 except pexpect.EOF:
2606 main.log.error( self.name + ": EOF exception found" )
2607 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002608 main.cleanAndExit()
Jeremy Songster5665f1b2016-06-20 14:38:22 -07002609 except Exception:
2610 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002611 main.cleanAndExit()
Devin Lim3ebd5e72017-11-14 10:38:00 -08002612
2613 def formCluster( self, onosIPs ):
2614 """
2615 From ONOS cluster for IP addresses in onosIPs list
2616 """
2617 try:
2618 onosIPs = " ".join( onosIPs )
2619 command = "onos-form-cluster {}".format( onosIPs )
Jon Hall3c0114c2020-08-11 15:07:42 -07002620 main.log.info( self.name + ": Sending: " + command )
Devin Lim3ebd5e72017-11-14 10:38:00 -08002621 self.handle.sendline( "" )
2622 self.handle.expect( self.prompt )
2623 self.handle.sendline( command )
2624 self.handle.expect( self.prompt )
2625 handle = self.handle.before
2626 main.log.debug( handle )
2627 assert handle is not None, "Error in sendline"
2628 assert "Command not found:" not in handle, handle
2629 assert "Error" not in handle, handle
2630 assert "Exception:" not in handle, handle
2631 assert "curl:" not in handle, handle
2632 return main.TRUE
2633 except AssertionError:
2634 main.log.exception( "{} Error in onos-form-cluster output:".format( self.name ) )
2635 return main.FALSE
2636 except TypeError:
2637 main.log.exception( self.name + ": Object not as expected" )
2638 return main.FALSE
2639 except pexpect.EOF:
2640 main.log.error( self.name + ": EOF exception found" )
2641 main.log.error( self.name + ": " + self.handle.before )
2642 main.cleanAndExit()
2643 except Exception:
2644 main.log.exception( self.name + ": Uncaught exception!" )
2645 main.cleanAndExit()
Jon Hall7ce46ea2018-02-05 12:20:59 -08002646
2647 def backupData( self, location ):
2648 """
2649 Backs up ONOS data and logs to a given location. Returns main.FALSE
2650 if there is an error executing the command, and main.TRUE otherwise.
2651 required arguments:
2652 loaction - The file path to save the backup to
2653 """
2654 try:
2655 cmd = "/opt/onos/bin/onos-backup " + str( location )
2656 self.handle.sendline( cmd )
2657 self.handle.expect( self.prompt )
2658 handle = self.handle.before
2659 main.log.debug( handle )
2660 assert handle is not None, "Error in sendline"
2661 assert "Command not found:" not in handle, handle
2662 assert "Error" not in handle, handle
2663 assert "Exception:" not in handle, handle
2664 return main.TRUE
2665 except AssertionError:
2666 main.log.exception( "{} Error in onos-backup output:".format( self.name ) )
2667 return main.FALSE
2668 except TypeError:
2669 main.log.exception( self.name + ": Object not as expected" )
2670 return main.FALSE
2671 except pexpect.EOF:
2672 main.log.error( self.name + ": EOF exception found" )
2673 main.log.error( self.name + ": " + self.handle.before )
2674 main.cleanAndExit()
2675 except Exception:
2676 main.log.exception( self.name + ": Uncaught exception!" )
2677 main.cleanAndExit()
2678
2679 def restoreData( self, location ):
2680 """
2681 Restores ONOS data and logs from a given location. Returns main.FALSE
2682 if there is an error executing the command, and main.TRUE otherwise.
2683 required arguments:
2684 loaction - The file path of a backup file
2685 """
2686 try:
2687 cmd = "/opt/onos/bin/onos-restore " + str( location )
2688 self.handle.sendline( cmd )
2689 self.handle.expect( self.prompt )
2690 handle = self.handle.before
2691 main.log.debug( handle )
2692 assert handle is not None, "Error in sendline"
2693 assert "Command not found:" not in handle, handle
2694 assert "Error" not in handle, handle
2695 assert "Exception:" not in handle, handle
2696 return main.TRUE
2697 except AssertionError:
2698 main.log.exception( "{} Error in onos-restore output:".format( self.name ) )
2699 return main.FALSE
2700 except TypeError:
2701 main.log.exception( self.name + ": Object not as expected" )
2702 return main.FALSE
2703 except pexpect.EOF:
2704 main.log.error( self.name + ": EOF exception found" )
2705 main.log.error( self.name + ": " + self.handle.before )
2706 main.cleanAndExit()
2707 except Exception:
2708 main.log.exception( self.name + ": Uncaught exception!" )
2709 main.cleanAndExit()
You Wang5df1c6d2018-04-06 18:02:02 -07002710
Jon Hall43060f62020-06-23 13:13:33 -07002711 def onosDiagnostics( self, onosIPs, dstDir, suffix, timeout=300, profile="TRELLIS_PROFILE" ):
You Wang5df1c6d2018-04-06 18:02:02 -07002712 """
2713 Run onos-diagnostics with given ONOS instance IPs and save output to dstDir
2714 with suffix specified E.g. onos-diags-suffix.tar.gz
Jon Hall0e240372018-05-02 11:21:57 -07002715 required arguments:
You Wang5df1c6d2018-04-06 18:02:02 -07002716 onosIPs - list of ONOS IPs for collecting diags
2717 dstDir - diags file will be saved under the directory specified
2718 suffix - diags file will be named with the suffix specified
2719 returns:
2720 main.FALSE if there's an error executing the command, and main.TRUE otherwise
2721 """
2722 try:
Jon Hall43060f62020-06-23 13:13:33 -07002723 self.handle.sendline( "export DIAGS_PROFILE=%s" % profile )
2724 self.handle.expect( self.prompt )
You Wang5df1c6d2018-04-06 18:02:02 -07002725 cmd = "onos-diagnostics"
2726 assert isinstance( onosIPs, list )
2727 for ip in onosIPs:
2728 cmd += " " + str( ip )
2729 self.handle.sendline( cmd )
Jon Hall9b0de1f2020-08-24 15:38:04 -07002730 i = 0
2731 while i == 0:
2732 i = self.handle.expect( [ "Password", self.prompt ], timeout=timeout )
2733 handle = self.handle.before
2734 main.log.debug( "%s: %s" % ( self.name, handle ) )
2735 if i == 0:
2736 self.handle.sendline( self.pwd )
You Wang5df1c6d2018-04-06 18:02:02 -07002737 assert handle is not None, "Error in sendline"
Jon Hall9b0de1f2020-08-24 15:38:04 -07002738 assert "The requested URL returned error" not in handle, handle
You Wang5df1c6d2018-04-06 18:02:02 -07002739 assert "Command not found:" not in handle, handle
2740 assert "Exception:" not in handle, handle
2741 # Rename and move diags file to dstDir from /tmp
2742 if dstDir[ -1: ] != "/":
2743 dstDir += "/"
2744 self.handle.sendline( "mv /tmp/onos-diags.tar.gz " + str( dstDir ) + "onos-diags" + str( suffix ) + ".tar.gz" )
2745 self.handle.expect( self.prompt )
2746 handle = self.handle.before
Jon Hall9b0de1f2020-08-24 15:38:04 -07002747 main.log.debug( "%s: %s" % ( self.name, handle ) )
You Wang5df1c6d2018-04-06 18:02:02 -07002748 assert handle is not None, "Error in sendline"
2749 assert "No such file or directory" not in handle, handle
2750 return main.TRUE
2751 except AssertionError:
2752 main.log.exception( "{} Error in onos-diagnostics output:".format( self.name ) )
2753 return main.FALSE
2754 except TypeError:
2755 main.log.exception( self.name + ": Object not as expected" )
2756 return main.FALSE
You Wang223faa32018-06-21 10:45:47 -07002757 except pexpect.TIMEOUT:
2758 main.log.exception( self.name + ": TIMEOUT exception found in onosDiagnostics" )
2759 main.log.error( self.name + ": " + self.handle.before )
You Wangb65d2372018-08-17 15:37:59 -07002760 self.exitFromCmd( self.prompt, 100 )
You Wang223faa32018-06-21 10:45:47 -07002761 return main.FALSE
You Wang5df1c6d2018-04-06 18:02:02 -07002762 except pexpect.EOF:
2763 main.log.error( self.name + ": EOF exception found" )
2764 main.log.error( self.name + ": " + self.handle.before )
2765 main.cleanAndExit()
2766 except Exception:
2767 main.log.exception( self.name + ": Uncaught exception!" )
2768 main.cleanAndExit()
Jon Hall0e240372018-05-02 11:21:57 -07002769
2770 def onosPower( self, onosIP, toggle, userName=None ):
2771 """
2772 Run onos-power script to tell the cell warden to simulate a power faulure
2773 for the given container.
2774 required :
2775 onosIP - ONOS node IP
2776 toggle - either "off" or "on", used to indicate whether
2777 the node should be powered off or on
2778 returns:
2779 main.FALSE if there's an error executing the command, and main.TRUE otherwise
2780 """
2781 try:
2782 cmd = "onos-power {} {}".format( onosIP, toggle )
2783 if userName:
2784 cmd += " {}".format( userName )
2785 self.handle.sendline( cmd )
2786 self.handle.expect( self.prompt )
2787 handle = self.handle.before
2788 main.log.debug( handle )
2789 assert handle is not None, "Error in sendline"
2790 assert "Command not found:" not in handle, handle
2791 assert "Exception:" not in handle, handle
2792 assert "usage:" not in handle, handle
2793 return main.TRUE
2794 except AssertionError:
2795 main.log.exception( "{} Error in onos-power output:".format( self.name ) )
2796 return main.FALSE
2797 except TypeError:
2798 main.log.exception( self.name + ": Object not as expected" )
2799 return main.FALSE
2800 except pexpect.EOF:
2801 main.log.error( self.name + ": EOF exception found" )
2802 main.log.error( self.name + ": " + self.handle.before )
2803 main.cleanAndExit()
2804 except Exception:
2805 main.log.exception( self.name + ": Uncaught exception!" )
2806 main.cleanAndExit()
You Wangf9d95be2018-08-01 14:35:37 -07002807
2808 def atomixKill( self, nodeIp ):
2809 """
2810 Calls the command: 'atomix-kill [<node-ip>]'
2811 Kills the Atomix instance running on the specified node
2812 """
2813 try:
2814 self.handle.sendline( "" )
2815 self.handle.expect( self.prompt )
2816 self.handle.sendline( "atomix-kill " + str( nodeIp ) )
2817 i = self.handle.expect( [
2818 self.prompt,
2819 "No\sroute\sto\shost",
2820 "password:",
2821 pexpect.TIMEOUT ], timeout=60 )
2822
2823 if i == 0:
Jon Hall3c0114c2020-08-11 15:07:42 -07002824 main.log.info( self.name + ": Atomix instance " + str( nodeIp ) + " was killed" )
You Wangf9d95be2018-08-01 14:35:37 -07002825 return main.TRUE
2826 elif i == 1:
Jon Hall3c0114c2020-08-11 15:07:42 -07002827 main.log.info( self.name + ": No route to host" )
You Wangf9d95be2018-08-01 14:35:37 -07002828 return main.FALSE
2829 elif i == 2:
Jon Hall3c0114c2020-08-11 15:07:42 -07002830 main.log.info( self.name + ": Passwordless login for host: " + str( nodeIp ) + " not configured" )
You Wangf9d95be2018-08-01 14:35:37 -07002831 return main.FALSE
2832 else:
Jon Hall3c0114c2020-08-11 15:07:42 -07002833 main.log.info( self.name + ": Atomix instance was not killed" )
You Wangf9d95be2018-08-01 14:35:37 -07002834 return main.FALSE
2835
2836 except pexpect.EOF:
2837 main.log.error( self.name + ": EOF exception found" )
2838 main.log.error( self.name + ": " + self.handle.before )
2839 main.cleanAndExit()
2840 except Exception:
2841 main.log.exception( self.name + ": Uncaught exception!" )
2842 main.cleanAndExit()
2843
2844 def atomixUninstall( self, nodeIp="" ):
2845 """
2846 Calls the command: 'atomix-uninstall'
2847 Uninstalls Atomix from the designated node, stopping if needed
2848 """
2849 try:
2850 self.handle.sendline( "" )
2851 self.handle.expect( self.prompt, timeout=180 )
2852 self.handle.sendline( "atomix-uninstall " + str( nodeIp ) )
2853 self.handle.expect( self.prompt, timeout=180 )
Jon Hall3c0114c2020-08-11 15:07:42 -07002854 main.log.info( self.name + ": Atomix " + nodeIp + " was uninstalled" )
You Wangf9d95be2018-08-01 14:35:37 -07002855 # onos-uninstall command does not return any text
2856 return main.TRUE
2857 except pexpect.TIMEOUT:
2858 main.log.exception( self.name + ": Timeout in atomixUninstall" )
2859 self.handle.send( "\x03" ) # Control-C
2860 self.handle.expect( self.prompt )
2861 return main.FALSE
2862 except pexpect.EOF:
2863 main.log.error( self.name + ": EOF exception found" )
2864 main.log.error( self.name + ": " + self.handle.before )
2865 main.cleanAndExit()
2866 except Exception:
2867 main.log.exception( self.name + ": Uncaught exception!" )
2868 main.cleanAndExit()
2869
2870 def atomixInstall( self, options="", node="" ):
2871 """
2872 Installs Atomix on the designated nodes.
2873 Returns: main.TRUE on success and main.FALSE on failure
2874 """
2875 try:
2876 if options:
2877 self.handle.sendline( "atomix-install " + options + " " + node )
2878 else:
2879 self.handle.sendline( "atomix-install " + node )
2880 self.handle.expect( "atomix-install " )
2881 i = self.handle.expect( [ "Network\sis\sunreachable",
2882 "is already installed",
2883 "saved",
2884 self.prompt,
2885 pexpect.TIMEOUT ], timeout=180 )
2886 if i == 0:
2887 # can't reach ONOS node
Jon Hall3e6edb32018-08-21 16:20:30 -07002888 main.log.warn( self.name + ": Network is unreachable" )
You Wangf9d95be2018-08-01 14:35:37 -07002889 self.handle.expect( self.prompt )
2890 return main.FALSE
2891 elif i == 1:
2892 # same bits are already on Atomix node
Jon Hall3e6edb32018-08-21 16:20:30 -07002893 main.log.info( self.name + ": Atomix is already installed on " + node )
You Wangf9d95be2018-08-01 14:35:37 -07002894 self.handle.expect( self.prompt )
2895 return main.TRUE
Jon Hallb685a1c2018-10-30 15:17:01 -07002896 elif i == 2:
Jon Hall3e6edb32018-08-21 16:20:30 -07002897 main.log.info( self.name + ": Atomix was installed on " + node )
You Wangf9d95be2018-08-01 14:35:37 -07002898 self.handle.expect( self.prompt )
2899 return main.TRUE
Jon Hallb685a1c2018-10-30 15:17:01 -07002900 elif i == 3:
2901 self.handle.sendline( "echo Return code: $?" )
2902 self.handle.expect( "\$\?" )
2903 self.handle.expect( self.prompt )
Jon Hallb685a1c2018-10-30 15:17:01 -07002904 match = re.search( "Return code: (\d+)", self.handle.before )
2905 if match:
2906 exitCode = int( match.group( 1 ) )
2907 else:
2908 # Didn't match pattern
2909 main.log.error( "Could not parse exit code of atomix-install" )
Jon Hall5e1469a2018-11-01 13:55:53 -07002910 main.log.debug( self.handle.before + self.handle.before )
Jon Hallb685a1c2018-10-30 15:17:01 -07002911 return main.FALSE
2912 if exitCode == 0:
2913 return main.TRUE
2914 else:
Jon Hall5e1469a2018-11-01 13:55:53 -07002915 main.log.error( "Unsuccessful exit code of atomix-install" )
2916 main.log.debug( self.handle.before + self.handle.before )
Jon Hallb685a1c2018-10-30 15:17:01 -07002917 return main.FALSE
You Wangf9d95be2018-08-01 14:35:37 -07002918 elif i == 4:
2919 # timeout
Jon Hall3e6edb32018-08-21 16:20:30 -07002920 main.log.info( self.name + ": Installation of Atomix on " + node + " timed out" )
You Wangf9d95be2018-08-01 14:35:37 -07002921 self.handle.expect( self.prompt )
2922 main.log.warn( self.handle.before )
2923 self.handle.send( "\x03" ) # Control-C
2924 self.handle.expect( self.prompt )
2925 return main.FALSE
2926 except pexpect.EOF:
2927 main.log.error( self.name + ": EOF exception found" )
2928 main.log.error( self.name + ": " + self.handle.before )
2929 main.cleanAndExit()
2930 except Exception:
2931 main.log.exception( self.name + ": Uncaught exception!" )
2932 main.cleanAndExit()
Jon Hall43060f62020-06-23 13:13:33 -07002933
2934 def onosFetchApp( self, url, dstPath=None ):
2935 """
2936 Fetch an external onos app
2937
2938 Required:
2939 url - url for where to download the app
2940 dstPath - where the file will be saved
2941
2942 Returns main.TRUE on successfully fetching file, and main.FALSE if
2943 there is an error.
2944 """
2945 try:
2946 cmd = "wget -q --backups=1 "
2947 if dstPath:
2948 cmd += "-P %s " % ( dstPath )
2949 cmd += str( url )
Jon Hall3c0114c2020-08-11 15:07:42 -07002950 main.log.info( self.name + ": Sending: " + cmd )
2951 self.handle.sendline( cmd )
2952 self.handle.expect( self.prompt )
Jon Hall43060f62020-06-23 13:13:33 -07002953 output = self.handle.before
2954 main.log.debug( output )
2955 if "Error" in output or "No such file or directory" in output:
2956 main.log.error( self.name + ": " + output + self.handle.after )
2957 return main.FALSE
2958 return main.TRUE
2959 except pexpect.EOF:
2960 main.log.error( self.name + ": EOF exception found" )
2961 main.log.error( self.name + ": " + self.handle.before )
2962 main.cleanAndExit()
2963 except Exception:
2964 main.log.exception( self.name + ": Uncaught exception!" )
2965 main.cleanAndExit()
2966
2967 def onosApp( self, onosIP, option, fileName, filePath='~/onos/'):
2968 """
2969 Wrapper for onos-app script
2970
2971 Required:
2972 - onosIP - The ip address of the onos instance
2973 - option - What command are we doing?
2974 [ list|install|install!|reinstall|reinstall!|activate|deactivate|uninstall ]
2975 - fileName - The name of the app file
2976 Optional Arguments:
2977 - filePath - The location of the file
2978
2979 Returns main.TRUE on successfully executing the command, and main.FALSE if
2980 there is an error.
2981 """
2982 # FIXME: Not all options may work, more testing is required, only tested with install(!)
2983 try:
2984 cmd = "onos-app %s %s %s/%s" % ( onosIP, option, filePath, fileName )
Jon Hall3c0114c2020-08-11 15:07:42 -07002985 main.log.info( self.name + ": Sending: " + cmd )
2986 self.handle.sendline( cmd )
2987 self.handle.expect( self.prompt )
Jon Hall43060f62020-06-23 13:13:33 -07002988 handle = self.handle.before
2989 main.log.debug( handle )
2990 if "Error" in handle or "usage: " in handle or "curl: " in handle:
2991 main.log.error( self.name + ": " + handle + self.handle.after )
2992 return main.FALSE
2993 return main.TRUE
2994 except pexpect.EOF:
2995 main.log.error( self.name + ": EOF exception found" )
2996 main.log.error( self.name + ": " + self.handle.before )
2997 main.cleanAndExit()
2998 except Exception:
2999 main.log.exception( self.name + ": Uncaught exception!" )
3000 main.cleanAndExit()
Jon Hall3c0114c2020-08-11 15:07:42 -07003001
3002 def makeDocker( self, path, cmd, prompt="Successfully tagged", timeout=600 ):
3003 """
3004 Build a docker image using a command, such as make
3005 Arguments:
3006 - path: a path where the script is located. will cd to path
3007 - cmd: the command to run
3008 Optional Arguments:
3009 - prompt: A custom prompt to expect after the command is finished,
3010 incase the host prompt is printed during the build
3011 - timeout: how long to wait for the build
3012 """
3013 try:
3014 main.log.warn( "%s: makeDocker()" % self.name )
3015 self.handle.sendline( "cd %s" % path )
3016 self.handle.expect( self.prompt )
3017 self.handle.sendline( cmd )
3018 self.handle.expect( prompt, timeout=timeout )
3019 fullResponse = self.handle.before
3020 tailResponse = self.handle.after
3021 # TODO: error checking, might be difficult with custom expects
3022 self.handle.expect( self.prompt )
3023 tailResponse += self.handle.before + self.handle.after
3024 fullResponse += tailResponse
3025 main.log.debug( self.name + ": " + tailResponse )
3026 self.handle.sendline( "cd %s" % self.home )
3027 self.handle.expect( self.prompt )
3028 return main.TRUE
3029 except pexpect.EOF:
3030 main.log.error( self.name + ": EOF exception found" )
3031 main.log.error( self.name + ": " + self.handle.before )
3032 main.cleanAndExit()
3033 except Exception:
3034 main.log.exception( self.name + ": Uncaught exception!" )
3035 main.log.debug( self.name + ": " + self.handle.before )
3036 main.cleanAndExit()
3037
3038 def generateOnosConfig( self, nodeIp, path="cluster.json" ):
3039 """
3040 Generate onos cluster configuration file
3041 Arguments:
3042 - nodeIp: ip of the node this file is fore
3043 Optional Arguments:
3044 - The path to save the file to
3045 """
3046 try:
3047 main.log.info( "%s: Generating onos config file for %s" % ( self.name, nodeIp ) )
3048 self.handle.sendline( "onos-gen-config %s %s" % ( nodeIp, path ) )
3049 i = self.handle.expect( [ self.prompt, "not found", "Error" ] )
3050 response = self.handle.before
3051 if i == 0:
3052 main.log.debug( "%s: %s" % ( self.name, response ) )
3053 return main.TRUE
3054 else:
3055 response += self.handle.after
3056 self.handle.expect( self.prompt )
3057 response += self.handle.before
3058 main.log.debug( "%s: %s" % ( self.name, response ) )
3059 return main.FALSE
3060 except pexpect.EOF:
3061 main.log.error( self.name + ": EOF exception found" )
3062 main.log.error( self.name + ": " + self.handle.before )
3063 main.cleanAndExit()
3064 except Exception:
3065 main.log.exception( self.name + ": Uncaught exception!" )
3066 main.log.debug( self.name + ": " + self.handle.before )
3067 main.cleanAndExit()
3068
3069 def generateAtomixConfig( self, nodeIp, path="atomix.json" ):
3070 """
3071 Generate atomix cluster configuration file
3072 Arguments:
3073 - nodeIp: ip of the node this file is fore
3074 Optional Arguments:
3075 - The path to save the file to
3076 """
3077 try:
3078 main.log.info( "%s: Generating atomix config file for %s" % ( self.name, nodeIp ) )
3079 self.handle.sendline( "atomix-gen-config %s %s" % ( nodeIp, path ) )
3080 i = self.handle.expect( [ self.prompt, "not found", "Error" ] )
3081 response = self.handle.before
3082 if i == 0:
3083 main.log.debug( "%s: %s" % ( self.name, response ) )
3084 return main.TRUE
3085 else:
3086 response += self.handle.after
3087 self.handle.expect( self.prompt )
3088 response += self.handle.before
3089 main.log.debug( "%s: %s" % ( self.name, response ) )
3090 return main.FALSE
3091 except pexpect.EOF:
3092 main.log.error( self.name + ": EOF exception found" )
3093 main.log.error( self.name + ": " + self.handle.before )
3094 main.cleanAndExit()
3095 except Exception:
3096 main.log.exception( self.name + ": Uncaught exception!" )
3097 main.log.debug( self.name + ": " + self.handle.before )
3098 main.cleanAndExit()