blob: ad8a2847c35f5a83f9256abdb272129efec6362e [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"""
4This driver interacts with ONOS bench, the OSGi platform
5that configures the ONOS nodes. ( aka ONOS-next )
andrewonlabe8e56fd2014-10-09 17:12:44 -04006
kelvin8ec71442015-01-15 16:57:00 -08007Please follow the coding style demonstrated by existing
andrewonlabe8e56fd2014-10-09 17:12:44 -04008functions and document properly.
9
10If you are a contributor to the driver, please
11list your email here for future contact:
12
13jhall@onlab.us
14andrew@onlab.us
15
16OCT 9 2014
17
kelvin8ec71442015-01-15 16:57:00 -080018"""
Jon Hall05b2b432014-10-08 19:53:25 -040019import time
Jon Hall6801cda2015-07-15 14:13:45 -070020import types
Jon Hall05b2b432014-10-08 19:53:25 -040021import pexpect
kelvin-onlaba4074292015-07-09 15:19:49 -070022import os
Jon Hall6c44c0b2016-04-20 15:21:00 -070023import re
24import subprocess
pingping-lin6d23d9e2015-02-02 16:54:24 -080025from requests.models import Response
Jon Hall05b2b432014-10-08 19:53:25 -040026from drivers.common.clidriver import CLI
27
Jon Hall05b2b432014-10-08 19:53:25 -040028
kelvin8ec71442015-01-15 16:57:00 -080029class OnosDriver( CLI ):
Jon Hall05b2b432014-10-08 19:53:25 -040030
kelvin8ec71442015-01-15 16:57:00 -080031 def __init__( self ):
32 """
33 Initialize client
34 """
Jon Hallefbd9792015-03-05 16:11:36 -080035 self.name = None
36 self.home = None
37 self.handle = None
Jon Hall6c44c0b2016-04-20 15:21:00 -070038 self.nicAddr = None
kelvin8ec71442015-01-15 16:57:00 -080039 super( CLI, self ).__init__()
40
41 def connect( self, **connectargs ):
42 """
Jon Hall05b2b432014-10-08 19:53:25 -040043 Creates ssh handle for ONOS "bench".
kelvin-onlaba4074292015-07-09 15:19:49 -070044 NOTE:
45 The ip_address would come from the topo file using the host tag, the
46 value can be an environment variable as well as a "localhost" to get
47 the ip address needed to ssh to the "bench"
kelvin8ec71442015-01-15 16:57:00 -080048 """
Jon Hall05b2b432014-10-08 19:53:25 -040049 try:
50 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080051 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us3b087132015-03-11 15:00:08 -070052 self.home = "~/onos"
Jon Hall05b2b432014-10-08 19:53:25 -040053 for key in self.options:
54 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080055 self.home = self.options[ 'home' ]
Jon Hall05b2b432014-10-08 19:53:25 -040056 break
Jon Hall274b6642015-02-17 11:57:17 -080057 if self.home is None or self.home == "":
Jon Halle94919c2015-03-23 11:42:57 -070058 self.home = "~/onos"
Jon Hall21270ac2015-02-16 17:59:55 -080059
kelvin8ec71442015-01-15 16:57:00 -080060 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070061
kelvin-onlabc2b79102015-07-14 11:41:20 -070062 # The 'nodes' tag is optional and it is not required in .topo file
kelvin-onlaba4074292015-07-09 15:19:49 -070063 for key in self.options:
64 if key == "nodes":
kelvin-onlabc2b79102015-07-14 11:41:20 -070065 # Maximum number of ONOS nodes to run, if there is any
kelvin-onlaba4074292015-07-09 15:19:49 -070066 self.maxNodes = int( self.options[ 'nodes' ] )
67 break
68 self.maxNodes = None
69
kelvin-onlabc2b79102015-07-14 11:41:20 -070070 if self.maxNodes == None or self.maxNodes == "":
71 self.maxNodes = 100
kelvin-onlaba4074292015-07-09 15:19:49 -070072
kelvin-onlabc2b79102015-07-14 11:41:20 -070073
74 # Grabs all OC environment variables based on max number of nodes
kelvin-onlaba4074292015-07-09 15:19:49 -070075 self.onosIps = {} # Dictionary of all possible ONOS ip
76
77 try:
78 if self.maxNodes:
kelvin-onlaba4074292015-07-09 15:19:49 -070079 for i in range( self.maxNodes ):
80 envString = "OC" + str( i + 1 )
kelvin-onlabc2b79102015-07-14 11:41:20 -070081 # If there is no more OC# then break the loop
82 if os.getenv( envString ):
83 self.onosIps[ envString ] = os.getenv( envString )
84 else:
85 self.maxNodes = len( self.onosIps )
86 main.log.info( self.name +
87 ": Created cluster data with " +
88 str( self.maxNodes ) +
89 " maximum number" +
90 " of nodes" )
91 break
kelvin-onlaba4074292015-07-09 15:19:49 -070092
93 if not self.onosIps:
94 main.log.info( "Could not read any environment variable"
95 + " please load a cell file with all" +
96 " onos IP" )
Jon Hall5cf14d52015-07-16 12:15:19 -070097 self.maxNodes = None
kelvin-onlaba4074292015-07-09 15:19:49 -070098 else:
99 main.log.info( self.name + ": Found " +
100 str( self.onosIps.values() ) +
101 " ONOS IPs" )
kelvin-onlaba4074292015-07-09 15:19:49 -0700102 except KeyError:
103 main.log.info( "Invalid environment variable" )
104 except Exception as inst:
105 main.log.error( "Uncaught exception: " + str( inst ) )
106
107 try:
108 if os.getenv( str( self.ip_address ) ) != None:
109 self.ip_address = os.getenv( str( self.ip_address ) )
110 else:
111 main.log.info( self.name +
112 ": Trying to connect to " +
113 self.ip_address )
kelvin-onlaba4074292015-07-09 15:19:49 -0700114 except KeyError:
115 main.log.info( "Invalid host name," +
116 " connecting to local host instead" )
117 self.ip_address = 'localhost'
118 except Exception as inst:
119 main.log.error( "Uncaught exception: " + str( inst ) )
120
kelvin8ec71442015-01-15 16:57:00 -0800121 self.handle = super( OnosDriver, self ).connect(
122 user_name=self.user_name,
kelvin-onlab08679eb2015-01-21 16:11:48 -0800123 ip_address=self.ip_address,
kelvin-onlabd3b64892015-01-20 13:26:24 -0800124 port=self.port,
125 pwd=self.pwd,
126 home=self.home )
Jon Hall05b2b432014-10-08 19:53:25 -0400127
Jon Hall05b2b432014-10-08 19:53:25 -0400128 if self.handle:
Jon Hall0fc0d452015-07-14 09:49:58 -0700129 self.handle.sendline( "cd " + self.home )
130 self.handle.expect( "\$" )
Jon Hall05b2b432014-10-08 19:53:25 -0400131 return self.handle
kelvin8ec71442015-01-15 16:57:00 -0800132 else:
Jon Hall0fc0d452015-07-14 09:49:58 -0700133 main.log.info( "Failed to create ONOS handle" )
Jon Hall05b2b432014-10-08 19:53:25 -0400134 return main.FALSE
135 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800136 main.log.error( self.name + ": EOF exception found" )
137 main.log.error( self.name + ": " + self.handle.before )
Jon Hall05b2b432014-10-08 19:53:25 -0400138 main.cleanup()
139 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800140 except Exception:
141 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall05b2b432014-10-08 19:53:25 -0400142 main.cleanup()
143 main.exit()
144
kelvin8ec71442015-01-15 16:57:00 -0800145 def disconnect( self ):
146 """
Jon Hall05b2b432014-10-08 19:53:25 -0400147 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800148 """
Jon Halld61331b2015-02-17 16:35:47 -0800149 response = main.TRUE
Jon Hall05b2b432014-10-08 19:53:25 -0400150 try:
Jon Hall61282e32015-03-19 11:34:11 -0700151 if self.handle:
152 self.handle.sendline( "" )
153 self.handle.expect( "\$" )
154 self.handle.sendline( "exit" )
155 self.handle.expect( "closed" )
Jon Hall05b2b432014-10-08 19:53:25 -0400156 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800157 main.log.error( self.name + ": EOF exception found" )
158 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700159 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700160 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700161 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800162 except Exception:
163 main.log.exception( self.name + ": Connection failed to the host" )
Jon Hall05b2b432014-10-08 19:53:25 -0400164 response = main.FALSE
165 return response
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400166
andrew@onlab.usaee415a2015-06-05 14:38:58 -0400167 def getEpochMs( self ):
168 """
169 Returns milliseconds since epoch
Jon Hall4ba53f02015-07-29 13:07:41 -0700170
171 When checking multiple nodes in a for loop,
172 around a hundred milliseconds of difference (ascending) is
173 generally acceptable due to calltime of the function.
174 Few seconds, however, is not and it means clocks
175 are off sync.
andrew@onlab.usaee415a2015-06-05 14:38:58 -0400176 """
177 try:
178 self.handle.sendline( 'date +%s.%N' )
179 self.handle.expect( 'date \+\%s\.\%N' )
180 self.handle.expect( '\$' )
181 epochMs = self.handle.before
182 return epochMs
183 except Exception:
184 main.log.exception( 'Uncaught exception getting epoch time' )
185 main.cleanup()
186 main.exit()
187
Jon Hall6c44c0b2016-04-20 15:21:00 -0700188 def onosPackage( self, opTimeout=180 ):
kelvin8ec71442015-01-15 16:57:00 -0800189 """
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400190 Produce a self-contained tar.gz file that can be deployed
Jon Hall64af8502015-12-15 10:09:33 -0800191 and executed on any platform with Java 8 JRE.
kelvin8ec71442015-01-15 16:57:00 -0800192 """
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400193 try:
Jon Hall64af8502015-12-15 10:09:33 -0800194 ret = main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800195 self.handle.sendline( "onos-package" )
196 self.handle.expect( "onos-package" )
Jon Hallc6793552016-01-19 14:18:37 -0800197 i = self.handle.expect( [ "Downloading",
198 "tar.gz",
199 "\$",
200 "Unknown options" ],
201 opTimeout )
Jon Hall64af8502015-12-15 10:09:33 -0800202 handle = str( self.handle.before + self.handle.after )
203 if i == 0:
Jon Hallc6793552016-01-19 14:18:37 -0800204 # Give more time to download the file
205 self.handle.expect( "\$", opTimeout * 2 )
Jon Hall64af8502015-12-15 10:09:33 -0800206 handle += str( self.handle.before )
207 elif i == 1:
Jon Hallc6793552016-01-19 14:18:37 -0800208 self.handle.expect( "\$" )
209 handle += str( self.handle.before )
210 elif i == 2:
Jon Hall64af8502015-12-15 10:09:33 -0800211 # This seems to be harmless, but may be a problem
212 main.log.warn( "onos-package output not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -0800213 elif i == 3:
Jon Hall64af8502015-12-15 10:09:33 -0800214 # Incorrect usage
215 main.log.error( "onos-package does not recognize the given options" )
216 self.handle.expect( "\$" )
217 handle += str( self.handle.before )
218 ret = main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -0800219 main.log.info( "onos-package command returned: " + handle )
kelvin8ec71442015-01-15 16:57:00 -0800220 # As long as the sendline does not time out,
221 # return true. However, be careful to interpret
222 # the results of the onos-package command return
Jon Hall64af8502015-12-15 10:09:33 -0800223 return ret
224 except pexpect.TIMEOUT:
225 main.log.exception( self.name + ": TIMEOUT exception found in onosPackage" )
226 main.log.error( self.name + ": " + self.handle.before )
227 return main.FALSE
andrewonlab7735d852014-10-09 13:02:47 -0400228 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800229 main.log.error( self.name + ": EOF exception found" )
230 main.log.error( self.name + ": " + self.handle.before )
Jon Hall64af8502015-12-15 10:09:33 -0800231 main.cleanup()
232 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800233 except Exception:
234 main.log.exception( "Failed to package ONOS" )
andrew@onlab.us9e2cd0f2014-10-08 20:32:32 -0400235 main.cleanup()
236 main.exit()
237
kelvin-onlabd3b64892015-01-20 13:26:24 -0800238 def onosBuild( self ):
kelvin8ec71442015-01-15 16:57:00 -0800239 """
andrewonlab8790abb2014-11-06 13:51:54 -0500240 Use the pre defined script to build onos via mvn
kelvin8ec71442015-01-15 16:57:00 -0800241 """
andrewonlab8790abb2014-11-06 13:51:54 -0500242 try:
kelvin8ec71442015-01-15 16:57:00 -0800243 self.handle.sendline( "onos-build" )
244 self.handle.expect( "onos-build" )
245 i = self.handle.expect( [
kelvin-onlabd3b64892015-01-20 13:26:24 -0800246 "BUILD SUCCESS",
247 "ERROR",
248 "BUILD FAILED" ],
249 timeout=120 )
kelvin8ec71442015-01-15 16:57:00 -0800250 handle = str( self.handle.before )
Jon Hall3b489db2015-10-05 14:38:37 -0700251 self.handle.expect( "\$" )
andrewonlab8790abb2014-11-06 13:51:54 -0500252
kelvin8ec71442015-01-15 16:57:00 -0800253 main.log.info( "onos-build command returned: " +
254 handle )
andrewonlab8790abb2014-11-06 13:51:54 -0500255
256 if i == 0:
257 return main.TRUE
258 else:
259 return handle
260
261 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800262 main.log.error( self.name + ": EOF exception found" )
263 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -0800264 except Exception:
265 main.log.exception( "Failed to build ONOS" )
andrewonlab8790abb2014-11-06 13:51:54 -0500266 main.cleanup()
267 main.exit()
268
shahshreya9f531fe2015-06-10 12:03:51 -0700269 def cleanInstall( self, skipTest=False, mciTimeout=600 ):
kelvin8ec71442015-01-15 16:57:00 -0800270 """
271 Runs mvn clean install in the root of the ONOS directory.
272 This will clean all ONOS artifacts then compile each module
shahshreya9f531fe2015-06-10 12:03:51 -0700273 Optional:
274 skipTest - Does "-DskipTests -Dcheckstyle.skip -U -T 1C" which
275 skip the test. This will make the building faster.
276 Disregarding the credibility of the build
kelvin8ec71442015-01-15 16:57:00 -0800277 Returns: main.TRUE on success
Jon Hallde9d9aa2014-10-08 20:36:02 -0400278 On Failure, exits the test
kelvin8ec71442015-01-15 16:57:00 -0800279 """
Jon Hallde9d9aa2014-10-08 20:36:02 -0400280 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800281 main.log.info( "Running 'mvn clean install' on " +
282 str( self.name ) +
kelvin8ec71442015-01-15 16:57:00 -0800283 ". This may take some time." )
284 self.handle.sendline( "cd " + self.home )
285 self.handle.expect( "\$" )
Jon Hallea7818b2014-10-09 14:30:59 -0400286
kelvin8ec71442015-01-15 16:57:00 -0800287 self.handle.sendline( "" )
288 self.handle.expect( "\$" )
shahshreya9f531fe2015-06-10 12:03:51 -0700289
290 if not skipTest:
291 self.handle.sendline( "mvn clean install" )
292 self.handle.expect( "mvn clean install" )
293 else:
294 self.handle.sendline( "mvn clean install -DskipTests" +
295 " -Dcheckstyle.skip -U -T 1C" )
296 self.handle.expect( "mvn clean install -DskipTests" +
297 " -Dcheckstyle.skip -U -T 1C" )
kelvin8ec71442015-01-15 16:57:00 -0800298 while True:
299 i = self.handle.expect( [
Jon Hall274b6642015-02-17 11:57:17 -0800300 'There\sis\sinsufficient\smemory\sfor\sthe\sJava\s' +
Jon Hallefbd9792015-03-05 16:11:36 -0800301 'Runtime\sEnvironment\sto\scontinue',
Jon Hallde9d9aa2014-10-08 20:36:02 -0400302 'BUILD\sFAILURE',
303 'BUILD\sSUCCESS',
Jon Halle94919c2015-03-23 11:42:57 -0700304 'onos\$', #TODO: fix this to be more generic?
Jon Hallde9d9aa2014-10-08 20:36:02 -0400305 'ONOS\$',
pingping-lin57a56ce2015-05-20 16:43:48 -0700306 pexpect.TIMEOUT ], mciTimeout )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400307 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800308 main.log.error( self.name + ":There is insufficient memory \
309 for the Java Runtime Environment to continue." )
310 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400311 main.cleanup()
312 main.exit()
313 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800314 main.log.error( self.name + ": Build failure!" )
315 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400316 main.cleanup()
317 main.exit()
318 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800319 main.log.info( self.name + ": Build success!" )
Jon Halle94919c2015-03-23 11:42:57 -0700320 elif i == 3 or i == 4:
kelvin8ec71442015-01-15 16:57:00 -0800321 main.log.info( self.name + ": Build complete" )
322 # Print the build time
Jon Hallf8ef52c2014-10-09 19:37:33 -0400323 for line in self.handle.before.splitlines():
324 if "Total time:" in line:
kelvin8ec71442015-01-15 16:57:00 -0800325 main.log.info( line )
326 self.handle.sendline( "" )
327 self.handle.expect( "\$", timeout=60 )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400328 return main.TRUE
Jon Halle94919c2015-03-23 11:42:57 -0700329 elif i == 5:
kelvin8ec71442015-01-15 16:57:00 -0800330 main.log.error(
331 self.name +
332 ": mvn clean install TIMEOUT!" )
333 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400334 main.cleanup()
335 main.exit()
336 else:
Jon Hall274b6642015-02-17 11:57:17 -0800337 main.log.error( self.name + ": unexpected response from " +
Jon Hallefbd9792015-03-05 16:11:36 -0800338 "mvn clean install" )
kelvin8ec71442015-01-15 16:57:00 -0800339 # return main.FALSE
Jon Hallde9d9aa2014-10-08 20:36:02 -0400340 main.cleanup()
341 main.exit()
342 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800343 main.log.error( self.name + ": EOF exception found" )
344 main.log.error( self.name + ": " + self.handle.before )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400345 main.cleanup()
346 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800347 except Exception:
348 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallde9d9aa2014-10-08 20:36:02 -0400349 main.cleanup()
350 main.exit()
Jon Hallacabffd2014-10-09 12:36:53 -0400351
Jon Hall61282e32015-03-19 11:34:11 -0700352 def gitPull( self, comp1="", fastForward=True ):
kelvin8ec71442015-01-15 16:57:00 -0800353 """
Jon Hallacabffd2014-10-09 12:36:53 -0400354 Assumes that "git pull" works without login
Jon Hall47a93fb2015-01-06 16:46:06 -0800355
Jon Hall61282e32015-03-19 11:34:11 -0700356 If the fastForward boolean is set to true, only git pulls that can
357 be fast forwarded will be performed. IE if you have not local commits
358 in your branch.
359
Jon Hallacabffd2014-10-09 12:36:53 -0400360 This function will perform a git pull on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800361 If used as gitPull( "NODE" ) it will do git pull + NODE. This is
Jon Hallacabffd2014-10-09 12:36:53 -0400362 for the purpose of pulling from other nodes if necessary.
363
Jon Hall47a93fb2015-01-06 16:46:06 -0800364 Otherwise, this function will perform a git pull in the
Jon Hallacabffd2014-10-09 12:36:53 -0400365 ONOS repository. If it has any problems, it will return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -0800366 If it successfully does a gitPull, it will return a 1 ( main.TRUE )
Shreya Shahee15f6c2014-10-28 18:12:30 -0400367 If it has no updates, it will return 3.
Jon Hallacabffd2014-10-09 12:36:53 -0400368
kelvin8ec71442015-01-15 16:57:00 -0800369 """
Jon Hallacabffd2014-10-09 12:36:53 -0400370 try:
kelvin8ec71442015-01-15 16:57:00 -0800371 self.handle.sendline( "cd " + self.home )
kelvin-onlaba1484582015-02-02 15:46:20 -0800372 self.handle.expect( self.home + "\$" )
Jon Hall61282e32015-03-19 11:34:11 -0700373 cmd = "git pull"
374 if comp1 != "":
375 cmd += ' ' + comp1
376 if fastForward:
377 cmd += ' ' + " --ff-only"
378 self.handle.sendline( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800379 i = self.handle.expect(
380 [
381 'fatal',
382 'Username\sfor\s(.*):\s',
383 '\sfile(s*) changed,\s',
384 'Already up-to-date',
385 'Aborting',
386 'You\sare\snot\scurrently\son\sa\sbranch',
Jon Hall274b6642015-02-17 11:57:17 -0800387 'You asked me to pull without telling me which branch you',
388 'Pull is not possible because you have unmerged files',
Jon Hall61282e32015-03-19 11:34:11 -0700389 'Please enter a commit message to explain why this merge',
390 'Found a swap file by the name',
391 'Please, commit your changes before you can merge.',
kelvin-onlabd3b64892015-01-20 13:26:24 -0800392 pexpect.TIMEOUT ],
393 timeout=300 )
kelvin8ec71442015-01-15 16:57:00 -0800394 if i == 0:
Jon Hall61282e32015-03-19 11:34:11 -0700395 main.log.error( self.name + ": Git pull had some issue" )
396 output = self.handle.after
397 self.handle.expect( '\$' )
398 output += self.handle.before
399 main.log.warn( output )
Jon Hallacabffd2014-10-09 12:36:53 -0400400 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800401 elif i == 1:
402 main.log.error(
403 self.name +
404 ": Git Pull Asking for username. " )
Jon Hallacabffd2014-10-09 12:36:53 -0400405 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800406 elif i == 2:
407 main.log.info(
408 self.name +
409 ": Git Pull - pulling repository now" )
kelvin-onlaba1484582015-02-02 15:46:20 -0800410 self.handle.expect( self.home + "\$", 120 )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800411 # So that only when git pull is done, we do mvn clean compile
412 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800413 elif i == 3:
414 main.log.info( self.name + ": Git Pull - Already up to date" )
Jon Hall47a93fb2015-01-06 16:46:06 -0800415 return i
kelvin8ec71442015-01-15 16:57:00 -0800416 elif i == 4:
417 main.log.info(
418 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800419 ": Git Pull - Aborting..." +
420 "Are there conflicting git files?" )
Jon Hallacabffd2014-10-09 12:36:53 -0400421 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800422 elif i == 5:
423 main.log.info(
424 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800425 ": Git Pull - You are not currently " +
426 "on a branch so git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400427 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800428 elif i == 6:
429 main.log.info(
430 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800431 ": Git Pull - You have not configured an upstream " +
432 "branch to pull from. Git pull failed!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400433 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800434 elif i == 7:
435 main.log.info(
436 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800437 ": Git Pull - Pull is not possible because " +
438 "you have unmerged files." )
Jon Hallacabffd2014-10-09 12:36:53 -0400439 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800440 elif i == 8:
Jon Hall61282e32015-03-19 11:34:11 -0700441 # NOTE: abandoning test since we can't reliably handle this
442 # there could be different default text editors and we
443 # also don't know if we actually want to make the commit
444 main.log.error( "Git pull resulted in a merge commit message" +
445 ". Exiting test!" )
446 main.cleanup()
447 main.exit()
448 elif i == 9: # Merge commit message but swap file exists
449 main.log.error( "Git pull resulted in a merge commit message" +
450 " but a swap file exists." )
451 try:
452 self.handle.send( 'A' ) # Abort
453 self.handle.expect( "\$" )
454 return main.ERROR
455 except Exception:
456 main.log.exception( "Couldn't exit editor prompt!")
457 main.cleanup()
458 main.exit()
459 elif i == 10: # In the middle of a merge commit
460 main.log.error( "Git branch is in the middle of a merge. " )
461 main.log.warn( self.handle.before + self.handle.after )
462 return main.ERROR
463 elif i == 11:
kelvin8ec71442015-01-15 16:57:00 -0800464 main.log.error( self.name + ": Git Pull - TIMEOUT" )
465 main.log.error(
466 self.name + " Response was: " + str(
467 self.handle.before ) )
Jon Hallacabffd2014-10-09 12:36:53 -0400468 return main.ERROR
469 else:
kelvin8ec71442015-01-15 16:57:00 -0800470 main.log.error(
471 self.name +
472 ": Git Pull - Unexpected response, check for pull errors" )
Jon Hallacabffd2014-10-09 12:36:53 -0400473 return main.ERROR
474 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800475 main.log.error( self.name + ": EOF exception found" )
476 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400477 main.cleanup()
478 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800479 except Exception:
480 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400481 main.cleanup()
482 main.exit()
483
kelvin-onlabd3b64892015-01-20 13:26:24 -0800484 def gitCheckout( self, branch="master" ):
kelvin8ec71442015-01-15 16:57:00 -0800485 """
Jon Hallacabffd2014-10-09 12:36:53 -0400486 Assumes that "git pull" works without login
kelvin8ec71442015-01-15 16:57:00 -0800487
Jon Hallacabffd2014-10-09 12:36:53 -0400488 This function will perform a git git checkout on the ONOS instance.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800489 If used as gitCheckout( "branch" ) it will do git checkout
490 of the "branch".
Jon Hallacabffd2014-10-09 12:36:53 -0400491
492 Otherwise, this function will perform a git checkout of the master
kelvin8ec71442015-01-15 16:57:00 -0800493 branch of the ONOS repository. If it has any problems, it will return
494 main.ERROR.
495 If the branch was already the specified branch, or the git checkout was
Jon Hallacabffd2014-10-09 12:36:53 -0400496 successful then the function will return main.TRUE.
497
kelvin8ec71442015-01-15 16:57:00 -0800498 """
Jon Hallacabffd2014-10-09 12:36:53 -0400499 try:
kelvin8ec71442015-01-15 16:57:00 -0800500 self.handle.sendline( "cd " + self.home )
kelvin-onlaba1484582015-02-02 15:46:20 -0800501 self.handle.expect( self.home + "\$" )
Jon Hall274b6642015-02-17 11:57:17 -0800502 main.log.info( self.name +
503 ": Checking out git branch/ref: " + branch + "..." )
kelvin8ec71442015-01-15 16:57:00 -0800504 cmd = "git checkout " + branch
505 self.handle.sendline( cmd )
506 self.handle.expect( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800507 i = self.handle.expect(
Jon Hall274b6642015-02-17 11:57:17 -0800508 [ 'fatal',
Jon Hall61282e32015-03-19 11:34:11 -0700509 'Username for (.*): ',
510 'Already on \'',
Jon Hall7a8354f2015-06-10 15:37:00 -0700511 'Switched to (a new )?branch \'' + str( branch ),
Jon Hall274b6642015-02-17 11:57:17 -0800512 pexpect.TIMEOUT,
513 'error: Your local changes to the following files' +
Jon Hallefbd9792015-03-05 16:11:36 -0800514 'would be overwritten by checkout:',
Jon Hall274b6642015-02-17 11:57:17 -0800515 'error: you need to resolve your current index first',
516 "You are in 'detached HEAD' state.",
517 "HEAD is now at " ],
kelvin-onlabd3b64892015-01-20 13:26:24 -0800518 timeout=60 )
kelvin8ec71442015-01-15 16:57:00 -0800519 if i == 0:
520 main.log.error(
521 self.name +
522 ": Git checkout had some issue..." )
523 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400524 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800525 elif i == 1:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800526 main.log.error(
527 self.name +
528 ": Git checkout asking for username." +
529 " Please configure your local git repository to be able " +
530 "to access your remote repository passwordlessly" )
Jon Hall274b6642015-02-17 11:57:17 -0800531 # TODO add support for authenticating
Jon Hallacabffd2014-10-09 12:36:53 -0400532 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800533 elif i == 2:
534 main.log.info(
535 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800536 ": Git Checkout %s : Already on this branch" % branch )
kelvin-onlaba1484582015-02-02 15:46:20 -0800537 self.handle.expect( self.home + "\$" )
kelvin8ec71442015-01-15 16:57:00 -0800538 # main.log.info( "DEBUG: after checkout cmd = "+
539 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400540 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800541 elif i == 3:
542 main.log.info(
543 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800544 ": Git checkout %s - Switched to this branch" % branch )
kelvin-onlaba1484582015-02-02 15:46:20 -0800545 self.handle.expect( self.home + "\$" )
kelvin8ec71442015-01-15 16:57:00 -0800546 # main.log.info( "DEBUG: after checkout cmd = "+
547 # self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400548 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800549 elif i == 4:
550 main.log.error( self.name + ": Git Checkout- TIMEOUT" )
551 main.log.error(
Jon Hall274b6642015-02-17 11:57:17 -0800552 self.name + " Response was: " + str( self.handle.before ) )
Jon Hallacabffd2014-10-09 12:36:53 -0400553 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800554 elif i == 5:
555 self.handle.expect( "Aborting" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800556 main.log.error(
557 self.name +
558 ": Git checkout error: \n" +
Jon Hall274b6642015-02-17 11:57:17 -0800559 "Your local changes to the following files would" +
560 " be overwritten by checkout:" +
561 str( self.handle.before ) )
kelvin-onlaba1484582015-02-02 15:46:20 -0800562 self.handle.expect( self.home + "\$" )
Jon Hall81e29af2014-11-04 20:41:23 -0500563 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -0800564 elif i == 6:
Jon Hall274b6642015-02-17 11:57:17 -0800565 main.log.error(
566 self.name +
567 ": Git checkout error: \n" +
568 "You need to resolve your current index first:" +
569 str( self.handle.before ) )
kelvin-onlaba1484582015-02-02 15:46:20 -0800570 self.handle.expect( self.home + "\$" )
Jon Hall81e29af2014-11-04 20:41:23 -0500571 return main.ERROR
Jon Hall274b6642015-02-17 11:57:17 -0800572 elif i == 7:
573 main.log.info(
574 self.name +
575 ": Git checkout " + str( branch ) +
576 " - You are in 'detached HEAD' state. HEAD is now at " +
577 str( branch ) )
578 self.handle.expect( self.home + "\$" )
579 return main.TRUE
580 elif i == 8: # Already in detached HEAD on the specified commit
581 main.log.info(
582 self.name +
583 ": Git Checkout %s : Already on commit" % branch )
584 self.handle.expect( self.home + "\$" )
585 return main.TRUE
Jon Hallacabffd2014-10-09 12:36:53 -0400586 else:
kelvin8ec71442015-01-15 16:57:00 -0800587 main.log.error(
588 self.name +
Jon Hall274b6642015-02-17 11:57:17 -0800589 ": Git Checkout - Unexpected response, " +
590 "check for pull errors" )
kelvin8ec71442015-01-15 16:57:00 -0800591 main.log.error( self.name + ": " + self.handle.before )
Jon Hallacabffd2014-10-09 12:36:53 -0400592 return main.ERROR
593
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 )
Jon Hallacabffd2014-10-09 12:36:53 -0400597 main.cleanup()
598 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800599 except Exception:
600 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hallacabffd2014-10-09 12:36:53 -0400601 main.cleanup()
602 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400603
pingping-lin6d23d9e2015-02-02 16:54:24 -0800604 def getBranchName( self ):
pingping-linf30cf272015-05-29 15:54:07 -0700605 main.log.info( "self.home = " )
606 main.log.info( self.home )
pingping-lin6d23d9e2015-02-02 16:54:24 -0800607 self.handle.sendline( "cd " + self.home )
pingping-lin9bf3d8f2015-05-29 16:05:28 -0700608 self.handle.expect( self.home + "\$" )
pingping-lin6d23d9e2015-02-02 16:54:24 -0800609 self.handle.sendline( "git name-rev --name-only HEAD" )
610 self.handle.expect( "git name-rev --name-only HEAD" )
611 self.handle.expect( "\$" )
612
613 lines = self.handle.before.splitlines()
614 if lines[1] == "master":
615 return "master"
616 elif lines[1] == "onos-1.0":
617 return "onos-1.0"
618 else:
619 main.log.info( lines[1] )
620 return "unexpected ONOS branch for SDN-IP test"
621
kelvin-onlabd3b64892015-01-20 13:26:24 -0800622 def getVersion( self, report=False ):
kelvin8ec71442015-01-15 16:57:00 -0800623 """
Jon Hall274b6642015-02-17 11:57:17 -0800624 Writes the COMMIT number to the report to be parsed
Jon Hallefbd9792015-03-05 16:11:36 -0800625 by Jenkins data collector.
kelvin8ec71442015-01-15 16:57:00 -0800626 """
Jon Hall45ec0922014-10-10 19:33:49 -0400627 try:
kelvin8ec71442015-01-15 16:57:00 -0800628 self.handle.sendline( "" )
629 self.handle.expect( "\$" )
630 self.handle.sendline(
631 "cd " +
632 self.home +
Jon Hall274b6642015-02-17 11:57:17 -0800633 "; git log -1 --pretty=fuller --decorate=short | grep -A 6 " +
634 " \"commit\" --color=never" )
kelvin8ec71442015-01-15 16:57:00 -0800635 # NOTE: for some reason there are backspaces inserted in this
636 # phrase when run from Jenkins on some tests
637 self.handle.expect( "never" )
638 self.handle.expect( "\$" )
639 response = ( self.name + ": \n" + str(
640 self.handle.before + self.handle.after ) )
641 self.handle.sendline( "cd " + self.home )
642 self.handle.expect( "\$" )
643 lines = response.splitlines()
Jon Hall45ec0922014-10-10 19:33:49 -0400644 for line in lines:
Jon Hallfd191202014-11-07 18:36:09 -0500645 print line
646 if report:
pingping-lin763ee042015-05-20 17:45:30 -0700647 main.log.wiki( "<blockquote>" )
kelvin8ec71442015-01-15 16:57:00 -0800648 for line in lines[ 2:-1 ]:
649 # Bracket replacement is for Wiki-compliant
650 # formatting. '<' or '>' are interpreted
651 # as xml specific tags that cause errors
652 line = line.replace( "<", "[" )
653 line = line.replace( ">", "]" )
pingping-lin763ee042015-05-20 17:45:30 -0700654 #main.log.wiki( "\t" + line )
655 main.log.wiki( line + "<br /> " )
656 main.log.summary( line )
657 main.log.wiki( "</blockquote>" )
658 main.log.summary("\n")
kelvin8ec71442015-01-15 16:57:00 -0800659 return lines[ 2 ]
Jon Hall45ec0922014-10-10 19:33:49 -0400660 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800661 main.log.error( self.name + ": EOF exception found" )
662 main.log.error( self.name + ": " + self.handle.before )
Jon Hall45ec0922014-10-10 19:33:49 -0400663 main.cleanup()
664 main.exit()
Jon Hall368769f2014-11-19 15:43:35 -0800665 except pexpect.TIMEOUT:
kelvin8ec71442015-01-15 16:57:00 -0800666 main.log.error( self.name + ": TIMEOUT exception found" )
667 main.log.error( self.name + ": " + self.handle.before )
Jon Hall368769f2014-11-19 15:43:35 -0800668 main.cleanup()
669 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800670 except Exception:
671 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall45ec0922014-10-10 19:33:49 -0400672 main.cleanup()
673 main.exit()
674
kelvin-onlabd3b64892015-01-20 13:26:24 -0800675 def createCellFile( self, benchIp, fileName, mnIpAddrs,
Flavio Castrocc38a542016-03-03 13:15:46 -0800676 appString, onosIpAddrs, onosUser="sdn" ):
kelvin8ec71442015-01-15 16:57:00 -0800677 """
andrewonlab94282092014-10-10 13:00:11 -0400678 Creates a cell file based on arguments
679 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800680 * Bench IP address ( benchIp )
andrewonlab94282092014-10-10 13:00:11 -0400681 - Needed to copy the cell file over
kelvin-onlabd3b64892015-01-20 13:26:24 -0800682 * File name of the cell file ( fileName )
683 * Mininet IP address ( mnIpAddrs )
kelvin8ec71442015-01-15 16:57:00 -0800684 - Note that only 1 ip address is
andrewonlab94282092014-10-10 13:00:11 -0400685 supported currently
kelvin-onlabd3b64892015-01-20 13:26:24 -0800686 * ONOS IP addresses ( onosIpAddrs )
andrewonlab94282092014-10-10 13:00:11 -0400687 - Must be passed in as last arguments
Flavio Castrocc38a542016-03-03 13:15:46 -0800688 * ONOS USER (onosUser)
689 - optional argument to set ONOS_USER environment variable
kelvin8ec71442015-01-15 16:57:00 -0800690
andrewonlab94282092014-10-10 13:00:11 -0400691 NOTE: Assumes cells are located at:
692 ~/<self.home>/tools/test/cells/
kelvin8ec71442015-01-15 16:57:00 -0800693 """
694 # Variable initialization
Jon Hall6801cda2015-07-15 14:13:45 -0700695 cellDirectory = self.home + "/tools/test/cells/"
kelvin8ec71442015-01-15 16:57:00 -0800696 # We want to create the cell file in the dependencies directory
697 # of TestON first, then copy over to ONOS bench
kelvin-onlabd3b64892015-01-20 13:26:24 -0800698 tempDirectory = "/tmp/"
kelvin8ec71442015-01-15 16:57:00 -0800699 # Create the cell file in the directory for writing ( w+ )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800700 cellFile = open( tempDirectory + fileName, 'w+' )
Jon Hall6801cda2015-07-15 14:13:45 -0700701 if isinstance( onosIpAddrs, types.StringType ):
702 onosIpAddrs = [ onosIpAddrs ]
kelvin8ec71442015-01-15 16:57:00 -0800703
cameron@onlab.us75900962015-03-30 13:22:49 -0700704 # App string is hardcoded environment variables
kelvin8ec71442015-01-15 16:57:00 -0800705 # That you may wish to use by default on startup.
cameron@onlab.us75900962015-03-30 13:22:49 -0700706 # Note that you may not want certain apps listed
kelvin8ec71442015-01-15 16:57:00 -0800707 # on here.
cameron@onlab.us75900962015-03-30 13:22:49 -0700708 appString = "export ONOS_APPS=" + appString
Flavio Castrocc38a542016-03-03 13:15:46 -0800709 onosGroup = "export ONOS_GROUP=" + onosUser
710 onosUser = "export ONOS_USER=" + onosUser
kelvin-onlabd3b64892015-01-20 13:26:24 -0800711 mnString = "export OCN="
kelvin-onlabf70fd542015-05-07 18:41:40 -0700712 if mnIpAddrs == "":
713 mnString = ""
kelvin-onlabd3b64892015-01-20 13:26:24 -0800714 onosString = "export OC"
715 tempCount = 1
kelvin8ec71442015-01-15 16:57:00 -0800716
kelvin-onlabd3b64892015-01-20 13:26:24 -0800717 # Create ONOSNIC ip address prefix
kelvin-onlaba4074292015-07-09 15:19:49 -0700718 tempOnosIp = str( onosIpAddrs[ 0 ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800719 tempList = []
720 tempList = tempOnosIp.split( "." )
kelvin8ec71442015-01-15 16:57:00 -0800721 # Omit last element of list to format for NIC
kelvin-onlabd3b64892015-01-20 13:26:24 -0800722 tempList = tempList[ :-1 ]
kelvin8ec71442015-01-15 16:57:00 -0800723 # Structure the nic string ip
kelvin-onlabd3b64892015-01-20 13:26:24 -0800724 nicAddr = ".".join( tempList ) + ".*"
Jon Hall6c44c0b2016-04-20 15:21:00 -0700725 self.nicAddr = nicAddr
kelvin-onlabd3b64892015-01-20 13:26:24 -0800726 onosNicString = "export ONOS_NIC=" + nicAddr
andrewonlab94282092014-10-10 13:00:11 -0400727
728 try:
kelvin8ec71442015-01-15 16:57:00 -0800729 # Start writing to file
kelvin-onlabd3b64892015-01-20 13:26:24 -0800730 cellFile.write( onosNicString + "\n" )
andrewonlab94282092014-10-10 13:00:11 -0400731
kelvin-onlabd3b64892015-01-20 13:26:24 -0800732 for arg in onosIpAddrs:
733 # For each argument in onosIpAddrs, write to file
kelvin8ec71442015-01-15 16:57:00 -0800734 # Output should look like the following:
andrewonlabd4940492014-10-24 12:21:27 -0400735 # export OC1="10.128.20.11"
736 # export OC2="10.128.20.12"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800737 cellFile.write( onosString + str( tempCount ) +
Jon Hall6f665652015-09-18 10:08:07 -0700738 "=\"" + arg + "\"\n" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800739 tempCount = tempCount + 1
kelvin8ec71442015-01-15 16:57:00 -0800740
Jon Hall6f665652015-09-18 10:08:07 -0700741 cellFile.write( "export OCI=$OC1\n" )
742 cellFile.write( mnString + "\"" + mnIpAddrs + "\"\n" )
cameron@onlab.us75900962015-03-30 13:22:49 -0700743 cellFile.write( appString + "\n" )
Flavio Castrocc38a542016-03-03 13:15:46 -0800744 cellFile.write( onosGroup + "\n" )
745 cellFile.write( onosUser + "\n" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800746 cellFile.close()
andrewonlab94282092014-10-10 13:00:11 -0400747
kelvin8ec71442015-01-15 16:57:00 -0800748 # We use os.system to send the command to TestON cluster
749 # to account for the case in which TestON is not located
750 # on the same cluster as the ONOS bench
751 # Note that even if TestON is located on the same cluster
752 # as ONOS bench, you must setup passwordless ssh
753 # between TestON and ONOS bench in order to automate the test.
kelvin-onlabc2b79102015-07-14 11:41:20 -0700754 os.system( "scp " + tempDirectory + fileName + " " +
755 self.user_name + "@" + self.ip_address + ":" + cellDirectory )
andrewonlab94282092014-10-10 13:00:11 -0400756
andrewonlab2a6c9342014-10-16 13:40:15 -0400757 return main.TRUE
758
andrewonlab94282092014-10-10 13:00:11 -0400759 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800760 main.log.error( self.name + ": EOF exception found" )
761 main.log.error( self.name + ": " + self.handle.before )
andrewonlab94282092014-10-10 13:00:11 -0400762 main.cleanup()
763 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800764 except Exception:
765 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab94282092014-10-10 13:00:11 -0400766 main.cleanup()
767 main.exit()
768
kelvin-onlabd3b64892015-01-20 13:26:24 -0800769 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800770 """
andrewonlab95ca1462014-10-09 14:04:24 -0400771 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800772 """
Hari Krishna03f530e2015-07-10 17:28:27 -0700773 import re
andrewonlab95ca1462014-10-09 14:04:24 -0400774 try:
775 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800776 main.log.error( "Must define cellname" )
andrewonlab95ca1462014-10-09 14:04:24 -0400777 main.cleanup()
778 main.exit()
779 else:
kelvin8ec71442015-01-15 16:57:00 -0800780 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800781 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800782 # Note that this variable name is subject to change
andrewonlab95ca1462014-10-09 14:04:24 -0400783 # and that this driver will have to change accordingly
Jon Hall3b489db2015-10-05 14:38:37 -0700784 self.handle.expect( str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800785 handleBefore = self.handle.before
786 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800787 # Get the rest of the handle
Jon Hall3b489db2015-10-05 14:38:37 -0700788 self.handle.expect( "\$" )
Jon Hall439c8912016-04-15 02:22:03 -0700789 time.sleep(10)
kelvin-onlabd3b64892015-01-20 13:26:24 -0800790 handleMore = self.handle.before
andrewonlab95ca1462014-10-09 14:04:24 -0400791
Hari Krishna03f530e2015-07-10 17:28:27 -0700792 cell_result = handleBefore + handleAfter + handleMore
793 print cell_result
794 if( re.search( "No such cell", cell_result ) ):
795 main.log.error( "Cell call returned: " + handleBefore +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800796 handleAfter + handleMore )
Hari Krishna03f530e2015-07-10 17:28:27 -0700797 main.cleanup()
798 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400799 return main.TRUE
andrewonlab95ca1462014-10-09 14:04:24 -0400800 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800801 main.log.error( self.name + ": EOF exception found" )
802 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ca1462014-10-09 14:04:24 -0400803 main.cleanup()
804 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800805 except Exception:
806 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ca1462014-10-09 14:04:24 -0400807 main.cleanup()
808 main.exit()
809
kelvin-onlabd3b64892015-01-20 13:26:24 -0800810 def verifyCell( self ):
kelvin8ec71442015-01-15 16:57:00 -0800811 """
andrewonlabc03bf6c2014-10-09 14:56:18 -0400812 Calls 'onos-verify-cell' to check for cell installation
kelvin8ec71442015-01-15 16:57:00 -0800813 """
814 # TODO: Add meaningful expect value
andrewonlab8d0d7d72014-10-09 16:33:15 -0400815
andrewonlabc03bf6c2014-10-09 14:56:18 -0400816 try:
kelvin8ec71442015-01-15 16:57:00 -0800817 # Clean handle by sending empty and expecting $
818 self.handle.sendline( "" )
819 self.handle.expect( "\$" )
820 self.handle.sendline( "onos-verify-cell" )
821 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800822 handleBefore = self.handle.before
823 handleAfter = self.handle.after
kelvin-onlabd3b64892015-01-20 13:26:24 -0800824 main.log.info( "Verify cell returned: " + handleBefore +
Jon Hall3b489db2015-10-05 14:38:37 -0700825 handleAfter )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400826 return main.TRUE
Jon Halla5cb6172015-02-23 09:28:28 -0800827 except pexpect.ExceptionPexpect as e:
Jon Hall3b489db2015-10-05 14:38:37 -0700828 main.log.exception( self.name + ": Pexpect exception found: " )
kelvin8ec71442015-01-15 16:57:00 -0800829 main.log.error( self.name + ": " + self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -0400830 main.cleanup()
831 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800832 except Exception:
833 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400834 main.cleanup()
835 main.exit()
836
jenkins1e99e7b2015-04-02 18:15:39 -0700837 def onosCfgSet( self, ONOSIp, configName, configParam ):
838 """
839 Uses 'onos <node-ip> cfg set' to change a parameter value of an
Jon Hall4ba53f02015-07-29 13:07:41 -0700840 application.
841
jenkins1e99e7b2015-04-02 18:15:39 -0700842 ex)
843 onos 10.0.0.1 cfg set org.onosproject.myapp appSetting 1
jenkins1e99e7b2015-04-02 18:15:39 -0700844 ONOSIp = '10.0.0.1'
845 configName = 'org.onosproject.myapp'
846 configParam = 'appSetting 1'
jenkins1e99e7b2015-04-02 18:15:39 -0700847 """
Jon Hall72280bc2016-01-25 14:29:05 -0800848 try:
849 cfgStr = "onos {} cfg set {} {}".format( ONOSIp,
850 configName,
851 configParam )
852 self.handle.sendline( "" )
853 self.handle.expect( ":~" )
854 self.handle.sendline( cfgStr )
855 self.handle.expect("cfg set")
856 self.handle.expect( ":~" )
jenkins1e99e7b2015-04-02 18:15:39 -0700857
Jon Hall72280bc2016-01-25 14:29:05 -0800858 paramValue = configParam.split(" ")[1]
859 paramName = configParam.split(" ")[0]
Jon Hall4ba53f02015-07-29 13:07:41 -0700860
Jon Hall72280bc2016-01-25 14:29:05 -0800861 checkStr = 'onos {} cfg get " {} {} " '.format( ONOSIp, configName, paramName )
Jon Hall4ba53f02015-07-29 13:07:41 -0700862
Jon Hall72280bc2016-01-25 14:29:05 -0800863 self.handle.sendline( checkStr )
864 self.handle.expect( ":~" )
jenkins1e99e7b2015-04-02 18:15:39 -0700865
Jon Hall72280bc2016-01-25 14:29:05 -0800866 if "value=" + paramValue + "," in self.handle.before:
867 main.log.info("cfg " + configName + " successfully set to " + configParam)
868 return main.TRUE
869 except pexpect.ExceptionPexpect as e:
870 main.log.exception( self.name + ": Pexpect exception found: " )
871 main.log.error( self.name + ": " + self.handle.before )
872 main.cleanup()
873 main.exit()
874 except Exception:
875 main.log.exception( self.name + ": Uncaught exception!" )
876 main.cleanup()
877 main.exit()
Jon Hall4ba53f02015-07-29 13:07:41 -0700878
kelvin-onlabd3b64892015-01-20 13:26:24 -0800879 def onosCli( self, ONOSIp, cmdstr ):
kelvin8ec71442015-01-15 16:57:00 -0800880 """
andrewonlab05e362f2014-10-10 00:40:57 -0400881 Uses 'onos' command to send various ONOS CLI arguments.
882 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800883 * ONOSIp: specify the ip of the cell machine
andrewonlab94282092014-10-10 13:00:11 -0400884 * cmdstr: specify the command string to send
kelvin8ec71442015-01-15 16:57:00 -0800885
886 This function is intended to expose the entire karaf
andrewonlab6e20c342014-10-10 18:08:48 -0400887 CLI commands for ONOS. Try to use this function first
888 before attempting to write a ONOS CLI specific driver
kelvin8ec71442015-01-15 16:57:00 -0800889 function.
890 You can see a list of available 'cmdstr' arguments
andrewonlab6e20c342014-10-10 18:08:48 -0400891 by starting onos, and typing in 'onos' to enter the
892 onos> CLI. Then, type 'help' to see the list of
kelvin8ec71442015-01-15 16:57:00 -0800893 available commands.
894 """
andrewonlab05e362f2014-10-10 00:40:57 -0400895 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800896 if not ONOSIp:
kelvin8ec71442015-01-15 16:57:00 -0800897 main.log.error( "You must specify the IP address" )
andrewonlab05e362f2014-10-10 00:40:57 -0400898 return main.FALSE
899 if not cmdstr:
kelvin8ec71442015-01-15 16:57:00 -0800900 main.log.error( "You must specify the command string" )
andrewonlab05e362f2014-10-10 00:40:57 -0400901 return main.FALSE
902
kelvin8ec71442015-01-15 16:57:00 -0800903 cmdstr = str( cmdstr )
904 self.handle.sendline( "" )
905 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400906
kelvin-onlabd3b64892015-01-20 13:26:24 -0800907 self.handle.sendline( "onos -w " + ONOSIp + " " + cmdstr )
kelvin8ec71442015-01-15 16:57:00 -0800908 self.handle.expect( "\$" )
andrewonlab05e362f2014-10-10 00:40:57 -0400909
kelvin-onlabd3b64892015-01-20 13:26:24 -0800910 handleBefore = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -0800911 main.log.info( "Command sent successfully" )
kelvin8ec71442015-01-15 16:57:00 -0800912 # Obtain return handle that consists of result from
913 # the onos command. The string may need to be
914 # configured further.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800915 returnString = handleBefore
kelvin-onlabd3b64892015-01-20 13:26:24 -0800916 return returnString
andrewonlab05e362f2014-10-10 00:40:57 -0400917 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800918 main.log.error( self.name + ": EOF exception found" )
919 main.log.error( self.name + ": " + self.handle.before )
andrewonlab05e362f2014-10-10 00:40:57 -0400920 main.cleanup()
921 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800922 except Exception:
923 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab05e362f2014-10-10 00:40:57 -0400924 main.cleanup()
925 main.exit()
Jon Hall7993bfc2014-10-09 16:30:14 -0400926
kelvin-onlabd3b64892015-01-20 13:26:24 -0800927 def onosInstall( self, options="-f", node="" ):
kelvin8ec71442015-01-15 16:57:00 -0800928 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400929 Installs ONOS bits on the designated cell machine.
kelvin8ec71442015-01-15 16:57:00 -0800930 If -f option is provided, it also forces an uninstall.
931 Presently, install also includes onos-push-bits and
Jon Hall7993bfc2014-10-09 16:30:14 -0400932 onos-config within.
kelvin8ec71442015-01-15 16:57:00 -0800933 The node option allows you to selectively only push the jar
Jon Hall7993bfc2014-10-09 16:30:14 -0400934 files to certain onos nodes
935
936 Returns: main.TRUE on success and main.FALSE on failure
kelvin8ec71442015-01-15 16:57:00 -0800937 """
Jon Hall7993bfc2014-10-09 16:30:14 -0400938 try:
andrewonlab114768a2014-11-14 12:44:44 -0500939 if options:
kelvin8ec71442015-01-15 16:57:00 -0800940 self.handle.sendline( "onos-install " + options + " " + node )
andrewonlab114768a2014-11-14 12:44:44 -0500941 else:
kelvin8ec71442015-01-15 16:57:00 -0800942 self.handle.sendline( "onos-install " + node )
943 self.handle.expect( "onos-install " )
944 # NOTE: this timeout may need to change depending on the network
945 # and size of ONOS
946 i = self.handle.expect( [ "Network\sis\sunreachable",
kelvin-onlabd3b64892015-01-20 13:26:24 -0800947 "onos\sstart/running,\sprocess",
kelvin8ec71442015-01-15 16:57:00 -0800948 "ONOS\sis\salready\sinstalled",
Jeremyc72b2582016-02-26 18:27:38 -0800949 "already\sup-to-date",
950 "\$",
Jon Hall6c44c0b2016-04-20 15:21:00 -0700951 pexpect.TIMEOUT ], timeout=180 )
Jon Hall7993bfc2014-10-09 16:30:14 -0400952 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800953 main.log.warn( "Network is unreachable" )
Jon Hall3b489db2015-10-05 14:38:37 -0700954 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400955 return main.FALSE
956 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -0800957 main.log.info(
958 "ONOS was installed on " +
959 node +
960 " and started" )
Jon Hall3b489db2015-10-05 14:38:37 -0700961 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -0400962 return main.TRUE
andrewonlabd9a73a72014-11-14 17:28:21 -0500963 elif i == 2:
kelvin8ec71442015-01-15 16:57:00 -0800964 main.log.info( "ONOS is already installed on " + node )
Jon Hall3b489db2015-10-05 14:38:37 -0700965 self.handle.expect( "\$" )
andrewonlabd9a73a72014-11-14 17:28:21 -0500966 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800967 elif i == 3:
Jeremyc72b2582016-02-26 18:27:38 -0800968 main.log.info( "ONOS is already installed on " + node )
969 self.handle.expect( "\$" )
970 return main.TRUE
971 elif i == 4:
972 main.log.info( "ONOS was installed on " + node )
973 return main.TRUE
974 elif i == 5:
kelvin8ec71442015-01-15 16:57:00 -0800975 main.log.info(
976 "Installation of ONOS on " +
977 node +
978 " timed out" )
Jon Hall3b489db2015-10-05 14:38:37 -0700979 self.handle.expect( "\$" )
Jon Hall53c5e662016-04-13 16:06:56 -0700980 main.log.warn( self.handle.before )
Jon Hall7993bfc2014-10-09 16:30:14 -0400981 return main.FALSE
andrewonlabc03bf6c2014-10-09 14:56:18 -0400982 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800983 main.log.error( self.name + ": EOF exception found" )
984 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400985 main.cleanup()
986 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800987 except Exception:
988 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc03bf6c2014-10-09 14:56:18 -0400989 main.cleanup()
990 main.exit()
andrewonlab95ca1462014-10-09 14:04:24 -0400991
kelvin-onlabd3b64892015-01-20 13:26:24 -0800992 def onosStart( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -0800993 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400994 Calls onos command: 'onos-service [<node-ip>] start'
andrewonlabe8e56fd2014-10-09 17:12:44 -0400995 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -0800996 """
andrewonlab8d0d7d72014-10-09 16:33:15 -0400997 try:
kelvin8ec71442015-01-15 16:57:00 -0800998 self.handle.sendline( "" )
999 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001000 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001001 " start" )
1002 i = self.handle.expect( [
andrewonlab8d0d7d72014-10-09 16:33:15 -04001003 "Job\sis\salready\srunning",
1004 "start/running",
Jeremyd0e9a6d2016-03-02 11:28:52 -08001005 "\$",
andrewonlab8d0d7d72014-10-09 16:33:15 -04001006 "Unknown\sinstance",
Jeremy Songster14c13572016-04-21 17:34:03 -07001007 pexpect.TIMEOUT ], timeout=180 )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001008 if i == 0:
Jon Halleab7a242016-03-04 10:20:43 -08001009 self.handle.expect( "\$" )
kelvin8ec71442015-01-15 16:57:00 -08001010 main.log.info( "Service is already running" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001011 return main.TRUE
1012 elif i == 1:
Jon Halleab7a242016-03-04 10:20:43 -08001013 self.handle.expect( "\$" )
kelvin8ec71442015-01-15 16:57:00 -08001014 main.log.info( "ONOS service started" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001015 return main.TRUE
Jeremyd0e9a6d2016-03-02 11:28:52 -08001016 elif i == 2:
1017 main.log.info( "ONOS service started" )
1018 return main.TRUE
andrewonlab8d0d7d72014-10-09 16:33:15 -04001019 else:
Jon Halleab7a242016-03-04 10:20:43 -08001020 self.handle.expect( "\$" )
kelvin8ec71442015-01-15 16:57:00 -08001021 main.log.error( "ONOS service failed to start" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001022 main.cleanup()
1023 main.exit()
andrewonlab8d0d7d72014-10-09 16:33:15 -04001024 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001025 main.log.error( self.name + ": EOF exception found" )
1026 main.log.error( self.name + ": " + self.handle.before )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001027 main.cleanup()
1028 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001029 except Exception:
1030 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab8d0d7d72014-10-09 16:33:15 -04001031 main.cleanup()
1032 main.exit()
1033
kelvin-onlabd3b64892015-01-20 13:26:24 -08001034 def onosStop( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001035 """
andrewonlab2b30bd32014-10-09 16:48:55 -04001036 Calls onos command: 'onos-service [<node-ip>] stop'
andrewonlabe8e56fd2014-10-09 17:12:44 -04001037 This command is a remote management of the ONOS upstart daemon
kelvin8ec71442015-01-15 16:57:00 -08001038 """
andrewonlab2b30bd32014-10-09 16:48:55 -04001039 try:
kelvin8ec71442015-01-15 16:57:00 -08001040 self.handle.sendline( "" )
1041 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001042 self.handle.sendline( "onos-service " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001043 " stop" )
1044 i = self.handle.expect( [
andrewonlab2b30bd32014-10-09 16:48:55 -04001045 "stop/waiting",
Jon Hall61282e32015-03-19 11:34:11 -07001046 "Could not resolve hostname",
andrewonlab2b30bd32014-10-09 16:48:55 -04001047 "Unknown\sinstance",
YPZhang77badfc2016-03-09 10:28:59 -08001048 "\$",
Jeremy Songster14c13572016-04-21 17:34:03 -07001049 pexpect.TIMEOUT ], timeout=180 )
andrewonlab2b30bd32014-10-09 16:48:55 -04001050 if i == 0:
YPZhang77badfc2016-03-09 10:28:59 -08001051 self.handle.expect( "\$" )
kelvin8ec71442015-01-15 16:57:00 -08001052 main.log.info( "ONOS service stopped" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001053 return main.TRUE
1054 elif i == 1:
YPZhang77badfc2016-03-09 10:28:59 -08001055 self.handle.expect( "\$" )
Jon Hall65844a32015-03-09 19:09:37 -07001056 main.log.info( "onosStop() Unknown ONOS instance specified: " +
kelvin-onlabd3b64892015-01-20 13:26:24 -08001057 str( nodeIp ) )
andrewonlab2b30bd32014-10-09 16:48:55 -04001058 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -07001059 elif i == 2:
YPZhang77badfc2016-03-09 10:28:59 -08001060 self.handle.expect( "\$" )
Jon Hall61282e32015-03-19 11:34:11 -07001061 main.log.warn( "ONOS wasn't running" )
1062 return main.TRUE
YPZhang77badfc2016-03-09 10:28:59 -08001063 elif i == 3:
1064 main.log.info( "ONOS service stopped" )
1065 return main.TRUE
andrewonlab2b30bd32014-10-09 16:48:55 -04001066 else:
kelvin8ec71442015-01-15 16:57:00 -08001067 main.log.error( "ONOS service failed to stop" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001068 return main.FALSE
andrewonlab2b30bd32014-10-09 16:48:55 -04001069 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001070 main.log.error( self.name + ": EOF exception found" )
1071 main.log.error( self.name + ": " + self.handle.before )
andrewonlab2b30bd32014-10-09 16:48:55 -04001072 main.cleanup()
1073 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001074 except Exception:
1075 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab2b30bd32014-10-09 16:48:55 -04001076 main.cleanup()
1077 main.exit()
kelvin8ec71442015-01-15 16:57:00 -08001078
kelvin-onlabd3b64892015-01-20 13:26:24 -08001079 def onosUninstall( self, nodeIp="" ):
kelvin8ec71442015-01-15 16:57:00 -08001080 """
andrewonlabc8d47972014-10-09 16:52:36 -04001081 Calls the command: 'onos-uninstall'
kelvin8ec71442015-01-15 16:57:00 -08001082 Uninstalls ONOS from the designated cell machine, stopping
andrewonlabe8e56fd2014-10-09 17:12:44 -04001083 if needed
kelvin8ec71442015-01-15 16:57:00 -08001084 """
andrewonlabc8d47972014-10-09 16:52:36 -04001085 try:
kelvin8ec71442015-01-15 16:57:00 -08001086 self.handle.sendline( "" )
Jeremy Songster14c13572016-04-21 17:34:03 -07001087 self.handle.expect( "\$", timeout=180 )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001088 self.handle.sendline( "onos-uninstall " + str( nodeIp ) )
Jeremy Songster14c13572016-04-21 17:34:03 -07001089 self.handle.expect( "\$", timeout=180 )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001090 main.log.info( "ONOS " + nodeIp + " was uninstalled" )
kelvin8ec71442015-01-15 16:57:00 -08001091 # onos-uninstall command does not return any text
andrewonlabc8d47972014-10-09 16:52:36 -04001092 return main.TRUE
pingping-lin763ee042015-05-20 17:45:30 -07001093 except pexpect.TIMEOUT:
1094 main.log.exception( self.name + ": Timeout in onosUninstall" )
1095 return main.FALSE
andrewonlabc8d47972014-10-09 16:52:36 -04001096 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001097 main.log.error( self.name + ": EOF exception found" )
1098 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc8d47972014-10-09 16:52:36 -04001099 main.cleanup()
1100 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001101 except Exception:
1102 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc8d47972014-10-09 16:52:36 -04001103 main.cleanup()
1104 main.exit()
andrewonlab2b30bd32014-10-09 16:48:55 -04001105
kelvin-onlabd3b64892015-01-20 13:26:24 -08001106 def onosDie( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001107 """
andrewonlabaedc8332014-12-04 12:43:03 -05001108 Issues the command 'onos-die <node-ip>'
1109 This command calls onos-kill and also stops the node
kelvin8ec71442015-01-15 16:57:00 -08001110 """
andrewonlabaedc8332014-12-04 12:43:03 -05001111 try:
kelvin8ec71442015-01-15 16:57:00 -08001112 self.handle.sendline( "" )
1113 self.handle.expect( "\$" )
Jeremyf0aecdb2016-03-30 13:19:57 -07001114 cmdStr = "onos-die " + str( nodeIp )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001115 self.handle.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -08001116 i = self.handle.expect( [
andrewonlabaedc8332014-12-04 12:43:03 -05001117 "Killing\sONOS",
1118 "ONOS\sprocess\sis\snot\srunning",
Jeremy Songster14c13572016-04-21 17:34:03 -07001119 pexpect.TIMEOUT ], timeout=60 )
andrewonlabaedc8332014-12-04 12:43:03 -05001120 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001121 main.log.info( "ONOS instance " + str( nodeIp ) +
kelvin8ec71442015-01-15 16:57:00 -08001122 " was killed and stopped" )
Jon Hall53c5e662016-04-13 16:06:56 -07001123 self.handle.sendline( "" )
1124 self.handle.expect( "\$" )
andrewonlabaedc8332014-12-04 12:43:03 -05001125 return main.TRUE
1126 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001127 main.log.info( "ONOS process was not running" )
Jon Hall53c5e662016-04-13 16:06:56 -07001128 self.handle.sendline( "" )
1129 self.handle.expect( "\$" )
andrewonlabaedc8332014-12-04 12:43:03 -05001130 return main.FALSE
1131 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001132 main.log.error( self.name + ": EOF exception found" )
1133 main.log.error( self.name + ": " + self.handle.before )
andrewonlabaedc8332014-12-04 12:43:03 -05001134 main.cleanup()
1135 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001136 except Exception:
1137 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabaedc8332014-12-04 12:43:03 -05001138 main.cleanup()
1139 main.exit()
1140
kelvin-onlabd3b64892015-01-20 13:26:24 -08001141 def onosKill( self, nodeIp ):
kelvin8ec71442015-01-15 16:57:00 -08001142 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001143 Calls the command: 'onos-kill [<node-ip>]'
1144 "Remotely, and unceremoniously kills the ONOS instance running on
1145 the specified cell machine" - Tom V
kelvin8ec71442015-01-15 16:57:00 -08001146 """
andrewonlabe8e56fd2014-10-09 17:12:44 -04001147 try:
kelvin8ec71442015-01-15 16:57:00 -08001148 self.handle.sendline( "" )
1149 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001150 self.handle.sendline( "onos-kill " + str( nodeIp ) )
kelvin8ec71442015-01-15 16:57:00 -08001151 i = self.handle.expect( [
andrewonlabe8e56fd2014-10-09 17:12:44 -04001152 "\$",
1153 "No\sroute\sto\shost",
1154 "password:",
Jeremy Songster14c13572016-04-21 17:34:03 -07001155 pexpect.TIMEOUT ], timeout=60 )
kelvin8ec71442015-01-15 16:57:00 -08001156
andrewonlabe8e56fd2014-10-09 17:12:44 -04001157 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001158 main.log.info(
1159 "ONOS instance " + str(
kelvin-onlabd3b64892015-01-20 13:26:24 -08001160 nodeIp ) + " was killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001161 return main.TRUE
1162 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001163 main.log.info( "No route to host" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001164 return main.FALSE
1165 elif i == 2:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001166 main.log.info(
1167 "Passwordless login for host: " +
1168 str( nodeIp ) +
1169 " not configured" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001170 return main.FALSE
1171 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001172 main.log.info( "ONOS instance was not killed" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001173 return main.FALSE
kelvin8ec71442015-01-15 16:57:00 -08001174
andrewonlabe8e56fd2014-10-09 17:12:44 -04001175 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001176 main.log.error( self.name + ": EOF exception found" )
1177 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001178 main.cleanup()
1179 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001180 except Exception:
1181 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe8e56fd2014-10-09 17:12:44 -04001182 main.cleanup()
1183 main.exit()
1184
kelvin-onlabd3b64892015-01-20 13:26:24 -08001185 def onosRemoveRaftLogs( self ):
kelvin8ec71442015-01-15 16:57:00 -08001186 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001187 Removes Raft / Copy cat files from ONOS to ensure
Jon Hallfcc88622014-11-25 13:09:54 -05001188 a cleaner environment.
1189
andrewonlab19fbdca2014-11-14 12:55:59 -05001190 Description:
Jon Hallfcc88622014-11-25 13:09:54 -05001191 Stops all ONOS defined in the cell,
andrewonlab19fbdca2014-11-14 12:55:59 -05001192 wipes the raft / copycat log files
kelvin8ec71442015-01-15 16:57:00 -08001193 """
andrewonlab19fbdca2014-11-14 12:55:59 -05001194 try:
kelvin8ec71442015-01-15 16:57:00 -08001195 self.handle.sendline( "" )
1196 self.handle.expect( "\$" )
1197 self.handle.sendline( "onos-remove-raft-logs" )
1198 # Sometimes this command hangs
1199 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
1200 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001201 if i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001202 i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
1203 timeout=120 )
Jon Hallfcc88622014-11-25 13:09:54 -05001204 if i == 1:
1205 return main.FALSE
andrewonlab19fbdca2014-11-14 12:55:59 -05001206 return main.TRUE
andrewonlab19fbdca2014-11-14 12:55:59 -05001207 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001208 main.log.error( self.name + ": EOF exception found" )
1209 main.log.error( self.name + ": " + self.handle.before )
andrewonlab19fbdca2014-11-14 12:55:59 -05001210 main.cleanup()
1211 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001212 except Exception:
1213 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab19fbdca2014-11-14 12:55:59 -05001214 main.cleanup()
1215 main.exit()
Jon Hallfcc88622014-11-25 13:09:54 -05001216
kelvin-onlabd3b64892015-01-20 13:26:24 -08001217 def onosStartNetwork( self, mntopo ):
kelvin8ec71442015-01-15 16:57:00 -08001218 """
1219 Calls the command 'onos-start-network [ <mininet-topo> ]
1220 "remotely starts the specified topology on the cell's
andrewonlab94282092014-10-10 13:00:11 -04001221 mininet machine against all controllers configured in the
kelvin8ec71442015-01-15 16:57:00 -08001222 cell."
andrewonlab94282092014-10-10 13:00:11 -04001223 * Specify mininet topology file name for mntopo
1224 * Topo files should be placed at:
1225 ~/<your-onos-directory>/tools/test/topos
kelvin8ec71442015-01-15 16:57:00 -08001226
andrewonlab94282092014-10-10 13:00:11 -04001227 NOTE: This function will take you to the mininet prompt
kelvin8ec71442015-01-15 16:57:00 -08001228 """
andrewonlab94282092014-10-10 13:00:11 -04001229 try:
1230 if not mntopo:
kelvin8ec71442015-01-15 16:57:00 -08001231 main.log.error( "You must specify a topo file to execute" )
andrewonlab94282092014-10-10 13:00:11 -04001232 return main.FALSE
andrewonlab94282092014-10-10 13:00:11 -04001233
kelvin8ec71442015-01-15 16:57:00 -08001234 mntopo = str( mntopo )
1235 self.handle.sendline( "" )
1236 self.handle.expect( "\$" )
andrewonlab94282092014-10-10 13:00:11 -04001237
kelvin8ec71442015-01-15 16:57:00 -08001238 self.handle.sendline( "onos-start-network " + mntopo )
1239 self.handle.expect( "mininet>" )
1240 main.log.info( "Network started, entered mininet prompt" )
1241
1242 # TODO: Think about whether return is necessary or not
andrewonlab94282092014-10-10 13:00:11 -04001243
1244 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001245 main.log.error( self.name + ": EOF exception found" )
1246 main.log.error( self.name + ": " + self.handle.before )
andrewonlab94282092014-10-10 13:00:11 -04001247 main.cleanup()
1248 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001249 except Exception:
1250 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab94282092014-10-10 13:00:11 -04001251 main.cleanup()
1252 main.exit()
1253
Jeremy Songster14c13572016-04-21 17:34:03 -07001254 def isup( self, node="", timeout=240 ):
kelvin8ec71442015-01-15 16:57:00 -08001255 """
1256 Run's onos-wait-for-start which only returns once ONOS is at run
Cameron Franke9c94fb02015-01-21 10:20:20 -08001257 level 100(ready for use)
andrewonlab8d0d7d72014-10-09 16:33:15 -04001258
Jon Hall7993bfc2014-10-09 16:30:14 -04001259 Returns: main.TRUE if ONOS is running and main.FALSE on timeout
kelvin8ec71442015-01-15 16:57:00 -08001260 """
Jon Hall7993bfc2014-10-09 16:30:14 -04001261 try:
Jon Hall3b489db2015-10-05 14:38:37 -07001262 self.handle.sendline( "onos-wait-for-start " + node )
1263 self.handle.expect( "onos-wait-for-start" )
kelvin8ec71442015-01-15 16:57:00 -08001264 # NOTE: this timeout is arbitrary"
Cameron Franke9c94fb02015-01-21 10:20:20 -08001265 i = self.handle.expect(["\$", pexpect.TIMEOUT], timeout)
Jon Hall7993bfc2014-10-09 16:30:14 -04001266 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -08001267 main.log.info( self.name + ": " + node + " is up" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001268 return main.TRUE
1269 elif i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001270 # NOTE: since this function won't return until ONOS is ready,
Jon Hall7993bfc2014-10-09 16:30:14 -04001271 # we will kill it on timeout
kelvin8ec71442015-01-15 16:57:00 -08001272 main.log.error( "ONOS has not started yet" )
1273 self.handle.send( "\x03" ) # Control-C
1274 self.handle.expect( "\$" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001275 return main.FALSE
1276 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 )
Jon Hall7993bfc2014-10-09 16:30:14 -04001279 main.cleanup()
1280 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001281 except Exception:
1282 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall7993bfc2014-10-09 16:30:14 -04001283 main.cleanup()
1284 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001285
kelvin-onlabd3b64892015-01-20 13:26:24 -08001286 def pushTestIntentsShell(
1287 self,
1288 dpidSrc,
1289 dpidDst,
1290 numIntents,
1291 dirFile,
1292 onosIp,
1293 numMult="",
1294 appId="",
1295 report=True,
1296 options="" ):
kelvin8ec71442015-01-15 16:57:00 -08001297 """
andrewonlabb66dfa12014-12-02 15:51:10 -05001298 Description:
kelvin8ec71442015-01-15 16:57:00 -08001299 Use the linux prompt to push test intents to
andrewonlabb66dfa12014-12-02 15:51:10 -05001300 better parallelize the results than the CLI
1301 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001302 * dpidSrc: specify source dpid
1303 * dpidDst: specify destination dpid
1304 * numIntents: specify number of intents to push
1305 * dirFile: specify directory and file name to save
andrewonlabb66dfa12014-12-02 15:51:10 -05001306 results
kelvin-onlabd3b64892015-01-20 13:26:24 -08001307 * onosIp: specify the IP of ONOS to install on
kelvin8ec71442015-01-15 16:57:00 -08001308 NOTE:
andrewonlabb66dfa12014-12-02 15:51:10 -05001309 You must invoke this command at linux shell prompt
kelvin8ec71442015-01-15 16:57:00 -08001310 """
1311 try:
1312 # Create the string to sendline
andrewonlabaedc8332014-12-04 12:43:03 -05001313 if options:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001314 baseCmd = "onos " + str( onosIp ) + " push-test-intents " +\
kelvin8ec71442015-01-15 16:57:00 -08001315 options + " "
andrewonlabaedc8332014-12-04 12:43:03 -05001316 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001317 baseCmd = "onos " + str( onosIp ) + " push-test-intents "
kelvin8ec71442015-01-15 16:57:00 -08001318
kelvin-onlabd3b64892015-01-20 13:26:24 -08001319 addDpid = baseCmd + str( dpidSrc ) + " " + str( dpidDst )
1320 if not numMult:
1321 addIntents = addDpid + " " + str( numIntents )
1322 elif numMult:
1323 addIntents = addDpid + " " + str( numIntents ) + " " +\
1324 str( numMult )
1325 if appId:
1326 addApp = addIntents + " " + str( appId )
andrewonlabb66dfa12014-12-02 15:51:10 -05001327 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001328 addApp = addIntents
andrewonlabb66dfa12014-12-02 15:51:10 -05001329
andrewonlabaedc8332014-12-04 12:43:03 -05001330 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001331 sendCmd = addApp + " > " + str( dirFile ) + " &"
andrewonlabaedc8332014-12-04 12:43:03 -05001332 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001333 sendCmd = addApp + " &"
1334 main.log.info( "Send cmd: " + sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001335
kelvin-onlabd3b64892015-01-20 13:26:24 -08001336 self.handle.sendline( sendCmd )
andrewonlabb66dfa12014-12-02 15:51:10 -05001337
1338 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001339 main.log.error( self.name + ": EOF exception found" )
1340 main.log.error( self.name + ": " + self.handle.before )
andrewonlabb66dfa12014-12-02 15:51:10 -05001341 main.cleanup()
1342 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001343 except Exception:
1344 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabb66dfa12014-12-02 15:51:10 -05001345 main.cleanup()
kelvin8ec71442015-01-15 16:57:00 -08001346 main.exit()
andrewonlab05e362f2014-10-10 00:40:57 -04001347
kelvin-onlabd3b64892015-01-20 13:26:24 -08001348 def tsharkPcap( self, interface, dirFile ):
kelvin8ec71442015-01-15 16:57:00 -08001349 """
andrewonlab970399c2014-11-07 13:09:32 -05001350 Capture all packet activity and store in specified
1351 directory/file
1352
1353 Required:
1354 * interface: interface to capture
1355 * dir: directory/filename to store pcap
kelvin8ec71442015-01-15 16:57:00 -08001356 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001357 try:
1358 self.handle.sendline( "" )
1359 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001360
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001361 self.handle.sendline( "tshark -i " + str( interface ) + " -t e -w " + str( dirFile ) + " &" )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001362 self.handle.sendline( "\n" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001363 self.handle.expect( "Capturing on" )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001364 self.handle.sendline( "\n" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001365 self.handle.expect( "\$" )
andrewonlab970399c2014-11-07 13:09:32 -05001366
Jon Hallfebb1c72015-03-05 13:30:09 -08001367 main.log.info( "Tshark started capturing files on " +
1368 str( interface ) + " and saving to directory: " +
1369 str( dirFile ) )
1370 except pexpect.EOF:
1371 main.log.error( self.name + ": EOF exception found" )
1372 main.log.error( self.name + ": " + self.handle.before )
1373 main.cleanup()
1374 main.exit()
1375 except Exception:
1376 main.log.exception( self.name + ": Uncaught exception!" )
1377 main.cleanup()
1378 main.exit()
Shreya Shaha73aaad2014-10-27 18:03:09 -04001379
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001380 def onosTopoCfg( self, onosIp, jsonFile ):
kelvin8ec71442015-01-15 16:57:00 -08001381 """
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001382 Description:
1383 Execute onos-topo-cfg command
1384 Required:
1385 onosIp - IP of the onos node you want to send the json to
1386 jsonFile - File path of the json file
1387 Return:
1388 Returns main.TRUE if the command is successfull; Returns
1389 main.FALSE if there was an error
kelvin8ec71442015-01-15 16:57:00 -08001390 """
shahshreyae6c7cf42014-11-26 16:39:01 -08001391 try:
kelvin8ec71442015-01-15 16:57:00 -08001392 self.handle.sendline( "" )
1393 self.handle.expect( "\$" )
kelvin-onlabd9e23de2015-08-06 10:34:44 -07001394 cmd = "onos-topo-cfg "
1395 self.handle.sendline( cmd + str( onosIp ) + " " + jsonFile )
1396 handle = self.handle.before
1397 print handle
1398 if "Error" in handle:
1399 main.log.error( self.name + ": " + self.handle.before )
1400 return main.FALSE
1401 else:
1402 self.handle.expect( "\$" )
1403 return main.TRUE
1404
Jon Hallfebb1c72015-03-05 13:30:09 -08001405 except pexpect.EOF:
1406 main.log.error( self.name + ": EOF exception found" )
1407 main.log.error( self.name + ": " + self.handle.before )
1408 main.cleanup()
1409 main.exit()
1410 except Exception:
1411 main.log.exception( self.name + ": Uncaught exception!" )
1412 main.cleanup()
1413 main.exit()
kelvin8ec71442015-01-15 16:57:00 -08001414
jenkins1e99e7b2015-04-02 18:15:39 -07001415 def tsharkGrep( self, grep, directory, interface='eth0', grepOptions='' ):
kelvin8ec71442015-01-15 16:57:00 -08001416 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001417 Required:
kelvin8ec71442015-01-15 16:57:00 -08001418 * grep string
andrewonlabba44bcf2014-10-16 16:54:41 -04001419 * directory to store results
1420 Optional:
1421 * interface - default: eth0
Jon Hall4ba53f02015-07-29 13:07:41 -07001422 * grepOptions - options for grep
andrewonlabba44bcf2014-10-16 16:54:41 -04001423 Description:
1424 Uses tshark command to grep specific group of packets
1425 and stores the results to specified directory.
kelvin8ec71442015-01-15 16:57:00 -08001426 The timestamp is hardcoded to be in epoch
1427 """
Jon Hallfebb1c72015-03-05 13:30:09 -08001428 try:
1429 self.handle.sendline( "" )
1430 self.handle.expect( "\$" )
1431 self.handle.sendline( "" )
jenkins1e99e7b2015-04-02 18:15:39 -07001432 if grepOptions:
1433 grepStr = "grep "+str(grepOptions)
1434 else:
1435 grepStr = "grep"
Jon Hall4ba53f02015-07-29 13:07:41 -07001436
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001437 cmd = (
1438 "sudo tshark -i " +
Jon Hallfebb1c72015-03-05 13:30:09 -08001439 str( interface ) +
jenkins1e99e7b2015-04-02 18:15:39 -07001440 " -t e | " +
1441 grepStr + " --line-buffered \"" +
Jon Hallfebb1c72015-03-05 13:30:09 -08001442 str(grep) +
1443 "\" >" +
1444 directory +
1445 " &" )
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001446 self.handle.sendline(cmd)
1447 main.log.info(cmd)
Jon Hallfebb1c72015-03-05 13:30:09 -08001448 self.handle.expect( "Capturing on" )
cameron@onlab.us21106ea2015-07-23 15:32:51 -07001449 self.handle.sendline( "\n" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001450 self.handle.expect( "\$" )
1451 except pexpect.EOF:
1452 main.log.error( self.name + ": EOF exception found" )
1453 main.log.error( self.name + ": " + self.handle.before )
1454 main.cleanup()
1455 main.exit()
1456 except Exception:
1457 main.log.exception( self.name + ": Uncaught exception!" )
1458 main.cleanup()
1459 main.exit()
1460
kelvin-onlabd3b64892015-01-20 13:26:24 -08001461 def tsharkStop( self ):
kelvin8ec71442015-01-15 16:57:00 -08001462 """
andrewonlabba44bcf2014-10-16 16:54:41 -04001463 Removes wireshark files from /tmp and kills all tshark processes
kelvin8ec71442015-01-15 16:57:00 -08001464 """
1465 # Remove all pcap from previous captures
Jon Hallfebb1c72015-03-05 13:30:09 -08001466 try:
1467 self.execute( cmd="sudo rm /tmp/wireshark*" )
1468 self.handle.sendline( "" )
Jon Hallefbd9792015-03-05 16:11:36 -08001469 self.handle.sendline( "sudo kill -9 `ps -ef | grep \"tshark -i\"" +
1470 " | grep -v grep | awk '{print $2}'`" )
Jon Hallfebb1c72015-03-05 13:30:09 -08001471 self.handle.sendline( "" )
1472 main.log.info( "Tshark stopped" )
1473 except pexpect.EOF:
1474 main.log.error( self.name + ": EOF exception found" )
1475 main.log.error( self.name + ": " + self.handle.before )
1476 main.cleanup()
1477 main.exit()
1478 except Exception:
1479 main.log.exception( self.name + ": Uncaught exception!" )
1480 main.cleanup()
1481 main.exit()
1482
kelvin8ec71442015-01-15 16:57:00 -08001483 def ptpd( self, args ):
1484 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001485 Initiate ptp with user-specified args.
1486 Required:
1487 * args: specify string of args after command
1488 'sudo ptpd'
kelvin8ec71442015-01-15 16:57:00 -08001489 """
andrewonlab0c38a4a2014-10-28 18:35:35 -04001490 try:
kelvin8ec71442015-01-15 16:57:00 -08001491 self.handle.sendline( "sudo ptpd " + str( args ) )
1492 i = self.handle.expect( [
andrewonlab0c38a4a2014-10-28 18:35:35 -04001493 "Multiple",
1494 "Error",
kelvin8ec71442015-01-15 16:57:00 -08001495 "\$" ] )
1496 self.handle.expect( "\$" )
andrewonlabba44bcf2014-10-16 16:54:41 -04001497
andrewonlab0c38a4a2014-10-28 18:35:35 -04001498 if i == 0:
1499 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001500 main.log.info( "ptpd returned an error: " +
1501 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001502 return handle
1503 elif i == 1:
1504 handle = self.handle.before
kelvin8ec71442015-01-15 16:57:00 -08001505 main.log.error( "ptpd returned an error: " +
1506 str( handle ) )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001507 return handle
1508 else:
1509 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -08001510
andrewonlab0c38a4a2014-10-28 18:35:35 -04001511 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001512 main.log.error( self.name + ": EOF exception found" )
1513 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001514 main.cleanup()
1515 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001516 except Exception:
1517 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0c38a4a2014-10-28 18:35:35 -04001518 main.cleanup()
1519 main.exit()
andrewonlabba44bcf2014-10-16 16:54:41 -04001520
Flavio Castrod2ffffa2016-04-26 15:56:56 -07001521 def dumpFlows(self,ONOSIp, destDir, filename="flows" ):
1522 """
1523 Dump Flow Tables to a desired directory.
1524 For debugging purposes, you may want to use
1525 this function to capture flows at a given point in time.
1526 Localtime will be attached to the filename
1527
1528 Required:
1529 * ONOSIp: the IP of the target ONOS instance
1530 * destDir: specify directory to copy to.
1531 ex ) /tmp/
1532 Optional:
1533 * fileName: Name of the file
1534 """
1535
1536 localtime = time.strftime( '%x %X' )
1537 localtime = localtime.replace( "/", "" )
1538 localtime = localtime.replace( " ", "_" )
1539 localtime = localtime.replace( ":", "" )
1540 if destDir[ -1: ] != "/":
1541 destDir += "/"
1542 cmd="flows > "+ str( destDir ) + str( filename ) + localtime
1543 return self.onosCli(ONOSIp,cmd)
1544
kelvin-onlabd3b64892015-01-20 13:26:24 -08001545 def cpLogsToDir( self, logToCopy,
Jon Hallefbd9792015-03-05 16:11:36 -08001546 destDir, copyFileName="" ):
kelvin8ec71442015-01-15 16:57:00 -08001547 """
1548 Copies logs to a desired directory.
andrewonlab5d7a8f32014-11-10 13:07:56 -05001549 Current implementation of ONOS deletes its karaf
1550 logs on every iteration. For debugging purposes,
kelvin8ec71442015-01-15 16:57:00 -08001551 you may want to use this function to capture
1552 certain karaf logs. ( or any other logs if needed )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001553 Localtime will be attached to the filename
1554
1555 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001556 * logToCopy: specify directory and log name to
andrewonlab5d7a8f32014-11-10 13:07:56 -05001557 copy.
kelvin8ec71442015-01-15 16:57:00 -08001558 ex ) /opt/onos/log/karaf.log.1
kelvin-onlabd3b64892015-01-20 13:26:24 -08001559 For copying multiple files, leave copyFileName
1560 empty and only specify destDir -
kelvin8ec71442015-01-15 16:57:00 -08001561 ex ) /opt/onos/log/karaf*
kelvin-onlabd3b64892015-01-20 13:26:24 -08001562 * destDir: specify directory to copy to.
kelvin8ec71442015-01-15 16:57:00 -08001563 ex ) /tmp/
1564 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001565 * copyFileName: If you want to rename the log
1566 file, specify copyFileName. This will not work
andrewonlab5d7a8f32014-11-10 13:07:56 -05001567 with multiple file copying
kelvin8ec71442015-01-15 16:57:00 -08001568 """
andrewonlab5d7a8f32014-11-10 13:07:56 -05001569 try:
kelvin8ec71442015-01-15 16:57:00 -08001570 localtime = time.strftime( '%x %X' )
1571 localtime = localtime.replace( "/", "" )
1572 localtime = localtime.replace( " ", "_" )
1573 localtime = localtime.replace( ":", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001574 if destDir[ -1: ] != "/":
1575 destDir += "/"
andrewonlab5d7a8f32014-11-10 13:07:56 -05001576
kelvin-onlabd3b64892015-01-20 13:26:24 -08001577 if copyFileName:
Jon Hallfebb1c72015-03-05 13:30:09 -08001578 self.handle.sendline( "cp " + str( logToCopy ) + " " +
1579 str( destDir ) + str( copyFileName ) +
1580 localtime )
kelvin8ec71442015-01-15 16:57:00 -08001581 self.handle.expect( "cp" )
1582 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001583 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001584 self.handle.sendline( "cp " + str( logToCopy ) +
1585 " " + str( destDir ) )
kelvin8ec71442015-01-15 16:57:00 -08001586 self.handle.expect( "cp" )
1587 self.handle.expect( "\$" )
andrewonlab5d7a8f32014-11-10 13:07:56 -05001588
kelvin8ec71442015-01-15 16:57:00 -08001589 return self.handle.before
1590
1591 except pexpect.EOF:
1592 main.log.error( "Copying files failed" )
1593 main.log.error( self.name + ": EOF exception found" )
1594 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001595 except Exception:
1596 main.log.exception( "Copying files failed" )
1597
Jon Hall16b72c42015-05-20 10:23:36 -07001598 def checkLogs( self, onosIp, restart=False):
kelvin8ec71442015-01-15 16:57:00 -08001599 """
Jon Hall94fd0472014-12-08 11:52:42 -08001600 runs onos-check-logs on the given onos node
Jon Hall80daded2015-05-27 16:07:00 -07001601 If restart is True, use the old version of onos-check-logs which
1602 does not print the full stacktrace, but shows the entire log file,
1603 including across restarts
Jon Hall94fd0472014-12-08 11:52:42 -08001604 returns the response
kelvin8ec71442015-01-15 16:57:00 -08001605 """
Jon Hall94fd0472014-12-08 11:52:42 -08001606 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001607 cmd = "onos-check-logs " + str( onosIp )
Jon Hall16b72c42015-05-20 10:23:36 -07001608 if restart:
1609 cmd += " old"
kelvin8ec71442015-01-15 16:57:00 -08001610 self.handle.sendline( cmd )
1611 self.handle.expect( cmd )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001612 self.handle.expect( "\$ " )
Jon Hall94fd0472014-12-08 11:52:42 -08001613 response = self.handle.before
1614 return response
1615 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001616 main.log.error( "Lost ssh connection" )
1617 main.log.error( self.name + ": EOF exception found" )
1618 main.log.error( self.name + ": " + self.handle.before )
Jon Hallfebb1c72015-03-05 13:30:09 -08001619 except Exception:
1620 main.log.exception( self.name + ": Uncaught exception!" )
1621 main.cleanup()
1622 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -08001623
kelvin-onlabd3b64892015-01-20 13:26:24 -08001624 def onosStatus( self, node="" ):
kelvin8ec71442015-01-15 16:57:00 -08001625 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001626 Calls onos command: 'onos-service [<node-ip>] status'
kelvin8ec71442015-01-15 16:57:00 -08001627 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001628 try:
kelvin8ec71442015-01-15 16:57:00 -08001629 self.handle.sendline( "" )
1630 self.handle.expect( "\$" )
1631 self.handle.sendline( "onos-service " + str( node ) +
1632 " status" )
1633 i = self.handle.expect( [
You Wangef1e6572016-03-08 12:53:18 -08001634 "start/running",
You Wang7bd83062016-03-01 11:50:00 -08001635 "Running ...",
You Wangef1e6572016-03-08 12:53:18 -08001636 "stop/waiting",
You Wang7bd83062016-03-01 11:50:00 -08001637 "Not Running ...",
kelvin8ec71442015-01-15 16:57:00 -08001638 pexpect.TIMEOUT ], timeout=120 )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001639
You Wangef1e6572016-03-08 12:53:18 -08001640 if i == 0 or i == 1:
kelvin8ec71442015-01-15 16:57:00 -08001641 main.log.info( "ONOS is running" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001642 return main.TRUE
You Wangef1e6572016-03-08 12:53:18 -08001643 elif i == 2 or i == 3:
kelvin8ec71442015-01-15 16:57:00 -08001644 main.log.info( "ONOS is stopped" )
kelvin8ec71442015-01-15 16:57:00 -08001645 main.log.error( "ONOS service failed to check the status" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001646 main.cleanup()
1647 main.exit()
1648 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001649 main.log.error( self.name + ": EOF exception found" )
1650 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001651 main.cleanup()
1652 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001653 except Exception:
1654 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001655 main.cleanup()
1656 main.exit()
Jon Hall21270ac2015-02-16 17:59:55 -08001657
Jon Hall63604932015-02-26 17:09:50 -08001658 def setIpTables( self, ip, port='', action='add', packet_type='',
1659 direction='INPUT', rule='DROP', states=True ):
Jon Hallefbd9792015-03-05 16:11:36 -08001660 """
Jon Hall21270ac2015-02-16 17:59:55 -08001661 Description:
1662 add or remove iptables rule to DROP (default) packets from
1663 specific IP and PORT
1664 Usage:
1665 * specify action ('add' or 'remove')
1666 when removing, pass in the same argument as you would add. It will
1667 delete that specific rule.
1668 * specify the ip to block
1669 * specify the destination port to block (defaults to all ports)
1670 * optional packet type to block (default tcp)
1671 * optional iptables rule (default DROP)
1672 * optional direction to block (default 'INPUT')
Jon Hall63604932015-02-26 17:09:50 -08001673 * States boolean toggles adding all supported tcp states to the
1674 firewall rule
Jon Hall21270ac2015-02-16 17:59:55 -08001675 Returns:
1676 main.TRUE on success or
1677 main.FALSE if given invalid input or
1678 main.ERROR if there is an error in response from iptables
1679 WARNING:
1680 * This function uses root privilege iptables command which may result
1681 in unwanted network errors. USE WITH CAUTION
Jon Hallefbd9792015-03-05 16:11:36 -08001682 """
Jon Hall21270ac2015-02-16 17:59:55 -08001683
1684 # NOTE*********
1685 # The strict checking methods of this driver function is intentional
1686 # to discourage any misuse or error of iptables, which can cause
1687 # severe network errors
1688 # *************
1689
1690 # NOTE: Sleep needed to give some time for rule to be added and
1691 # registered to the instance. If you are calling this function
1692 # multiple times this sleep will prevent any errors.
1693 # DO NOT REMOVE
Jon Hall63604932015-02-26 17:09:50 -08001694 # time.sleep( 5 )
Jon Hall21270ac2015-02-16 17:59:55 -08001695 try:
1696 # input validation
1697 action_type = action.lower()
1698 rule = rule.upper()
1699 direction = direction.upper()
1700 if action_type != 'add' and action_type != 'remove':
1701 main.log.error( "Invalid action type. Use 'add' or "
1702 "'remove' table rule" )
1703 if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
1704 # NOTE Currently only supports rules DROP, ACCEPT, and LOG
1705 main.log.error( "Invalid rule. Valid rules are 'DROP' or "
1706 "'ACCEPT' or 'LOG' only." )
1707 if direction != 'INPUT' and direction != 'OUTPUT':
1708 # NOTE currently only supports rules INPUT and OUPTUT
1709 main.log.error( "Invalid rule. Valid directions are"
1710 " 'OUTPUT' or 'INPUT'" )
1711 return main.FALSE
1712 return main.FALSE
1713 return main.FALSE
1714 if action_type == 'add':
1715 # -A is the 'append' action of iptables
1716 actionFlag = '-A'
1717 elif action_type == 'remove':
1718 # -D is the 'delete' rule of iptables
1719 actionFlag = '-D'
1720 self.handle.sendline( "" )
1721 self.handle.expect( "\$" )
1722 cmd = "sudo iptables " + actionFlag + " " +\
1723 direction +\
Jon Hall21270ac2015-02-16 17:59:55 -08001724 " -s " + str( ip )
Jon Hall63604932015-02-26 17:09:50 -08001725 # " -p " + str( packet_type ) +\
1726 if packet_type:
1727 cmd += " -p " + str( packet_type )
Jon Hall21270ac2015-02-16 17:59:55 -08001728 if port:
1729 cmd += " --dport " + str( port )
Jon Hall63604932015-02-26 17:09:50 -08001730 if states:
1731 cmd += " -m state --state="
1732 #FIXME- Allow user to configure which states to block
1733 cmd += "INVALID,ESTABLISHED,NEW,RELATED,UNTRACKED"
Jon Hall21270ac2015-02-16 17:59:55 -08001734 cmd += " -j " + str( rule )
1735
1736 self.handle.sendline( cmd )
1737 self.handle.expect( "\$" )
1738 main.log.warn( self.handle.before )
1739
1740 info_string = "On " + str( self.name )
1741 info_string += " " + str( action_type )
1742 info_string += " iptable rule [ "
1743 info_string += " IP: " + str( ip )
1744 info_string += " Port: " + str( port )
1745 info_string += " Rule: " + str( rule )
1746 info_string += " Direction: " + str( direction ) + " ]"
1747 main.log.info( info_string )
1748 return main.TRUE
1749 except pexpect.TIMEOUT:
1750 main.log.exception( self.name + ": Timeout exception in "
1751 "setIpTables function" )
1752 return main.ERROR
1753 except pexpect.EOF:
1754 main.log.error( self.name + ": EOF exception found" )
1755 main.log.error( self.name + ": " + self.handle.before )
1756 main.cleanup()
1757 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001758 except Exception:
1759 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall21270ac2015-02-16 17:59:55 -08001760 main.cleanup()
1761 main.exit()
1762
Jon Hall0468b042015-02-19 19:08:21 -08001763 def detailed_status(self, log_filename):
Jon Hallefbd9792015-03-05 16:11:36 -08001764 """
Jon Hall0468b042015-02-19 19:08:21 -08001765 This method is used by STS to check the status of the controller
1766 Reports RUNNING, STARTING, STOPPED, FROZEN, ERROR (and reason)
Jon Hallefbd9792015-03-05 16:11:36 -08001767 """
Jon Hall0468b042015-02-19 19:08:21 -08001768 import re
1769 try:
1770 self.handle.sendline( "" )
1771 self.handle.expect( "\$" )
1772 self.handle.sendline( "cd " + self.home )
1773 self.handle.expect( "\$" )
1774 self.handle.sendline( "service onos status" )
1775 self.handle.expect( "\$" )
1776 response = self.handle.before
1777 if re.search( "onos start/running", response ):
1778 # onos start/running, process 10457
1779 return 'RUNNING'
1780 # FIXME: Implement this case
1781 # elif re.search( pattern, response ):
1782 # return 'STARTING'
1783 elif re.search( "onos stop/", response ):
1784 # onos stop/waiting
1785 # FIXME handle this differently?: onos stop/pre-stop
1786 return 'STOPPED'
1787 # FIXME: Implement this case
1788 # elif re.search( pattern, response ):
1789 # return 'FROZEN'
1790 else:
1791 main.log.warn( self.name +
Jon Hallefbd9792015-03-05 16:11:36 -08001792 " WARNING: status received unknown response" )
Jon Hall0468b042015-02-19 19:08:21 -08001793 main.log.warn( response )
1794 return 'ERROR', "Unknown response: %s" % response
1795 except pexpect.TIMEOUT:
1796 main.log.exception( self.name + ": Timeout exception in "
1797 "setIpTables function" )
1798 return 'ERROR', "Pexpect Timeout"
1799 except pexpect.EOF:
1800 main.log.error( self.name + ": EOF exception found" )
1801 main.log.error( self.name + ": " + self.handle.before )
1802 main.cleanup()
1803 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001804 except Exception:
1805 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall0468b042015-02-19 19:08:21 -08001806 main.cleanup()
1807 main.exit()
1808
andrew@onlab.us3b087132015-03-11 15:00:08 -07001809 def createLinkGraphFile( self, benchIp, ONOSIpList, deviceCount):
1810 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07001811 Create/formats the LinkGraph.cfg file based on arguments
1812 -only creates a linear topology and connects islands
1813 -evenly distributes devices
andrew@onlab.us3b087132015-03-11 15:00:08 -07001814 -must be called by ONOSbench
1815
Jon Hall4ba53f02015-07-29 13:07:41 -07001816 ONOSIpList - list of all of the node IPs to be used
1817
1818 deviceCount - number of switches to be assigned
andrew@onlab.us3b087132015-03-11 15:00:08 -07001819 '''
1820 main.log.step("Creating link graph configuration file." )
1821 linkGraphPath = self.home + "/tools/package/etc/linkGraph.cfg"
Jon Hall4ba53f02015-07-29 13:07:41 -07001822 tempFile = "/tmp/linkGraph.cfg"
andrew@onlab.us3b087132015-03-11 15:00:08 -07001823
1824 linkGraph = open(tempFile, 'w+')
1825 linkGraph.write("# NullLinkProvider topology description (config file).\n")
1826 linkGraph.write("# The NodeId is only added if the destination is another node's device.\n")
1827 linkGraph.write("# Bugs: Comments cannot be appended to a line to be read.\n")
Jon Hall4ba53f02015-07-29 13:07:41 -07001828
andrew@onlab.us3b087132015-03-11 15:00:08 -07001829 clusterCount = len(ONOSIpList)
Jon Hall4ba53f02015-07-29 13:07:41 -07001830
1831 if type(deviceCount) is int or type(deviceCount) is str:
andrew@onlab.us3b087132015-03-11 15:00:08 -07001832 deviceCount = int(deviceCount)
1833 switchList = [0]*(clusterCount+1)
1834 baselineSwitchCount = deviceCount/clusterCount
Jon Hall4ba53f02015-07-29 13:07:41 -07001835
andrew@onlab.us3b087132015-03-11 15:00:08 -07001836 for node in range(1, clusterCount + 1):
1837 switchList[node] = baselineSwitchCount
1838
1839 for node in range(1, (deviceCount%clusterCount)+1):
1840 switchList[node] += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07001841
andrew@onlab.us3b087132015-03-11 15:00:08 -07001842 if type(deviceCount) is list:
1843 main.log.info("Using provided device distribution")
1844 switchList = [0]
1845 for i in deviceCount:
1846 switchList.append(int(i))
1847
1848 tempList = ['0']
1849 tempList.extend(ONOSIpList)
1850 ONOSIpList = tempList
1851
1852 myPort = 6
1853 lastSwitch = 0
1854 for node in range(1, clusterCount+1):
1855 if switchList[node] == 0:
1856 continue
1857
1858 linkGraph.write("graph " + ONOSIpList[node] + " {\n")
Jon Hall4ba53f02015-07-29 13:07:41 -07001859
andrew@onlab.us3b087132015-03-11 15:00:08 -07001860 if node > 1:
1861 #connect to last device on previous node
Jon Hall4ba53f02015-07-29 13:07:41 -07001862 line = ("\t0:5 -> " + str(lastSwitch) + ":6:" + lastIp + "\n") #ONOSIpList[node-1]
1863 linkGraph.write(line)
1864
1865 lastSwitch = 0
1866 for switch in range (0, switchList[node]-1):
andrew@onlab.us3b087132015-03-11 15:00:08 -07001867 line = ""
1868 line = ("\t" + str(switch) + ":" + str(myPort))
1869 line += " -- "
1870 line += (str(switch+1) + ":" + str(myPort-1) + "\n")
1871 linkGraph.write(line)
Jon Hall4ba53f02015-07-29 13:07:41 -07001872 lastSwitch = switch+1
andrew@onlab.us3b087132015-03-11 15:00:08 -07001873 lastIp = ONOSIpList[node]
Jon Hall4ba53f02015-07-29 13:07:41 -07001874
andrew@onlab.us3b087132015-03-11 15:00:08 -07001875 #lastSwitch += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07001876 if node < (clusterCount):
andrew@onlab.us3b087132015-03-11 15:00:08 -07001877 #connect to first device on the next node
Jon Hall4ba53f02015-07-29 13:07:41 -07001878 line = ("\t" + str(lastSwitch) + ":6 -> 0:5:" + ONOSIpList[node+1] + "\n")
andrew@onlab.us3b087132015-03-11 15:00:08 -07001879 linkGraph.write(line)
Jon Hall4ba53f02015-07-29 13:07:41 -07001880
andrew@onlab.us3b087132015-03-11 15:00:08 -07001881 linkGraph.write("}\n")
1882 linkGraph.close()
1883
1884 #SCP
Jon Hall4ba53f02015-07-29 13:07:41 -07001885 os.system( "scp " + tempFile + " " + self.user_name + "@" + benchIp + ":" + linkGraphPath)
andrew@onlab.us3b087132015-03-11 15:00:08 -07001886 main.log.info("linkGraph.cfg creation complete")
1887
cameron@onlab.us75900962015-03-30 13:22:49 -07001888 def configNullDev( self, ONOSIpList, deviceCount, numPorts=10):
Jon Hall4ba53f02015-07-29 13:07:41 -07001889
andrew@onlab.us3b087132015-03-11 15:00:08 -07001890 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07001891 ONOSIpList = list of Ip addresses of nodes switches will be devided amongst
1892 deviceCount = number of switches to distribute, or list of values to use as custom distribution
cameron@onlab.us75900962015-03-30 13:22:49 -07001893 numPorts = number of ports per device. Defaults to 10 both in this function and in ONOS. Optional arg
andrew@onlab.us3b087132015-03-11 15:00:08 -07001894 '''
1895
cameron@onlab.us75900962015-03-30 13:22:49 -07001896 main.log.step("Configuring Null Device Provider" )
andrew@onlab.us3b087132015-03-11 15:00:08 -07001897 clusterCount = len(ONOSIpList)
1898
Jon Hall4ba53f02015-07-29 13:07:41 -07001899 try:
1900
cameron@onlab.us75900962015-03-30 13:22:49 -07001901 if type(deviceCount) is int or type(deviceCount) is str:
1902 main.log.step("Creating device distribution")
1903 deviceCount = int(deviceCount)
1904 switchList = [0]*(clusterCount+1)
1905 baselineSwitchCount = deviceCount/clusterCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001906
cameron@onlab.us75900962015-03-30 13:22:49 -07001907 for node in range(1, clusterCount + 1):
1908 switchList[node] = baselineSwitchCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001909
cameron@onlab.us75900962015-03-30 13:22:49 -07001910 for node in range(1, (deviceCount%clusterCount)+1):
1911 switchList[node] += 1
Jon Hall4ba53f02015-07-29 13:07:41 -07001912
1913 if type(deviceCount) is list:
1914 main.log.info("Using provided device distribution")
1915
1916 if len(deviceCount) == clusterCount:
cameron@onlab.us75900962015-03-30 13:22:49 -07001917 switchList = ['0']
1918 switchList.extend(deviceCount)
Jon Hall4ba53f02015-07-29 13:07:41 -07001919
1920 if len(deviceCount) == (clusterCount + 1):
1921 if deviceCount[0] == '0' or deviceCount[0] == 0:
cameron@onlab.us75900962015-03-30 13:22:49 -07001922 switchList = deviceCount
andrew@onlab.us3b087132015-03-11 15:00:08 -07001923
cameron@onlab.us75900962015-03-30 13:22:49 -07001924 assert len(switchList) == (clusterCount + 1)
Jon Hall4ba53f02015-07-29 13:07:41 -07001925
cameron@onlab.us75900962015-03-30 13:22:49 -07001926 except AssertionError:
Jon Hall4ba53f02015-07-29 13:07:41 -07001927 main.log.error( "Bad device/Ip list match")
cameron@onlab.us75900962015-03-30 13:22:49 -07001928 except TypeError:
1929 main.log.exception( self.name + ": Object not as expected" )
1930 return None
Jon Hall77ba41c2015-04-06 10:25:40 -07001931 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07001932 main.log.exception( self.name + ": Uncaught exception!" )
1933 main.cleanup()
1934 main.exit()
1935
andrew@onlab.us3b087132015-03-11 15:00:08 -07001936
1937 ONOSIp = [0]
1938 ONOSIp.extend(ONOSIpList)
Jon Hall4ba53f02015-07-29 13:07:41 -07001939
andrew@onlab.us3b087132015-03-11 15:00:08 -07001940 devicesString = "devConfigs = "
1941 for node in range(1, len(ONOSIp)):
1942 devicesString += (ONOSIp[node] + ":" + str(switchList[node] ))
1943 if node < clusterCount:
1944 devicesString += (",")
Jon Hall4ba53f02015-07-29 13:07:41 -07001945
1946 try:
cameron@onlab.us75900962015-03-30 13:22:49 -07001947 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider devConfigs " + devicesString )
1948 self.handle.expect(":~")
1949 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider numPorts " + str(numPorts) )
1950 self.handle.expect(":~")
andrew@onlab.us3b087132015-03-11 15:00:08 -07001951
cameron@onlab.us75900962015-03-30 13:22:49 -07001952 for i in range(10):
1953 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.device.impl.NullDeviceProvider")
1954 self.handle.expect(":~")
1955 verification = self.handle.before
1956 if (" value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification:
1957 break
1958 else:
1959 time.sleep(1)
andrew@onlab.us3b087132015-03-11 15:00:08 -07001960
cameron@onlab.us2cc8bf12015-04-02 14:12:30 -07001961 assert ("value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification
Jon Hall4ba53f02015-07-29 13:07:41 -07001962
cameron@onlab.us75900962015-03-30 13:22:49 -07001963 except AssertionError:
1964 main.log.error("Incorrect Config settings: " + verification)
Jon Hall77ba41c2015-04-06 10:25:40 -07001965 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07001966 main.log.exception( self.name + ": Uncaught exception!" )
1967 main.cleanup()
1968 main.exit()
1969
Jon Hall4ba53f02015-07-29 13:07:41 -07001970 def configNullLink( self,fileName="/opt/onos/apache-karaf-3.0.3/etc/linkGraph.cfg", eventRate=0):
andrew@onlab.us3b087132015-03-11 15:00:08 -07001971 '''
Jon Hall4ba53f02015-07-29 13:07:41 -07001972 fileName default is currently the same as the default on ONOS, specify alternate file if
cameron@onlab.us75900962015-03-30 13:22:49 -07001973 you want to use a different topology file than linkGraph.cfg
andrew@onlab.us3b087132015-03-11 15:00:08 -07001974 '''
1975
Jon Hall4ba53f02015-07-29 13:07:41 -07001976
1977 try:
1978 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider eventRate " + str(eventRate))
1979 self.handle.expect(":~")
cameron@onlab.us75900962015-03-30 13:22:49 -07001980 self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider cfgFile " + fileName )
1981 self.handle.expect(":~")
Jon Hall4ba53f02015-07-29 13:07:41 -07001982
1983 for i in range(10):
1984 self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.link.impl.NullLinkProvider")
cameron@onlab.us75900962015-03-30 13:22:49 -07001985 self.handle.expect(":~")
1986 verification = self.handle.before
Jon Hall4ba53f02015-07-29 13:07:41 -07001987 if (" value=" + str(eventRate)) in verification and (" value=" + fileName) in verification:
cameron@onlab.us75900962015-03-30 13:22:49 -07001988 break
Jon Hall4ba53f02015-07-29 13:07:41 -07001989 else:
cameron@onlab.us75900962015-03-30 13:22:49 -07001990 time.sleep(1)
Jon Hall4ba53f02015-07-29 13:07:41 -07001991
cameron@onlab.us75900962015-03-30 13:22:49 -07001992 assert ("value=" + str(eventRate)) in verification and (" value=" + fileName) in verification
Jon Hall4ba53f02015-07-29 13:07:41 -07001993
cameron@onlab.us75900962015-03-30 13:22:49 -07001994 except pexpect.EOF:
1995 main.log.error( self.name + ": EOF exception found" )
1996 main.log.error( self.name + ": " + self.handle.before )
1997 main.cleanup()
1998 main.exit()
cameron@onlab.us75900962015-03-30 13:22:49 -07001999 except AssertionError:
2000 main.log.info("Settings did not post to ONOS")
Jon Hall4ba53f02015-07-29 13:07:41 -07002001 main.log.error(varification)
Jon Hall77ba41c2015-04-06 10:25:40 -07002002 except Exception:
cameron@onlab.us75900962015-03-30 13:22:49 -07002003 main.log.exception( self.name + ": Uncaught exception!" )
2004 main.log.error(varification)
2005 main.cleanup()
2006 main.exit()
andrew@onlab.us3b087132015-03-11 15:00:08 -07002007
kelvin-onlaba4074292015-07-09 15:19:49 -07002008 def getOnosIps( self ):
2009 """
2010 Get all onos IPs stored in
2011 """
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002012
kelvin-onlaba4074292015-07-09 15:19:49 -07002013 return sorted( self.onosIps.values() )
cameron@onlab.us59d29d92015-05-11 14:31:54 -07002014
kelvin-onlaba4074292015-07-09 15:19:49 -07002015 def logReport( self, nodeIp, searchTerms, outputMode="s" ):
Jon Hallb4242222016-01-25 17:07:04 -08002016 """
2017 Searches the latest ONOS log file for the given search terms and
2018 prints the total occurances of each term. Returns to combined total of
2019 all occurances.
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002020
Jon Hallb4242222016-01-25 17:07:04 -08002021 Arguments:
2022 * nodeIp - The ip of the ONOS node where the log is located
2023 * searchTerms - A string to grep for or a list of strings to grep
2024 for in the ONOS log. Will print out the number of
2025 occurances for each term.
2026 Optional Arguments:
2027 * outputMode - 's' or 'd'. If 'd' will print the last 5 lines
2028 containing each search term as well as the total
2029 number of occurances of each term. Defaults to 's',
2030 which prints the simple output of just the number
2031 of occurances for each term.
2032 """
2033 try:
2034 main.log.info( " Log Report for {} ".format( nodeIp ).center( 70, '=' ) )
2035 if type( searchTerms ) is str:
2036 searchTerms = [searchTerms]
2037 numTerms = len( searchTerms )
2038 outputMode = outputMode.lower()
cameron@onlab.us70dd8c62015-05-14 11:19:39 -07002039
Jon Hallb4242222016-01-25 17:07:04 -08002040 totalHits = 0
2041 logLines = []
2042 for termIndex in range( numTerms ):
2043 term = searchTerms[termIndex]
2044 logLines.append( [term] )
2045 cmd = "onos-ssh " + nodeIp + " cat /opt/onos/log/karaf.log | grep " + term
2046 self.handle.sendline( cmd )
2047 self.handle.expect( ":~" )
2048 before = self.handle.before.splitlines()
2049 count = 0
2050 for line in before:
2051 if term in line and "grep" not in line:
2052 count += 1
2053 if before.index( line ) > ( len( before ) - 7 ):
2054 logLines[termIndex].append( line )
2055 main.log.info( "{}: {}".format( term, count ) )
2056 totalHits += count
2057 if termIndex == numTerms - 1:
2058 print "\n"
2059 if outputMode != "s":
2060 outputString = ""
2061 for term in logLines:
2062 outputString = term[0] + ": \n"
2063 for line in range( 1, len( term ) ):
2064 outputString += ( "\t" + term[line] + "\n" )
2065 if outputString != ( term[0] + ": \n" ):
2066 main.log.info( outputString )
2067 main.log.info( "=" * 70 )
2068 return totalHits
2069 except pexpect.EOF:
2070 main.log.error( self.name + ": EOF exception found" )
2071 main.log.error( self.name + ": " + self.handle.before )
2072 main.cleanup()
2073 main.exit()
2074 except pexpect.TIMEOUT:
2075 main.log.error( self.name + ": TIMEOUT exception found" )
2076 main.log.error( self.name + ": " + self.handle.before )
2077 main.cleanup()
2078 main.exit()
2079 except Exception:
2080 main.log.exception( self.name + ": Uncaught exception!" )
2081 main.cleanup()
2082 main.exit()
kelvin-onlab7a719bb2015-07-08 11:09:51 -07002083
2084 def copyMininetFile( self, fileName, localPath, userName, ip,
2085 mnPath='~/mininet/custom/', timeout = 60 ):
2086 """
2087 Description:
2088 Copy mininet topology file from dependency folder in the test folder
2089 and paste it to the mininet machine's mininet/custom folder
2090 Required:
2091 fileName - Name of the topology file to copy
2092 localPath - File path of the mininet topology file
2093 userName - User name of the mininet machine to send the file to
2094 ip - Ip address of the mininet machine
2095 Optional:
2096 mnPath - of the mininet directory to send the file to
2097 Return:
2098 Return main.TRUE if successfully copied the file otherwise
2099 return main.FALSE
2100 """
2101
2102 try:
2103 cmd = "scp " + localPath + fileName + " " + userName + "@" + \
2104 str( ip ) + ":" + mnPath + fileName
2105
2106 self.handle.sendline( "" )
2107 self.handle.expect( "\$" )
2108
2109 main.log.info( self.name + ": Execute: " + cmd )
2110
2111 self.handle.sendline( cmd )
2112
2113 i = self.handle.expect( [ 'No such file',
2114 "100%",
2115 pexpect.TIMEOUT ] )
2116
2117 if i == 0:
2118 main.log.error( self.name + ": File " + fileName +
2119 " does not exist!" )
2120 return main.FALSE
2121
2122 if i == 1:
2123 main.log.info( self.name + ": File " + fileName +
2124 " has been copied!" )
2125 self.handle.sendline( "" )
2126 self.handle.expect( "\$" )
2127 return main.TRUE
2128
2129 except pexpect.EOF:
2130 main.log.error( self.name + ": EOF exception found" )
2131 main.log.error( self.name + ": " + self.handle.before )
2132 main.cleanup()
2133 main.exit()
2134 except pexpect.TIMEOUT:
2135 main.log.error( self.name + ": TIMEOUT exception found" )
2136 main.log.error( self.name + ": " + self.handle.before )
2137 main.cleanup()
2138 main.exit()
cameron@onlab.us78b89652015-07-08 15:21:03 -07002139
2140 def jvmSet(self, memory=8):
Jon Hall4ba53f02015-07-29 13:07:41 -07002141
cameron@onlab.us78b89652015-07-08 15:21:03 -07002142 import os
2143
2144 homeDir = os.path.expanduser('~')
2145 filename = "/onos/tools/package/bin/onos-service"
2146
2147 serviceConfig = open(homeDir + filename, 'w+')
2148 serviceConfig.write("#!/bin/bash\n ")
2149 serviceConfig.write("#------------------------------------- \n ")
2150 serviceConfig.write("# Starts ONOS Apache Karaf container\n ")
2151 serviceConfig.write("#------------------------------------- \n ")
2152 serviceConfig.write("#export JAVA_HOME=${JAVA_HOME:-/usr/lib/jvm/java-7-openjdk-amd64/}\n ")
2153 serviceConfig.write("""export JAVA_OPTS="${JAVA_OPTS:--Xms""" + str(memory) + "G -Xmx" + str(memory) + """G}" \n """)
2154 serviceConfig.write("[ -d $ONOS_HOME ] && cd $ONOS_HOME || ONOS_HOME=$(dirname $0)/..\n")
2155 serviceConfig.write("""${ONOS_HOME}/apache-karaf-$KARAF_VERSION/bin/karaf "$@" \n """)
2156 serviceConfig.close()
2157
Jon Hall6c44c0b2016-04-20 15:21:00 -07002158 def createDBFile( self, testData ):
Jon Hall4ba53f02015-07-29 13:07:41 -07002159
cameron@onlab.us78b89652015-07-08 15:21:03 -07002160 filename = main.TEST + "DB"
2161 DBString = ""
Jon Hall4ba53f02015-07-29 13:07:41 -07002162
cameron@onlab.us78b89652015-07-08 15:21:03 -07002163 for item in testData:
Jon Hall6c44c0b2016-04-20 15:21:00 -07002164 if type( item ) is string:
cameron@onlab.us78b89652015-07-08 15:21:03 -07002165 item = "'" + item + "'"
Jon Hall6c44c0b2016-04-20 15:21:00 -07002166 if testData.index( item ) < len( testData - 1 ):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002167 item += ","
Jon Hall6c44c0b2016-04-20 15:21:00 -07002168 DBString += str( item )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002169
Jon Hall6c44c0b2016-04-20 15:21:00 -07002170 DBFile = open( filename, "a" )
2171 DBFile.write( DBString )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002172 DBFile.close()
2173
Jon Hall6c44c0b2016-04-20 15:21:00 -07002174 def verifySummary( self, ONOSIp, *deviceCount ):
cameron@onlab.us78b89652015-07-08 15:21:03 -07002175
Jon Hall6c44c0b2016-04-20 15:21:00 -07002176 self.handle.sendline( "onos " + ONOSIp + " summary" )
2177 self.handle.expect( ":~" )
cameron@onlab.us78b89652015-07-08 15:21:03 -07002178
2179 summaryStr = self.handle.before
2180 print "\nSummary\n==============\n" + summaryStr + "\n\n"
2181
2182 #passed = "SCC(s)=1" in summaryStr
2183 #if deviceCount:
2184 # passed = "devices=" + str(deviceCount) + "," not in summaryStr
2185
GlennRC772363b2015-08-25 13:05:57 -07002186 passed = False
cameron@onlab.us78b89652015-07-08 15:21:03 -07002187 if "SCC(s)=1," in summaryStr:
2188 passed = True
Jon Hall6c44c0b2016-04-20 15:21:00 -07002189 print "Summary is verifed"
Jon Hall4ba53f02015-07-29 13:07:41 -07002190 else:
Jon Hall6c44c0b2016-04-20 15:21:00 -07002191 print "Summary failed"
cameron@onlab.us78b89652015-07-08 15:21:03 -07002192
2193 if deviceCount:
2194 print" ============================="
Jon Hall6c44c0b2016-04-20 15:21:00 -07002195 checkStr = "devices=" + str( deviceCount[0] ) + ","
cameron@onlab.us78b89652015-07-08 15:21:03 -07002196 print "Checkstr: " + checkStr
2197 if checkStr not in summaryStr:
2198 passed = False
Jon Hall6c44c0b2016-04-20 15:21:00 -07002199 print "Device count failed"
Jon Hall4ba53f02015-07-29 13:07:41 -07002200 else:
2201 print "device count verified"
cameron@onlab.us78b89652015-07-08 15:21:03 -07002202
2203 return passed
Jon Hall6c44c0b2016-04-20 15:21:00 -07002204
2205 def getIpAddr( self ):
2206 """
2207 Update self.ip_address with numerical ip address. If multiple IP's are
2208 located on the device, will attempt to use self.nicAddr to choose the
2209 right one. Defaults to 127.0.0.1 if no other address is found or cannot
2210 determine the correct address.
2211
2212 ONLY WORKS WITH IPV4 ADDRESSES
2213 """
2214 try:
2215 localhost = "127.0.0.1"
2216 ipPat = "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"
2217 pattern = re.compile( ipPat )
2218 match = re.search( pattern, self.ip_address )
2219 if self.nicAddr:
2220 nicPat = self.nicAddr.replace( ".", "\." ).replace( "\*", r"\d{1,3}" )
2221 nicPat = re.compile( nicPat )
2222 else:
2223 nicPat = None
2224 # IF self.ip_address is an ip address and matches
2225 # self.nicAddr: return self.ip_address
2226 if match:
2227 curIp = match.group(0)
2228 if nicPat:
2229 nicMatch = re.search( nicPat, curIp )
2230 if nicMatch:
2231 return self.ip_address
2232 # ELSE: attempt to get correct address.
2233 raw = subprocess.check_output( "ifconfig")
2234 ifPat = re.compile( "inet addr:({})".format( ipPat ) )
2235 ips = re.findall( ifPat, raw )
2236 if nicPat:
2237 for ip in ips:
2238 curMatch = re.search( nicPat, ip )
2239 if curMatch:
2240 self.ip_address = ip
2241 return ip
2242 else:
2243 tmpList = [ ip for ip in ips if ip is not localhost ]
2244 if len(tmpList) == 1:
2245 curIp = tmpList[0]
2246 self.ip_address = curIp
2247 return curIp
2248 return localhost
2249 except Exception:
2250 main.log.exception( "Uncaught exception" )