blob: 9d9a3fad8fd2471be78882413148591c11e84489 [file] [log] [blame]
Jon Hall6aec96b2015-01-19 14:49:31 -08001"""
Jon Hall73cf9cc2014-11-20 22:28:38 -08002Description: This test is to determine if a single
3 instance ONOS 'cluster' can handle a restart
4
5List of test cases:
6CASE1: Compile ONOS and push it to the test machines
7CASE2: Assign mastership to controllers
8CASE3: Assign intents
9CASE4: Ping across added host intents
10CASE5: Reading state of ONOS
11CASE6: The Failure case. Since this is the Sanity test, we do nothing.
12CASE7: Check state after control plane failure
13CASE8: Compare topo
14CASE9: Link s3-s28 down
15CASE10: Link s3-s28 up
16CASE11: Switch down
17CASE12: Switch up
18CASE13: Clean up
Jon Hall669173b2014-12-17 11:36:30 -080019CASE14: start election app on all onos nodes
20CASE15: Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -080021"""
Jon Hall8f89dda2015-01-22 16:03:33 -080022
23
Jon Hall48cf3ce2015-01-12 15:43:18 -080024class HATestSingleInstanceRestart:
Jon Hall73cf9cc2014-11-20 22:28:38 -080025
Jon Hall6aec96b2015-01-19 14:49:31 -080026 def __init__( self ):
Jon Hall73cf9cc2014-11-20 22:28:38 -080027 self.default = ''
28
Jon Hall6aec96b2015-01-19 14:49:31 -080029 def CASE1( self, main ):
30 """
Jon Hall73cf9cc2014-11-20 22:28:38 -080031 CASE1 is to compile ONOS and push it to the test machines
32
33 Startup sequence:
Jon Hall73cf9cc2014-11-20 22:28:38 -080034 cell <name>
35 onos-verify-cell
36 NOTE: temporary - onos-remove-raft-logs
Jon Hall58c76b72015-02-23 11:09:24 -080037 onos-uninstall
38 start mininet
39 git pull
40 mvn clean install
41 onos-package
Jon Hall73cf9cc2014-11-20 22:28:38 -080042 onos-install -f
43 onos-wait-for-start
Jon Hall58c76b72015-02-23 11:09:24 -080044 start cli sessions
45 start tcpdump
Jon Hall6aec96b2015-01-19 14:49:31 -080046 """
47 main.log.report( "ONOS Single node cluster restart " +
48 "HA test - initialization" )
49 main.case( "Setting up test environment" )
50 # TODO: save all the timers and output them for plotting
Jon Hall73cf9cc2014-11-20 22:28:38 -080051
52 # load some vairables from the params file
Jon Hall8f89dda2015-01-22 16:03:33 -080053 PULLCODE = False
Jon Hall6aec96b2015-01-19 14:49:31 -080054 if main.params[ 'Git' ] == 'True':
Jon Hall8f89dda2015-01-22 16:03:33 -080055 PULLCODE = True
Jon Hall529a37f2015-01-28 10:02:00 -080056 gitBranch = main.params[ 'branch' ]
Jon Hall8f89dda2015-01-22 16:03:33 -080057 cellName = main.params[ 'ENV' ][ 'cellName' ]
Jon Hall6aec96b2015-01-19 14:49:31 -080058
59 # set global variables
Jon Hall8f89dda2015-01-22 16:03:33 -080060 global ONOS1Ip
61 global ONOS1Port
62 global ONOS2Ip
63 global ONOS2Port
64 global ONOS3Ip
65 global ONOS3Port
66 global ONOS4Ip
67 global ONOS4Port
68 global ONOS5Ip
69 global ONOS5Port
70 global ONOS6Ip
71 global ONOS6Port
72 global ONOS7Ip
73 global ONOS7Port
74 global numControllers
Jon Hall73cf9cc2014-11-20 22:28:38 -080075
Jon Hall8f89dda2015-01-22 16:03:33 -080076 ONOS1Ip = main.params[ 'CTRL' ][ 'ip1' ]
77 ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
78 ONOS2Ip = main.params[ 'CTRL' ][ 'ip2' ]
79 ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
80 ONOS3Ip = main.params[ 'CTRL' ][ 'ip3' ]
81 ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
82 ONOS4Ip = main.params[ 'CTRL' ][ 'ip4' ]
83 ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
84 ONOS5Ip = main.params[ 'CTRL' ][ 'ip5' ]
85 ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
86 ONOS6Ip = main.params[ 'CTRL' ][ 'ip6' ]
87 ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
88 ONOS7Ip = main.params[ 'CTRL' ][ 'ip7' ]
89 ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
90 numControllers = int( main.params[ 'num_controllers' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -080091
Jon Hall6aec96b2015-01-19 14:49:31 -080092 main.step( "Applying cell variable to environment" )
Jon Hall8f89dda2015-01-22 16:03:33 -080093 cellResult = main.ONOSbench.setCell( cellName )
94 verifyResult = main.ONOSbench.verifyCell()
Jon Hall73cf9cc2014-11-20 22:28:38 -080095
Jon Hall6aec96b2015-01-19 14:49:31 -080096 # FIXME:this is short term fix
97 main.log.report( "Removing raft logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -080098 main.ONOSbench.onosRemoveRaftLogs()
Jon Hall6aec96b2015-01-19 14:49:31 -080099 main.log.report( "Uninstalling ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800100 main.ONOSbench.onosUninstall( ONOS1Ip )
101 main.ONOSbench.onosUninstall( ONOS2Ip )
102 main.ONOSbench.onosUninstall( ONOS3Ip )
103 main.ONOSbench.onosUninstall( ONOS4Ip )
104 main.ONOSbench.onosUninstall( ONOS5Ip )
105 main.ONOSbench.onosUninstall( ONOS6Ip )
106 main.ONOSbench.onosUninstall( ONOS7Ip )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800107
Jon Hall8f89dda2015-01-22 16:03:33 -0800108 cleanInstallResult = main.TRUE
109 gitPullResult = main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800110
Jon Hall97f31752015-02-04 12:01:04 -0800111 main.step( "Starting Mininet" )
112 main.Mininet1.startNet( )
113
Jon Hall6aec96b2015-01-19 14:49:31 -0800114 main.step( "Compiling the latest version of ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800115 if PULLCODE:
Jon Hall58c76b72015-02-23 11:09:24 -0800116 main.step( "Git checkout and pull " + gitBranch )
Jon Hall529a37f2015-01-28 10:02:00 -0800117 main.ONOSbench.gitCheckout( gitBranch )
Jon Hall8f89dda2015-01-22 16:03:33 -0800118 gitPullResult = main.ONOSbench.gitPull()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800119
Jon Hall6aec96b2015-01-19 14:49:31 -0800120 main.step( "Using mvn clean & install" )
Jon Hall529a37f2015-01-28 10:02:00 -0800121 cleanInstallResult = main.ONOSbench.cleanInstall()
122 else:
123 main.log.warn( "Did not pull new code so skipping mvn " +
124 "clean install" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800125 main.ONOSbench.getVersion( report=True )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800126
Jon Hall8f89dda2015-01-22 16:03:33 -0800127 cellResult = main.ONOSbench.setCell( "SingleHA" )
128 verifyResult = main.ONOSbench.verifyCell()
Jon Hall6aec96b2015-01-19 14:49:31 -0800129 main.step( "Creating ONOS package" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800130 packageResult = main.ONOSbench.onosPackage()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800131
Jon Hall6aec96b2015-01-19 14:49:31 -0800132 main.step( "Installing ONOS package" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800133 onos1InstallResult = main.ONOSbench.onosInstall( options="-f",
134 node=ONOS1Ip )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800135
Jon Hall6aec96b2015-01-19 14:49:31 -0800136 main.step( "Checking if ONOS is up yet" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800137 for i in range( 2 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800138 onos1Isup = main.ONOSbench.isup( ONOS1Ip )
139 if onos1Isup:
Jon Hall94fd0472014-12-08 11:52:42 -0800140 break
Jon Hall8f89dda2015-01-22 16:03:33 -0800141 if not onos1Isup:
Jon Hall6aec96b2015-01-19 14:49:31 -0800142 main.log.report( "ONOS1 didn't start!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800143
Jon Hall8f89dda2015-01-22 16:03:33 -0800144 cliResult = main.ONOScli1.startOnosCli( ONOS1Ip )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800145
Jon Hall6aec96b2015-01-19 14:49:31 -0800146 main.step( "Start Packet Capture MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800147 main.Mininet2.startTcpdump(
Jon Hall6aec96b2015-01-19 14:49:31 -0800148 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
149 + "-MN.pcap",
150 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
151 port=main.params[ 'MNtcpdump' ][ 'port' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800152
Jon Hall8f89dda2015-01-22 16:03:33 -0800153 case1Result = ( cleanInstallResult and packageResult and
154 cellResult and verifyResult and onos1InstallResult
155 and onos1Isup and cliResult )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800156
Jon Hall8f89dda2015-01-22 16:03:33 -0800157 utilities.assert_equals( expect=main.TRUE, actual=case1Result,
Jon Hall58c76b72015-02-23 11:09:24 -0800158 onpass="Test startup successful",
159 onfail="Test startup NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800160
Jon Hall8f89dda2015-01-22 16:03:33 -0800161 if case1Result == main.FALSE:
Jon Hall73cf9cc2014-11-20 22:28:38 -0800162 main.cleanup()
163 main.exit()
164
Jon Hall6aec96b2015-01-19 14:49:31 -0800165 def CASE2( self, main ):
166 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800167 Assign mastership to controllers
Jon Hall6aec96b2015-01-19 14:49:31 -0800168 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800169 import re
170
Jon Hall6aec96b2015-01-19 14:49:31 -0800171 main.log.report( "Assigning switches to controllers" )
172 main.case( "Assigning Controllers" )
173 main.step( "Assign switches to controllers" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800174
Jon Hall6aec96b2015-01-19 14:49:31 -0800175 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800176 main.Mininet1.assignSwController(
Jon Hall6aec96b2015-01-19 14:49:31 -0800177 sw=str( i ),
Jon Hall8f89dda2015-01-22 16:03:33 -0800178 ip1=ONOS1Ip, port1=ONOS1Port )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800179
Jon Hall8f89dda2015-01-22 16:03:33 -0800180 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800181 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800182 response = main.Mininet1.getSwController( "s" + str( i ) )
Jon Hallffb386d2014-11-21 13:43:38 -0800183 try:
Jon Hall6aec96b2015-01-19 14:49:31 -0800184 main.log.info( str( response ) )
Jon Hallfebb1c72015-03-05 13:30:09 -0800185 except Exception:
Jon Hall6aec96b2015-01-19 14:49:31 -0800186 main.log.info( repr( response ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800187 if re.search( "tcp:" + ONOS1Ip, response ):
188 mastershipCheck = mastershipCheck and main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800189 else:
Jon Hall8f89dda2015-01-22 16:03:33 -0800190 mastershipCheck = main.FALSE
191 if mastershipCheck == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800192 main.log.report( "Switch mastership assigned correctly" )
193 utilities.assert_equals(
194 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800195 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800196 onpass="Switch mastership assigned correctly",
197 onfail="Switches not assigned correctly to controllers" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800198
Jon Hall6aec96b2015-01-19 14:49:31 -0800199 def CASE3( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800200 """
201 Assign intents
Jon Hall73cf9cc2014-11-20 22:28:38 -0800202 """
203 import time
Jon Hallfebb1c72015-03-05 13:30:09 -0800204 import json
Jon Hall73cf9cc2014-11-20 22:28:38 -0800205 # FIXME: we must reinstall intents until we have a persistant
206 # datastore!
Jon Hall6aec96b2015-01-19 14:49:31 -0800207 main.log.report( "Adding host intents" )
208 main.case( "Adding host Intents" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800209
Jon Hall8f89dda2015-01-22 16:03:33 -0800210 main.step( "Discovering Hosts( Via pingall for now )" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800211 # FIXME: Once we have a host discovery mechanism, use that instead
Jon Hall73cf9cc2014-11-20 22:28:38 -0800212
Jon Hall6aec96b2015-01-19 14:49:31 -0800213 # install onos-app-fwd
214 main.log.info( "Install reactive forwarding app" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800215 main.ONOScli1.featureInstall( "onos-app-fwd" )
Jon Hall94fd0472014-12-08 11:52:42 -0800216
Jon Hall6aec96b2015-01-19 14:49:31 -0800217 # REACTIVE FWD test
Jon Hall8f89dda2015-01-22 16:03:33 -0800218 pingResult = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800219 time1 = time.time()
Jon Hall8f89dda2015-01-22 16:03:33 -0800220 pingResult = main.Mininet1.pingall()
Jon Hall529a37f2015-01-28 10:02:00 -0800221 utilities.assert_equals(
222 expect=main.TRUE,
223 actual=pingResult,
224 onpass="Reactive Pingall test passed",
225 onfail="Reactive Pingall failed, one or more ping pairs failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800226 time2 = time.time()
Jon Hall6aec96b2015-01-19 14:49:31 -0800227 main.log.info( "Time for pingall: %2f seconds" % ( time2 - time1 ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800228
Jon Hall6aec96b2015-01-19 14:49:31 -0800229 # uninstall onos-app-fwd
230 main.log.info( "Uninstall reactive forwarding app" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800231 main.ONOScli1.featureUninstall( "onos-app-fwd" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800232 # timeout for fwd flows
233 time.sleep( 10 )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800234
Jon Hall6aec96b2015-01-19 14:49:31 -0800235 main.step( "Add host intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800236 intentIds = []
Jon Hall6aec96b2015-01-19 14:49:31 -0800237 # TODO: move the host numbers to params
Jon Hall58c76b72015-02-23 11:09:24 -0800238 # Maybe look at all the paths we ping?
Jon Hall8f89dda2015-01-22 16:03:33 -0800239 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800240 hostResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800241 for i in range( 8, 18 ):
242 main.log.info( "Adding host intent between h" + str( i ) +
243 " and h" + str( i + 10 ) )
244 host1 = "00:00:00:00:00:" + \
245 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
246 host2 = "00:00:00:00:00:" + \
247 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800248 # NOTE: getHost can return None
249 host1Dict = main.ONOScli1.getHost( host1 )
250 host2Dict = main.ONOScli1.getHost( host2 )
251 host1Id = None
252 host2Id = None
253 if host1Dict and host2Dict:
254 host1Id = host1Dict.get( 'id', None )
255 host2Id = host2Dict.get( 'id', None )
Jon Hall8f89dda2015-01-22 16:03:33 -0800256 if host1Id and host2Id:
Jon Hall58c76b72015-02-23 11:09:24 -0800257 tmpId = main.ONOScli1.addHostIntent(
Jon Hall8f89dda2015-01-22 16:03:33 -0800258 host1Id,
259 host2Id )
Jon Hall63604932015-02-26 17:09:50 -0800260 if tmpId:
261 main.log.info( "Added intent with id: " + tmpId )
262 intentIds.append( tmpId )
263 else:
264 main.log.error( "addHostIntent reutrned None" )
Jon Hall669173b2014-12-17 11:36:30 -0800265 else:
Jon Hall8f89dda2015-01-22 16:03:33 -0800266 main.log.error( "Error, getHost() failed" )
Jon Hall1b8f54a2015-02-04 13:24:20 -0800267 main.log.warn( json.dumps( json.loads( main.ONOScli1.hosts() ),
268 sort_keys=True,
269 indent=4,
270 separators=( ',', ': ' ) ) )
Jon Hall58c76b72015-02-23 11:09:24 -0800271 hostResult = main.FALSE
272 onosIds = main.ONOScli1.getAllIntentsId()
273 main.log.info( "Submitted intents: " + str( intentIds ) )
274 main.log.info( "Intents in ONOS: " + str( onosIds ) )
275 for intent in intentIds:
276 if intent in onosIds:
277 pass # intent submitted is still in onos
278 else:
279 intentAddResult = False
Jon Hall1b8f54a2015-02-04 13:24:20 -0800280 # Print the intent states
Jon Hall58c76b72015-02-23 11:09:24 -0800281 intents = main.ONOScli1.intents()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800282 intentStates = []
Jon Hall63604932015-02-26 17:09:50 -0800283 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800284 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
285 count = 0
Jon Hall1b8f54a2015-02-04 13:24:20 -0800286 for intent in json.loads( intents ): # Iter through intents of a node
Jon Hall58c76b72015-02-23 11:09:24 -0800287 state = intent.get( 'state', None )
Jon Hall63604932015-02-26 17:09:50 -0800288 if "INSTALLED" not in state:
289 installedCheck = False
Jon Hall58c76b72015-02-23 11:09:24 -0800290 intentId = intent.get( 'id', None )
291 intentStates.append( ( intentId, state ) )
292 # add submitted intents not in the store
293 tmplist = [ i for i, s in intentStates ]
294 missingIntents = False
295 for i in intentIds:
296 if i not in tmplist:
297 intentStates.append( ( i, " - " ) )
298 missingIntents = True
299 intentStates.sort()
300 for i, s in intentStates:
301 count += 1
302 main.log.info( "%-6s%-15s%-15s" %
303 ( str( count ), str( i ), str( s ) ) )
Jon Hall63604932015-02-26 17:09:50 -0800304 main.ONOScli1.leaders()
305 main.ONOScli1.partitions()
306 # for node in nodes:
307 # node.pendingMap()
308 pendingMap = main.ONOScli1.pendingMap()
Jon Hall58c76b72015-02-23 11:09:24 -0800309 intentAddResult = bool( pingResult and hostResult and intentAddResult
Jon Hall63604932015-02-26 17:09:50 -0800310 and not missingIntents and installedCheck )
Jon Hall6aec96b2015-01-19 14:49:31 -0800311 utilities.assert_equals(
312 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -0800313 actual=intentAddResult,
Jon Hall529a37f2015-01-28 10:02:00 -0800314 onpass="Pushed host intents to ONOS",
315 onfail="Error in pushing host intents to ONOS" )
Jon Hall58c76b72015-02-23 11:09:24 -0800316
Jon Hall63604932015-02-26 17:09:50 -0800317 if not intentAddResult or "key" in pendingMap:
Jon Hall58c76b72015-02-23 11:09:24 -0800318 import time
Jon Hall63604932015-02-26 17:09:50 -0800319 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800320 main.log.info( "Sleeping 60 seconds to see if intents are found" )
321 time.sleep( 60 )
322 onosIds = main.ONOScli1.getAllIntentsId()
323 main.log.info( "Submitted intents: " + str( intentIds ) )
324 main.log.info( "Intents in ONOS: " + str( onosIds ) )
325 # Print the intent states
326 intents = main.ONOScli1.intents()
327 intentStates = []
328 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
329 count = 0
330 for intent in json.loads( intents ):
331 # Iter through intents of a node
332 state = intent.get( 'state', None )
Jon Hall63604932015-02-26 17:09:50 -0800333 if "INSTALLED" not in state:
334 installedCheck = False
Jon Hall58c76b72015-02-23 11:09:24 -0800335 intentId = intent.get( 'id', None )
336 intentStates.append( ( intentId, state ) )
337 # add submitted intents not in the store
338 tmplist = [ i for i, s in intentStates ]
339 for i in intentIds:
340 if i not in tmplist:
341 intentStates.append( ( i, " - " ) )
342 intentStates.sort()
343 for i, s in intentStates:
344 count += 1
345 main.log.info( "%-6s%-15s%-15s" %
346 ( str( count ), str( i ), str( s ) ) )
Jon Hall63604932015-02-26 17:09:50 -0800347 main.ONOScli1.leaders()
348 main.ONOScli1.pendingMap()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800349
Jon Hall6aec96b2015-01-19 14:49:31 -0800350 def CASE4( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800351 """
352 Ping across added host intents
353 """
Jon Hallfebb1c72015-03-05 13:30:09 -0800354 import json
Jon Hall73cf9cc2014-11-20 22:28:38 -0800355 description = " Ping across added host intents"
Jon Hall6aec96b2015-01-19 14:49:31 -0800356 main.log.report( description )
357 main.case( description )
Jon Hall8f89dda2015-01-22 16:03:33 -0800358 PingResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800359 for i in range( 8, 18 ):
Jon Hall58c76b72015-02-23 11:09:24 -0800360 ping = main.Mininet1.pingHost( src="h" + str( i ),
361 target="h" + str( i + 10 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800362 PingResult = PingResult and ping
Jon Hall6aec96b2015-01-19 14:49:31 -0800363 if ping == main.FALSE:
364 main.log.warn( "Ping failed between h" + str( i ) +
365 " and h" + str( i + 10 ) )
366 elif ping == main.TRUE:
367 main.log.info( "Ping test passed!" )
Jon Hall21270ac2015-02-16 17:59:55 -0800368 # Don't set PingResult or you'd override failures
Jon Hall8f89dda2015-01-22 16:03:33 -0800369 if PingResult == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800370 main.log.report(
371 "Intents have not been installed correctly, pings failed." )
Jon Hall58c76b72015-02-23 11:09:24 -0800372 # TODO: pretty print
Jon Hall529a37f2015-01-28 10:02:00 -0800373 main.log.warn( "ONSO1 intents: " )
374 main.log.warn( json.dumps( json.loads( main.ONOScli1.intents() ),
375 sort_keys=True,
376 indent=4,
377 separators=( ',', ': ' ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800378 if PingResult == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800379 main.log.report(
380 "Intents have been installed correctly and verified by pings" )
381 utilities.assert_equals(
382 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800383 actual=PingResult,
Jon Hall6aec96b2015-01-19 14:49:31 -0800384 onpass="Intents have been installed correctly and pings work",
385 onfail="Intents have not been installed correctly, pings failed." )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800386
Jon Hall63604932015-02-26 17:09:50 -0800387 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800388 if PingResult is not main.TRUE:
389 # Print the intent states
390 intents = main.ONOScli1.intents()
391 intentStates = []
392 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
393 count = 0
394 # Iter through intents of a node
395 for intent in json.loads( intents ):
396 state = intent.get( 'state', None )
Jon Hall63604932015-02-26 17:09:50 -0800397 if "INSTALLED" not in state:
398 installedCheck = False
Jon Hall58c76b72015-02-23 11:09:24 -0800399 intentId = intent.get( 'id', None )
400 intentStates.append( ( intentId, state ) )
401 intentStates.sort()
402 for i, s in intentStates:
403 count += 1
404 main.log.info( "%-6s%-15s%-15s" %
405 ( str( count ), str( i ), str( s ) ) )
Jon Hall63604932015-02-26 17:09:50 -0800406 main.ONOScli1.leaders()
407 main.ONOScli1.partitions()
408 if not installedCheck:
409 main.log.info( "Waiting 60 seconds to see if intent states change" )
410 time.sleep( 60 )
411 # Print the intent states
412 intents = main.ONOScli1.intents()
413 intentStates = []
414 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
415 count = 0
416 # Iter through intents of a node
417 for intent in json.loads( intents ):
418 state = intent.get( 'state', None )
419 if "INSTALLED" not in state:
420 installedCheck = False
421 intentId = intent.get( 'id', None )
422 intentStates.append( ( intentId, state ) )
423 intentStates.sort()
424 for i, s in intentStates:
425 count += 1
426 main.log.info( "%-6s%-15s%-15s" %
427 ( str( count ), str( i ), str( s ) ) )
428 main.ONOScli1.leaders()
429 main.ONOScli1.partitions()
430 main.ONOScli1.pendingMap()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800431
Jon Hall6aec96b2015-01-19 14:49:31 -0800432 def CASE5( self, main ):
433 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800434 Reading state of ONOS
Jon Hall6aec96b2015-01-19 14:49:31 -0800435 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800436 import json
Jon Hall6aec96b2015-01-19 14:49:31 -0800437 # assumes that sts is already in you PYTHONPATH
438 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -0800439
Jon Hall6aec96b2015-01-19 14:49:31 -0800440 main.log.report( "Setting up and gathering data for current state" )
441 main.case( "Setting up and gathering data for current state" )
442 # The general idea for this test case is to pull the state of
443 # ( intents,flows, topology,... ) from each ONOS node
444 # We can then compare them with eachother and also with past states
Jon Hall73cf9cc2014-11-20 22:28:38 -0800445
Jon Hall6aec96b2015-01-19 14:49:31 -0800446 main.step( "Get the Mastership of each switch from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800447 global mastershipState
448 mastershipState = []
Jon Hall94fd0472014-12-08 11:52:42 -0800449
Jon Hall6aec96b2015-01-19 14:49:31 -0800450 # Assert that each device has a master
Jon Hall8f89dda2015-01-22 16:03:33 -0800451 rolesNotNull = main.ONOScli1.rolesNotNull()
Jon Hall6aec96b2015-01-19 14:49:31 -0800452 utilities.assert_equals(
453 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800454 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -0800455 onpass="Each device has a master",
456 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -0800457
Jon Hall8f89dda2015-01-22 16:03:33 -0800458 ONOS1Mastership = main.ONOScli1.roles()
Jon Hall6aec96b2015-01-19 14:49:31 -0800459 # TODO: Make this a meaningful check
Jon Hall8f89dda2015-01-22 16:03:33 -0800460 if "Error" in ONOS1Mastership or not ONOS1Mastership:
Jon Hall6aec96b2015-01-19 14:49:31 -0800461 main.log.report( "Error in getting ONOS roles" )
462 main.log.warn(
463 "ONOS1 mastership response: " +
Jon Hall8f89dda2015-01-22 16:03:33 -0800464 repr( ONOS1Mastership ) )
465 consistentMastership = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800466 else:
Jon Hall8f89dda2015-01-22 16:03:33 -0800467 mastershipState = ONOS1Mastership
468 consistentMastership = main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800469
Jon Hall6aec96b2015-01-19 14:49:31 -0800470 main.step( "Get the intents from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800471 global intentState
472 intentState = []
473 ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
474 intentCheck = main.FALSE
475 if "Error" in ONOS1Intents or not ONOS1Intents:
Jon Hall6aec96b2015-01-19 14:49:31 -0800476 main.log.report( "Error in getting ONOS intents" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800477 main.log.warn( "ONOS1 intents response: " + repr( ONOS1Intents ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800478 else:
Jon Hall8f89dda2015-01-22 16:03:33 -0800479 intentCheck = main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800480
Jon Hall6aec96b2015-01-19 14:49:31 -0800481 main.step( "Get the flows from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800482 global flowState
483 flowState = []
Jon Hall8f89dda2015-01-22 16:03:33 -0800484 flowCheck = main.FALSE
Jon Hall58c76b72015-02-23 11:09:24 -0800485 ONOS1Flows = main.ONOScli1.flows( jsonFormat=True )
Jon Hall8f89dda2015-01-22 16:03:33 -0800486 if "Error" in ONOS1Flows or not ONOS1Flows:
Jon Hall58c76b72015-02-23 11:09:24 -0800487 main.log.report( "Error in getting ONOS flows" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800488 main.log.warn( "ONOS1 flows repsponse: " + ONOS1Flows )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800489 else:
Jon Hall6aec96b2015-01-19 14:49:31 -0800490 # TODO: Do a better check, maybe compare flows on switches?
Jon Hall8f89dda2015-01-22 16:03:33 -0800491 flowState = ONOS1Flows
492 flowCheck = main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800493
Jon Hall6aec96b2015-01-19 14:49:31 -0800494 main.step( "Get the OF Table entries" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800495 global flows
Jon Hall6aec96b2015-01-19 14:49:31 -0800496 flows = []
497 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800498 flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
Jon Hall58c76b72015-02-23 11:09:24 -0800499 if flowCheck == main.FALSE:
500 for table in flows:
501 main.log.warn( table )
Jon Hall6aec96b2015-01-19 14:49:31 -0800502 # TODO: Compare switch flow tables with ONOS flow tables
Jon Hall73cf9cc2014-11-20 22:28:38 -0800503
Jon Hall6aec96b2015-01-19 14:49:31 -0800504 main.step( "Create TestONTopology object" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800505 ctrls = []
506 count = 1
507 temp = ()
Jon Hall6aec96b2015-01-19 14:49:31 -0800508 temp = temp + ( getattr( main, ( 'ONOS' + str( count ) ) ), )
509 temp = temp + ( "ONOS" + str( count ), )
510 temp = temp + ( main.params[ 'CTRL' ][ 'ip' + str( count ) ], )
511 temp = temp + \
512 ( eval( main.params[ 'CTRL' ][ 'port' + str( count ) ] ), )
513 ctrls.append( temp )
514 MNTopo = TestONTopology(
515 main.Mininet1,
516 ctrls ) # can also add Intent API info for intent operations
Jon Hall73cf9cc2014-11-20 22:28:38 -0800517
Jon Hall6aec96b2015-01-19 14:49:31 -0800518 main.step( "Collecting topology information from ONOS" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800519 devices = []
520 devices.append( main.ONOScli1.devices() )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800521 hosts = []
Jon Hall58c76b72015-02-23 11:09:24 -0800522 hosts.append( json.loads( main.ONOScli1.hosts() ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800523 ports = []
524 ports.append( main.ONOScli1.ports() )
525 links = []
526 links.append( main.ONOScli1.links() )
Jon Hall58c76b72015-02-23 11:09:24 -0800527 clusters = []
528 clusters.append( main.ONOScli1.clusters() )
529 ipResult = main.TRUE
530 for controller in range( 0, len( hosts ) ):
531 controllerStr = str( controller + 1 )
532 for host in hosts[ controller ]:
533 if host is None or host.get( 'ips', [] ) == []:
534 main.log.error(
535 "DEBUG:Error with host ips on controller" +
536 controllerStr + ": " + str( host ) )
537 ipResult = main.FALSE
538
539 # there should always only be one cluster
540 numClusters = len( json.loads( clusters[ 0 ] ) )
541 clusterResults = main.FALSE
542 if numClusters == 1:
543 clusterResults = main.TRUE
544 utilities.assert_equals(
545 expect=1,
546 actual=numClusters,
547 onpass="ONOS shows 1 SCC",
548 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800549
Jon Hall6aec96b2015-01-19 14:49:31 -0800550 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800551 devicesResults = main.TRUE
552 portsResults = main.TRUE
553 linksResults = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -0800554 hostsResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -0800555 for controller in range( numControllers ):
556 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -0800557 if devices[ controller ] or "Error" not in devices[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -0800558 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -0800559 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -0800560 json.loads( devices[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800561 else:
Jon Hall8f89dda2015-01-22 16:03:33 -0800562 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800563 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -0800564 actual=currentDevicesResult,
565 onpass="ONOS" + controllerStr +
566 " Switches view is correct",
567 onfail="ONOS" + controllerStr +
568 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800569
Jon Hall6aec96b2015-01-19 14:49:31 -0800570 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -0800571 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -0800572 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -0800573 json.loads( ports[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800574 else:
Jon Hall8f89dda2015-01-22 16:03:33 -0800575 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800576 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -0800577 actual=currentPortsResult,
578 onpass="ONOS" + controllerStr +
579 " ports view is correct",
580 onfail="ONOS" + controllerStr +
581 " ports view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800582
Jon Hall6aec96b2015-01-19 14:49:31 -0800583 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -0800584 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -0800585 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -0800586 json.loads( links[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800587 else:
Jon Hall8f89dda2015-01-22 16:03:33 -0800588 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800589 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -0800590 actual=currentLinksResult,
591 onpass="ONOS" + controllerStr +
592 " links view is correct",
593 onfail="ONOS" + controllerStr +
594 " links view is incorrect" )
595
596 if hosts[ controller ] or "Error" not in hosts[ controller ]:
597 currentHostsResult = main.Mininet1.compareHosts(
598 MNTopo, hosts[ controller ] )
599 else:
600 currentHostsResult = main.FALSE
601 utilities.assert_equals( expect=main.TRUE,
602 actual=currentHostsResult,
603 onpass="ONOS" + controllerStr +
604 " hosts exist in Mininet",
605 onfail="ONOS" + controllerStr +
606 " hosts don't match Mininet" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800607
Jon Hall8f89dda2015-01-22 16:03:33 -0800608 devicesResults = devicesResults and currentDevicesResult
609 portsResults = portsResults and currentPortsResult
610 linksResults = linksResults and currentLinksResult
Jon Hall58c76b72015-02-23 11:09:24 -0800611 hostsResults = hostsResults and currentHostsResult
Jon Hall73cf9cc2014-11-20 22:28:38 -0800612
Jon Hall58c76b72015-02-23 11:09:24 -0800613 topoResult = devicesResults and portsResults and linksResults\
614 and clusterResults and ipResult and hostsResults
Jon Hall8f89dda2015-01-22 16:03:33 -0800615 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -0800616 onpass="Topology Check Test successful",
617 onfail="Topology Check Test NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800618
Jon Hall8f89dda2015-01-22 16:03:33 -0800619 finalAssert = main.TRUE
620 finalAssert = finalAssert and topoResult and flowCheck \
Jon Hall58c76b72015-02-23 11:09:24 -0800621 and intentCheck and consistentMastership and rolesNotNull
Jon Hall8f89dda2015-01-22 16:03:33 -0800622 utilities.assert_equals( expect=main.TRUE, actual=finalAssert,
Jon Hall58c76b72015-02-23 11:09:24 -0800623 onpass="State check successful",
624 onfail="State check NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800625
Jon Hall6aec96b2015-01-19 14:49:31 -0800626 def CASE6( self, main ):
627 """
Jon Hallffb386d2014-11-21 13:43:38 -0800628 The Failure case.
Jon Hall6aec96b2015-01-19 14:49:31 -0800629 """
Jon Hallffb386d2014-11-21 13:43:38 -0800630 import time
Jon Hall73cf9cc2014-11-20 22:28:38 -0800631
Jon Hall6aec96b2015-01-19 14:49:31 -0800632 main.log.report( "Restart ONOS node" )
633 main.log.case( "Restart ONOS node" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800634 main.ONOSbench.onosKill( ONOS1Ip )
Jon Hallffb386d2014-11-21 13:43:38 -0800635 start = time.time()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800636
Jon Hall6aec96b2015-01-19 14:49:31 -0800637 main.step( "Checking if ONOS is up yet" )
Jon Hallffb386d2014-11-21 13:43:38 -0800638 count = 0
Jon Hall94fd0472014-12-08 11:52:42 -0800639 while count < 10:
Jon Hall8f89dda2015-01-22 16:03:33 -0800640 onos1Isup = main.ONOSbench.isup( ONOS1Ip )
641 if onos1Isup == main.TRUE:
Jon Hallffb386d2014-11-21 13:43:38 -0800642 elapsed = time.time() - start
643 break
644 else:
645 count = count + 1
Jon Hall73cf9cc2014-11-20 22:28:38 -0800646
Jon Hall8f89dda2015-01-22 16:03:33 -0800647 cliResult = main.ONOScli1.startOnosCli( ONOS1Ip )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800648
Jon Hall8f89dda2015-01-22 16:03:33 -0800649 caseResults = main.TRUE and onos1Isup and cliResult
650 utilities.assert_equals( expect=main.TRUE, actual=caseResults,
Jon Hall58c76b72015-02-23 11:09:24 -0800651 onpass="ONOS restart successful",
652 onfail="ONOS restart NOT successful" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800653 if elapsed:
654 main.log.info( "ESTIMATE: ONOS took %s seconds to restart" %
655 str( elapsed ) )
Jon Hall6aec96b2015-01-19 14:49:31 -0800656 time.sleep( 5 )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800657
Jon Hall6aec96b2015-01-19 14:49:31 -0800658 def CASE7( self, main ):
659 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800660 Check state after ONOS failure
Jon Hall6aec96b2015-01-19 14:49:31 -0800661 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800662 import json
Jon Hall6aec96b2015-01-19 14:49:31 -0800663 main.case( "Running ONOS Constant State Tests" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800664
Jon Hall6aec96b2015-01-19 14:49:31 -0800665 # Assert that each device has a master
Jon Hall8f89dda2015-01-22 16:03:33 -0800666 rolesNotNull = main.ONOScli1.rolesNotNull()
Jon Hall6aec96b2015-01-19 14:49:31 -0800667 utilities.assert_equals(
668 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800669 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -0800670 onpass="Each device has a master",
671 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -0800672
Jon Hall6aec96b2015-01-19 14:49:31 -0800673 main.step( "Check if switch roles are consistent across all nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800674 ONOS1Mastership = main.ONOScli1.roles()
Jon Hall6aec96b2015-01-19 14:49:31 -0800675 # FIXME: Refactor this whole case for single instance
Jon Hall8f89dda2015-01-22 16:03:33 -0800676 if "Error" in ONOS1Mastership or not ONOS1Mastership:
Jon Hall6aec96b2015-01-19 14:49:31 -0800677 main.log.report( "Error in getting ONOS mastership" )
Jon Hall58c76b72015-02-23 11:09:24 -0800678 main.log.warn( "ONOS1 mastership response: " +
679 repr( ONOS1Mastership ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800680 consistentMastership = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800681 else:
Jon Hall8f89dda2015-01-22 16:03:33 -0800682 consistentMastership = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800683 main.log.report(
684 "Switch roles are consistent across all ONOS nodes" )
685 utilities.assert_equals(
686 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800687 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -0800688 onpass="Switch roles are consistent across all ONOS nodes",
689 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800690
691 description2 = "Compare switch roles from before failure"
Jon Hall6aec96b2015-01-19 14:49:31 -0800692 main.step( description2 )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800693
Jon Hall8f89dda2015-01-22 16:03:33 -0800694 currentJson = json.loads( ONOS1Mastership )
695 oldJson = json.loads( mastershipState )
696 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800697 for i in range( 1, 29 ):
698 switchDPID = str(
Jon Hall58c76b72015-02-23 11:09:24 -0800699 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800700
Jon Hall8f89dda2015-01-22 16:03:33 -0800701 current = [ switch[ 'master' ] for switch in currentJson
Jon Hall6aec96b2015-01-19 14:49:31 -0800702 if switchDPID in switch[ 'id' ] ]
Jon Hall8f89dda2015-01-22 16:03:33 -0800703 old = [ switch[ 'master' ] for switch in oldJson
Jon Hall6aec96b2015-01-19 14:49:31 -0800704 if switchDPID in switch[ 'id' ] ]
Jon Hall73cf9cc2014-11-20 22:28:38 -0800705 if current == old:
Jon Hall8f89dda2015-01-22 16:03:33 -0800706 mastershipCheck = mastershipCheck and main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800707 else:
Jon Hall6aec96b2015-01-19 14:49:31 -0800708 main.log.warn( "Mastership of switch %s changed" % switchDPID )
Jon Hall8f89dda2015-01-22 16:03:33 -0800709 mastershipCheck = main.FALSE
710 if mastershipCheck == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800711 main.log.report( "Mastership of Switches was not changed" )
712 utilities.assert_equals(
713 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800714 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800715 onpass="Mastership of Switches was not changed",
716 onfail="Mastership of some switches changed" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800717 mastershipCheck = mastershipCheck and consistentMastership
Jon Hall73cf9cc2014-11-20 22:28:38 -0800718
Jon Hall6aec96b2015-01-19 14:49:31 -0800719 main.step( "Get the intents and compare across all nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800720 ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
721 intentCheck = main.FALSE
722 if "Error" in ONOS1Intents or not ONOS1Intents:
Jon Hall6aec96b2015-01-19 14:49:31 -0800723 main.log.report( "Error in getting ONOS intents" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800724 main.log.warn( "ONOS1 intents response: " + repr( ONOS1Intents ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800725 else:
Jon Hall8f89dda2015-01-22 16:03:33 -0800726 intentCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800727 main.log.report( "Intents are consistent across all ONOS nodes" )
728 utilities.assert_equals(
729 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800730 actual=intentCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800731 onpass="Intents are consistent across all ONOS nodes",
732 onfail="ONOS nodes have different views of intents" )
Jon Hall1b8f54a2015-02-04 13:24:20 -0800733 # Print the intent states
734 intents = []
735 intents.append( ONOS1Intents )
736 intentStates = []
737 for node in intents: # Iter through ONOS nodes
738 nodeStates = []
Jon Hall58c76b72015-02-23 11:09:24 -0800739 # Iter through intents of a node
740 for intent in json.loads( node ):
Jon Hall1b8f54a2015-02-04 13:24:20 -0800741 nodeStates.append( intent[ 'state' ] )
742 intentStates.append( nodeStates )
743 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
744 main.log.info( dict( out ) )
745
Jon Hall58c76b72015-02-23 11:09:24 -0800746 # NOTE: Store has no durability, so intents are lost across system
747 # restarts
Jon Hall6aec96b2015-01-19 14:49:31 -0800748 """
749 main.step( "Compare current intents with intents before the failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800750 # NOTE: this requires case 5 to pass for intentState to be set.
Jon Hall6aec96b2015-01-19 14:49:31 -0800751 # maybe we should stop the test if that fails?
Jon Hall1b8f54a2015-02-04 13:24:20 -0800752 sameIntents = main.TRUE
753 if intentState and intentState == ONOS1Intents:
Jon Hall8f89dda2015-01-22 16:03:33 -0800754 sameIntents = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800755 main.log.report( "Intents are consistent with before failure" )
756 # TODO: possibly the states have changed? we may need to figure out
757 # what the aceptable states are
Jon Hall73cf9cc2014-11-20 22:28:38 -0800758 else:
Jon Hall6aec96b2015-01-19 14:49:31 -0800759 try:
760 main.log.warn( "ONOS1 intents: " )
Jon Hall8f89dda2015-01-22 16:03:33 -0800761 print json.dumps( json.loads( ONOS1Intents ),
Jon Hall6aec96b2015-01-19 14:49:31 -0800762 sort_keys=True, indent=4,
763 separators=( ',', ': ' ) )
Jon Hallfebb1c72015-03-05 13:30:09 -0800764 except Exception:
Jon Hall6aec96b2015-01-19 14:49:31 -0800765 pass
Jon Hall8f89dda2015-01-22 16:03:33 -0800766 sameIntents = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800767 utilities.assert_equals(
768 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800769 actual=sameIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -0800770 onpass="Intents are consistent with before failure",
771 onfail="The Intents changed during failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800772 intentCheck = intentCheck and sameIntents
Jon Hall6aec96b2015-01-19 14:49:31 -0800773 """
774 main.step( "Get the OF Table entries and compare to before " +
775 "component failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800776 FlowTables = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800777 flows2 = []
778 for i in range( 28 ):
779 main.log.info( "Checking flow table on s" + str( i + 1 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800780 tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
781 flows2.append( tmpFlows )
782 tempResult = main.Mininet2.flowComp(
Jon Hall6aec96b2015-01-19 14:49:31 -0800783 flow1=flows[ i ],
Jon Hall8f89dda2015-01-22 16:03:33 -0800784 flow2=tmpFlows )
785 FlowTables = FlowTables and tempResult
786 if FlowTables == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800787 main.log.info( "Differences in flow table for switch: s" +
788 str( i + 1 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800789 if FlowTables == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800790 main.log.report( "No changes were found in the flow tables" )
791 utilities.assert_equals(
792 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800793 actual=FlowTables,
Jon Hall6aec96b2015-01-19 14:49:31 -0800794 onpass="No changes were found in the flow tables",
795 onfail="Changes were found in the flow tables" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800796
Jon Hall6aec96b2015-01-19 14:49:31 -0800797 # Test of LeadershipElection
Jon Hall669173b2014-12-17 11:36:30 -0800798
Jon Hall8f89dda2015-01-22 16:03:33 -0800799 leader = ONOS1Ip
800 leaderResult = main.TRUE
801 for controller in range( 1, numControllers + 1 ):
Jon Hall6aec96b2015-01-19 14:49:31 -0800802 # loop through ONOScli handlers
803 node = getattr( main, ( 'ONOScli' + str( controller ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800804 leaderN = node.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -0800805 # verify leader is ONOS1
806 # NOTE even though we restarted ONOS, it is the only one so onos 1
807 # must be leader
Jon Hall669173b2014-12-17 11:36:30 -0800808 if leaderN == leader:
Jon Hall6aec96b2015-01-19 14:49:31 -0800809 # all is well
Jon Hall669173b2014-12-17 11:36:30 -0800810 pass
811 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800812 # error in response
813 main.log.report( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -0800814 "electionTestLeader function, check the" +
Jon Hall6aec96b2015-01-19 14:49:31 -0800815 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800816 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -0800817 elif leader != leaderN:
Jon Hall8f89dda2015-01-22 16:03:33 -0800818 leaderResult = main.FALSE
Jon Hall58c76b72015-02-23 11:09:24 -0800819 main.log.report( "ONOS" + str( controller ) + " sees " +
820 str( leaderN ) +
821 " as the leader of the election app. " +
822 "Leader should be " + str( leader ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800823 if leaderResult:
824 main.log.report( "Leadership election tests passed( consistent " +
Jon Hall6aec96b2015-01-19 14:49:31 -0800825 "view of leader across listeners and a new " +
Jon Hall8f89dda2015-01-22 16:03:33 -0800826 "leader was re-elected if applicable )" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800827 utilities.assert_equals(
828 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800829 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -0800830 onpass="Leadership election passed",
831 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -0800832
Jon Hall8f89dda2015-01-22 16:03:33 -0800833 result = ( mastershipCheck and intentCheck and FlowTables and
834 rolesNotNull and leaderResult )
Jon Hall6aec96b2015-01-19 14:49:31 -0800835 result = int( result )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800836 if result == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800837 main.log.report( "Constant State Tests Passed" )
838 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall58c76b72015-02-23 11:09:24 -0800839 onpass="Constant State Tests Passed",
840 onfail="Constant state tests failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800841
Jon Hall6aec96b2015-01-19 14:49:31 -0800842 def CASE8( self, main ):
843 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800844 Compare topo
Jon Hall6aec96b2015-01-19 14:49:31 -0800845 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800846 import sys
Jon Hall6aec96b2015-01-19 14:49:31 -0800847 # FIXME add this path to params
848 sys.path.append( "/home/admin/sts" )
849 # assumes that sts is already in you PYTHONPATH
850 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -0800851 import json
852 import time
853
Jon Hall6aec96b2015-01-19 14:49:31 -0800854 description = "Compare ONOS Topology view to Mininet topology"
855 main.case( description )
856 main.log.report( description )
857 main.step( "Create TestONTopology object" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800858 ctrls = []
859 count = 1
860 temp = ()
Jon Hall6aec96b2015-01-19 14:49:31 -0800861 temp = temp + ( getattr( main, ( 'ONOS' + str( count ) ) ), )
862 temp = temp + ( "ONOS" + str( count ), )
863 temp = temp + ( main.params[ 'CTRL' ][ 'ip' + str( count ) ], )
864 temp = temp + \
865 ( eval( main.params[ 'CTRL' ][ 'port' + str( count ) ] ), )
866 ctrls.append( temp )
867 MNTopo = TestONTopology(
868 main.Mininet1,
869 ctrls ) # can also add Intent API info for intent operations
Jon Hall73cf9cc2014-11-20 22:28:38 -0800870
Jon Hall6aec96b2015-01-19 14:49:31 -0800871 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800872 devicesResults = main.TRUE
873 portsResults = main.TRUE
874 linksResults = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -0800875 hostsResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -0800876 topoResult = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800877 elapsed = 0
Jon Hallffb386d2014-11-21 13:43:38 -0800878 count = 0
Jon Hall6aec96b2015-01-19 14:49:31 -0800879 main.step( "Collecting topology information from ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800880 startTime = time.time()
Jon Hall58c76b72015-02-23 11:09:24 -0800881 # Give time for Gossip to work
Jon Hall8f89dda2015-01-22 16:03:33 -0800882 while topoResult == main.FALSE and elapsed < 60:
Jon Hallffb386d2014-11-21 13:43:38 -0800883 count = count + 1
Jon Hall94fd0472014-12-08 11:52:42 -0800884 if count > 1:
Jon Hall58c76b72015-02-23 11:09:24 -0800885 # TODO: Depricate STS usage
886 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall8f89dda2015-01-22 16:03:33 -0800887 cliStart = time.time()
Jon Hall94fd0472014-12-08 11:52:42 -0800888 devices = []
889 devices.append( main.ONOScli1.devices() )
Jon Hall94fd0472014-12-08 11:52:42 -0800890 hosts = []
Jon Hall58c76b72015-02-23 11:09:24 -0800891 hosts.append( json.loads( main.ONOScli1.hosts() ) )
892 ipResult = main.TRUE
893 for controller in range( 0, len( hosts ) ):
894 controllerStr = str( controller + 1 )
895 for host in hosts[ controller ]:
896 if host is None or host.get( 'ips', [] ) == []:
897 main.log.error(
898 "DEBUG:Error with host ips on controller" +
899 controllerStr + ": " + str( host ) )
900 ipResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -0800901 ports = []
902 ports.append( main.ONOScli1.ports() )
903 links = []
904 links.append( main.ONOScli1.links() )
Jon Hall58c76b72015-02-23 11:09:24 -0800905 clusters = []
906 clusters.append( main.ONOScli1.clusters() )
907
Jon Hall8f89dda2015-01-22 16:03:33 -0800908 elapsed = time.time() - startTime
909 cliTime = time.time() - cliStart
910 print "CLI time: " + str( cliTime )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800911
Jon Hall8f89dda2015-01-22 16:03:33 -0800912 for controller in range( numControllers ):
913 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -0800914 if devices[ controller ] or "Error" not in devices[
915 controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -0800916 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -0800917 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -0800918 json.loads( devices[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800919 else:
Jon Hall8f89dda2015-01-22 16:03:33 -0800920 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800921 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -0800922 actual=currentDevicesResult,
923 onpass="ONOS" + controllerStr +
924 " Switches view is correct",
925 onfail="ONOS" + controllerStr +
926 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800927
Jon Hall6aec96b2015-01-19 14:49:31 -0800928 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -0800929 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -0800930 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -0800931 json.loads( ports[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800932 else:
Jon Hall8f89dda2015-01-22 16:03:33 -0800933 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800934 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -0800935 actual=currentPortsResult,
936 onpass="ONOS" + controllerStr +
937 " ports view is correct",
938 onfail="ONOS" + controllerStr +
939 " ports view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800940
Jon Hall6aec96b2015-01-19 14:49:31 -0800941 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -0800942 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -0800943 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -0800944 json.loads( links[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800945 else:
Jon Hall8f89dda2015-01-22 16:03:33 -0800946 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800947 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -0800948 actual=currentLinksResult,
949 onpass="ONOS" + controllerStr +
950 " links view is correct",
951 onfail="ONOS" + controllerStr +
952 " links view is incorrect" )
953
954 if hosts[ controller ] or "Error" not in hosts[ controller ]:
955 currentHostsResult = main.Mininet1.compareHosts(
956 MNTopo, hosts[ controller ] )
957 else:
958 currentHostsResult = main.FALSE
959 utilities.assert_equals( expect=main.TRUE,
960 actual=currentHostsResult,
961 onpass="ONOS" + controllerStr +
962 " hosts exist in Mininet",
963 onfail="ONOS" + controllerStr +
964 " hosts don't match Mininet" )
965
966 devicesResults = devicesResults and currentDevicesResult
967 portsResults = portsResults and currentPortsResult
968 linksResults = linksResults and currentLinksResult
969 hostsResults = hostsResults and currentHostsResult
970
Jon Hall63604932015-02-26 17:09:50 -0800971 # "consistent" results don't make sense for single instance
Jon Hall58c76b72015-02-23 11:09:24 -0800972 # there should always only be one cluster
973 numClusters = len( json.loads( clusters[ 0 ] ) )
974 clusterResults = main.FALSE
975 if numClusters == 1:
976 clusterResults = main.TRUE
977 utilities.assert_equals(
978 expect=1,
979 actual=numClusters,
980 onpass="ONOS shows 1 SCC",
981 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
982
983 topoResult = ( devicesResults and portsResults and linksResults
984 and hostsResults and ipResult and clusterResults )
Jon Hall94fd0472014-12-08 11:52:42 -0800985
Jon Hall8f89dda2015-01-22 16:03:33 -0800986 topoResult = topoResult and int( count <= 2 )
987 note = "note it takes about " + str( int( cliTime ) ) + \
988 " seconds for the test to make all the cli calls to fetch " +\
989 "the topology from each ONOS instance"
Jon Hall1b8f54a2015-02-04 13:24:20 -0800990 main.log.info(
Jon Hall8f89dda2015-01-22 16:03:33 -0800991 "Very crass estimate for topology discovery/convergence( " +
992 str( note ) + " ): " + str( elapsed ) + " seconds, " +
Jon Hall6aec96b2015-01-19 14:49:31 -0800993 str( count ) + " tries" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800994 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -0800995 onpass="Topology Check Test successful",
996 onfail="Topology Check Test NOT successful" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800997 if topoResult == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800998 main.log.report( "ONOS topology view matches Mininet topology" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800999
Jon Hall6aec96b2015-01-19 14:49:31 -08001000 def CASE9( self, main ):
1001 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001002 Link s3-s28 down
Jon Hall6aec96b2015-01-19 14:49:31 -08001003 """
1004 import time
1005 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08001006
Jon Hall8f89dda2015-01-22 16:03:33 -08001007 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001008
Jon Hall6aec96b2015-01-19 14:49:31 -08001009 description = "Turn off a link to ensure that Link Discovery " +\
Jon Hall58c76b72015-02-23 11:09:24 -08001010 "is working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08001011 main.log.report( description )
1012 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001013
Jon Hall6aec96b2015-01-19 14:49:31 -08001014 main.step( "Kill Link between s3 and s28" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001015 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
Jon Hall58c76b72015-02-23 11:09:24 -08001016 main.log.info( "Waiting " + str( linkSleep ) +
1017 " seconds for link down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001018 time.sleep( linkSleep )
1019 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
Jon Hall58c76b72015-02-23 11:09:24 -08001020 onpass="Link down succesful",
1021 onfail="Failed to bring link down" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001022 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08001023
Jon Hall6aec96b2015-01-19 14:49:31 -08001024 def CASE10( self, main ):
1025 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001026 Link s3-s28 up
Jon Hall6aec96b2015-01-19 14:49:31 -08001027 """
1028 import time
1029 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08001030
Jon Hall8f89dda2015-01-22 16:03:33 -08001031 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001032
Jon Hall6aec96b2015-01-19 14:49:31 -08001033 description = "Restore a link to ensure that Link Discovery is " + \
Jon Hall58c76b72015-02-23 11:09:24 -08001034 "working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08001035 main.log.report( description )
1036 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001037
Jon Hall6aec96b2015-01-19 14:49:31 -08001038 main.step( "Bring link between s3 and s28 back up" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001039 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
Jon Hall58c76b72015-02-23 11:09:24 -08001040 main.log.info( "Waiting " + str( linkSleep ) +
1041 " seconds for link up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001042 time.sleep( linkSleep )
1043 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
Jon Hall58c76b72015-02-23 11:09:24 -08001044 onpass="Link up succesful",
1045 onfail="Failed to bring link up" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001046 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08001047
Jon Hall6aec96b2015-01-19 14:49:31 -08001048 def CASE11( self, main ):
1049 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001050 Switch Down
Jon Hall6aec96b2015-01-19 14:49:31 -08001051 """
1052 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08001053 import time
1054
Jon Hall8f89dda2015-01-22 16:03:33 -08001055 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001056
1057 description = "Killing a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08001058 main.log.report( description )
1059 main.case( description )
1060 switch = main.params[ 'kill' ][ 'switch' ]
1061 switchDPID = main.params[ 'kill' ][ 'dpid' ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08001062
Jon Hall6aec96b2015-01-19 14:49:31 -08001063 # TODO: Make this switch parameterizable
1064 main.step( "Kill " + switch )
1065 main.log.report( "Deleting " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08001066 main.Mininet1.delSwitch( switch )
1067 main.log.info( "Waiting " + str( switchSleep ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08001068 " seconds for switch down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001069 time.sleep( switchSleep )
1070 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08001071 # Peek at the deleted switch
1072 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001073 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001074 if device and device[ 'available' ] is False:
Jon Hall94fd0472014-12-08 11:52:42 -08001075 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001076 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall58c76b72015-02-23 11:09:24 -08001077 onpass="Kill switch succesful",
1078 onfail="Failed to kill switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001079
Jon Hall6aec96b2015-01-19 14:49:31 -08001080 def CASE12( self, main ):
1081 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001082 Switch Up
Jon Hall6aec96b2015-01-19 14:49:31 -08001083 """
1084 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08001085 import time
Jon Hall669173b2014-12-17 11:36:30 -08001086
Jon Hall8f89dda2015-01-22 16:03:33 -08001087 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall6aec96b2015-01-19 14:49:31 -08001088 switch = main.params[ 'kill' ][ 'switch' ]
1089 switchDPID = main.params[ 'kill' ][ 'dpid' ]
1090 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hall73cf9cc2014-11-20 22:28:38 -08001091 description = "Adding a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08001092 main.log.report( description )
1093 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001094
Jon Hall6aec96b2015-01-19 14:49:31 -08001095 main.step( "Add back " + switch )
1096 main.log.report( "Adding back " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08001097 main.Mininet1.addSwitch( switch, dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08001098 # TODO: New dpid or same? Ask Thomas?
1099 for peer in links:
Jon Hall8f89dda2015-01-22 16:03:33 -08001100 main.Mininet1.addLink( switch, peer )
1101 main.Mininet1.assignSwController( sw=switch.split( 's' )[ 1 ],
Jon Hall58c76b72015-02-23 11:09:24 -08001102 ip1=ONOS1Ip,
1103 port1=ONOS1Port )
1104 main.log.info( "Waiting " + str( switchSleep ) +
1105 " seconds for switch up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001106 time.sleep( switchSleep )
1107 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08001108 # Peek at the deleted switch
1109 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001110 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001111 if device and device[ 'available' ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001112 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001113 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall58c76b72015-02-23 11:09:24 -08001114 onpass="add switch succesful",
1115 onfail="Failed to add switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001116
Jon Hall6aec96b2015-01-19 14:49:31 -08001117 def CASE13( self, main ):
1118 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001119 Clean up
Jon Hall6aec96b2015-01-19 14:49:31 -08001120 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001121 import os
1122 import time
Jon Hall6aec96b2015-01-19 14:49:31 -08001123 # printing colors to terminal
Jon Hall669173b2014-12-17 11:36:30 -08001124 colors = {}
Jon Hall6aec96b2015-01-19 14:49:31 -08001125 colors[ 'cyan' ] = '\033[96m'
1126 colors[ 'purple' ] = '\033[95m'
1127 colors[ 'blue' ] = '\033[94m'
1128 colors[ 'green' ] = '\033[92m'
1129 colors[ 'yellow' ] = '\033[93m'
1130 colors[ 'red' ] = '\033[91m'
1131 colors[ 'end' ] = '\033[0m'
Jon Hall73cf9cc2014-11-20 22:28:38 -08001132 description = "Test Cleanup"
Jon Hall6aec96b2015-01-19 14:49:31 -08001133 main.log.report( description )
1134 main.case( description )
1135 main.step( "Killing tcpdumps" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001136 main.Mininet2.stopTcpdump()
Jon Hall73cf9cc2014-11-20 22:28:38 -08001137
Jon Hall6aec96b2015-01-19 14:49:31 -08001138 main.step( "Checking ONOS Logs for errors" )
1139 print colors[ 'purple' ] + "Checking logs for errors on ONOS1:" + \
Jon Hall8f89dda2015-01-22 16:03:33 -08001140 colors[ 'end' ]
1141 print main.ONOSbench.checkLogs( ONOS1Ip )
Jon Hall6aec96b2015-01-19 14:49:31 -08001142 main.step( "Copying MN pcap and ONOS log files to test station" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001143 testname = main.TEST
Jon Hall8f89dda2015-01-22 16:03:33 -08001144 teststationUser = main.params[ 'TESTONUSER' ]
1145 teststationIP = main.params[ 'TESTONIP' ]
Jon Hall6aec96b2015-01-19 14:49:31 -08001146 # NOTE: MN Pcap file is being saved to ~/packet_captures
Jon Hall73cf9cc2014-11-20 22:28:38 -08001147 # scp this file as MN and TestON aren't necessarily the same vm
Jon Hall6aec96b2015-01-19 14:49:31 -08001148 # FIXME: scp
1149 # mn files
1150 # TODO: Load these from params
1151 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08001152 logFolder = "/opt/onos/log/"
1153 logFiles = [ "karaf.log", "karaf.log.1" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08001154 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08001155 dstDir = "~/packet_captures/"
1156 for f in logFiles:
1157 main.ONOSbench.handle.sendline( "scp sdn@" + ONOS1Ip + ":" +
1158 logFolder + f + " " +
1159 teststationUser + "@" +
1160 teststationIP + ":" + dstDir +
Jon Hall6aec96b2015-01-19 14:49:31 -08001161 str( testname ) + "-ONOS1-" + f )
1162 main.ONOSbench.handle.expect( "\$" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001163
Jon Hall6aec96b2015-01-19 14:49:31 -08001164 # std*.log's
1165 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08001166 logFolder = "/opt/onos/var/"
1167 logFiles = [ "stderr.log", "stdout.log" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08001168 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08001169 dstDir = "~/packet_captures/"
1170 for f in logFiles:
1171 main.ONOSbench.handle.sendline( "scp sdn@" + ONOS1Ip + ":" +
1172 logFolder + f + " " +
1173 teststationUser + "@" +
1174 teststationIP + ":" + dstDir +
Jon Hall6aec96b2015-01-19 14:49:31 -08001175 str( testname ) + "-ONOS1-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08001176 main.ONOSbench.handle.expect( "\$" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001177 # sleep so scp can finish
1178 time.sleep( 10 )
Jon Hall58c76b72015-02-23 11:09:24 -08001179 main.Mininet1.stopNet()
Jon Hall6aec96b2015-01-19 14:49:31 -08001180 main.step( "Packing and rotating pcap archives" )
1181 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001182
Jon Hall6aec96b2015-01-19 14:49:31 -08001183 # TODO: actually check something here
1184 utilities.assert_equals( expect=main.TRUE, actual=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001185 onpass="Test cleanup successful",
1186 onfail="Test cleanup NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001187
Jon Hall6aec96b2015-01-19 14:49:31 -08001188 def CASE14( self, main ):
1189 """
Jon Hall669173b2014-12-17 11:36:30 -08001190 start election app on all onos nodes
Jon Hall6aec96b2015-01-19 14:49:31 -08001191 """
Jon Hall8f89dda2015-01-22 16:03:33 -08001192 leaderResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001193 # install app on onos 1
1194 main.log.info( "Install leadership election app" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001195 main.ONOScli1.featureInstall( "onos-app-election" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001196 # wait for election
1197 # check for leader
Jon Hall8f89dda2015-01-22 16:03:33 -08001198 leader = main.ONOScli1.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08001199 # verify leader is ONOS1
Jon Hall8f89dda2015-01-22 16:03:33 -08001200 if leader == ONOS1Ip:
Jon Hall6aec96b2015-01-19 14:49:31 -08001201 # all is well
Jon Hall669173b2014-12-17 11:36:30 -08001202 pass
Jon Hall6aec96b2015-01-19 14:49:31 -08001203 elif leader is None:
1204 # No leader elected
1205 main.log.report( "No leader was elected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001206 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08001207 elif leader == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001208 # error in response
1209 # TODO: add check for "Command not found:" in the driver, this
1210 # means the app isn't loaded
Jon Hall8f89dda2015-01-22 16:03:33 -08001211 main.log.report( "Something is wrong with electionTestLeader" +
Jon Hall6aec96b2015-01-19 14:49:31 -08001212 " function, check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001213 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08001214 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001215 # error in response
1216 main.log.report(
Jon Hall8f89dda2015-01-22 16:03:33 -08001217 "Unexpected response from electionTestLeader function:'" +
1218 str( leader ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08001219 "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001220 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08001221
Jon Hall6aec96b2015-01-19 14:49:31 -08001222 # install on other nodes and check for leader.
1223 # Should be onos1 and each app should show the same leader
Jon Hall8f89dda2015-01-22 16:03:33 -08001224 for controller in range( 2, numControllers + 1 ):
Jon Hall6aec96b2015-01-19 14:49:31 -08001225 # loop through ONOScli handlers
1226 node = getattr( main, ( 'ONOScli' + str( controller ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001227 node.featureInstall( "onos-app-election" )
1228 leaderN = node.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08001229 # verify leader is ONOS1
Jon Hall8f89dda2015-01-22 16:03:33 -08001230 if leaderN == ONOS1Ip:
Jon Hall6aec96b2015-01-19 14:49:31 -08001231 # all is well
Jon Hall669173b2014-12-17 11:36:30 -08001232 pass
1233 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001234 # error in response
1235 # TODO: add check for "Command not found:" in the driver, this
1236 # means the app isn't loaded
1237 main.log.report( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001238 "electionTestLeader function, check the" +
Jon Hall6aec96b2015-01-19 14:49:31 -08001239 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001240 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08001241 elif leader != leaderN:
Jon Hall8f89dda2015-01-22 16:03:33 -08001242 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001243 main.log.report( "ONOS" + str( controller ) + " sees " +
1244 str( leaderN ) +
1245 " as the leader of the election app. Leader" +
1246 " should be " +
1247 str( leader ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001248 if leaderResult:
Jon Hall6aec96b2015-01-19 14:49:31 -08001249 main.log.report( "Leadership election tests passed( consistent " +
1250 "view of leader across listeners and a leader " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001251 "was elected )" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001252 utilities.assert_equals(
1253 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001254 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001255 onpass="Leadership election passed",
1256 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08001257
Jon Hall6aec96b2015-01-19 14:49:31 -08001258 def CASE15( self, main ):
1259 """
Jon Hall669173b2014-12-17 11:36:30 -08001260 Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -08001261 """
Jon Hall8f89dda2015-01-22 16:03:33 -08001262 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08001263 description = "Check that Leadership Election is still functional"
Jon Hall6aec96b2015-01-19 14:49:31 -08001264 main.log.report( description )
1265 main.case( description )
1266 main.step( "Find current leader and withdraw" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001267 leader = main.ONOScli1.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08001268 # TODO: do some sanity checking on leader before using it
Jon Hall8f89dda2015-01-22 16:03:33 -08001269 withdrawResult = main.FALSE
1270 if leader == ONOS1Ip:
1271 oldLeader = getattr( main, "ONOScli1" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001272 elif leader is None or leader == main.FALSE:
1273 main.log.report(
1274 "Leader for the election app should be an ONOS node," +
Jon Hall58c76b72015-02-23 11:09:24 -08001275 "instead got '" + str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001276 leaderResult = main.FALSE
Jon Hall63604932015-02-26 17:09:50 -08001277 oldLeader = None
1278 else:
1279 main.log.error( "Leader election --- why am I HERE?!?")
1280 if oldLeader:
1281 withdrawResult = oldLeader.electionTestWithdraw()
Jon Hall6aec96b2015-01-19 14:49:31 -08001282 utilities.assert_equals(
1283 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001284 actual=withdrawResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001285 onpass="App was withdrawn from election",
1286 onfail="App was not withdrawn from election" )
Jon Hall669173b2014-12-17 11:36:30 -08001287
Jon Hall6aec96b2015-01-19 14:49:31 -08001288 main.step( "Make sure new leader is elected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001289 leaderList = []
1290 leaderN = main.ONOScli1.electionTestLeader()
Jon Hall669173b2014-12-17 11:36:30 -08001291 if leaderN == leader:
Jon Hall6aec96b2015-01-19 14:49:31 -08001292 main.log.report( "ONOS still sees " + str( leaderN ) +
1293 " as leader after they withdrew" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001294 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08001295 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001296 # error in response
1297 # TODO: add check for "Command not found:" in the driver, this
1298 # means the app isn't loaded
Jon Hall8f89dda2015-01-22 16:03:33 -08001299 main.log.report( "Something is wrong with electionTestLeader " +
Jon Hall6aec96b2015-01-19 14:49:31 -08001300 "function, check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001301 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001302 elif leaderN is None:
1303 main.log.info(
1304 "There is no leader after the app withdrew from election" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001305 if leaderResult:
1306 main.log.report( "Leadership election tests passed( There is no " +
1307 "leader after the old leader resigned )" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001308 utilities.assert_equals(
1309 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001310 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001311 onpass="Leadership election passed",
1312 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08001313
Jon Hall58c76b72015-02-23 11:09:24 -08001314 main.step( "Run for election on old leader( just so everyone " +
1315 "is in the hat )" )
Jon Hall63604932015-02-26 17:09:50 -08001316 if oldLeader:
1317 runResult = oldLeader.electionTestRun()
1318 else:
1319 runResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001320 utilities.assert_equals(
1321 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001322 actual=runResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001323 onpass="App re-ran for election",
1324 onfail="App failed to run for election" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001325 leader = main.ONOScli1.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08001326 # verify leader is ONOS1
Jon Hall8f89dda2015-01-22 16:03:33 -08001327 if leader == ONOS1Ip:
1328 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08001329 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001330 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001331 # TODO: assert on run and withdraw results?
Jon Hall669173b2014-12-17 11:36:30 -08001332
Jon Hall6aec96b2015-01-19 14:49:31 -08001333 utilities.assert_equals(
1334 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001335 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001336 onpass="Leadership election passed",
1337 onfail="ONOS1's election app was not leader after it re-ran " +
1338 "for election" )