blob: 78b847706a7a68bc8f29cbdecef1b2c5a6ce834d [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",
Devin Limc20e79a2017-06-07 10:29:57 -07001152 self.prompt,
Jon Hall6c44c0b2016-04-20 15:21:00 -07001153 pexpect.TIMEOUT ], timeout=180 )
Jon Hall7993bfc2014-10-09 16:30:14 -04001154 if i == 0:
Jon Hall3576f572016-08-23 10:01:07 -07001155 # can't reach ONOS node
kelvin8ec71442015-01-15 16:57:00 -08001156 main.log.warn( "Network is unreachable" )
Devin Limc20e79a2017-06-07 10:29:57 -07001157 self.handle.expect( self.prompt )
Jon Hall7993bfc2014-10-09 16:30:14 -04001158 return main.FALSE
1159 elif i == 1:
Jon Hall3576f572016-08-23 10:01:07 -07001160 # Process started
kelvin8ec71442015-01-15 16:57:00 -08001161 main.log.info(
1162 "ONOS was installed on " +
1163 node +
1164 " and started" )
Devin Limc20e79a2017-06-07 10:29:57 -07001165 self.handle.expect( self.prompt )
Jon Hall7993bfc2014-10-09 16:30:14 -04001166 return main.TRUE
You Wangd65ba842018-08-14 11:20:59 -07001167 elif i == 2:
Jon Hall3576f572016-08-23 10:01:07 -07001168 # same bits are already on ONOS node
Jon Hall3c0114c2020-08-11 15:07:42 -07001169 main.log.info( self.name + ": ONOS is already installed on " + node )
Devin Limc20e79a2017-06-07 10:29:57 -07001170 self.handle.expect( self.prompt )
Jeremyc72b2582016-02-26 18:27:38 -08001171 return main.TRUE
You Wangd65ba842018-08-14 11:20:59 -07001172 elif i == 3:
Jon Hall3576f572016-08-23 10:01:07 -07001173 # onos not packaged
1174 main.log.error( "ONOS package not found." )
Devin Limc20e79a2017-06-07 10:29:57 -07001175 self.handle.expect( self.prompt )
Jon Hall3576f572016-08-23 10:01:07 -07001176 return main.FALSE
You Wangd65ba842018-08-14 11:20:59 -07001177 elif i == 4:
Jon Hall3576f572016-08-23 10:01:07 -07001178 # prompt
Jon Hall3c0114c2020-08-11 15:07:42 -07001179 main.log.info( self.name + ": ONOS was installed on {} {}.".format( node,
Jon Hall3e6edb32018-08-21 16:20:30 -07001180 "but not started" if 'n' in options else "and started" ) )
Jeremyc72b2582016-02-26 18:27:38 -08001181 return main.TRUE
You Wangd65ba842018-08-14 11:20:59 -07001182 elif i == 5:
Jon Hall3576f572016-08-23 10:01:07 -07001183 # timeout
kelvin8ec71442015-01-15 16:57:00 -08001184 main.log.info(
1185 "Installation of ONOS on " +
1186 node +
1187 " timed out" )
Devin Limc20e79a2017-06-07 10:29:57 -07001188 self.handle.expect( self.prompt )
Jon Hall53c5e662016-04-13 16:06:56 -07001189 main.log.warn( self.handle.before )
You Wang141b43b2018-06-26 16:50:18 -07001190 self.handle.send( "\x03" ) # Control-C
1191 self.handle.expect( self.prompt )
Jon Hall7993bfc2014-10-09 16:30:14 -04001192 return main.FALSE
andrewonlabc03bf6c2014-10-09 14:56:18 -04001193 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001194 main.log.error( self.name + ": EOF exception found" )
1195 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001196 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001197 except Exception:
1198 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001199 main.cleanAndExit()
andrewonlab95ca1462014-10-09 14:04:24 -04001200
kelvin-onlabd3b64892015-01-20 13:26:24 -08001201 def onosStart( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001202 """
andrewonlab8d0d7d72014-10-09 16:33:15 -04001203 Calls onos command: 'onos-service [<node-ip>] start'
andrewonlabe8e56fd2014-10-09 17:12:44 -04001204 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -08001205 """
andrewonlab8d0d7d72014-10-09 16:33:15 -04001206 try:
kelvin8ec71442015-01-15 16:57:00 -08001207 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001208 self.handle.expect( self.prompt )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001209 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001210 " start" )
1211 i = self.handle.expect( [
andrewonlab8d0d7d72014-10-09 16:33:15 -04001212 "Job\sis\salready\srunning",
1213 "start/running",
Devin Limc20e79a2017-06-07 10:29:57 -07001214 self.prompt,
andrewonlab8d0d7d72014-10-09 16:33:15 -04001215 "Unknown\sinstance",
Jeremy Songster14c13572016-04-21 17:34:03 -07001216 pexpect.TIMEOUT ], timeout=180 )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001217 if i == 0:
Devin Limc20e79a2017-06-07 10:29:57 -07001218 self.handle.expect( self.prompt )
Jon Hall3c0114c2020-08-11 15:07:42 -07001219 main.log.info( self.name + ": Service is already running" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001220 return main.TRUE
1221 elif i == 1:
Devin Limc20e79a2017-06-07 10:29:57 -07001222 self.handle.expect( self.prompt )
Jon Hall3c0114c2020-08-11 15:07:42 -07001223 main.log.info( self.name + ": ONOS service started" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001224 return main.TRUE
Jeremyd0e9a6d2016-03-02 11:28:52 -08001225 elif i == 2:
Jon Hall3c0114c2020-08-11 15:07:42 -07001226 main.log.info( self.name + ": ONOS service started" )
Jeremyd0e9a6d2016-03-02 11:28:52 -08001227 return main.TRUE
andrewonlab8d0d7d72014-10-09 16:33:15 -04001228 else:
Devin Limc20e79a2017-06-07 10:29:57 -07001229 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -08001230 main.log.error( "ONOS service failed to start" )
Devin Lim44075962017-08-11 10:56:37 -07001231
1232 main.cleanAndExit()
andrewonlab8d0d7d72014-10-09 16:33:15 -04001233 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001234 main.log.error( self.name + ": EOF exception found" )
1235 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001236 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001237 except Exception:
1238 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001239 main.cleanAndExit()
andrewonlab8d0d7d72014-10-09 16:33:15 -04001240
kelvin-onlabd3b64892015-01-20 13:26:24 -08001241 def onosStop( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001242 """
andrewonlab2b30bd32014-10-09 16:48:55 -04001243 Calls onos command: 'onos-service [<node-ip>] stop'
andrewonlabe8e56fd2014-10-09 17:12:44 -04001244 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -08001245 """
andrewonlab2b30bd32014-10-09 16:48:55 -04001246 try:
kelvin8ec71442015-01-15 16:57:00 -08001247 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001248 self.handle.expect( self.prompt )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001249 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001250 " stop" )
1251 i = self.handle.expect( [
andrewonlab2b30bd32014-10-09 16:48:55 -04001252 "stop/waiting",
Jon Hall61282e32015-03-19 11:34:11 -07001253 "Could not resolve hostname",
andrewonlab2b30bd32014-10-09 16:48:55 -04001254 "Unknown\sinstance",
Devin Limc20e79a2017-06-07 10:29:57 -07001255 self.prompt,
Jeremy Songster14c13572016-04-21 17:34:03 -07001256 pexpect.TIMEOUT ], timeout=180 )
andrewonlab2b30bd32014-10-09 16:48:55 -04001257 if i == 0:
Devin Limc20e79a2017-06-07 10:29:57 -07001258 self.handle.expect( self.prompt )
Jon Hall3c0114c2020-08-11 15:07:42 -07001259 main.log.info( self.name + ": ONOS service stopped" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001260 return main.TRUE
1261 elif i == 1:
Devin Limc20e79a2017-06-07 10:29:57 -07001262 self.handle.expect( self.prompt )
Jon Hall3c0114c2020-08-11 15:07:42 -07001263 main.log.info( self.name + ": onosStop() Unknown ONOS instance specified: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001264 str( nodeIp ) )
andrewonlab2b30bd32014-10-09 16:48:55 -04001265 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -07001266 elif i == 2:
Devin Limc20e79a2017-06-07 10:29:57 -07001267 self.handle.expect( self.prompt )
Jon Hall61282e32015-03-19 11:34:11 -07001268 main.log.warn( "ONOS wasn't running" )
1269 return main.TRUE
YPZhang77badfc2016-03-09 10:28:59 -08001270 elif i == 3:
Jon Hall3c0114c2020-08-11 15:07:42 -07001271 main.log.info( self.name + ": ONOS service stopped" )
YPZhang77badfc2016-03-09 10:28:59 -08001272 return main.TRUE
andrewonlab2b30bd32014-10-09 16:48:55 -04001273 else:
kelvin8ec71442015-01-15 16:57:00 -08001274 main.log.error( "ONOS service failed to stop" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001275 return main.FALSE
andrewonlab2b30bd32014-10-09 16:48:55 -04001276 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001277 main.log.error( self.name + ": EOF exception found" )
1278 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001279 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001280 except Exception:
1281 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001282 main.cleanAndExit()
kelvin8ec71442015-01-15 16:57:00 -08001283
kelvin-onlabd3b64892015-01-20 13:26:24 -08001284 def onosUninstall( self, nodeIp="" ):
kelvin8ec71442015-01-15 16:57:00 -08001285 """
andrewonlabc8d47972014-10-09 16:52:36 -04001286 Calls the command: 'onos-uninstall'
kelvin8ec71442015-01-15 16:57:00 -08001287 Uninstalls ONOS from the designated cell machine, stopping
andrewonlabe8e56fd2014-10-09 17:12:44 -04001288 if needed
kelvin8ec71442015-01-15 16:57:00 -08001289 """
andrewonlabc8d47972014-10-09 16:52:36 -04001290 try:
kelvin8ec71442015-01-15 16:57:00 -08001291 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001292 self.handle.expect( self.prompt, timeout=180 )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001293 self.handle.sendline( "onos-uninstall " + str( nodeIp ) )
Devin Limc20e79a2017-06-07 10:29:57 -07001294 self.handle.expect( self.prompt, timeout=180 )
Jon Hall3c0114c2020-08-11 15:07:42 -07001295 main.log.info( self.name + ": ONOS " + nodeIp + " was uninstalled" )
kelvin8ec71442015-01-15 16:57:00 -08001296 # onos-uninstall command does not return any text
andrewonlabc8d47972014-10-09 16:52:36 -04001297 return main.TRUE
pingping-lin763ee042015-05-20 17:45:30 -07001298 except pexpect.TIMEOUT:
1299 main.log.exception( self.name + ": Timeout in onosUninstall" )
You Wang141b43b2018-06-26 16:50:18 -07001300 self.handle.send( "\x03" ) # Control-C
1301 self.handle.expect( self.prompt )
pingping-lin763ee042015-05-20 17:45:30 -07001302 return main.FALSE
andrewonlabc8d47972014-10-09 16:52:36 -04001303 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001304 main.log.error( self.name + ": EOF exception found" )
1305 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001306 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001307 except Exception:
1308 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001309 main.cleanAndExit()
andrewonlab2b30bd32014-10-09 16:48:55 -04001310
kelvin-onlabd3b64892015-01-20 13:26:24 -08001311 def onosDie( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001312 """
andrewonlabaedc8332014-12-04 12:43:03 -05001313 Issues the command 'onos-die <node-ip>'
1314 This command calls onos-kill and also stops the node
kelvin8ec71442015-01-15 16:57:00 -08001315 """
andrewonlabaedc8332014-12-04 12:43:03 -05001316 try:
kelvin8ec71442015-01-15 16:57:00 -08001317 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001318 self.handle.expect( self.prompt )
Jon Hall214f88b2020-09-21 10:21:42 -07001319 if self.inDocker:
1320 return self.dockerStop( self.name )
1321 else:
1322 cmdStr = "onos-die " + str( nodeIp )
1323 self.handle.sendline( cmdStr )
1324 i = self.handle.expect( [
1325 "Killing\sONOS",
1326 "ONOS\sprocess\sis\snot\srunning",
1327 pexpect.TIMEOUT ], timeout=60 )
1328 if i == 0:
1329 main.log.info( self.name + ": ONOS instance " + str( nodeIp ) +
1330 " was killed and stopped" )
1331 self.handle.sendline( "" )
1332 self.handle.expect( self.prompt )
1333 return main.TRUE
1334 elif i == 1:
1335 main.log.info( self.name + ": ONOS process was not running" )
1336 self.handle.sendline( "" )
1337 self.handle.expect( self.prompt )
1338 return main.FALSE
andrewonlabaedc8332014-12-04 12:43:03 -05001339 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001340 main.log.error( self.name + ": EOF exception found" )
1341 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001342 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001343 except Exception:
1344 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001345 main.cleanAndExit()
andrewonlabaedc8332014-12-04 12:43:03 -05001346
kelvin-onlabd3b64892015-01-20 13:26:24 -08001347 def onosKill( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001348 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001349 Calls the command: 'onos-kill [<node-ip>]'
1350 "Remotely, and unceremoniously kills the ONOS instance running on
1351 the specified cell machine" - Tom V
kelvin8ec71442015-01-15 16:57:00 -08001352 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001353 try:
kelvin8ec71442015-01-15 16:57:00 -08001354 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001355 self.handle.expect( self.prompt )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001356 self.handle.sendline( "onos-kill " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -08001357 i = self.handle.expect( [
Devin Limc20e79a2017-06-07 10:29:57 -07001358 self.prompt,
andrewonlabe8e56fd2014-10-09 17:12:44 -04001359 "No\sroute\sto\shost",
1360 "password:",
Jeremy Songster14c13572016-04-21 17:34:03 -07001361 pexpect.TIMEOUT ], timeout=60 )
kelvin8ec71442015-01-15 16:57:00 -08001362
andrewonlabe8e56fd2014-10-09 17:12:44 -04001363 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001364 main.log.info(
1365 "ONOS instance " + str(
kelvin-onlabd3b64892015-01-20 13:26:24 -08001366 nodeIp ) + " was killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001367 return main.TRUE
1368 elif i == 1:
Jon Hall3c0114c2020-08-11 15:07:42 -07001369 main.log.info( self.name + ": No route to host" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001370 return main.FALSE
1371 elif i == 2:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001372 main.log.info(
1373 "Passwordless login for host: " +
1374 str( nodeIp ) +
1375 " not configured" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001376 return main.FALSE
1377 else:
Jon Hall3c0114c2020-08-11 15:07:42 -07001378 main.log.info( self.name + ": ONOS instance was not killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001379 return main.FALSE
kelvin8ec71442015-01-15 16:57:00 -08001380
andrewonlabe8e56fd2014-10-09 17:12:44 -04001381 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001382 main.log.error( self.name + ": EOF exception found" )
1383 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001384 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001385 except Exception:
1386 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001387 main.cleanAndExit()
andrewonlabe8e56fd2014-10-09 17:12:44 -04001388
You Wang5bf49592020-07-08 18:47:46 -07001389 def onosAppInstall( self, nodeIp, oarFile ):
1390 """
Jon Hall3c0114c2020-08-11 15:07:42 -07001391 Calls the command: 'onos-app nodeIp reinstall! oarFile'
You Wang5bf49592020-07-08 18:47:46 -07001392 Installs an ONOS application from an oar file
1393 """
1394 try:
Jon Hall3c0114c2020-08-11 15:07:42 -07001395 cmd = "onos-app " + str( nodeIp ) + " reinstall! " + str( oarFile )
You Wang5bf49592020-07-08 18:47:46 -07001396 self.handle.sendline( cmd )
Jon Hall3c0114c2020-08-11 15:07:42 -07001397 i = self.handle.expect( [ "409 Conflict", self.prompt ] )
1398 if i == 0:
1399 self.handle.expect( self.prompt )
1400 time.sleep( 30 )
1401 self.handle.sendline( cmd )
You Wang5bf49592020-07-08 18:47:46 -07001402 handle = self.handle.before
Jon Hall3c0114c2020-08-11 15:07:42 -07001403 main.log.debug( "%s: %s" % ( self.name, handle ) )
You Wang5bf49592020-07-08 18:47:46 -07001404 assert handle is not None, "Error in sendline"
1405 assert "Command not found:" not in handle, handle
1406 assert "error" not in handle, handle
1407 assert "usage:" not in handle, handle
1408 return main.TRUE
1409 except AssertionError:
1410 main.log.exception( "Error in onos-app output" )
1411 return main.FALSE
1412 except pexpect.TIMEOUT:
1413 main.log.exception( self.name + ": Timeout in onosAppInstall" )
1414 self.handle.send( "\x03" ) # Control-C
1415 self.handle.expect( self.prompt )
1416 return main.FALSE
1417 except pexpect.EOF:
1418 main.log.error( self.name + ": EOF exception found" )
1419 main.log.error( self.name + ": " + self.handle.before )
1420 main.cleanAndExit()
1421 except Exception:
1422 main.log.exception( self.name + ": Uncaught exception!" )
1423 main.cleanAndExit()
1424
kelvin-onlabd3b64892015-01-20 13:26:24 -08001425 def onosRemoveRaftLogs( self ):
kelvin8ec71442015-01-15 16:57:00 -08001426 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001427 Removes Raft / Copy cat files from ONOS to ensure
Jon Hallfcc88622014-11-25 13:09:54 -05001428 a cleaner environment.
1429
andrewonlab19fbdca2014-11-14 12:55:59 -05001430 Description:
Jon Hallfcc88622014-11-25 13:09:54 -05001431 Stops all ONOS defined in the cell,
andrewonlab19fbdca2014-11-14 12:55:59 -05001432 wipes the raft / copycat log files
kelvin8ec71442015-01-15 16:57:00 -08001433 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001434 try:
kelvin8ec71442015-01-15 16:57:00 -08001435 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001436 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -08001437 self.handle.sendline( "onos-remove-raft-logs" )
1438 # Sometimes this command hangs
Devin Limc20e79a2017-06-07 10:29:57 -07001439 i = self.handle.expect( [ self.prompt, pexpect.TIMEOUT ],
kelvin8ec71442015-01-15 16:57:00 -08001440 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001441 if i == 1:
Devin Limc20e79a2017-06-07 10:29:57 -07001442 i = self.handle.expect( [ self.prompt, pexpect.TIMEOUT ],
kelvin8ec71442015-01-15 16:57:00 -08001443 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001444 if i == 1:
1445 return main.FALSE
andrewonlab19fbdca2014-11-14 12:55:59 -05001446 return main.TRUE
andrewonlab19fbdca2014-11-14 12:55:59 -05001447 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001448 main.log.error( self.name + ": EOF exception found" )
1449 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001450 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001451 except Exception:
1452 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001453 main.cleanAndExit()
Jon Hallfcc88622014-11-25 13:09:54 -05001454
kelvin-onlabd3b64892015-01-20 13:26:24 -08001455 def onosStartNetwork( self, mntopo ):
kelvin8ec71442015-01-15 16:57:00 -08001456 """
1457 Calls the command 'onos-start-network [ <mininet-topo> ]
1458 "remotely starts the specified topology on the cell's
andrewonlab94282092014-10-10 13:00:11 -04001459 mininet machine against all controllers configured in the
kelvin8ec71442015-01-15 16:57:00 -08001460 cell."
andrewonlab94282092014-10-10 13:00:11 -04001461 * Specify mininet topology file name for mntopo
1462 * Topo files should be placed at:
1463 ~/<your-onos-directory>/tools/test/topos
kelvin8ec71442015-01-15 16:57:00 -08001464
andrewonlab94282092014-10-10 13:00:11 -04001465 NOTE: This function will take you to the mininet prompt
kelvin8ec71442015-01-15 16:57:00 -08001466 """
andrewonlab94282092014-10-10 13:00:11 -04001467 try:
1468 if not mntopo:
kelvin8ec71442015-01-15 16:57:00 -08001469 main.log.error( "You must specify a topo file to execute" )
andrewonlab94282092014-10-10 13:00:11 -04001470 return main.FALSE
andrewonlab94282092014-10-10 13:00:11 -04001471
kelvin8ec71442015-01-15 16:57:00 -08001472 mntopo = str( mntopo )
1473 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001474 self.handle.expect( self.prompt )
andrewonlab94282092014-10-10 13:00:11 -04001475
kelvin8ec71442015-01-15 16:57:00 -08001476 self.handle.sendline( "onos-start-network " + mntopo )
1477 self.handle.expect( "mininet>" )
Jon Hall3c0114c2020-08-11 15:07:42 -07001478 main.log.info( self.name + ": Network started, entered mininet prompt" )
kelvin8ec71442015-01-15 16:57:00 -08001479
1480 # TODO: Think about whether return is necessary or not
andrewonlab94282092014-10-10 13:00:11 -04001481
1482 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001483 main.log.error( self.name + ": EOF exception found" )
1484 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001485 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001486 except Exception:
1487 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001488 main.cleanAndExit()
andrewonlab94282092014-10-10 13:00:11 -04001489
Jeremy Songster14c13572016-04-21 17:34:03 -07001490 def isup( self, node="", timeout=240 ):
kelvin8ec71442015-01-15 16:57:00 -08001491 """
1492 Run's onos-wait-for-start which only returns once ONOS is at run
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001493 level 100(ready for use)
andrewonlab8d0d7d72014-10-09 16:33:15 -04001494
Jon Hall7993bfc2014-10-09 16:30:14 -04001495 Returns: main.TRUE if ONOS is running and main.FALSE on timeout
kelvin8ec71442015-01-15 16:57:00 -08001496 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001497 try:
Jon Hall3b489db2015-10-05 14:38:37 -07001498 self.handle.sendline( "onos-wait-for-start " + node )
1499 self.handle.expect( "onos-wait-for-start" )
kelvin8ec71442015-01-15 16:57:00 -08001500 # NOTE: this timeout is arbitrary"
Jon Hallcababf72018-02-05 12:05:19 -08001501 i = self.handle.expect( [ self.prompt, pexpect.TIMEOUT, "Password:" ], timeout )
Jon Hall7993bfc2014-10-09 16:30:14 -04001502 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001503 main.log.info( self.name + ": " + node + " is up" )
You Wangb65f2e92018-12-21 11:31:34 -08001504 # FIXME: for now we sleep 5s for CLI to become ready
1505 time.sleep( 5 )
Jon Hall7993bfc2014-10-09 16:30:14 -04001506 return main.TRUE
Jon Hallcababf72018-02-05 12:05:19 -08001507 elif i == 1 or i == 2:
kelvin8ec71442015-01-15 16:57:00 -08001508 # NOTE: since this function won't return until ONOS is ready,
Jon Hall7993bfc2014-10-09 16:30:14 -04001509 # we will kill it on timeout
Jon Hallcababf72018-02-05 12:05:19 -08001510 if i == 1:
Jon Hall3e6edb32018-08-21 16:20:30 -07001511 main.log.error( "{}: ONOS {} has not started yet".format( self.name, node ) )
Jon Hallcababf72018-02-05 12:05:19 -08001512 elif i == 2:
Jon Hall3e6edb32018-08-21 16:20:30 -07001513 main.log.error( "{}: Cannot login to ONOS CLI {}, try using onos-secure-ssh".format( self.name, node ) )
kelvin8ec71442015-01-15 16:57:00 -08001514 self.handle.send( "\x03" ) # Control-C
Devin Limc20e79a2017-06-07 10:29:57 -07001515 self.handle.expect( self.prompt )
Jon Hall7993bfc2014-10-09 16:30:14 -04001516 return main.FALSE
1517 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001518 main.log.error( self.name + ": EOF exception found" )
1519 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001520 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001521 except Exception:
1522 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001523 main.cleanAndExit()
andrewonlab05e362f2014-10-10 00:40:57 -04001524
Devin Lim142b5342017-07-20 15:22:39 -07001525 def preventAutoRespawn( self ):
1526 """
1527 Description:
1528 This will prevent ONOSservice to automatically
1529 respawn.
1530 """
1531 try:
1532 self.handle.sendline( "sed -i -e 's/^respawn$/#respawn/g' tools/package/init/onos.conf" )
1533 self.handle.expect( "\$" ) # $ from the command
1534 self.handle.sendline( "sed -i -e 's/^Restart=always/Restart=no/g' tools/package/init/onos.service" )
1535 self.handle.expect( "\$" ) # $ from the command
1536 self.handle.expect( "\$" ) # $ from the prompt
1537 except pexpect.EOF:
1538 main.log.error( self.name + ": EOF exception found" )
1539 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001540 main.cleanAndExit()
Devin Lim142b5342017-07-20 15:22:39 -07001541 except Exception:
1542 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001543 main.cleanAndExit()
Devin Lim142b5342017-07-20 15:22:39 -07001544
kelvin-onlabd3b64892015-01-20 13:26:24 -08001545 def pushTestIntentsShell(
1546 self,
1547 dpidSrc,
1548 dpidDst,
1549 numIntents,
1550 dirFile,
1551 onosIp,
1552 numMult="",
1553 appId="",
1554 report=True,
1555 options="" ):
kelvin8ec71442015-01-15 16:57:00 -08001556 """
andrewonlabb66dfa12014-12-02 15:51:10 -05001557 Description:
kelvin8ec71442015-01-15 16:57:00 -08001558 Use the linux prompt to push test intents to
andrewonlabb66dfa12014-12-02 15:51:10 -05001559 better parallelize the results than the CLI
1560 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001561 * dpidSrc: specify source dpid
1562 * dpidDst: specify destination dpid
1563 * numIntents: specify number of intents to push
1564 * dirFile: specify directory and file name to save
andrewonlabb66dfa12014-12-02 15:51:10 -05001565 results
kelvin-onlabd3b64892015-01-20 13:26:24 -08001566 * onosIp: specify the IP of ONOS to install on
kelvin8ec71442015-01-15 16:57:00 -08001567 NOTE:
andrewonlabb66dfa12014-12-02 15:51:10 -05001568 You must invoke this command at linux shell prompt
kelvin8ec71442015-01-15 16:57:00 -08001569 """
1570 try:
1571 # Create the string to sendline
andrewonlabaedc8332014-12-04 12:43:03 -05001572 if options:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001573 baseCmd = "onos " + str( onosIp ) + " push-test-intents " +\
kelvin8ec71442015-01-15 16:57:00 -08001574 options + " "
andrewonlabaedc8332014-12-04 12:43:03 -05001575 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001576 baseCmd = "onos " + str( onosIp ) + " push-test-intents "
kelvin8ec71442015-01-15 16:57:00 -08001577
kelvin-onlabd3b64892015-01-20 13:26:24 -08001578 addDpid = baseCmd + str( dpidSrc ) + " " + str( dpidDst )
1579 if not numMult:
1580 addIntents = addDpid + " " + str( numIntents )
1581 elif numMult:
1582 addIntents = addDpid + " " + str( numIntents ) + " " +\
1583 str( numMult )
1584 if appId:
1585 addApp = addIntents + " " + str( appId )
andrewonlabb66dfa12014-12-02 15:51:10 -05001586 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001587 addApp = addIntents
andrewonlabb66dfa12014-12-02 15:51:10 -05001588
andrewonlabaedc8332014-12-04 12:43:03 -05001589 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001590 sendCmd = addApp + " > " + str( dirFile ) + " &"
andrewonlabaedc8332014-12-04 12:43:03 -05001591 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001592 sendCmd = addApp + " &"
Jon Hall3c0114c2020-08-11 15:07:42 -07001593 main.log.info( self.name + ": Send cmd: " + sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001594
kelvin-onlabd3b64892015-01-20 13:26:24 -08001595 self.handle.sendline( sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001596
1597 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001598 main.log.error( self.name + ": EOF exception found" )
1599 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001600 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001601 except Exception:
1602 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001603 main.cleanAndExit()
andrewonlab05e362f2014-10-10 00:40:57 -04001604
kelvin-onlabd3b64892015-01-20 13:26:24 -08001605 def tsharkPcap( self, interface, dirFile ):
kelvin8ec71442015-01-15 16:57:00 -08001606 """
andrewonlab970399c2014-11-07 13:09:32 -05001607 Capture all packet activity and store in specified
1608 directory/file
1609
1610 Required:
1611 * interface: interface to capture
1612 * dir: directory/filename to store pcap
kelvin8ec71442015-01-15 16:57:00 -08001613 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001614 try:
1615 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001616 self.handle.expect( self.prompt )
andrewonlab970399c2014-11-07 13:09:32 -05001617
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001618 self.handle.sendline( "tshark -i " + str( interface ) + " -t e -w " + str( dirFile ) + " &" )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001619 self.handle.sendline( "\n" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001620 self.handle.expect( "Capturing on" )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001621 self.handle.sendline( "\n" )
Devin Limc20e79a2017-06-07 10:29:57 -07001622 self.handle.expect( self.prompt )
andrewonlab970399c2014-11-07 13:09:32 -05001623
Jon Hall3c0114c2020-08-11 15:07:42 -07001624 main.log.info( self.name + ": Tshark started capturing files on " +
Jon Hallfebb1c72015-03-05 13:30:09 -08001625 str( interface ) + " and saving to directory: " +
1626 str( dirFile ) )
1627 except pexpect.EOF:
1628 main.log.error( self.name + ": EOF exception found" )
1629 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001630 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001631 except Exception:
1632 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001633 main.cleanAndExit()
Shreya Shaha73aaad2014-10-27 18:03:09 -04001634
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001635 def onosTopoCfg( self, onosIp, jsonFile ):
kelvin8ec71442015-01-15 16:57:00 -08001636 """
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001637 Description:
1638 Execute onos-topo-cfg command
1639 Required:
1640 onosIp - IP of the onos node you want to send the json to
1641 jsonFile - File path of the json file
1642 Return:
1643 Returns main.TRUE if the command is successfull; Returns
1644 main.FALSE if there was an error
kelvin8ec71442015-01-15 16:57:00 -08001645 """
shahshreyae6c7cf42014-11-26 16:39:01 -08001646 try:
kelvin8ec71442015-01-15 16:57:00 -08001647 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001648 self.handle.expect( self.prompt )
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001649 cmd = "onos-topo-cfg "
1650 self.handle.sendline( cmd + str( onosIp ) + " " + jsonFile )
1651 handle = self.handle.before
1652 print handle
1653 if "Error" in handle:
1654 main.log.error( self.name + ": " + self.handle.before )
1655 return main.FALSE
1656 else:
Devin Limc20e79a2017-06-07 10:29:57 -07001657 self.handle.expect( self.prompt )
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001658 return main.TRUE
1659
Jon Hallfebb1c72015-03-05 13:30:09 -08001660 except pexpect.EOF:
1661 main.log.error( self.name + ": EOF exception found" )
1662 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001663 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001664 except Exception:
1665 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001666 main.cleanAndExit()
kelvin8ec71442015-01-15 16:57:00 -08001667
jenkins1e99e7b2015-04-02 18:15:39 -07001668 def tsharkGrep( self, grep, directory, interface='eth0', grepOptions='' ):
kelvin8ec71442015-01-15 16:57:00 -08001669 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001670 Required:
kelvin8ec71442015-01-15 16:57:00 -08001671 * grep string
andrewonlabba44bcf2014-10-16 16:54:41 -04001672 * directory to store results
1673 Optional:
1674 * interface - default: eth0
Jon Hall4ba53f02015-07-29 13:07:41 -07001675 * grepOptions - options for grep
andrewonlabba44bcf2014-10-16 16:54:41 -04001676 Description:
1677 Uses tshark command to grep specific group of packets
1678 and stores the results to specified directory.
kelvin8ec71442015-01-15 16:57:00 -08001679 The timestamp is hardcoded to be in epoch
1680 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001681 try:
1682 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001683 self.handle.expect( self.prompt )
Jon Hallfebb1c72015-03-05 13:30:09 -08001684 self.handle.sendline( "" )
jenkins1e99e7b2015-04-02 18:15:39 -07001685 if grepOptions:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001686 grepStr = "grep " + str( grepOptions )
jenkins1e99e7b2015-04-02 18:15:39 -07001687 else:
1688 grepStr = "grep"
Jon Hall4ba53f02015-07-29 13:07:41 -07001689
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001690 cmd = (
1691 "sudo tshark -i " +
Jon Hallfebb1c72015-03-05 13:30:09 -08001692 str( interface ) +
jenkins1e99e7b2015-04-02 18:15:39 -07001693 " -t e | " +
1694 grepStr + " --line-buffered \"" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001695 str( grep ) +
Jon Hallfebb1c72015-03-05 13:30:09 -08001696 "\" >" +
1697 directory +
1698 " &" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001699 self.handle.sendline( cmd )
1700 main.log.info( cmd )
Jon Hallfebb1c72015-03-05 13:30:09 -08001701 self.handle.expect( "Capturing on" )
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001702 self.handle.sendline( "\n" )
Devin Limc20e79a2017-06-07 10:29:57 -07001703 self.handle.expect( self.prompt )
Jon Hallfebb1c72015-03-05 13:30:09 -08001704 except pexpect.EOF:
1705 main.log.error( self.name + ": EOF exception found" )
1706 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001707 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001708 except Exception:
1709 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001710 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001711
kelvin-onlabd3b64892015-01-20 13:26:24 -08001712 def tsharkStop( self ):
kelvin8ec71442015-01-15 16:57:00 -08001713 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001714 Removes wireshark files from /tmp and kills all tshark processes
kelvin8ec71442015-01-15 16:57:00 -08001715 """
1716 # Remove all pcap from previous captures
Jon Hallfebb1c72015-03-05 13:30:09 -08001717 try:
1718 self.execute( cmd="sudo rm /tmp/wireshark*" )
1719 self.handle.sendline( "" )
Jon Hallefbd9792015-03-05 16:11:36 -08001720 self.handle.sendline( "sudo kill -9 `ps -ef | grep \"tshark -i\"" +
1721 " | grep -v grep | awk '{print $2}'`" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001722 self.handle.sendline( "" )
Jon Hall3c0114c2020-08-11 15:07:42 -07001723 main.log.info( self.name + ": Tshark stopped" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001724 except pexpect.EOF:
1725 main.log.error( self.name + ": EOF exception found" )
1726 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001727 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001728 except Exception:
1729 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001730 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001731
kelvin8ec71442015-01-15 16:57:00 -08001732 def ptpd( self, args ):
1733 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001734 Initiate ptp with user-specified args.
1735 Required:
1736 * args: specify string of args after command
1737 'sudo ptpd'
kelvin8ec71442015-01-15 16:57:00 -08001738 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001739 try:
kelvin8ec71442015-01-15 16:57:00 -08001740 self.handle.sendline( "sudo ptpd " + str( args ) )
1741 i = self.handle.expect( [
andrewonlab0c38a4a2014-10-28 18:35:35 -04001742 "Multiple",
1743 "Error",
Devin Limc20e79a2017-06-07 10:29:57 -07001744 self.prompt ] )
1745 self.handle.expect( self.prompt )
andrewonlabba44bcf2014-10-16 16:54:41 -04001746
andrewonlab0c38a4a2014-10-28 18:35:35 -04001747 if i == 0:
1748 handle = self.handle.before
Jon Hall3c0114c2020-08-11 15:07:42 -07001749 main.log.info( self.name + ": ptpd returned an error: " +
kelvin8ec71442015-01-15 16:57:00 -08001750 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001751 return handle
1752 elif i == 1:
1753 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001754 main.log.error( "ptpd returned an error: " +
1755 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001756 return handle
1757 else:
1758 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -08001759
andrewonlab0c38a4a2014-10-28 18:35:35 -04001760 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001761 main.log.error( self.name + ": EOF exception found" )
1762 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001763 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001764 except Exception:
1765 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001766 main.cleanAndExit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001767
Jon Hall06fd0df2021-01-25 15:50:06 -08001768 def dumpONOSCmd( self, ONOSIp, CMD, destDir, filename, options="", cliPort=8101, timeout=60 ):
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001769 """
Pier50f0bc62016-09-07 17:53:40 -07001770 Dump Cmd to a desired directory.
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001771 For debugging purposes, you may want to use
Pier50f0bc62016-09-07 17:53:40 -07001772 this function to capture Cmd at a given point in time.
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001773 Localtime will be attached to the filename
1774
1775 Required:
1776 * ONOSIp: the IP of the target ONOS instance
Pier50f0bc62016-09-07 17:53:40 -07001777 * CMD: the command to dump;
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001778 * destDir: specify directory to copy to.
1779 ex ) /tmp/
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001780 * fileName: Name of the file
You Wang54b1d672018-06-11 16:44:13 -07001781 Optional:
Pier50f0bc62016-09-07 17:53:40 -07001782 * options: Options for ONOS command
You Wang54b1d672018-06-11 16:44:13 -07001783 * timeout: pexpect timeout for running the ONOS command
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001784 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001785
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001786 localtime = time.strftime( '%x %X' )
1787 localtime = localtime.replace( "/", "" )
1788 localtime = localtime.replace( " ", "_" )
1789 localtime = localtime.replace( ":", "" )
1790 if destDir[ -1: ] != "/":
1791 destDir += "/"
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001792 cmd = CMD + " " + options + " > " + str( destDir ) + str( filename ) + localtime
Jon Hall06fd0df2021-01-25 15:50:06 -08001793 return self.onosCli( ONOSIp, cmd, cliPort=cliPort, timeout=timeout )
Flavio Castrob7718952016-05-18 08:53:41 -07001794
kelvin-onlabd3b64892015-01-20 13:26:24 -08001795 def cpLogsToDir( self, logToCopy,
Jon Hallefbd9792015-03-05 16:11:36 -08001796 destDir, copyFileName="" ):
kelvin8ec71442015-01-15 16:57:00 -08001797 """
1798 Copies logs to a desired directory.
andrewonlab5d7a8f32014-11-10 13:07:56 -05001799 Current implementation of ONOS deletes its karaf
1800 logs on every iteration. For debugging purposes,
kelvin8ec71442015-01-15 16:57:00 -08001801 you may want to use this function to capture
1802 certain karaf logs. ( or any other logs if needed )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001803 Localtime will be attached to the filename
1804
1805 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001806 * logToCopy: specify directory and log name to
andrewonlab5d7a8f32014-11-10 13:07:56 -05001807 copy.
kelvin8ec71442015-01-15 16:57:00 -08001808 ex ) /opt/onos/log/karaf.log.1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001809 For copying multiple files, leave copyFileName
1810 empty and only specify destDir -
kelvin8ec71442015-01-15 16:57:00 -08001811 ex ) /opt/onos/log/karaf*
kelvin-onlabd3b64892015-01-20 13:26:24 -08001812 * destDir: specify directory to copy to.
kelvin8ec71442015-01-15 16:57:00 -08001813 ex ) /tmp/
1814 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001815 * copyFileName: If you want to rename the log
1816 file, specify copyFileName. This will not work
andrewonlab5d7a8f32014-11-10 13:07:56 -05001817 with multiple file copying
kelvin8ec71442015-01-15 16:57:00 -08001818 """
andrewonlab5d7a8f32014-11-10 13:07:56 -05001819 try:
Flavio Castro09ab59d2016-05-25 17:01:35 -07001820 localtime = time.strftime( '%H %M' )
kelvin8ec71442015-01-15 16:57:00 -08001821 localtime = localtime.replace( "/", "" )
1822 localtime = localtime.replace( " ", "_" )
1823 localtime = localtime.replace( ":", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001824 if destDir[ -1: ] != "/":
1825 destDir += "/"
andrewonlab5d7a8f32014-11-10 13:07:56 -05001826
kelvin-onlabd3b64892015-01-20 13:26:24 -08001827 if copyFileName:
Jon Hallfebb1c72015-03-05 13:30:09 -08001828 self.handle.sendline( "cp " + str( logToCopy ) + " " +
1829 str( destDir ) + str( copyFileName ) +
1830 localtime )
kelvin8ec71442015-01-15 16:57:00 -08001831 self.handle.expect( "cp" )
Devin Limc20e79a2017-06-07 10:29:57 -07001832 self.handle.expect( self.prompt )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001833 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001834 self.handle.sendline( "cp " + str( logToCopy ) +
1835 " " + str( destDir ) )
kelvin8ec71442015-01-15 16:57:00 -08001836 self.handle.expect( "cp" )
Devin Limc20e79a2017-06-07 10:29:57 -07001837 self.handle.expect( self.prompt )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001838
kelvin8ec71442015-01-15 16:57:00 -08001839 return self.handle.before
1840
1841 except pexpect.EOF:
1842 main.log.error( "Copying files failed" )
1843 main.log.error( self.name + ": EOF exception found" )
1844 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001845 except Exception:
1846 main.log.exception( "Copying files failed" )
1847
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001848 def checkLogs( self, onosIp, restart=False ):
kelvin8ec71442015-01-15 16:57:00 -08001849 """
Jon Hall94fd0472014-12-08 11:52:42 -08001850 runs onos-check-logs on the given onos node
Jon Hall80daded2015-05-27 16:07:00 -07001851 If restart is True, use the old version of onos-check-logs which
1852 does not print the full stacktrace, but shows the entire log file,
1853 including across restarts
Jon Hall94fd0472014-12-08 11:52:42 -08001854 returns the response
kelvin8ec71442015-01-15 16:57:00 -08001855 """
Jon Hall94fd0472014-12-08 11:52:42 -08001856 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001857 cmd = "onos-check-logs " + str( onosIp )
Jon Hall16b72c42015-05-20 10:23:36 -07001858 if restart:
1859 cmd += " old"
kelvin8ec71442015-01-15 16:57:00 -08001860 self.handle.sendline( cmd )
1861 self.handle.expect( cmd )
Devin Limdc78e202017-06-09 18:30:07 -07001862 self.handle.expect( self.prompt + " " )
Jon Hall94fd0472014-12-08 11:52:42 -08001863 response = self.handle.before
1864 return response
1865 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001866 main.log.error( "Lost ssh connection" )
1867 main.log.error( self.name + ": EOF exception found" )
1868 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001869 except Exception:
1870 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001871 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001872
kelvin-onlabd3b64892015-01-20 13:26:24 -08001873 def onosStatus( self, node="" ):
kelvin8ec71442015-01-15 16:57:00 -08001874 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001875 Calls onos command: 'onos-service [<node-ip>] status'
kelvin8ec71442015-01-15 16:57:00 -08001876 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001877 try:
kelvin8ec71442015-01-15 16:57:00 -08001878 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001879 self.handle.expect( self.prompt )
kelvin8ec71442015-01-15 16:57:00 -08001880 self.handle.sendline( "onos-service " + str( node ) +
1881 " status" )
1882 i = self.handle.expect( [
You Wangef1e6572016-03-08 12:53:18 -08001883 "start/running",
You Wang7bd83062016-03-01 11:50:00 -08001884 "Running ...",
You Wangef1e6572016-03-08 12:53:18 -08001885 "stop/waiting",
You Wang7bd83062016-03-01 11:50:00 -08001886 "Not Running ...",
kelvin8ec71442015-01-15 16:57:00 -08001887 pexpect.TIMEOUT ], timeout=120 )
YPZhangfebf7302016-05-24 16:45:56 -07001888 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001889 self.handle.expect( self.prompt )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001890
You Wangef1e6572016-03-08 12:53:18 -08001891 if i == 0 or i == 1:
Jon Hall3c0114c2020-08-11 15:07:42 -07001892 main.log.info( self.name + ": ONOS is running" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001893 return main.TRUE
You Wangef1e6572016-03-08 12:53:18 -08001894 elif i == 2 or i == 3:
Jon Hall3c0114c2020-08-11 15:07:42 -07001895 main.log.info( self.name + ": ONOS is stopped" )
kelvin8ec71442015-01-15 16:57:00 -08001896 main.log.error( "ONOS service failed to check the status" )
Devin Lim44075962017-08-11 10:56:37 -07001897
1898 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001899 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001900 main.log.error( self.name + ": EOF exception found" )
1901 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001902 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001903 except Exception:
1904 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001905 main.cleanAndExit()
Jon Hall21270ac2015-02-16 17:59:55 -08001906
Jon Hall63604932015-02-26 17:09:50 -08001907 def setIpTables( self, ip, port='', action='add', packet_type='',
1908 direction='INPUT', rule='DROP', states=True ):
Jon Hallefbd9792015-03-05 16:11:36 -08001909 """
Jon Hall21270ac2015-02-16 17:59:55 -08001910 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001911 add or remove iptables rule to DROP (default) packets from
Jon Hall21270ac2015-02-16 17:59:55 -08001912 specific IP and PORT
1913 Usage:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001914 * specify action ('add' or 'remove')
Jon Hall21270ac2015-02-16 17:59:55 -08001915 when removing, pass in the same argument as you would add. It will
1916 delete that specific rule.
1917 * specify the ip to block
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001918 * specify the destination port to block (defaults to all ports)
1919 * optional packet type to block (default tcp)
1920 * optional iptables rule (default DROP)
1921 * optional direction to block (default 'INPUT')
Jon Hall63604932015-02-26 17:09:50 -08001922 * States boolean toggles adding all supported tcp states to the
1923 firewall rule
Jon Hall21270ac2015-02-16 17:59:55 -08001924 Returns:
1925 main.TRUE on success or
1926 main.FALSE if given invalid input or
1927 main.ERROR if there is an error in response from iptables
1928 WARNING:
1929 * This function uses root privilege iptables command which may result
1930 in unwanted network errors. USE WITH CAUTION
Jon Hallefbd9792015-03-05 16:11:36 -08001931 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00001932
Jon Hall21270ac2015-02-16 17:59:55 -08001933 # NOTE*********
1934 # The strict checking methods of this driver function is intentional
1935 # to discourage any misuse or error of iptables, which can cause
1936 # severe network errors
1937 # *************
1938
1939 # NOTE: Sleep needed to give some time for rule to be added and
1940 # registered to the instance. If you are calling this function
1941 # multiple times this sleep will prevent any errors.
1942 # DO NOT REMOVE
Jon Hall63604932015-02-26 17:09:50 -08001943 # time.sleep( 5 )
Jon Hall21270ac2015-02-16 17:59:55 -08001944 try:
1945 # input validation
1946 action_type = action.lower()
1947 rule = rule.upper()
1948 direction = direction.upper()
1949 if action_type != 'add' and action_type != 'remove':
1950 main.log.error( "Invalid action type. Use 'add' or "
1951 "'remove' table rule" )
1952 if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
1953 # NOTE Currently only supports rules DROP, ACCEPT, and LOG
1954 main.log.error( "Invalid rule. Valid rules are 'DROP' or "
1955 "'ACCEPT' or 'LOG' only." )
1956 if direction != 'INPUT' and direction != 'OUTPUT':
1957 # NOTE currently only supports rules INPUT and OUPTUT
1958 main.log.error( "Invalid rule. Valid directions are"
1959 " 'OUTPUT' or 'INPUT'" )
1960 return main.FALSE
1961 return main.FALSE
1962 return main.FALSE
1963 if action_type == 'add':
1964 # -A is the 'append' action of iptables
1965 actionFlag = '-A'
1966 elif action_type == 'remove':
1967 # -D is the 'delete' rule of iptables
1968 actionFlag = '-D'
1969 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07001970 self.handle.expect( self.prompt )
Jon Hall21270ac2015-02-16 17:59:55 -08001971 cmd = "sudo iptables " + actionFlag + " " +\
1972 direction +\
Jon Hall21270ac2015-02-16 17:59:55 -08001973 " -s " + str( ip )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001974 # " -p " + str( packet_type ) +\
Jon Hall63604932015-02-26 17:09:50 -08001975 if packet_type:
1976 cmd += " -p " + str( packet_type )
Jon Hall21270ac2015-02-16 17:59:55 -08001977 if port:
1978 cmd += " --dport " + str( port )
Jon Hall63604932015-02-26 17:09:50 -08001979 if states:
1980 cmd += " -m state --state="
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001981 # FIXME- Allow user to configure which states to block
Jon Hall63604932015-02-26 17:09:50 -08001982 cmd += "INVALID,ESTABLISHED,NEW,RELATED,UNTRACKED"
Jon Hall21270ac2015-02-16 17:59:55 -08001983 cmd += " -j " + str( rule )
1984
1985 self.handle.sendline( cmd )
Devin Limc20e79a2017-06-07 10:29:57 -07001986 self.handle.expect( self.prompt )
Jon Hall21270ac2015-02-16 17:59:55 -08001987 main.log.warn( self.handle.before )
1988
1989 info_string = "On " + str( self.name )
1990 info_string += " " + str( action_type )
1991 info_string += " iptable rule [ "
1992 info_string += " IP: " + str( ip )
1993 info_string += " Port: " + str( port )
1994 info_string += " Rule: " + str( rule )
1995 info_string += " Direction: " + str( direction ) + " ]"
1996 main.log.info( info_string )
1997 return main.TRUE
1998 except pexpect.TIMEOUT:
1999 main.log.exception( self.name + ": Timeout exception in "
2000 "setIpTables function" )
You Wang141b43b2018-06-26 16:50:18 -07002001 self.handle.send( "\x03" ) # Control-C
2002 self.handle.expect( self.prompt )
Jon Hall21270ac2015-02-16 17:59:55 -08002003 return main.ERROR
2004 except pexpect.EOF:
2005 main.log.error( self.name + ": EOF exception found" )
2006 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002007 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002008 except Exception:
2009 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002010 main.cleanAndExit()
Jon Hall21270ac2015-02-16 17:59:55 -08002011
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002012 def detailed_status( self, log_filename ):
Jon Hallefbd9792015-03-05 16:11:36 -08002013 """
Jon Hall0468b042015-02-19 19:08:21 -08002014 This method is used by STS to check the status of the controller
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002015 Reports RUNNING, STARTING, STOPPED, FROZEN, ERROR (and reason)
Jon Hallefbd9792015-03-05 16:11:36 -08002016 """
Jon Hall0468b042015-02-19 19:08:21 -08002017 import re
2018 try:
2019 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07002020 self.handle.expect( self.prompt )
Jon Hall0468b042015-02-19 19:08:21 -08002021 self.handle.sendline( "cd " + self.home )
Devin Limc20e79a2017-06-07 10:29:57 -07002022 self.handle.expect( self.prompt )
Jon Hall0468b042015-02-19 19:08:21 -08002023 self.handle.sendline( "service onos status" )
Devin Limc20e79a2017-06-07 10:29:57 -07002024 self.handle.expect( self.prompt )
Jon Hall0468b042015-02-19 19:08:21 -08002025 response = self.handle.before
2026 if re.search( "onos start/running", response ):
2027 # onos start/running, process 10457
2028 return 'RUNNING'
2029 # FIXME: Implement this case
2030 # elif re.search( pattern, response ):
2031 # return 'STARTING'
2032 elif re.search( "onos stop/", response ):
2033 # onos stop/waiting
2034 # FIXME handle this differently?: onos stop/pre-stop
2035 return 'STOPPED'
2036 # FIXME: Implement this case
2037 # elif re.search( pattern, response ):
2038 # return 'FROZEN'
2039 else:
2040 main.log.warn( self.name +
Jon Hallefbd9792015-03-05 16:11:36 -08002041 " WARNING: status received unknown response" )
Jon Hall0468b042015-02-19 19:08:21 -08002042 main.log.warn( response )
2043 return 'ERROR', "Unknown response: %s" % response
2044 except pexpect.TIMEOUT:
2045 main.log.exception( self.name + ": Timeout exception in "
2046 "setIpTables function" )
You Wang141b43b2018-06-26 16:50:18 -07002047 self.handle.send( "\x03" ) # Control-C
2048 self.handle.expect( self.prompt )
Jon Hall0468b042015-02-19 19:08:21 -08002049 return 'ERROR', "Pexpect Timeout"
2050 except pexpect.EOF:
2051 main.log.error( self.name + ": EOF exception found" )
2052 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002053 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002054 except Exception:
2055 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002056 main.cleanAndExit()
Jon Hall0468b042015-02-19 19:08:21 -08002057
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002058 def createLinkGraphFile( self, benchIp, ONOSIpList, deviceCount ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002059 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07002060 Create/formats the LinkGraph.cfg file based on arguments
2061 -only creates a linear topology and connects islands
2062 -evenly distributes devices
andrew@onlab.us3b087132015-03-11 15:00:08 -07002063 -must be called by ONOSbench
2064
Jon Hall4ba53f02015-07-29 13:07:41 -07002065 ONOSIpList - list of all of the node IPs to be used
2066
2067 deviceCount - number of switches to be assigned
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002068 '''
Jon Hall3c0114c2020-08-11 15:07:42 -07002069 main.log.info( self.name + ": Creating link graph configuration file." )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002070 linkGraphPath = self.home + "/tools/package/etc/linkGraph.cfg"
Jon Hall4ba53f02015-07-29 13:07:41 -07002071 tempFile = "/tmp/linkGraph.cfg"
andrew@onlab.us3b087132015-03-11 15:00:08 -07002072
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002073 linkGraph = open( tempFile, 'w+' )
2074 linkGraph.write( "# NullLinkProvider topology description (config file).\n" )
2075 linkGraph.write( "# The NodeId is only added if the destination is another node's device.\n" )
2076 linkGraph.write( "# Bugs: Comments cannot be appended to a line to be read.\n" )
Jon Hall4ba53f02015-07-29 13:07:41 -07002077
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002078 clusterCount = len( ONOSIpList )
Jon Hall4ba53f02015-07-29 13:07:41 -07002079
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002080 if isinstance( deviceCount, int ) or isinstance( deviceCount, str ):
2081 deviceCount = int( deviceCount )
2082 switchList = [ 0 ]*( clusterCount+1 )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002083 baselineSwitchCount = deviceCount/clusterCount
Jon Hall4ba53f02015-07-29 13:07:41 -07002084
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002085 for node in range( 1, clusterCount + 1 ):
2086 switchList[ node ] = baselineSwitchCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07002087
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002088 for node in range( 1, ( deviceCount % clusterCount )+1 ):
2089 switchList[ node ] += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07002090
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002091 if isinstance( deviceCount, list ):
Jon Hall3c0114c2020-08-11 15:07:42 -07002092 main.log.info( self.name + ": Using provided device distribution" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002093 switchList = [ 0 ]
andrew@onlab.us3b087132015-03-11 15:00:08 -07002094 for i in deviceCount:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002095 switchList.append( int( i ) )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002096
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002097 tempList = [ '0' ]
2098 tempList.extend( ONOSIpList )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002099 ONOSIpList = tempList
2100
2101 myPort = 6
2102 lastSwitch = 0
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002103 for node in range( 1, clusterCount+1 ):
2104 if switchList[ node ] == 0:
andrew@onlab.us3b087132015-03-11 15:00:08 -07002105 continue
2106
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002107 linkGraph.write( "graph " + ONOSIpList[ node ] + " {\n" )
Jon Hall4ba53f02015-07-29 13:07:41 -07002108
andrew@onlab.us3b087132015-03-11 15:00:08 -07002109 if node > 1:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002110 # connect to last device on previous node
2111 line = ( "\t0:5 -> " + str( lastSwitch ) + ":6:" + lastIp + "\n" ) # ONOSIpList[node-1]
2112 linkGraph.write( line )
Jon Hall4ba53f02015-07-29 13:07:41 -07002113
2114 lastSwitch = 0
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002115 for switch in range( 0, switchList[ node ]-1 ):
andrew@onlab.us3b087132015-03-11 15:00:08 -07002116 line = ""
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002117 line = ( "\t" + str( switch ) + ":" + str( myPort ) )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002118 line += " -- "
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002119 line += ( str( switch+1 ) + ":" + str( myPort-1 ) + "\n" )
2120 linkGraph.write( line )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002121 lastSwitch = switch+1
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002122 lastIp = ONOSIpList[ node ]
Jon Hall4ba53f02015-07-29 13:07:41 -07002123
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002124 # lastSwitch += 1
2125 if node < ( clusterCount ):
2126 # connect to first device on the next node
2127 line = ( "\t" + str( lastSwitch ) + ":6 -> 0:5:" + ONOSIpList[ node+1 ] + "\n" )
2128 linkGraph.write( line )
Jon Hall4ba53f02015-07-29 13:07:41 -07002129
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002130 linkGraph.write( "}\n" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002131 linkGraph.close()
2132
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002133 # SCP
2134 os.system( "scp " + tempFile + " " + self.user_name + "@" + benchIp + ":" + linkGraphPath )
Jon Hall3c0114c2020-08-11 15:07:42 -07002135 main.log.info( self.name + ": linkGraph.cfg creation complete" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002136
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002137 def configNullDev( self, ONOSIpList, deviceCount, numPorts=10 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002138 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07002139 ONOSIpList = list of Ip addresses of nodes switches will be devided amongst
2140 deviceCount = number of switches to distribute, or list of values to use as custom distribution
cameron@onlab.us75900962015-03-30 13:22:49 -07002141 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 +00002142 '''
2143
Jon Hall3c0114c2020-08-11 15:07:42 -07002144 main.log.info( self.name + ": Configuring Null Device Provider" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002145 clusterCount = len( ONOSIpList )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002146
Jon Hall4ba53f02015-07-29 13:07:41 -07002147 try:
2148
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002149 if isinstance( deviceCount, int ) or isinstance( deviceCount, str ):
Jon Hall3c0114c2020-08-11 15:07:42 -07002150 main.log.info( self.name + ": Creating device distribution" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002151 deviceCount = int( deviceCount )
2152 switchList = [ 0 ]*( clusterCount+1 )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002153 baselineSwitchCount = deviceCount/clusterCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07002154
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002155 for node in range( 1, clusterCount + 1 ):
2156 switchList[ node ] = baselineSwitchCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07002157
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002158 for node in range( 1, ( deviceCount % clusterCount )+1 ):
2159 switchList[ node ] += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07002160
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002161 if isinstance( deviceCount, list ):
Jon Hall3c0114c2020-08-11 15:07:42 -07002162 main.log.info( self.name + ": Using provided device distribution" )
Jon Hall4ba53f02015-07-29 13:07:41 -07002163
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002164 if len( deviceCount ) == clusterCount:
2165 switchList = [ '0' ]
2166 switchList.extend( deviceCount )
Jon Hall4ba53f02015-07-29 13:07:41 -07002167
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002168 if len( deviceCount ) == ( clusterCount + 1 ):
2169 if deviceCount[ 0 ] == '0' or deviceCount[ 0 ] == 0:
cameron@onlab.us75900962015-03-30 13:22:49 -07002170 switchList = deviceCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07002171
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002172 assert len( switchList ) == ( clusterCount + 1 )
Jon Hall4ba53f02015-07-29 13:07:41 -07002173
cameron@onlab.us75900962015-03-30 13:22:49 -07002174 except AssertionError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002175 main.log.error( "Bad device/Ip list match" )
cameron@onlab.us75900962015-03-30 13:22:49 -07002176 except TypeError:
2177 main.log.exception( self.name + ": Object not as expected" )
2178 return None
Jon Hall77ba41c2015-04-06 10:25:40 -07002179 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002180 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002181 main.cleanAndExit()
cameron@onlab.us75900962015-03-30 13:22:49 -07002182
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002183 ONOSIp = [ 0 ]
2184 ONOSIp.extend( ONOSIpList )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002185
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002186 devicesString = "devConfigs = "
2187 for node in range( 1, len( ONOSIp ) ):
2188 devicesString += ( ONOSIp[ node ] + ":" + str( switchList[ node ] ) )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002189 if node < clusterCount:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002190 devicesString += ( "," )
Jon Hall4ba53f02015-07-29 13:07:41 -07002191
2192 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002193 self.handle.sendline( "onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider devConfigs " + devicesString )
2194 self.handle.expect( ":~" )
2195 self.handle.sendline( "onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider numPorts " + str( numPorts ) )
2196 self.handle.expect( ":~" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002197
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002198 for i in range( 10 ):
2199 self.handle.sendline( "onos $OC1 cfg get org.onosproject.provider.nil.device.impl.NullDeviceProvider" )
2200 self.handle.expect( ":~" )
cameron@onlab.us75900962015-03-30 13:22:49 -07002201 verification = self.handle.before
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002202 if ( " value=" + str( numPorts ) ) in verification and ( " value=" + devicesString ) in verification:
cameron@onlab.us75900962015-03-30 13:22:49 -07002203 break
2204 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002205 time.sleep( 1 )
andrew@onlab.us3b087132015-03-11 15:00:08 -07002206
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002207 assert ( "value=" + str( numPorts ) ) in verification and ( " value=" + devicesString ) in verification
Jon Hall4ba53f02015-07-29 13:07:41 -07002208
cameron@onlab.us75900962015-03-30 13:22:49 -07002209 except AssertionError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002210 main.log.error( "Incorrect Config settings: " + verification )
Jon Hall77ba41c2015-04-06 10:25:40 -07002211 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002212 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002213 main.cleanAndExit()
cameron@onlab.us75900962015-03-30 13:22:49 -07002214
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002215 def configNullLink( self, fileName="/opt/onos/apache-karaf-3.0.3/etc/linkGraph.cfg", eventRate=0 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002216 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07002217 fileName default is currently the same as the default on ONOS, specify alternate file if
cameron@onlab.us75900962015-03-30 13:22:49 -07002218 you want to use a different topology file than linkGraph.cfg
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002219 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07002220
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002221 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002222 self.handle.sendline( "onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider eventRate " + str( eventRate ) )
2223 self.handle.expect( ":~" )
2224 self.handle.sendline( "onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider cfgFile " + fileName )
2225 self.handle.expect( ":~" )
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002226
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002227 for i in range( 10 ):
2228 self.handle.sendline( "onos $OC1 cfg get org.onosproject.provider.nil.link.impl.NullLinkProvider" )
2229 self.handle.expect( ":~" )
cameron@onlab.us75900962015-03-30 13:22:49 -07002230 verification = self.handle.before
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002231 if ( " value=" + str( eventRate ) ) in verification and ( " value=" + fileName ) in verification:
cameron@onlab.us75900962015-03-30 13:22:49 -07002232 break
Jon Hall4ba53f02015-07-29 13:07:41 -07002233 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002234 time.sleep( 1 )
Jon Hall4ba53f02015-07-29 13:07:41 -07002235
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002236 assert ( "value=" + str( eventRate ) ) in verification and ( " value=" + fileName ) in verification
Jon Hall4ba53f02015-07-29 13:07:41 -07002237
cameron@onlab.us75900962015-03-30 13:22:49 -07002238 except pexpect.EOF:
2239 main.log.error( self.name + ": EOF exception found" )
2240 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002241 main.cleanAndExit()
cameron@onlab.us75900962015-03-30 13:22:49 -07002242 except AssertionError:
Jon Hall3c0114c2020-08-11 15:07:42 -07002243 main.log.info( self.name + ": Settings did not post to ONOS" )
Jon Hall3e6edb32018-08-21 16:20:30 -07002244 main.log.error( verification )
Jon Hall77ba41c2015-04-06 10:25:40 -07002245 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002246 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall3e6edb32018-08-21 16:20:30 -07002247 main.log.error( verification )
Devin Lim44075962017-08-11 10:56:37 -07002248 main.cleanAndExit()
andrew@onlab.us3b087132015-03-11 15:00:08 -07002249
kelvin-onlaba4074292015-07-09 15:19:49 -07002250 def getOnosIps( self ):
2251 """
2252 Get all onos IPs stored in
2253 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002254
kelvin-onlaba4074292015-07-09 15:19:49 -07002255 return sorted( self.onosIps.values() )
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002256
Chiyu Chengec63bde2016-11-17 18:11:36 -08002257 def listLog( self, nodeIp ):
2258 """
2259 Get a list of all the karaf log names
2260 """
2261 try:
2262 cmd = "onos-ssh " + nodeIp + " ls -tr /opt/onos/log"
2263 self.handle.sendline( cmd )
2264 self.handle.expect( ":~" )
2265 before = self.handle.before.splitlines()
2266 logNames = []
2267 for word in before:
2268 if 'karaf.log' in word:
2269 logNames.append( word )
2270 return logNames
2271 except pexpect.EOF:
2272 main.log.error( self.name + ": EOF exception found" )
2273 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002274 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08002275 except pexpect.TIMEOUT:
2276 main.log.error( self.name + ": TIMEOUT exception found" )
2277 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002278 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08002279 except Exception:
2280 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002281 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08002282
Pratik Parab3b2ab5a2017-02-14 13:15:14 -08002283 def logReport( self, nodeIp, searchTerms, outputMode="s", startStr=None, endStr=None ):
Jon Hallb4242222016-01-25 17:07:04 -08002284 """
2285 Searches the latest ONOS log file for the given search terms and
2286 prints the total occurances of each term. Returns to combined total of
2287 all occurances.
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002288
Jon Hallb4242222016-01-25 17:07:04 -08002289 Arguments:
2290 * nodeIp - The ip of the ONOS node where the log is located
2291 * searchTerms - A string to grep for or a list of strings to grep
2292 for in the ONOS log. Will print out the number of
2293 occurances for each term.
2294 Optional Arguments:
2295 * outputMode - 's' or 'd'. If 'd' will print the last 5 lines
2296 containing each search term as well as the total
2297 number of occurances of each term. Defaults to 's',
2298 which prints the simple output of just the number
2299 of occurances for each term.
Pratik Parab3b2ab5a2017-02-14 13:15:14 -08002300 * startStr - the start string to be given to stream editor command
2301 as the start point for extraction of data
2302 * endStr - the end string to be given to stream editor command as
2303 the end point for extraction of data
Jon Hallb4242222016-01-25 17:07:04 -08002304 """
2305 try:
Jon Hall3c0114c2020-08-11 15:07:42 -07002306 main.log.info( self.name + ": Log Report for {} ".format( nodeIp ).center( 70, '=' ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002307 if isinstance( searchTerms, str ):
2308 searchTerms = [ searchTerms ]
Jon Hallb4242222016-01-25 17:07:04 -08002309 numTerms = len( searchTerms )
2310 outputMode = outputMode.lower()
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002311
Jon Hallb4242222016-01-25 17:07:04 -08002312 totalHits = 0
2313 logLines = []
2314 for termIndex in range( numTerms ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002315 term = searchTerms[ termIndex ]
2316 logLines.append( [ term ] )
Pratik Parab3b2ab5a2017-02-14 13:15:14 -08002317 if startStr and endStr:
2318 cmd = "onos-ssh {} \"sed -n '/{}/,/{}/p' /opt/onos/log/karaf.log | grep {}\"".format( nodeIp,
2319 startStr,
2320 endStr,
2321 term )
2322 else:
2323 cmd = "onos-ssh {} cat /opt/onos/log/karaf.log | grep {}".format( nodeIp,
2324 term )
Jon Hallb4242222016-01-25 17:07:04 -08002325 self.handle.sendline( cmd )
2326 self.handle.expect( ":~" )
2327 before = self.handle.before.splitlines()
2328 count = 0
2329 for line in before:
2330 if term in line and "grep" not in line:
2331 count += 1
2332 if before.index( line ) > ( len( before ) - 7 ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002333 logLines[ termIndex ].append( line )
Jon Hall3c0114c2020-08-11 15:07:42 -07002334 main.log.info( self.name + ": {}: {}".format( term, count ) )
Jon Hallb4242222016-01-25 17:07:04 -08002335 totalHits += count
2336 if termIndex == numTerms - 1:
2337 print "\n"
2338 if outputMode != "s":
2339 outputString = ""
2340 for term in logLines:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002341 outputString = term[ 0 ] + ": \n"
Jon Hallb4242222016-01-25 17:07:04 -08002342 for line in range( 1, len( term ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002343 outputString += ( "\t" + term[ line ] + "\n" )
2344 if outputString != ( term[ 0 ] + ": \n" ):
Jon Hallb4242222016-01-25 17:07:04 -08002345 main.log.info( outputString )
Jon Hall3c0114c2020-08-11 15:07:42 -07002346 main.log.info( self.name + ": =" * 70 )
Jon Hallb4242222016-01-25 17:07:04 -08002347 return totalHits
2348 except pexpect.EOF:
2349 main.log.error( self.name + ": EOF exception found" )
2350 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002351 main.cleanAndExit()
Jon Hallb4242222016-01-25 17:07:04 -08002352 except pexpect.TIMEOUT:
2353 main.log.error( self.name + ": TIMEOUT exception found" )
2354 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002355 main.cleanAndExit()
Jon Hallb4242222016-01-25 17:07:04 -08002356 except Exception:
2357 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002358 main.cleanAndExit()
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002359
2360 def copyMininetFile( self, fileName, localPath, userName, ip,
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002361 mnPath='~/mininet/custom/', timeout = 60 ):
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002362 """
2363 Description:
2364 Copy mininet topology file from dependency folder in the test folder
2365 and paste it to the mininet machine's mininet/custom folder
2366 Required:
2367 fileName - Name of the topology file to copy
2368 localPath - File path of the mininet topology file
2369 userName - User name of the mininet machine to send the file to
2370 ip - Ip address of the mininet machine
2371 Optional:
2372 mnPath - of the mininet directory to send the file to
2373 Return:
2374 Return main.TRUE if successfully copied the file otherwise
2375 return main.FALSE
2376 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002377
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002378 try:
2379 cmd = "scp " + localPath + fileName + " " + userName + "@" + \
2380 str( ip ) + ":" + mnPath + fileName
2381
2382 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07002383 self.handle.expect( self.prompt )
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002384
2385 main.log.info( self.name + ": Execute: " + cmd )
2386
2387 self.handle.sendline( cmd )
2388
2389 i = self.handle.expect( [ 'No such file',
2390 "100%",
2391 pexpect.TIMEOUT ] )
2392
2393 if i == 0:
2394 main.log.error( self.name + ": File " + fileName +
2395 " does not exist!" )
2396 return main.FALSE
2397
2398 if i == 1:
2399 main.log.info( self.name + ": File " + fileName +
2400 " has been copied!" )
2401 self.handle.sendline( "" )
Devin Limc20e79a2017-06-07 10:29:57 -07002402 self.handle.expect( self.prompt )
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002403 return main.TRUE
2404
2405 except pexpect.EOF:
2406 main.log.error( self.name + ": EOF exception found" )
2407 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002408 main.cleanAndExit()
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002409 except pexpect.TIMEOUT:
2410 main.log.error( self.name + ": TIMEOUT exception found" )
2411 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002412 main.cleanAndExit()
cameron@onlab.us78b89652015-07-08 15:21:03 -07002413
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002414 def jvmSet( self, memory=8 ):
Jon Hall4ba53f02015-07-29 13:07:41 -07002415
cameron@onlab.us78b89652015-07-08 15:21:03 -07002416 import os
2417
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002418 homeDir = os.path.expanduser( '~' )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002419 filename = "/onos/tools/package/bin/onos-service"
2420
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002421 serviceConfig = open( homeDir + filename, 'w+' )
2422 serviceConfig.write( "#!/bin/bash\n " )
2423 serviceConfig.write( "#------------------------------------- \n " )
2424 serviceConfig.write( "# Starts ONOS Apache Karaf container\n " )
2425 serviceConfig.write( "#------------------------------------- \n " )
2426 serviceConfig.write( "#export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-7-openjdk-amd64/}\n " )
2427 serviceConfig.write( """export JAVA_OPTS="${JAVA_OPTS:--Xms""" + str( memory ) + "G -Xmx" + str( memory ) + """G}" \n """ )
2428 serviceConfig.write( "[ -d $ONOS_HOME ] && cd $ONOS_HOME || ONOS_HOME=$(dirname $0)/..\n" )
2429 serviceConfig.write( """${ONOS_HOME}/apache-karaf-$KARAF_VERSION/bin/karaf "$@" \n """ )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002430 serviceConfig.close()
2431
Jon Hall6c44c0b2016-04-20 15:21:00 -07002432 def createDBFile( self, testData ):
Jon Hall4ba53f02015-07-29 13:07:41 -07002433
cameron@onlab.us78b89652015-07-08 15:21:03 -07002434 filename = main.TEST + "DB"
2435 DBString = ""
Jon Hall4ba53f02015-07-29 13:07:41 -07002436
cameron@onlab.us78b89652015-07-08 15:21:03 -07002437 for item in testData:
Jon Hall3e6edb32018-08-21 16:20:30 -07002438 if isinstance( item, str ):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002439 item = "'" + item + "'"
Jon Hall6c44c0b2016-04-20 15:21:00 -07002440 if testData.index( item ) < len( testData - 1 ):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002441 item += ","
Jon Hall6c44c0b2016-04-20 15:21:00 -07002442 DBString += str( item )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002443
Jon Hall6c44c0b2016-04-20 15:21:00 -07002444 DBFile = open( filename, "a" )
2445 DBFile.write( DBString )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002446 DBFile.close()
2447
Jon Hall6c44c0b2016-04-20 15:21:00 -07002448 def verifySummary( self, ONOSIp, *deviceCount ):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002449
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002450 self.handle.sendline( "onos " + ONOSIp + " summary" )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002451 self.handle.expect( ":~" )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002452
2453 summaryStr = self.handle.before
2454 print "\nSummary\n==============\n" + summaryStr + "\n\n"
2455
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002456 # passed = "SCC(s)=1" in summaryStr
2457 # if deviceCount:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002458 # passed = "devices=" + str(deviceCount) + "," not in summaryStr
cameron@onlab.us78b89652015-07-08 15:21:03 -07002459
GlennRC772363b2015-08-25 13:05:57 -07002460 passed = False
cameron@onlab.us78b89652015-07-08 15:21:03 -07002461 if "SCC(s)=1," in summaryStr:
2462 passed = True
Jon Hall6c44c0b2016-04-20 15:21:00 -07002463 print "Summary is verifed"
Jon Hall4ba53f02015-07-29 13:07:41 -07002464 else:
Jon Hall6c44c0b2016-04-20 15:21:00 -07002465 print "Summary failed"
cameron@onlab.us78b89652015-07-08 15:21:03 -07002466
2467 if deviceCount:
2468 print" ============================="
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002469 checkStr = "devices=" + str( deviceCount[ 0 ] ) + ","
cameron@onlab.us78b89652015-07-08 15:21:03 -07002470 print "Checkstr: " + checkStr
2471 if checkStr not in summaryStr:
2472 passed = False
Jon Hall6c44c0b2016-04-20 15:21:00 -07002473 print "Device count failed"
Jon Hall4ba53f02015-07-29 13:07:41 -07002474 else:
2475 print "device count verified"
cameron@onlab.us78b89652015-07-08 15:21:03 -07002476
2477 return passed
Jon Hall6c44c0b2016-04-20 15:21:00 -07002478
Jon Hall8f6d4622016-05-23 15:27:18 -07002479 def getIpAddr( self, iface=None ):
Jon Hall6c44c0b2016-04-20 15:21:00 -07002480 """
2481 Update self.ip_address with numerical ip address. If multiple IP's are
2482 located on the device, will attempt to use self.nicAddr to choose the
2483 right one. Defaults to 127.0.0.1 if no other address is found or cannot
2484 determine the correct address.
2485
2486 ONLY WORKS WITH IPV4 ADDRESSES
2487 """
2488 try:
Jon Hall8f6d4622016-05-23 15:27:18 -07002489 LOCALHOST = "127.0.0.1"
Jon Hall6c44c0b2016-04-20 15:21:00 -07002490 ipPat = "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"
2491 pattern = re.compile( ipPat )
2492 match = re.search( pattern, self.ip_address )
2493 if self.nicAddr:
2494 nicPat = self.nicAddr.replace( ".", "\." ).replace( "\*", r"\d{1,3}" )
2495 nicPat = re.compile( nicPat )
2496 else:
2497 nicPat = None
2498 # IF self.ip_address is an ip address and matches
2499 # self.nicAddr: return self.ip_address
2500 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002501 curIp = match.group( 0 )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002502 if nicPat:
2503 nicMatch = re.search( nicPat, curIp )
2504 if nicMatch:
2505 return self.ip_address
Jon Hall8f6d4622016-05-23 15:27:18 -07002506 # ELSE: IF iface, return ip of interface
2507 cmd = "ifconfig"
2508 ifPat = re.compile( "inet addr:({})".format( ipPat ) )
2509 if iface:
2510 cmd += " " + str( iface )
2511 raw = subprocess.check_output( cmd.split() )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002512 ifPat = re.compile( "inet addr:({})".format( ipPat ) )
2513 ips = re.findall( ifPat, raw )
Jon Hall8f6d4622016-05-23 15:27:18 -07002514 if iface:
2515 if ips:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002516 ip = ips[ 0 ]
Jon Hall8f6d4622016-05-23 15:27:18 -07002517 self.ip_address = ip
2518 return ip
2519 else:
2520 main.log.error( "Error finding ip, ifconfig output:".format( raw ) )
2521 # ELSE: attempt to get address matching nicPat.
Jon Hall6c44c0b2016-04-20 15:21:00 -07002522 if nicPat:
2523 for ip in ips:
2524 curMatch = re.search( nicPat, ip )
2525 if curMatch:
2526 self.ip_address = ip
2527 return ip
Jon Hall8f6d4622016-05-23 15:27:18 -07002528 else: # If only one non-localhost ip, return that
2529 tmpList = [ ip for ip in ips if ip is not LOCALHOST ]
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002530 if len( tmpList ) == 1:
2531 curIp = tmpList[ 0 ]
Jon Hall6c44c0b2016-04-20 15:21:00 -07002532 self.ip_address = curIp
2533 return curIp
Jon Hall8f6d4622016-05-23 15:27:18 -07002534 # Either no non-localhost IPs, or more than 1
Jon Hallebccd352016-05-20 15:17:17 -07002535 main.log.warn( "getIpAddr failed to find a public IP address" )
Jon Hall8f6d4622016-05-23 15:27:18 -07002536 return LOCALHOST
Jon Halle1790952016-05-23 15:51:46 -07002537 except subprocess.CalledProcessError:
Jon Hall8f6d4622016-05-23 15:27:18 -07002538 main.log.exception( "Error executing ifconfig" )
2539 except IndexError:
2540 main.log.exception( "Error getting IP Address" )
Jon Hall6c44c0b2016-04-20 15:21:00 -07002541 except Exception:
2542 main.log.exception( "Uncaught exception" )
suibin zhang116647a2016-05-06 16:30:09 -07002543
Devin Lim461f0872017-06-05 16:49:33 -07002544 def startBasicONOS( self, nodeList, opSleep=60, onosStartupSleep=30, onosUser="sdn" ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002545 '''
suibin zhang116647a2016-05-06 16:30:09 -07002546 Start onos cluster with defined nodes, but only with drivers app
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002547 '''
suibin zhang116647a2016-05-06 16:30:09 -07002548 import time
2549
2550 self.createCellFile( self.ip_address,
Jon Hall3e6edb32018-08-21 16:20:30 -07002551 "temp",
2552 self.ip_address,
2553 "drivers",
2554 nodeList,
2555 nodeList,
2556 onosUser=onosUser )
suibin zhang116647a2016-05-06 16:30:09 -07002557
2558 main.log.info( self.name + ": Apply cell to environment" )
2559 cellResult = self.setCell( "temp" )
2560 verifyResult = self.verifyCell()
2561
2562 main.log.info( self.name + ": Creating ONOS package" )
You Wangd1bcaca2016-10-24 15:23:26 -07002563 packageResult = self.buckBuild( timeout=opSleep )
suibin zhang116647a2016-05-06 16:30:09 -07002564
You Wangc669d212017-01-25 11:09:48 -08002565 main.log.info( self.name + ": Uninstalling ONOS" )
2566 for nd in nodeList:
2567 self.onosUninstall( nodeIp=nd )
2568
suibin zhang116647a2016-05-06 16:30:09 -07002569 main.log.info( self.name + ": Installing ONOS package" )
2570 for nd in nodeList:
You Wangc669d212017-01-25 11:09:48 -08002571 self.onosInstall( node=nd )
2572
2573 main.log.info( self.name + ": Set up ONOS secure SSH" )
2574 for nd in nodeList:
2575 self.onosSecureSSH( node=nd )
suibin zhang116647a2016-05-06 16:30:09 -07002576
2577 main.log.info( self.name + ": Starting ONOS service" )
2578 time.sleep( onosStartupSleep )
2579
2580 onosStatus = True
2581 for nd in nodeList:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002582 onosStatus = onosStatus & self.isup( node = nd )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002583 # print "onosStatus is: " + str( onosStatus )
suibin zhang116647a2016-05-06 16:30:09 -07002584
2585 return main.TRUE if onosStatus else main.FALSE
2586
Jon Hall39570262020-11-17 12:18:19 -08002587 def onosNetCfg( self, controllerIp, path, fileName, user=None, password=None ):
Jeremy Songster5665f1b2016-06-20 14:38:22 -07002588 """
2589 Push a specified json file to ONOS through the onos-netcfg service
2590
2591 Required:
Devin Lim02075272017-07-10 15:33:21 -07002592 controllerIp - the Ip of the ONOS node in the cluster
Jeremy Songster5665f1b2016-06-20 14:38:22 -07002593 path - the location of the file to be sent
2594 fileName - name of the json file to be sent
2595
2596 Returns main.TRUE on successfully sending json file, and main.FALSE if
2597 there is an error.
2598 """
2599 try:
Jon Hall3c0114c2020-08-11 15:07:42 -07002600 cmd = "onos-netcfg "
2601 if user:
2602 cmd += "-u %s " % user
2603 if password:
2604 cmd += "-p %s " % password
2605 cmd += "{0} {1}{2}".format( controllerIp, path, fileName )
2606 main.log.info( self.name + ": Sending: " + cmd )
2607 self.handle.sendline( cmd )
2608 self.handle.expect( self.prompt )
Devin Lim02075272017-07-10 15:33:21 -07002609 handle = self.handle.before
Jon Hall3c0114c2020-08-11 15:07:42 -07002610 if "Error" in handle or\
2611 "No such file or directory" in handle or\
2612 "command not found" in handle or\
2613 "curl: " in handle:
Jeremy Ronquillo3008aa32017-07-07 15:38:57 -07002614 main.log.error( self.name + ": " + handle + self.handle.after )
Devin Lim02075272017-07-10 15:33:21 -07002615 return main.FALSE
Jon Hall3c0114c2020-08-11 15:07:42 -07002616 main.log.debug( self.name + ": " + handle )
Devin Lim752dd7b2017-06-27 14:40:03 -07002617 return main.TRUE
Jeremy Songster5665f1b2016-06-20 14:38:22 -07002618 except pexpect.EOF:
2619 main.log.error( self.name + ": EOF exception found" )
2620 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002621 main.cleanAndExit()
Jeremy Songster5665f1b2016-06-20 14:38:22 -07002622 except Exception:
2623 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002624 main.cleanAndExit()
Devin Lim3ebd5e72017-11-14 10:38:00 -08002625
2626 def formCluster( self, onosIPs ):
2627 """
2628 From ONOS cluster for IP addresses in onosIPs list
2629 """
2630 try:
2631 onosIPs = " ".join( onosIPs )
2632 command = "onos-form-cluster {}".format( onosIPs )
Jon Hall3c0114c2020-08-11 15:07:42 -07002633 main.log.info( self.name + ": Sending: " + command )
Devin Lim3ebd5e72017-11-14 10:38:00 -08002634 self.handle.sendline( "" )
2635 self.handle.expect( self.prompt )
2636 self.handle.sendline( command )
2637 self.handle.expect( self.prompt )
2638 handle = self.handle.before
2639 main.log.debug( handle )
2640 assert handle is not None, "Error in sendline"
2641 assert "Command not found:" not in handle, handle
2642 assert "Error" not in handle, handle
2643 assert "Exception:" not in handle, handle
2644 assert "curl:" not in handle, handle
2645 return main.TRUE
2646 except AssertionError:
2647 main.log.exception( "{} Error in onos-form-cluster output:".format( self.name ) )
2648 return main.FALSE
2649 except TypeError:
2650 main.log.exception( self.name + ": Object not as expected" )
2651 return main.FALSE
2652 except pexpect.EOF:
2653 main.log.error( self.name + ": EOF exception found" )
2654 main.log.error( self.name + ": " + self.handle.before )
2655 main.cleanAndExit()
2656 except Exception:
2657 main.log.exception( self.name + ": Uncaught exception!" )
2658 main.cleanAndExit()
Jon Hall7ce46ea2018-02-05 12:20:59 -08002659
2660 def backupData( self, location ):
2661 """
2662 Backs up ONOS data and logs to a given location. Returns main.FALSE
2663 if there is an error executing the command, and main.TRUE otherwise.
2664 required arguments:
2665 loaction - The file path to save the backup to
2666 """
2667 try:
2668 cmd = "/opt/onos/bin/onos-backup " + str( location )
2669 self.handle.sendline( cmd )
2670 self.handle.expect( self.prompt )
2671 handle = self.handle.before
2672 main.log.debug( handle )
2673 assert handle is not None, "Error in sendline"
2674 assert "Command not found:" not in handle, handle
2675 assert "Error" not in handle, handle
2676 assert "Exception:" not in handle, handle
2677 return main.TRUE
2678 except AssertionError:
2679 main.log.exception( "{} Error in onos-backup output:".format( self.name ) )
2680 return main.FALSE
2681 except TypeError:
2682 main.log.exception( self.name + ": Object not as expected" )
2683 return main.FALSE
2684 except pexpect.EOF:
2685 main.log.error( self.name + ": EOF exception found" )
2686 main.log.error( self.name + ": " + self.handle.before )
2687 main.cleanAndExit()
2688 except Exception:
2689 main.log.exception( self.name + ": Uncaught exception!" )
2690 main.cleanAndExit()
2691
2692 def restoreData( self, location ):
2693 """
2694 Restores ONOS data and logs from a given location. Returns main.FALSE
2695 if there is an error executing the command, and main.TRUE otherwise.
2696 required arguments:
2697 loaction - The file path of a backup file
2698 """
2699 try:
2700 cmd = "/opt/onos/bin/onos-restore " + str( location )
2701 self.handle.sendline( cmd )
2702 self.handle.expect( self.prompt )
2703 handle = self.handle.before
2704 main.log.debug( handle )
2705 assert handle is not None, "Error in sendline"
2706 assert "Command not found:" not in handle, handle
2707 assert "Error" not in handle, handle
2708 assert "Exception:" not in handle, handle
2709 return main.TRUE
2710 except AssertionError:
2711 main.log.exception( "{} Error in onos-restore output:".format( self.name ) )
2712 return main.FALSE
2713 except TypeError:
2714 main.log.exception( self.name + ": Object not as expected" )
2715 return main.FALSE
2716 except pexpect.EOF:
2717 main.log.error( self.name + ": EOF exception found" )
2718 main.log.error( self.name + ": " + self.handle.before )
2719 main.cleanAndExit()
2720 except Exception:
2721 main.log.exception( self.name + ": Uncaught exception!" )
2722 main.cleanAndExit()
You Wang5df1c6d2018-04-06 18:02:02 -07002723
Jon Hall43060f62020-06-23 13:13:33 -07002724 def onosDiagnostics( self, onosIPs, dstDir, suffix, timeout=300, profile="TRELLIS_PROFILE" ):
You Wang5df1c6d2018-04-06 18:02:02 -07002725 """
2726 Run onos-diagnostics with given ONOS instance IPs and save output to dstDir
2727 with suffix specified E.g. onos-diags-suffix.tar.gz
Jon Hall0e240372018-05-02 11:21:57 -07002728 required arguments:
You Wang5df1c6d2018-04-06 18:02:02 -07002729 onosIPs - list of ONOS IPs for collecting diags
2730 dstDir - diags file will be saved under the directory specified
2731 suffix - diags file will be named with the suffix specified
2732 returns:
2733 main.FALSE if there's an error executing the command, and main.TRUE otherwise
2734 """
2735 try:
Jon Hall43060f62020-06-23 13:13:33 -07002736 self.handle.sendline( "export DIAGS_PROFILE=%s" % profile )
2737 self.handle.expect( self.prompt )
You Wang5df1c6d2018-04-06 18:02:02 -07002738 cmd = "onos-diagnostics"
2739 assert isinstance( onosIPs, list )
2740 for ip in onosIPs:
2741 cmd += " " + str( ip )
2742 self.handle.sendline( cmd )
Jon Hall9b0de1f2020-08-24 15:38:04 -07002743 i = 0
2744 while i == 0:
2745 i = self.handle.expect( [ "Password", self.prompt ], timeout=timeout )
2746 handle = self.handle.before
2747 main.log.debug( "%s: %s" % ( self.name, handle ) )
2748 if i == 0:
2749 self.handle.sendline( self.pwd )
You Wang5df1c6d2018-04-06 18:02:02 -07002750 assert handle is not None, "Error in sendline"
Jon Hall9b0de1f2020-08-24 15:38:04 -07002751 assert "The requested URL returned error" not in handle, handle
You Wang5df1c6d2018-04-06 18:02:02 -07002752 assert "Command not found:" not in handle, handle
2753 assert "Exception:" not in handle, handle
2754 # Rename and move diags file to dstDir from /tmp
2755 if dstDir[ -1: ] != "/":
2756 dstDir += "/"
2757 self.handle.sendline( "mv /tmp/onos-diags.tar.gz " + str( dstDir ) + "onos-diags" + str( suffix ) + ".tar.gz" )
2758 self.handle.expect( self.prompt )
2759 handle = self.handle.before
Jon Hall9b0de1f2020-08-24 15:38:04 -07002760 main.log.debug( "%s: %s" % ( self.name, handle ) )
You Wang5df1c6d2018-04-06 18:02:02 -07002761 assert handle is not None, "Error in sendline"
2762 assert "No such file or directory" not in handle, handle
2763 return main.TRUE
2764 except AssertionError:
2765 main.log.exception( "{} Error in onos-diagnostics output:".format( self.name ) )
2766 return main.FALSE
2767 except TypeError:
2768 main.log.exception( self.name + ": Object not as expected" )
2769 return main.FALSE
You Wang223faa32018-06-21 10:45:47 -07002770 except pexpect.TIMEOUT:
2771 main.log.exception( self.name + ": TIMEOUT exception found in onosDiagnostics" )
2772 main.log.error( self.name + ": " + self.handle.before )
You Wangb65d2372018-08-17 15:37:59 -07002773 self.exitFromCmd( self.prompt, 100 )
You Wang223faa32018-06-21 10:45:47 -07002774 return main.FALSE
You Wang5df1c6d2018-04-06 18:02:02 -07002775 except pexpect.EOF:
2776 main.log.error( self.name + ": EOF exception found" )
2777 main.log.error( self.name + ": " + self.handle.before )
2778 main.cleanAndExit()
2779 except Exception:
2780 main.log.exception( self.name + ": Uncaught exception!" )
2781 main.cleanAndExit()
Jon Hall0e240372018-05-02 11:21:57 -07002782
2783 def onosPower( self, onosIP, toggle, userName=None ):
2784 """
2785 Run onos-power script to tell the cell warden to simulate a power faulure
2786 for the given container.
2787 required :
2788 onosIP - ONOS node IP
2789 toggle - either "off" or "on", used to indicate whether
2790 the node should be powered off or on
2791 returns:
2792 main.FALSE if there's an error executing the command, and main.TRUE otherwise
2793 """
2794 try:
2795 cmd = "onos-power {} {}".format( onosIP, toggle )
2796 if userName:
2797 cmd += " {}".format( userName )
2798 self.handle.sendline( cmd )
2799 self.handle.expect( self.prompt )
2800 handle = self.handle.before
2801 main.log.debug( handle )
2802 assert handle is not None, "Error in sendline"
2803 assert "Command not found:" not in handle, handle
2804 assert "Exception:" not in handle, handle
2805 assert "usage:" not in handle, handle
2806 return main.TRUE
2807 except AssertionError:
2808 main.log.exception( "{} Error in onos-power output:".format( self.name ) )
2809 return main.FALSE
2810 except TypeError:
2811 main.log.exception( self.name + ": Object not as expected" )
2812 return main.FALSE
2813 except pexpect.EOF:
2814 main.log.error( self.name + ": EOF exception found" )
2815 main.log.error( self.name + ": " + self.handle.before )
2816 main.cleanAndExit()
2817 except Exception:
2818 main.log.exception( self.name + ": Uncaught exception!" )
2819 main.cleanAndExit()
You Wangf9d95be2018-08-01 14:35:37 -07002820
2821 def atomixKill( self, nodeIp ):
2822 """
2823 Calls the command: 'atomix-kill [<node-ip>]'
2824 Kills the Atomix instance running on the specified node
2825 """
2826 try:
2827 self.handle.sendline( "" )
2828 self.handle.expect( self.prompt )
2829 self.handle.sendline( "atomix-kill " + str( nodeIp ) )
2830 i = self.handle.expect( [
2831 self.prompt,
2832 "No\sroute\sto\shost",
2833 "password:",
2834 pexpect.TIMEOUT ], timeout=60 )
2835
2836 if i == 0:
Jon Hall3c0114c2020-08-11 15:07:42 -07002837 main.log.info( self.name + ": Atomix instance " + str( nodeIp ) + " was killed" )
You Wangf9d95be2018-08-01 14:35:37 -07002838 return main.TRUE
2839 elif i == 1:
Jon Hall3c0114c2020-08-11 15:07:42 -07002840 main.log.info( self.name + ": No route to host" )
You Wangf9d95be2018-08-01 14:35:37 -07002841 return main.FALSE
2842 elif i == 2:
Jon Hall3c0114c2020-08-11 15:07:42 -07002843 main.log.info( self.name + ": Passwordless login for host: " + str( nodeIp ) + " not configured" )
You Wangf9d95be2018-08-01 14:35:37 -07002844 return main.FALSE
2845 else:
Jon Hall3c0114c2020-08-11 15:07:42 -07002846 main.log.info( self.name + ": Atomix instance was not killed" )
You Wangf9d95be2018-08-01 14:35:37 -07002847 return main.FALSE
2848
2849 except pexpect.EOF:
2850 main.log.error( self.name + ": EOF exception found" )
2851 main.log.error( self.name + ": " + self.handle.before )
2852 main.cleanAndExit()
2853 except Exception:
2854 main.log.exception( self.name + ": Uncaught exception!" )
2855 main.cleanAndExit()
2856
2857 def atomixUninstall( self, nodeIp="" ):
2858 """
2859 Calls the command: 'atomix-uninstall'
2860 Uninstalls Atomix from the designated node, stopping if needed
2861 """
2862 try:
2863 self.handle.sendline( "" )
2864 self.handle.expect( self.prompt, timeout=180 )
2865 self.handle.sendline( "atomix-uninstall " + str( nodeIp ) )
2866 self.handle.expect( self.prompt, timeout=180 )
Jon Hall3c0114c2020-08-11 15:07:42 -07002867 main.log.info( self.name + ": Atomix " + nodeIp + " was uninstalled" )
You Wangf9d95be2018-08-01 14:35:37 -07002868 # onos-uninstall command does not return any text
2869 return main.TRUE
2870 except pexpect.TIMEOUT:
2871 main.log.exception( self.name + ": Timeout in atomixUninstall" )
2872 self.handle.send( "\x03" ) # Control-C
2873 self.handle.expect( self.prompt )
2874 return main.FALSE
2875 except pexpect.EOF:
2876 main.log.error( self.name + ": EOF exception found" )
2877 main.log.error( self.name + ": " + self.handle.before )
2878 main.cleanAndExit()
2879 except Exception:
2880 main.log.exception( self.name + ": Uncaught exception!" )
2881 main.cleanAndExit()
2882
2883 def atomixInstall( self, options="", node="" ):
2884 """
2885 Installs Atomix on the designated nodes.
2886 Returns: main.TRUE on success and main.FALSE on failure
2887 """
2888 try:
2889 if options:
2890 self.handle.sendline( "atomix-install " + options + " " + node )
2891 else:
2892 self.handle.sendline( "atomix-install " + node )
2893 self.handle.expect( "atomix-install " )
2894 i = self.handle.expect( [ "Network\sis\sunreachable",
2895 "is already installed",
2896 "saved",
2897 self.prompt,
2898 pexpect.TIMEOUT ], timeout=180 )
2899 if i == 0:
2900 # can't reach ONOS node
Jon Hall3e6edb32018-08-21 16:20:30 -07002901 main.log.warn( self.name + ": Network is unreachable" )
You Wangf9d95be2018-08-01 14:35:37 -07002902 self.handle.expect( self.prompt )
2903 return main.FALSE
2904 elif i == 1:
2905 # same bits are already on Atomix node
Jon Hall3e6edb32018-08-21 16:20:30 -07002906 main.log.info( self.name + ": Atomix is already installed on " + node )
You Wangf9d95be2018-08-01 14:35:37 -07002907 self.handle.expect( self.prompt )
2908 return main.TRUE
Jon Hallb685a1c2018-10-30 15:17:01 -07002909 elif i == 2:
Jon Hall3e6edb32018-08-21 16:20:30 -07002910 main.log.info( self.name + ": Atomix was installed on " + node )
You Wangf9d95be2018-08-01 14:35:37 -07002911 self.handle.expect( self.prompt )
2912 return main.TRUE
Jon Hallb685a1c2018-10-30 15:17:01 -07002913 elif i == 3:
2914 self.handle.sendline( "echo Return code: $?" )
2915 self.handle.expect( "\$\?" )
2916 self.handle.expect( self.prompt )
Jon Hallb685a1c2018-10-30 15:17:01 -07002917 match = re.search( "Return code: (\d+)", self.handle.before )
2918 if match:
2919 exitCode = int( match.group( 1 ) )
2920 else:
2921 # Didn't match pattern
2922 main.log.error( "Could not parse exit code of atomix-install" )
Jon Hall5e1469a2018-11-01 13:55:53 -07002923 main.log.debug( self.handle.before + self.handle.before )
Jon Hallb685a1c2018-10-30 15:17:01 -07002924 return main.FALSE
2925 if exitCode == 0:
2926 return main.TRUE
2927 else:
Jon Hall5e1469a2018-11-01 13:55:53 -07002928 main.log.error( "Unsuccessful exit code of atomix-install" )
2929 main.log.debug( self.handle.before + self.handle.before )
Jon Hallb685a1c2018-10-30 15:17:01 -07002930 return main.FALSE
You Wangf9d95be2018-08-01 14:35:37 -07002931 elif i == 4:
2932 # timeout
Jon Hall3e6edb32018-08-21 16:20:30 -07002933 main.log.info( self.name + ": Installation of Atomix on " + node + " timed out" )
You Wangf9d95be2018-08-01 14:35:37 -07002934 self.handle.expect( self.prompt )
2935 main.log.warn( self.handle.before )
2936 self.handle.send( "\x03" ) # Control-C
2937 self.handle.expect( self.prompt )
2938 return main.FALSE
2939 except pexpect.EOF:
2940 main.log.error( self.name + ": EOF exception found" )
2941 main.log.error( self.name + ": " + self.handle.before )
2942 main.cleanAndExit()
2943 except Exception:
2944 main.log.exception( self.name + ": Uncaught exception!" )
2945 main.cleanAndExit()
Jon Hall43060f62020-06-23 13:13:33 -07002946
2947 def onosFetchApp( self, url, dstPath=None ):
2948 """
2949 Fetch an external onos app
2950
2951 Required:
2952 url - url for where to download the app
2953 dstPath - where the file will be saved
2954
2955 Returns main.TRUE on successfully fetching file, and main.FALSE if
2956 there is an error.
2957 """
2958 try:
2959 cmd = "wget -q --backups=1 "
2960 if dstPath:
2961 cmd += "-P %s " % ( dstPath )
2962 cmd += str( url )
Jon Hall3c0114c2020-08-11 15:07:42 -07002963 main.log.info( self.name + ": Sending: " + cmd )
2964 self.handle.sendline( cmd )
2965 self.handle.expect( self.prompt )
Jon Hall43060f62020-06-23 13:13:33 -07002966 output = self.handle.before
2967 main.log.debug( output )
2968 if "Error" in output or "No such file or directory" in output:
2969 main.log.error( self.name + ": " + output + self.handle.after )
2970 return main.FALSE
2971 return main.TRUE
2972 except pexpect.EOF:
2973 main.log.error( self.name + ": EOF exception found" )
2974 main.log.error( self.name + ": " + self.handle.before )
2975 main.cleanAndExit()
2976 except Exception:
2977 main.log.exception( self.name + ": Uncaught exception!" )
2978 main.cleanAndExit()
2979
Jon Hall39570262020-11-17 12:18:19 -08002980 def onosApp( self, onosIP, option, fileName, filePath='~/onos/',
2981 appName=None, user=None, password=None ):
Jon Hall43060f62020-06-23 13:13:33 -07002982 """
2983 Wrapper for onos-app script
2984
2985 Required:
2986 - onosIP - The ip address of the onos instance
2987 - option - What command are we doing?
2988 [ list|install|install!|reinstall|reinstall!|activate|deactivate|uninstall ]
2989 - fileName - The name of the app file
2990 Optional Arguments:
Jon Hall39570262020-11-17 12:18:19 -08002991 - appName - The name of the app, some options require this
Jon Hall43060f62020-06-23 13:13:33 -07002992 - filePath - The location of the file
Jon Hall39570262020-11-17 12:18:19 -08002993 - user - ONOS cli user
2994 - password - ONOS cli password
Jon Hall43060f62020-06-23 13:13:33 -07002995
2996 Returns main.TRUE on successfully executing the command, and main.FALSE if
2997 there is an error.
2998 """
2999 # FIXME: Not all options may work, more testing is required, only tested with install(!)
3000 try:
Jon Hall39570262020-11-17 12:18:19 -08003001 cmd = "onos-app %s %s %s %s/%s" % ( onosIP, option, appName if "reinstall" in option else "", filePath, fileName )
3002 if user:
3003 cmd += " -u %s" % user
3004 if password:
3005 cmd += " -p %s" % password
Jon Hall3c0114c2020-08-11 15:07:42 -07003006 main.log.info( self.name + ": Sending: " + cmd )
3007 self.handle.sendline( cmd )
3008 self.handle.expect( self.prompt )
Jon Hall43060f62020-06-23 13:13:33 -07003009 handle = self.handle.before
3010 main.log.debug( handle )
3011 if "Error" in handle or "usage: " in handle or "curl: " in handle:
3012 main.log.error( self.name + ": " + handle + self.handle.after )
3013 return main.FALSE
3014 return main.TRUE
3015 except pexpect.EOF:
3016 main.log.error( self.name + ": EOF exception found" )
3017 main.log.error( self.name + ": " + self.handle.before )
3018 main.cleanAndExit()
3019 except Exception:
3020 main.log.exception( self.name + ": Uncaught exception!" )
3021 main.cleanAndExit()
Jon Hall3c0114c2020-08-11 15:07:42 -07003022
3023 def makeDocker( self, path, cmd, prompt="Successfully tagged", timeout=600 ):
3024 """
3025 Build a docker image using a command, such as make
3026 Arguments:
3027 - path: a path where the script is located. will cd to path
3028 - cmd: the command to run
3029 Optional Arguments:
3030 - prompt: A custom prompt to expect after the command is finished,
3031 incase the host prompt is printed during the build
3032 - timeout: how long to wait for the build
3033 """
3034 try:
3035 main.log.warn( "%s: makeDocker()" % self.name )
3036 self.handle.sendline( "cd %s" % path )
3037 self.handle.expect( self.prompt )
3038 self.handle.sendline( cmd )
3039 self.handle.expect( prompt, timeout=timeout )
3040 fullResponse = self.handle.before
3041 tailResponse = self.handle.after
3042 # TODO: error checking, might be difficult with custom expects
3043 self.handle.expect( self.prompt )
3044 tailResponse += self.handle.before + self.handle.after
3045 fullResponse += tailResponse
3046 main.log.debug( self.name + ": " + tailResponse )
3047 self.handle.sendline( "cd %s" % self.home )
3048 self.handle.expect( self.prompt )
3049 return main.TRUE
3050 except pexpect.EOF:
3051 main.log.error( self.name + ": EOF exception found" )
3052 main.log.error( self.name + ": " + self.handle.before )
3053 main.cleanAndExit()
3054 except Exception:
3055 main.log.exception( self.name + ": Uncaught exception!" )
3056 main.log.debug( self.name + ": " + self.handle.before )
3057 main.cleanAndExit()
3058
3059 def generateOnosConfig( self, nodeIp, path="cluster.json" ):
3060 """
3061 Generate onos cluster configuration file
3062 Arguments:
3063 - nodeIp: ip of the node this file is fore
3064 Optional Arguments:
3065 - The path to save the file to
3066 """
3067 try:
3068 main.log.info( "%s: Generating onos config file for %s" % ( self.name, nodeIp ) )
3069 self.handle.sendline( "onos-gen-config %s %s" % ( nodeIp, path ) )
3070 i = self.handle.expect( [ self.prompt, "not found", "Error" ] )
3071 response = self.handle.before
3072 if i == 0:
3073 main.log.debug( "%s: %s" % ( self.name, response ) )
3074 return main.TRUE
3075 else:
3076 response += self.handle.after
3077 self.handle.expect( self.prompt )
3078 response += self.handle.before
3079 main.log.debug( "%s: %s" % ( self.name, response ) )
3080 return main.FALSE
3081 except pexpect.EOF:
3082 main.log.error( self.name + ": EOF exception found" )
3083 main.log.error( self.name + ": " + self.handle.before )
3084 main.cleanAndExit()
3085 except Exception:
3086 main.log.exception( self.name + ": Uncaught exception!" )
3087 main.log.debug( self.name + ": " + self.handle.before )
3088 main.cleanAndExit()
3089
3090 def generateAtomixConfig( self, nodeIp, path="atomix.json" ):
3091 """
3092 Generate atomix cluster configuration file
3093 Arguments:
3094 - nodeIp: ip of the node this file is fore
3095 Optional Arguments:
3096 - The path to save the file to
3097 """
3098 try:
3099 main.log.info( "%s: Generating atomix config file for %s" % ( self.name, nodeIp ) )
3100 self.handle.sendline( "atomix-gen-config %s %s" % ( nodeIp, path ) )
3101 i = self.handle.expect( [ self.prompt, "not found", "Error" ] )
3102 response = self.handle.before
3103 if i == 0:
3104 main.log.debug( "%s: %s" % ( self.name, response ) )
3105 return main.TRUE
3106 else:
3107 response += self.handle.after
3108 self.handle.expect( self.prompt )
3109 response += self.handle.before
3110 main.log.debug( "%s: %s" % ( self.name, response ) )
3111 return main.FALSE
3112 except pexpect.EOF:
3113 main.log.error( self.name + ": EOF exception found" )
3114 main.log.error( self.name + ": " + self.handle.before )
3115 main.cleanAndExit()
3116 except Exception:
3117 main.log.exception( self.name + ": Uncaught exception!" )
3118 main.log.debug( self.name + ": " + self.handle.before )
3119 main.cleanAndExit()