blob: ba2b1136b798c613b4861684f024d90048a34b3f [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 ONOS can handle
3 a minority of it's nodes restarting
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.
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 Hall73cf9cc2014-11-20 22:28:38 -080024class HATestMinorityRestart:
25
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(
48 "ONOS HA test: Restart minority of ONOS nodes - 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
Jon Hall5cfd23c2015-03-19 11:40:57 -070052 # load some variables 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 ONOS1Port
Jon Hall8f89dda2015-01-22 16:03:33 -080061 global ONOS2Port
Jon Hall8f89dda2015-01-22 16:03:33 -080062 global ONOS3Port
Jon Hall8f89dda2015-01-22 16:03:33 -080063 global ONOS4Port
Jon Hall8f89dda2015-01-22 16:03:33 -080064 global ONOS5Port
Jon Hall8f89dda2015-01-22 16:03:33 -080065 global ONOS6Port
Jon Hall8f89dda2015-01-22 16:03:33 -080066 global ONOS7Port
67 global numControllers
Jon Hall8f89dda2015-01-22 16:03:33 -080068 numControllers = int( main.params[ 'num_controllers' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -080069
Jon Hall5cfd23c2015-03-19 11:40:57 -070070 # FIXME: just get controller port from params?
71 # TODO: do we really need all these?
72 ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
73 ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
74 ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
75 ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
76 ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
77 ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
78 ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
79
80 global CLIs
81 CLIs = []
82 global nodes
83 nodes = []
84 for i in range( 1, numControllers + 1 ):
85 CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
86 nodes.append( getattr( main, 'ONOS' + str( i ) ) )
87
Jon Hall6aec96b2015-01-19 14:49:31 -080088 main.step( "Applying cell variable to environment" )
Jon Hall8f89dda2015-01-22 16:03:33 -080089 cellResult = main.ONOSbench.setCell( cellName )
90 verifyResult = main.ONOSbench.verifyCell()
Jon Hall73cf9cc2014-11-20 22:28:38 -080091
Jon Hall6aec96b2015-01-19 14:49:31 -080092 # FIXME:this is short term fix
93 main.log.report( "Removing raft logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -080094 main.ONOSbench.onosRemoveRaftLogs()
Jon Hall5cfd23c2015-03-19 11:40:57 -070095
Jon Hall6aec96b2015-01-19 14:49:31 -080096 main.log.report( "Uninstalling ONOS" )
Jon Hall5cfd23c2015-03-19 11:40:57 -070097 for node in nodes:
98 main.ONOSbench.onosUninstall( node.ip_address )
Jon Hall73cf9cc2014-11-20 22:28:38 -080099
Jon Hall8f89dda2015-01-22 16:03:33 -0800100 cleanInstallResult = main.TRUE
101 gitPullResult = main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800102
Jon Hall97f31752015-02-04 12:01:04 -0800103 main.step( "Starting Mininet" )
104 main.Mininet1.startNet( )
105
Jon Hall6aec96b2015-01-19 14:49:31 -0800106 main.step( "Compiling the latest version of ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800107 if PULLCODE:
Jon Hall58c76b72015-02-23 11:09:24 -0800108 main.step( "Git checkout and pull " + gitBranch )
Jon Hall529a37f2015-01-28 10:02:00 -0800109 main.ONOSbench.gitCheckout( gitBranch )
Jon Hall8f89dda2015-01-22 16:03:33 -0800110 gitPullResult = main.ONOSbench.gitPull()
Jon Hall5cfd23c2015-03-19 11:40:57 -0700111 if gitPullResult == main.ERROR:
112 main.log.error( "Error pulling git branch" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800113
Jon Hall6aec96b2015-01-19 14:49:31 -0800114 main.step( "Using mvn clean & install" )
Jon Hall529a37f2015-01-28 10:02:00 -0800115 cleanInstallResult = main.ONOSbench.cleanInstall()
116 else:
117 main.log.warn( "Did not pull new code so skipping mvn " +
118 "clean install" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800119 main.ONOSbench.getVersion( report=True )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800120
Jon Hall6aec96b2015-01-19 14:49:31 -0800121 main.step( "Creating ONOS package" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800122 packageResult = main.ONOSbench.onosPackage()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800123
Jon Hall6aec96b2015-01-19 14:49:31 -0800124 main.step( "Installing ONOS package" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700125 onosInstallResult = main.TRUE
126 for node in nodes:
127 tmpResult = main.ONOSbench.onosInstall( options="-f",
128 node=node.ip_address )
129 onosInstallResult = onosInstallResult and tmpResult
Jon Hall73cf9cc2014-11-20 22:28:38 -0800130
Jon Hall6aec96b2015-01-19 14:49:31 -0800131 main.step( "Checking if ONOS is up yet" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800132 for i in range( 2 ):
Jon Hall5cfd23c2015-03-19 11:40:57 -0700133 onosIsupResult = main.TRUE
134 for node in nodes:
135 started = main.ONOSbench.isup( node.ip_address )
136 if not started:
137 main.log.report( node.name + " didn't start!" )
138 main.ONOSbench.onosStop( node.ip_address )
139 main.ONOSbench.onosStart( node.ip_address )
140 onosIsupResult = onosIsupResult and started
Jon Hall8f89dda2015-01-22 16:03:33 -0800141 if onosIsupResult == main.TRUE:
Jon Hall94fd0472014-12-08 11:52:42 -0800142 break
Jon Hall73cf9cc2014-11-20 22:28:38 -0800143
Jon Hall5cfd23c2015-03-19 11:40:57 -0700144 main.log.step( "Starting ONOS CLI sessions" )
145 cliResults = main.TRUE
146 threads = []
147 for i in range( numControllers ):
148 t = main.Thread( target=CLIs[i].startOnosCli,
149 name="startOnosCli-" + str( i ),
150 args=[nodes[i].ip_address] )
151 threads.append( t )
152 t.start()
153
154 for t in threads:
155 t.join()
156 cliResults = cliResults and t.result
Jon Hall73cf9cc2014-11-20 22:28:38 -0800157
Jon Hall6aec96b2015-01-19 14:49:31 -0800158 main.step( "Start Packet Capture MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800159 main.Mininet2.startTcpdump(
Jon Hall6aec96b2015-01-19 14:49:31 -0800160 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
161 + "-MN.pcap",
162 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
163 port=main.params[ 'MNtcpdump' ][ 'port' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800164
Jon Hall8f89dda2015-01-22 16:03:33 -0800165 case1Result = ( cleanInstallResult and packageResult and
166 cellResult and verifyResult and onosInstallResult
167 and onosIsupResult and cliResults )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800168
Jon Hall8f89dda2015-01-22 16:03:33 -0800169 utilities.assert_equals( expect=main.TRUE, actual=case1Result,
Jon Hall58c76b72015-02-23 11:09:24 -0800170 onpass="Test startup successful",
171 onfail="Test startup NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800172
Jon Hall8f89dda2015-01-22 16:03:33 -0800173 if case1Result == main.FALSE:
Jon Hall94fd0472014-12-08 11:52:42 -0800174 main.cleanup()
175 main.exit()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800176
Jon Hall6aec96b2015-01-19 14:49:31 -0800177 def CASE2( self, main ):
178 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800179 Assign mastership to controllers
Jon Hall6aec96b2015-01-19 14:49:31 -0800180 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800181 import re
Jon Hall5cfd23c2015-03-19 11:40:57 -0700182 assert numControllers, "numControllers not defined"
183 assert main, "main not defined"
184 assert utilities.assert_equals, "utilities.assert_equals not defined"
185 assert CLIs, "CLIs not defined"
186 assert nodes, "nodes not defined"
187 assert ONOS1Port, "ONOS1Port not defined"
188 assert ONOS2Port, "ONOS2Port not defined"
189 assert ONOS3Port, "ONOS3Port not defined"
190 assert ONOS4Port, "ONOS4Port not defined"
191 assert ONOS5Port, "ONOS5Port not defined"
192 assert ONOS6Port, "ONOS6Port not defined"
193 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -0800194
Jon Hall6aec96b2015-01-19 14:49:31 -0800195 main.log.report( "Assigning switches to controllers" )
196 main.case( "Assigning Controllers" )
197 main.step( "Assign switches to controllers" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800198
Jon Hall5cfd23c2015-03-19 11:40:57 -0700199 # TODO: rewrite this function to take lists of ips and ports?
200 # or list of tuples?
Jon Hall6aec96b2015-01-19 14:49:31 -0800201 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800202 main.Mininet1.assignSwController(
Jon Hall6aec96b2015-01-19 14:49:31 -0800203 sw=str( i ),
Jon Hall8f89dda2015-01-22 16:03:33 -0800204 count=numControllers,
Jon Hall5cfd23c2015-03-19 11:40:57 -0700205 ip1=nodes[ 0 ].ip_address, port1=ONOS1Port,
206 ip2=nodes[ 1 ].ip_address, port2=ONOS2Port,
207 ip3=nodes[ 2 ].ip_address, port3=ONOS3Port,
208 ip4=nodes[ 3 ].ip_address, port4=ONOS4Port,
209 ip5=nodes[ 4 ].ip_address, port5=ONOS5Port,
210 ip6=nodes[ 5 ].ip_address, port6=ONOS6Port,
211 ip7=nodes[ 6 ].ip_address, port7=ONOS7Port )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800212
Jon Hall8f89dda2015-01-22 16:03:33 -0800213 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800214 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800215 response = main.Mininet1.getSwController( "s" + str( i ) )
Jon Hallffb386d2014-11-21 13:43:38 -0800216 try:
Jon Hall6aec96b2015-01-19 14:49:31 -0800217 main.log.info( str( response ) )
Jon Hallfebb1c72015-03-05 13:30:09 -0800218 except Exception:
Jon Hall6aec96b2015-01-19 14:49:31 -0800219 main.log.info( repr( response ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700220 for node in nodes:
221 if re.search( "tcp:" + node.ip_address, response ):
222 mastershipCheck = mastershipCheck and main.TRUE
223 else:
224 mastershipCheck = main.FALSE
Jon Hall8f89dda2015-01-22 16:03:33 -0800225 if mastershipCheck == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800226 main.log.report( "Switch mastership assigned correctly" )
227 utilities.assert_equals(
228 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800229 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800230 onpass="Switch mastership assigned correctly",
231 onfail="Switches not assigned correctly to controllers" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700232 #FIXME: turning off because of ONOS-1286
Jon Hall6aec96b2015-01-19 14:49:31 -0800233 # Manually assign mastership to the controller we want
Jon Hall8f89dda2015-01-22 16:03:33 -0800234 roleCall = main.TRUE
235 roleCheck = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -0800236 try:
237 # Assign switch
Jon Hall5cfd23c2015-03-19 11:40:57 -0700238 ip = nodes[ 0 ].ip_address # ONOS1
Jon Hall58c76b72015-02-23 11:09:24 -0800239 deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
240 assert deviceId, "No device id for s1 in ONOS"
Jon Hall8f89dda2015-01-22 16:03:33 -0800241 roleCall = roleCall and main.ONOScli1.deviceRole(
242 deviceId,
Jon Hall5cfd23c2015-03-19 11:40:57 -0700243 ip )
Jon Hall6aec96b2015-01-19 14:49:31 -0800244 # Check assignment
Jon Hall5cfd23c2015-03-19 11:40:57 -0700245 if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800246 roleCheck = roleCheck and main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800247 else:
Jon Hall8f89dda2015-01-22 16:03:33 -0800248 roleCheck = roleCheck and main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800249
Jon Hall58c76b72015-02-23 11:09:24 -0800250 # Assign switch
251 deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
252 assert deviceId, "No device id for s28 in ONOS"
Jon Hall8f89dda2015-01-22 16:03:33 -0800253 roleCall = roleCall and main.ONOScli1.deviceRole(
254 deviceId,
Jon Hall5cfd23c2015-03-19 11:40:57 -0700255 ip )
Jon Hall6aec96b2015-01-19 14:49:31 -0800256 # Check assignment
Jon Hall5cfd23c2015-03-19 11:40:57 -0700257 if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800258 roleCheck = roleCheck and main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800259 else:
Jon Hall8f89dda2015-01-22 16:03:33 -0800260 roleCheck = roleCheck and main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -0800261
Jon Hall5cfd23c2015-03-19 11:40:57 -0700262 ip = nodes[ 1 ].ip_address # ONOS2
Jon Hall58c76b72015-02-23 11:09:24 -0800263 # Assign switch
264 deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
265 assert deviceId, "No device id for s2 in ONOS"
266 roleCall = roleCall and main.ONOScli1.deviceRole(
267 deviceId,
Jon Hall5cfd23c2015-03-19 11:40:57 -0700268 ip )
Jon Hall58c76b72015-02-23 11:09:24 -0800269 # Check assignment
Jon Hall5cfd23c2015-03-19 11:40:57 -0700270 if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
Jon Hall58c76b72015-02-23 11:09:24 -0800271 roleCheck = roleCheck and main.TRUE
272 else:
273 roleCheck = roleCheck and main.FALSE
274
275 # Assign switch
276 deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
277 assert deviceId, "No device id for s3 in ONOS"
278 roleCall = roleCall and main.ONOScli1.deviceRole(
279 deviceId,
Jon Hall5cfd23c2015-03-19 11:40:57 -0700280 ip )
Jon Hall58c76b72015-02-23 11:09:24 -0800281 # Check assignment
Jon Hall5cfd23c2015-03-19 11:40:57 -0700282 if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
Jon Hall58c76b72015-02-23 11:09:24 -0800283 roleCheck = roleCheck and main.TRUE
284 else:
285 roleCheck = roleCheck and main.FALSE
286
Jon Hall5cfd23c2015-03-19 11:40:57 -0700287 ip = nodes[ 2 ].ip_address # ONOS3
Jon Hall58c76b72015-02-23 11:09:24 -0800288 # Assign switch
289 deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
290 assert deviceId, "No device id for s5 in ONOS"
291 roleCall = roleCall and main.ONOScli1.deviceRole(
292 deviceId,
Jon Hall5cfd23c2015-03-19 11:40:57 -0700293 ip )
Jon Hall58c76b72015-02-23 11:09:24 -0800294 # Check assignment
Jon Hall5cfd23c2015-03-19 11:40:57 -0700295 if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
Jon Hall58c76b72015-02-23 11:09:24 -0800296 roleCheck = roleCheck and main.TRUE
297 else:
298 roleCheck = roleCheck and main.FALSE
299
300 # Assign switch
301 deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
302 assert deviceId, "No device id for s6 in ONOS"
303 roleCall = roleCall and main.ONOScli1.deviceRole(
304 deviceId,
Jon Hall5cfd23c2015-03-19 11:40:57 -0700305 ip )
Jon Hall58c76b72015-02-23 11:09:24 -0800306 # Check assignment
Jon Hall5cfd23c2015-03-19 11:40:57 -0700307 if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
Jon Hall58c76b72015-02-23 11:09:24 -0800308 roleCheck = roleCheck and main.TRUE
309 else:
310 roleCheck = roleCheck and main.FALSE
311
Jon Hall5cfd23c2015-03-19 11:40:57 -0700312 ip = nodes[ 3 ].ip_address # ONOS4
Jon Hall58c76b72015-02-23 11:09:24 -0800313 # Assign switch
314 deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
315 assert deviceId, "No device id for s4 in ONOS"
316 roleCall = roleCall and main.ONOScli1.deviceRole(
317 deviceId,
Jon Hall5cfd23c2015-03-19 11:40:57 -0700318 ip )
Jon Hall58c76b72015-02-23 11:09:24 -0800319 # Check assignment
Jon Hall5cfd23c2015-03-19 11:40:57 -0700320 if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
Jon Hall58c76b72015-02-23 11:09:24 -0800321 roleCheck = roleCheck and main.TRUE
322 else:
323 roleCheck = roleCheck and main.FALSE
324
Jon Hall5cfd23c2015-03-19 11:40:57 -0700325 ip = nodes[ 4 ].ip_address # ONOS5
Jon Hall58c76b72015-02-23 11:09:24 -0800326 for i in range( 8, 18 ):
327 dpid = '3' + str( i ).zfill( 3 )
328 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
329 assert deviceId, "No device id for s%i in ONOS" % i
330 roleCall = roleCall and main.ONOScli1.deviceRole(
331 deviceId,
Jon Hall5cfd23c2015-03-19 11:40:57 -0700332 ip )
Jon Hall58c76b72015-02-23 11:09:24 -0800333 # Check assignment
Jon Hall5cfd23c2015-03-19 11:40:57 -0700334 if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
Jon Hall58c76b72015-02-23 11:09:24 -0800335 roleCheck = roleCheck and main.TRUE
336 else:
337 roleCheck = roleCheck and main.FALSE
338
Jon Hall5cfd23c2015-03-19 11:40:57 -0700339 ip = nodes[ 5 ].ip_address # ONOS6
Jon Hall58c76b72015-02-23 11:09:24 -0800340 deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
341 assert deviceId, "No device id for s7 in ONOS"
342 roleCall = roleCall and main.ONOScli1.deviceRole(
343 deviceId,
Jon Hall5cfd23c2015-03-19 11:40:57 -0700344 ip )
Jon Hall58c76b72015-02-23 11:09:24 -0800345 # Check assignment
Jon Hall5cfd23c2015-03-19 11:40:57 -0700346 if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
Jon Hall58c76b72015-02-23 11:09:24 -0800347 roleCheck = roleCheck and main.TRUE
348 else:
349 roleCheck = roleCheck and main.FALSE
350
Jon Hall5cfd23c2015-03-19 11:40:57 -0700351 ip = nodes[ 6 ].ip_address # ONOS7
Jon Hall58c76b72015-02-23 11:09:24 -0800352 for i in range( 18, 28 ):
353 dpid = '6' + str( i ).zfill( 3 )
354 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
355 assert deviceId, "No device id for s%i in ONOS" % i
356 roleCall = roleCall and main.ONOScli1.deviceRole(
357 deviceId,
Jon Hall5cfd23c2015-03-19 11:40:57 -0700358 ip )
Jon Hall58c76b72015-02-23 11:09:24 -0800359 # Check assignment
Jon Hall5cfd23c2015-03-19 11:40:57 -0700360 if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
Jon Hall58c76b72015-02-23 11:09:24 -0800361 roleCheck = roleCheck and main.TRUE
362 else:
363 roleCheck = roleCheck and main.FALSE
364 except ( AttributeError, AssertionError ):
365 main.log.exception( "Something is wrong with ONOS device view" )
366 main.log.info( main.ONOScli1.devices() )
Jon Hall6aec96b2015-01-19 14:49:31 -0800367 utilities.assert_equals(
368 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800369 actual=roleCall,
Jon Hall6aec96b2015-01-19 14:49:31 -0800370 onpass="Re-assigned switch mastership to designated controller",
Jon Hall8f89dda2015-01-22 16:03:33 -0800371 onfail="Something wrong with deviceRole calls" )
Jon Hall94fd0472014-12-08 11:52:42 -0800372
Jon Hall6aec96b2015-01-19 14:49:31 -0800373 utilities.assert_equals(
374 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800375 actual=roleCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800376 onpass="Switches were successfully reassigned to designated " +
377 "controller",
378 onfail="Switches were not successfully reassigned" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800379 mastershipCheck = mastershipCheck and roleCall and roleCheck
380 utilities.assert_equals( expect=main.TRUE, actual=mastershipCheck,
Jon Hall21270ac2015-02-16 17:59:55 -0800381 onpass="Switch mastership correctly assigned",
382 onfail="Error in (re)assigning switch" +
383 " mastership" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800384
Jon Hall6aec96b2015-01-19 14:49:31 -0800385 def CASE3( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800386 """
387 Assign intents
Jon Hall73cf9cc2014-11-20 22:28:38 -0800388 """
389 import time
Jon Hallfebb1c72015-03-05 13:30:09 -0800390 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700391 assert numControllers, "numControllers not defined"
392 assert main, "main not defined"
393 assert utilities.assert_equals, "utilities.assert_equals not defined"
394 assert CLIs, "CLIs not defined"
395 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -0800396 main.log.report( "Adding host intents" )
397 main.case( "Adding host Intents" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800398
Jon Hall8f89dda2015-01-22 16:03:33 -0800399 main.step( "Discovering Hosts( Via pingall for now )" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800400 # FIXME: Once we have a host discovery mechanism, use that instead
Jon Hall73cf9cc2014-11-20 22:28:38 -0800401
Jon Hall6aec96b2015-01-19 14:49:31 -0800402 # install onos-app-fwd
403 main.log.info( "Install reactive forwarding app" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700404 appResults = main.TRUE
405 threads = []
406 for i in range( numControllers ):
407 t = main.Thread( target=CLIs[i].featureInstall,
408 name="featureInstall-" + str( i ),
409 args=["onos-app-fwd"] )
410 threads.append( t )
411 t.start()
412
413 for t in threads:
414 t.join()
415 appResults = appResults and t.result
Jon Hall94fd0472014-12-08 11:52:42 -0800416
Jon Hall6aec96b2015-01-19 14:49:31 -0800417 # REACTIVE FWD test
Jon Hall8f89dda2015-01-22 16:03:33 -0800418 pingResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700419 for i in range(2): # Retry if pingall fails first time
420 time1 = time.time()
421 pingResult = main.Mininet1.pingall()
422 utilities.assert_equals(
423 expect=main.TRUE,
424 actual=pingResult,
425 onpass="Reactive Pingall test passed",
426 onfail="Reactive Pingall failed, one or more ping pairs failed" )
427 time2 = time.time()
428 main.log.info( "Time for pingall: %2f seconds" % ( time2 - time1 ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800429
Jon Hall6aec96b2015-01-19 14:49:31 -0800430 # uninstall onos-app-fwd
431 main.log.info( "Uninstall reactive forwarding app" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700432 threads = []
433 for i in range( numControllers ):
434 t = main.Thread( target=CLIs[i].featureUninstall,
435 name="featureUninstall-" + str( i ),
436 args=["onos-app-fwd"] )
437 threads.append( t )
438 t.start()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800439
Jon Hall5cfd23c2015-03-19 11:40:57 -0700440 for t in threads:
441 t.join()
442 appResults = appResults and t.result
443
444 # timeout for fwd flows
445 time.sleep( 11 )
446
447 main.step( "Add host intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800448 intentIds = []
Jon Hall6aec96b2015-01-19 14:49:31 -0800449 # TODO: move the host numbers to params
Jon Hall58c76b72015-02-23 11:09:24 -0800450 # Maybe look at all the paths we ping?
Jon Hall8f89dda2015-01-22 16:03:33 -0800451 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800452 hostResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800453 for i in range( 8, 18 ):
454 main.log.info( "Adding host intent between h" + str( i ) +
455 " and h" + str( i + 10 ) )
456 host1 = "00:00:00:00:00:" + \
457 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
458 host2 = "00:00:00:00:00:" + \
459 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800460 # NOTE: getHost can return None
461 host1Dict = main.ONOScli1.getHost( host1 )
462 host2Dict = main.ONOScli1.getHost( host2 )
463 host1Id = None
464 host2Id = None
465 if host1Dict and host2Dict:
466 host1Id = host1Dict.get( 'id', None )
467 host2Id = host2Dict.get( 'id', None )
Jon Hall8f89dda2015-01-22 16:03:33 -0800468 if host1Id and host2Id:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700469 nodeNum = ( i % 7 )
470 tmpId = CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
Jon Hall63604932015-02-26 17:09:50 -0800471 if tmpId:
472 main.log.info( "Added intent with id: " + tmpId )
473 intentIds.append( tmpId )
474 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700475 main.log.error( "addHostIntent returned: " +
476 repr( tmpId ) )
Jon Hall669173b2014-12-17 11:36:30 -0800477 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700478 main.log.error( "Error, getHost() failed for h" + str( i ) +
479 " and/or h" + str( i + 10 ) )
480 hosts = CLIs[ 0 ].hosts()
481 main.log.warn( "Hosts output: " )
482 try:
483 main.log.warn( json.dumps( json.loads( hosts ),
484 sort_keys=True,
485 indent=4,
486 separators=( ',', ': ' ) ) )
487 except ( ValueError, TypeError ):
488 main.log.warn( repr( hosts ) )
Jon Hall58c76b72015-02-23 11:09:24 -0800489 hostResult = main.FALSE
490 onosIds = main.ONOScli1.getAllIntentsId()
491 main.log.info( "Submitted intents: " + str( intentIds ) )
492 main.log.info( "Intents in ONOS: " + str( onosIds ) )
493 for intent in intentIds:
494 if intent in onosIds:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700495 pass # intent submitted is in onos
Jon Hall58c76b72015-02-23 11:09:24 -0800496 else:
497 intentAddResult = False
Jon Hall1b8f54a2015-02-04 13:24:20 -0800498 # Print the intent states
Jon Hall58c76b72015-02-23 11:09:24 -0800499 intents = main.ONOScli1.intents()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800500 intentStates = []
Jon Hall5cfd23c2015-03-19 11:40:57 -0700501 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800502 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
503 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700504 try:
505 for intent in json.loads( intents ):
506 state = intent.get( 'state', None )
507 if "INSTALLED" not in state:
508 installedCheck = False
509 intentId = intent.get( 'id', None )
510 intentStates.append( ( intentId, state ) )
511 except ( ValueError, TypeError ):
512 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800513 # add submitted intents not in the store
514 tmplist = [ i for i, s in intentStates ]
515 missingIntents = False
516 for i in intentIds:
517 if i not in tmplist:
518 intentStates.append( ( i, " - " ) )
519 missingIntents = True
520 intentStates.sort()
521 for i, s in intentStates:
522 count += 1
523 main.log.info( "%-6s%-15s%-15s" %
524 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700525 leaders = main.ONOScli1.leaders()
526 try:
527 if leaders:
528 parsedLeaders = json.loads( leaders )
529 main.log.warn( json.dumps( parsedLeaders,
530 sort_keys=True,
531 indent=4,
532 separators=( ',', ': ' ) ) )
533 # check for all intent partitions
534 # check for election
535 topics = []
536 for i in range( 14 ):
537 topics.append( "intent-partition-" + str( i ) )
538 # FIXME: this should only be after we start the app
539 topics.append( "org.onosproject.election" )
540 main.log.debug( topics )
541 ONOStopics = [ j['topic'] for j in parsedLeaders ]
542 for topic in topics:
543 if topic not in ONOStopics:
544 main.log.error( "Error: " + topic +
545 " not in leaders" )
546 else:
547 main.log.error( "leaders() returned None" )
548 except ( ValueError, TypeError ):
549 main.log.exception( "Error parsing leaders" )
550 main.log.error( repr( leaders ) )
551 partitions = main.ONOScli1.partitions()
552 try:
553 if partitions :
554 parsedPartitions = json.loads( partitions )
555 main.log.warn( json.dumps( parsedPartitions,
556 sort_keys=True,
557 indent=4,
558 separators=( ',', ': ' ) ) )
559 # TODO check for a leader in all paritions
560 # TODO check for consistency among nodes
561 else:
562 main.log.error( "partitions() returned None" )
563 except ( ValueError, TypeError ):
564 main.log.exception( "Error parsing partitions" )
565 main.log.error( repr( partitions ) )
Jon Hall63604932015-02-26 17:09:50 -0800566 pendingMap = main.ONOScli1.pendingMap()
Jon Hall5cfd23c2015-03-19 11:40:57 -0700567 try:
568 if pendingMap :
569 parsedPending = json.loads( pendingMap )
570 main.log.warn( json.dumps( parsedPending,
571 sort_keys=True,
572 indent=4,
573 separators=( ',', ': ' ) ) )
574 # TODO check something here?
575 else:
576 main.log.error( "pendingMap() returned None" )
577 except ( ValueError, TypeError ):
578 main.log.exception( "Error parsing pending map" )
579 main.log.error( repr( pendingMap ) )
580
Jon Hall58c76b72015-02-23 11:09:24 -0800581 intentAddResult = bool( pingResult and hostResult and intentAddResult
Jon Hall63604932015-02-26 17:09:50 -0800582 and not missingIntents and installedCheck )
Jon Hall6aec96b2015-01-19 14:49:31 -0800583 utilities.assert_equals(
584 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -0800585 actual=intentAddResult,
Jon Hall529a37f2015-01-28 10:02:00 -0800586 onpass="Pushed host intents to ONOS",
587 onfail="Error in pushing host intents to ONOS" )
Jon Hall58c76b72015-02-23 11:09:24 -0800588
Jon Hall63604932015-02-26 17:09:50 -0800589 if not intentAddResult or "key" in pendingMap:
Jon Hall58c76b72015-02-23 11:09:24 -0800590 import time
Jon Hall63604932015-02-26 17:09:50 -0800591 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800592 main.log.info( "Sleeping 60 seconds to see if intents are found" )
593 time.sleep( 60 )
594 onosIds = main.ONOScli1.getAllIntentsId()
595 main.log.info( "Submitted intents: " + str( intentIds ) )
596 main.log.info( "Intents in ONOS: " + str( onosIds ) )
597 # Print the intent states
598 intents = main.ONOScli1.intents()
599 intentStates = []
600 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
601 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700602 try:
603 for intent in json.loads( intents ):
604 # Iter through intents of a node
605 state = intent.get( 'state', None )
606 if "INSTALLED" not in state:
607 installedCheck = False
608 intentId = intent.get( 'id', None )
609 intentStates.append( ( intentId, state ) )
610 except ( ValueError, TypeError ):
611 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800612 # add submitted intents not in the store
613 tmplist = [ i for i, s in intentStates ]
614 for i in intentIds:
615 if i not in tmplist:
616 intentStates.append( ( i, " - " ) )
617 intentStates.sort()
618 for i, s in intentStates:
619 count += 1
620 main.log.info( "%-6s%-15s%-15s" %
621 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700622 leaders = main.ONOScli1.leaders()
623 try:
624 if leaders:
625 parsedLeaders = json.loads( leaders )
626 main.log.warn( json.dumps( parsedLeaders,
627 sort_keys=True,
628 indent=4,
629 separators=( ',', ': ' ) ) )
630 # check for all intent partitions
631 # check for election
632 topics = []
633 for i in range( 14 ):
634 topics.append( "intent-partition-" + str( i ) )
635 # FIXME: this should only be after we start the app
636 topics.append( "org.onosproject.election" )
637 main.log.debug( topics )
638 ONOStopics = [ j['topic'] for j in parsedLeaders ]
639 for topic in topics:
640 if topic not in ONOStopics:
641 main.log.error( "Error: " + topic +
642 " not in leaders" )
643 else:
644 main.log.error( "leaders() returned None" )
645 except ( ValueError, TypeError ):
646 main.log.exception( "Error parsing leaders" )
647 main.log.error( repr( leaders ) )
648 partitions = main.ONOScli1.partitions()
649 try:
650 if partitions :
651 parsedPartitions = json.loads( partitions )
652 main.log.warn( json.dumps( parsedPartitions,
653 sort_keys=True,
654 indent=4,
655 separators=( ',', ': ' ) ) )
656 # TODO check for a leader in all paritions
657 # TODO check for consistency among nodes
658 else:
659 main.log.error( "partitions() returned None" )
660 except ( ValueError, TypeError ):
661 main.log.exception( "Error parsing partitions" )
662 main.log.error( repr( partitions ) )
663 pendingMap = main.ONOScli1.pendingMap()
664 try:
665 if pendingMap :
666 parsedPending = json.loads( pendingMap )
667 main.log.warn( json.dumps( parsedPending,
668 sort_keys=True,
669 indent=4,
670 separators=( ',', ': ' ) ) )
671 # TODO check something here?
672 else:
673 main.log.error( "pendingMap() returned None" )
674 except ( ValueError, TypeError ):
675 main.log.exception( "Error parsing pending map" )
676 main.log.error( repr( pendingMap ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800677
Jon Hall6aec96b2015-01-19 14:49:31 -0800678 def CASE4( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800679 """
680 Ping across added host intents
681 """
Jon Hallfebb1c72015-03-05 13:30:09 -0800682 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700683 import time
684 assert numControllers, "numControllers not defined"
685 assert main, "main not defined"
686 assert utilities.assert_equals, "utilities.assert_equals not defined"
687 assert CLIs, "CLIs not defined"
688 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -0800689 description = " Ping across added host intents"
Jon Hall6aec96b2015-01-19 14:49:31 -0800690 main.log.report( description )
691 main.case( description )
Jon Hall8f89dda2015-01-22 16:03:33 -0800692 PingResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800693 for i in range( 8, 18 ):
Jon Hall21270ac2015-02-16 17:59:55 -0800694 ping = main.Mininet1.pingHost( src="h" + str( i ),
695 target="h" + str( i + 10 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800696 PingResult = PingResult and ping
Jon Hall6aec96b2015-01-19 14:49:31 -0800697 if ping == main.FALSE:
698 main.log.warn( "Ping failed between h" + str( i ) +
699 " and h" + str( i + 10 ) )
700 elif ping == main.TRUE:
701 main.log.info( "Ping test passed!" )
Jon Hall21270ac2015-02-16 17:59:55 -0800702 # Don't set PingResult or you'd override failures
Jon Hall8f89dda2015-01-22 16:03:33 -0800703 if PingResult == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800704 main.log.report(
705 "Intents have not been installed correctly, pings failed." )
Jon Hall58c76b72015-02-23 11:09:24 -0800706 # TODO: pretty print
Jon Hall5cfd23c2015-03-19 11:40:57 -0700707 main.log.warn( "ONOS1 intents: " )
708 try:
709 tmpIntents = main.ONOScli1.intents()
710 main.log.warn( json.dumps( json.loads( tmpIntents ),
711 sort_keys=True,
712 indent=4,
713 separators=( ',', ': ' ) ) )
714 except ( ValueError, TypeError ):
715 main.log.warn( repr( tmpIntents ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800716 if PingResult == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800717 main.log.report(
718 "Intents have been installed correctly and verified by pings" )
719 utilities.assert_equals(
720 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800721 actual=PingResult,
Jon Hall6aec96b2015-01-19 14:49:31 -0800722 onpass="Intents have been installed correctly and pings work",
723 onfail="Intents have not been installed correctly, pings failed." )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800724
Jon Hall63604932015-02-26 17:09:50 -0800725 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800726 if PingResult is not main.TRUE:
727 # Print the intent states
728 intents = main.ONOScli1.intents()
729 intentStates = []
730 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
731 count = 0
732 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700733 try:
734 for intent in json.loads( intents ):
735 state = intent.get( 'state', None )
736 if "INSTALLED" not in state:
737 installedCheck = False
738 intentId = intent.get( 'id', None )
739 intentStates.append( ( intentId, state ) )
740 except ( ValueError, TypeError ):
741 main.log.exception( "Error parsing intents." )
Jon Hall58c76b72015-02-23 11:09:24 -0800742 intentStates.sort()
743 for i, s in intentStates:
744 count += 1
745 main.log.info( "%-6s%-15s%-15s" %
746 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700747 leaders = main.ONOScli1.leaders()
748 try:
749 if leaders:
750 parsedLeaders = json.loads( leaders )
751 main.log.warn( json.dumps( parsedLeaders,
752 sort_keys=True,
753 indent=4,
754 separators=( ',', ': ' ) ) )
755 # check for all intent partitions
756 # check for election
757 topics = []
758 for i in range( 14 ):
759 topics.append( "intent-partition-" + str( i ) )
760 # FIXME: this should only be after we start the app
761 topics.append( "org.onosproject.election" )
762 main.log.debug( topics )
763 ONOStopics = [ j['topic'] for j in parsedLeaders ]
764 for topic in topics:
765 if topic not in ONOStopics:
766 main.log.error( "Error: " + topic +
767 " not in leaders" )
768 else:
769 main.log.error( "leaders() returned None" )
770 except ( ValueError, TypeError ):
771 main.log.exception( "Error parsing leaders" )
772 main.log.error( repr( leaders ) )
773 partitions = main.ONOScli1.partitions()
774 try:
775 if partitions :
776 parsedPartitions = json.loads( partitions )
777 main.log.warn( json.dumps( parsedPartitions,
778 sort_keys=True,
779 indent=4,
780 separators=( ',', ': ' ) ) )
781 # TODO check for a leader in all paritions
782 # TODO check for consistency among nodes
783 else:
784 main.log.error( "partitions() returned None" )
785 except ( ValueError, TypeError ):
786 main.log.exception( "Error parsing partitions" )
787 main.log.error( repr( partitions ) )
788 pendingMap = main.ONOScli1.pendingMap()
789 try:
790 if pendingMap :
791 parsedPending = json.loads( pendingMap )
792 main.log.warn( json.dumps( parsedPending,
793 sort_keys=True,
794 indent=4,
795 separators=( ',', ': ' ) ) )
796 # TODO check something here?
797 else:
798 main.log.error( "pendingMap() returned None" )
799 except ( ValueError, TypeError ):
800 main.log.exception( "Error parsing pending map" )
801 main.log.error( repr( pendingMap ) )
802
Jon Hall63604932015-02-26 17:09:50 -0800803 if not installedCheck:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700804 main.log.info( "Waiting 60 seconds to see if the state of " +
805 "intents change" )
Jon Hall63604932015-02-26 17:09:50 -0800806 time.sleep( 60 )
807 # Print the intent states
808 intents = main.ONOScli1.intents()
809 intentStates = []
810 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
811 count = 0
812 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700813 try:
814 for intent in json.loads( intents ):
815 state = intent.get( 'state', None )
816 if "INSTALLED" not in state:
817 installedCheck = False
818 intentId = intent.get( 'id', None )
819 intentStates.append( ( intentId, state ) )
820 except ( ValueError, TypeError ):
821 main.log.exception( "Error parsing intents." )
Jon Hall63604932015-02-26 17:09:50 -0800822 intentStates.sort()
823 for i, s in intentStates:
824 count += 1
825 main.log.info( "%-6s%-15s%-15s" %
826 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700827 leaders = main.ONOScli1.leaders()
828 try:
829 if leaders:
830 parsedLeaders = json.loads( leaders )
831 main.log.warn( json.dumps( parsedLeaders,
832 sort_keys=True,
833 indent=4,
834 separators=( ',', ': ' ) ) )
835 # check for all intent partitions
836 # check for election
837 topics = []
838 for i in range( 14 ):
839 topics.append( "intent-partition-" + str( i ) )
840 # FIXME: this should only be after we start the app
841 topics.append( "org.onosproject.election" )
842 main.log.debug( topics )
843 ONOStopics = [ j['topic'] for j in parsedLeaders ]
844 for topic in topics:
845 if topic not in ONOStopics:
846 main.log.error( "Error: " + topic +
847 " not in leaders" )
848 else:
849 main.log.error( "leaders() returned None" )
850 except ( ValueError, TypeError ):
851 main.log.exception( "Error parsing leaders" )
852 main.log.error( repr( leaders ) )
853 partitions = main.ONOScli1.partitions()
854 try:
855 if partitions :
856 parsedPartitions = json.loads( partitions )
857 main.log.warn( json.dumps( parsedPartitions,
858 sort_keys=True,
859 indent=4,
860 separators=( ',', ': ' ) ) )
861 # TODO check for a leader in all paritions
862 # TODO check for consistency among nodes
863 else:
864 main.log.error( "partitions() returned None" )
865 except ( ValueError, TypeError ):
866 main.log.exception( "Error parsing partitions" )
867 main.log.error( repr( partitions ) )
868 pendingMap = main.ONOScli1.pendingMap()
869 try:
870 if pendingMap :
871 parsedPending = json.loads( pendingMap )
872 main.log.warn( json.dumps( parsedPending,
873 sort_keys=True,
874 indent=4,
875 separators=( ',', ': ' ) ) )
876 # TODO check something here?
877 else:
878 main.log.error( "pendingMap() returned None" )
879 except ( ValueError, TypeError ):
880 main.log.exception( "Error parsing pending map" )
881 main.log.error( repr( pendingMap ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800882
Jon Hall6aec96b2015-01-19 14:49:31 -0800883 def CASE5( self, main ):
884 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800885 Reading state of ONOS
Jon Hall6aec96b2015-01-19 14:49:31 -0800886 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800887 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700888 import time
889 assert numControllers, "numControllers not defined"
890 assert main, "main not defined"
891 assert utilities.assert_equals, "utilities.assert_equals not defined"
892 assert CLIs, "CLIs not defined"
893 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -0800894 # assumes that sts is already in you PYTHONPATH
895 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -0800896
Jon Hall6aec96b2015-01-19 14:49:31 -0800897 main.log.report( "Setting up and gathering data for current state" )
898 main.case( "Setting up and gathering data for current state" )
899 # The general idea for this test case is to pull the state of
900 # ( intents,flows, topology,... ) from each ONOS node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700901 # We can then compare them with each other and also with past states
Jon Hall73cf9cc2014-11-20 22:28:38 -0800902
Jon Hall5cfd23c2015-03-19 11:40:57 -0700903 main.step( "Check that each switch has a master" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800904 global mastershipState
Jon Hall5cfd23c2015-03-19 11:40:57 -0700905 mastershipState = '[]'
Jon Hall94fd0472014-12-08 11:52:42 -0800906
Jon Hall6aec96b2015-01-19 14:49:31 -0800907 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -0700908 rolesNotNull = main.TRUE
909 threads = []
910 for i in range( numControllers ):
911 t = main.Thread( target=CLIs[i].rolesNotNull,
912 name="rolesNotNull-" + str( i ),
913 args=[] )
914 threads.append( t )
915 t.start()
916
917 for t in threads:
918 t.join()
919 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -0800920 utilities.assert_equals(
921 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800922 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -0800923 onpass="Each device has a master",
924 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -0800925
Jon Hall5cfd23c2015-03-19 11:40:57 -0700926 main.step( "Get the Mastership of each switch from each controller" )
927 ONOSMastership = []
928 mastershipCheck = main.FALSE
929 consistentMastership = True
930 rolesResults = True
931 threads = []
932 for i in range( numControllers ):
933 t = main.Thread( target=CLIs[i].roles,
934 name="roles-" + str( i ),
935 args=[] )
936 threads.append( t )
937 t.start()
938
939 for t in threads:
940 t.join()
941 ONOSMastership.append( t.result )
942
943 for i in range( numControllers ):
944 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
945 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
946 " roles" )
947 main.log.warn(
948 "ONOS" + str( i + 1 ) + " mastership response: " +
949 repr( ONOSMastership[i] ) )
950 rolesResults = False
951 utilities.assert_equals(
952 expect=True,
953 actual=rolesResults,
954 onpass="No error in reading roles output",
955 onfail="Error in reading roles from ONOS" )
956
957 main.step( "Check for consistency in roles from each controller" )
958 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall6aec96b2015-01-19 14:49:31 -0800959 main.log.report(
960 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800961 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700962 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -0800963 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -0700964 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -0800965 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -0800966 onpass="Switch roles are consistent across all ONOS nodes",
967 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800968
Jon Hall5cfd23c2015-03-19 11:40:57 -0700969 if rolesResults and not consistentMastership:
970 for i in range( numControllers ):
971 try:
972 main.log.warn(
973 "ONOS" + str( i + 1 ) + " roles: ",
974 json.dumps(
975 json.loads( ONOSMastership[ i ] ),
976 sort_keys=True,
977 indent=4,
978 separators=( ',', ': ' ) ) )
979 except ( ValueError, TypeError ):
980 main.log.warn( repr( ONOSMastership[ i ] ) )
981 elif rolesResults and consistentMastership:
982 mastershipCheck = main.TRUE
983 mastershipState = ONOSMastership[ 0 ]
984
Jon Hall6aec96b2015-01-19 14:49:31 -0800985 main.step( "Get the intents from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800986 global intentState
987 intentState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -0700988 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -0800989 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700990 consistentIntents = True
991 intentsResults = True
992 threads = []
993 for i in range( numControllers ):
994 t = main.Thread( target=CLIs[i].intents,
995 name="intents-" + str( i ),
996 args=[],
997 kwargs={ 'jsonFormat': True } )
998 threads.append( t )
999 t.start()
1000
1001 for t in threads:
1002 t.join()
1003 ONOSIntents.append( t.result )
1004
1005 for i in range( numControllers ):
1006 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1007 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1008 " intents" )
1009 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1010 repr( ONOSIntents[ i ] ) )
1011 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001012 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001013 expect=True,
1014 actual=intentsResults,
1015 onpass="No error in reading intents output",
1016 onfail="Error in reading intents from ONOS" )
1017
1018 main.step( "Check for consistency in Intents from each controller" )
1019 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1020 main.log.report( "Intents are consistent across all ONOS " +
1021 "nodes" )
1022 else:
1023 consistentIntents = False
1024 main.log.report( "Intents not consistent" )
1025 utilities.assert_equals(
1026 expect=True,
1027 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001028 onpass="Intents are consistent across all ONOS nodes",
1029 onfail="ONOS nodes have different views of intents" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001030
Jon Hall5cfd23c2015-03-19 11:40:57 -07001031 if intentsResults and not consistentIntents:
1032 n = len(ONOSIntents)
1033 main.log.warn( "ONOS" + str( n ) + " intents: " )
1034 main.log.warn( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1035 sort_keys=True,
1036 indent=4,
1037 separators=( ',', ': ' ) ) )
1038 for i in range( numControllers ):
1039 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
1040 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1041 main.log.warn( json.dumps( json.loads( ONOSIntents[i] ),
1042 sort_keys=True,
1043 indent=4,
1044 separators=( ',', ': ' ) ) )
1045 else:
1046 main.log.warn( nodes[ i ].name + " intents match ONOS" +
1047 str( n ) + " intents" )
1048 elif intentsResults and consistentIntents:
1049 intentCheck = main.TRUE
1050 intentState = ONOSIntents[ 0 ]
1051
Jon Hall6aec96b2015-01-19 14:49:31 -08001052 main.step( "Get the flows from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001053 global flowState
1054 flowState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001055 ONOSFlows = []
1056 ONOSFlowsJson = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001057 flowCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001058 consistentFlows = True
1059 flowsResults = True
1060 threads = []
1061 for i in range( numControllers ):
1062 t = main.Thread( target=CLIs[i].flows,
1063 name="flows-" + str( i ),
1064 args=[],
1065 kwargs={ 'jsonFormat': True } )
1066 threads.append( t )
1067 t.start()
1068
1069 time.sleep(30)
1070 for t in threads:
1071 t.join()
1072 result = t.result
1073 ONOSFlows.append( result )
1074
1075 for i in range( numControllers ):
1076 num = str( i + 1 )
1077 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1078 main.log.report( "Error in getting ONOS" + num + " flows" )
1079 main.log.warn( "ONOS" + num + " flows response: " +
1080 repr( ONOSFlows[ i ] ) )
1081 flowsResults = False
1082 ONOSFlowsJson.append( None )
Jon Hall58c76b72015-02-23 11:09:24 -08001083 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001084 try:
1085 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1086 except ( ValueError, TypeError ):
1087 # FIXME: change this to log.error?
1088 main.log.exception( "Error in parsing ONOS" + num +
1089 " response as json." )
1090 main.log.error( repr( ONOSFlows[ i ] ) )
1091 ONOSFlowsJson.append( None )
1092 flowsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001093 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001094 expect=True,
1095 actual=flowsResults,
1096 onpass="No error in reading flows output",
1097 onfail="Error in reading flows from ONOS" )
1098
1099 main.step( "Check for consistency in Flows from each controller" )
1100 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1101 if all( tmp ):
1102 main.log.report( "Flow count is consistent across all ONOS nodes" )
1103 else:
1104 consistentFlows = False
1105 utilities.assert_equals(
1106 expect=True,
1107 actual=consistentFlows,
Jon Hall6aec96b2015-01-19 14:49:31 -08001108 onpass="The flow count is consistent across all ONOS nodes",
1109 onfail="ONOS nodes have different flow counts" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001110
Jon Hall5cfd23c2015-03-19 11:40:57 -07001111 if flowsResults and not consistentFlows:
1112 for i in range( numControllers ):
1113 try:
1114 main.log.warn(
1115 "ONOS" + str( i + 1 ) + " flows: " +
1116 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1117 indent=4, separators=( ',', ': ' ) ) )
1118 except ( ValueError, TypeError ):
1119 main.log.warn(
1120 "ONOS" + str( i + 1 ) + " flows: " +
1121 repr( ONOSFlows[ i ] ) )
1122 elif flowsResults and consistentFlows:
1123 flowCheck = main.TRUE
1124 flowState = ONOSFlows[ 0 ]
1125
Jon Hall6aec96b2015-01-19 14:49:31 -08001126 main.step( "Get the OF Table entries" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001127 global flows
Jon Hall6aec96b2015-01-19 14:49:31 -08001128 flows = []
1129 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001130 flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001131 if flowCheck == main.FALSE:
1132 for table in flows:
1133 main.log.warn( table )
Jon Hall6aec96b2015-01-19 14:49:31 -08001134 # TODO: Compare switch flow tables with ONOS flow tables
Jon Hall73cf9cc2014-11-20 22:28:38 -08001135
Jon Hall6aec96b2015-01-19 14:49:31 -08001136 main.step( "Start continuous pings" )
1137 main.Mininet2.pingLong(
1138 src=main.params[ 'PING' ][ 'source1' ],
1139 target=main.params[ 'PING' ][ 'target1' ],
1140 pingTime=500 )
1141 main.Mininet2.pingLong(
1142 src=main.params[ 'PING' ][ 'source2' ],
1143 target=main.params[ 'PING' ][ 'target2' ],
1144 pingTime=500 )
1145 main.Mininet2.pingLong(
1146 src=main.params[ 'PING' ][ 'source3' ],
1147 target=main.params[ 'PING' ][ 'target3' ],
1148 pingTime=500 )
1149 main.Mininet2.pingLong(
1150 src=main.params[ 'PING' ][ 'source4' ],
1151 target=main.params[ 'PING' ][ 'target4' ],
1152 pingTime=500 )
1153 main.Mininet2.pingLong(
1154 src=main.params[ 'PING' ][ 'source5' ],
1155 target=main.params[ 'PING' ][ 'target5' ],
1156 pingTime=500 )
1157 main.Mininet2.pingLong(
1158 src=main.params[ 'PING' ][ 'source6' ],
1159 target=main.params[ 'PING' ][ 'target6' ],
1160 pingTime=500 )
1161 main.Mininet2.pingLong(
1162 src=main.params[ 'PING' ][ 'source7' ],
1163 target=main.params[ 'PING' ][ 'target7' ],
1164 pingTime=500 )
1165 main.Mininet2.pingLong(
1166 src=main.params[ 'PING' ][ 'source8' ],
1167 target=main.params[ 'PING' ][ 'target8' ],
1168 pingTime=500 )
1169 main.Mininet2.pingLong(
1170 src=main.params[ 'PING' ][ 'source9' ],
1171 target=main.params[ 'PING' ][ 'target9' ],
1172 pingTime=500 )
1173 main.Mininet2.pingLong(
1174 src=main.params[ 'PING' ][ 'source10' ],
1175 target=main.params[ 'PING' ][ 'target10' ],
1176 pingTime=500 )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001177
Jon Hall6aec96b2015-01-19 14:49:31 -08001178 main.step( "Create TestONTopology object" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001179 ctrls = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001180 for node in nodes:
1181 temp = ( node, node.name, node.ip_address, 6633 )
1182 ctrls.append( temp )
1183 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001184
Jon Hall6aec96b2015-01-19 14:49:31 -08001185 main.step( "Collecting topology information from ONOS" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001186 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001187 threads = []
1188 for i in range( numControllers ):
1189 t = main.Thread( target=CLIs[i].devices,
1190 name="devices-" + str( i ),
1191 args=[ ] )
1192 threads.append( t )
1193 t.start()
1194
1195 for t in threads:
1196 t.join()
1197 devices.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001198 hosts = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001199 threads = []
1200 for i in range( numControllers ):
1201 t = main.Thread( target=CLIs[i].hosts,
1202 name="hosts-" + str( i ),
1203 args=[ ] )
1204 threads.append( t )
1205 t.start()
1206
1207 for t in threads:
1208 t.join()
1209 try:
1210 hosts.append( json.loads( t.result ) )
1211 except ( ValueError, TypeError ):
1212 # FIXME: better handling of this, print which node
1213 # Maybe use thread name?
1214 main.log.exception( "Error parsing json output of hosts" )
1215 # FIXME: should this be an empty json object instead?
1216 hosts.append( None )
1217
Jon Hall73cf9cc2014-11-20 22:28:38 -08001218 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001219 threads = []
1220 for i in range( numControllers ):
1221 t = main.Thread( target=CLIs[i].ports,
1222 name="ports-" + str( i ),
1223 args=[ ] )
1224 threads.append( t )
1225 t.start()
1226
1227 for t in threads:
1228 t.join()
1229 ports.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001230 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001231 threads = []
1232 for i in range( numControllers ):
1233 t = main.Thread( target=CLIs[i].links,
1234 name="links-" + str( i ),
1235 args=[ ] )
1236 threads.append( t )
1237 t.start()
1238
1239 for t in threads:
1240 t.join()
1241 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001242 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001243 threads = []
1244 for i in range( numControllers ):
1245 t = main.Thread( target=CLIs[i].clusters,
1246 name="clusters-" + str( i ),
1247 args=[ ] )
1248 threads.append( t )
1249 t.start()
1250
1251 for t in threads:
1252 t.join()
1253 clusters.append( t.result )
Jon Hall529a37f2015-01-28 10:02:00 -08001254 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08001255
Jon Hall6aec96b2015-01-19 14:49:31 -08001256 # hosts
Jon Hall8f89dda2015-01-22 16:03:33 -08001257 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001258 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001259 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001260 if "Error" not in hosts[ controller ]:
1261 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001262 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001263 else: # hosts not consistent
1264 main.log.report( "hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001265 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001266 " is inconsistent with ONOS1" )
1267 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001268 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001269
1270 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001271 main.log.report( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001272 controllerStr )
1273 consistentHostsResult = main.FALSE
1274 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001275 " hosts response: " +
1276 repr( hosts[ controller ] ) )
1277 utilities.assert_equals(
1278 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001279 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001280 onpass="Hosts view is consistent across all ONOS nodes",
1281 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08001282
Jon Hall58c76b72015-02-23 11:09:24 -08001283 ipResult = main.TRUE
1284 for controller in range( 0, len( hosts ) ):
1285 controllerStr = str( controller + 1 )
1286 for host in hosts[ controller ]:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001287 if not host.get( 'ips', [ ] ):
1288 main.log.error( "DEBUG:Error with host ips on controller" +
1289 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001290 ipResult = main.FALSE
1291 utilities.assert_equals(
1292 expect=main.TRUE,
1293 actual=ipResult,
1294 onpass="The ips of the hosts aren't empty",
1295 onfail="The ip of at least one host is missing" )
1296
Jon Hall6aec96b2015-01-19 14:49:31 -08001297 # Strongly connected clusters of devices
Jon Hall8f89dda2015-01-22 16:03:33 -08001298 consistentClustersResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001299 for controller in range( len( clusters ) ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001300 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001301 if "Error" not in clusters[ controller ]:
1302 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001303 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001304 else: # clusters not consistent
Jon Hall5cfd23c2015-03-19 11:40:57 -07001305 main.log.report( "clusters from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001306 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001307 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001308
1309 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001310 main.log.report( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001311 "from ONOS" + controllerStr )
1312 consistentClustersResult = main.FALSE
1313 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001314 " clusters response: " +
1315 repr( clusters[ controller ] ) )
1316 utilities.assert_equals(
1317 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001318 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001319 onpass="Clusters view is consistent across all ONOS nodes",
1320 onfail="ONOS nodes have different views of clusters" )
1321 # there should always only be one cluster
Jon Hall5cfd23c2015-03-19 11:40:57 -07001322 try:
1323 numClusters = len( json.loads( clusters[ 0 ] ) )
1324 except ( ValueError, TypeError ):
1325 main.log.exception( "Error parsing clusters[0]: " +
1326 repr( clusters[ 0 ] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001327 clusterResults = main.FALSE
1328 if numClusters == 1:
1329 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001330 utilities.assert_equals(
1331 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08001332 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08001333 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08001334 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08001335
Jon Hall6aec96b2015-01-19 14:49:31 -08001336 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001337 devicesResults = main.TRUE
1338 portsResults = main.TRUE
1339 linksResults = main.TRUE
1340 for controller in range( numControllers ):
1341 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001342 if devices[ controller ] or "Error" not in devices[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001343 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -08001344 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001345 json.loads( devices[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001346 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001347 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001348 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001349 actual=currentDevicesResult,
1350 onpass="ONOS" + controllerStr +
1351 " Switches view is correct",
1352 onfail="ONOS" + controllerStr +
1353 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001354
Jon Hall6aec96b2015-01-19 14:49:31 -08001355 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001356 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -08001357 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001358 json.loads( ports[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001359 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001360 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001361 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001362 actual=currentPortsResult,
1363 onpass="ONOS" + controllerStr +
1364 " ports view is correct",
1365 onfail="ONOS" + controllerStr +
1366 " ports view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001367
Jon Hall6aec96b2015-01-19 14:49:31 -08001368 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001369 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -08001370 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001371 json.loads( links[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001372 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001373 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001374 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001375 actual=currentLinksResult,
1376 onpass="ONOS" + controllerStr +
1377 " links view is correct",
1378 onfail="ONOS" + controllerStr +
1379 " links view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001380
Jon Hall8f89dda2015-01-22 16:03:33 -08001381 devicesResults = devicesResults and currentDevicesResult
1382 portsResults = portsResults and currentPortsResult
1383 linksResults = linksResults and currentLinksResult
Jon Hall73cf9cc2014-11-20 22:28:38 -08001384
Jon Hall5cfd23c2015-03-19 11:40:57 -07001385 topoResult = ( devicesResults and portsResults and linksResults
1386 and consistentHostsResult and consistentClustersResult
1387 and clusterResults and ipResult )
Jon Hall8f89dda2015-01-22 16:03:33 -08001388 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08001389 onpass="Topology Check Test successful",
1390 onfail="Topology Check Test NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001391
Jon Hall8f89dda2015-01-22 16:03:33 -08001392 finalAssert = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001393 finalAssert = ( finalAssert and topoResult and flowCheck
1394 and intentCheck and consistentMastership
1395 and rolesNotNull )
Jon Hall8f89dda2015-01-22 16:03:33 -08001396 utilities.assert_equals( expect=main.TRUE, actual=finalAssert,
Jon Hall58c76b72015-02-23 11:09:24 -08001397 onpass="State check successful",
1398 onfail="State check NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001399
Jon Hall6aec96b2015-01-19 14:49:31 -08001400 def CASE6( self, main ):
1401 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001402 The Failure case.
Jon Hall6aec96b2015-01-19 14:49:31 -08001403 """
Jon Hall94fd0472014-12-08 11:52:42 -08001404 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001405 assert numControllers, "numControllers not defined"
1406 assert main, "main not defined"
1407 assert utilities.assert_equals, "utilities.assert_equals not defined"
1408 assert CLIs, "CLIs not defined"
1409 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001410 main.log.report( "Killing 3 ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001411 main.case( "Restart minority of ONOS nodes" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001412 # TODO: Randomize these nodes
Jon Hall5cfd23c2015-03-19 11:40:57 -07001413 # TODO: use threads in this case
1414 main.ONOSbench.onosKill( nodes[0].ip_address )
Jon Hall6aec96b2015-01-19 14:49:31 -08001415 time.sleep( 10 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001416 main.ONOSbench.onosKill( nodes[1].ip_address )
Jon Hall6aec96b2015-01-19 14:49:31 -08001417 time.sleep( 10 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001418 main.ONOSbench.onosKill( nodes[2].ip_address )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001419
Jon Hall6aec96b2015-01-19 14:49:31 -08001420 main.step( "Checking if ONOS is up yet" )
Jon Hallffb386d2014-11-21 13:43:38 -08001421 count = 0
Jon Hall8f89dda2015-01-22 16:03:33 -08001422 onosIsupResult = main.FALSE
1423 while onosIsupResult == main.FALSE and count < 10:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001424 onos1Isup = main.ONOSbench.isup( nodes[0].ip_address )
1425 onos2Isup = main.ONOSbench.isup( nodes[1].ip_address )
1426 onos3Isup = main.ONOSbench.isup( nodes[2].ip_address )
Jon Hall8f89dda2015-01-22 16:03:33 -08001427 onosIsupResult = onos1Isup and onos2Isup and onos3Isup
Jon Hallffb386d2014-11-21 13:43:38 -08001428 count = count + 1
Jon Hall73cf9cc2014-11-20 22:28:38 -08001429 # TODO: if it becomes an issue, we can retry this step a few times
1430
Jon Hall5cfd23c2015-03-19 11:40:57 -07001431 cliResult1 = main.ONOScli1.startOnosCli( nodes[0].ip_address )
1432 cliResult2 = main.ONOScli2.startOnosCli( nodes[1].ip_address )
1433 cliResult3 = main.ONOScli3.startOnosCli( nodes[2].ip_address )
Jon Hall8f89dda2015-01-22 16:03:33 -08001434 cliResults = cliResult1 and cliResult2 and cliResult3
Jon Hall73cf9cc2014-11-20 22:28:38 -08001435
Jon Hall21270ac2015-02-16 17:59:55 -08001436 # Grab the time of restart so we chan check how long the gossip
1437 # protocol has had time to work
1438 main.restartTime = time.time()
Jon Hall8f89dda2015-01-22 16:03:33 -08001439 caseResults = main.TRUE and onosIsupResult and cliResults
1440 utilities.assert_equals( expect=main.TRUE, actual=caseResults,
Jon Hall58c76b72015-02-23 11:09:24 -08001441 onpass="ONOS restart successful",
1442 onfail="ONOS restart NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001443
Jon Hall6aec96b2015-01-19 14:49:31 -08001444 def CASE7( self, main ):
1445 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001446 Check state after ONOS failure
Jon Hall6aec96b2015-01-19 14:49:31 -08001447 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001448 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001449 assert numControllers, "numControllers not defined"
1450 assert main, "main not defined"
1451 assert utilities.assert_equals, "utilities.assert_equals not defined"
1452 assert CLIs, "CLIs not defined"
1453 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001454 main.case( "Running ONOS Constant State Tests" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001455
Jon Hall5cfd23c2015-03-19 11:40:57 -07001456 main.step( "Check that each switch has a master" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001457 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -07001458 rolesNotNull = main.TRUE
1459 threads = []
1460 for i in range( numControllers ):
1461 t = main.Thread( target=CLIs[i].rolesNotNull,
1462 name="rolesNotNull-" + str( i ),
1463 args=[ ] )
1464 threads.append( t )
1465 t.start()
1466
1467 for t in threads:
1468 t.join()
1469 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001470 utilities.assert_equals(
1471 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001472 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001473 onpass="Each device has a master",
1474 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001475
Jon Hall5cfd23c2015-03-19 11:40:57 -07001476 ONOSMastership = []
1477 mastershipCheck = main.FALSE
1478 consistentMastership = True
1479 rolesResults = True
1480 threads = []
1481 for i in range( numControllers ):
1482 t = main.Thread( target=CLIs[i].roles,
1483 name="roles-" + str( i ),
1484 args=[] )
1485 threads.append( t )
1486 t.start()
1487
1488 for t in threads:
1489 t.join()
1490 ONOSMastership.append( t.result )
1491
1492 for i in range( numControllers ):
1493 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1494 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1495 " roles" )
1496 main.log.warn(
1497 "ONOS" + str( i + 1 ) + " mastership response: " +
1498 repr( ONOSMastership[i] ) )
1499 rolesResults = False
1500 utilities.assert_equals(
1501 expect=True,
1502 actual=rolesResults,
1503 onpass="No error in reading roles output",
1504 onfail="Error in reading roles from ONOS" )
1505
1506 main.step( "Check for consistency in roles from each controller" )
1507 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall6aec96b2015-01-19 14:49:31 -08001508 main.log.report(
1509 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001510 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001511 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001512 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001513 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001514 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001515 onpass="Switch roles are consistent across all ONOS nodes",
1516 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001517
Jon Hall5cfd23c2015-03-19 11:40:57 -07001518 if rolesResults and not consistentMastership:
1519 for i in range( numControllers ):
1520 main.log.warn(
1521 "ONOS" + str( i + 1 ) + " roles: ",
1522 json.dumps(
1523 json.loads( ONOSMastership[ i ] ),
1524 sort_keys=True,
1525 indent=4,
1526 separators=( ',', ': ' ) ) )
1527 elif rolesResults and not consistentMastership:
1528 mastershipCheck = main.TRUE
1529
Jon Hall73cf9cc2014-11-20 22:28:38 -08001530 description2 = "Compare switch roles from before failure"
Jon Hall6aec96b2015-01-19 14:49:31 -08001531 main.step( description2 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001532 try:
1533 currentJson = json.loads( ONOSMastership[0] )
1534 oldJson = json.loads( mastershipState )
1535 except ( ValueError, TypeError ):
1536 main.log.exception( "Something is wrong with parsing " +
1537 "ONOSMastership[0] or mastershipState" )
1538 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1539 main.log.error( "mastershipState" + repr( mastershipState ) )
1540 main.cleanup()
1541 main.exit()
Jon Hall8f89dda2015-01-22 16:03:33 -08001542 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001543 for i in range( 1, 29 ):
1544 switchDPID = str(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001545 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001546 current = [ switch[ 'master' ] for switch in currentJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001547 if switchDPID in switch[ 'id' ] ]
Jon Hall8f89dda2015-01-22 16:03:33 -08001548 old = [ switch[ 'master' ] for switch in oldJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001549 if switchDPID in switch[ 'id' ] ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08001550 if current == old:
Jon Hall8f89dda2015-01-22 16:03:33 -08001551 mastershipCheck = mastershipCheck and main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001552 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001553 main.log.warn( "Mastership of switch %s changed" % switchDPID )
Jon Hall8f89dda2015-01-22 16:03:33 -08001554 mastershipCheck = main.FALSE
1555 if mastershipCheck == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001556 main.log.report( "Mastership of Switches was not changed" )
1557 utilities.assert_equals(
1558 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001559 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -08001560 onpass="Mastership of Switches was not changed",
1561 onfail="Mastership of some switches changed" )
1562 # NOTE: we expect mastership to change on controller failure
Jon Hall8f89dda2015-01-22 16:03:33 -08001563 mastershipCheck = consistentMastership
Jon Hall73cf9cc2014-11-20 22:28:38 -08001564
Jon Hall58c76b72015-02-23 11:09:24 -08001565 main.step( "Get the intents and compare across all nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001566 ONOSIntents = []
Jon Hall58c76b72015-02-23 11:09:24 -08001567 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001568 consistentIntents = True
1569 intentsResults = True
1570 threads = []
1571 for i in range( numControllers ):
1572 t = main.Thread( target=CLIs[i].intents,
1573 name="intents-" + str( i ),
1574 args=[],
1575 kwargs={ 'jsonFormat': True } )
1576 threads.append( t )
1577 t.start()
1578
1579 for t in threads:
1580 t.join()
1581 ONOSIntents.append( t.result )
1582
1583 for i in range( numControllers ):
1584 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1585 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1586 " intents" )
1587 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1588 repr( ONOSIntents[ i ] ) )
1589 intentsResults = False
Jon Hall58c76b72015-02-23 11:09:24 -08001590 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001591 expect=True,
1592 actual=intentsResults,
1593 onpass="No error in reading intents output",
1594 onfail="Error in reading intents from ONOS" )
1595
1596 main.step( "Check for consistency in Intents from each controller" )
1597 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1598 main.log.report( "Intents are consistent across all ONOS " +
1599 "nodes" )
1600 else:
1601 consistentIntents = False
1602 utilities.assert_equals(
1603 expect=True,
1604 actual=consistentIntents,
Jon Hall58c76b72015-02-23 11:09:24 -08001605 onpass="Intents are consistent across all ONOS nodes",
1606 onfail="ONOS nodes have different views of intents" )
Jon Hall58c76b72015-02-23 11:09:24 -08001607 intentStates = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001608 for node in ONOSIntents: # Iter through ONOS nodes
Jon Hall58c76b72015-02-23 11:09:24 -08001609 nodeStates = []
1610 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001611 try:
1612 for intent in json.loads( node ):
1613 nodeStates.append( intent[ 'state' ] )
1614 except ( ValueError, TypeError ):
1615 main.log.exception( "Error in parsing intents" )
1616 main.log.error( repr( node ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001617 intentStates.append( nodeStates )
1618 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1619 main.log.info( dict( out ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001620
Jon Hall5cfd23c2015-03-19 11:40:57 -07001621 if intentsResults and not consistentIntents:
1622 for i in range( numControllers ):
1623 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1624 main.log.warn( json.dumps(
1625 json.loads( ONOSIntents[ i ] ),
1626 sort_keys=True,
1627 indent=4,
1628 separators=( ',', ': ' ) ) )
1629 elif intentsResults and consistentIntents:
1630 intentCheck = main.TRUE
1631
Jon Hall58c76b72015-02-23 11:09:24 -08001632 # NOTE: Store has no durability, so intents are lost across system
1633 # restarts
1634 main.step( "Compare current intents with intents before the failure" )
1635 # NOTE: this requires case 5 to pass for intentState to be set.
1636 # maybe we should stop the test if that fails?
1637 sameIntents = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001638 if intentState and intentState == ONOSIntents[ 0 ]:
Jon Hall21270ac2015-02-16 17:59:55 -08001639 sameIntents = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08001640 main.log.report( "Intents are consistent with before failure" )
1641 # TODO: possibly the states have changed? we may need to figure out
Jon Hall5cfd23c2015-03-19 11:40:57 -07001642 # what the acceptable states are
Jon Hall58c76b72015-02-23 11:09:24 -08001643 else:
1644 try:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001645 main.log.warn( "ONOS intents: " )
1646 main.log.warn( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1647 sort_keys=True, indent=4,
1648 separators=( ',', ': ' ) ) )
1649 except ( ValueError, TypeError ):
1650 main.log.exception( "Exception printing intents" )
1651 main.log.warn( repr( ONOSIntents[0] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001652 sameIntents = main.FALSE
1653 utilities.assert_equals(
1654 expect=main.TRUE,
1655 actual=sameIntents,
1656 onpass="Intents are consistent with before failure",
1657 onfail="The Intents changed during failure" )
1658 intentCheck = intentCheck and sameIntents
Jon Hall21270ac2015-02-16 17:59:55 -08001659
Jon Hall58c76b72015-02-23 11:09:24 -08001660 main.step( "Get the OF Table entries and compare to before " +
1661 "component failure" )
1662 FlowTables = main.TRUE
1663 flows2 = []
1664 for i in range( 28 ):
1665 main.log.info( "Checking flow table on s" + str( i + 1 ) )
1666 tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
1667 flows2.append( tmpFlows )
1668 tempResult = main.Mininet2.flowComp(
1669 flow1=flows[ i ],
1670 flow2=tmpFlows )
1671 FlowTables = FlowTables and tempResult
1672 if FlowTables == main.FALSE:
1673 main.log.info( "Differences in flow table for switch: s" +
1674 str( i + 1 ) )
1675 if FlowTables == main.TRUE:
1676 main.log.report( "No changes were found in the flow tables" )
1677 utilities.assert_equals(
1678 expect=main.TRUE,
1679 actual=FlowTables,
1680 onpass="No changes were found in the flow tables",
1681 onfail="Changes were found in the flow tables" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001682
Jon Hall6aec96b2015-01-19 14:49:31 -08001683 main.step( "Check the continuous pings to ensure that no packets " +
1684 "were dropped during component failure" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001685 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
1686 main.params[ 'TESTONIP' ] )
Jon Hall8f89dda2015-01-22 16:03:33 -08001687 LossInPings = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001688 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
1689 for i in range( 8, 18 ):
1690 main.log.info(
1691 "Checking for a loss in pings along flow from s" +
1692 str( i ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001693 LossInPings = main.Mininet2.checkForLoss(
Jon Hall6aec96b2015-01-19 14:49:31 -08001694 "/tmp/ping.h" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001695 str( i ) ) or LossInPings
1696 if LossInPings == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001697 main.log.info( "Loss in ping detected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001698 elif LossInPings == main.ERROR:
Jon Hall6aec96b2015-01-19 14:49:31 -08001699 main.log.info( "There are multiple mininet process running" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001700 elif LossInPings == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001701 main.log.info( "No Loss in the pings" )
1702 main.log.report( "No loss of dataplane connectivity" )
1703 utilities.assert_equals(
1704 expect=main.FALSE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001705 actual=LossInPings,
Jon Hall6aec96b2015-01-19 14:49:31 -08001706 onpass="No Loss of connectivity",
1707 onfail="Loss of dataplane connectivity detected" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001708
Jon Hall6aec96b2015-01-19 14:49:31 -08001709 # Test of LeadershipElection
Jon Hall8f89dda2015-01-22 16:03:33 -08001710 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001711 # FIXME: make sure this matches nodes that were restarted
1712 restarted = [ nodes[0].ip_address, nodes[1].ip_address,
1713 nodes[2].ip_address ]
1714
Jon Hall8f89dda2015-01-22 16:03:33 -08001715 leaderResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001716 for cli in CLIs:
1717 leaderN = cli.electionTestLeader()
Jon Hall8f89dda2015-01-22 16:03:33 -08001718 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08001719 if leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001720 # error in response
1721 main.log.report( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001722 "electionTestLeader function, check the" +
Jon Hall6aec96b2015-01-19 14:49:31 -08001723 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001724 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001725 elif leaderN is None:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001726 main.log.report( cli.name +
Jon Hall6aec96b2015-01-19 14:49:31 -08001727 " shows no leader for the election-app was" +
1728 " elected after the old one died" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001729 leaderResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001730 elif leaderN in restarted:
1731 main.log.report( cli.name + " shows " + str( leaderN ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08001732 " as leader for the election-app, but it " +
1733 "was restarted" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001734 leaderResult = main.FALSE
1735 if len( set( leaderList ) ) != 1:
1736 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001737 main.log.error(
1738 "Inconsistent view of leader for the election test app" )
1739 # TODO: print the list
Jon Hall8f89dda2015-01-22 16:03:33 -08001740 if leaderResult:
1741 main.log.report( "Leadership election tests passed( consistent " +
Jon Hall6aec96b2015-01-19 14:49:31 -08001742 "view of leader across listeners and a new " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001743 "leader was re-elected if applicable )" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001744 utilities.assert_equals(
1745 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001746 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001747 onpass="Leadership election passed",
1748 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08001749
Jon Hall58c76b72015-02-23 11:09:24 -08001750 result = ( mastershipCheck and intentCheck and FlowTables and
1751 ( not LossInPings ) and rolesNotNull and leaderResult )
Jon Hall6aec96b2015-01-19 14:49:31 -08001752 result = int( result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001753 if result == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001754 main.log.report( "Constant State Tests Passed" )
1755 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hallfebb1c72015-03-05 13:30:09 -08001756 onpass="Constant State Tests Passed",
1757 onfail="Constant state tests failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001758
Jon Hall6aec96b2015-01-19 14:49:31 -08001759 def CASE8( self, main ):
1760 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001761 Compare topo
Jon Hall6aec96b2015-01-19 14:49:31 -08001762 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001763 import sys
Jon Hall6aec96b2015-01-19 14:49:31 -08001764 # FIXME add this path to params
1765 sys.path.append( "/home/admin/sts" )
1766 # assumes that sts is already in you PYTHONPATH
1767 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -08001768 import json
1769 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001770 assert numControllers, "numControllers not defined"
1771 assert main, "main not defined"
1772 assert utilities.assert_equals, "utilities.assert_equals not defined"
1773 assert CLIs, "CLIs not defined"
1774 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08001775
Jon Hall6aec96b2015-01-19 14:49:31 -08001776 description = "Compare ONOS Topology view to Mininet topology"
1777 main.case( description )
1778 main.log.report( description )
1779 main.step( "Create TestONTopology object" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001780 ctrls = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001781 for node in nodes:
1782 temp = ( node, node.name, node.ip_address, 6633 )
1783 ctrls.append( temp )
1784 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001785
Jon Hall6aec96b2015-01-19 14:49:31 -08001786 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001787 devicesResults = main.TRUE
1788 portsResults = main.TRUE
1789 linksResults = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08001790 hostsResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -08001791 topoResult = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001792 elapsed = 0
Jon Hallffb386d2014-11-21 13:43:38 -08001793 count = 0
Jon Hall6aec96b2015-01-19 14:49:31 -08001794 main.step( "Collecting topology information from ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001795 startTime = time.time()
Jon Hall21270ac2015-02-16 17:59:55 -08001796 # Give time for Gossip to work
Jon Hall8f89dda2015-01-22 16:03:33 -08001797 while topoResult == main.FALSE and elapsed < 60:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001798 count += 1
Jon Hall94fd0472014-12-08 11:52:42 -08001799 if count > 1:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001800 # TODO: Deprecate STS usage
Jon Hall58c76b72015-02-23 11:09:24 -08001801 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall8f89dda2015-01-22 16:03:33 -08001802 cliStart = time.time()
Jon Hall94fd0472014-12-08 11:52:42 -08001803 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001804 threads = []
1805 for i in range( numControllers ):
1806 t = main.Thread( target=CLIs[i].devices,
1807 name="devices-" + str( i ),
1808 args=[ ] )
1809 threads.append( t )
1810 t.start()
1811
1812 for t in threads:
1813 t.join()
1814 devices.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001815 hosts = []
Jon Hall58c76b72015-02-23 11:09:24 -08001816 ipResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001817 threads = []
1818 for i in range( numControllers ):
1819 t = main.Thread( target=CLIs[i].hosts,
1820 name="hosts-" + str( i ),
1821 args=[ ] )
1822 threads.append( t )
1823 t.start()
1824
1825 for t in threads:
1826 t.join()
1827 try:
1828 hosts.append( json.loads( t.result ) )
1829 except ( ValueError, TypeError ):
1830 main.log.exception( "Error parsing hosts results" )
1831 main.log.error( repr( t.result ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08001832 for controller in range( 0, len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001833 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001834 for host in hosts[ controller ]:
Jon Hall58c76b72015-02-23 11:09:24 -08001835 if host is None or host.get( 'ips', [] ) == []:
Jon Hall6aec96b2015-01-19 14:49:31 -08001836 main.log.error(
1837 "DEBUG:Error with host ips on controller" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001838 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001839 ipResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001840 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001841 threads = []
1842 for i in range( numControllers ):
1843 t = main.Thread( target=CLIs[i].ports,
1844 name="ports-" + str( i ),
1845 args=[ ] )
1846 threads.append( t )
1847 t.start()
1848
1849 for t in threads:
1850 t.join()
1851 ports.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001852 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001853 threads = []
1854 for i in range( numControllers ):
1855 t = main.Thread( target=CLIs[i].links,
1856 name="links-" + str( i ),
1857 args=[ ] )
1858 threads.append( t )
1859 t.start()
1860
1861 for t in threads:
1862 t.join()
1863 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001864 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001865 threads = []
1866 for i in range( numControllers ):
1867 t = main.Thread( target=CLIs[i].clusters,
1868 name="clusters-" + str( i ),
1869 args=[ ] )
1870 threads.append( t )
1871 t.start()
1872
1873 for t in threads:
1874 t.join()
1875 clusters.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001876
Jon Hall8f89dda2015-01-22 16:03:33 -08001877 elapsed = time.time() - startTime
1878 cliTime = time.time() - cliStart
1879 print "CLI time: " + str( cliTime )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001880
Jon Hall8f89dda2015-01-22 16:03:33 -08001881 for controller in range( numControllers ):
1882 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001883 if devices[ controller ] or "Error" not in devices[
1884 controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001885 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -08001886 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08001887 json.loads( devices[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001888 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001889 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001890 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001891 actual=currentDevicesResult,
1892 onpass="ONOS" + controllerStr +
1893 " Switches view is correct",
1894 onfail="ONOS" + controllerStr +
1895 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001896
Jon Hall6aec96b2015-01-19 14:49:31 -08001897 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001898 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -08001899 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08001900 json.loads( ports[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001901 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001902 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001903 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001904 actual=currentPortsResult,
1905 onpass="ONOS" + controllerStr +
1906 " ports view is correct",
1907 onfail="ONOS" + controllerStr +
1908 " ports view is incorrect" )
Jon Hall94fd0472014-12-08 11:52:42 -08001909
Jon Hall6aec96b2015-01-19 14:49:31 -08001910 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001911 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -08001912 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08001913 json.loads( links[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001914 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001915 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001916 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001917 actual=currentLinksResult,
1918 onpass="ONOS" + controllerStr +
1919 " links view is correct",
1920 onfail="ONOS" + controllerStr +
1921 " links view is incorrect" )
1922
1923 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1924 currentHostsResult = main.Mininet1.compareHosts(
1925 MNTopo, hosts[ controller ] )
1926 else:
1927 currentHostsResult = main.FALSE
1928 utilities.assert_equals( expect=main.TRUE,
1929 actual=currentHostsResult,
1930 onpass="ONOS" + controllerStr +
1931 " hosts exist in Mininet",
1932 onfail="ONOS" + controllerStr +
1933 " hosts don't match Mininet" )
1934
1935 devicesResults = devicesResults and currentDevicesResult
1936 portsResults = portsResults and currentPortsResult
1937 linksResults = linksResults and currentLinksResult
1938 hostsResults = hostsResults and currentHostsResult
Jon Hall94fd0472014-12-08 11:52:42 -08001939
Jon Hall529a37f2015-01-28 10:02:00 -08001940 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08001941
Jon Hall6aec96b2015-01-19 14:49:31 -08001942 # hosts
Jon Hall8f89dda2015-01-22 16:03:33 -08001943 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001944 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001945 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001946 if "Error" not in hosts[ controller ]:
1947 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001948 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001949 else: # hosts not consistent
Jon Hall8f89dda2015-01-22 16:03:33 -08001950 main.log.report( "hosts from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001951 " is inconsistent with ONOS1" )
1952 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001953 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001954
1955 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001956 main.log.report( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001957 controllerStr )
1958 consistentHostsResult = main.FALSE
1959 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001960 " hosts response: " +
1961 repr( hosts[ controller ] ) )
1962 utilities.assert_equals(
1963 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001964 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001965 onpass="Hosts view is consistent across all ONOS nodes",
1966 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08001967
Jon Hall6aec96b2015-01-19 14:49:31 -08001968 # Strongly connected clusters of devices
Jon Hall8f89dda2015-01-22 16:03:33 -08001969 consistentClustersResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001970 for controller in range( len( clusters ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001971 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001972 if "Error" not in clusters[ controller ]:
1973 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001974 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001975 else: # clusters not consistent
1976 main.log.report( "clusters from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001977 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001978 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001979 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001980
1981 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001982 main.log.report( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001983 "from ONOS" + controllerStr )
1984 consistentClustersResult = main.FALSE
1985 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001986 " clusters response: " +
1987 repr( clusters[ controller ] ) )
1988 utilities.assert_equals(
1989 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001990 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001991 onpass="Clusters view is consistent across all ONOS nodes",
1992 onfail="ONOS nodes have different views of clusters" )
1993 # there should always only be one cluster
Jon Hall5cfd23c2015-03-19 11:40:57 -07001994 try:
1995 numClusters = len( json.loads( clusters[ 0 ] ) )
1996 except ( ValueError, TypeError ):
1997 main.log.exception( "Error parsing clusters[0]: " +
1998 repr( clusters[0] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001999 clusterResults = main.FALSE
2000 if numClusters == 1:
2001 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002002 utilities.assert_equals(
2003 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08002004 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08002005 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08002006 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08002007
Jon Hall8f89dda2015-01-22 16:03:33 -08002008 topoResult = ( devicesResults and portsResults and linksResults
Jon Hall58c76b72015-02-23 11:09:24 -08002009 and hostsResults and consistentHostsResult
2010 and consistentClustersResult and clusterResults
2011 and ipResult )
Jon Hall94fd0472014-12-08 11:52:42 -08002012
Jon Hall8f89dda2015-01-22 16:03:33 -08002013 topoResult = topoResult and int( count <= 2 )
2014 note = "note it takes about " + str( int( cliTime ) ) + \
2015 " seconds for the test to make all the cli calls to fetch " +\
2016 "the topology from each ONOS instance"
Jon Hall1b8f54a2015-02-04 13:24:20 -08002017 main.log.info(
Jon Hall8f89dda2015-01-22 16:03:33 -08002018 "Very crass estimate for topology discovery/convergence( " +
2019 str( note ) + " ): " + str( elapsed ) + " seconds, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002020 str( count ) + " tries" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002021 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08002022 onpass="Topology Check Test successful",
2023 onfail="Topology Check Test NOT successful" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002024 if topoResult == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002025 main.log.report( "ONOS topology view matches Mininet topology" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002026
Jon Hall6aec96b2015-01-19 14:49:31 -08002027 def CASE9( self, main ):
2028 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002029 Link s3-s28 down
Jon Hall6aec96b2015-01-19 14:49:31 -08002030 """
2031 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002032 assert numControllers, "numControllers not defined"
2033 assert main, "main not defined"
2034 assert utilities.assert_equals, "utilities.assert_equals not defined"
2035 assert CLIs, "CLIs not defined"
2036 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002037 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002038
Jon Hall8f89dda2015-01-22 16:03:33 -08002039 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002040
Jon Hall6aec96b2015-01-19 14:49:31 -08002041 description = "Turn off a link to ensure that Link Discovery " +\
Jon Hall58c76b72015-02-23 11:09:24 -08002042 "is working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002043 main.log.report( description )
2044 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002045
Jon Hall6aec96b2015-01-19 14:49:31 -08002046 main.step( "Kill Link between s3 and s28" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002047 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
Jon Hall58c76b72015-02-23 11:09:24 -08002048 main.log.info( "Waiting " + str( linkSleep ) +
2049 " seconds for link down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002050 time.sleep( linkSleep )
2051 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002052 onpass="Link down successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002053 onfail="Failed to bring link down" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002054 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08002055
Jon Hall6aec96b2015-01-19 14:49:31 -08002056 def CASE10( self, main ):
2057 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002058 Link s3-s28 up
Jon Hall6aec96b2015-01-19 14:49:31 -08002059 """
2060 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002061 assert numControllers, "numControllers not defined"
2062 assert main, "main not defined"
2063 assert utilities.assert_equals, "utilities.assert_equals not defined"
2064 assert CLIs, "CLIs not defined"
2065 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002066 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002067
Jon Hall8f89dda2015-01-22 16:03:33 -08002068 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002069
Jon Hall6aec96b2015-01-19 14:49:31 -08002070 description = "Restore a link to ensure that Link Discovery is " + \
Jon Hall63604932015-02-26 17:09:50 -08002071 "working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002072 main.log.report( description )
2073 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002074
Jon Hall6aec96b2015-01-19 14:49:31 -08002075 main.step( "Bring link between s3 and s28 back up" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002076 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
Jon Hall58c76b72015-02-23 11:09:24 -08002077 main.log.info( "Waiting " + str( linkSleep ) +
2078 " seconds for link up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002079 time.sleep( linkSleep )
2080 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002081 onpass="Link up successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002082 onfail="Failed to bring link up" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002083 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08002084
Jon Hall6aec96b2015-01-19 14:49:31 -08002085 def CASE11( self, main ):
2086 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002087 Switch Down
Jon Hall6aec96b2015-01-19 14:49:31 -08002088 """
2089 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002090 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002091 assert numControllers, "numControllers not defined"
2092 assert main, "main not defined"
2093 assert utilities.assert_equals, "utilities.assert_equals not defined"
2094 assert CLIs, "CLIs not defined"
2095 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08002096
Jon Hall8f89dda2015-01-22 16:03:33 -08002097 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002098
2099 description = "Killing a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002100 main.log.report( description )
2101 main.case( description )
2102 switch = main.params[ 'kill' ][ 'switch' ]
2103 switchDPID = main.params[ 'kill' ][ 'dpid' ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08002104
Jon Hall6aec96b2015-01-19 14:49:31 -08002105 # TODO: Make this switch parameterizable
2106 main.step( "Kill " + switch )
2107 main.log.report( "Deleting " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002108 main.Mininet1.delSwitch( switch )
2109 main.log.info( "Waiting " + str( switchSleep ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002110 " seconds for switch down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002111 time.sleep( switchSleep )
2112 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002113 # Peek at the deleted switch
2114 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002115 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002116 if device and device[ 'available' ] is False:
Jon Hall94fd0472014-12-08 11:52:42 -08002117 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002118 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002119 onpass="Kill switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002120 onfail="Failed to kill switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002121
Jon Hall6aec96b2015-01-19 14:49:31 -08002122 def CASE12( self, main ):
2123 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002124 Switch Up
Jon Hall6aec96b2015-01-19 14:49:31 -08002125 """
2126 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002127 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002128 assert numControllers, "numControllers not defined"
2129 assert main, "main not defined"
2130 assert utilities.assert_equals, "utilities.assert_equals not defined"
2131 assert CLIs, "CLIs not defined"
2132 assert nodes, "nodes not defined"
2133 assert ONOS1Port, "ONOS1Port not defined"
2134 assert ONOS2Port, "ONOS2Port not defined"
2135 assert ONOS3Port, "ONOS3Port not defined"
2136 assert ONOS4Port, "ONOS4Port not defined"
2137 assert ONOS5Port, "ONOS5Port not defined"
2138 assert ONOS6Port, "ONOS6Port not defined"
2139 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall669173b2014-12-17 11:36:30 -08002140
Jon Hall8f89dda2015-01-22 16:03:33 -08002141 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall6aec96b2015-01-19 14:49:31 -08002142 switch = main.params[ 'kill' ][ 'switch' ]
2143 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2144 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002145 description = "Adding a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002146 main.log.report( description )
2147 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002148
Jon Hall6aec96b2015-01-19 14:49:31 -08002149 main.step( "Add back " + switch )
2150 main.log.report( "Adding back " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002151 main.Mininet1.addSwitch( switch, dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002152 for peer in links:
Jon Hall8f89dda2015-01-22 16:03:33 -08002153 main.Mininet1.addLink( switch, peer )
Jon Hall58c76b72015-02-23 11:09:24 -08002154 main.Mininet1.assignSwController( sw=switch.split( 's' )[ 1 ],
2155 count=numControllers,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002156 ip1=nodes[ 0 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002157 port1=ONOS1Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002158 ip2=nodes[ 1 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002159 port2=ONOS2Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002160 ip3=nodes[ 2 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002161 port3=ONOS3Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002162 ip4=nodes[ 3 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002163 port4=ONOS4Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002164 ip5=nodes[ 4 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002165 port5=ONOS5Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002166 ip6=nodes[ 5 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002167 port6=ONOS6Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002168 ip7=nodes[ 6 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002169 port7=ONOS7Port )
2170 main.log.info( "Waiting " + str( switchSleep ) +
2171 " seconds for switch up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002172 time.sleep( switchSleep )
2173 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002174 # Peek at the deleted switch
2175 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002176 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002177 if device and device[ 'available' ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002178 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002179 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002180 onpass="add switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002181 onfail="Failed to add switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002182
Jon Hall6aec96b2015-01-19 14:49:31 -08002183 def CASE13( self, main ):
2184 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002185 Clean up
Jon Hall6aec96b2015-01-19 14:49:31 -08002186 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002187 import os
2188 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002189 assert numControllers, "numControllers not defined"
2190 assert main, "main not defined"
2191 assert utilities.assert_equals, "utilities.assert_equals not defined"
2192 assert CLIs, "CLIs not defined"
2193 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002194
2195 # printing colors to terminal
Jon Hall5cfd23c2015-03-19 11:40:57 -07002196 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2197 'blue': '\033[94m', 'green': '\033[92m',
2198 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
Jon Hall73cf9cc2014-11-20 22:28:38 -08002199 description = "Test Cleanup"
Jon Hall6aec96b2015-01-19 14:49:31 -08002200 main.log.report( description )
2201 main.case( description )
2202 main.step( "Killing tcpdumps" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002203 main.Mininet2.stopTcpdump()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002204
Jon Hall6aec96b2015-01-19 14:49:31 -08002205 main.step( "Copying MN pcap and ONOS log files to test station" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002206 testname = main.TEST
Jon Hall8f89dda2015-01-22 16:03:33 -08002207 teststationUser = main.params[ 'TESTONUSER' ]
2208 teststationIP = main.params[ 'TESTONIP' ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002209 # NOTE: MN Pcap file is being saved to ~/packet_captures
Jon Hall73cf9cc2014-11-20 22:28:38 -08002210 # scp this file as MN and TestON aren't necessarily the same vm
Jon Hall6aec96b2015-01-19 14:49:31 -08002211 # FIXME: scp
2212 # mn files
2213 # TODO: Load these from params
2214 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002215 logFolder = "/opt/onos/log/"
2216 logFiles = [ "karaf.log", "karaf.log.1" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002217 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002218 dstDir = "~/packet_captures/"
2219 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002220 for node in nodes:
2221 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2222 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002223 teststationUser + "@" +
2224 teststationIP + ":" +
2225 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002226 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002227 main.ONOSbench.handle.expect( "\$" )
2228
Jon Hall6aec96b2015-01-19 14:49:31 -08002229 # std*.log's
2230 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002231 logFolder = "/opt/onos/var/"
2232 logFiles = [ "stderr.log", "stdout.log" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002233 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002234 dstDir = "~/packet_captures/"
2235 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002236 for node in nodes:
2237 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2238 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002239 teststationUser + "@" +
2240 teststationIP + ":" +
2241 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002242 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002243 main.ONOSbench.handle.expect( "\$" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002244 # sleep so scp can finish
2245 time.sleep( 10 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002246
2247 main.step( "Stopping Mininet" )
Jon Hall58c76b72015-02-23 11:09:24 -08002248 main.Mininet1.stopNet()
Jon Hall5cfd23c2015-03-19 11:40:57 -07002249
2250 main.step( "Checking ONOS Logs for errors" )
2251 for node in nodes:
2252 print colors[ 'purple' ] + "Checking logs for errors on " + \
2253 node.name + ":" + colors[ 'end' ]
2254 print main.ONOSbench.checkLogs( node.ip_address )
2255
Jon Hall6aec96b2015-01-19 14:49:31 -08002256 main.step( "Packing and rotating pcap archives" )
2257 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002258
Jon Hall6aec96b2015-01-19 14:49:31 -08002259 # TODO: actually check something here
2260 utilities.assert_equals( expect=main.TRUE, actual=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002261 onpass="Test cleanup successful",
2262 onfail="Test cleanup NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002263
Jon Hall6aec96b2015-01-19 14:49:31 -08002264 def CASE14( self, main ):
2265 """
Jon Hall669173b2014-12-17 11:36:30 -08002266 start election app on all onos nodes
Jon Hall6aec96b2015-01-19 14:49:31 -08002267 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07002268 import time
2269 assert numControllers, "numControllers not defined"
2270 assert main, "main not defined"
2271 assert utilities.assert_equals, "utilities.assert_equals not defined"
2272 assert CLIs, "CLIs not defined"
2273 assert nodes, "nodes not defined"
2274
Jon Hall8f89dda2015-01-22 16:03:33 -08002275 leaderResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002276 # install app on onos 1
2277 main.log.info( "Install leadership election app" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002278 main.ONOScli1.featureInstall( "onos-app-election" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002279 leader = nodes[0].ip_address
Jon Hall6aec96b2015-01-19 14:49:31 -08002280 # wait for election
2281 # check for leader
Jon Hall5cfd23c2015-03-19 11:40:57 -07002282 for i in range(2): # try this twice
2283 leader1 = main.ONOScli1.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08002284 # verify leader is ONOS1
Jon Hall5cfd23c2015-03-19 11:40:57 -07002285 if leader1 == leader:
2286 # all is well
2287 # pass
2288 if i > 0:
2289 main.log.warn( "It took ONOS sometime for leader to be" +
2290 "elected" )
2291 main.log.debug( "I don't think this should be happening" )
2292 break
2293 elif leader1 is None:
2294 # No leader elected
2295 main.log.report( "No leader was elected" )
2296 leaderResult = main.FALSE
2297 elif leader1 == main.FALSE:
2298 # error in response
2299 # TODO: add check for "Command not found:" in the driver, this
2300 # means the app isn't loaded
2301 main.log.report( "Something is wrong with electionTestLeader" +
2302 " function, check the error logs" )
2303 leaderResult = main.FALSE
2304 else:
2305 # error in response
2306 main.log.report(
2307 "Unexpected response from electionTestLeader function:'" +
2308 str( leader1 ) + "'" )
2309 leaderResult = main.FALSE
2310 time.sleep(2)
2311 # install on other nodes and check for leader.
2312 # Leader should be ONOS1 and each app should show the same leader
2313 for cli in CLIs[ 1: ]:
2314 cli.featureInstall( "onos-app-election" )
2315 leaderN = cli.electionTestLeader()
2316 # verify leader is ONOS1
2317 if leaderN == leader:
Jon Hall6aec96b2015-01-19 14:49:31 -08002318 # all is well
Jon Hall669173b2014-12-17 11:36:30 -08002319 pass
2320 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002321 # error in response
2322 # TODO: add check for "Command not found:" in the driver, this
2323 # means the app isn't loaded
2324 main.log.report( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002325 "electionTestLeader function, check the" +
Jon Hall6aec96b2015-01-19 14:49:31 -08002326 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002327 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002328 elif leader != leaderN:
Jon Hall8f89dda2015-01-22 16:03:33 -08002329 leaderResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002330 main.log.report( cli.name + " sees " + str( leaderN ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002331 " as the leader of the election app. Leader" +
2332 " should be " +
2333 str( leader ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08002334 if leaderResult:
Jon Hall6aec96b2015-01-19 14:49:31 -08002335 main.log.report( "Leadership election tests passed( consistent " +
2336 "view of leader across listeners and a leader " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002337 "was elected )" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002338 utilities.assert_equals(
2339 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002340 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002341 onpass="Leadership election passed",
2342 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002343
Jon Hall6aec96b2015-01-19 14:49:31 -08002344 def CASE15( self, main ):
2345 """
Jon Hall669173b2014-12-17 11:36:30 -08002346 Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -08002347 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07002348 assert numControllers, "numControllers not defined"
2349 assert main, "main not defined"
2350 assert utilities.assert_equals, "utilities.assert_equals not defined"
2351 assert CLIs, "CLIs not defined"
2352 assert nodes, "nodes not defined"
2353
Jon Hall8f89dda2015-01-22 16:03:33 -08002354 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002355 description = "Check that Leadership Election is still functional"
Jon Hall6aec96b2015-01-19 14:49:31 -08002356 main.log.report( description )
2357 main.case( description )
2358 main.step( "Find current leader and withdraw" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002359 leader = main.ONOScli1.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08002360 # TODO: do some sanity checking on leader before using it
Jon Hall8f89dda2015-01-22 16:03:33 -08002361 withdrawResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002362 if leader is None or leader == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002363 main.log.report(
2364 "Leader for the election app should be an ONOS node," +
Jon Hall58c76b72015-02-23 11:09:24 -08002365 "instead got '" + str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002366 leaderResult = main.FALSE
Jon Hall63604932015-02-26 17:09:50 -08002367 oldLeader = None
Jon Hall5cfd23c2015-03-19 11:40:57 -07002368 for i in range( len( CLIs ) ):
2369 if leader == nodes[ i ].ip_address:
2370 oldLeader = CLIs[ i ]
2371 break
Jon Hall63604932015-02-26 17:09:50 -08002372 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002373 main.log.error( "Leader election, could not find current leader" )
Jon Hall63604932015-02-26 17:09:50 -08002374 if oldLeader:
2375 withdrawResult = oldLeader.electionTestWithdraw()
Jon Hall6aec96b2015-01-19 14:49:31 -08002376 utilities.assert_equals(
2377 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002378 actual=withdrawResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002379 onpass="App was withdrawn from election",
2380 onfail="App was not withdrawn from election" )
Jon Hall669173b2014-12-17 11:36:30 -08002381
Jon Hall6aec96b2015-01-19 14:49:31 -08002382 main.step( "Make sure new leader is elected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002383 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002384 for cli in CLIs:
2385 leaderN = cli.electionTestLeader()
2386 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08002387 if leaderN == leader:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002388 main.log.report( cli.name + " still sees " + str( leader ) +
2389 " as leader after they withdrew" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002390 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002391 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002392 # error in response
2393 # TODO: add check for "Command not found:" in the driver, this
Jon Hall5cfd23c2015-03-19 11:40:57 -07002394 # means the app isn't loaded
Jon Hall6aec96b2015-01-19 14:49:31 -08002395 main.log.report( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002396 "electionTestLeader function, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002397 "check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002398 leaderResult = main.FALSE
2399 consistentLeader = main.FALSE
2400 if len( set( leaderList ) ) == 1:
Jon Hall6aec96b2015-01-19 14:49:31 -08002401 main.log.info( "Each Election-app sees '" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002402 str( leaderList[ 0 ] ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002403 "' as the leader" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002404 consistentLeader = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002405 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08002406 main.log.report(
2407 "Inconsistent responses for leader of Election-app:" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002408 for n in range( len( leaderList ) ):
Jon Hall6aec96b2015-01-19 14:49:31 -08002409 main.log.report( "ONOS" + str( n + 1 ) + " response: " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002410 str( leaderList[ n ] ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002411 leaderResult = leaderResult and consistentLeader
Jon Hall8f89dda2015-01-22 16:03:33 -08002412 if leaderResult:
2413 main.log.report( "Leadership election tests passed( consistent " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002414 "view of leader across listeners and a new " +
2415 "leader was elected when the old leader " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002416 "resigned )" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002417 utilities.assert_equals(
2418 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002419 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002420 onpass="Leadership election passed",
2421 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002422
Jon Hall58c76b72015-02-23 11:09:24 -08002423 main.step( "Run for election on old leader( just so everyone " +
2424 "is in the hat )" )
Jon Hall63604932015-02-26 17:09:50 -08002425 if oldLeader:
2426 runResult = oldLeader.electionTestRun()
2427 else:
2428 runResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002429 utilities.assert_equals(
2430 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002431 actual=runResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002432 onpass="App re-ran for election",
2433 onfail="App failed to run for election" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002434 if consistentLeader == main.TRUE:
2435 afterRun = main.ONOScli1.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08002436 # verify leader didn't just change
Jon Hall8f89dda2015-01-22 16:03:33 -08002437 if afterRun == leaderList[ 0 ]:
2438 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002439 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002440 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002441 # TODO: assert on run and withdraw results?
Jon Hall669173b2014-12-17 11:36:30 -08002442
Jon Hall6aec96b2015-01-19 14:49:31 -08002443 utilities.assert_equals(
2444 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002445 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002446 onpass="Leadership election passed",
2447 onfail="Something went wrong with Leadership election after " +
2448 "the old leader re-ran for election" )