blob: fef844a9307dc67ac57aa8d845d8fe737123cc8e [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 Hallffb386d2014-11-21 13:43:38 -0800185 except:
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 """
Jon Hall6aec96b2015-01-19 14:49:31 -0800203 # FIXME: we must reinstall intents until we have a persistant
204 # datastore!
Jon Hall73cf9cc2014-11-20 22:28:38 -0800205 import time
Jon Hall58c76b72015-02-23 11:09:24 -0800206 import json
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 Hall58c76b72015-02-23 11:09:24 -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 Hall63604932015-02-26 17:09:50 -0800386
387 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" )
653 main.log.info( "ESTIMATE: ONOS took %s seconds to restart" %
654 str( elapsed ) )
Jon Hall6aec96b2015-01-19 14:49:31 -0800655 time.sleep( 5 )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800656
Jon Hall6aec96b2015-01-19 14:49:31 -0800657 def CASE7( self, main ):
658 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800659 Check state after ONOS failure
Jon Hall6aec96b2015-01-19 14:49:31 -0800660 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800661 import json
Jon Hall6aec96b2015-01-19 14:49:31 -0800662 main.case( "Running ONOS Constant State Tests" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800663
Jon Hall6aec96b2015-01-19 14:49:31 -0800664 # Assert that each device has a master
Jon Hall8f89dda2015-01-22 16:03:33 -0800665 rolesNotNull = main.ONOScli1.rolesNotNull()
Jon Hall6aec96b2015-01-19 14:49:31 -0800666 utilities.assert_equals(
667 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800668 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -0800669 onpass="Each device has a master",
670 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -0800671
Jon Hall6aec96b2015-01-19 14:49:31 -0800672 main.step( "Check if switch roles are consistent across all nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800673 ONOS1Mastership = main.ONOScli1.roles()
Jon Hall6aec96b2015-01-19 14:49:31 -0800674 # FIXME: Refactor this whole case for single instance
Jon Hall8f89dda2015-01-22 16:03:33 -0800675 if "Error" in ONOS1Mastership or not ONOS1Mastership:
Jon Hall6aec96b2015-01-19 14:49:31 -0800676 main.log.report( "Error in getting ONOS mastership" )
Jon Hall58c76b72015-02-23 11:09:24 -0800677 main.log.warn( "ONOS1 mastership response: " +
678 repr( ONOS1Mastership ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800679 consistentMastership = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800680 else:
Jon Hall8f89dda2015-01-22 16:03:33 -0800681 consistentMastership = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800682 main.log.report(
683 "Switch roles are consistent across all ONOS nodes" )
684 utilities.assert_equals(
685 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800686 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -0800687 onpass="Switch roles are consistent across all ONOS nodes",
688 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800689
690 description2 = "Compare switch roles from before failure"
Jon Hall6aec96b2015-01-19 14:49:31 -0800691 main.step( description2 )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800692
Jon Hall8f89dda2015-01-22 16:03:33 -0800693 currentJson = json.loads( ONOS1Mastership )
694 oldJson = json.loads( mastershipState )
695 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800696 for i in range( 1, 29 ):
697 switchDPID = str(
Jon Hall58c76b72015-02-23 11:09:24 -0800698 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800699
Jon Hall8f89dda2015-01-22 16:03:33 -0800700 current = [ switch[ 'master' ] for switch in currentJson
Jon Hall6aec96b2015-01-19 14:49:31 -0800701 if switchDPID in switch[ 'id' ] ]
Jon Hall8f89dda2015-01-22 16:03:33 -0800702 old = [ switch[ 'master' ] for switch in oldJson
Jon Hall6aec96b2015-01-19 14:49:31 -0800703 if switchDPID in switch[ 'id' ] ]
Jon Hall73cf9cc2014-11-20 22:28:38 -0800704 if current == old:
Jon Hall8f89dda2015-01-22 16:03:33 -0800705 mastershipCheck = mastershipCheck and main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800706 else:
Jon Hall6aec96b2015-01-19 14:49:31 -0800707 main.log.warn( "Mastership of switch %s changed" % switchDPID )
Jon Hall8f89dda2015-01-22 16:03:33 -0800708 mastershipCheck = main.FALSE
709 if mastershipCheck == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800710 main.log.report( "Mastership of Switches was not changed" )
711 utilities.assert_equals(
712 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800713 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800714 onpass="Mastership of Switches was not changed",
715 onfail="Mastership of some switches changed" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800716 mastershipCheck = mastershipCheck and consistentMastership
Jon Hall73cf9cc2014-11-20 22:28:38 -0800717
Jon Hall6aec96b2015-01-19 14:49:31 -0800718 main.step( "Get the intents and compare across all nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800719 ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
720 intentCheck = main.FALSE
721 if "Error" in ONOS1Intents or not ONOS1Intents:
Jon Hall6aec96b2015-01-19 14:49:31 -0800722 main.log.report( "Error in getting ONOS intents" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800723 main.log.warn( "ONOS1 intents response: " + repr( ONOS1Intents ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800724 else:
Jon Hall8f89dda2015-01-22 16:03:33 -0800725 intentCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800726 main.log.report( "Intents are consistent across all ONOS nodes" )
727 utilities.assert_equals(
728 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800729 actual=intentCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800730 onpass="Intents are consistent across all ONOS nodes",
731 onfail="ONOS nodes have different views of intents" )
Jon Hall1b8f54a2015-02-04 13:24:20 -0800732 # Print the intent states
733 intents = []
734 intents.append( ONOS1Intents )
735 intentStates = []
736 for node in intents: # Iter through ONOS nodes
737 nodeStates = []
Jon Hall58c76b72015-02-23 11:09:24 -0800738 # Iter through intents of a node
739 for intent in json.loads( node ):
Jon Hall1b8f54a2015-02-04 13:24:20 -0800740 nodeStates.append( intent[ 'state' ] )
741 intentStates.append( nodeStates )
742 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
743 main.log.info( dict( out ) )
744
Jon Hall58c76b72015-02-23 11:09:24 -0800745 # NOTE: Store has no durability, so intents are lost across system
746 # restarts
Jon Hall6aec96b2015-01-19 14:49:31 -0800747 """
748 main.step( "Compare current intents with intents before the failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800749 # NOTE: this requires case 5 to pass for intentState to be set.
Jon Hall6aec96b2015-01-19 14:49:31 -0800750 # maybe we should stop the test if that fails?
Jon Hall1b8f54a2015-02-04 13:24:20 -0800751 sameIntents = main.TRUE
752 if intentState and intentState == ONOS1Intents:
Jon Hall8f89dda2015-01-22 16:03:33 -0800753 sameIntents = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800754 main.log.report( "Intents are consistent with before failure" )
755 # TODO: possibly the states have changed? we may need to figure out
756 # what the aceptable states are
Jon Hall73cf9cc2014-11-20 22:28:38 -0800757 else:
Jon Hall6aec96b2015-01-19 14:49:31 -0800758 try:
759 main.log.warn( "ONOS1 intents: " )
Jon Hall8f89dda2015-01-22 16:03:33 -0800760 print json.dumps( json.loads( ONOS1Intents ),
Jon Hall6aec96b2015-01-19 14:49:31 -0800761 sort_keys=True, indent=4,
762 separators=( ',', ': ' ) )
763 except:
764 pass
Jon Hall8f89dda2015-01-22 16:03:33 -0800765 sameIntents = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800766 utilities.assert_equals(
767 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800768 actual=sameIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -0800769 onpass="Intents are consistent with before failure",
770 onfail="The Intents changed during failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800771 intentCheck = intentCheck and sameIntents
Jon Hall6aec96b2015-01-19 14:49:31 -0800772 """
773 main.step( "Get the OF Table entries and compare to before " +
774 "component failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800775 FlowTables = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800776 flows2 = []
777 for i in range( 28 ):
778 main.log.info( "Checking flow table on s" + str( i + 1 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800779 tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
780 flows2.append( tmpFlows )
781 tempResult = main.Mininet2.flowComp(
Jon Hall6aec96b2015-01-19 14:49:31 -0800782 flow1=flows[ i ],
Jon Hall8f89dda2015-01-22 16:03:33 -0800783 flow2=tmpFlows )
784 FlowTables = FlowTables and tempResult
785 if FlowTables == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800786 main.log.info( "Differences in flow table for switch: s" +
787 str( i + 1 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800788 if FlowTables == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800789 main.log.report( "No changes were found in the flow tables" )
790 utilities.assert_equals(
791 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800792 actual=FlowTables,
Jon Hall6aec96b2015-01-19 14:49:31 -0800793 onpass="No changes were found in the flow tables",
794 onfail="Changes were found in the flow tables" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800795
Jon Hall6aec96b2015-01-19 14:49:31 -0800796 # Test of LeadershipElection
Jon Hall669173b2014-12-17 11:36:30 -0800797
Jon Hall8f89dda2015-01-22 16:03:33 -0800798 leader = ONOS1Ip
799 leaderResult = main.TRUE
800 for controller in range( 1, numControllers + 1 ):
Jon Hall6aec96b2015-01-19 14:49:31 -0800801 # loop through ONOScli handlers
802 node = getattr( main, ( 'ONOScli' + str( controller ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800803 leaderN = node.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -0800804 # verify leader is ONOS1
805 # NOTE even though we restarted ONOS, it is the only one so onos 1
806 # must be leader
Jon Hall669173b2014-12-17 11:36:30 -0800807 if leaderN == leader:
Jon Hall6aec96b2015-01-19 14:49:31 -0800808 # all is well
Jon Hall669173b2014-12-17 11:36:30 -0800809 pass
810 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800811 # error in response
812 main.log.report( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -0800813 "electionTestLeader function, check the" +
Jon Hall6aec96b2015-01-19 14:49:31 -0800814 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800815 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -0800816 elif leader != leaderN:
Jon Hall8f89dda2015-01-22 16:03:33 -0800817 leaderResult = main.FALSE
Jon Hall58c76b72015-02-23 11:09:24 -0800818 main.log.report( "ONOS" + str( controller ) + " sees " +
819 str( leaderN ) +
820 " as the leader of the election app. " +
821 "Leader should be " + str( leader ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800822 if leaderResult:
823 main.log.report( "Leadership election tests passed( consistent " +
Jon Hall6aec96b2015-01-19 14:49:31 -0800824 "view of leader across listeners and a new " +
Jon Hall8f89dda2015-01-22 16:03:33 -0800825 "leader was re-elected if applicable )" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800826 utilities.assert_equals(
827 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800828 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -0800829 onpass="Leadership election passed",
830 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -0800831
Jon Hall8f89dda2015-01-22 16:03:33 -0800832 result = ( mastershipCheck and intentCheck and FlowTables and
833 rolesNotNull and leaderResult )
Jon Hall6aec96b2015-01-19 14:49:31 -0800834 result = int( result )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800835 if result == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800836 main.log.report( "Constant State Tests Passed" )
837 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall58c76b72015-02-23 11:09:24 -0800838 onpass="Constant State Tests Passed",
839 onfail="Constant state tests failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800840
Jon Hall6aec96b2015-01-19 14:49:31 -0800841 def CASE8( self, main ):
842 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800843 Compare topo
Jon Hall6aec96b2015-01-19 14:49:31 -0800844 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800845 import sys
Jon Hall6aec96b2015-01-19 14:49:31 -0800846 # FIXME add this path to params
847 sys.path.append( "/home/admin/sts" )
848 # assumes that sts is already in you PYTHONPATH
849 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -0800850 import json
851 import time
852
Jon Hall6aec96b2015-01-19 14:49:31 -0800853 description = "Compare ONOS Topology view to Mininet topology"
854 main.case( description )
855 main.log.report( description )
856 main.step( "Create TestONTopology object" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800857 ctrls = []
858 count = 1
859 temp = ()
Jon Hall6aec96b2015-01-19 14:49:31 -0800860 temp = temp + ( getattr( main, ( 'ONOS' + str( count ) ) ), )
861 temp = temp + ( "ONOS" + str( count ), )
862 temp = temp + ( main.params[ 'CTRL' ][ 'ip' + str( count ) ], )
863 temp = temp + \
864 ( eval( main.params[ 'CTRL' ][ 'port' + str( count ) ] ), )
865 ctrls.append( temp )
866 MNTopo = TestONTopology(
867 main.Mininet1,
868 ctrls ) # can also add Intent API info for intent operations
Jon Hall73cf9cc2014-11-20 22:28:38 -0800869
Jon Hall6aec96b2015-01-19 14:49:31 -0800870 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800871 devicesResults = main.TRUE
872 portsResults = main.TRUE
873 linksResults = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -0800874 hostsResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -0800875 topoResult = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800876 elapsed = 0
Jon Hallffb386d2014-11-21 13:43:38 -0800877 count = 0
Jon Hall6aec96b2015-01-19 14:49:31 -0800878 main.step( "Collecting topology information from ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800879 startTime = time.time()
Jon Hall58c76b72015-02-23 11:09:24 -0800880 # Give time for Gossip to work
Jon Hall8f89dda2015-01-22 16:03:33 -0800881 while topoResult == main.FALSE and elapsed < 60:
Jon Hallffb386d2014-11-21 13:43:38 -0800882 count = count + 1
Jon Hall94fd0472014-12-08 11:52:42 -0800883 if count > 1:
Jon Hall58c76b72015-02-23 11:09:24 -0800884 # TODO: Depricate STS usage
885 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall8f89dda2015-01-22 16:03:33 -0800886 cliStart = time.time()
Jon Hall94fd0472014-12-08 11:52:42 -0800887 devices = []
888 devices.append( main.ONOScli1.devices() )
Jon Hall94fd0472014-12-08 11:52:42 -0800889 hosts = []
Jon Hall58c76b72015-02-23 11:09:24 -0800890 hosts.append( json.loads( main.ONOScli1.hosts() ) )
891 ipResult = main.TRUE
892 for controller in range( 0, len( hosts ) ):
893 controllerStr = str( controller + 1 )
894 for host in hosts[ controller ]:
895 if host is None or host.get( 'ips', [] ) == []:
896 main.log.error(
897 "DEBUG:Error with host ips on controller" +
898 controllerStr + ": " + str( host ) )
899 ipResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -0800900 ports = []
901 ports.append( main.ONOScli1.ports() )
902 links = []
903 links.append( main.ONOScli1.links() )
Jon Hall58c76b72015-02-23 11:09:24 -0800904 clusters = []
905 clusters.append( main.ONOScli1.clusters() )
906
Jon Hall8f89dda2015-01-22 16:03:33 -0800907 elapsed = time.time() - startTime
908 cliTime = time.time() - cliStart
909 print "CLI time: " + str( cliTime )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800910
Jon Hall8f89dda2015-01-22 16:03:33 -0800911 for controller in range( numControllers ):
912 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -0800913 if devices[ controller ] or "Error" not in devices[
914 controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -0800915 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -0800916 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -0800917 json.loads( devices[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800918 else:
Jon Hall8f89dda2015-01-22 16:03:33 -0800919 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800920 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -0800921 actual=currentDevicesResult,
922 onpass="ONOS" + controllerStr +
923 " Switches view is correct",
924 onfail="ONOS" + controllerStr +
925 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800926
Jon Hall6aec96b2015-01-19 14:49:31 -0800927 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -0800928 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -0800929 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -0800930 json.loads( ports[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800931 else:
Jon Hall8f89dda2015-01-22 16:03:33 -0800932 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800933 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -0800934 actual=currentPortsResult,
935 onpass="ONOS" + controllerStr +
936 " ports view is correct",
937 onfail="ONOS" + controllerStr +
938 " ports view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800939
Jon Hall6aec96b2015-01-19 14:49:31 -0800940 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -0800941 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -0800942 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -0800943 json.loads( links[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800944 else:
Jon Hall8f89dda2015-01-22 16:03:33 -0800945 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800946 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -0800947 actual=currentLinksResult,
948 onpass="ONOS" + controllerStr +
949 " links view is correct",
950 onfail="ONOS" + controllerStr +
951 " links view is incorrect" )
952
953 if hosts[ controller ] or "Error" not in hosts[ controller ]:
954 currentHostsResult = main.Mininet1.compareHosts(
955 MNTopo, hosts[ controller ] )
956 else:
957 currentHostsResult = main.FALSE
958 utilities.assert_equals( expect=main.TRUE,
959 actual=currentHostsResult,
960 onpass="ONOS" + controllerStr +
961 " hosts exist in Mininet",
962 onfail="ONOS" + controllerStr +
963 " hosts don't match Mininet" )
964
965 devicesResults = devicesResults and currentDevicesResult
966 portsResults = portsResults and currentPortsResult
967 linksResults = linksResults and currentLinksResult
968 hostsResults = hostsResults and currentHostsResult
969
Jon Hall63604932015-02-26 17:09:50 -0800970 # "consistent" results don't make sense for single instance
Jon Hall58c76b72015-02-23 11:09:24 -0800971 # there should always only be one cluster
972 numClusters = len( json.loads( clusters[ 0 ] ) )
973 clusterResults = main.FALSE
974 if numClusters == 1:
975 clusterResults = main.TRUE
976 utilities.assert_equals(
977 expect=1,
978 actual=numClusters,
979 onpass="ONOS shows 1 SCC",
980 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
981
982 topoResult = ( devicesResults and portsResults and linksResults
983 and hostsResults and ipResult and clusterResults )
Jon Hall94fd0472014-12-08 11:52:42 -0800984
Jon Hall8f89dda2015-01-22 16:03:33 -0800985 topoResult = topoResult and int( count <= 2 )
986 note = "note it takes about " + str( int( cliTime ) ) + \
987 " seconds for the test to make all the cli calls to fetch " +\
988 "the topology from each ONOS instance"
Jon Hall1b8f54a2015-02-04 13:24:20 -0800989 main.log.info(
Jon Hall8f89dda2015-01-22 16:03:33 -0800990 "Very crass estimate for topology discovery/convergence( " +
991 str( note ) + " ): " + str( elapsed ) + " seconds, " +
Jon Hall6aec96b2015-01-19 14:49:31 -0800992 str( count ) + " tries" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800993 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -0800994 onpass="Topology Check Test successful",
995 onfail="Topology Check Test NOT successful" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800996 if topoResult == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800997 main.log.report( "ONOS topology view matches Mininet topology" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800998
Jon Hall6aec96b2015-01-19 14:49:31 -0800999 def CASE9( self, main ):
1000 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001001 Link s3-s28 down
Jon Hall6aec96b2015-01-19 14:49:31 -08001002 """
1003 import time
1004 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08001005
Jon Hall8f89dda2015-01-22 16:03:33 -08001006 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001007
Jon Hall6aec96b2015-01-19 14:49:31 -08001008 description = "Turn off a link to ensure that Link Discovery " +\
Jon Hall58c76b72015-02-23 11:09:24 -08001009 "is working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08001010 main.log.report( description )
1011 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001012
Jon Hall6aec96b2015-01-19 14:49:31 -08001013 main.step( "Kill Link between s3 and s28" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001014 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
Jon Hall58c76b72015-02-23 11:09:24 -08001015 main.log.info( "Waiting " + str( linkSleep ) +
1016 " seconds for link down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001017 time.sleep( linkSleep )
1018 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
Jon Hall58c76b72015-02-23 11:09:24 -08001019 onpass="Link down succesful",
1020 onfail="Failed to bring link down" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001021 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08001022
Jon Hall6aec96b2015-01-19 14:49:31 -08001023 def CASE10( self, main ):
1024 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001025 Link s3-s28 up
Jon Hall6aec96b2015-01-19 14:49:31 -08001026 """
1027 import time
1028 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08001029
Jon Hall8f89dda2015-01-22 16:03:33 -08001030 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001031
Jon Hall6aec96b2015-01-19 14:49:31 -08001032 description = "Restore a link to ensure that Link Discovery is " + \
Jon Hall58c76b72015-02-23 11:09:24 -08001033 "working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08001034 main.log.report( description )
1035 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001036
Jon Hall6aec96b2015-01-19 14:49:31 -08001037 main.step( "Bring link between s3 and s28 back up" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001038 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
Jon Hall58c76b72015-02-23 11:09:24 -08001039 main.log.info( "Waiting " + str( linkSleep ) +
1040 " seconds for link up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001041 time.sleep( linkSleep )
1042 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
Jon Hall58c76b72015-02-23 11:09:24 -08001043 onpass="Link up succesful",
1044 onfail="Failed to bring link up" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001045 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08001046
Jon Hall6aec96b2015-01-19 14:49:31 -08001047 def CASE11( self, main ):
1048 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001049 Switch Down
Jon Hall6aec96b2015-01-19 14:49:31 -08001050 """
1051 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08001052 import time
1053
Jon Hall8f89dda2015-01-22 16:03:33 -08001054 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001055
1056 description = "Killing a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08001057 main.log.report( description )
1058 main.case( description )
1059 switch = main.params[ 'kill' ][ 'switch' ]
1060 switchDPID = main.params[ 'kill' ][ 'dpid' ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08001061
Jon Hall6aec96b2015-01-19 14:49:31 -08001062 # TODO: Make this switch parameterizable
1063 main.step( "Kill " + switch )
1064 main.log.report( "Deleting " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08001065 main.Mininet1.delSwitch( switch )
1066 main.log.info( "Waiting " + str( switchSleep ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08001067 " seconds for switch down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001068 time.sleep( switchSleep )
1069 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08001070 # Peek at the deleted switch
1071 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001072 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001073 if device and device[ 'available' ] is False:
Jon Hall94fd0472014-12-08 11:52:42 -08001074 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001075 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall58c76b72015-02-23 11:09:24 -08001076 onpass="Kill switch succesful",
1077 onfail="Failed to kill switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001078
Jon Hall6aec96b2015-01-19 14:49:31 -08001079 def CASE12( self, main ):
1080 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001081 Switch Up
Jon Hall6aec96b2015-01-19 14:49:31 -08001082 """
1083 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08001084 import time
Jon Hall669173b2014-12-17 11:36:30 -08001085
Jon Hall8f89dda2015-01-22 16:03:33 -08001086 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall6aec96b2015-01-19 14:49:31 -08001087 switch = main.params[ 'kill' ][ 'switch' ]
1088 switchDPID = main.params[ 'kill' ][ 'dpid' ]
1089 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hall73cf9cc2014-11-20 22:28:38 -08001090 description = "Adding a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08001091 main.log.report( description )
1092 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001093
Jon Hall6aec96b2015-01-19 14:49:31 -08001094 main.step( "Add back " + switch )
1095 main.log.report( "Adding back " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08001096 main.Mininet1.addSwitch( switch, dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08001097 # TODO: New dpid or same? Ask Thomas?
1098 for peer in links:
Jon Hall8f89dda2015-01-22 16:03:33 -08001099 main.Mininet1.addLink( switch, peer )
1100 main.Mininet1.assignSwController( sw=switch.split( 's' )[ 1 ],
Jon Hall58c76b72015-02-23 11:09:24 -08001101 ip1=ONOS1Ip,
1102 port1=ONOS1Port )
1103 main.log.info( "Waiting " + str( switchSleep ) +
1104 " seconds for switch up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001105 time.sleep( switchSleep )
1106 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08001107 # Peek at the deleted switch
1108 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001109 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001110 if device and device[ 'available' ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001111 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001112 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall58c76b72015-02-23 11:09:24 -08001113 onpass="add switch succesful",
1114 onfail="Failed to add switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001115
Jon Hall6aec96b2015-01-19 14:49:31 -08001116 def CASE13( self, main ):
1117 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001118 Clean up
Jon Hall6aec96b2015-01-19 14:49:31 -08001119 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001120 import os
1121 import time
Jon Hall6aec96b2015-01-19 14:49:31 -08001122 # printing colors to terminal
Jon Hall669173b2014-12-17 11:36:30 -08001123 colors = {}
Jon Hall6aec96b2015-01-19 14:49:31 -08001124 colors[ 'cyan' ] = '\033[96m'
1125 colors[ 'purple' ] = '\033[95m'
1126 colors[ 'blue' ] = '\033[94m'
1127 colors[ 'green' ] = '\033[92m'
1128 colors[ 'yellow' ] = '\033[93m'
1129 colors[ 'red' ] = '\033[91m'
1130 colors[ 'end' ] = '\033[0m'
Jon Hall73cf9cc2014-11-20 22:28:38 -08001131 description = "Test Cleanup"
Jon Hall6aec96b2015-01-19 14:49:31 -08001132 main.log.report( description )
1133 main.case( description )
1134 main.step( "Killing tcpdumps" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001135 main.Mininet2.stopTcpdump()
Jon Hall73cf9cc2014-11-20 22:28:38 -08001136
Jon Hall6aec96b2015-01-19 14:49:31 -08001137 main.step( "Checking ONOS Logs for errors" )
1138 print colors[ 'purple' ] + "Checking logs for errors on ONOS1:" + \
Jon Hall8f89dda2015-01-22 16:03:33 -08001139 colors[ 'end' ]
1140 print main.ONOSbench.checkLogs( ONOS1Ip )
Jon Hall6aec96b2015-01-19 14:49:31 -08001141 main.step( "Copying MN pcap and ONOS log files to test station" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001142 testname = main.TEST
Jon Hall8f89dda2015-01-22 16:03:33 -08001143 teststationUser = main.params[ 'TESTONUSER' ]
1144 teststationIP = main.params[ 'TESTONIP' ]
Jon Hall6aec96b2015-01-19 14:49:31 -08001145 # NOTE: MN Pcap file is being saved to ~/packet_captures
Jon Hall73cf9cc2014-11-20 22:28:38 -08001146 # scp this file as MN and TestON aren't necessarily the same vm
Jon Hall6aec96b2015-01-19 14:49:31 -08001147 # FIXME: scp
1148 # mn files
1149 # TODO: Load these from params
1150 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08001151 logFolder = "/opt/onos/log/"
1152 logFiles = [ "karaf.log", "karaf.log.1" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08001153 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08001154 dstDir = "~/packet_captures/"
1155 for f in logFiles:
1156 main.ONOSbench.handle.sendline( "scp sdn@" + ONOS1Ip + ":" +
1157 logFolder + f + " " +
1158 teststationUser + "@" +
1159 teststationIP + ":" + dstDir +
Jon Hall6aec96b2015-01-19 14:49:31 -08001160 str( testname ) + "-ONOS1-" + f )
1161 main.ONOSbench.handle.expect( "\$" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001162
Jon Hall6aec96b2015-01-19 14:49:31 -08001163 # std*.log's
1164 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08001165 logFolder = "/opt/onos/var/"
1166 logFiles = [ "stderr.log", "stdout.log" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08001167 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08001168 dstDir = "~/packet_captures/"
1169 for f in logFiles:
1170 main.ONOSbench.handle.sendline( "scp sdn@" + ONOS1Ip + ":" +
1171 logFolder + f + " " +
1172 teststationUser + "@" +
1173 teststationIP + ":" + dstDir +
Jon Hall6aec96b2015-01-19 14:49:31 -08001174 str( testname ) + "-ONOS1-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08001175 main.ONOSbench.handle.expect( "\$" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001176 # sleep so scp can finish
1177 time.sleep( 10 )
Jon Hall58c76b72015-02-23 11:09:24 -08001178 main.Mininet1.stopNet()
Jon Hall6aec96b2015-01-19 14:49:31 -08001179 main.step( "Packing and rotating pcap archives" )
1180 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001181
Jon Hall6aec96b2015-01-19 14:49:31 -08001182 # TODO: actually check something here
1183 utilities.assert_equals( expect=main.TRUE, actual=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001184 onpass="Test cleanup successful",
1185 onfail="Test cleanup NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001186
Jon Hall6aec96b2015-01-19 14:49:31 -08001187 def CASE14( self, main ):
1188 """
Jon Hall669173b2014-12-17 11:36:30 -08001189 start election app on all onos nodes
Jon Hall6aec96b2015-01-19 14:49:31 -08001190 """
Jon Hall8f89dda2015-01-22 16:03:33 -08001191 leaderResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001192 # install app on onos 1
1193 main.log.info( "Install leadership election app" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001194 main.ONOScli1.featureInstall( "onos-app-election" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001195 # wait for election
1196 # check for leader
Jon Hall8f89dda2015-01-22 16:03:33 -08001197 leader = main.ONOScli1.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08001198 # verify leader is ONOS1
Jon Hall8f89dda2015-01-22 16:03:33 -08001199 if leader == ONOS1Ip:
Jon Hall6aec96b2015-01-19 14:49:31 -08001200 # all is well
Jon Hall669173b2014-12-17 11:36:30 -08001201 pass
Jon Hall6aec96b2015-01-19 14:49:31 -08001202 elif leader is None:
1203 # No leader elected
1204 main.log.report( "No leader was elected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001205 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08001206 elif leader == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001207 # error in response
1208 # TODO: add check for "Command not found:" in the driver, this
1209 # means the app isn't loaded
Jon Hall8f89dda2015-01-22 16:03:33 -08001210 main.log.report( "Something is wrong with electionTestLeader" +
Jon Hall6aec96b2015-01-19 14:49:31 -08001211 " function, check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001212 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08001213 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001214 # error in response
1215 main.log.report(
Jon Hall8f89dda2015-01-22 16:03:33 -08001216 "Unexpected response from electionTestLeader function:'" +
1217 str( leader ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08001218 "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001219 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08001220
Jon Hall6aec96b2015-01-19 14:49:31 -08001221 # install on other nodes and check for leader.
1222 # Should be onos1 and each app should show the same leader
Jon Hall8f89dda2015-01-22 16:03:33 -08001223 for controller in range( 2, numControllers + 1 ):
Jon Hall6aec96b2015-01-19 14:49:31 -08001224 # loop through ONOScli handlers
1225 node = getattr( main, ( 'ONOScli' + str( controller ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001226 node.featureInstall( "onos-app-election" )
1227 leaderN = node.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08001228 # verify leader is ONOS1
Jon Hall8f89dda2015-01-22 16:03:33 -08001229 if leaderN == ONOS1Ip:
Jon Hall6aec96b2015-01-19 14:49:31 -08001230 # all is well
Jon Hall669173b2014-12-17 11:36:30 -08001231 pass
1232 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001233 # error in response
1234 # TODO: add check for "Command not found:" in the driver, this
1235 # means the app isn't loaded
1236 main.log.report( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001237 "electionTestLeader function, check the" +
Jon Hall6aec96b2015-01-19 14:49:31 -08001238 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001239 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08001240 elif leader != leaderN:
Jon Hall8f89dda2015-01-22 16:03:33 -08001241 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001242 main.log.report( "ONOS" + str( controller ) + " sees " +
1243 str( leaderN ) +
1244 " as the leader of the election app. Leader" +
1245 " should be " +
1246 str( leader ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001247 if leaderResult:
Jon Hall6aec96b2015-01-19 14:49:31 -08001248 main.log.report( "Leadership election tests passed( consistent " +
1249 "view of leader across listeners and a leader " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001250 "was elected )" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001251 utilities.assert_equals(
1252 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001253 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001254 onpass="Leadership election passed",
1255 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08001256
Jon Hall6aec96b2015-01-19 14:49:31 -08001257 def CASE15( self, main ):
1258 """
Jon Hall669173b2014-12-17 11:36:30 -08001259 Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -08001260 """
Jon Hall8f89dda2015-01-22 16:03:33 -08001261 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08001262 description = "Check that Leadership Election is still functional"
Jon Hall6aec96b2015-01-19 14:49:31 -08001263 main.log.report( description )
1264 main.case( description )
1265 main.step( "Find current leader and withdraw" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001266 leader = main.ONOScli1.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08001267 # TODO: do some sanity checking on leader before using it
Jon Hall8f89dda2015-01-22 16:03:33 -08001268 withdrawResult = main.FALSE
1269 if leader == ONOS1Ip:
1270 oldLeader = getattr( main, "ONOScli1" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001271 elif leader is None or leader == main.FALSE:
1272 main.log.report(
1273 "Leader for the election app should be an ONOS node," +
Jon Hall58c76b72015-02-23 11:09:24 -08001274 "instead got '" + str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001275 leaderResult = main.FALSE
Jon Hall63604932015-02-26 17:09:50 -08001276 oldLeader = None
1277 else:
1278 main.log.error( "Leader election --- why am I HERE?!?")
1279 if oldLeader:
1280 withdrawResult = oldLeader.electionTestWithdraw()
Jon Hall6aec96b2015-01-19 14:49:31 -08001281 utilities.assert_equals(
1282 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001283 actual=withdrawResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001284 onpass="App was withdrawn from election",
1285 onfail="App was not withdrawn from election" )
Jon Hall669173b2014-12-17 11:36:30 -08001286
Jon Hall6aec96b2015-01-19 14:49:31 -08001287 main.step( "Make sure new leader is elected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001288 leaderList = []
1289 leaderN = main.ONOScli1.electionTestLeader()
Jon Hall669173b2014-12-17 11:36:30 -08001290 if leaderN == leader:
Jon Hall6aec96b2015-01-19 14:49:31 -08001291 main.log.report( "ONOS still sees " + str( leaderN ) +
1292 " as leader after they withdrew" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001293 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08001294 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001295 # error in response
1296 # TODO: add check for "Command not found:" in the driver, this
1297 # means the app isn't loaded
Jon Hall8f89dda2015-01-22 16:03:33 -08001298 main.log.report( "Something is wrong with electionTestLeader " +
Jon Hall6aec96b2015-01-19 14:49:31 -08001299 "function, check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001300 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001301 elif leaderN is None:
1302 main.log.info(
1303 "There is no leader after the app withdrew from election" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001304 if leaderResult:
1305 main.log.report( "Leadership election tests passed( There is no " +
1306 "leader after the old leader resigned )" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001307 utilities.assert_equals(
1308 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001309 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001310 onpass="Leadership election passed",
1311 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08001312
Jon Hall58c76b72015-02-23 11:09:24 -08001313 main.step( "Run for election on old leader( just so everyone " +
1314 "is in the hat )" )
Jon Hall63604932015-02-26 17:09:50 -08001315 if oldLeader:
1316 runResult = oldLeader.electionTestRun()
1317 else:
1318 runResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001319 utilities.assert_equals(
1320 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001321 actual=runResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001322 onpass="App re-ran for election",
1323 onfail="App failed to run for election" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001324 leader = main.ONOScli1.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08001325 # verify leader is ONOS1
Jon Hall8f89dda2015-01-22 16:03:33 -08001326 if leader == ONOS1Ip:
1327 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08001328 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001329 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001330 # TODO: assert on run and withdraw results?
Jon Hall669173b2014-12-17 11:36:30 -08001331
Jon Hall6aec96b2015-01-19 14:49:31 -08001332 utilities.assert_equals(
1333 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001334 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001335 onpass="Leadership election passed",
1336 onfail="ONOS1's election app was not leader after it re-ran " +
1337 "for election" )