blob: 06caa7c426153a1978cb97861c6fb831ed54a478 [file] [log] [blame]
Jon Hall05b2b432014-10-08 19:53:25 -04001#!/usr/bin/env python
andrewonlabe8e56fd2014-10-09 17:12:44 -04002
kelvin8ec71442015-01-15 16:57:00 -08003"""
Jeremy Ronquilloec916a42018-02-02 13:05:57 -08004Copyright 2014 Open Networking Foundation (ONF)
5
kelvin8ec71442015-01-15 16:57:00 -08006This driver interacts with ONOS bench, the OSGi platform
7that configures the ONOS nodes. ( aka ONOS-next )
andrewonlabe8e56fd2014-10-09 17:12:44 -04008
kelvin8ec71442015-01-15 16:57:00 -08009Please follow the coding style demonstrated by existing
andrewonlabe8e56fd2014-10-09 17:12:44 -040010functions and document properly.
11
12If you are a contributor to the driver, please
13list your email here for future contact:
14
15jhall@onlab.us
16andrew@onlab.us
17
18OCT 9 2014
Jeremy Songsterae01bba2016-07-11 15:39:17 -070019Modified 2016 by ON.Lab
20
21Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
22the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
23or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
andrewonlabe8e56fd2014-10-09 17:12:44 -040024
kelvin8ec71442015-01-15 16:57:00 -080025"""
Jon Hall05b2b432014-10-08 19:53:25 -040026import time
Jon Hall6801cda2015-07-15 14:13:45 -070027import types
Jon Hall05b2b432014-10-08 19:53:25 -040028import pexpect
kelvin-onlaba4074292015-07-09 15:19:49 -070029import os
Jon Hall6c44c0b2016-04-20 15:21:00 -070030import re
31import subprocess
Jon Hall05b2b432014-10-08 19:53:25 -040032from drivers.common.clidriver import CLI
33
kelvin8ec71442015-01-15 16:57:00 -080034class OnosDriver( CLI ):
Jon Hall05b2b432014-10-08 19:53:25 -040035
kelvin8ec71442015-01-15 16:57:00 -080036 def __init__( self ):
37 """
38 Initialize client
39 """
Jon Hallefbd9792015-03-05 16:11:36 -080040 self.name = None
41 self.home = None
Jon Hall9b0de1f2020-08-24 15:38:04 -070042 self.maxNodes = None
43 self.karafUser = None
44 self.karafPass = None
45 self.webUser = None
46 self.webPass = None
Jon Hallefbd9792015-03-05 16:11:36 -080047 self.handle = None
Jon Hall6c44c0b2016-04-20 15:21:00 -070048 self.nicAddr = None
Devin Limdc78e202017-06-09 18:30:07 -070049 super( OnosDriver, self ).__init__()
kelvin8ec71442015-01-15 16:57:00 -080050
51 def connect( self, **connectargs ):
52 """
Jon Hall05b2b432014-10-08 19:53:25 -040053 Creates ssh handle for ONOS "bench".
kelvin-onlaba4074292015-07-09 15:19:49 -070054 NOTE:
55 The ip_address would come from the topo file using the host tag, the
56 value can be an environment variable as well as a "localhost" to get
57 the ip address needed to ssh to the "bench"
kelvin8ec71442015-01-15 16:57:00 -080058 """
Jon Hall05b2b432014-10-08 19:53:25 -040059 try:
Devin Limdc78e202017-06-09 18:30:07 -070060
Jon Hall05b2b432014-10-08 19:53:25 -040061 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080062 vars( self )[ key ] = connectargs[ key ]
kelvin8ec71442015-01-15 16:57:00 -080063 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070064
kelvin-onlabc2b79102015-07-14 11:41:20 -070065 # The 'nodes' tag is optional and it is not required in .topo file
kelvin-onlaba4074292015-07-09 15:19:49 -070066 for key in self.options:
Jon Hall9b0de1f2020-08-24 15:38:04 -070067 if key == "home":
Jon Halle37bd1f2020-09-10 12:16:41 -070068 self.home = self.options[ key ]
Jon Hall9b0de1f2020-08-24 15:38:04 -070069 elif key == "nodes":
kelvin-onlabc2b79102015-07-14 11:41:20 -070070 # Maximum number of ONOS nodes to run, if there is any
Jon Halle37bd1f2020-09-10 12:16:41 -070071 self.maxNodes = int( self.options[ key ] )
Jon Hall9b0de1f2020-08-24 15:38:04 -070072 elif key == "web_user":
73 self.webUser = self.options[ key ]
74 elif key == "web_pass":
75 self.webPass = self.options[ key ]
Jon Hall06fd0df2021-01-25 15:50:06 -080076 elif key == "karaf_username":
77 self.karafUser = self.options[ key ]
78 elif key == "karaf_password":
79 self.karafPass = self.options[ key ]
kelvin-onlaba4074292015-07-09 15:19:49 -070080
Jon Hall9b0de1f2020-08-24 15:38:04 -070081 self.home = self.checkOptions( self.home, "~/onos" )
82 self.maxNodes = self.checkOptions( self.maxNodes, 100 )
83 self.karafUser = self.checkOptions( self.karafUser, self.user_name )
84 self.karafPass = self.checkOptions( self.karafPass, self.pwd )
85 self.webUser = self.checkOptions( self.webUser, "onos" )
86 self.webPass = self.checkOptions( self.webPass, "rocks" )
kelvin-onlaba4074292015-07-09 15:19:49 -070087
kelvin-onlabc2b79102015-07-14 11:41:20 -070088 # Grabs all OC environment variables based on max number of nodes
kelvin-onlaba4074292015-07-09 15:19:49 -070089 self.onosIps = {} # Dictionary of all possible ONOS ip
90
91 try:
92 if self.maxNodes:
kelvin-onlaba4074292015-07-09 15:19:49 -070093 for i in range( self.maxNodes ):
94 envString = "OC" + str( i + 1 )
kelvin-onlabc2b79102015-07-14 11:41:20 -070095 # If there is no more OC# then break the loop
96 if os.getenv( envString ):
97 self.onosIps[ envString ] = os.getenv( envString )
98 else:
99 self.maxNodes = len( self.onosIps )
100 main.log.info( self.name +
101 ": Created cluster data with " +
102 str( self.maxNodes ) +
103 " maximum number" +
104 " of nodes" )
105 break
kelvin-onlaba4074292015-07-09 15:19:49 -0700106
107 if not self.onosIps:
Jon Hall3c0114c2020-08-11 15:07:42 -0700108 main.log.info( self.name + ": Could not read any environment variable"
kelvin-onlaba4074292015-07-09 15:19:49 -0700109 + " please load a cell file with all" +
110 " onos IP" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700111 self.maxNodes = None
kelvin-onlaba4074292015-07-09 15:19:49 -0700112 else:
113 main.log.info( self.name + ": Found " +
114 str( self.onosIps.values() ) +
115 " ONOS IPs" )
kelvin-onlaba4074292015-07-09 15:19:49 -0700116 except KeyError:
Jon Hall3c0114c2020-08-11 15:07:42 -0700117 main.log.info( self.name + ": Invalid environment variable" )
kelvin-onlaba4074292015-07-09 15:19:49 -0700118 except Exception as inst:
119 main.log.error( "Uncaught exception: " + str( inst ) )
120
121 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700122 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -0700123 self.ip_address = os.getenv( str( self.ip_address ) )
124 else:
125 main.log.info( self.name +
126 ": Trying to connect to " +
127 self.ip_address )
kelvin-onlaba4074292015-07-09 15:19:49 -0700128 except KeyError:
Jon Hall3c0114c2020-08-11 15:07:42 -0700129 main.log.info( self.name + ": Invalid host name," +
kelvin-onlaba4074292015-07-09 15:19:49 -0700130 " connecting to local host instead" )
131 self.ip_address = 'localhost'
132 except Exception as inst:
133 main.log.error( "Uncaught exception: " + str( inst ) )
134
kelvin8ec71442015-01-15 16:57:00 -0800135 self.handle = super( OnosDriver, self ).connect(
136 user_name=self.user_name,
kelvin-onlab08679eb2015-01-21 16:11:48 -0800137 ip_address=self.ip_address,
kelvin-onlabd3b64892015-01-20 13:26:24 -0800138 port=self.port,
139 pwd=self.pwd,
140 home=self.home )
Jon Hall05b2b432014-10-08 19:53:25 -0400141 if self.handle:
Jon Hall500ed642019-06-17 18:25:46 +0000142 self.handle.setwinsize( 24, 250 )
Jon Hall0fc0d452015-07-14 09:49:58 -0700143 self.handle.sendline( "cd " + self.home )
Jon Hall4b668212019-06-17 11:08:49 -0700144 self.handle.expect( "cd " + self.home )
Devin Limc20e79a2017-06-07 10:29:57 -0700145 self.handle.expect( self.prompt )
Jon Hall05b2b432014-10-08 19:53:25 -0400146 return self.handle
kelvin8ec71442015-01-15 16:57:00 -0800147 else:
Jon Hall3c0114c2020-08-11 15:07:42 -0700148 main.log.info( self.name + ": Failed to create ONOS handle" )
Jon Hall05b2b432014-10-08 19:53:25 -0400149 return main.FALSE
150 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800151 main.log.error( self.name + ": EOF exception found" )
152 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700153 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800154 except Exception:
155 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700156 main.cleanAndExit()
Jon Hall05b2b432014-10-08 19:53:25 -0400157
kelvin8ec71442015-01-15 16:57:00 -0800158 def disconnect( self ):
159 """
Jon Hall05b2b432014-10-08 19:53:25 -0400160 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800161 """
Jon Halld61331b2015-02-17 16:35:47 -0800162 response = main.TRUE
Jon Hall05b2b432014-10-08 19:53:25 -0400163 try:
Jon Hall61282e32015-03-19 11:34:11 -0700164 if self.handle:
Jon Hall06fd0df2021-01-25 15:50:06 -0800165 self.preDisconnect()
Jon Hall61282e32015-03-19 11:34:11 -0700166 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -0700167 self.handle.expect( self.prompt )
Jon Hall61282e32015-03-19 11:34:11 -0700168 self.handle.sendline( "exit" )
169 self.handle.expect( "closed" )
Jon Hall05b2b432014-10-08 19:53:25 -0400170 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800171 main.log.error( self.name + ": EOF exception found" )
172 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700173 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700174 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700175 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800176 except Exception:
177 main.log.exception( self.name + ": Connection failed to the host" )
Jon Hall05b2b432014-10-08 19:53:25 -0400178 response = main.FALSE
179 return response
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400180
andrew@onlab.usaee415a2015-06-05 14:38:58 -0400181 def getEpochMs( self ):
182 """
183 Returns milliseconds since epoch
Jon Hall4ba53f02015-07-29 13:07:41 -0700184
185 When checking multiple nodes in a for loop,
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000186 around a hundred milliseconds of difference (ascending) is
Jon Hall4ba53f02015-07-29 13:07:41 -0700187 generally acceptable due to calltime of the function.
188 Few seconds, however, is not and it means clocks
189 are off sync.
andrew@onlab.usaee415a2015-06-05 14:38:58 -0400190 """
191 try:
192 self.handle.sendline( 'date +%s.%N' )
193 self.handle.expect( 'date \+\%s\.\%N' )
Devin Limdc78e202017-06-09 18:30:07 -0700194 self.handle.expect( self.prompt )
andrew@onlab.usaee415a2015-06-05 14:38:58 -0400195 epochMs = self.handle.before
196 return epochMs
197 except Exception:
198 main.log.exception( 'Uncaught exception getting epoch time' )
Devin Lim44075962017-08-11 10:56:37 -0700199 main.cleanAndExit()
andrew@onlab.usaee415a2015-06-05 14:38:58 -0400200
Jon Hall6c44c0b2016-04-20 15:21:00 -0700201 def onosPackage( self, opTimeout=180 ):
kelvin8ec71442015-01-15 16:57:00 -0800202 """
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400203 Produce a self-contained tar.gz file that can be deployed
Jon Hall64af8502015-12-15 10:09:33 -0800204 and executed on any platform with Java 8 JRE.
kelvin8ec71442015-01-15 16:57:00 -0800205 """
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400206 try:
Jon Hall64af8502015-12-15 10:09:33 -0800207 ret = main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800208 self.handle.sendline( "onos-package" )
209 self.handle.expect( "onos-package" )
Jon Hall96451092016-05-04 09:42:30 -0700210 while True:
211 i = self.handle.expect( [ "Downloading",
212 "Unknown options",
213 "No such file or directory",
214 "tar.gz",
Devin Limc20e79a2017-06-07 10:29:57 -0700215 self.prompt ],
Jon Hall96451092016-05-04 09:42:30 -0700216 opTimeout )
217 handle = str( self.handle.before + self.handle.after )
218 if i == 0:
219 # Give more time to download the file
220 continue # expect again
221 elif i == 1:
222 # Incorrect usage
223 main.log.error( "onos-package does not recognize the given options" )
224 ret = main.FALSE
225 continue # expect again
226 elif i == 2:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000227 # File(s) not found
Jon Hall96451092016-05-04 09:42:30 -0700228 main.log.error( "onos-package could not find a file or directory" )
229 ret = main.FALSE
230 continue # expect again
231 elif i == 3:
232 # tar.gz
233 continue # expect again
234 elif i == 4:
235 # Prompt returned
236 break
Jon Hall3c0114c2020-08-11 15:07:42 -0700237 main.log.info( self.name + ": onos-package command returned: " + handle )
kelvin8ec71442015-01-15 16:57:00 -0800238 # As long as the sendline does not time out,
239 # return true. However, be careful to interpret
240 # the results of the onos-package command return
Jon Hall64af8502015-12-15 10:09:33 -0800241 return ret
242 except pexpect.TIMEOUT:
243 main.log.exception( self.name + ": TIMEOUT exception found in onosPackage" )
244 main.log.error( self.name + ": " + self.handle.before )
You Wang141b43b2018-06-26 16:50:18 -0700245 self.handle.send( "\x03" ) # Control-C
246 self.handle.expect( self.prompt )
Jon Hall64af8502015-12-15 10:09:33 -0800247 return main.FALSE
andrewonlab7735d852014-10-09 13:02:47 -0400248 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800249 main.log.error( self.name + ": EOF exception found" )
250 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700251 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800252 except Exception:
253 main.log.exception( "Failed to package ONOS" )
Devin Lim44075962017-08-11 10:56:37 -0700254 main.cleanAndExit()
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400255
kelvin-onlabd3b64892015-01-20 13:26:24 -0800256 def onosBuild( self ):
kelvin8ec71442015-01-15 16:57:00 -0800257 """
andrewonlab8790abb2014-11-06 13:51:54 -0500258 Use the pre defined script to build onos via mvn
kelvin8ec71442015-01-15 16:57:00 -0800259 """
andrewonlab8790abb2014-11-06 13:51:54 -0500260 try:
kelvin8ec71442015-01-15 16:57:00 -0800261 self.handle.sendline( "onos-build" )
262 self.handle.expect( "onos-build" )
263 i = self.handle.expect( [
kelvin-onlabd3b64892015-01-20 13:26:24 -0800264 "BUILD SUCCESS",
265 "ERROR",
266 "BUILD FAILED" ],
267 timeout=120 )
kelvin8ec71442015-01-15 16:57:00 -0800268 handle = str( self.handle.before )
Devin Limc20e79a2017-06-07 10:29:57 -0700269 self.handle.expect( self.prompt )
andrewonlab8790abb2014-11-06 13:51:54 -0500270
Jon Hall3c0114c2020-08-11 15:07:42 -0700271 main.log.info( self.name + ": onos-build command returned: " +
kelvin8ec71442015-01-15 16:57:00 -0800272 handle )
andrewonlab8790abb2014-11-06 13:51:54 -0500273
274 if i == 0:
275 return main.TRUE
276 else:
277 return handle
278
279 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800280 main.log.error( self.name + ": EOF exception found" )
281 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -0800282 except Exception:
283 main.log.exception( "Failed to build ONOS" )
Devin Lim44075962017-08-11 10:56:37 -0700284 main.cleanAndExit()
andrewonlab8790abb2014-11-06 13:51:54 -0500285
shahshreya9f531fe2015-06-10 12:03:51 -0700286 def cleanInstall( self, skipTest=False, mciTimeout=600 ):
kelvin8ec71442015-01-15 16:57:00 -0800287 """
288 Runs mvn clean install in the root of the ONOS directory.
289 This will clean all ONOS artifacts then compile each module
shahshreya9f531fe2015-06-10 12:03:51 -0700290 Optional:
291 skipTest - Does "-DskipTests -Dcheckstyle.skip -U -T 1C" which
292 skip the test. This will make the building faster.
293 Disregarding the credibility of the build
kelvin8ec71442015-01-15 16:57:00 -0800294 Returns: main.TRUE on success
Jon Hallde9d9aa2014-10-08 20:36:02 -0400295 On Failure, exits the test
kelvin8ec71442015-01-15 16:57:00 -0800296 """
Jon Hallde9d9aa2014-10-08 20:36:02 -0400297 try:
Jon Hall3c0114c2020-08-11 15:07:42 -0700298 main.log.info( self.name + ": Running 'mvn clean install' on " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800299 str( self.name ) +
kelvin8ec71442015-01-15 16:57:00 -0800300 ". This may take some time." )
301 self.handle.sendline( "cd " + self.home )
Devin Limc20e79a2017-06-07 10:29:57 -0700302 self.handle.expect( self.prompt )
Jon Hallea7818b2014-10-09 14:30:59 -0400303
kelvin8ec71442015-01-15 16:57:00 -0800304 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -0700305 self.handle.expect( self.prompt )
shahshreya9f531fe2015-06-10 12:03:51 -0700306
307 if not skipTest:
308 self.handle.sendline( "mvn clean install" )
309 self.handle.expect( "mvn clean install" )
310 else:
311 self.handle.sendline( "mvn clean install -DskipTests" +
312 " -Dcheckstyle.skip -U -T 1C" )
313 self.handle.expect( "mvn clean install -DskipTests" +
314 " -Dcheckstyle.skip -U -T 1C" )
kelvin8ec71442015-01-15 16:57:00 -0800315 while True:
316 i = self.handle.expect( [
Jon Hall274b6642015-02-17 11:57:17 -0800317 'There\sis\sinsufficient\smemory\sfor\sthe\sJava\s' +
Jon Hallefbd9792015-03-05 16:11:36 -0800318 'Runtime\sEnvironment\sto\scontinue',
Jon Hallde9d9aa2014-10-08 20:36:02 -0400319 'BUILD\sFAILURE',
320 'BUILD\sSUCCESS',
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700321 'onos' + self.prompt, # TODO: fix this to be more generic?
Devin Limdc78e202017-06-09 18:30:07 -0700322 'ONOS' + self.prompt,
pingping-lin57a56ce2015-05-20 16:43:48 -0700323 pexpect.TIMEOUT ], mciTimeout )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400324 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800325 main.log.error( self.name + ":There is insufficient memory \
326 for the Java Runtime Environment to continue." )
327 # return main.FALSE
Devin Lim44075962017-08-11 10:56:37 -0700328
329 main.cleanAndExit()
Jon Hallde9d9aa2014-10-08 20:36:02 -0400330 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800331 main.log.error( self.name + ": Build failure!" )
332 # return main.FALSE
Devin Lim44075962017-08-11 10:56:37 -0700333
334 main.cleanAndExit()
Jon Hallde9d9aa2014-10-08 20:36:02 -0400335 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800336 main.log.info( self.name + ": Build success!" )
Jon Halle94919c2015-03-23 11:42:57 -0700337 elif i == 3 or i == 4:
kelvin8ec71442015-01-15 16:57:00 -0800338 main.log.info( self.name + ": Build complete" )
339 # Print the build time
Jon Hallf8ef52c2014-10-09 19:37:33 -0400340 for line in self.handle.before.splitlines():
341 if "Total time:" in line:
kelvin8ec71442015-01-15 16:57:00 -0800342 main.log.info( line )
343 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -0700344 self.handle.expect( self.prompt, timeout=60 )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400345 return main.TRUE
Jon Halle94919c2015-03-23 11:42:57 -0700346 elif i == 5:
kelvin8ec71442015-01-15 16:57:00 -0800347 main.log.error(
348 self.name +
349 ": mvn clean install TIMEOUT!" )
350 # return main.FALSE
Devin Lim44075962017-08-11 10:56:37 -0700351
352 main.cleanAndExit()
Jon Hallde9d9aa2014-10-08 20:36:02 -0400353 else:
Jon Hall274b6642015-02-17 11:57:17 -0800354 main.log.error( self.name + ": unexpected response from " +
Jon Hallefbd9792015-03-05 16:11:36 -0800355 "mvn clean install" )
kelvin8ec71442015-01-15 16:57:00 -0800356 # return main.FALSE
Devin Lim44075962017-08-11 10:56:37 -0700357
358 main.cleanAndExit()
Jon Hallde9d9aa2014-10-08 20:36:02 -0400359 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800360 main.log.error( self.name + ": EOF exception found" )
361 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700362 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800363 except Exception:
364 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700365 main.cleanAndExit()
Jon Hallacabffd2014-10-09 12:36:53 -0400366
Jon Hall3576f572016-08-23 10:01:07 -0700367 def buckBuild( self, timeout=180 ):
368 """
369 Build onos using buck.
370 """
371 try:
372 ret = main.TRUE
373 self.handle.sendline( "buck build onos" )
374 self.handle.expect( "buck build onos" )
375 output = ""
376 while True:
377 i = self.handle.expect( [ "This does not appear to be the root of a Buck project.",
378 "\n",
379 "BUILD FAILED",
Jon Halld9066132018-03-01 14:52:53 -0800380 "no buck in",
Devin Limc20e79a2017-06-07 10:29:57 -0700381 self.prompt ],
Jon Hall3576f572016-08-23 10:01:07 -0700382 timeout=timeout )
383 output += str( self.handle.before + self.handle.after )
384 if i == 0:
385 main.log.error( "Wrong location" )
386 ret = main.FALSE
387 elif i == 1:
388 # end of a line, buck is still printing output
389 pass
390 elif i == 2:
391 # Build failed
392 main.log.error( "Build failed" )
393 ret = main.FALSE
394 elif i == 3:
Jon Halld9066132018-03-01 14:52:53 -0800395 main.log.error( "Could not find buck in your PATH." )
396 ret = main.FALSE
397 elif i == 4:
Jon Hall3576f572016-08-23 10:01:07 -0700398 # Prompt returned
399 break
Jon Hall06fd0df2021-01-25 15:50:06 -0800400 main.log.debug( self.name + ": " + output )
Jon Hall3576f572016-08-23 10:01:07 -0700401 return ret
402 except pexpect.TIMEOUT:
403 main.log.exception( self.name + ": TIMEOUT exception found" )
404 main.log.error( self.name + ": " + self.handle.before )
You Wang141b43b2018-06-26 16:50:18 -0700405 self.handle.send( "\x03" ) # Control-C
406 self.handle.expect( self.prompt )
Jon Hall3576f572016-08-23 10:01:07 -0700407 return main.FALSE
408 except pexpect.EOF:
409 main.log.error( self.name + ": EOF exception found" )
410 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700411 main.cleanAndExit()
Jon Hall3576f572016-08-23 10:01:07 -0700412 except Exception:
413 main.log.exception( "Failed to build and package ONOS" )
Devin Lim44075962017-08-11 10:56:37 -0700414 main.cleanAndExit()
Jon Hall3576f572016-08-23 10:01:07 -0700415
You Wangd54c7052018-08-07 16:06:27 -0700416 def bazelBuild( self, timeout=180 ):
417 """
418 Build onos using bazel.
419 """
420 try:
421 ret = main.TRUE
422 self.handle.sendline( "bazel build onos" )
423 self.handle.expect( "bazel build onos" )
424 output = ""
425 while True:
426 i = self.handle.expect( [ "command is only supported from within a workspace",
427 "\n",
428 "FAILED",
429 "ERROR",
430 "command not found",
431 self.prompt ],
432 timeout=timeout )
433 output += str( self.handle.before + self.handle.after )
434 if i == 0:
435 main.log.error( "Please run the build from root of ONOS project" )
436 ret = main.FALSE
437 elif i == 1:
438 # end of a line, buck is still printing output
439 pass
440 elif i == 2:
441 # Build failed
442 main.log.error( "Build failed" )
443 ret = main.FALSE
444 elif i == 3:
445 # Build failed
446 main.log.error( "Build failed" )
447 ret = main.FALSE
448 elif i == 4:
449 main.log.error( "Command not found" )
450 ret = main.FALSE
451 elif i == 5:
452 # Prompt returned
453 break
Jon Hall06fd0df2021-01-25 15:50:06 -0800454 main.log.debug( self.name + ": " + output )
You Wangd54c7052018-08-07 16:06:27 -0700455 return ret
456 except pexpect.TIMEOUT:
457 main.log.exception( self.name + ": TIMEOUT exception found" )
458 main.log.error( self.name + ": " + self.handle.before )
459 self.handle.send( "\x03" ) # Control-C
460 self.handle.expect( self.prompt )
461 return main.FALSE
462 except pexpect.EOF:
463 main.log.error( self.name + ": EOF exception found" )
464 main.log.error( self.name + ": " + self.handle.before )
465 main.cleanAndExit()
466 except Exception:
467 main.log.exception( "Failed to build and package ONOS" )
468 main.cleanAndExit()
469
Jon Hall61282e32015-03-19 11:34:11 -0700470 def gitPull( self, comp1="", fastForward=True ):
kelvin8ec71442015-01-15 16:57:00 -0800471 """
Jon Hallacabffd2014-10-09 12:36:53 -0400472 Assumes that "git pull" works without login
Jon Hall47a93fb2015-01-06 16:46:06 -0800473
Jon Hall61282e32015-03-19 11:34:11 -0700474 If the fastForward boolean is set to true, only git pulls that can
475 be fast forwarded will be performed. IE if you have not local commits
476 in your branch.
477
Jon Hallacabffd2014-10-09 12:36:53 -0400478 This function will perform a git pull on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800479 If used as gitPull( "NODE" ) it will do git pull + NODE. This is
Jon Hallacabffd2014-10-09 12:36:53 -0400480 for the purpose of pulling from other nodes if necessary.
481
Jon Hall47a93fb2015-01-06 16:46:06 -0800482 Otherwise, this function will perform a git pull in the
Jon Hallacabffd2014-10-09 12:36:53 -0400483 ONOS repository. If it has any problems, it will return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -0800484 If it successfully does a gitPull, it will return a 1 ( main.TRUE )
Shreya Shahee15f6c2014-10-28 18:12:30 -0400485 If it has no updates, it will return 3.
Jon Hallacabffd2014-10-09 12:36:53 -0400486
kelvin8ec71442015-01-15 16:57:00 -0800487 """
Jon Hallacabffd2014-10-09 12:36:53 -0400488 try:
kelvin8ec71442015-01-15 16:57:00 -0800489 self.handle.sendline( "cd " + self.home )
Devin Limc20e79a2017-06-07 10:29:57 -0700490 self.handle.expect( self.prompt )
Jon Hall61282e32015-03-19 11:34:11 -0700491 cmd = "git pull"
492 if comp1 != "":
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700493 cmd += ' ' + comp1
Jon Hall61282e32015-03-19 11:34:11 -0700494 if fastForward:
495 cmd += ' ' + " --ff-only"
496 self.handle.sendline( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800497 i = self.handle.expect(
498 [
499 'fatal',
500 'Username\sfor\s(.*):\s',
501 '\sfile(s*) changed,\s',
502 'Already up-to-date',
503 'Aborting',
504 'You\sare\snot\scurrently\son\sa\sbranch',
Jon Hall274b6642015-02-17 11:57:17 -0800505 'You asked me to pull without telling me which branch you',
506 'Pull is not possible because you have unmerged files',
Jon Hall61282e32015-03-19 11:34:11 -0700507 'Please enter a commit message to explain why this merge',
508 'Found a swap file by the name',
509 'Please, commit your changes before you can merge.',
kelvin-onlabd3b64892015-01-20 13:26:24 -0800510 pexpect.TIMEOUT ],
511 timeout=300 )
kelvin8ec71442015-01-15 16:57:00 -0800512 if i == 0:
Jon Hall61282e32015-03-19 11:34:11 -0700513 main.log.error( self.name + ": Git pull had some issue" )
514 output = self.handle.after
Devin Limdc78e202017-06-09 18:30:07 -0700515 self.handle.expect( self.prompt )
Jon Hall61282e32015-03-19 11:34:11 -0700516 output += self.handle.before
517 main.log.warn( output )
Jon Hallacabffd2014-10-09 12:36:53 -0400518 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800519 elif i == 1:
520 main.log.error(
521 self.name +
522 ": Git Pull Asking for username. " )
Jon Hallacabffd2014-10-09 12:36:53 -0400523 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800524 elif i == 2:
525 main.log.info(
526 self.name +
527 ": Git Pull - pulling repository now" )
Devin Limc20e79a2017-06-07 10:29:57 -0700528 self.handle.expect( self.prompt, 120 )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800529 # So that only when git pull is done, we do mvn clean compile
530 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800531 elif i == 3:
532 main.log.info( self.name + ": Git Pull - Already up to date" )
Devin Limc20e79a2017-06-07 10:29:57 -0700533 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800534 elif i == 4:
535 main.log.info(
536 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800537 ": Git Pull - Aborting..." +
538 "Are there conflicting git files?" )
Jon Hallacabffd2014-10-09 12:36:53 -0400539 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800540 elif i == 5:
541 main.log.info(
542 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800543 ": Git Pull - You are not currently " +
544 "on a branch so git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400545 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800546 elif i == 6:
547 main.log.info(
548 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800549 ": Git Pull - You have not configured an upstream " +
550 "branch to pull from. Git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400551 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800552 elif i == 7:
553 main.log.info(
554 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800555 ": Git Pull - Pull is not possible because " +
556 "you have unmerged files." )
Jon Hallacabffd2014-10-09 12:36:53 -0400557 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800558 elif i == 8:
Jon Hall61282e32015-03-19 11:34:11 -0700559 # NOTE: abandoning test since we can't reliably handle this
560 # there could be different default text editors and we
561 # also don't know if we actually want to make the commit
562 main.log.error( "Git pull resulted in a merge commit message" +
563 ". Exiting test!" )
Devin Lim44075962017-08-11 10:56:37 -0700564
565 main.cleanAndExit()
Jon Hall61282e32015-03-19 11:34:11 -0700566 elif i == 9: # Merge commit message but swap file exists
567 main.log.error( "Git pull resulted in a merge commit message" +
568 " but a swap file exists." )
569 try:
570 self.handle.send( 'A' ) # Abort
Devin Limc20e79a2017-06-07 10:29:57 -0700571 self.handle.expect( self.prompt )
Jon Hall61282e32015-03-19 11:34:11 -0700572 return main.ERROR
573 except Exception:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700574 main.log.exception( "Couldn't exit editor prompt!" )
Devin Lim44075962017-08-11 10:56:37 -0700575
576 main.cleanAndExit()
Jon Hall61282e32015-03-19 11:34:11 -0700577 elif i == 10: # In the middle of a merge commit
578 main.log.error( "Git branch is in the middle of a merge. " )
579 main.log.warn( self.handle.before + self.handle.after )
580 return main.ERROR
581 elif i == 11:
kelvin8ec71442015-01-15 16:57:00 -0800582 main.log.error( self.name + ": Git Pull - TIMEOUT" )
583 main.log.error(
584 self.name + " Response was: " + str(
585 self.handle.before ) )
You Wang141b43b2018-06-26 16:50:18 -0700586 self.handle.send( "\x03" ) # Control-C
587 self.handle.expect( self.prompt )
Jon Hallacabffd2014-10-09 12:36:53 -0400588 return main.ERROR
589 else:
kelvin8ec71442015-01-15 16:57:00 -0800590 main.log.error(
591 self.name +
592 ": Git Pull - Unexpected response, check for pull errors" )
Jon Hallacabffd2014-10-09 12:36:53 -0400593 return main.ERROR
594 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800595 main.log.error( self.name + ": EOF exception found" )
596 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700597 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800598 except Exception:
599 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700600 main.cleanAndExit()
Jon Hallacabffd2014-10-09 12:36:53 -0400601
kelvin-onlabd3b64892015-01-20 13:26:24 -0800602 def gitCheckout( self, branch="master" ):
kelvin8ec71442015-01-15 16:57:00 -0800603 """
Jon Hallacabffd2014-10-09 12:36:53 -0400604 Assumes that "git pull" works without login
kelvin8ec71442015-01-15 16:57:00 -0800605
Jon Hallacabffd2014-10-09 12:36:53 -0400606 This function will perform a git git checkout on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800607 If used as gitCheckout( "branch" ) it will do git checkout
608 of the "branch".
Jon Hallacabffd2014-10-09 12:36:53 -0400609
610 Otherwise, this function will perform a git checkout of the master
kelvin8ec71442015-01-15 16:57:00 -0800611 branch of the ONOS repository. If it has any problems, it will return
612 main.ERROR.
613 If the branch was already the specified branch, or the git checkout was
Jon Hallacabffd2014-10-09 12:36:53 -0400614 successful then the function will return main.TRUE.
615
kelvin8ec71442015-01-15 16:57:00 -0800616 """
Jon Hallacabffd2014-10-09 12:36:53 -0400617 try:
kelvin8ec71442015-01-15 16:57:00 -0800618 self.handle.sendline( "cd " + self.home )
Devin Limc20e79a2017-06-07 10:29:57 -0700619 self.handle.expect( self.prompt )
Jon Hall274b6642015-02-17 11:57:17 -0800620 main.log.info( self.name +
621 ": Checking out git branch/ref: " + branch + "..." )
kelvin8ec71442015-01-15 16:57:00 -0800622 cmd = "git checkout " + branch
623 self.handle.sendline( cmd )
624 self.handle.expect( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800625 i = self.handle.expect(
Jon Hall274b6642015-02-17 11:57:17 -0800626 [ 'fatal',
Jon Hall61282e32015-03-19 11:34:11 -0700627 'Username for (.*): ',
628 'Already on \'',
Jon Hall7a8354f2015-06-10 15:37:00 -0700629 'Switched to (a new )?branch \'' + str( branch ),
Jon Hall274b6642015-02-17 11:57:17 -0800630 pexpect.TIMEOUT,
631 'error: Your local changes to the following files' +
Jon Hallefbd9792015-03-05 16:11:36 -0800632 'would be overwritten by checkout:',
Jon Hall274b6642015-02-17 11:57:17 -0800633 'error: you need to resolve your current index first',
634 "You are in 'detached HEAD' state.",
635 "HEAD is now at " ],
kelvin-onlabd3b64892015-01-20 13:26:24 -0800636 timeout=60 )
kelvin8ec71442015-01-15 16:57:00 -0800637 if i == 0:
638 main.log.error(
639 self.name +
640 ": Git checkout had some issue..." )
641 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400642 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800643 elif i == 1:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800644 main.log.error(
645 self.name +
646 ": Git checkout asking for username." +
647 " Please configure your local git repository to be able " +
648 "to access your remote repository passwordlessly" )
Jon Hall274b6642015-02-17 11:57:17 -0800649 # TODO add support for authenticating
Jon Hallacabffd2014-10-09 12:36:53 -0400650 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800651 elif i == 2:
652 main.log.info(
653 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800654 ": Git Checkout %s : Already on this branch" % branch )
Devin Limc20e79a2017-06-07 10:29:57 -0700655 self.handle.expect( self.prompt )
Jon Hall3c0114c2020-08-11 15:07:42 -0700656 # main.log.info( self.name + ": DEBUG: after checkout cmd = "+
kelvin8ec71442015-01-15 16:57:00 -0800657 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400658 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800659 elif i == 3:
660 main.log.info(
661 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800662 ": Git checkout %s - Switched to this branch" % branch )
Devin Limc20e79a2017-06-07 10:29:57 -0700663 self.handle.expect( self.prompt )
Jon Hall3c0114c2020-08-11 15:07:42 -0700664 # main.log.info( self.name + ": DEBUG: after checkout cmd = "+
kelvin8ec71442015-01-15 16:57:00 -0800665 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400666 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800667 elif i == 4:
668 main.log.error( self.name + ": Git Checkout- TIMEOUT" )
669 main.log.error(
Jon Hall274b6642015-02-17 11:57:17 -0800670 self.name + " Response was: " + str( self.handle.before ) )
You Wang141b43b2018-06-26 16:50:18 -0700671 self.handle.send( "\x03" ) # Control-C
672 self.handle.expect( self.prompt )
Jon Hallacabffd2014-10-09 12:36:53 -0400673 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800674 elif i == 5:
675 self.handle.expect( "Aborting" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800676 main.log.error(
677 self.name +
678 ": Git checkout error: \n" +
Jon Hall274b6642015-02-17 11:57:17 -0800679 "Your local changes to the following files would" +
680 " be overwritten by checkout:" +
681 str( self.handle.before ) )
Devin Limc20e79a2017-06-07 10:29:57 -0700682 self.handle.expect( self.prompt )
Jon Hall81e29af2014-11-04 20:41:23 -0500683 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800684 elif i == 6:
Jon Hall274b6642015-02-17 11:57:17 -0800685 main.log.error(
686 self.name +
687 ": Git checkout error: \n" +
688 "You need to resolve your current index first:" +
689 str( self.handle.before ) )
Devin Limc20e79a2017-06-07 10:29:57 -0700690 self.handle.expect( self.prompt )
Jon Hall81e29af2014-11-04 20:41:23 -0500691 return main.ERROR
Jon Hall274b6642015-02-17 11:57:17 -0800692 elif i == 7:
693 main.log.info(
694 self.name +
695 ": Git checkout " + str( branch ) +
696 " - You are in 'detached HEAD' state. HEAD is now at " +
697 str( branch ) )
Devin Limc20e79a2017-06-07 10:29:57 -0700698 self.handle.expect( self.prompt )
Jon Hall274b6642015-02-17 11:57:17 -0800699 return main.TRUE
700 elif i == 8: # Already in detached HEAD on the specified commit
701 main.log.info(
702 self.name +
703 ": Git Checkout %s : Already on commit" % branch )
Devin Limc20e79a2017-06-07 10:29:57 -0700704 self.handle.expect( self.prompt )
Jon Hall274b6642015-02-17 11:57:17 -0800705 return main.TRUE
Jon Hallacabffd2014-10-09 12:36:53 -0400706 else:
kelvin8ec71442015-01-15 16:57:00 -0800707 main.log.error(
708 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800709 ": Git Checkout - Unexpected response, " +
710 "check for pull errors" )
kelvin8ec71442015-01-15 16:57:00 -0800711 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400712 return main.ERROR
713
714 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800715 main.log.error( self.name + ": EOF exception found" )
716 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700717 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800718 except Exception:
719 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700720 main.cleanAndExit()
andrewonlab95ca1462014-10-09 14:04:24 -0400721
pingping-lin6d23d9e2015-02-02 16:54:24 -0800722 def getBranchName( self ):
You Wang9cdf9a22017-05-01 13:44:18 -0700723 import re
724 try:
Jon Hall3e6edb32018-08-21 16:20:30 -0700725 main.log.info( self.name + " home is " + self.home )
You Wang9cdf9a22017-05-01 13:44:18 -0700726 self.handle.sendline( "cd " + self.home )
Devin Limc20e79a2017-06-07 10:29:57 -0700727 self.handle.expect( self.prompt )
You Wang9cdf9a22017-05-01 13:44:18 -0700728 self.handle.sendline( "git name-rev --name-only HEAD" )
729 self.handle.expect( "git name-rev --name-only HEAD" )
Devin Limc20e79a2017-06-07 10:29:57 -0700730 self.handle.expect( self.prompt )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700731 lines = self.handle.before.splitlines()
732 if lines[ 1 ] == "master" or re.search( "^onos-\d+(\.\d+)+$", lines[ 1 ] ):
733 return lines[ 1 ]
You Wang9cdf9a22017-05-01 13:44:18 -0700734 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700735 main.log.info( lines[ 1 ] )
You Wang9cdf9a22017-05-01 13:44:18 -0700736 return "unexpected ONOS branch"
737 except pexpect.EOF:
738 main.log.error( self.name + ": EOF exception found" )
739 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700740 main.cleanAndExit()
You Wang9cdf9a22017-05-01 13:44:18 -0700741 except pexpect.TIMEOUT:
742 main.log.error( self.name + ": TIMEOUT exception found" )
743 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700744 main.cleanAndExit()
You Wang9cdf9a22017-05-01 13:44:18 -0700745 except Exception:
746 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700747 main.cleanAndExit()
pingping-lin6d23d9e2015-02-02 16:54:24 -0800748
kelvin-onlabd3b64892015-01-20 13:26:24 -0800749 def getVersion( self, report=False ):
kelvin8ec71442015-01-15 16:57:00 -0800750 """
Jon Hall274b6642015-02-17 11:57:17 -0800751 Writes the COMMIT number to the report to be parsed
Jon Hallefbd9792015-03-05 16:11:36 -0800752 by Jenkins data collector.
kelvin8ec71442015-01-15 16:57:00 -0800753 """
Jon Hall45ec0922014-10-10 19:33:49 -0400754 try:
kelvin8ec71442015-01-15 16:57:00 -0800755 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -0700756 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -0800757 self.handle.sendline(
758 "cd " +
759 self.home +
Jon Hall274b6642015-02-17 11:57:17 -0800760 "; git log -1 --pretty=fuller --decorate=short | grep -A 6 " +
761 " \"commit\" --color=never" )
kelvin8ec71442015-01-15 16:57:00 -0800762 # NOTE: for some reason there are backspaces inserted in this
763 # phrase when run from Jenkins on some tests
764 self.handle.expect( "never" )
Devin Limc20e79a2017-06-07 10:29:57 -0700765 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -0800766 response = ( self.name + ": \n" + str(
767 self.handle.before + self.handle.after ) )
768 self.handle.sendline( "cd " + self.home )
Devin Limc20e79a2017-06-07 10:29:57 -0700769 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -0800770 lines = response.splitlines()
Jon Hall45ec0922014-10-10 19:33:49 -0400771 for line in lines:
Jon Hallfd191202014-11-07 18:36:09 -0500772 print line
773 if report:
pingping-lin763ee042015-05-20 17:45:30 -0700774 main.log.wiki( "<blockquote>" )
kelvin8ec71442015-01-15 16:57:00 -0800775 for line in lines[ 2:-1 ]:
776 # Bracket replacement is for Wiki-compliant
777 # formatting. '<' or '>' are interpreted
778 # as xml specific tags that cause errors
779 line = line.replace( "<", "[" )
780 line = line.replace( ">", "]" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700781 # main.log.wiki( "\t" + line )
pingping-lin763ee042015-05-20 17:45:30 -0700782 main.log.wiki( line + "<br /> " )
783 main.log.summary( line )
784 main.log.wiki( "</blockquote>" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700785 main.log.summary( "\n" )
kelvin8ec71442015-01-15 16:57:00 -0800786 return lines[ 2 ]
Jon Hall45ec0922014-10-10 19:33:49 -0400787 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800788 main.log.error( self.name + ": EOF exception found" )
789 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700790 main.cleanAndExit()
Jon Hall368769f2014-11-19 15:43:35 -0800791 except pexpect.TIMEOUT:
kelvin8ec71442015-01-15 16:57:00 -0800792 main.log.error( self.name + ": TIMEOUT exception found" )
793 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700794 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800795 except Exception:
796 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700797 main.cleanAndExit()
Jon Hall45ec0922014-10-10 19:33:49 -0400798
kelvin-onlabd3b64892015-01-20 13:26:24 -0800799 def createCellFile( self, benchIp, fileName, mnIpAddrs,
Jon Hall3e6edb32018-08-21 16:20:30 -0700800 appString, onosIpAddrs, atomixIps,
801 onosUser="sdn", useSSH=True ):
kelvin8ec71442015-01-15 16:57:00 -0800802 """
andrewonlab94282092014-10-10 13:00:11 -0400803 Creates a cell file based on arguments
804 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800805 * Bench IP address ( benchIp )
andrewonlab94282092014-10-10 13:00:11 -0400806 - Needed to copy the cell file over
kelvin-onlabd3b64892015-01-20 13:26:24 -0800807 * File name of the cell file ( fileName )
808 * Mininet IP address ( mnIpAddrs )
kelvin8ec71442015-01-15 16:57:00 -0800809 - Note that only 1 ip address is
andrewonlab94282092014-10-10 13:00:11 -0400810 supported currently
kelvin-onlabd3b64892015-01-20 13:26:24 -0800811 * ONOS IP addresses ( onosIpAddrs )
andrewonlab94282092014-10-10 13:00:11 -0400812 - Must be passed in as last arguments
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000813 * ONOS USER (onosUser)
Flavio Castrocc38a542016-03-03 13:15:46 -0800814 - optional argument to set ONOS_USER environment variable
kelvin8ec71442015-01-15 16:57:00 -0800815
andrewonlab94282092014-10-10 13:00:11 -0400816 NOTE: Assumes cells are located at:
817 ~/<self.home>/tools/test/cells/
kelvin8ec71442015-01-15 16:57:00 -0800818 """
andrewonlab94282092014-10-10 13:00:11 -0400819 try:
Jon Hall2c8959e2016-12-16 12:17:34 -0800820 # Variable initialization
821 cellDirectory = self.home + "/tools/test/cells/"
822 # We want to create the cell file in the dependencies directory
823 # of TestON first, then copy over to ONOS bench
824 tempDirectory = "/tmp/"
825 # Create the cell file in the directory for writing ( w+ )
826 cellFile = open( tempDirectory + fileName, 'w+' )
827 if isinstance( onosIpAddrs, types.StringType ):
828 onosIpAddrs = [ onosIpAddrs ]
Jon Hall3e6edb32018-08-21 16:20:30 -0700829 if isinstance( atomixIps, types.StringType ):
830 atomixIps = [ atomixIps ]
Jon Hall2c8959e2016-12-16 12:17:34 -0800831
832 # App string is hardcoded environment variables
833 # That you may wish to use by default on startup.
834 # Note that you may not want certain apps listed
835 # on here.
836 appString = "export ONOS_APPS=" + appString
837 onosGroup = "export ONOS_GROUP=" + onosUser
Jon Hall9b0de1f2020-08-24 15:38:04 -0700838 onosWebUser = "export ONOS_WEB_USER=" + self.webUser
839 onosWebPass = "export ONOS_WEB_PASS=" + self.webPass
Jon Hall2c8959e2016-12-16 12:17:34 -0800840 onosUser = "export ONOS_USER=" + onosUser
841 if useSSH:
842 onosUseSSH = "export ONOS_USE_SSH=true"
843 mnString = "export OCN="
844 if mnIpAddrs == "":
845 mnString = ""
846 onosString = "export OC"
Jon Hall3e6edb32018-08-21 16:20:30 -0700847 atomixString = "export OCC"
Jon Hall2c8959e2016-12-16 12:17:34 -0800848
849 # Create ONOSNIC ip address prefix
850 tempOnosIp = str( onosIpAddrs[ 0 ] )
851 tempList = []
852 tempList = tempOnosIp.split( "." )
853 # Omit last element of list to format for NIC
854 tempList = tempList[ :-1 ]
855 # Structure the nic string ip
856 nicAddr = ".".join( tempList ) + ".*"
857 self.nicAddr = nicAddr
858 onosNicString = "export ONOS_NIC=" + nicAddr
859
kelvin8ec71442015-01-15 16:57:00 -0800860 # Start writing to file
kelvin-onlabd3b64892015-01-20 13:26:24 -0800861 cellFile.write( onosNicString + "\n" )
andrewonlab94282092014-10-10 13:00:11 -0400862
Jon Hall3e6edb32018-08-21 16:20:30 -0700863 onosIndex = 1
kelvin-onlabd3b64892015-01-20 13:26:24 -0800864 for arg in onosIpAddrs:
865 # For each argument in onosIpAddrs, write to file
kelvin8ec71442015-01-15 16:57:00 -0800866 # Output should look like the following:
andrewonlabd4940492014-10-24 12:21:27 -0400867 # export OC1="10.128.20.11"
868 # export OC2="10.128.20.12"
Jon Hall3e6edb32018-08-21 16:20:30 -0700869 cellFile.write( onosString + str( onosIndex ) +
Jon Hall6f665652015-09-18 10:08:07 -0700870 "=\"" + arg + "\"\n" )
Jon Hall3e6edb32018-08-21 16:20:30 -0700871 onosIndex = onosIndex + 1
872
873 atomixIndex = 1
874 for ip in atomixIps:
875 cellFile.write( atomixString + str( atomixIndex ) +
876 "=\"" + ip + "\"\n" )
877 atomixIndex += 1
kelvin8ec71442015-01-15 16:57:00 -0800878
Jon Hall6f665652015-09-18 10:08:07 -0700879 cellFile.write( "export OCI=$OC1\n" )
Jon Hallab611372018-02-21 15:26:05 -0800880 if mnString:
881 cellFile.write( mnString + "\"" + str( mnIpAddrs ) + "\"\n" )
cameron@onlab.us75900962015-03-30 13:22:49 -0700882 cellFile.write( appString + "\n" )
Flavio Castrocc38a542016-03-03 13:15:46 -0800883 cellFile.write( onosGroup + "\n" )
884 cellFile.write( onosUser + "\n" )
Jon Hall9b0de1f2020-08-24 15:38:04 -0700885 cellFile.write( onosWebUser + "\n" )
886 cellFile.write( onosWebPass + "\n" )
Pier88189b62016-09-07 17:01:53 -0700887 if useSSH:
888 cellFile.write( onosUseSSH + "\n" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800889 cellFile.close()
andrewonlab94282092014-10-10 13:00:11 -0400890
kelvin8ec71442015-01-15 16:57:00 -0800891 # We use os.system to send the command to TestON cluster
892 # to account for the case in which TestON is not located
893 # on the same cluster as the ONOS bench
894 # Note that even if TestON is located on the same cluster
895 # as ONOS bench, you must setup passwordless ssh
896 # between TestON and ONOS bench in order to automate the test.
kelvin-onlabc2b79102015-07-14 11:41:20 -0700897 os.system( "scp " + tempDirectory + fileName + " " +
898 self.user_name + "@" + self.ip_address + ":" + cellDirectory )
andrewonlab94282092014-10-10 13:00:11 -0400899
andrewonlab2a6c9342014-10-16 13:40:15 -0400900 return main.TRUE
901
andrewonlab94282092014-10-10 13:00:11 -0400902 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800903 main.log.error( self.name + ": EOF exception found" )
904 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700905 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800906 except Exception:
907 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700908 main.cleanAndExit()
andrewonlab94282092014-10-10 13:00:11 -0400909
kelvin-onlabd3b64892015-01-20 13:26:24 -0800910 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800911 """
andrewonlab95ca1462014-10-09 14:04:24 -0400912 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800913 """
andrewonlab95ca1462014-10-09 14:04:24 -0400914 try:
915 if not cellname:
You Wang1cdc5f52017-12-19 16:47:51 -0800916 main.log.error( self.name + ": Must define cellname" )
Devin Lim44075962017-08-11 10:56:37 -0700917 main.cleanAndExit()
andrewonlab95ca1462014-10-09 14:04:24 -0400918 else:
kelvin8ec71442015-01-15 16:57:00 -0800919 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800920 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800921 # Note that this variable name is subject to change
andrewonlab95ca1462014-10-09 14:04:24 -0400922 # and that this driver will have to change accordingly
Jon Hall3b489db2015-10-05 14:38:37 -0700923 self.handle.expect( str( cellname ) )
Jon Hallab611372018-02-21 15:26:05 -0800924 response = self.handle.before + self.handle.after
You Wang1cdc5f52017-12-19 16:47:51 -0800925 i = self.handle.expect( [ "No such cell",
Jon Hallab611372018-02-21 15:26:05 -0800926 "command not found",
927 self.prompt ], timeout=10 )
928 response += self.handle.before + self.handle.after
You Wang1cdc5f52017-12-19 16:47:51 -0800929 if i == 0:
Jon Hallab611372018-02-21 15:26:05 -0800930 main.log.error( self.name + ": No such cell. Response: " + str( response ) )
You Wang1cdc5f52017-12-19 16:47:51 -0800931 main.cleanAndExit()
932 elif i == 1:
Jon Hallab611372018-02-21 15:26:05 -0800933 main.log.error( self.name + ": Error setting cell. Response: " + str( response ) )
934 main.cleanAndExit()
You Wang1cdc5f52017-12-19 16:47:51 -0800935 elif i == 2:
Jon Hallab611372018-02-21 15:26:05 -0800936 main.log.info( self.name + ": Successfully set cell: " + str( response ) )
andrewonlab95ca1462014-10-09 14:04:24 -0400937 return main.TRUE
You Wang1cdc5f52017-12-19 16:47:51 -0800938 except pexpect.TIMEOUT:
939 main.log.error( self.name + ": TIMEOUT exception found" )
940 main.log.error( self.name + ": " + self.handle.before )
941 main.cleanAndExit()
andrewonlab95ca1462014-10-09 14:04:24 -0400942 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800943 main.log.error( self.name + ": EOF exception found" )
944 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700945 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800946 except Exception:
947 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700948 main.cleanAndExit()
andrewonlab95ca1462014-10-09 14:04:24 -0400949
kelvin-onlabd3b64892015-01-20 13:26:24 -0800950 def verifyCell( self ):
kelvin8ec71442015-01-15 16:57:00 -0800951 """
andrewonlabc03bf6c2014-10-09 14:56:18 -0400952 Calls 'onos-verify-cell' to check for cell installation
kelvin8ec71442015-01-15 16:57:00 -0800953 """
954 # TODO: Add meaningful expect value
andrewonlab8d0d7d72014-10-09 16:33:15 -0400955
andrewonlabc03bf6c2014-10-09 14:56:18 -0400956 try:
kelvin8ec71442015-01-15 16:57:00 -0800957 # Clean handle by sending empty and expecting $
958 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -0700959 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -0800960 self.handle.sendline( "onos-verify-cell" )
Devin Limc20e79a2017-06-07 10:29:57 -0700961 self.handle.expect( self.prompt )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800962 handleBefore = self.handle.before
963 handleAfter = self.handle.after
Jon Hall3c0114c2020-08-11 15:07:42 -0700964 main.log.info( self.name + ": Verify cell returned: " + handleBefore +
Jon Hall3b489db2015-10-05 14:38:37 -0700965 handleAfter )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400966 return main.TRUE
Jon Hall3e6edb32018-08-21 16:20:30 -0700967 except pexpect.ExceptionPexpect:
Jon Hall3b489db2015-10-05 14:38:37 -0700968 main.log.exception( self.name + ": Pexpect exception found: " )
kelvin8ec71442015-01-15 16:57:00 -0800969 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700970 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800971 except Exception:
972 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700973 main.cleanAndExit()
Jon Hall7993bfc2014-10-09 16:30:14 -0400974
jenkins1e99e7b2015-04-02 18:15:39 -0700975 def onosCfgSet( self, ONOSIp, configName, configParam ):
976 """
977 Uses 'onos <node-ip> cfg set' to change a parameter value of an
Jon Hall4ba53f02015-07-29 13:07:41 -0700978 application.
979
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000980 ex)
jenkins1e99e7b2015-04-02 18:15:39 -0700981 onos 10.0.0.1 cfg set org.onosproject.myapp appSetting 1
jenkins1e99e7b2015-04-02 18:15:39 -0700982 ONOSIp = '10.0.0.1'
983 configName = 'org.onosproject.myapp'
984 configParam = 'appSetting 1'
jenkins1e99e7b2015-04-02 18:15:39 -0700985 """
Jon Hall72280bc2016-01-25 14:29:05 -0800986 try:
987 cfgStr = "onos {} cfg set {} {}".format( ONOSIp,
988 configName,
989 configParam )
990 self.handle.sendline( "" )
991 self.handle.expect( ":~" )
992 self.handle.sendline( cfgStr )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700993 self.handle.expect( "cfg set" )
Jon Hall72280bc2016-01-25 14:29:05 -0800994 self.handle.expect( ":~" )
jenkins1e99e7b2015-04-02 18:15:39 -0700995
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700996 paramValue = configParam.split( " " )[ 1 ]
997 paramName = configParam.split( " " )[ 0 ]
Jon Hall4ba53f02015-07-29 13:07:41 -0700998
Jon Hall72280bc2016-01-25 14:29:05 -0800999 checkStr = 'onos {} cfg get " {} {} " '.format( ONOSIp, configName, paramName )
Jon Hall4ba53f02015-07-29 13:07:41 -07001000
Jon Hall72280bc2016-01-25 14:29:05 -08001001 self.handle.sendline( checkStr )
1002 self.handle.expect( ":~" )
jenkins1e99e7b2015-04-02 18:15:39 -07001003
Jon Hall72280bc2016-01-25 14:29:05 -08001004 if "value=" + paramValue + "," in self.handle.before:
Jon Hall3c0114c2020-08-11 15:07:42 -07001005 main.log.info( self.name + ": cfg " + configName + " successfully set to " + configParam )
Jon Hall72280bc2016-01-25 14:29:05 -08001006 return main.TRUE
Jon Hall3e6edb32018-08-21 16:20:30 -07001007 except pexpect.ExceptionPexpect:
Jon Hall72280bc2016-01-25 14:29:05 -08001008 main.log.exception( self.name + ": Pexpect exception found: " )
1009 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001010 main.cleanAndExit()
Jon Hall72280bc2016-01-25 14:29:05 -08001011 except Exception:
1012 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001013 main.cleanAndExit()
Jon Hall4ba53f02015-07-29 13:07:41 -07001014
Jon Hall06fd0df2021-01-25 15:50:06 -08001015 def onosCli( self, ONOSIp, cmdstr, cliPort=8101, waitForStart=False, timeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -08001016 """
andrewonlab05e362f2014-10-10 00:40:57 -04001017 Uses 'onos' command to send various ONOS CLI arguments.
1018 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001019 * ONOSIp: specify the ip of the cell machine
andrewonlab94282092014-10-10 13:00:11 -04001020 * cmdstr: specify the command string to send
You Wang54b1d672018-06-11 16:44:13 -07001021 Optional:
1022 * timeout: pexpect timeout for running the command
kelvin8ec71442015-01-15 16:57:00 -08001023
1024 This function is intended to expose the entire karaf
andrewonlab6e20c342014-10-10 18:08:48 -04001025 CLI commands for ONOS. Try to use this function first
1026 before attempting to write a ONOS CLI specific driver
kelvin8ec71442015-01-15 16:57:00 -08001027 function.
1028 You can see a list of available 'cmdstr' arguments
andrewonlab6e20c342014-10-10 18:08:48 -04001029 by starting onos, and typing in 'onos' to enter the
1030 onos> CLI. Then, type 'help' to see the list of
kelvin8ec71442015-01-15 16:57:00 -08001031 available commands.
1032 """
andrewonlab05e362f2014-10-10 00:40:57 -04001033 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001034 if not ONOSIp:
kelvin8ec71442015-01-15 16:57:00 -08001035 main.log.error( "You must specify the IP address" )
andrewonlab05e362f2014-10-10 00:40:57 -04001036 return main.FALSE
1037 if not cmdstr:
kelvin8ec71442015-01-15 16:57:00 -08001038 main.log.error( "You must specify the command string" )
andrewonlab05e362f2014-10-10 00:40:57 -04001039 return main.FALSE
1040
kelvin8ec71442015-01-15 16:57:00 -08001041 cmdstr = str( cmdstr )
1042 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001043 self.handle.expect( self.prompt )
andrewonlab05e362f2014-10-10 00:40:57 -04001044
Jon Hall06fd0df2021-01-25 15:50:06 -08001045 if waitForStart:
1046 self.handle.sendline( "onos-wait-for-start " + ONOSIp )
1047 i = self.handle.expect( [ self.prompt, "Password: " ] )
1048 if i == 1:
1049 self.handle.sendline( self.pwd )
1050 self.handle.expect( self.prompt )
1051 self.handle.sendline( "ssh -q -p %s -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null %s@%s %s " % ( cliPort, self.karafUser, ONOSIp, cmdstr ) )
Jon Hall3c0114c2020-08-11 15:07:42 -07001052 i = self.handle.expect( [ self.prompt, "Password: ", pexpect.TIMEOUT ], timeout=timeout )
1053 if i == 1:
Jon Hall06fd0df2021-01-25 15:50:06 -08001054 self.handle.sendline( self.karafPass )
1055 i = self.handle.expect( [ self.prompt, "Password:", pexpect.TIMEOUT ], timeout=timeout )
You Wang54b1d672018-06-11 16:44:13 -07001056 if i == 0:
1057 handleBefore = self.handle.before
Jon Hall3c0114c2020-08-11 15:07:42 -07001058 main.log.info( self.name + ": Command sent successfully" )
You Wang54b1d672018-06-11 16:44:13 -07001059 # Obtain return handle that consists of result from
1060 # the onos command. The string may need to be
1061 # configured further.
1062 returnString = handleBefore
1063 return returnString
1064 elif i == 1:
Jon Hall06fd0df2021-01-25 15:50:06 -08001065 main.log.error( self.name + ": Incorrect password for ONOS cli" )
1066 self.handle.send( "\x03" ) # Control-C
1067 self.handle.expect( self.prompt )
1068 return main.FALSE
1069 elif i == 2:
You Wang54b1d672018-06-11 16:44:13 -07001070 main.log.error( self.name + ": Timeout when sending " + cmdstr )
Jon Hall06fd0df2021-01-25 15:50:06 -08001071 main.log.debug( self.name + ": " + self.handle.before )
You Wang141b43b2018-06-26 16:50:18 -07001072 self.handle.send( "\x03" ) # Control-C
You Wang54b1d672018-06-11 16:44:13 -07001073 self.handle.expect( self.prompt )
1074 return main.FALSE
You Wangd66de192018-04-30 17:30:12 -07001075 except pexpect.TIMEOUT:
Jon Hall06fd0df2021-01-25 15:50:06 -08001076 main.log.debug( self.handle.before + str( self.handle.after ) )
You Wangd66de192018-04-30 17:30:12 -07001077 main.log.exception( self.name + ": Timeout when sending " + cmdstr )
1078 return main.FALSE
andrewonlab05e362f2014-10-10 00:40:57 -04001079 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001080 main.log.error( self.name + ": EOF exception found" )
1081 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001082 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001083 except Exception:
1084 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001085 main.cleanAndExit()
Jon Hall7993bfc2014-10-09 16:30:14 -04001086
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001087 def onosSecureSSH( self, userName="onos", userPWD="rocks", node="" ):
Pier88189b62016-09-07 17:01:53 -07001088 """
1089 Enables secure access to ONOS console
1090 by removing default users & keys.
1091
1092 onos-secure-ssh -u onos -p rocks node
1093
1094 Returns: main.TRUE on success and main.FALSE on failure
1095 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001096
Pier88189b62016-09-07 17:01:53 -07001097 try:
Chiyu Chengef109502016-11-21 15:51:38 -08001098 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001099 self.handle.expect( self.prompt )
Pier88189b62016-09-07 17:01:53 -07001100 self.handle.sendline( " onos-secure-ssh -u " + userName + " -p " + userPWD + " " + node )
1101
1102 # NOTE: this timeout may need to change depending on the network
1103 # and size of ONOS
1104 # TODO: Handle the other possible error
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001105 i = self.handle.expect( [ "Network\sis\sunreachable",
1106 self.prompt,
1107 pexpect.TIMEOUT ], timeout=180 )
Pier88189b62016-09-07 17:01:53 -07001108 if i == 0:
1109 # can't reach ONOS node
Jon Hall3e6edb32018-08-21 16:20:30 -07001110 main.log.warn( self.name + ": Network is unreachable" )
Devin Limc20e79a2017-06-07 10:29:57 -07001111 self.handle.expect( self.prompt )
Pier88189b62016-09-07 17:01:53 -07001112 return main.FALSE
1113 elif i == 1:
1114 # Process started
Jon Hall3e6edb32018-08-21 16:20:30 -07001115 main.log.info( self.name + ": Secure SSH performed on " + node )
Pier88189b62016-09-07 17:01:53 -07001116 return main.TRUE
Jon Hall3e6edb32018-08-21 16:20:30 -07001117 elif i == 2:
1118 # timeout
1119 main.log.error( self.name + ": Failed to secure ssh on " + node )
Jon Hall06fd0df2021-01-25 15:50:06 -08001120 main.log.debug( self.name + ": " + self.handle.before )
Pier88189b62016-09-07 17:01:53 -07001121 except pexpect.EOF:
1122 main.log.error( self.name + ": EOF exception found" )
1123 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001124 main.cleanAndExit()
Pier88189b62016-09-07 17:01:53 -07001125 except Exception:
1126 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001127 main.cleanAndExit()
Pier88189b62016-09-07 17:01:53 -07001128
kelvin-onlabd3b64892015-01-20 13:26:24 -08001129 def onosInstall( self, options="-f", node="" ):
kelvin8ec71442015-01-15 16:57:00 -08001130 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001131 Installs ONOS bits on the designated cell machine.
kelvin8ec71442015-01-15 16:57:00 -08001132 If -f option is provided, it also forces an uninstall.
1133 Presently, install also includes onos-push-bits and
Jon Hall7993bfc2014-10-09 16:30:14 -04001134 onos-config within.
kelvin8ec71442015-01-15 16:57:00 -08001135 The node option allows you to selectively only push the jar
Jon Hall7993bfc2014-10-09 16:30:14 -04001136 files to certain onos nodes
1137
1138 Returns: main.TRUE on success and main.FALSE on failure
kelvin8ec71442015-01-15 16:57:00 -08001139 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001140 try:
andrewonlab114768a2014-11-14 12:44:44 -05001141 if options:
kelvin8ec71442015-01-15 16:57:00 -08001142 self.handle.sendline( "onos-install " + options + " " + node )
andrewonlab114768a2014-11-14 12:44:44 -05001143 else:
kelvin8ec71442015-01-15 16:57:00 -08001144 self.handle.sendline( "onos-install " + node )
1145 self.handle.expect( "onos-install " )
1146 # NOTE: this timeout may need to change depending on the network
1147 # and size of ONOS
1148 i = self.handle.expect( [ "Network\sis\sunreachable",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001149 "onos\sstart/running,\sprocess",
kelvin8ec71442015-01-15 16:57:00 -08001150 "ONOS\sis\salready\sinstalled",
Jon Hall3576f572016-08-23 10:01:07 -07001151 "does not exist",
Jon Hall23bbe852021-03-26 10:47:23 -07001152 "Failed to start",
Devin Limc20e79a2017-06-07 10:29:57 -07001153 self.prompt,
Jon Hall6c44c0b2016-04-20 15:21:00 -07001154 pexpect.TIMEOUT ], timeout=180 )
Jon Hall7993bfc2014-10-09 16:30:14 -04001155 if i == 0:
Jon Hall3576f572016-08-23 10:01:07 -07001156 # can't reach ONOS node
kelvin8ec71442015-01-15 16:57:00 -08001157 main.log.warn( "Network is unreachable" )
Devin Limc20e79a2017-06-07 10:29:57 -07001158 self.handle.expect( self.prompt )
Jon Hall7993bfc2014-10-09 16:30:14 -04001159 return main.FALSE
1160 elif i == 1:
Jon Hall3576f572016-08-23 10:01:07 -07001161 # Process started
kelvin8ec71442015-01-15 16:57:00 -08001162 main.log.info(
1163 "ONOS was installed on " +
1164 node +
1165 " and started" )
Devin Limc20e79a2017-06-07 10:29:57 -07001166 self.handle.expect( self.prompt )
Jon Hall7993bfc2014-10-09 16:30:14 -04001167 return main.TRUE
You Wangd65ba842018-08-14 11:20:59 -07001168 elif i == 2:
Jon Hall3576f572016-08-23 10:01:07 -07001169 # same bits are already on ONOS node
Jon Hall3c0114c2020-08-11 15:07:42 -07001170 main.log.info( self.name + ": ONOS is already installed on " + node )
Devin Limc20e79a2017-06-07 10:29:57 -07001171 self.handle.expect( self.prompt )
Jeremyc72b2582016-02-26 18:27:38 -08001172 return main.TRUE
You Wangd65ba842018-08-14 11:20:59 -07001173 elif i == 3:
Jon Hall3576f572016-08-23 10:01:07 -07001174 # onos not packaged
1175 main.log.error( "ONOS package not found." )
Devin Limc20e79a2017-06-07 10:29:57 -07001176 self.handle.expect( self.prompt )
Jon Hall3576f572016-08-23 10:01:07 -07001177 return main.FALSE
You Wangd65ba842018-08-14 11:20:59 -07001178 elif i == 4:
Jon Hall23bbe852021-03-26 10:47:23 -07001179 # Service failed to start
1180 main.log.error( "ONOS service failed to start" )
1181 self.handle.expect( self.prompt )
1182 return main.FALSE
1183 elif i == 5:
Jon Hall3576f572016-08-23 10:01:07 -07001184 # prompt
Jon Hall3c0114c2020-08-11 15:07:42 -07001185 main.log.info( self.name + ": ONOS was installed on {} {}.".format( node,
Jon Hall3e6edb32018-08-21 16:20:30 -07001186 "but not started" if 'n' in options else "and started" ) )
Jeremyc72b2582016-02-26 18:27:38 -08001187 return main.TRUE
Jon Hall23bbe852021-03-26 10:47:23 -07001188 elif i == 6:
Jon Hall3576f572016-08-23 10:01:07 -07001189 # timeout
kelvin8ec71442015-01-15 16:57:00 -08001190 main.log.info(
1191 "Installation of ONOS on " +
1192 node +
1193 " timed out" )
Devin Limc20e79a2017-06-07 10:29:57 -07001194 self.handle.expect( self.prompt )
Jon Hall53c5e662016-04-13 16:06:56 -07001195 main.log.warn( self.handle.before )
You Wang141b43b2018-06-26 16:50:18 -07001196 self.handle.send( "\x03" ) # Control-C
1197 self.handle.expect( self.prompt )
Jon Hall7993bfc2014-10-09 16:30:14 -04001198 return main.FALSE
andrewonlabc03bf6c2014-10-09 14:56:18 -04001199 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001200 main.log.error( self.name + ": EOF exception found" )
1201 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001202 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001203 except Exception:
1204 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001205 main.cleanAndExit()
andrewonlab95ca1462014-10-09 14:04:24 -04001206
kelvin-onlabd3b64892015-01-20 13:26:24 -08001207 def onosStart( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001208 """
andrewonlab8d0d7d72014-10-09 16:33:15 -04001209 Calls onos command: 'onos-service [<node-ip>] start'
andrewonlabe8e56fd2014-10-09 17:12:44 -04001210 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -08001211 """
andrewonlab8d0d7d72014-10-09 16:33:15 -04001212 try:
kelvin8ec71442015-01-15 16:57:00 -08001213 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001214 self.handle.expect( self.prompt )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001215 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001216 " start" )
1217 i = self.handle.expect( [
andrewonlab8d0d7d72014-10-09 16:33:15 -04001218 "Job\sis\salready\srunning",
1219 "start/running",
Devin Limc20e79a2017-06-07 10:29:57 -07001220 self.prompt,
andrewonlab8d0d7d72014-10-09 16:33:15 -04001221 "Unknown\sinstance",
Jeremy Songster14c13572016-04-21 17:34:03 -07001222 pexpect.TIMEOUT ], timeout=180 )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001223 if i == 0:
Devin Limc20e79a2017-06-07 10:29:57 -07001224 self.handle.expect( self.prompt )
Jon Hall3c0114c2020-08-11 15:07:42 -07001225 main.log.info( self.name + ": Service is already running" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001226 return main.TRUE
1227 elif i == 1:
Devin Limc20e79a2017-06-07 10:29:57 -07001228 self.handle.expect( self.prompt )
Jon Hall3c0114c2020-08-11 15:07:42 -07001229 main.log.info( self.name + ": ONOS service started" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001230 return main.TRUE
Jeremyd0e9a6d2016-03-02 11:28:52 -08001231 elif i == 2:
Jon Hall3c0114c2020-08-11 15:07:42 -07001232 main.log.info( self.name + ": ONOS service started" )
Jeremyd0e9a6d2016-03-02 11:28:52 -08001233 return main.TRUE
andrewonlab8d0d7d72014-10-09 16:33:15 -04001234 else:
Devin Limc20e79a2017-06-07 10:29:57 -07001235 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -08001236 main.log.error( "ONOS service failed to start" )
Devin Lim44075962017-08-11 10:56:37 -07001237
1238 main.cleanAndExit()
andrewonlab8d0d7d72014-10-09 16:33:15 -04001239 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001240 main.log.error( self.name + ": EOF exception found" )
1241 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001242 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001243 except Exception:
1244 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001245 main.cleanAndExit()
andrewonlab8d0d7d72014-10-09 16:33:15 -04001246
kelvin-onlabd3b64892015-01-20 13:26:24 -08001247 def onosStop( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001248 """
andrewonlab2b30bd32014-10-09 16:48:55 -04001249 Calls onos command: 'onos-service [<node-ip>] stop'
andrewonlabe8e56fd2014-10-09 17:12:44 -04001250 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -08001251 """
andrewonlab2b30bd32014-10-09 16:48:55 -04001252 try:
kelvin8ec71442015-01-15 16:57:00 -08001253 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001254 self.handle.expect( self.prompt )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001255 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001256 " stop" )
1257 i = self.handle.expect( [
andrewonlab2b30bd32014-10-09 16:48:55 -04001258 "stop/waiting",
Jon Hall61282e32015-03-19 11:34:11 -07001259 "Could not resolve hostname",
andrewonlab2b30bd32014-10-09 16:48:55 -04001260 "Unknown\sinstance",
Devin Limc20e79a2017-06-07 10:29:57 -07001261 self.prompt,
Jeremy Songster14c13572016-04-21 17:34:03 -07001262 pexpect.TIMEOUT ], timeout=180 )
andrewonlab2b30bd32014-10-09 16:48:55 -04001263 if i == 0:
Devin Limc20e79a2017-06-07 10:29:57 -07001264 self.handle.expect( self.prompt )
Jon Hall3c0114c2020-08-11 15:07:42 -07001265 main.log.info( self.name + ": ONOS service stopped" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001266 return main.TRUE
1267 elif i == 1:
Devin Limc20e79a2017-06-07 10:29:57 -07001268 self.handle.expect( self.prompt )
Jon Hall3c0114c2020-08-11 15:07:42 -07001269 main.log.info( self.name + ": onosStop() Unknown ONOS instance specified: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001270 str( nodeIp ) )
andrewonlab2b30bd32014-10-09 16:48:55 -04001271 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -07001272 elif i == 2:
Devin Limc20e79a2017-06-07 10:29:57 -07001273 self.handle.expect( self.prompt )
Jon Hall61282e32015-03-19 11:34:11 -07001274 main.log.warn( "ONOS wasn't running" )
1275 return main.TRUE
YPZhang77badfc2016-03-09 10:28:59 -08001276 elif i == 3:
Jon Hall3c0114c2020-08-11 15:07:42 -07001277 main.log.info( self.name + ": ONOS service stopped" )
YPZhang77badfc2016-03-09 10:28:59 -08001278 return main.TRUE
andrewonlab2b30bd32014-10-09 16:48:55 -04001279 else:
kelvin8ec71442015-01-15 16:57:00 -08001280 main.log.error( "ONOS service failed to stop" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001281 return main.FALSE
andrewonlab2b30bd32014-10-09 16:48:55 -04001282 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001283 main.log.error( self.name + ": EOF exception found" )
1284 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001285 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001286 except Exception:
1287 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001288 main.cleanAndExit()
kelvin8ec71442015-01-15 16:57:00 -08001289
kelvin-onlabd3b64892015-01-20 13:26:24 -08001290 def onosUninstall( self, nodeIp="" ):
kelvin8ec71442015-01-15 16:57:00 -08001291 """
andrewonlabc8d47972014-10-09 16:52:36 -04001292 Calls the command: 'onos-uninstall'
kelvin8ec71442015-01-15 16:57:00 -08001293 Uninstalls ONOS from the designated cell machine, stopping
andrewonlabe8e56fd2014-10-09 17:12:44 -04001294 if needed
kelvin8ec71442015-01-15 16:57:00 -08001295 """
andrewonlabc8d47972014-10-09 16:52:36 -04001296 try:
kelvin8ec71442015-01-15 16:57:00 -08001297 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001298 self.handle.expect( self.prompt, timeout=180 )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001299 self.handle.sendline( "onos-uninstall " + str( nodeIp ) )
Devin Limc20e79a2017-06-07 10:29:57 -07001300 self.handle.expect( self.prompt, timeout=180 )
Jon Hall3c0114c2020-08-11 15:07:42 -07001301 main.log.info( self.name + ": ONOS " + nodeIp + " was uninstalled" )
kelvin8ec71442015-01-15 16:57:00 -08001302 # onos-uninstall command does not return any text
andrewonlabc8d47972014-10-09 16:52:36 -04001303 return main.TRUE
pingping-lin763ee042015-05-20 17:45:30 -07001304 except pexpect.TIMEOUT:
1305 main.log.exception( self.name + ": Timeout in onosUninstall" )
You Wang141b43b2018-06-26 16:50:18 -07001306 self.handle.send( "\x03" ) # Control-C
1307 self.handle.expect( self.prompt )
pingping-lin763ee042015-05-20 17:45:30 -07001308 return main.FALSE
andrewonlabc8d47972014-10-09 16:52:36 -04001309 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001310 main.log.error( self.name + ": EOF exception found" )
1311 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001312 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001313 except Exception:
1314 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001315 main.cleanAndExit()
andrewonlab2b30bd32014-10-09 16:48:55 -04001316
kelvin-onlabd3b64892015-01-20 13:26:24 -08001317 def onosDie( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001318 """
andrewonlabaedc8332014-12-04 12:43:03 -05001319 Issues the command 'onos-die <node-ip>'
1320 This command calls onos-kill and also stops the node
kelvin8ec71442015-01-15 16:57:00 -08001321 """
andrewonlabaedc8332014-12-04 12:43:03 -05001322 try:
kelvin8ec71442015-01-15 16:57:00 -08001323 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001324 self.handle.expect( self.prompt )
Jon Hall214f88b2020-09-21 10:21:42 -07001325 if self.inDocker:
1326 return self.dockerStop( self.name )
1327 else:
1328 cmdStr = "onos-die " + str( nodeIp )
1329 self.handle.sendline( cmdStr )
1330 i = self.handle.expect( [
1331 "Killing\sONOS",
1332 "ONOS\sprocess\sis\snot\srunning",
1333 pexpect.TIMEOUT ], timeout=60 )
1334 if i == 0:
1335 main.log.info( self.name + ": ONOS instance " + str( nodeIp ) +
1336 " was killed and stopped" )
1337 self.handle.sendline( "" )
1338 self.handle.expect( self.prompt )
1339 return main.TRUE
1340 elif i == 1:
1341 main.log.info( self.name + ": ONOS process was not running" )
1342 self.handle.sendline( "" )
1343 self.handle.expect( self.prompt )
1344 return main.FALSE
andrewonlabaedc8332014-12-04 12:43:03 -05001345 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001346 main.log.error( self.name + ": EOF exception found" )
1347 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001348 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001349 except Exception:
1350 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001351 main.cleanAndExit()
andrewonlabaedc8332014-12-04 12:43:03 -05001352
kelvin-onlabd3b64892015-01-20 13:26:24 -08001353 def onosKill( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001354 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001355 Calls the command: 'onos-kill [<node-ip>]'
1356 "Remotely, and unceremoniously kills the ONOS instance running on
1357 the specified cell machine" - Tom V
kelvin8ec71442015-01-15 16:57:00 -08001358 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001359 try:
kelvin8ec71442015-01-15 16:57:00 -08001360 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001361 self.handle.expect( self.prompt )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001362 self.handle.sendline( "onos-kill " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -08001363 i = self.handle.expect( [
Devin Limc20e79a2017-06-07 10:29:57 -07001364 self.prompt,
andrewonlabe8e56fd2014-10-09 17:12:44 -04001365 "No\sroute\sto\shost",
1366 "password:",
Jeremy Songster14c13572016-04-21 17:34:03 -07001367 pexpect.TIMEOUT ], timeout=60 )
kelvin8ec71442015-01-15 16:57:00 -08001368
andrewonlabe8e56fd2014-10-09 17:12:44 -04001369 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001370 main.log.info(
1371 "ONOS instance " + str(
kelvin-onlabd3b64892015-01-20 13:26:24 -08001372 nodeIp ) + " was killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001373 return main.TRUE
1374 elif i == 1:
Jon Hall3c0114c2020-08-11 15:07:42 -07001375 main.log.info( self.name + ": No route to host" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001376 return main.FALSE
1377 elif i == 2:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001378 main.log.info(
1379 "Passwordless login for host: " +
1380 str( nodeIp ) +
1381 " not configured" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001382 return main.FALSE
1383 else:
Jon Hall3c0114c2020-08-11 15:07:42 -07001384 main.log.info( self.name + ": ONOS instance was not killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001385 return main.FALSE
kelvin8ec71442015-01-15 16:57:00 -08001386
andrewonlabe8e56fd2014-10-09 17:12:44 -04001387 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001388 main.log.error( self.name + ": EOF exception found" )
1389 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001390 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001391 except Exception:
1392 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001393 main.cleanAndExit()
andrewonlabe8e56fd2014-10-09 17:12:44 -04001394
You Wang5bf49592020-07-08 18:47:46 -07001395 def onosAppInstall( self, nodeIp, oarFile ):
1396 """
Jon Hall3c0114c2020-08-11 15:07:42 -07001397 Calls the command: 'onos-app nodeIp reinstall! oarFile'
You Wang5bf49592020-07-08 18:47:46 -07001398 Installs an ONOS application from an oar file
1399 """
1400 try:
Jon Hall3c0114c2020-08-11 15:07:42 -07001401 cmd = "onos-app " + str( nodeIp ) + " reinstall! " + str( oarFile )
You Wang5bf49592020-07-08 18:47:46 -07001402 self.handle.sendline( cmd )
Jon Hall3c0114c2020-08-11 15:07:42 -07001403 i = self.handle.expect( [ "409 Conflict", self.prompt ] )
1404 if i == 0:
1405 self.handle.expect( self.prompt )
1406 time.sleep( 30 )
1407 self.handle.sendline( cmd )
You Wang5bf49592020-07-08 18:47:46 -07001408 handle = self.handle.before
Jon Hall3c0114c2020-08-11 15:07:42 -07001409 main.log.debug( "%s: %s" % ( self.name, handle ) )
You Wang5bf49592020-07-08 18:47:46 -07001410 assert handle is not None, "Error in sendline"
1411 assert "Command not found:" not in handle, handle
1412 assert "error" not in handle, handle
1413 assert "usage:" not in handle, handle
1414 return main.TRUE
1415 except AssertionError:
1416 main.log.exception( "Error in onos-app output" )
1417 return main.FALSE
1418 except pexpect.TIMEOUT:
1419 main.log.exception( self.name + ": Timeout in onosAppInstall" )
1420 self.handle.send( "\x03" ) # Control-C
1421 self.handle.expect( self.prompt )
1422 return main.FALSE
1423 except pexpect.EOF:
1424 main.log.error( self.name + ": EOF exception found" )
1425 main.log.error( self.name + ": " + self.handle.before )
1426 main.cleanAndExit()
1427 except Exception:
1428 main.log.exception( self.name + ": Uncaught exception!" )
1429 main.cleanAndExit()
1430
kelvin-onlabd3b64892015-01-20 13:26:24 -08001431 def onosRemoveRaftLogs( self ):
kelvin8ec71442015-01-15 16:57:00 -08001432 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001433 Removes Raft / Copy cat files from ONOS to ensure
Jon Hallfcc88622014-11-25 13:09:54 -05001434 a cleaner environment.
1435
andrewonlab19fbdca2014-11-14 12:55:59 -05001436 Description:
Jon Hallfcc88622014-11-25 13:09:54 -05001437 Stops all ONOS defined in the cell,
andrewonlab19fbdca2014-11-14 12:55:59 -05001438 wipes the raft / copycat log files
kelvin8ec71442015-01-15 16:57:00 -08001439 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001440 try:
kelvin8ec71442015-01-15 16:57:00 -08001441 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001442 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -08001443 self.handle.sendline( "onos-remove-raft-logs" )
1444 # Sometimes this command hangs
Devin Limc20e79a2017-06-07 10:29:57 -07001445 i = self.handle.expect( [ self.prompt, pexpect.TIMEOUT ],
kelvin8ec71442015-01-15 16:57:00 -08001446 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001447 if i == 1:
Devin Limc20e79a2017-06-07 10:29:57 -07001448 i = self.handle.expect( [ self.prompt, pexpect.TIMEOUT ],
kelvin8ec71442015-01-15 16:57:00 -08001449 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001450 if i == 1:
1451 return main.FALSE
andrewonlab19fbdca2014-11-14 12:55:59 -05001452 return main.TRUE
andrewonlab19fbdca2014-11-14 12:55:59 -05001453 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001454 main.log.error( self.name + ": EOF exception found" )
1455 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001456 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001457 except Exception:
1458 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001459 main.cleanAndExit()
Jon Hallfcc88622014-11-25 13:09:54 -05001460
kelvin-onlabd3b64892015-01-20 13:26:24 -08001461 def onosStartNetwork( self, mntopo ):
kelvin8ec71442015-01-15 16:57:00 -08001462 """
1463 Calls the command 'onos-start-network [ <mininet-topo> ]
1464 "remotely starts the specified topology on the cell's
andrewonlab94282092014-10-10 13:00:11 -04001465 mininet machine against all controllers configured in the
kelvin8ec71442015-01-15 16:57:00 -08001466 cell."
andrewonlab94282092014-10-10 13:00:11 -04001467 * Specify mininet topology file name for mntopo
1468 * Topo files should be placed at:
1469 ~/<your-onos-directory>/tools/test/topos
kelvin8ec71442015-01-15 16:57:00 -08001470
andrewonlab94282092014-10-10 13:00:11 -04001471 NOTE: This function will take you to the mininet prompt
kelvin8ec71442015-01-15 16:57:00 -08001472 """
andrewonlab94282092014-10-10 13:00:11 -04001473 try:
1474 if not mntopo:
kelvin8ec71442015-01-15 16:57:00 -08001475 main.log.error( "You must specify a topo file to execute" )
andrewonlab94282092014-10-10 13:00:11 -04001476 return main.FALSE
andrewonlab94282092014-10-10 13:00:11 -04001477
kelvin8ec71442015-01-15 16:57:00 -08001478 mntopo = str( mntopo )
1479 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001480 self.handle.expect( self.prompt )
andrewonlab94282092014-10-10 13:00:11 -04001481
kelvin8ec71442015-01-15 16:57:00 -08001482 self.handle.sendline( "onos-start-network " + mntopo )
1483 self.handle.expect( "mininet>" )
Jon Hall3c0114c2020-08-11 15:07:42 -07001484 main.log.info( self.name + ": Network started, entered mininet prompt" )
kelvin8ec71442015-01-15 16:57:00 -08001485
1486 # TODO: Think about whether return is necessary or not
andrewonlab94282092014-10-10 13:00:11 -04001487
1488 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001489 main.log.error( self.name + ": EOF exception found" )
1490 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001491 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001492 except Exception:
1493 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001494 main.cleanAndExit()
andrewonlab94282092014-10-10 13:00:11 -04001495
Jeremy Songster14c13572016-04-21 17:34:03 -07001496 def isup( self, node="", timeout=240 ):
kelvin8ec71442015-01-15 16:57:00 -08001497 """
1498 Run's onos-wait-for-start which only returns once ONOS is at run
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001499 level 100(ready for use)
andrewonlab8d0d7d72014-10-09 16:33:15 -04001500
Jon Hall7993bfc2014-10-09 16:30:14 -04001501 Returns: main.TRUE if ONOS is running and main.FALSE on timeout
kelvin8ec71442015-01-15 16:57:00 -08001502 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001503 try:
Jon Hall3b489db2015-10-05 14:38:37 -07001504 self.handle.sendline( "onos-wait-for-start " + node )
1505 self.handle.expect( "onos-wait-for-start" )
kelvin8ec71442015-01-15 16:57:00 -08001506 # NOTE: this timeout is arbitrary"
Jon Hallcababf72018-02-05 12:05:19 -08001507 i = self.handle.expect( [ self.prompt, pexpect.TIMEOUT, "Password:" ], timeout )
Jon Hall7993bfc2014-10-09 16:30:14 -04001508 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001509 main.log.info( self.name + ": " + node + " is up" )
You Wangb65f2e92018-12-21 11:31:34 -08001510 # FIXME: for now we sleep 5s for CLI to become ready
1511 time.sleep( 5 )
Jon Hall7993bfc2014-10-09 16:30:14 -04001512 return main.TRUE
Jon Hallcababf72018-02-05 12:05:19 -08001513 elif i == 1 or i == 2:
kelvin8ec71442015-01-15 16:57:00 -08001514 # NOTE: since this function won't return until ONOS is ready,
Jon Hall7993bfc2014-10-09 16:30:14 -04001515 # we will kill it on timeout
Jon Hallcababf72018-02-05 12:05:19 -08001516 if i == 1:
Jon Hall3e6edb32018-08-21 16:20:30 -07001517 main.log.error( "{}: ONOS {} has not started yet".format( self.name, node ) )
Jon Hallcababf72018-02-05 12:05:19 -08001518 elif i == 2:
Jon Hall3e6edb32018-08-21 16:20:30 -07001519 main.log.error( "{}: Cannot login to ONOS CLI {}, try using onos-secure-ssh".format( self.name, node ) )
kelvin8ec71442015-01-15 16:57:00 -08001520 self.handle.send( "\x03" ) # Control-C
Devin Limc20e79a2017-06-07 10:29:57 -07001521 self.handle.expect( self.prompt )
Jon Hall7993bfc2014-10-09 16:30:14 -04001522 return main.FALSE
1523 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001524 main.log.error( self.name + ": EOF exception found" )
1525 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001526 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001527 except Exception:
1528 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001529 main.cleanAndExit()
andrewonlab05e362f2014-10-10 00:40:57 -04001530
Devin Lim142b5342017-07-20 15:22:39 -07001531 def preventAutoRespawn( self ):
1532 """
1533 Description:
1534 This will prevent ONOSservice to automatically
1535 respawn.
1536 """
1537 try:
1538 self.handle.sendline( "sed -i -e 's/^respawn$/#respawn/g' tools/package/init/onos.conf" )
1539 self.handle.expect( "\$" ) # $ from the command
1540 self.handle.sendline( "sed -i -e 's/^Restart=always/Restart=no/g' tools/package/init/onos.service" )
1541 self.handle.expect( "\$" ) # $ from the command
1542 self.handle.expect( "\$" ) # $ from the prompt
1543 except pexpect.EOF:
1544 main.log.error( self.name + ": EOF exception found" )
1545 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001546 main.cleanAndExit()
Devin Lim142b5342017-07-20 15:22:39 -07001547 except Exception:
1548 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001549 main.cleanAndExit()
Devin Lim142b5342017-07-20 15:22:39 -07001550
kelvin-onlabd3b64892015-01-20 13:26:24 -08001551 def pushTestIntentsShell(
1552 self,
1553 dpidSrc,
1554 dpidDst,
1555 numIntents,
1556 dirFile,
1557 onosIp,
1558 numMult="",
1559 appId="",
1560 report=True,
1561 options="" ):
kelvin8ec71442015-01-15 16:57:00 -08001562 """
andrewonlabb66dfa12014-12-02 15:51:10 -05001563 Description:
kelvin8ec71442015-01-15 16:57:00 -08001564 Use the linux prompt to push test intents to
andrewonlabb66dfa12014-12-02 15:51:10 -05001565 better parallelize the results than the CLI
1566 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001567 * dpidSrc: specify source dpid
1568 * dpidDst: specify destination dpid
1569 * numIntents: specify number of intents to push
1570 * dirFile: specify directory and file name to save
andrewonlabb66dfa12014-12-02 15:51:10 -05001571 results
kelvin-onlabd3b64892015-01-20 13:26:24 -08001572 * onosIp: specify the IP of ONOS to install on
kelvin8ec71442015-01-15 16:57:00 -08001573 NOTE:
andrewonlabb66dfa12014-12-02 15:51:10 -05001574 You must invoke this command at linux shell prompt
kelvin8ec71442015-01-15 16:57:00 -08001575 """
1576 try:
1577 # Create the string to sendline
andrewonlabaedc8332014-12-04 12:43:03 -05001578 if options:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001579 baseCmd = "onos " + str( onosIp ) + " push-test-intents " +\
kelvin8ec71442015-01-15 16:57:00 -08001580 options + " "
andrewonlabaedc8332014-12-04 12:43:03 -05001581 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001582 baseCmd = "onos " + str( onosIp ) + " push-test-intents "
kelvin8ec71442015-01-15 16:57:00 -08001583
kelvin-onlabd3b64892015-01-20 13:26:24 -08001584 addDpid = baseCmd + str( dpidSrc ) + " " + str( dpidDst )
1585 if not numMult:
1586 addIntents = addDpid + " " + str( numIntents )
1587 elif numMult:
1588 addIntents = addDpid + " " + str( numIntents ) + " " +\
1589 str( numMult )
1590 if appId:
1591 addApp = addIntents + " " + str( appId )
andrewonlabb66dfa12014-12-02 15:51:10 -05001592 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001593 addApp = addIntents
andrewonlabb66dfa12014-12-02 15:51:10 -05001594
andrewonlabaedc8332014-12-04 12:43:03 -05001595 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001596 sendCmd = addApp + " > " + str( dirFile ) + " &"
andrewonlabaedc8332014-12-04 12:43:03 -05001597 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001598 sendCmd = addApp + " &"
Jon Hall3c0114c2020-08-11 15:07:42 -07001599 main.log.info( self.name + ": Send cmd: " + sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001600
kelvin-onlabd3b64892015-01-20 13:26:24 -08001601 self.handle.sendline( sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001602
1603 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001604 main.log.error( self.name + ": EOF exception found" )
1605 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001606 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001607 except Exception:
1608 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001609 main.cleanAndExit()
andrewonlab05e362f2014-10-10 00:40:57 -04001610
kelvin-onlabd3b64892015-01-20 13:26:24 -08001611 def tsharkPcap( self, interface, dirFile ):
kelvin8ec71442015-01-15 16:57:00 -08001612 """
andrewonlab970399c2014-11-07 13:09:32 -05001613 Capture all packet activity and store in specified
1614 directory/file
1615
1616 Required:
1617 * interface: interface to capture
1618 * dir: directory/filename to store pcap
kelvin8ec71442015-01-15 16:57:00 -08001619 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001620 try:
1621 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001622 self.handle.expect( self.prompt )
andrewonlab970399c2014-11-07 13:09:32 -05001623
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001624 self.handle.sendline( "tshark -i " + str( interface ) + " -t e -w " + str( dirFile ) + " &" )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001625 self.handle.sendline( "\n" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001626 self.handle.expect( "Capturing on" )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001627 self.handle.sendline( "\n" )
Devin Limc20e79a2017-06-07 10:29:57 -07001628 self.handle.expect( self.prompt )
andrewonlab970399c2014-11-07 13:09:32 -05001629
Jon Hall3c0114c2020-08-11 15:07:42 -07001630 main.log.info( self.name + ": Tshark started capturing files on " +
Jon Hallfebb1c72015-03-05 13:30:09 -08001631 str( interface ) + " and saving to directory: " +
1632 str( dirFile ) )
1633 except pexpect.EOF:
1634 main.log.error( self.name + ": EOF exception found" )
1635 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001636 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001637 except Exception:
1638 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001639 main.cleanAndExit()
Shreya Shaha73aaad2014-10-27 18:03:09 -04001640
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001641 def onosTopoCfg( self, onosIp, jsonFile ):
kelvin8ec71442015-01-15 16:57:00 -08001642 """
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001643 Description:
1644 Execute onos-topo-cfg command
1645 Required:
1646 onosIp - IP of the onos node you want to send the json to
1647 jsonFile - File path of the json file
1648 Return:
1649 Returns main.TRUE if the command is successfull; Returns
1650 main.FALSE if there was an error
kelvin8ec71442015-01-15 16:57:00 -08001651 """
shahshreyae6c7cf42014-11-26 16:39:01 -08001652 try:
kelvin8ec71442015-01-15 16:57:00 -08001653 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001654 self.handle.expect( self.prompt )
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001655 cmd = "onos-topo-cfg "
1656 self.handle.sendline( cmd + str( onosIp ) + " " + jsonFile )
1657 handle = self.handle.before
1658 print handle
1659 if "Error" in handle:
1660 main.log.error( self.name + ": " + self.handle.before )
1661 return main.FALSE
1662 else:
Devin Limc20e79a2017-06-07 10:29:57 -07001663 self.handle.expect( self.prompt )
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001664 return main.TRUE
1665
Jon Hallfebb1c72015-03-05 13:30:09 -08001666 except pexpect.EOF:
1667 main.log.error( self.name + ": EOF exception found" )
1668 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001669 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001670 except Exception:
1671 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001672 main.cleanAndExit()
kelvin8ec71442015-01-15 16:57:00 -08001673
jenkins1e99e7b2015-04-02 18:15:39 -07001674 def tsharkGrep( self, grep, directory, interface='eth0', grepOptions='' ):
kelvin8ec71442015-01-15 16:57:00 -08001675 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001676 Required:
kelvin8ec71442015-01-15 16:57:00 -08001677 * grep string
andrewonlabba44bcf2014-10-16 16:54:41 -04001678 * directory to store results
1679 Optional:
1680 * interface - default: eth0
Jon Hall4ba53f02015-07-29 13:07:41 -07001681 * grepOptions - options for grep
andrewonlabba44bcf2014-10-16 16:54:41 -04001682 Description:
1683 Uses tshark command to grep specific group of packets
1684 and stores the results to specified directory.
kelvin8ec71442015-01-15 16:57:00 -08001685 The timestamp is hardcoded to be in epoch
1686 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001687 try:
1688 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001689 self.handle.expect( self.prompt )
Jon Hallfebb1c72015-03-05 13:30:09 -08001690 self.handle.sendline( "" )
jenkins1e99e7b2015-04-02 18:15:39 -07001691 if grepOptions:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001692 grepStr = "grep " + str( grepOptions )
jenkins1e99e7b2015-04-02 18:15:39 -07001693 else:
1694 grepStr = "grep"
Jon Hall4ba53f02015-07-29 13:07:41 -07001695
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001696 cmd = (
1697 "sudo tshark -i " +
Jon Hallfebb1c72015-03-05 13:30:09 -08001698 str( interface ) +
jenkins1e99e7b2015-04-02 18:15:39 -07001699 " -t e | " +
1700 grepStr + " --line-buffered \"" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001701 str( grep ) +
Jon Hallfebb1c72015-03-05 13:30:09 -08001702 "\" >" +
1703 directory +
1704 " &" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001705 self.handle.sendline( cmd )
1706 main.log.info( cmd )
Jon Hallfebb1c72015-03-05 13:30:09 -08001707 self.handle.expect( "Capturing on" )
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001708 self.handle.sendline( "\n" )
Devin Limc20e79a2017-06-07 10:29:57 -07001709 self.handle.expect( self.prompt )
Jon Hallfebb1c72015-03-05 13:30:09 -08001710 except pexpect.EOF:
1711 main.log.error( self.name + ": EOF exception found" )
1712 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001713 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001714 except Exception:
1715 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001716 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001717
kelvin-onlabd3b64892015-01-20 13:26:24 -08001718 def tsharkStop( self ):
kelvin8ec71442015-01-15 16:57:00 -08001719 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001720 Removes wireshark files from /tmp and kills all tshark processes
kelvin8ec71442015-01-15 16:57:00 -08001721 """
1722 # Remove all pcap from previous captures
Jon Hallfebb1c72015-03-05 13:30:09 -08001723 try:
1724 self.execute( cmd="sudo rm /tmp/wireshark*" )
1725 self.handle.sendline( "" )
Jon Hallefbd9792015-03-05 16:11:36 -08001726 self.handle.sendline( "sudo kill -9 `ps -ef | grep \"tshark -i\"" +
1727 " | grep -v grep | awk '{print $2}'`" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001728 self.handle.sendline( "" )
Jon Hall3c0114c2020-08-11 15:07:42 -07001729 main.log.info( self.name + ": Tshark stopped" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001730 except pexpect.EOF:
1731 main.log.error( self.name + ": EOF exception found" )
1732 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001733 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001734 except Exception:
1735 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001736 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001737
kelvin8ec71442015-01-15 16:57:00 -08001738 def ptpd( self, args ):
1739 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001740 Initiate ptp with user-specified args.
1741 Required:
1742 * args: specify string of args after command
1743 'sudo ptpd'
kelvin8ec71442015-01-15 16:57:00 -08001744 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001745 try:
kelvin8ec71442015-01-15 16:57:00 -08001746 self.handle.sendline( "sudo ptpd " + str( args ) )
1747 i = self.handle.expect( [
andrewonlab0c38a4a2014-10-28 18:35:35 -04001748 "Multiple",
1749 "Error",
Devin Limc20e79a2017-06-07 10:29:57 -07001750 self.prompt ] )
1751 self.handle.expect( self.prompt )
andrewonlabba44bcf2014-10-16 16:54:41 -04001752
andrewonlab0c38a4a2014-10-28 18:35:35 -04001753 if i == 0:
1754 handle = self.handle.before
Jon Hall3c0114c2020-08-11 15:07:42 -07001755 main.log.info( self.name + ": ptpd returned an error: " +
kelvin8ec71442015-01-15 16:57:00 -08001756 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001757 return handle
1758 elif i == 1:
1759 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001760 main.log.error( "ptpd returned an error: " +
1761 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001762 return handle
1763 else:
1764 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -08001765
andrewonlab0c38a4a2014-10-28 18:35:35 -04001766 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001767 main.log.error( self.name + ": EOF exception found" )
1768 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001769 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001770 except Exception:
1771 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001772 main.cleanAndExit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001773
Jon Hall06fd0df2021-01-25 15:50:06 -08001774 def dumpONOSCmd( self, ONOSIp, CMD, destDir, filename, options="", cliPort=8101, timeout=60 ):
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001775 """
Pier50f0bc62016-09-07 17:53:40 -07001776 Dump Cmd to a desired directory.
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001777 For debugging purposes, you may want to use
Pier50f0bc62016-09-07 17:53:40 -07001778 this function to capture Cmd at a given point in time.
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001779 Localtime will be attached to the filename
1780
1781 Required:
1782 * ONOSIp: the IP of the target ONOS instance
Pier50f0bc62016-09-07 17:53:40 -07001783 * CMD: the command to dump;
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001784 * destDir: specify directory to copy to.
1785 ex ) /tmp/
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001786 * fileName: Name of the file
You Wang54b1d672018-06-11 16:44:13 -07001787 Optional:
Pier50f0bc62016-09-07 17:53:40 -07001788 * options: Options for ONOS command
You Wang54b1d672018-06-11 16:44:13 -07001789 * timeout: pexpect timeout for running the ONOS command
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001790 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001791
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001792 localtime = time.strftime( '%x %X' )
1793 localtime = localtime.replace( "/", "" )
1794 localtime = localtime.replace( " ", "_" )
1795 localtime = localtime.replace( ":", "" )
1796 if destDir[ -1: ] != "/":
1797 destDir += "/"
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001798 cmd = CMD + " " + options + " > " + str( destDir ) + str( filename ) + localtime
Jon Hall06fd0df2021-01-25 15:50:06 -08001799 return self.onosCli( ONOSIp, cmd, cliPort=cliPort, timeout=timeout )
Flavio Castrob7718952016-05-18 08:53:41 -07001800
kelvin-onlabd3b64892015-01-20 13:26:24 -08001801 def cpLogsToDir( self, logToCopy,
Jon Hallefbd9792015-03-05 16:11:36 -08001802 destDir, copyFileName="" ):
kelvin8ec71442015-01-15 16:57:00 -08001803 """
1804 Copies logs to a desired directory.
andrewonlab5d7a8f32014-11-10 13:07:56 -05001805 Current implementation of ONOS deletes its karaf
1806 logs on every iteration. For debugging purposes,
kelvin8ec71442015-01-15 16:57:00 -08001807 you may want to use this function to capture
1808 certain karaf logs. ( or any other logs if needed )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001809 Localtime will be attached to the filename
1810
1811 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001812 * logToCopy: specify directory and log name to
andrewonlab5d7a8f32014-11-10 13:07:56 -05001813 copy.
kelvin8ec71442015-01-15 16:57:00 -08001814 ex ) /opt/onos/log/karaf.log.1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001815 For copying multiple files, leave copyFileName
1816 empty and only specify destDir -
kelvin8ec71442015-01-15 16:57:00 -08001817 ex ) /opt/onos/log/karaf*
kelvin-onlabd3b64892015-01-20 13:26:24 -08001818 * destDir: specify directory to copy to.
kelvin8ec71442015-01-15 16:57:00 -08001819 ex ) /tmp/
1820 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001821 * copyFileName: If you want to rename the log
1822 file, specify copyFileName. This will not work
andrewonlab5d7a8f32014-11-10 13:07:56 -05001823 with multiple file copying
kelvin8ec71442015-01-15 16:57:00 -08001824 """
andrewonlab5d7a8f32014-11-10 13:07:56 -05001825 try:
Flavio Castro09ab59d2016-05-25 17:01:35 -07001826 localtime = time.strftime( '%H %M' )
kelvin8ec71442015-01-15 16:57:00 -08001827 localtime = localtime.replace( "/", "" )
1828 localtime = localtime.replace( " ", "_" )
1829 localtime = localtime.replace( ":", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001830 if destDir[ -1: ] != "/":
1831 destDir += "/"
andrewonlab5d7a8f32014-11-10 13:07:56 -05001832
kelvin-onlabd3b64892015-01-20 13:26:24 -08001833 if copyFileName:
Jon Hallfebb1c72015-03-05 13:30:09 -08001834 self.handle.sendline( "cp " + str( logToCopy ) + " " +
1835 str( destDir ) + str( copyFileName ) +
1836 localtime )
kelvin8ec71442015-01-15 16:57:00 -08001837 self.handle.expect( "cp" )
Devin Limc20e79a2017-06-07 10:29:57 -07001838 self.handle.expect( self.prompt )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001839 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001840 self.handle.sendline( "cp " + str( logToCopy ) +
1841 " " + str( destDir ) )
kelvin8ec71442015-01-15 16:57:00 -08001842 self.handle.expect( "cp" )
Devin Limc20e79a2017-06-07 10:29:57 -07001843 self.handle.expect( self.prompt )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001844
kelvin8ec71442015-01-15 16:57:00 -08001845 return self.handle.before
1846
1847 except pexpect.EOF:
1848 main.log.error( "Copying files failed" )
1849 main.log.error( self.name + ": EOF exception found" )
1850 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001851 except Exception:
1852 main.log.exception( "Copying files failed" )
1853
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001854 def checkLogs( self, onosIp, restart=False ):
kelvin8ec71442015-01-15 16:57:00 -08001855 """
Jon Hall94fd0472014-12-08 11:52:42 -08001856 runs onos-check-logs on the given onos node
Jon Hall80daded2015-05-27 16:07:00 -07001857 If restart is True, use the old version of onos-check-logs which
1858 does not print the full stacktrace, but shows the entire log file,
1859 including across restarts
Jon Hall94fd0472014-12-08 11:52:42 -08001860 returns the response
kelvin8ec71442015-01-15 16:57:00 -08001861 """
Jon Hall94fd0472014-12-08 11:52:42 -08001862 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001863 cmd = "onos-check-logs " + str( onosIp )
Jon Hall16b72c42015-05-20 10:23:36 -07001864 if restart:
1865 cmd += " old"
kelvin8ec71442015-01-15 16:57:00 -08001866 self.handle.sendline( cmd )
1867 self.handle.expect( cmd )
Devin Limdc78e202017-06-09 18:30:07 -07001868 self.handle.expect( self.prompt + " " )
Jon Hall94fd0472014-12-08 11:52:42 -08001869 response = self.handle.before
1870 return response
1871 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001872 main.log.error( "Lost ssh connection" )
1873 main.log.error( self.name + ": EOF exception found" )
1874 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001875 except Exception:
1876 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001877 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001878
kelvin-onlabd3b64892015-01-20 13:26:24 -08001879 def onosStatus( self, node="" ):
kelvin8ec71442015-01-15 16:57:00 -08001880 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001881 Calls onos command: 'onos-service [<node-ip>] status'
kelvin8ec71442015-01-15 16:57:00 -08001882 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001883 try:
kelvin8ec71442015-01-15 16:57:00 -08001884 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001885 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -08001886 self.handle.sendline( "onos-service " + str( node ) +
1887 " status" )
1888 i = self.handle.expect( [
You Wangef1e6572016-03-08 12:53:18 -08001889 "start/running",
You Wang7bd83062016-03-01 11:50:00 -08001890 "Running ...",
You Wangef1e6572016-03-08 12:53:18 -08001891 "stop/waiting",
You Wang7bd83062016-03-01 11:50:00 -08001892 "Not Running ...",
kelvin8ec71442015-01-15 16:57:00 -08001893 pexpect.TIMEOUT ], timeout=120 )
YPZhangfebf7302016-05-24 16:45:56 -07001894 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001895 self.handle.expect( self.prompt )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001896
You Wangef1e6572016-03-08 12:53:18 -08001897 if i == 0 or i == 1:
Jon Hall3c0114c2020-08-11 15:07:42 -07001898 main.log.info( self.name + ": ONOS is running" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001899 return main.TRUE
You Wangef1e6572016-03-08 12:53:18 -08001900 elif i == 2 or i == 3:
Jon Hall3c0114c2020-08-11 15:07:42 -07001901 main.log.info( self.name + ": ONOS is stopped" )
kelvin8ec71442015-01-15 16:57:00 -08001902 main.log.error( "ONOS service failed to check the status" )
Devin Lim44075962017-08-11 10:56:37 -07001903
1904 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001905 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001906 main.log.error( self.name + ": EOF exception found" )
1907 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001908 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001909 except Exception:
1910 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001911 main.cleanAndExit()
Jon Hall21270ac2015-02-16 17:59:55 -08001912
Jon Hall63604932015-02-26 17:09:50 -08001913 def setIpTables( self, ip, port='', action='add', packet_type='',
1914 direction='INPUT', rule='DROP', states=True ):
Jon Hallefbd9792015-03-05 16:11:36 -08001915 """
Jon Hall21270ac2015-02-16 17:59:55 -08001916 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001917 add or remove iptables rule to DROP (default) packets from
Jon Hall21270ac2015-02-16 17:59:55 -08001918 specific IP and PORT
1919 Usage:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001920 * specify action ('add' or 'remove')
Jon Hall21270ac2015-02-16 17:59:55 -08001921 when removing, pass in the same argument as you would add. It will
1922 delete that specific rule.
1923 * specify the ip to block
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001924 * specify the destination port to block (defaults to all ports)
1925 * optional packet type to block (default tcp)
1926 * optional iptables rule (default DROP)
1927 * optional direction to block (default 'INPUT')
Jon Hall63604932015-02-26 17:09:50 -08001928 * States boolean toggles adding all supported tcp states to the
1929 firewall rule
Jon Hall21270ac2015-02-16 17:59:55 -08001930 Returns:
1931 main.TRUE on success or
1932 main.FALSE if given invalid input or
1933 main.ERROR if there is an error in response from iptables
1934 WARNING:
1935 * This function uses root privilege iptables command which may result
1936 in unwanted network errors. USE WITH CAUTION
Jon Hallefbd9792015-03-05 16:11:36 -08001937 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001938
Jon Hall21270ac2015-02-16 17:59:55 -08001939 # NOTE*********
1940 # The strict checking methods of this driver function is intentional
1941 # to discourage any misuse or error of iptables, which can cause
1942 # severe network errors
1943 # *************
1944
1945 # NOTE: Sleep needed to give some time for rule to be added and
1946 # registered to the instance. If you are calling this function
1947 # multiple times this sleep will prevent any errors.
1948 # DO NOT REMOVE
Jon Hall63604932015-02-26 17:09:50 -08001949 # time.sleep( 5 )
Jon Hall21270ac2015-02-16 17:59:55 -08001950 try:
1951 # input validation
1952 action_type = action.lower()
1953 rule = rule.upper()
1954 direction = direction.upper()
1955 if action_type != 'add' and action_type != 'remove':
1956 main.log.error( "Invalid action type. Use 'add' or "
1957 "'remove' table rule" )
1958 if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
1959 # NOTE Currently only supports rules DROP, ACCEPT, and LOG
1960 main.log.error( "Invalid rule. Valid rules are 'DROP' or "
1961 "'ACCEPT' or 'LOG' only." )
1962 if direction != 'INPUT' and direction != 'OUTPUT':
1963 # NOTE currently only supports rules INPUT and OUPTUT
1964 main.log.error( "Invalid rule. Valid directions are"
1965 " 'OUTPUT' or 'INPUT'" )
1966 return main.FALSE
1967 return main.FALSE
1968 return main.FALSE
1969 if action_type == 'add':
1970 # -A is the 'append' action of iptables
1971 actionFlag = '-A'
1972 elif action_type == 'remove':
1973 # -D is the 'delete' rule of iptables
1974 actionFlag = '-D'
1975 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001976 self.handle.expect( self.prompt )
Jon Hall21270ac2015-02-16 17:59:55 -08001977 cmd = "sudo iptables " + actionFlag + " " +\
1978 direction +\
Jon Hall21270ac2015-02-16 17:59:55 -08001979 " -s " + str( ip )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001980 # " -p " + str( packet_type ) +\
Jon Hall63604932015-02-26 17:09:50 -08001981 if packet_type:
1982 cmd += " -p " + str( packet_type )
Jon Hall21270ac2015-02-16 17:59:55 -08001983 if port:
1984 cmd += " --dport " + str( port )
Jon Hall63604932015-02-26 17:09:50 -08001985 if states:
1986 cmd += " -m state --state="
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001987 # FIXME- Allow user to configure which states to block
Jon Hall63604932015-02-26 17:09:50 -08001988 cmd += "INVALID,ESTABLISHED,NEW,RELATED,UNTRACKED"
Jon Hall21270ac2015-02-16 17:59:55 -08001989 cmd += " -j " + str( rule )
1990
1991 self.handle.sendline( cmd )
Devin Limc20e79a2017-06-07 10:29:57 -07001992 self.handle.expect( self.prompt )
Jon Hall21270ac2015-02-16 17:59:55 -08001993 main.log.warn( self.handle.before )
1994
1995 info_string = "On " + str( self.name )
1996 info_string += " " + str( action_type )
1997 info_string += " iptable rule [ "
1998 info_string += " IP: " + str( ip )
1999 info_string += " Port: " + str( port )
2000 info_string += " Rule: " + str( rule )
2001 info_string += " Direction: " + str( direction ) + " ]"
2002 main.log.info( info_string )
2003 return main.TRUE
2004 except pexpect.TIMEOUT:
2005 main.log.exception( self.name + ": Timeout exception in "
2006 "setIpTables function" )
You Wang141b43b2018-06-26 16:50:18 -07002007 self.handle.send( "\x03" ) # Control-C
2008 self.handle.expect( self.prompt )
Jon Hall21270ac2015-02-16 17:59:55 -08002009 return main.ERROR
2010 except pexpect.EOF:
2011 main.log.error( self.name + ": EOF exception found" )
2012 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002013 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002014 except Exception:
2015 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002016 main.cleanAndExit()
Jon Hall21270ac2015-02-16 17:59:55 -08002017
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002018 def detailed_status( self, log_filename ):
Jon Hallefbd9792015-03-05 16:11:36 -08002019 """
Jon Hall0468b042015-02-19 19:08:21 -08002020 This method is used by STS to check the status of the controller
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002021 Reports RUNNING, STARTING, STOPPED, FROZEN, ERROR (and reason)
Jon Hallefbd9792015-03-05 16:11:36 -08002022 """
Jon Hall0468b042015-02-19 19:08:21 -08002023 import re
2024 try:
2025 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07002026 self.handle.expect( self.prompt )
Jon Hall0468b042015-02-19 19:08:21 -08002027 self.handle.sendline( "cd " + self.home )
Devin Limc20e79a2017-06-07 10:29:57 -07002028 self.handle.expect( self.prompt )
Jon Hall0468b042015-02-19 19:08:21 -08002029 self.handle.sendline( "service onos status" )
Devin Limc20e79a2017-06-07 10:29:57 -07002030 self.handle.expect( self.prompt )
Jon Hall0468b042015-02-19 19:08:21 -08002031 response = self.handle.before
2032 if re.search( "onos start/running", response ):
2033 # onos start/running, process 10457
2034 return 'RUNNING'
2035 # FIXME: Implement this case
2036 # elif re.search( pattern, response ):
2037 # return 'STARTING'
2038 elif re.search( "onos stop/", response ):
2039 # onos stop/waiting
2040 # FIXME handle this differently?: onos stop/pre-stop
2041 return 'STOPPED'
2042 # FIXME: Implement this case
2043 # elif re.search( pattern, response ):
2044 # return 'FROZEN'
2045 else:
2046 main.log.warn( self.name +
Jon Hallefbd9792015-03-05 16:11:36 -08002047 " WARNING: status received unknown response" )
Jon Hall0468b042015-02-19 19:08:21 -08002048 main.log.warn( response )
2049 return 'ERROR', "Unknown response: %s" % response
2050 except pexpect.TIMEOUT:
2051 main.log.exception( self.name + ": Timeout exception in "
2052 "setIpTables function" )
You Wang141b43b2018-06-26 16:50:18 -07002053 self.handle.send( "\x03" ) # Control-C
2054 self.handle.expect( self.prompt )
Jon Hall0468b042015-02-19 19:08:21 -08002055 return 'ERROR', "Pexpect Timeout"
2056 except pexpect.EOF:
2057 main.log.error( self.name + ": EOF exception found" )
2058 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002059 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002060 except Exception:
2061 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002062 main.cleanAndExit()
Jon Hall0468b042015-02-19 19:08:21 -08002063
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002064 def createLinkGraphFile( self, benchIp, ONOSIpList, deviceCount ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002065 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07002066 Create/formats the LinkGraph.cfg file based on arguments
2067 -only creates a linear topology and connects islands
2068 -evenly distributes devices
andrew@onlab.us3b087132015-03-11 15:00:08 -07002069 -must be called by ONOSbench
2070
Jon Hall4ba53f02015-07-29 13:07:41 -07002071 ONOSIpList - list of all of the node IPs to be used
2072
2073 deviceCount - number of switches to be assigned
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002074 '''
Jon Hall3c0114c2020-08-11 15:07:42 -07002075 main.log.info( self.name + ": Creating link graph configuration file." )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002076 linkGraphPath = self.home + "/tools/package/etc/linkGraph.cfg"
Jon Hall4ba53f02015-07-29 13:07:41 -07002077 tempFile = "/tmp/linkGraph.cfg"
andrew@onlab.us3b087132015-03-11 15:00:08 -07002078
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002079 linkGraph = open( tempFile, 'w+' )
2080 linkGraph.write( "# NullLinkProvider topology description (config file).\n" )
2081 linkGraph.write( "# The NodeId is only added if the destination is another node's device.\n" )
2082 linkGraph.write( "# Bugs: Comments cannot be appended to a line to be read.\n" )
Jon Hall4ba53f02015-07-29 13:07:41 -07002083
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002084 clusterCount = len( ONOSIpList )
Jon Hall4ba53f02015-07-29 13:07:41 -07002085
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002086 if isinstance( deviceCount, int ) or isinstance( deviceCount, str ):
2087 deviceCount = int( deviceCount )
2088 switchList = [ 0 ]*( clusterCount+1 )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002089 baselineSwitchCount = deviceCount/clusterCount
Jon Hall4ba53f02015-07-29 13:07:41 -07002090
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002091 for node in range( 1, clusterCount + 1 ):
2092 switchList[ node ] = baselineSwitchCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07002093
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002094 for node in range( 1, ( deviceCount % clusterCount )+1 ):
2095 switchList[ node ] += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07002096
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002097 if isinstance( deviceCount, list ):
Jon Hall3c0114c2020-08-11 15:07:42 -07002098 main.log.info( self.name + ": Using provided device distribution" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002099 switchList = [ 0 ]
andrew@onlab.us3b087132015-03-11 15:00:08 -07002100 for i in deviceCount:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002101 switchList.append( int( i ) )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002102
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002103 tempList = [ '0' ]
2104 tempList.extend( ONOSIpList )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002105 ONOSIpList = tempList
2106
2107 myPort = 6
2108 lastSwitch = 0
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002109 for node in range( 1, clusterCount+1 ):
2110 if switchList[ node ] == 0:
andrew@onlab.us3b087132015-03-11 15:00:08 -07002111 continue
2112
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002113 linkGraph.write( "graph " + ONOSIpList[ node ] + " {\n" )
Jon Hall4ba53f02015-07-29 13:07:41 -07002114
andrew@onlab.us3b087132015-03-11 15:00:08 -07002115 if node > 1:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002116 # connect to last device on previous node
2117 line = ( "\t0:5 -> " + str( lastSwitch ) + ":6:" + lastIp + "\n" ) # ONOSIpList[node-1]
2118 linkGraph.write( line )
Jon Hall4ba53f02015-07-29 13:07:41 -07002119
2120 lastSwitch = 0
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002121 for switch in range( 0, switchList[ node ]-1 ):
andrew@onlab.us3b087132015-03-11 15:00:08 -07002122 line = ""
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002123 line = ( "\t" + str( switch ) + ":" + str( myPort ) )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002124 line += " -- "
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002125 line += ( str( switch+1 ) + ":" + str( myPort-1 ) + "\n" )
2126 linkGraph.write( line )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002127 lastSwitch = switch+1
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002128 lastIp = ONOSIpList[ node ]
Jon Hall4ba53f02015-07-29 13:07:41 -07002129
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002130 # lastSwitch += 1
2131 if node < ( clusterCount ):
2132 # connect to first device on the next node
2133 line = ( "\t" + str( lastSwitch ) + ":6 -> 0:5:" + ONOSIpList[ node+1 ] + "\n" )
2134 linkGraph.write( line )
Jon Hall4ba53f02015-07-29 13:07:41 -07002135
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002136 linkGraph.write( "}\n" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002137 linkGraph.close()
2138
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002139 # SCP
2140 os.system( "scp " + tempFile + " " + self.user_name + "@" + benchIp + ":" + linkGraphPath )
Jon Hall3c0114c2020-08-11 15:07:42 -07002141 main.log.info( self.name + ": linkGraph.cfg creation complete" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002142
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002143 def configNullDev( self, ONOSIpList, deviceCount, numPorts=10 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002144 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07002145 ONOSIpList = list of Ip addresses of nodes switches will be devided amongst
2146 deviceCount = number of switches to distribute, or list of values to use as custom distribution
cameron@onlab.us75900962015-03-30 13:22:49 -07002147 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 +00002148 '''
2149
Jon Hall3c0114c2020-08-11 15:07:42 -07002150 main.log.info( self.name + ": Configuring Null Device Provider" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002151 clusterCount = len( ONOSIpList )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002152
Jon Hall4ba53f02015-07-29 13:07:41 -07002153 try:
2154
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002155 if isinstance( deviceCount, int ) or isinstance( deviceCount, str ):
Jon Hall3c0114c2020-08-11 15:07:42 -07002156 main.log.info( self.name + ": Creating device distribution" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002157 deviceCount = int( deviceCount )
2158 switchList = [ 0 ]*( clusterCount+1 )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002159 baselineSwitchCount = deviceCount/clusterCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07002160
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002161 for node in range( 1, clusterCount + 1 ):
2162 switchList[ node ] = baselineSwitchCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07002163
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002164 for node in range( 1, ( deviceCount % clusterCount )+1 ):
2165 switchList[ node ] += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07002166
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002167 if isinstance( deviceCount, list ):
Jon Hall3c0114c2020-08-11 15:07:42 -07002168 main.log.info( self.name + ": Using provided device distribution" )
Jon Hall4ba53f02015-07-29 13:07:41 -07002169
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002170 if len( deviceCount ) == clusterCount:
2171 switchList = [ '0' ]
2172 switchList.extend( deviceCount )
Jon Hall4ba53f02015-07-29 13:07:41 -07002173
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002174 if len( deviceCount ) == ( clusterCount + 1 ):
2175 if deviceCount[ 0 ] == '0' or deviceCount[ 0 ] == 0:
cameron@onlab.us75900962015-03-30 13:22:49 -07002176 switchList = deviceCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07002177
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002178 assert len( switchList ) == ( clusterCount + 1 )
Jon Hall4ba53f02015-07-29 13:07:41 -07002179
cameron@onlab.us75900962015-03-30 13:22:49 -07002180 except AssertionError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002181 main.log.error( "Bad device/Ip list match" )
cameron@onlab.us75900962015-03-30 13:22:49 -07002182 except TypeError:
2183 main.log.exception( self.name + ": Object not as expected" )
2184 return None
Jon Hall77ba41c2015-04-06 10:25:40 -07002185 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002186 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002187 main.cleanAndExit()
cameron@onlab.us75900962015-03-30 13:22:49 -07002188
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002189 ONOSIp = [ 0 ]
2190 ONOSIp.extend( ONOSIpList )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002191
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002192 devicesString = "devConfigs = "
2193 for node in range( 1, len( ONOSIp ) ):
2194 devicesString += ( ONOSIp[ node ] + ":" + str( switchList[ node ] ) )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002195 if node < clusterCount:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002196 devicesString += ( "," )
Jon Hall4ba53f02015-07-29 13:07:41 -07002197
2198 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002199 self.handle.sendline( "onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider devConfigs " + devicesString )
2200 self.handle.expect( ":~" )
2201 self.handle.sendline( "onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider numPorts " + str( numPorts ) )
2202 self.handle.expect( ":~" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002203
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002204 for i in range( 10 ):
2205 self.handle.sendline( "onos $OC1 cfg get org.onosproject.provider.nil.device.impl.NullDeviceProvider" )
2206 self.handle.expect( ":~" )
cameron@onlab.us75900962015-03-30 13:22:49 -07002207 verification = self.handle.before
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002208 if ( " value=" + str( numPorts ) ) in verification and ( " value=" + devicesString ) in verification:
cameron@onlab.us75900962015-03-30 13:22:49 -07002209 break
2210 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002211 time.sleep( 1 )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002212
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002213 assert ( "value=" + str( numPorts ) ) in verification and ( " value=" + devicesString ) in verification
Jon Hall4ba53f02015-07-29 13:07:41 -07002214
cameron@onlab.us75900962015-03-30 13:22:49 -07002215 except AssertionError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002216 main.log.error( "Incorrect Config settings: " + verification )
Jon Hall77ba41c2015-04-06 10:25:40 -07002217 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002218 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002219 main.cleanAndExit()
cameron@onlab.us75900962015-03-30 13:22:49 -07002220
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002221 def configNullLink( self, fileName="/opt/onos/apache-karaf-3.0.3/etc/linkGraph.cfg", eventRate=0 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002222 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07002223 fileName default is currently the same as the default on ONOS, specify alternate file if
cameron@onlab.us75900962015-03-30 13:22:49 -07002224 you want to use a different topology file than linkGraph.cfg
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002225 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07002226
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002227 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002228 self.handle.sendline( "onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider eventRate " + str( eventRate ) )
2229 self.handle.expect( ":~" )
2230 self.handle.sendline( "onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider cfgFile " + fileName )
2231 self.handle.expect( ":~" )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002232
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002233 for i in range( 10 ):
2234 self.handle.sendline( "onos $OC1 cfg get org.onosproject.provider.nil.link.impl.NullLinkProvider" )
2235 self.handle.expect( ":~" )
cameron@onlab.us75900962015-03-30 13:22:49 -07002236 verification = self.handle.before
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002237 if ( " value=" + str( eventRate ) ) in verification and ( " value=" + fileName ) in verification:
cameron@onlab.us75900962015-03-30 13:22:49 -07002238 break
Jon Hall4ba53f02015-07-29 13:07:41 -07002239 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002240 time.sleep( 1 )
Jon Hall4ba53f02015-07-29 13:07:41 -07002241
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002242 assert ( "value=" + str( eventRate ) ) in verification and ( " value=" + fileName ) in verification
Jon Hall4ba53f02015-07-29 13:07:41 -07002243
cameron@onlab.us75900962015-03-30 13:22:49 -07002244 except pexpect.EOF:
2245 main.log.error( self.name + ": EOF exception found" )
2246 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002247 main.cleanAndExit()
cameron@onlab.us75900962015-03-30 13:22:49 -07002248 except AssertionError:
Jon Hall3c0114c2020-08-11 15:07:42 -07002249 main.log.info( self.name + ": Settings did not post to ONOS" )
Jon Hall3e6edb32018-08-21 16:20:30 -07002250 main.log.error( verification )
Jon Hall77ba41c2015-04-06 10:25:40 -07002251 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002252 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall3e6edb32018-08-21 16:20:30 -07002253 main.log.error( verification )
Devin Lim44075962017-08-11 10:56:37 -07002254 main.cleanAndExit()
andrew@onlab.us3b087132015-03-11 15:00:08 -07002255
kelvin-onlaba4074292015-07-09 15:19:49 -07002256 def getOnosIps( self ):
2257 """
2258 Get all onos IPs stored in
2259 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002260
kelvin-onlaba4074292015-07-09 15:19:49 -07002261 return sorted( self.onosIps.values() )
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002262
Chiyu Chengec63bde2016-11-17 18:11:36 -08002263 def listLog( self, nodeIp ):
2264 """
2265 Get a list of all the karaf log names
2266 """
2267 try:
2268 cmd = "onos-ssh " + nodeIp + " ls -tr /opt/onos/log"
2269 self.handle.sendline( cmd )
2270 self.handle.expect( ":~" )
2271 before = self.handle.before.splitlines()
2272 logNames = []
2273 for word in before:
2274 if 'karaf.log' in word:
2275 logNames.append( word )
2276 return logNames
2277 except pexpect.EOF:
2278 main.log.error( self.name + ": EOF exception found" )
2279 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002280 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08002281 except pexpect.TIMEOUT:
2282 main.log.error( self.name + ": TIMEOUT exception found" )
2283 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002284 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08002285 except Exception:
2286 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002287 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08002288
Pratik Parab3b2ab5a2017-02-14 13:15:14 -08002289 def logReport( self, nodeIp, searchTerms, outputMode="s", startStr=None, endStr=None ):
Jon Hallb4242222016-01-25 17:07:04 -08002290 """
2291 Searches the latest ONOS log file for the given search terms and
2292 prints the total occurances of each term. Returns to combined total of
2293 all occurances.
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002294
Jon Hallb4242222016-01-25 17:07:04 -08002295 Arguments:
2296 * nodeIp - The ip of the ONOS node where the log is located
2297 * searchTerms - A string to grep for or a list of strings to grep
2298 for in the ONOS log. Will print out the number of
2299 occurances for each term.
2300 Optional Arguments:
2301 * outputMode - 's' or 'd'. If 'd' will print the last 5 lines
2302 containing each search term as well as the total
2303 number of occurances of each term. Defaults to 's',
2304 which prints the simple output of just the number
2305 of occurances for each term.
Pratik Parab3b2ab5a2017-02-14 13:15:14 -08002306 * startStr - the start string to be given to stream editor command
2307 as the start point for extraction of data
2308 * endStr - the end string to be given to stream editor command as
2309 the end point for extraction of data
Jon Hallb4242222016-01-25 17:07:04 -08002310 """
2311 try:
Jon Hall3c0114c2020-08-11 15:07:42 -07002312 main.log.info( self.name + ": Log Report for {} ".format( nodeIp ).center( 70, '=' ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002313 if isinstance( searchTerms, str ):
2314 searchTerms = [ searchTerms ]
Jon Hallb4242222016-01-25 17:07:04 -08002315 numTerms = len( searchTerms )
2316 outputMode = outputMode.lower()
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002317
Jon Hallb4242222016-01-25 17:07:04 -08002318 totalHits = 0
2319 logLines = []
2320 for termIndex in range( numTerms ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002321 term = searchTerms[ termIndex ]
2322 logLines.append( [ term ] )
Pratik Parab3b2ab5a2017-02-14 13:15:14 -08002323 if startStr and endStr:
2324 cmd = "onos-ssh {} \"sed -n '/{}/,/{}/p' /opt/onos/log/karaf.log | grep {}\"".format( nodeIp,
2325 startStr,
2326 endStr,
2327 term )
2328 else:
2329 cmd = "onos-ssh {} cat /opt/onos/log/karaf.log | grep {}".format( nodeIp,
2330 term )
Jon Hallb4242222016-01-25 17:07:04 -08002331 self.handle.sendline( cmd )
2332 self.handle.expect( ":~" )
2333 before = self.handle.before.splitlines()
2334 count = 0
2335 for line in before:
2336 if term in line and "grep" not in line:
2337 count += 1
2338 if before.index( line ) > ( len( before ) - 7 ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002339 logLines[ termIndex ].append( line )
Jon Hall3c0114c2020-08-11 15:07:42 -07002340 main.log.info( self.name + ": {}: {}".format( term, count ) )
Jon Hallb4242222016-01-25 17:07:04 -08002341 totalHits += count
2342 if termIndex == numTerms - 1:
2343 print "\n"
2344 if outputMode != "s":
2345 outputString = ""
2346 for term in logLines:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002347 outputString = term[ 0 ] + ": \n"
Jon Hallb4242222016-01-25 17:07:04 -08002348 for line in range( 1, len( term ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002349 outputString += ( "\t" + term[ line ] + "\n" )
2350 if outputString != ( term[ 0 ] + ": \n" ):
Jon Hallb4242222016-01-25 17:07:04 -08002351 main.log.info( outputString )
Jon Hall3c0114c2020-08-11 15:07:42 -07002352 main.log.info( self.name + ": =" * 70 )
Jon Hallb4242222016-01-25 17:07:04 -08002353 return totalHits
2354 except pexpect.EOF:
2355 main.log.error( self.name + ": EOF exception found" )
2356 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002357 main.cleanAndExit()
Jon Hallb4242222016-01-25 17:07:04 -08002358 except pexpect.TIMEOUT:
2359 main.log.error( self.name + ": TIMEOUT exception found" )
2360 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002361 main.cleanAndExit()
Jon Hallb4242222016-01-25 17:07:04 -08002362 except Exception:
2363 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002364 main.cleanAndExit()
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002365
2366 def copyMininetFile( self, fileName, localPath, userName, ip,
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002367 mnPath='~/mininet/custom/', timeout = 60 ):
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002368 """
2369 Description:
2370 Copy mininet topology file from dependency folder in the test folder
2371 and paste it to the mininet machine's mininet/custom folder
2372 Required:
2373 fileName - Name of the topology file to copy
2374 localPath - File path of the mininet topology file
2375 userName - User name of the mininet machine to send the file to
2376 ip - Ip address of the mininet machine
2377 Optional:
2378 mnPath - of the mininet directory to send the file to
2379 Return:
2380 Return main.TRUE if successfully copied the file otherwise
2381 return main.FALSE
2382 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002383
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002384 try:
2385 cmd = "scp " + localPath + fileName + " " + userName + "@" + \
2386 str( ip ) + ":" + mnPath + fileName
2387
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
2391 main.log.info( self.name + ": Execute: " + cmd )
2392
2393 self.handle.sendline( cmd )
2394
2395 i = self.handle.expect( [ 'No such file',
2396 "100%",
2397 pexpect.TIMEOUT ] )
2398
2399 if i == 0:
2400 main.log.error( self.name + ": File " + fileName +
2401 " does not exist!" )
2402 return main.FALSE
2403
2404 if i == 1:
2405 main.log.info( self.name + ": File " + fileName +
2406 " has been copied!" )
2407 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07002408 self.handle.expect( self.prompt )
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002409 return main.TRUE
2410
2411 except pexpect.EOF:
2412 main.log.error( self.name + ": EOF exception found" )
2413 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002414 main.cleanAndExit()
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002415 except pexpect.TIMEOUT:
2416 main.log.error( self.name + ": TIMEOUT exception found" )
2417 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002418 main.cleanAndExit()
cameron@onlab.us78b89652015-07-08 15:21:03 -07002419
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002420 def jvmSet( self, memory=8 ):
Jon Hall4ba53f02015-07-29 13:07:41 -07002421
cameron@onlab.us78b89652015-07-08 15:21:03 -07002422 import os
2423
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002424 homeDir = os.path.expanduser( '~' )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002425 filename = "/onos/tools/package/bin/onos-service"
2426
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002427 serviceConfig = open( homeDir + filename, 'w+' )
2428 serviceConfig.write( "#!/bin/bash\n " )
2429 serviceConfig.write( "#------------------------------------- \n " )
2430 serviceConfig.write( "# Starts ONOS Apache Karaf container\n " )
2431 serviceConfig.write( "#------------------------------------- \n " )
2432 serviceConfig.write( "#export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-7-openjdk-amd64/}\n " )
2433 serviceConfig.write( """export JAVA_OPTS="${JAVA_OPTS:--Xms""" + str( memory ) + "G -Xmx" + str( memory ) + """G}" \n """ )
2434 serviceConfig.write( "[ -d $ONOS_HOME ] && cd $ONOS_HOME || ONOS_HOME=$(dirname $0)/..\n" )
2435 serviceConfig.write( """${ONOS_HOME}/apache-karaf-$KARAF_VERSION/bin/karaf "$@" \n """ )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002436 serviceConfig.close()
2437
Jon Hall6c44c0b2016-04-20 15:21:00 -07002438 def createDBFile( self, testData ):
Jon Hall4ba53f02015-07-29 13:07:41 -07002439
cameron@onlab.us78b89652015-07-08 15:21:03 -07002440 filename = main.TEST + "DB"
2441 DBString = ""
Jon Hall4ba53f02015-07-29 13:07:41 -07002442
cameron@onlab.us78b89652015-07-08 15:21:03 -07002443 for item in testData:
Jon Hall3e6edb32018-08-21 16:20:30 -07002444 if isinstance( item, str ):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002445 item = "'" + item + "'"
Jon Hall6c44c0b2016-04-20 15:21:00 -07002446 if testData.index( item ) < len( testData - 1 ):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002447 item += ","
Jon Hall6c44c0b2016-04-20 15:21:00 -07002448 DBString += str( item )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002449
Jon Hall6c44c0b2016-04-20 15:21:00 -07002450 DBFile = open( filename, "a" )
2451 DBFile.write( DBString )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002452 DBFile.close()
2453
Jon Hall6c44c0b2016-04-20 15:21:00 -07002454 def verifySummary( self, ONOSIp, *deviceCount ):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002455
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002456 self.handle.sendline( "onos " + ONOSIp + " summary" )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002457 self.handle.expect( ":~" )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002458
2459 summaryStr = self.handle.before
2460 print "\nSummary\n==============\n" + summaryStr + "\n\n"
2461
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002462 # passed = "SCC(s)=1" in summaryStr
2463 # if deviceCount:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002464 # passed = "devices=" + str(deviceCount) + "," not in summaryStr
cameron@onlab.us78b89652015-07-08 15:21:03 -07002465
GlennRC772363b2015-08-25 13:05:57 -07002466 passed = False
cameron@onlab.us78b89652015-07-08 15:21:03 -07002467 if "SCC(s)=1," in summaryStr:
2468 passed = True
Jon Hall6c44c0b2016-04-20 15:21:00 -07002469 print "Summary is verifed"
Jon Hall4ba53f02015-07-29 13:07:41 -07002470 else:
Jon Hall6c44c0b2016-04-20 15:21:00 -07002471 print "Summary failed"
cameron@onlab.us78b89652015-07-08 15:21:03 -07002472
2473 if deviceCount:
2474 print" ============================="
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002475 checkStr = "devices=" + str( deviceCount[ 0 ] ) + ","
cameron@onlab.us78b89652015-07-08 15:21:03 -07002476 print "Checkstr: " + checkStr
2477 if checkStr not in summaryStr:
2478 passed = False
Jon Hall6c44c0b2016-04-20 15:21:00 -07002479 print "Device count failed"
Jon Hall4ba53f02015-07-29 13:07:41 -07002480 else:
2481 print "device count verified"
cameron@onlab.us78b89652015-07-08 15:21:03 -07002482
2483 return passed
Jon Hall6c44c0b2016-04-20 15:21:00 -07002484
Jon Hall8f6d4622016-05-23 15:27:18 -07002485 def getIpAddr( self, iface=None ):
Jon Hall6c44c0b2016-04-20 15:21:00 -07002486 """
2487 Update self.ip_address with numerical ip address. If multiple IP's are
2488 located on the device, will attempt to use self.nicAddr to choose the
2489 right one. Defaults to 127.0.0.1 if no other address is found or cannot
2490 determine the correct address.
2491
2492 ONLY WORKS WITH IPV4 ADDRESSES
2493 """
2494 try:
Jon Hall8f6d4622016-05-23 15:27:18 -07002495 LOCALHOST = "127.0.0.1"
Jon Hall6c44c0b2016-04-20 15:21:00 -07002496 ipPat = "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"
2497 pattern = re.compile( ipPat )
2498 match = re.search( pattern, self.ip_address )
2499 if self.nicAddr:
2500 nicPat = self.nicAddr.replace( ".", "\." ).replace( "\*", r"\d{1,3}" )
2501 nicPat = re.compile( nicPat )
2502 else:
2503 nicPat = None
2504 # IF self.ip_address is an ip address and matches
2505 # self.nicAddr: return self.ip_address
2506 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002507 curIp = match.group( 0 )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002508 if nicPat:
2509 nicMatch = re.search( nicPat, curIp )
2510 if nicMatch:
2511 return self.ip_address
Jon Hall8f6d4622016-05-23 15:27:18 -07002512 # ELSE: IF iface, return ip of interface
2513 cmd = "ifconfig"
2514 ifPat = re.compile( "inet addr:({})".format( ipPat ) )
2515 if iface:
2516 cmd += " " + str( iface )
2517 raw = subprocess.check_output( cmd.split() )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002518 ifPat = re.compile( "inet addr:({})".format( ipPat ) )
2519 ips = re.findall( ifPat, raw )
Jon Hall8f6d4622016-05-23 15:27:18 -07002520 if iface:
2521 if ips:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002522 ip = ips[ 0 ]
Jon Hall8f6d4622016-05-23 15:27:18 -07002523 self.ip_address = ip
2524 return ip
2525 else:
2526 main.log.error( "Error finding ip, ifconfig output:".format( raw ) )
2527 # ELSE: attempt to get address matching nicPat.
Jon Hall6c44c0b2016-04-20 15:21:00 -07002528 if nicPat:
2529 for ip in ips:
2530 curMatch = re.search( nicPat, ip )
2531 if curMatch:
2532 self.ip_address = ip
2533 return ip
Jon Hall8f6d4622016-05-23 15:27:18 -07002534 else: # If only one non-localhost ip, return that
2535 tmpList = [ ip for ip in ips if ip is not LOCALHOST ]
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002536 if len( tmpList ) == 1:
2537 curIp = tmpList[ 0 ]
Jon Hall6c44c0b2016-04-20 15:21:00 -07002538 self.ip_address = curIp
2539 return curIp
Jon Hall8f6d4622016-05-23 15:27:18 -07002540 # Either no non-localhost IPs, or more than 1
Jon Hallebccd352016-05-20 15:17:17 -07002541 main.log.warn( "getIpAddr failed to find a public IP address" )
Jon Hall8f6d4622016-05-23 15:27:18 -07002542 return LOCALHOST
Jon Halle1790952016-05-23 15:51:46 -07002543 except subprocess.CalledProcessError:
Jon Hall8f6d4622016-05-23 15:27:18 -07002544 main.log.exception( "Error executing ifconfig" )
2545 except IndexError:
2546 main.log.exception( "Error getting IP Address" )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002547 except Exception:
2548 main.log.exception( "Uncaught exception" )
suibin zhang116647a2016-05-06 16:30:09 -07002549
Devin Lim461f0872017-06-05 16:49:33 -07002550 def startBasicONOS( self, nodeList, opSleep=60, onosStartupSleep=30, onosUser="sdn" ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002551 '''
suibin zhang116647a2016-05-06 16:30:09 -07002552 Start onos cluster with defined nodes, but only with drivers app
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002553 '''
suibin zhang116647a2016-05-06 16:30:09 -07002554 import time
2555
2556 self.createCellFile( self.ip_address,
Jon Hall3e6edb32018-08-21 16:20:30 -07002557 "temp",
2558 self.ip_address,
2559 "drivers",
2560 nodeList,
2561 nodeList,
2562 onosUser=onosUser )
suibin zhang116647a2016-05-06 16:30:09 -07002563
2564 main.log.info( self.name + ": Apply cell to environment" )
2565 cellResult = self.setCell( "temp" )
2566 verifyResult = self.verifyCell()
2567
2568 main.log.info( self.name + ": Creating ONOS package" )
You Wangd1bcaca2016-10-24 15:23:26 -07002569 packageResult = self.buckBuild( timeout=opSleep )
suibin zhang116647a2016-05-06 16:30:09 -07002570
You Wangc669d212017-01-25 11:09:48 -08002571 main.log.info( self.name + ": Uninstalling ONOS" )
2572 for nd in nodeList:
2573 self.onosUninstall( nodeIp=nd )
2574
suibin zhang116647a2016-05-06 16:30:09 -07002575 main.log.info( self.name + ": Installing ONOS package" )
2576 for nd in nodeList:
You Wangc669d212017-01-25 11:09:48 -08002577 self.onosInstall( node=nd )
2578
2579 main.log.info( self.name + ": Set up ONOS secure SSH" )
2580 for nd in nodeList:
2581 self.onosSecureSSH( node=nd )
suibin zhang116647a2016-05-06 16:30:09 -07002582
2583 main.log.info( self.name + ": Starting ONOS service" )
2584 time.sleep( onosStartupSleep )
2585
2586 onosStatus = True
2587 for nd in nodeList:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002588 onosStatus = onosStatus & self.isup( node = nd )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002589 # print "onosStatus is: " + str( onosStatus )
suibin zhang116647a2016-05-06 16:30:09 -07002590
2591 return main.TRUE if onosStatus else main.FALSE
2592
Jon Hall39570262020-11-17 12:18:19 -08002593 def onosNetCfg( self, controllerIp, path, fileName, user=None, password=None ):
Jeremy Songster5665f1b2016-06-20 14:38:22 -07002594 """
2595 Push a specified json file to ONOS through the onos-netcfg service
2596
2597 Required:
Devin Lim02075272017-07-10 15:33:21 -07002598 controllerIp - the Ip of the ONOS node in the cluster
Jeremy Songster5665f1b2016-06-20 14:38:22 -07002599 path - the location of the file to be sent
2600 fileName - name of the json file to be sent
2601
2602 Returns main.TRUE on successfully sending json file, and main.FALSE if
2603 there is an error.
2604 """
2605 try:
Jon Hall3c0114c2020-08-11 15:07:42 -07002606 cmd = "onos-netcfg "
2607 if user:
2608 cmd += "-u %s " % user
2609 if password:
2610 cmd += "-p %s " % password
2611 cmd += "{0} {1}{2}".format( controllerIp, path, fileName )
2612 main.log.info( self.name + ": Sending: " + cmd )
2613 self.handle.sendline( cmd )
2614 self.handle.expect( self.prompt )
Devin Lim02075272017-07-10 15:33:21 -07002615 handle = self.handle.before
Jon Hall3c0114c2020-08-11 15:07:42 -07002616 if "Error" in handle or\
2617 "No such file or directory" in handle or\
2618 "command not found" in handle or\
2619 "curl: " in handle:
Jeremy Ronquillo3008aa32017-07-07 15:38:57 -07002620 main.log.error( self.name + ": " + handle + self.handle.after )
Devin Lim02075272017-07-10 15:33:21 -07002621 return main.FALSE
Jon Hall3c0114c2020-08-11 15:07:42 -07002622 main.log.debug( self.name + ": " + handle )
Devin Lim752dd7b2017-06-27 14:40:03 -07002623 return main.TRUE
Jeremy Songster5665f1b2016-06-20 14:38:22 -07002624 except pexpect.EOF:
2625 main.log.error( self.name + ": EOF exception found" )
2626 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002627 main.cleanAndExit()
Jeremy Songster5665f1b2016-06-20 14:38:22 -07002628 except Exception:
2629 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002630 main.cleanAndExit()
Devin Lim3ebd5e72017-11-14 10:38:00 -08002631
2632 def formCluster( self, onosIPs ):
2633 """
2634 From ONOS cluster for IP addresses in onosIPs list
2635 """
2636 try:
2637 onosIPs = " ".join( onosIPs )
2638 command = "onos-form-cluster {}".format( onosIPs )
Jon Hall3c0114c2020-08-11 15:07:42 -07002639 main.log.info( self.name + ": Sending: " + command )
Devin Lim3ebd5e72017-11-14 10:38:00 -08002640 self.handle.sendline( "" )
2641 self.handle.expect( self.prompt )
2642 self.handle.sendline( command )
2643 self.handle.expect( self.prompt )
2644 handle = self.handle.before
2645 main.log.debug( handle )
2646 assert handle is not None, "Error in sendline"
2647 assert "Command not found:" not in handle, handle
2648 assert "Error" not in handle, handle
2649 assert "Exception:" not in handle, handle
2650 assert "curl:" not in handle, handle
2651 return main.TRUE
2652 except AssertionError:
2653 main.log.exception( "{} Error in onos-form-cluster output:".format( self.name ) )
2654 return main.FALSE
2655 except TypeError:
2656 main.log.exception( self.name + ": Object not as expected" )
2657 return main.FALSE
2658 except pexpect.EOF:
2659 main.log.error( self.name + ": EOF exception found" )
2660 main.log.error( self.name + ": " + self.handle.before )
2661 main.cleanAndExit()
2662 except Exception:
2663 main.log.exception( self.name + ": Uncaught exception!" )
2664 main.cleanAndExit()
Jon Hall7ce46ea2018-02-05 12:20:59 -08002665
2666 def backupData( self, location ):
2667 """
2668 Backs up ONOS data and logs to a given location. Returns main.FALSE
2669 if there is an error executing the command, and main.TRUE otherwise.
2670 required arguments:
2671 loaction - The file path to save the backup to
2672 """
2673 try:
2674 cmd = "/opt/onos/bin/onos-backup " + str( location )
2675 self.handle.sendline( cmd )
2676 self.handle.expect( self.prompt )
2677 handle = self.handle.before
2678 main.log.debug( handle )
2679 assert handle is not None, "Error in sendline"
2680 assert "Command not found:" not in handle, handle
2681 assert "Error" not in handle, handle
2682 assert "Exception:" not in handle, handle
2683 return main.TRUE
2684 except AssertionError:
2685 main.log.exception( "{} Error in onos-backup output:".format( self.name ) )
2686 return main.FALSE
2687 except TypeError:
2688 main.log.exception( self.name + ": Object not as expected" )
2689 return main.FALSE
2690 except pexpect.EOF:
2691 main.log.error( self.name + ": EOF exception found" )
2692 main.log.error( self.name + ": " + self.handle.before )
2693 main.cleanAndExit()
2694 except Exception:
2695 main.log.exception( self.name + ": Uncaught exception!" )
2696 main.cleanAndExit()
2697
2698 def restoreData( self, location ):
2699 """
2700 Restores ONOS data and logs from a given location. Returns main.FALSE
2701 if there is an error executing the command, and main.TRUE otherwise.
2702 required arguments:
2703 loaction - The file path of a backup file
2704 """
2705 try:
2706 cmd = "/opt/onos/bin/onos-restore " + str( location )
2707 self.handle.sendline( cmd )
2708 self.handle.expect( self.prompt )
2709 handle = self.handle.before
2710 main.log.debug( handle )
2711 assert handle is not None, "Error in sendline"
2712 assert "Command not found:" not in handle, handle
2713 assert "Error" not in handle, handle
2714 assert "Exception:" not in handle, handle
2715 return main.TRUE
2716 except AssertionError:
2717 main.log.exception( "{} Error in onos-restore output:".format( self.name ) )
2718 return main.FALSE
2719 except TypeError:
2720 main.log.exception( self.name + ": Object not as expected" )
2721 return main.FALSE
2722 except pexpect.EOF:
2723 main.log.error( self.name + ": EOF exception found" )
2724 main.log.error( self.name + ": " + self.handle.before )
2725 main.cleanAndExit()
2726 except Exception:
2727 main.log.exception( self.name + ": Uncaught exception!" )
2728 main.cleanAndExit()
You Wang5df1c6d2018-04-06 18:02:02 -07002729
Jon Hall43060f62020-06-23 13:13:33 -07002730 def onosDiagnostics( self, onosIPs, dstDir, suffix, timeout=300, profile="TRELLIS_PROFILE" ):
You Wang5df1c6d2018-04-06 18:02:02 -07002731 """
2732 Run onos-diagnostics with given ONOS instance IPs and save output to dstDir
2733 with suffix specified E.g. onos-diags-suffix.tar.gz
Jon Hall0e240372018-05-02 11:21:57 -07002734 required arguments:
You Wang5df1c6d2018-04-06 18:02:02 -07002735 onosIPs - list of ONOS IPs for collecting diags
2736 dstDir - diags file will be saved under the directory specified
2737 suffix - diags file will be named with the suffix specified
2738 returns:
2739 main.FALSE if there's an error executing the command, and main.TRUE otherwise
2740 """
2741 try:
Jon Hall43060f62020-06-23 13:13:33 -07002742 self.handle.sendline( "export DIAGS_PROFILE=%s" % profile )
2743 self.handle.expect( self.prompt )
You Wang5df1c6d2018-04-06 18:02:02 -07002744 cmd = "onos-diagnostics"
2745 assert isinstance( onosIPs, list )
2746 for ip in onosIPs:
2747 cmd += " " + str( ip )
2748 self.handle.sendline( cmd )
Jon Hall9b0de1f2020-08-24 15:38:04 -07002749 i = 0
2750 while i == 0:
2751 i = self.handle.expect( [ "Password", self.prompt ], timeout=timeout )
2752 handle = self.handle.before
2753 main.log.debug( "%s: %s" % ( self.name, handle ) )
2754 if i == 0:
2755 self.handle.sendline( self.pwd )
You Wang5df1c6d2018-04-06 18:02:02 -07002756 assert handle is not None, "Error in sendline"
Jon Hall9b0de1f2020-08-24 15:38:04 -07002757 assert "The requested URL returned error" not in handle, handle
You Wang5df1c6d2018-04-06 18:02:02 -07002758 assert "Command not found:" not in handle, handle
2759 assert "Exception:" not in handle, handle
2760 # Rename and move diags file to dstDir from /tmp
2761 if dstDir[ -1: ] != "/":
2762 dstDir += "/"
2763 self.handle.sendline( "mv /tmp/onos-diags.tar.gz " + str( dstDir ) + "onos-diags" + str( suffix ) + ".tar.gz" )
2764 self.handle.expect( self.prompt )
2765 handle = self.handle.before
Jon Hall9b0de1f2020-08-24 15:38:04 -07002766 main.log.debug( "%s: %s" % ( self.name, handle ) )
You Wang5df1c6d2018-04-06 18:02:02 -07002767 assert handle is not None, "Error in sendline"
2768 assert "No such file or directory" not in handle, handle
2769 return main.TRUE
2770 except AssertionError:
2771 main.log.exception( "{} Error in onos-diagnostics output:".format( self.name ) )
2772 return main.FALSE
2773 except TypeError:
2774 main.log.exception( self.name + ": Object not as expected" )
2775 return main.FALSE
You Wang223faa32018-06-21 10:45:47 -07002776 except pexpect.TIMEOUT:
2777 main.log.exception( self.name + ": TIMEOUT exception found in onosDiagnostics" )
2778 main.log.error( self.name + ": " + self.handle.before )
You Wangb65d2372018-08-17 15:37:59 -07002779 self.exitFromCmd( self.prompt, 100 )
You Wang223faa32018-06-21 10:45:47 -07002780 return main.FALSE
You Wang5df1c6d2018-04-06 18:02:02 -07002781 except pexpect.EOF:
2782 main.log.error( self.name + ": EOF exception found" )
2783 main.log.error( self.name + ": " + self.handle.before )
2784 main.cleanAndExit()
2785 except Exception:
2786 main.log.exception( self.name + ": Uncaught exception!" )
2787 main.cleanAndExit()
Jon Hall0e240372018-05-02 11:21:57 -07002788
2789 def onosPower( self, onosIP, toggle, userName=None ):
2790 """
2791 Run onos-power script to tell the cell warden to simulate a power faulure
2792 for the given container.
2793 required :
2794 onosIP - ONOS node IP
2795 toggle - either "off" or "on", used to indicate whether
2796 the node should be powered off or on
2797 returns:
2798 main.FALSE if there's an error executing the command, and main.TRUE otherwise
2799 """
2800 try:
2801 cmd = "onos-power {} {}".format( onosIP, toggle )
2802 if userName:
2803 cmd += " {}".format( userName )
2804 self.handle.sendline( cmd )
2805 self.handle.expect( self.prompt )
2806 handle = self.handle.before
2807 main.log.debug( handle )
2808 assert handle is not None, "Error in sendline"
2809 assert "Command not found:" not in handle, handle
2810 assert "Exception:" not in handle, handle
2811 assert "usage:" not in handle, handle
2812 return main.TRUE
2813 except AssertionError:
2814 main.log.exception( "{} Error in onos-power output:".format( self.name ) )
2815 return main.FALSE
2816 except TypeError:
2817 main.log.exception( self.name + ": Object not as expected" )
2818 return main.FALSE
2819 except pexpect.EOF:
2820 main.log.error( self.name + ": EOF exception found" )
2821 main.log.error( self.name + ": " + self.handle.before )
2822 main.cleanAndExit()
2823 except Exception:
2824 main.log.exception( self.name + ": Uncaught exception!" )
2825 main.cleanAndExit()
You Wangf9d95be2018-08-01 14:35:37 -07002826
2827 def atomixKill( self, nodeIp ):
2828 """
2829 Calls the command: 'atomix-kill [<node-ip>]'
2830 Kills the Atomix instance running on the specified node
2831 """
2832 try:
2833 self.handle.sendline( "" )
2834 self.handle.expect( self.prompt )
2835 self.handle.sendline( "atomix-kill " + str( nodeIp ) )
2836 i = self.handle.expect( [
2837 self.prompt,
2838 "No\sroute\sto\shost",
2839 "password:",
2840 pexpect.TIMEOUT ], timeout=60 )
2841
2842 if i == 0:
Jon Hall3c0114c2020-08-11 15:07:42 -07002843 main.log.info( self.name + ": Atomix instance " + str( nodeIp ) + " was killed" )
You Wangf9d95be2018-08-01 14:35:37 -07002844 return main.TRUE
2845 elif i == 1:
Jon Hall3c0114c2020-08-11 15:07:42 -07002846 main.log.info( self.name + ": No route to host" )
You Wangf9d95be2018-08-01 14:35:37 -07002847 return main.FALSE
2848 elif i == 2:
Jon Hall3c0114c2020-08-11 15:07:42 -07002849 main.log.info( self.name + ": Passwordless login for host: " + str( nodeIp ) + " not configured" )
You Wangf9d95be2018-08-01 14:35:37 -07002850 return main.FALSE
2851 else:
Jon Hall3c0114c2020-08-11 15:07:42 -07002852 main.log.info( self.name + ": Atomix instance was not killed" )
You Wangf9d95be2018-08-01 14:35:37 -07002853 return main.FALSE
2854
2855 except pexpect.EOF:
2856 main.log.error( self.name + ": EOF exception found" )
2857 main.log.error( self.name + ": " + self.handle.before )
2858 main.cleanAndExit()
2859 except Exception:
2860 main.log.exception( self.name + ": Uncaught exception!" )
2861 main.cleanAndExit()
2862
2863 def atomixUninstall( self, nodeIp="" ):
2864 """
2865 Calls the command: 'atomix-uninstall'
2866 Uninstalls Atomix from the designated node, stopping if needed
2867 """
2868 try:
2869 self.handle.sendline( "" )
2870 self.handle.expect( self.prompt, timeout=180 )
2871 self.handle.sendline( "atomix-uninstall " + str( nodeIp ) )
2872 self.handle.expect( self.prompt, timeout=180 )
Jon Hall3c0114c2020-08-11 15:07:42 -07002873 main.log.info( self.name + ": Atomix " + nodeIp + " was uninstalled" )
You Wangf9d95be2018-08-01 14:35:37 -07002874 # onos-uninstall command does not return any text
2875 return main.TRUE
2876 except pexpect.TIMEOUT:
2877 main.log.exception( self.name + ": Timeout in atomixUninstall" )
2878 self.handle.send( "\x03" ) # Control-C
2879 self.handle.expect( self.prompt )
2880 return main.FALSE
2881 except pexpect.EOF:
2882 main.log.error( self.name + ": EOF exception found" )
2883 main.log.error( self.name + ": " + self.handle.before )
2884 main.cleanAndExit()
2885 except Exception:
2886 main.log.exception( self.name + ": Uncaught exception!" )
2887 main.cleanAndExit()
2888
2889 def atomixInstall( self, options="", node="" ):
2890 """
2891 Installs Atomix on the designated nodes.
2892 Returns: main.TRUE on success and main.FALSE on failure
2893 """
2894 try:
2895 if options:
2896 self.handle.sendline( "atomix-install " + options + " " + node )
2897 else:
2898 self.handle.sendline( "atomix-install " + node )
2899 self.handle.expect( "atomix-install " )
2900 i = self.handle.expect( [ "Network\sis\sunreachable",
2901 "is already installed",
2902 "saved",
2903 self.prompt,
2904 pexpect.TIMEOUT ], timeout=180 )
2905 if i == 0:
2906 # can't reach ONOS node
Jon Hall3e6edb32018-08-21 16:20:30 -07002907 main.log.warn( self.name + ": Network is unreachable" )
You Wangf9d95be2018-08-01 14:35:37 -07002908 self.handle.expect( self.prompt )
2909 return main.FALSE
2910 elif i == 1:
2911 # same bits are already on Atomix node
Jon Hall3e6edb32018-08-21 16:20:30 -07002912 main.log.info( self.name + ": Atomix is already installed on " + node )
You Wangf9d95be2018-08-01 14:35:37 -07002913 self.handle.expect( self.prompt )
2914 return main.TRUE
Jon Hallb685a1c2018-10-30 15:17:01 -07002915 elif i == 2:
Jon Hall3e6edb32018-08-21 16:20:30 -07002916 main.log.info( self.name + ": Atomix was installed on " + node )
You Wangf9d95be2018-08-01 14:35:37 -07002917 self.handle.expect( self.prompt )
2918 return main.TRUE
Jon Hallb685a1c2018-10-30 15:17:01 -07002919 elif i == 3:
2920 self.handle.sendline( "echo Return code: $?" )
2921 self.handle.expect( "\$\?" )
2922 self.handle.expect( self.prompt )
Jon Hallb685a1c2018-10-30 15:17:01 -07002923 match = re.search( "Return code: (\d+)", self.handle.before )
2924 if match:
2925 exitCode = int( match.group( 1 ) )
2926 else:
2927 # Didn't match pattern
2928 main.log.error( "Could not parse exit code of atomix-install" )
Jon Hall5e1469a2018-11-01 13:55:53 -07002929 main.log.debug( self.handle.before + self.handle.before )
Jon Hallb685a1c2018-10-30 15:17:01 -07002930 return main.FALSE
2931 if exitCode == 0:
2932 return main.TRUE
2933 else:
Jon Hall5e1469a2018-11-01 13:55:53 -07002934 main.log.error( "Unsuccessful exit code of atomix-install" )
2935 main.log.debug( self.handle.before + self.handle.before )
Jon Hallb685a1c2018-10-30 15:17:01 -07002936 return main.FALSE
You Wangf9d95be2018-08-01 14:35:37 -07002937 elif i == 4:
2938 # timeout
Jon Hall3e6edb32018-08-21 16:20:30 -07002939 main.log.info( self.name + ": Installation of Atomix on " + node + " timed out" )
You Wangf9d95be2018-08-01 14:35:37 -07002940 self.handle.expect( self.prompt )
2941 main.log.warn( self.handle.before )
2942 self.handle.send( "\x03" ) # Control-C
2943 self.handle.expect( self.prompt )
2944 return main.FALSE
2945 except pexpect.EOF:
2946 main.log.error( self.name + ": EOF exception found" )
2947 main.log.error( self.name + ": " + self.handle.before )
2948 main.cleanAndExit()
2949 except Exception:
2950 main.log.exception( self.name + ": Uncaught exception!" )
2951 main.cleanAndExit()
Jon Hall43060f62020-06-23 13:13:33 -07002952
2953 def onosFetchApp( self, url, dstPath=None ):
2954 """
2955 Fetch an external onos app
2956
2957 Required:
2958 url - url for where to download the app
2959 dstPath - where the file will be saved
2960
2961 Returns main.TRUE on successfully fetching file, and main.FALSE if
2962 there is an error.
2963 """
2964 try:
2965 cmd = "wget -q --backups=1 "
2966 if dstPath:
2967 cmd += "-P %s " % ( dstPath )
2968 cmd += str( url )
Jon Hall3c0114c2020-08-11 15:07:42 -07002969 main.log.info( self.name + ": Sending: " + cmd )
2970 self.handle.sendline( cmd )
2971 self.handle.expect( self.prompt )
Jon Hall43060f62020-06-23 13:13:33 -07002972 output = self.handle.before
2973 main.log.debug( output )
2974 if "Error" in output or "No such file or directory" in output:
2975 main.log.error( self.name + ": " + output + self.handle.after )
2976 return main.FALSE
2977 return main.TRUE
2978 except pexpect.EOF:
2979 main.log.error( self.name + ": EOF exception found" )
2980 main.log.error( self.name + ": " + self.handle.before )
2981 main.cleanAndExit()
2982 except Exception:
2983 main.log.exception( self.name + ": Uncaught exception!" )
2984 main.cleanAndExit()
2985
Jon Hall39570262020-11-17 12:18:19 -08002986 def onosApp( self, onosIP, option, fileName, filePath='~/onos/',
2987 appName=None, user=None, password=None ):
Jon Hall43060f62020-06-23 13:13:33 -07002988 """
2989 Wrapper for onos-app script
2990
2991 Required:
2992 - onosIP - The ip address of the onos instance
2993 - option - What command are we doing?
2994 [ list|install|install!|reinstall|reinstall!|activate|deactivate|uninstall ]
2995 - fileName - The name of the app file
2996 Optional Arguments:
Jon Hall39570262020-11-17 12:18:19 -08002997 - appName - The name of the app, some options require this
Jon Hall43060f62020-06-23 13:13:33 -07002998 - filePath - The location of the file
Jon Hall39570262020-11-17 12:18:19 -08002999 - user - ONOS cli user
3000 - password - ONOS cli password
Jon Hall43060f62020-06-23 13:13:33 -07003001
3002 Returns main.TRUE on successfully executing the command, and main.FALSE if
3003 there is an error.
3004 """
3005 # FIXME: Not all options may work, more testing is required, only tested with install(!)
3006 try:
Jon Hall39570262020-11-17 12:18:19 -08003007 cmd = "onos-app %s %s %s %s/%s" % ( onosIP, option, appName if "reinstall" in option else "", filePath, fileName )
3008 if user:
3009 cmd += " -u %s" % user
3010 if password:
3011 cmd += " -p %s" % password
Jon Hall3c0114c2020-08-11 15:07:42 -07003012 main.log.info( self.name + ": Sending: " + cmd )
3013 self.handle.sendline( cmd )
3014 self.handle.expect( self.prompt )
Jon Hall43060f62020-06-23 13:13:33 -07003015 handle = self.handle.before
3016 main.log.debug( handle )
3017 if "Error" in handle or "usage: " in handle or "curl: " in handle:
3018 main.log.error( self.name + ": " + handle + self.handle.after )
3019 return main.FALSE
3020 return main.TRUE
3021 except pexpect.EOF:
3022 main.log.error( self.name + ": EOF exception found" )
3023 main.log.error( self.name + ": " + self.handle.before )
3024 main.cleanAndExit()
3025 except Exception:
3026 main.log.exception( self.name + ": Uncaught exception!" )
3027 main.cleanAndExit()
Jon Hall3c0114c2020-08-11 15:07:42 -07003028
3029 def makeDocker( self, path, cmd, prompt="Successfully tagged", timeout=600 ):
3030 """
3031 Build a docker image using a command, such as make
3032 Arguments:
3033 - path: a path where the script is located. will cd to path
3034 - cmd: the command to run
3035 Optional Arguments:
3036 - prompt: A custom prompt to expect after the command is finished,
3037 incase the host prompt is printed during the build
3038 - timeout: how long to wait for the build
3039 """
3040 try:
3041 main.log.warn( "%s: makeDocker()" % self.name )
3042 self.handle.sendline( "cd %s" % path )
3043 self.handle.expect( self.prompt )
3044 self.handle.sendline( cmd )
3045 self.handle.expect( prompt, timeout=timeout )
3046 fullResponse = self.handle.before
3047 tailResponse = self.handle.after
3048 # TODO: error checking, might be difficult with custom expects
3049 self.handle.expect( self.prompt )
3050 tailResponse += self.handle.before + self.handle.after
3051 fullResponse += tailResponse
3052 main.log.debug( self.name + ": " + tailResponse )
3053 self.handle.sendline( "cd %s" % self.home )
3054 self.handle.expect( self.prompt )
3055 return main.TRUE
3056 except pexpect.EOF:
3057 main.log.error( self.name + ": EOF exception found" )
3058 main.log.error( self.name + ": " + self.handle.before )
3059 main.cleanAndExit()
3060 except Exception:
3061 main.log.exception( self.name + ": Uncaught exception!" )
3062 main.log.debug( self.name + ": " + self.handle.before )
3063 main.cleanAndExit()
3064
3065 def generateOnosConfig( self, nodeIp, path="cluster.json" ):
3066 """
3067 Generate onos cluster configuration file
3068 Arguments:
3069 - nodeIp: ip of the node this file is fore
3070 Optional Arguments:
3071 - The path to save the file to
3072 """
3073 try:
3074 main.log.info( "%s: Generating onos config file for %s" % ( self.name, nodeIp ) )
3075 self.handle.sendline( "onos-gen-config %s %s" % ( nodeIp, path ) )
3076 i = self.handle.expect( [ self.prompt, "not found", "Error" ] )
3077 response = self.handle.before
3078 if i == 0:
3079 main.log.debug( "%s: %s" % ( self.name, response ) )
3080 return main.TRUE
3081 else:
3082 response += self.handle.after
3083 self.handle.expect( self.prompt )
3084 response += self.handle.before
3085 main.log.debug( "%s: %s" % ( self.name, response ) )
3086 return main.FALSE
3087 except pexpect.EOF:
3088 main.log.error( self.name + ": EOF exception found" )
3089 main.log.error( self.name + ": " + self.handle.before )
3090 main.cleanAndExit()
3091 except Exception:
3092 main.log.exception( self.name + ": Uncaught exception!" )
3093 main.log.debug( self.name + ": " + self.handle.before )
3094 main.cleanAndExit()
3095
3096 def generateAtomixConfig( self, nodeIp, path="atomix.json" ):
3097 """
3098 Generate atomix cluster configuration file
3099 Arguments:
3100 - nodeIp: ip of the node this file is fore
3101 Optional Arguments:
3102 - The path to save the file to
3103 """
3104 try:
3105 main.log.info( "%s: Generating atomix config file for %s" % ( self.name, nodeIp ) )
3106 self.handle.sendline( "atomix-gen-config %s %s" % ( nodeIp, path ) )
3107 i = self.handle.expect( [ self.prompt, "not found", "Error" ] )
3108 response = self.handle.before
3109 if i == 0:
3110 main.log.debug( "%s: %s" % ( self.name, response ) )
3111 return main.TRUE
3112 else:
3113 response += self.handle.after
3114 self.handle.expect( self.prompt )
3115 response += self.handle.before
3116 main.log.debug( "%s: %s" % ( self.name, response ) )
3117 return main.FALSE
3118 except pexpect.EOF:
3119 main.log.error( self.name + ": EOF exception found" )
3120 main.log.error( self.name + ": " + self.handle.before )
3121 main.cleanAndExit()
3122 except Exception:
3123 main.log.exception( self.name + ": Uncaught exception!" )
3124 main.log.debug( self.name + ": " + self.handle.before )
3125 main.cleanAndExit()