blob: 5b3e125af61ae58e44bd3724fd559cf0b64fd215 [file] [log] [blame]
Jon Hall6aec96b2015-01-19 14:49:31 -08001"""
Jon Hallb1290e82014-11-18 16:17:48 -05002Description: This test is to determine if the HA test setup is
3 working correctly. There are no failures so this test should
4 have a 100% pass rate
5
6List of test cases:
7CASE1: Compile ONOS and push it to the test machines
8CASE2: Assign mastership to controllers
9CASE3: Assign intents
10CASE4: Ping across added host intents
11CASE5: Reading state of ONOS
12CASE6: The Failure case. Since this is the Sanity test, we do nothing.
Jon Hall368769f2014-11-19 15:43:35 -080013CASE7: Check state after control plane failure
Jon Hallb1290e82014-11-18 16:17:48 -050014CASE8: Compare topo
15CASE9: Link s3-s28 down
16CASE10: Link s3-s28 up
17CASE11: Switch down
18CASE12: Switch up
19CASE13: Clean up
Jon Hall669173b2014-12-17 11:36:30 -080020CASE14: start election app on all onos nodes
21CASE15: Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -080022"""
Jon Hall8f89dda2015-01-22 16:03:33 -080023
24
Jon Hallb1290e82014-11-18 16:17:48 -050025class HATestSanity:
26
Jon Hall6aec96b2015-01-19 14:49:31 -080027 def __init__( self ):
Jon Hallb1290e82014-11-18 16:17:48 -050028 self.default = ''
29
Jon Hall6aec96b2015-01-19 14:49:31 -080030 def CASE1( self, main ):
31 """
Jon Hallb1290e82014-11-18 16:17:48 -050032 CASE1 is to compile ONOS and push it to the test machines
33
34 Startup sequence:
Jon Hallb1290e82014-11-18 16:17:48 -050035 cell <name>
36 onos-verify-cell
37 NOTE: temporary - onos-remove-raft-logs
Jon Hall58c76b72015-02-23 11:09:24 -080038 onos-uninstall
39 start mininet
40 git pull
41 mvn clean install
42 onos-package
Jon Hallb1290e82014-11-18 16:17:48 -050043 onos-install -f
44 onos-wait-for-start
Jon Hall58c76b72015-02-23 11:09:24 -080045 start cli sessions
46 start tcpdump
Jon Hall6aec96b2015-01-19 14:49:31 -080047 """
48 main.log.report( "ONOS HA Sanity test - initialization" )
49 main.case( "Setting up test environment" )
50 # TODO: save all the timers and output them for plotting
Jon Hallb1290e82014-11-18 16:17:48 -050051
Jon Hall65844a32015-03-09 19:09:37 -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 Hall5cfd23c2015-03-19 11:40:57 -070069
Jon Hall65844a32015-03-09 19:09:37 -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 ) ) )
Jon Hallb1290e82014-11-18 16:17:48 -050087
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 Hall368769f2014-11-19 15:43:35 -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 Hall65844a32015-03-09 19:09:37 -070095
Jon Hall6aec96b2015-01-19 14:49:31 -080096 main.log.report( "Uninstalling ONOS" )
Jon Hall65844a32015-03-09 19:09:37 -070097 for node in nodes:
98 main.ONOSbench.onosUninstall( node.ip_address )
Jon Hallb1290e82014-11-18 16:17:48 -050099
Jon Hall8f89dda2015-01-22 16:03:33 -0800100 cleanInstallResult = main.TRUE
101 gitPullResult = main.TRUE
Jon Hallb1290e82014-11-18 16:17:48 -0500102
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 Hallb1290e82014-11-18 16:17:48 -0500113
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 Hallb1290e82014-11-18 16:17:48 -0500120
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 Hallb1290e82014-11-18 16:17:48 -0500123
Jon Hall6aec96b2015-01-19 14:49:31 -0800124 main.step( "Installing ONOS package" )
Jon Hall65844a32015-03-09 19:09:37 -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 Hallb1290e82014-11-18 16:17:48 -0500130
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 Hall65844a32015-03-09 19:09:37 -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 Hallffb386d2014-11-21 13:43:38 -0800142 break
Jon Hallb1290e82014-11-18 16:17:48 -0500143
Jon Hall65844a32015-03-09 19:09:37 -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,
Jon Hall65844a32015-03-09 19:09:37 -0700149 name="startOnosCli-" + str( i ),
150 args=[nodes[i].ip_address] )
151 threads.append( t )
152 t.start()
Jon Hall65844a32015-03-09 19:09:37 -0700153
154 for t in threads:
155 t.join()
156 cliResults = cliResults and t.result
Jon Hallb1290e82014-11-18 16:17:48 -0500157
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 Hallb1290e82014-11-18 16:17:48 -0500164
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 Hallb1290e82014-11-18 16:17:48 -0500168
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 Hallb1290e82014-11-18 16:17:48 -0500172
Jon Hall8f89dda2015-01-22 16:03:33 -0800173 if case1Result == main.FALSE:
Jon Hallffb386d2014-11-21 13:43:38 -0800174 main.cleanup()
175 main.exit()
Jon Hallb1290e82014-11-18 16:17:48 -0500176
Jon Hall6aec96b2015-01-19 14:49:31 -0800177 def CASE2( self, main ):
178 """
Jon Hallb1290e82014-11-18 16:17:48 -0500179 Assign mastership to controllers
Jon Hall6aec96b2015-01-19 14:49:31 -0800180 """
Jon Hallb1290e82014-11-18 16:17:48 -0500181 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 Hallb1290e82014-11-18 16:17:48 -0500194
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 Hallb1290e82014-11-18 16:17:48 -0500198
Jon Hall65844a32015-03-09 19:09:37 -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 Hall65844a32015-03-09 19:09:37 -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 Hallb1290e82014-11-18 16:17:48 -0500212
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 Hall65844a32015-03-09 19:09:37 -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 Hall65844a32015-03-09 19:09:37 -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 Hall65844a32015-03-09 19:09:37 -0700243 ip )
Jon Hall6aec96b2015-01-19 14:49:31 -0800244 # Check assignment
Jon Hall65844a32015-03-09 19:09:37 -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 Hall65844a32015-03-09 19:09:37 -0700255 ip )
Jon Hall6aec96b2015-01-19 14:49:31 -0800256 # Check assignment
Jon Hall65844a32015-03-09 19:09:37 -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 Hall65844a32015-03-09 19:09:37 -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 Hall65844a32015-03-09 19:09:37 -0700268 ip )
Jon Hall58c76b72015-02-23 11:09:24 -0800269 # Check assignment
Jon Hall65844a32015-03-09 19:09:37 -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 Hall65844a32015-03-09 19:09:37 -0700280 ip )
Jon Hall58c76b72015-02-23 11:09:24 -0800281 # Check assignment
Jon Hall65844a32015-03-09 19:09:37 -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 Hall65844a32015-03-09 19:09:37 -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 Hall65844a32015-03-09 19:09:37 -0700293 ip )
Jon Hall58c76b72015-02-23 11:09:24 -0800294 # Check assignment
Jon Hall65844a32015-03-09 19:09:37 -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 Hall65844a32015-03-09 19:09:37 -0700305 ip )
Jon Hall58c76b72015-02-23 11:09:24 -0800306 # Check assignment
Jon Hall65844a32015-03-09 19:09:37 -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 Hall65844a32015-03-09 19:09:37 -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 Hall65844a32015-03-09 19:09:37 -0700318 ip )
Jon Hall58c76b72015-02-23 11:09:24 -0800319 # Check assignment
Jon Hall65844a32015-03-09 19:09:37 -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 Hall65844a32015-03-09 19:09:37 -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 Hall65844a32015-03-09 19:09:37 -0700332 ip )
Jon Hall58c76b72015-02-23 11:09:24 -0800333 # Check assignment
Jon Hall65844a32015-03-09 19:09:37 -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 Hall65844a32015-03-09 19:09:37 -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 Hall65844a32015-03-09 19:09:37 -0700344 ip )
Jon Hall58c76b72015-02-23 11:09:24 -0800345 # Check assignment
Jon Hall65844a32015-03-09 19:09:37 -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 Hall65844a32015-03-09 19:09:37 -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 Hall65844a32015-03-09 19:09:37 -0700358 ip )
Jon Hall58c76b72015-02-23 11:09:24 -0800359 # Check assignment
Jon Hall65844a32015-03-09 19:09:37 -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 Hall6aec96b2015-01-19 14:49:31 -0800381 onpass="Switch mastership correctly assigned",
382 onfail="Error in (re)assigning switch" +
Jon Hall8f89dda2015-01-22 16:03:33 -0800383 " mastership" )
Jon Hallb1290e82014-11-18 16:17:48 -0500384
Jon Hall6aec96b2015-01-19 14:49:31 -0800385 def CASE3( self, main ):
Jon Hallb1290e82014-11-18 16:17:48 -0500386 """
387 Assign intents
Jon Hallb1290e82014-11-18 16:17:48 -0500388 """
389 import time
Jon Hall58c76b72015-02-23 11:09:24 -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 Hallb1290e82014-11-18 16:17:48 -0500398
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 Hallb1290e82014-11-18 16:17:48 -0500401
Jon Hall6aec96b2015-01-19 14:49:31 -0800402 # install onos-app-fwd
403 main.log.info( "Install reactive forwarding app" )
Jon Hall65844a32015-03-09 19:09:37 -0700404 appResults = main.TRUE
405 threads = []
406 for i in range( numControllers ):
407 t = main.Thread( target=CLIs[i].featureInstall,
Jon Hall65844a32015-03-09 19:09:37 -0700408 name="featureInstall-" + str( i ),
409 args=["onos-app-fwd"] )
410 threads.append( t )
411 t.start()
Jon Hall65844a32015-03-09 19:09:37 -0700412
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 Hallb1290e82014-11-18 16:17:48 -0500429
Jon Hall6aec96b2015-01-19 14:49:31 -0800430 # uninstall onos-app-fwd
431 main.log.info( "Uninstall reactive forwarding app" )
Jon Hall65844a32015-03-09 19:09:37 -0700432 threads = []
433 for i in range( numControllers ):
434 t = main.Thread( target=CLIs[i].featureUninstall,
Jon Hall65844a32015-03-09 19:09:37 -0700435 name="featureUninstall-" + str( i ),
436 args=["onos-app-fwd"] )
437 threads.append( t )
438 t.start()
Jon Hall65844a32015-03-09 19:09:37 -0700439
440 for t in threads:
441 t.join()
442 appResults = appResults and t.result
443
Jon Hall6aec96b2015-01-19 14:49:31 -0800444 # timeout for fwd flows
Jon Hall5cfd23c2015-03-19 11:40:57 -0700445 time.sleep( 11 )
Jon Hallb1290e82014-11-18 16:17:48 -0500446
Jon Hall5cfd23c2015-03-19 11:40:57 -0700447 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
Jon Hall5cfd23c2015-03-19 11:40:57 -0700461 host1Dict = main.ONOScli1.getHost( host1 )
462 host2Dict = main.ONOScli1.getHost( host2 )
Jon Hall1b8f54a2015-02-04 13:24:20 -0800463 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
Jon Hall5cfd23c2015-03-19 11:40:57 -0700490 # FIXME: DEBUG
491 intentStart = time.time()
Jon Hall58c76b72015-02-23 11:09:24 -0800492 onosIds = main.ONOScli1.getAllIntentsId()
493 main.log.info( "Submitted intents: " + str( intentIds ) )
494 main.log.info( "Intents in ONOS: " + str( onosIds ) )
495 for intent in intentIds:
496 if intent in onosIds:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700497 pass # intent submitted is in onos
Jon Hall58c76b72015-02-23 11:09:24 -0800498 else:
499 intentAddResult = False
Jon Hall5cfd23c2015-03-19 11:40:57 -0700500 # FIXME: DEBUG
501 if intentAddResult:
502 intentStop = time.time()
503 else:
504 intentStop = None
Jon Hall1b8f54a2015-02-04 13:24:20 -0800505 # Print the intent states
Jon Hall58c76b72015-02-23 11:09:24 -0800506 intents = main.ONOScli1.intents()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800507 intentStates = []
Jon Hall65844a32015-03-09 19:09:37 -0700508 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800509 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
510 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700511 try:
512 for intent in json.loads( intents ):
513 state = intent.get( 'state', None )
514 if "INSTALLED" not in state:
515 installedCheck = False
516 intentId = intent.get( 'id', None )
517 intentStates.append( ( intentId, state ) )
518 except ( ValueError, TypeError ):
519 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800520 # add submitted intents not in the store
521 tmplist = [ i for i, s in intentStates ]
522 missingIntents = False
523 for i in intentIds:
524 if i not in tmplist:
525 intentStates.append( ( i, " - " ) )
526 missingIntents = True
527 intentStates.sort()
528 for i, s in intentStates:
529 count += 1
530 main.log.info( "%-6s%-15s%-15s" %
531 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700532 leaders = main.ONOScli1.leaders()
533 try:
534 if leaders:
535 parsedLeaders = json.loads( leaders )
536 main.log.warn( json.dumps( parsedLeaders,
537 sort_keys=True,
538 indent=4,
539 separators=( ',', ': ' ) ) )
540 # check for all intent partitions
541 # check for election
542 topics = []
543 for i in range( 14 ):
544 topics.append( "intent-partition-" + str( i ) )
545 # FIXME: this should only be after we start the app
546 # FIXME: move this to the election test sections
547 topics.append( "org.onosproject.election" )
548 main.log.debug( topics )
549 ONOStopics = [ j['topic'] for j in parsedLeaders ]
550 for topic in topics:
551 if topic not in ONOStopics:
552 main.log.error( "Error: " + topic +
553 " not in leaders" )
554 else:
555 main.log.error( "leaders() returned None" )
556 except ( ValueError, TypeError ):
557 main.log.exception( "Error parsing leaders" )
558 main.log.error( repr( leaders ) )
559 partitions = main.ONOScli1.partitions()
560 try:
561 if partitions :
562 parsedPartitions = json.loads( partitions )
563 main.log.warn( json.dumps( parsedPartitions,
564 sort_keys=True,
565 indent=4,
566 separators=( ',', ': ' ) ) )
567 # TODO check for a leader in all paritions
568 # TODO check for consistency among nodes
569 else:
570 main.log.error( "partitions() returned None" )
571 except ( ValueError, TypeError ):
572 main.log.exception( "Error parsing partitions" )
573 main.log.error( repr( partitions ) )
Jon Hall63604932015-02-26 17:09:50 -0800574 pendingMap = main.ONOScli1.pendingMap()
Jon Hall5cfd23c2015-03-19 11:40:57 -0700575 try:
576 if pendingMap :
577 parsedPending = json.loads( pendingMap )
578 main.log.warn( json.dumps( parsedPending,
579 sort_keys=True,
580 indent=4,
581 separators=( ',', ': ' ) ) )
582 # TODO check something here?
583 else:
584 main.log.error( "pendingMap() returned None" )
585 except ( ValueError, TypeError ):
586 main.log.exception( "Error parsing pending map" )
587 main.log.error( repr( pendingMap ) )
588
Jon Hall58c76b72015-02-23 11:09:24 -0800589 intentAddResult = bool( pingResult and hostResult and intentAddResult
Jon Hall63604932015-02-26 17:09:50 -0800590 and not missingIntents and installedCheck )
Jon Hall6aec96b2015-01-19 14:49:31 -0800591 utilities.assert_equals(
592 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -0800593 actual=intentAddResult,
594 onpass="Pushed host intents to ONOS",
595 onfail="Error in pushing host intents to ONOS" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700596 for i in range(100):
597 onosIds = main.ONOScli1.getAllIntentsId()
598 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
599 main.log.info( "Intents in ONOS: " + str( sorted( onosIds ) ) )
600 if sorted(onosIds) == sorted(intentIds):
601 break
602 else:
603 time.sleep(1)
604 # FIXME: DEBUG
605 if not intentStop:
606 intentStop = time.time()
607 gossipTime = intentStop - intentStart
608 main.log.info( "It took about " + str( gossipTime ) +
609 " seconds for all intents to appear on ONOS1" )
610 # FIXME: make this time configurable/calculate based off of # of nodes
611 # and gossip rounds
612 utilities.assert_greater_equals(
613 expect=30, actual=gossipTime,
614 onpass="ECM anti-entropy for intents worked within " +
615 "expected time",
616 onfail="Intent ECM anti-entropy took too long" )
Jon Hall58c76b72015-02-23 11:09:24 -0800617
Jon Hall63604932015-02-26 17:09:50 -0800618 if not intentAddResult or "key" in pendingMap:
Jon Hall58c76b72015-02-23 11:09:24 -0800619 import time
Jon Hall63604932015-02-26 17:09:50 -0800620 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800621 main.log.info( "Sleeping 60 seconds to see if intents are found" )
622 time.sleep( 60 )
623 onosIds = main.ONOScli1.getAllIntentsId()
624 main.log.info( "Submitted intents: " + str( intentIds ) )
625 main.log.info( "Intents in ONOS: " + str( onosIds ) )
626 # Print the intent states
627 intents = main.ONOScli1.intents()
628 intentStates = []
629 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
630 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700631 try:
632 for intent in json.loads( intents ):
633 # Iter through intents of a node
634 state = intent.get( 'state', None )
635 if "INSTALLED" not in state:
636 installedCheck = False
637 intentId = intent.get( 'id', None )
638 intentStates.append( ( intentId, state ) )
639 except ( ValueError, TypeError ):
640 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800641 # add submitted intents not in the store
642 tmplist = [ i for i, s in intentStates ]
643 for i in intentIds:
644 if i not in tmplist:
645 intentStates.append( ( i, " - " ) )
646 intentStates.sort()
647 for i, s in intentStates:
648 count += 1
649 main.log.info( "%-6s%-15s%-15s" %
650 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700651 leaders = main.ONOScli1.leaders()
652 try:
653 if leaders:
654 parsedLeaders = json.loads( leaders )
655 main.log.warn( json.dumps( parsedLeaders,
656 sort_keys=True,
657 indent=4,
658 separators=( ',', ': ' ) ) )
659 # check for all intent partitions
660 # check for election
661 topics = []
662 for i in range( 14 ):
663 topics.append( "intent-partition-" + str( i ) )
664 # FIXME: this should only be after we start the app
665 topics.append( "org.onosproject.election" )
666 main.log.debug( topics )
667 ONOStopics = [ j['topic'] for j in parsedLeaders ]
668 for topic in topics:
669 if topic not in ONOStopics:
670 main.log.error( "Error: " + topic +
671 " not in leaders" )
672 else:
673 main.log.error( "leaders() returned None" )
674 except ( ValueError, TypeError ):
675 main.log.exception( "Error parsing leaders" )
676 main.log.error( repr( leaders ) )
677 partitions = main.ONOScli1.partitions()
678 try:
679 if partitions :
680 parsedPartitions = json.loads( partitions )
681 main.log.warn( json.dumps( parsedPartitions,
682 sort_keys=True,
683 indent=4,
684 separators=( ',', ': ' ) ) )
685 # TODO check for a leader in all paritions
686 # TODO check for consistency among nodes
687 else:
688 main.log.error( "partitions() returned None" )
689 except ( ValueError, TypeError ):
690 main.log.exception( "Error parsing partitions" )
691 main.log.error( repr( partitions ) )
692 pendingMap = main.ONOScli1.pendingMap()
693 try:
694 if pendingMap :
695 parsedPending = json.loads( pendingMap )
696 main.log.warn( json.dumps( parsedPending,
697 sort_keys=True,
698 indent=4,
699 separators=( ',', ': ' ) ) )
700 # TODO check something here?
701 else:
702 main.log.error( "pendingMap() returned None" )
703 except ( ValueError, TypeError ):
704 main.log.exception( "Error parsing pending map" )
705 main.log.error( repr( pendingMap ) )
Jon Hallb1290e82014-11-18 16:17:48 -0500706
Jon Hall6aec96b2015-01-19 14:49:31 -0800707 def CASE4( self, main ):
Jon Hallb1290e82014-11-18 16:17:48 -0500708 """
709 Ping across added host intents
710 """
Jon Hall58c76b72015-02-23 11:09:24 -0800711 import json
Jon Hall65844a32015-03-09 19:09:37 -0700712 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -0700713 assert numControllers, "numControllers not defined"
714 assert main, "main not defined"
715 assert utilities.assert_equals, "utilities.assert_equals not defined"
716 assert CLIs, "CLIs not defined"
717 assert nodes, "nodes not defined"
Jon Hall368769f2014-11-19 15:43:35 -0800718 description = " Ping across added host intents"
Jon Hall6aec96b2015-01-19 14:49:31 -0800719 main.log.report( description )
720 main.case( description )
Jon Hall8f89dda2015-01-22 16:03:33 -0800721 PingResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800722 for i in range( 8, 18 ):
Jon Hall58c76b72015-02-23 11:09:24 -0800723 ping = main.Mininet1.pingHost( src="h" + str( i ),
724 target="h" + str( i + 10 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800725 PingResult = PingResult and ping
Jon Hall6aec96b2015-01-19 14:49:31 -0800726 if ping == main.FALSE:
727 main.log.warn( "Ping failed between h" + str( i ) +
728 " and h" + str( i + 10 ) )
729 elif ping == main.TRUE:
730 main.log.info( "Ping test passed!" )
Jon Hall21270ac2015-02-16 17:59:55 -0800731 # Don't set PingResult or you'd override failures
Jon Hall8f89dda2015-01-22 16:03:33 -0800732 if PingResult == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800733 main.log.report(
734 "Intents have not been installed correctly, pings failed." )
Jon Hall58c76b72015-02-23 11:09:24 -0800735 # TODO: pretty print
Jon Hall65844a32015-03-09 19:09:37 -0700736 main.log.warn( "ONOS1 intents: " )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700737 try:
738 tmpIntents = main.ONOScli1.intents()
739 main.log.warn( json.dumps( json.loads( tmpIntents ),
740 sort_keys=True,
741 indent=4,
742 separators=( ',', ': ' ) ) )
743 except ( ValueError, TypeError ):
744 main.log.warn( repr( tmpIntents ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800745 if PingResult == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800746 main.log.report(
747 "Intents have been installed correctly and verified by pings" )
748 utilities.assert_equals(
749 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800750 actual=PingResult,
Jon Hall6aec96b2015-01-19 14:49:31 -0800751 onpass="Intents have been installed correctly and pings work",
752 onfail="Intents have not been installed correctly, pings failed." )
Jon Hallb1290e82014-11-18 16:17:48 -0500753
Jon Hall63604932015-02-26 17:09:50 -0800754 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800755 if PingResult is not main.TRUE:
756 # Print the intent states
757 intents = main.ONOScli1.intents()
758 intentStates = []
759 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
760 count = 0
761 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700762 try:
763 for intent in json.loads( intents ):
764 state = intent.get( 'state', None )
765 if "INSTALLED" not in state:
766 installedCheck = False
767 intentId = intent.get( 'id', None )
768 intentStates.append( ( intentId, state ) )
769 except ( ValueError, TypeError ):
770 main.log.exception( "Error parsing intents." )
Jon Hall58c76b72015-02-23 11:09:24 -0800771 intentStates.sort()
772 for i, s in intentStates:
773 count += 1
774 main.log.info( "%-6s%-15s%-15s" %
775 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700776 leaders = main.ONOScli1.leaders()
777 try:
778 if leaders:
779 parsedLeaders = json.loads( leaders )
780 main.log.warn( json.dumps( parsedLeaders,
781 sort_keys=True,
782 indent=4,
783 separators=( ',', ': ' ) ) )
784 # check for all intent partitions
785 # check for election
786 topics = []
787 for i in range( 14 ):
788 topics.append( "intent-partition-" + str( i ) )
789 # FIXME: this should only be after we start the app
790 topics.append( "org.onosproject.election" )
791 main.log.debug( topics )
792 ONOStopics = [ j['topic'] for j in parsedLeaders ]
793 for topic in topics:
794 if topic not in ONOStopics:
795 main.log.error( "Error: " + topic +
796 " not in leaders" )
797 else:
798 main.log.error( "leaders() returned None" )
799 except ( ValueError, TypeError ):
800 main.log.exception( "Error parsing leaders" )
801 main.log.error( repr( leaders ) )
802 partitions = main.ONOScli1.partitions()
803 try:
804 if partitions :
805 parsedPartitions = json.loads( partitions )
806 main.log.warn( json.dumps( parsedPartitions,
807 sort_keys=True,
808 indent=4,
809 separators=( ',', ': ' ) ) )
810 # TODO check for a leader in all paritions
811 # TODO check for consistency among nodes
812 else:
813 main.log.error( "partitions() returned None" )
814 except ( ValueError, TypeError ):
815 main.log.exception( "Error parsing partitions" )
816 main.log.error( repr( partitions ) )
817 pendingMap = main.ONOScli1.pendingMap()
818 try:
819 if pendingMap :
820 parsedPending = json.loads( pendingMap )
821 main.log.warn( json.dumps( parsedPending,
822 sort_keys=True,
823 indent=4,
824 separators=( ',', ': ' ) ) )
825 # TODO check something here?
826 else:
827 main.log.error( "pendingMap() returned None" )
828 except ( ValueError, TypeError ):
829 main.log.exception( "Error parsing pending map" )
830 main.log.error( repr( pendingMap ) )
831
Jon Hall63604932015-02-26 17:09:50 -0800832 if not installedCheck:
Jon Hall65844a32015-03-09 19:09:37 -0700833 main.log.info( "Waiting 60 seconds to see if the state of " +
834 "intents change" )
Jon Hall63604932015-02-26 17:09:50 -0800835 time.sleep( 60 )
836 # Print the intent states
837 intents = main.ONOScli1.intents()
838 intentStates = []
839 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
840 count = 0
841 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700842 try:
843 for intent in json.loads( intents ):
844 state = intent.get( 'state', None )
845 if "INSTALLED" not in state:
846 installedCheck = False
847 intentId = intent.get( 'id', None )
848 intentStates.append( ( intentId, state ) )
849 except ( ValueError, TypeError ):
850 main.log.exception( "Error parsing intents." )
Jon Hall63604932015-02-26 17:09:50 -0800851 intentStates.sort()
852 for i, s in intentStates:
853 count += 1
854 main.log.info( "%-6s%-15s%-15s" %
855 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700856 leaders = main.ONOScli1.leaders()
857 try:
858 if leaders:
859 parsedLeaders = json.loads( leaders )
860 main.log.warn( json.dumps( parsedLeaders,
861 sort_keys=True,
862 indent=4,
863 separators=( ',', ': ' ) ) )
864 # check for all intent partitions
865 # check for election
866 topics = []
867 for i in range( 14 ):
868 topics.append( "intent-partition-" + str( i ) )
869 # FIXME: this should only be after we start the app
870 topics.append( "org.onosproject.election" )
871 main.log.debug( topics )
872 ONOStopics = [ j['topic'] for j in parsedLeaders ]
873 for topic in topics:
874 if topic not in ONOStopics:
875 main.log.error( "Error: " + topic +
876 " not in leaders" )
877 else:
878 main.log.error( "leaders() returned None" )
879 except ( ValueError, TypeError ):
880 main.log.exception( "Error parsing leaders" )
881 main.log.error( repr( leaders ) )
882 partitions = main.ONOScli1.partitions()
883 try:
884 if partitions :
885 parsedPartitions = json.loads( partitions )
886 main.log.warn( json.dumps( parsedPartitions,
887 sort_keys=True,
888 indent=4,
889 separators=( ',', ': ' ) ) )
890 # TODO check for a leader in all paritions
891 # TODO check for consistency among nodes
892 else:
893 main.log.error( "partitions() returned None" )
894 except ( ValueError, TypeError ):
895 main.log.exception( "Error parsing partitions" )
896 main.log.error( repr( partitions ) )
897 pendingMap = main.ONOScli1.pendingMap()
898 try:
899 if pendingMap :
900 parsedPending = json.loads( pendingMap )
901 main.log.warn( json.dumps( parsedPending,
902 sort_keys=True,
903 indent=4,
904 separators=( ',', ': ' ) ) )
905 # TODO check something here?
906 else:
907 main.log.error( "pendingMap() returned None" )
908 except ( ValueError, TypeError ):
909 main.log.exception( "Error parsing pending map" )
910 main.log.error( repr( pendingMap ) )
Jon Hallb1290e82014-11-18 16:17:48 -0500911
Jon Hall6aec96b2015-01-19 14:49:31 -0800912 def CASE5( self, main ):
913 """
Jon Hallb1290e82014-11-18 16:17:48 -0500914 Reading state of ONOS
Jon Hall6aec96b2015-01-19 14:49:31 -0800915 """
Jon Hallb1290e82014-11-18 16:17:48 -0500916 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700917 import time
918 assert numControllers, "numControllers not defined"
919 assert main, "main not defined"
920 assert utilities.assert_equals, "utilities.assert_equals not defined"
921 assert CLIs, "CLIs not defined"
922 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -0800923 # assumes that sts is already in you PYTHONPATH
924 from sts.topology.teston_topology import TestONTopology
Jon Hallb1290e82014-11-18 16:17:48 -0500925
Jon Hall6aec96b2015-01-19 14:49:31 -0800926 main.log.report( "Setting up and gathering data for current state" )
927 main.case( "Setting up and gathering data for current state" )
928 # The general idea for this test case is to pull the state of
929 # ( intents,flows, topology,... ) from each ONOS node
Jon Hall65844a32015-03-09 19:09:37 -0700930 # We can then compare them with each other and also with past states
Jon Hallb1290e82014-11-18 16:17:48 -0500931
Jon Hall65844a32015-03-09 19:09:37 -0700932 main.step( "Check that each switch has a master" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800933 global mastershipState
Jon Hall5cfd23c2015-03-19 11:40:57 -0700934 mastershipState = '[]'
Jon Hall94fd0472014-12-08 11:52:42 -0800935
Jon Hall6aec96b2015-01-19 14:49:31 -0800936 # Assert that each device has a master
Jon Hall65844a32015-03-09 19:09:37 -0700937 rolesNotNull = main.TRUE
938 threads = []
939 for i in range( numControllers ):
940 t = main.Thread( target=CLIs[i].rolesNotNull,
Jon Hall65844a32015-03-09 19:09:37 -0700941 name="rolesNotNull-" + str( i ),
942 args=[] )
943 threads.append( t )
944 t.start()
Jon Hall65844a32015-03-09 19:09:37 -0700945
946 for t in threads:
947 t.join()
948 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -0800949 utilities.assert_equals(
950 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800951 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -0800952 onpass="Each device has a master",
953 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -0800954
Jon Hall65844a32015-03-09 19:09:37 -0700955 main.step( "Get the Mastership of each switch from each controller" )
956 ONOSMastership = []
957 mastershipCheck = main.FALSE
958 consistentMastership = True
959 rolesResults = True
960 threads = []
961 for i in range( numControllers ):
962 t = main.Thread( target=CLIs[i].roles,
Jon Hall65844a32015-03-09 19:09:37 -0700963 name="roles-" + str( i ),
964 args=[] )
965 threads.append( t )
966 t.start()
Jon Hall65844a32015-03-09 19:09:37 -0700967
968 for t in threads:
969 t.join()
970 ONOSMastership.append( t.result )
971
972 for i in range( numControllers ):
973 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
974 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
975 " roles" )
976 main.log.warn(
977 "ONOS" + str( i + 1 ) + " mastership response: " +
978 repr( ONOSMastership[i] ) )
979 rolesResults = False
980 utilities.assert_equals(
981 expect=True,
982 actual=rolesResults,
983 onpass="No error in reading roles output",
984 onfail="Error in reading roles from ONOS" )
985
986 main.step( "Check for consistency in roles from each controller" )
987 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall6aec96b2015-01-19 14:49:31 -0800988 main.log.report(
989 "Switch roles are consistent across all ONOS nodes" )
Jon Hallb1290e82014-11-18 16:17:48 -0500990 else:
Jon Hall65844a32015-03-09 19:09:37 -0700991 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -0800992 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -0700993 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -0800994 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -0800995 onpass="Switch roles are consistent across all ONOS nodes",
996 onfail="ONOS nodes have different views of switch roles" )
Jon Hallb1290e82014-11-18 16:17:48 -0500997
Jon Hall65844a32015-03-09 19:09:37 -0700998 if rolesResults and not consistentMastership:
999 for i in range( numControllers ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001000 try:
1001 main.log.warn(
1002 "ONOS" + str( i + 1 ) + " roles: ",
1003 json.dumps(
1004 json.loads( ONOSMastership[ i ] ),
1005 sort_keys=True,
1006 indent=4,
1007 separators=( ',', ': ' ) ) )
1008 except ( ValueError, TypeError ):
1009 main.log.warn( repr( ONOSMastership[ i ] ) )
1010 elif rolesResults and consistentMastership:
Jon Hall65844a32015-03-09 19:09:37 -07001011 mastershipCheck = main.TRUE
1012 mastershipState = ONOSMastership[ 0 ]
1013
Jon Hall6aec96b2015-01-19 14:49:31 -08001014 main.step( "Get the intents from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001015 global intentState
1016 intentState = []
Jon Hall65844a32015-03-09 19:09:37 -07001017 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001018 intentCheck = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07001019 consistentIntents = True
1020 intentsResults = True
1021 threads = []
1022 for i in range( numControllers ):
1023 t = main.Thread( target=CLIs[i].intents,
Jon Hall65844a32015-03-09 19:09:37 -07001024 name="intents-" + str( i ),
1025 args=[],
1026 kwargs={ 'jsonFormat': True } )
1027 threads.append( t )
1028 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001029
1030 for t in threads:
1031 t.join()
1032 ONOSIntents.append( t.result )
1033
1034 for i in range( numControllers ):
1035 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1036 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1037 " intents" )
1038 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1039 repr( ONOSIntents[ i ] ) )
1040 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001041 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001042 expect=True,
1043 actual=intentsResults,
1044 onpass="No error in reading intents output",
1045 onfail="Error in reading intents from ONOS" )
1046
1047 main.step( "Check for consistency in Intents from each controller" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001048 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
Jon Hall65844a32015-03-09 19:09:37 -07001049 main.log.report( "Intents are consistent across all ONOS " +
1050 "nodes" )
1051 else:
1052 consistentIntents = False
Jon Hall5cfd23c2015-03-19 11:40:57 -07001053 main.log.report( "Intents not consistent" )
Jon Hall65844a32015-03-09 19:09:37 -07001054 utilities.assert_equals(
1055 expect=True,
1056 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001057 onpass="Intents are consistent across all ONOS nodes",
1058 onfail="ONOS nodes have different views of intents" )
Jon Hallb1290e82014-11-18 16:17:48 -05001059
Jon Hall65844a32015-03-09 19:09:37 -07001060 if intentsResults and not consistentIntents:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001061 n = len(ONOSIntents)
1062 main.log.warn( "ONOS" + str( n ) + " intents: " )
1063 main.log.warn( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1064 sort_keys=True,
1065 indent=4,
1066 separators=( ',', ': ' ) ) )
Jon Hall65844a32015-03-09 19:09:37 -07001067 for i in range( numControllers ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001068 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
1069 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1070 main.log.warn( json.dumps( json.loads( ONOSIntents[i] ),
1071 sort_keys=True,
1072 indent=4,
1073 separators=( ',', ': ' ) ) )
1074 else:
1075 main.log.warn( nodes[ i ].name + " intents match ONOS" +
1076 str( n ) + " intents" )
Jon Hall65844a32015-03-09 19:09:37 -07001077 elif intentsResults and consistentIntents:
1078 intentCheck = main.TRUE
1079 intentState = ONOSIntents[ 0 ]
1080
Jon Hall6aec96b2015-01-19 14:49:31 -08001081 main.step( "Get the flows from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001082 global flowState
1083 flowState = []
Jon Hall65844a32015-03-09 19:09:37 -07001084 ONOSFlows = []
1085 ONOSFlowsJson = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001086 flowCheck = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07001087 consistentFlows = True
1088 flowsResults = True
1089 threads = []
1090 for i in range( numControllers ):
1091 t = main.Thread( target=CLIs[i].flows,
Jon Hall65844a32015-03-09 19:09:37 -07001092 name="flows-" + str( i ),
1093 args=[],
1094 kwargs={ 'jsonFormat': True } )
1095 threads.append( t )
1096 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001097
Jon Hall5cfd23c2015-03-19 11:40:57 -07001098 # FIXME: why am I sleeping here?
1099 time.sleep(30)
Jon Hall65844a32015-03-09 19:09:37 -07001100 for t in threads:
1101 t.join()
Jon Hall5cfd23c2015-03-19 11:40:57 -07001102 result = t.result
Jon Hall65844a32015-03-09 19:09:37 -07001103 ONOSFlows.append( result )
1104
1105 for i in range( numControllers ):
1106 num = str( i + 1 )
1107 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1108 main.log.report( "Error in getting ONOS" + num + " flows" )
1109 main.log.warn( "ONOS" + num + " flows response: " +
1110 repr( ONOSFlows[ i ] ) )
1111 flowsResults = False
1112 ONOSFlowsJson.append( None )
Jon Hall58c76b72015-02-23 11:09:24 -08001113 else:
Jon Hall65844a32015-03-09 19:09:37 -07001114 try:
1115 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1116 except ( ValueError, TypeError ):
1117 # FIXME: change this to log.error?
1118 main.log.exception( "Error in parsing ONOS" + num +
1119 " response as json." )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001120 main.log.error( repr( ONOSFlows[ i ] ) )
Jon Hall65844a32015-03-09 19:09:37 -07001121 ONOSFlowsJson.append( None )
1122 flowsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001123 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001124 expect=True,
1125 actual=flowsResults,
1126 onpass="No error in reading flows output",
1127 onfail="Error in reading flows from ONOS" )
1128
1129 main.step( "Check for consistency in Flows from each controller" )
1130 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1131 if all( tmp ):
1132 main.log.report( "Flow count is consistent across all ONOS nodes" )
1133 else:
1134 consistentFlows = False
1135 utilities.assert_equals(
1136 expect=True,
1137 actual=consistentFlows,
Jon Hall6aec96b2015-01-19 14:49:31 -08001138 onpass="The flow count is consistent across all ONOS nodes",
1139 onfail="ONOS nodes have different flow counts" )
Jon Hallb1290e82014-11-18 16:17:48 -05001140
Jon Hall65844a32015-03-09 19:09:37 -07001141 if flowsResults and not consistentFlows:
1142 for i in range( numControllers ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001143 try:
1144 main.log.warn(
1145 "ONOS" + str( i + 1 ) + " flows: " +
1146 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1147 indent=4, separators=( ',', ': ' ) ) )
1148 except ( ValueError, TypeError ):
1149 main.log.warn(
1150 "ONOS" + str( i + 1 ) + " flows: " +
1151 repr( ONOSFlows[ i ] ) )
Jon Hall65844a32015-03-09 19:09:37 -07001152 elif flowsResults and consistentFlows:
1153 flowCheck = main.TRUE
1154 flowState = ONOSFlows[ 0 ]
1155
Jon Hall6aec96b2015-01-19 14:49:31 -08001156 main.step( "Get the OF Table entries" )
Jon Hallb1290e82014-11-18 16:17:48 -05001157 global flows
Jon Hall6aec96b2015-01-19 14:49:31 -08001158 flows = []
1159 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001160 flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001161 if flowCheck == main.FALSE:
1162 for table in flows:
1163 main.log.warn( table )
Jon Hall6aec96b2015-01-19 14:49:31 -08001164 # TODO: Compare switch flow tables with ONOS flow tables
Jon Hallb1290e82014-11-18 16:17:48 -05001165
Jon Hall6aec96b2015-01-19 14:49:31 -08001166 main.step( "Start continuous pings" )
1167 main.Mininet2.pingLong(
1168 src=main.params[ 'PING' ][ 'source1' ],
1169 target=main.params[ 'PING' ][ 'target1' ],
1170 pingTime=500 )
1171 main.Mininet2.pingLong(
1172 src=main.params[ 'PING' ][ 'source2' ],
1173 target=main.params[ 'PING' ][ 'target2' ],
1174 pingTime=500 )
1175 main.Mininet2.pingLong(
1176 src=main.params[ 'PING' ][ 'source3' ],
1177 target=main.params[ 'PING' ][ 'target3' ],
1178 pingTime=500 )
1179 main.Mininet2.pingLong(
1180 src=main.params[ 'PING' ][ 'source4' ],
1181 target=main.params[ 'PING' ][ 'target4' ],
1182 pingTime=500 )
1183 main.Mininet2.pingLong(
1184 src=main.params[ 'PING' ][ 'source5' ],
1185 target=main.params[ 'PING' ][ 'target5' ],
1186 pingTime=500 )
1187 main.Mininet2.pingLong(
1188 src=main.params[ 'PING' ][ 'source6' ],
1189 target=main.params[ 'PING' ][ 'target6' ],
1190 pingTime=500 )
1191 main.Mininet2.pingLong(
1192 src=main.params[ 'PING' ][ 'source7' ],
1193 target=main.params[ 'PING' ][ 'target7' ],
1194 pingTime=500 )
1195 main.Mininet2.pingLong(
1196 src=main.params[ 'PING' ][ 'source8' ],
1197 target=main.params[ 'PING' ][ 'target8' ],
1198 pingTime=500 )
1199 main.Mininet2.pingLong(
1200 src=main.params[ 'PING' ][ 'source9' ],
1201 target=main.params[ 'PING' ][ 'target9' ],
1202 pingTime=500 )
1203 main.Mininet2.pingLong(
1204 src=main.params[ 'PING' ][ 'source10' ],
1205 target=main.params[ 'PING' ][ 'target10' ],
1206 pingTime=500 )
Jon Hallb1290e82014-11-18 16:17:48 -05001207
Jon Hall6aec96b2015-01-19 14:49:31 -08001208 main.step( "Create TestONTopology object" )
Jon Hallb1290e82014-11-18 16:17:48 -05001209 ctrls = []
Jon Hall65844a32015-03-09 19:09:37 -07001210 for node in nodes:
1211 temp = ( node, node.name, node.ip_address, 6633 )
Jon Hall65844a32015-03-09 19:09:37 -07001212 ctrls.append( temp )
Jon Hall65844a32015-03-09 19:09:37 -07001213 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hallb1290e82014-11-18 16:17:48 -05001214
Jon Hall6aec96b2015-01-19 14:49:31 -08001215 main.step( "Collecting topology information from ONOS" )
Jon Hallb1290e82014-11-18 16:17:48 -05001216 devices = []
Jon Hall65844a32015-03-09 19:09:37 -07001217 threads = []
1218 for i in range( numControllers ):
1219 t = main.Thread( target=CLIs[i].devices,
Jon Hall65844a32015-03-09 19:09:37 -07001220 name="devices-" + str( i ),
1221 args=[ ] )
1222 threads.append( t )
1223 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001224
1225 for t in threads:
1226 t.join()
1227 devices.append( t.result )
Jon Hallb1290e82014-11-18 16:17:48 -05001228 hosts = []
Jon Hall65844a32015-03-09 19:09:37 -07001229 threads = []
1230 for i in range( numControllers ):
1231 t = main.Thread( target=CLIs[i].hosts,
Jon Hall65844a32015-03-09 19:09:37 -07001232 name="hosts-" + str( i ),
1233 args=[ ] )
1234 threads.append( t )
1235 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001236
1237 for t in threads:
1238 t.join()
1239 try:
1240 hosts.append( json.loads( t.result ) )
1241 except ( ValueError, TypeError ):
1242 # FIXME: better handling of this, print which node
1243 # Maybe use thread name?
1244 main.log.exception( "Error parsing json output of hosts" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001245 # FIXME: should this be an empty json object instead?
1246 hosts.append( None )
Jon Hall65844a32015-03-09 19:09:37 -07001247
Jon Hallb1290e82014-11-18 16:17:48 -05001248 ports = []
Jon Hall65844a32015-03-09 19:09:37 -07001249 threads = []
1250 for i in range( numControllers ):
1251 t = main.Thread( target=CLIs[i].ports,
Jon Hall65844a32015-03-09 19:09:37 -07001252 name="ports-" + str( i ),
1253 args=[ ] )
1254 threads.append( t )
1255 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001256
1257 for t in threads:
1258 t.join()
1259 ports.append( t.result )
Jon Hallb1290e82014-11-18 16:17:48 -05001260 links = []
Jon Hall65844a32015-03-09 19:09:37 -07001261 threads = []
1262 for i in range( numControllers ):
1263 t = main.Thread( target=CLIs[i].links,
Jon Hall65844a32015-03-09 19:09:37 -07001264 name="links-" + str( i ),
1265 args=[ ] )
1266 threads.append( t )
1267 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001268
1269 for t in threads:
1270 t.join()
1271 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001272 clusters = []
Jon Hall65844a32015-03-09 19:09:37 -07001273 threads = []
1274 for i in range( numControllers ):
1275 t = main.Thread( target=CLIs[i].clusters,
Jon Hall65844a32015-03-09 19:09:37 -07001276 name="clusters-" + str( i ),
1277 args=[ ] )
1278 threads.append( t )
1279 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001280
1281 for t in threads:
1282 t.join()
1283 clusters.append( t.result )
Jon Hall529a37f2015-01-28 10:02:00 -08001284 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08001285
Jon Hall6aec96b2015-01-19 14:49:31 -08001286 # hosts
Jon Hall8f89dda2015-01-22 16:03:33 -08001287 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001288 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001289 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001290 if "Error" not in hosts[ controller ]:
1291 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001292 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001293 else: # hosts not consistent
1294 main.log.report( "hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001295 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001296 " is inconsistent with ONOS1" )
1297 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001298 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001299
1300 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001301 main.log.report( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001302 controllerStr )
1303 consistentHostsResult = main.FALSE
1304 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001305 " hosts response: " +
1306 repr( hosts[ controller ] ) )
1307 utilities.assert_equals(
1308 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001309 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001310 onpass="Hosts view is consistent across all ONOS nodes",
1311 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08001312
Jon Hall58c76b72015-02-23 11:09:24 -08001313 ipResult = main.TRUE
1314 for controller in range( 0, len( hosts ) ):
1315 controllerStr = str( controller + 1 )
1316 for host in hosts[ controller ]:
Jon Hall65844a32015-03-09 19:09:37 -07001317 if not host.get( 'ips', [ ] ):
1318 main.log.error( "DEBUG:Error with host ips on controller" +
1319 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001320 ipResult = main.FALSE
1321 utilities.assert_equals(
1322 expect=main.TRUE,
1323 actual=ipResult,
1324 onpass="The ips of the hosts aren't empty",
1325 onfail="The ip of at least one host is missing" )
1326
Jon Hall6aec96b2015-01-19 14:49:31 -08001327 # Strongly connected clusters of devices
Jon Hall8f89dda2015-01-22 16:03:33 -08001328 consistentClustersResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001329 for controller in range( len( clusters ) ):
Jon Hall65844a32015-03-09 19:09:37 -07001330 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001331 if "Error" not in clusters[ controller ]:
1332 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001333 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001334 else: # clusters not consistent
Jon Hall65844a32015-03-09 19:09:37 -07001335 main.log.report( "clusters from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001336 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001337 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001338
1339 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001340 main.log.report( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001341 "from ONOS" + controllerStr )
1342 consistentClustersResult = main.FALSE
1343 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001344 " clusters response: " +
1345 repr( clusters[ controller ] ) )
1346 utilities.assert_equals(
1347 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001348 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001349 onpass="Clusters view is consistent across all ONOS nodes",
1350 onfail="ONOS nodes have different views of clusters" )
1351 # there should always only be one cluster
Jon Hall5cfd23c2015-03-19 11:40:57 -07001352 try:
1353 numClusters = len( json.loads( clusters[ 0 ] ) )
1354 except ( ValueError, TypeError ):
1355 main.log.exception( "Error parsing clusters[0]: " +
1356 repr( clusters[ 0 ] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001357 clusterResults = main.FALSE
1358 if numClusters == 1:
1359 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001360 utilities.assert_equals(
1361 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08001362 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08001363 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08001364 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08001365
Jon Hall6aec96b2015-01-19 14:49:31 -08001366 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001367 devicesResults = main.TRUE
1368 portsResults = main.TRUE
1369 linksResults = main.TRUE
1370 for controller in range( numControllers ):
1371 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001372 if devices[ controller ] or "Error" not in devices[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001373 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -08001374 MNTopo,
Jon Hall65844a32015-03-09 19:09:37 -07001375 json.loads( devices[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001376 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001377 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001378 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001379 actual=currentDevicesResult,
1380 onpass="ONOS" + controllerStr +
1381 " Switches view is correct",
1382 onfail="ONOS" + controllerStr +
1383 " Switches view is incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05001384
Jon Hall6aec96b2015-01-19 14:49:31 -08001385 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001386 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -08001387 MNTopo,
Jon Hall65844a32015-03-09 19:09:37 -07001388 json.loads( ports[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001389 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001390 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001391 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001392 actual=currentPortsResult,
1393 onpass="ONOS" + controllerStr +
1394 " ports view is correct",
1395 onfail="ONOS" + controllerStr +
1396 " ports view is incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05001397
Jon Hall6aec96b2015-01-19 14:49:31 -08001398 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001399 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -08001400 MNTopo,
Jon Hall65844a32015-03-09 19:09:37 -07001401 json.loads( links[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001402 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001403 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001404 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001405 actual=currentLinksResult,
1406 onpass="ONOS" + controllerStr +
1407 " links view is correct",
1408 onfail="ONOS" + controllerStr +
1409 " links view is incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05001410
Jon Hall8f89dda2015-01-22 16:03:33 -08001411 devicesResults = devicesResults and currentDevicesResult
1412 portsResults = portsResults and currentPortsResult
1413 linksResults = linksResults and currentLinksResult
Jon Hallb1290e82014-11-18 16:17:48 -05001414
Jon Hall65844a32015-03-09 19:09:37 -07001415 topoResult = ( devicesResults and portsResults and linksResults
1416 and consistentHostsResult and consistentClustersResult
1417 and clusterResults and ipResult )
Jon Hall8f89dda2015-01-22 16:03:33 -08001418 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08001419 onpass="Topology Check Test successful",
1420 onfail="Topology Check Test NOT successful" )
Jon Hallb1290e82014-11-18 16:17:48 -05001421
Jon Hall8f89dda2015-01-22 16:03:33 -08001422 finalAssert = main.TRUE
Jon Hall65844a32015-03-09 19:09:37 -07001423 finalAssert = ( finalAssert and topoResult and flowCheck
1424 and intentCheck and consistentMastership
1425 and rolesNotNull )
Jon Hall8f89dda2015-01-22 16:03:33 -08001426 utilities.assert_equals( expect=main.TRUE, actual=finalAssert,
Jon Hall58c76b72015-02-23 11:09:24 -08001427 onpass="State check successful",
1428 onfail="State check NOT successful" )
Jon Hallb1290e82014-11-18 16:17:48 -05001429
Jon Hall6aec96b2015-01-19 14:49:31 -08001430 def CASE6( self, main ):
1431 """
Jon Hallb1290e82014-11-18 16:17:48 -05001432 The Failure case. Since this is the Sanity test, we do nothing.
Jon Hall6aec96b2015-01-19 14:49:31 -08001433 """
Jon Hall368769f2014-11-19 15:43:35 -08001434 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001435 assert numControllers, "numControllers not defined"
1436 assert main, "main not defined"
1437 assert utilities.assert_equals, "utilities.assert_equals not defined"
1438 assert CLIs, "CLIs not defined"
1439 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001440 main.log.report( "Wait 60 seconds instead of inducing a failure" )
1441 time.sleep( 60 )
1442 utilities.assert_equals(
1443 expect=main.TRUE,
1444 actual=main.TRUE,
1445 onpass="Sleeping 60 seconds",
1446 onfail="Something is terribly wrong with my math" )
Jon Hallb1290e82014-11-18 16:17:48 -05001447
Jon Hall6aec96b2015-01-19 14:49:31 -08001448 def CASE7( self, main ):
1449 """
Jon Hall368769f2014-11-19 15:43:35 -08001450 Check state after ONOS failure
Jon Hall6aec96b2015-01-19 14:49:31 -08001451 """
Jon Hallb1290e82014-11-18 16:17:48 -05001452 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001453 assert numControllers, "numControllers not defined"
1454 assert main, "main not defined"
1455 assert utilities.assert_equals, "utilities.assert_equals not defined"
1456 assert CLIs, "CLIs not defined"
1457 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001458 main.case( "Running ONOS Constant State Tests" )
Jon Hallb1290e82014-11-18 16:17:48 -05001459
Jon Hall65844a32015-03-09 19:09:37 -07001460 main.step( "Check that each switch has a master" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001461 # Assert that each device has a master
Jon Hall65844a32015-03-09 19:09:37 -07001462 rolesNotNull = main.TRUE
1463 threads = []
1464 for i in range( numControllers ):
1465 t = main.Thread( target=CLIs[i].rolesNotNull,
Jon Hall65844a32015-03-09 19:09:37 -07001466 name="rolesNotNull-" + str( i ),
1467 args=[ ] )
1468 threads.append( t )
1469 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001470
1471 for t in threads:
1472 t.join()
1473 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001474 utilities.assert_equals(
1475 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001476 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001477 onpass="Each device has a master",
1478 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001479
Jon Hall65844a32015-03-09 19:09:37 -07001480 ONOSMastership = []
1481 mastershipCheck = main.FALSE
1482 consistentMastership = True
1483 rolesResults = True
1484 threads = []
1485 for i in range( numControllers ):
1486 t = main.Thread( target=CLIs[i].roles,
Jon Hall65844a32015-03-09 19:09:37 -07001487 name="roles-" + str( i ),
1488 args=[] )
1489 threads.append( t )
1490 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001491
1492 for t in threads:
1493 t.join()
1494 ONOSMastership.append( t.result )
1495
1496 for i in range( numControllers ):
1497 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1498 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1499 " roles" )
1500 main.log.warn(
1501 "ONOS" + str( i + 1 ) + " mastership response: " +
1502 repr( ONOSMastership[i] ) )
1503 rolesResults = False
1504 utilities.assert_equals(
1505 expect=True,
1506 actual=rolesResults,
1507 onpass="No error in reading roles output",
1508 onfail="Error in reading roles from ONOS" )
1509
1510 main.step( "Check for consistency in roles from each controller" )
1511 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall6aec96b2015-01-19 14:49:31 -08001512 main.log.report(
1513 "Switch roles are consistent across all ONOS nodes" )
Jon Hallb1290e82014-11-18 16:17:48 -05001514 else:
Jon Hall65844a32015-03-09 19:09:37 -07001515 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001516 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001517 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001518 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001519 onpass="Switch roles are consistent across all ONOS nodes",
1520 onfail="ONOS nodes have different views of switch roles" )
Jon Hallb1290e82014-11-18 16:17:48 -05001521
Jon Hall65844a32015-03-09 19:09:37 -07001522 if rolesResults and not consistentMastership:
1523 for i in range( numControllers ):
1524 main.log.warn(
1525 "ONOS" + str( i + 1 ) + " roles: ",
1526 json.dumps(
1527 json.loads( ONOSMastership[ i ] ),
1528 sort_keys=True,
1529 indent=4,
1530 separators=( ',', ': ' ) ) )
1531 elif rolesResults and not consistentMastership:
1532 mastershipCheck = main.TRUE
1533
Jon Hallb1290e82014-11-18 16:17:48 -05001534 description2 = "Compare switch roles from before failure"
Jon Hall6aec96b2015-01-19 14:49:31 -08001535 main.step( description2 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001536 try:
1537 currentJson = json.loads( ONOSMastership[0] )
1538 oldJson = json.loads( mastershipState )
1539 except ( ValueError, TypeError ):
1540 main.log.exception( "Something is wrong with parsing " +
1541 "ONOSMastership[0] or mastershipState" )
1542 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1543 main.log.error( "mastershipState" + repr( mastershipState ) )
1544 main.cleanup()
1545 main.exit()
Jon Hall8f89dda2015-01-22 16:03:33 -08001546 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001547 for i in range( 1, 29 ):
1548 switchDPID = str(
Jon Hall65844a32015-03-09 19:09:37 -07001549 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001550 current = [ switch[ 'master' ] for switch in currentJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001551 if switchDPID in switch[ 'id' ] ]
Jon Hall8f89dda2015-01-22 16:03:33 -08001552 old = [ switch[ 'master' ] for switch in oldJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001553 if switchDPID in switch[ 'id' ] ]
Jon Hallb1290e82014-11-18 16:17:48 -05001554 if current == old:
Jon Hall8f89dda2015-01-22 16:03:33 -08001555 mastershipCheck = mastershipCheck and main.TRUE
Jon Hallb1290e82014-11-18 16:17:48 -05001556 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001557 main.log.warn( "Mastership of switch %s changed" % switchDPID )
Jon Hall8f89dda2015-01-22 16:03:33 -08001558 mastershipCheck = main.FALSE
1559 if mastershipCheck == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001560 main.log.report( "Mastership of Switches was not changed" )
1561 utilities.assert_equals(
1562 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001563 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -08001564 onpass="Mastership of Switches was not changed",
1565 onfail="Mastership of some switches changed" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001566 mastershipCheck = mastershipCheck and consistentMastership
Jon Hallb1290e82014-11-18 16:17:48 -05001567
Jon Hall6aec96b2015-01-19 14:49:31 -08001568 main.step( "Get the intents and compare across all nodes" )
Jon Hall65844a32015-03-09 19:09:37 -07001569 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001570 intentCheck = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07001571 consistentIntents = True
1572 intentsResults = True
1573 threads = []
1574 for i in range( numControllers ):
1575 t = main.Thread( target=CLIs[i].intents,
Jon Hall65844a32015-03-09 19:09:37 -07001576 name="intents-" + str( i ),
1577 args=[],
1578 kwargs={ 'jsonFormat': True } )
1579 threads.append( t )
1580 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001581
1582 for t in threads:
1583 t.join()
1584 ONOSIntents.append( t.result )
1585
1586 for i in range( numControllers ):
1587 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1588 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1589 " intents" )
1590 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1591 repr( ONOSIntents[ i ] ) )
1592 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001593 utilities.assert_equals(
Jon Hall65844a32015-03-09 19:09:37 -07001594 expect=True,
1595 actual=intentsResults,
1596 onpass="No error in reading intents output",
1597 onfail="Error in reading intents from ONOS" )
1598
1599 main.step( "Check for consistency in Intents from each controller" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001600 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
Jon Hall65844a32015-03-09 19:09:37 -07001601 main.log.report( "Intents are consistent across all ONOS " +
1602 "nodes" )
1603 else:
1604 consistentIntents = False
1605 utilities.assert_equals(
1606 expect=True,
1607 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001608 onpass="Intents are consistent across all ONOS nodes",
1609 onfail="ONOS nodes have different views of intents" )
Jon Hall1b8f54a2015-02-04 13:24:20 -08001610 intentStates = []
Jon Hall65844a32015-03-09 19:09:37 -07001611 for node in ONOSIntents: # Iter through ONOS nodes
Jon Hall1b8f54a2015-02-04 13:24:20 -08001612 nodeStates = []
Jon Hall58c76b72015-02-23 11:09:24 -08001613 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001614 try:
1615 for intent in json.loads( node ):
1616 nodeStates.append( intent[ 'state' ] )
1617 except ( ValueError, TypeError ):
1618 main.log.exception( "Error in parsing intents" )
1619 main.log.error( repr( node ) )
Jon Hall1b8f54a2015-02-04 13:24:20 -08001620 intentStates.append( nodeStates )
1621 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1622 main.log.info( dict( out ) )
1623
Jon Hall65844a32015-03-09 19:09:37 -07001624 if intentsResults and not consistentIntents:
1625 for i in range( numControllers ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001626 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1627 main.log.warn( json.dumps(
1628 json.loads( ONOSIntents[ i ] ),
1629 sort_keys=True,
1630 indent=4,
1631 separators=( ',', ': ' ) ) )
Jon Hall65844a32015-03-09 19:09:37 -07001632 elif intentsResults and consistentIntents:
1633 intentCheck = main.TRUE
Jon Hall65844a32015-03-09 19:09:37 -07001634
Jon Hall58c76b72015-02-23 11:09:24 -08001635 # NOTE: Store has no durability, so intents are lost across system
1636 # restarts
Jon Hall6aec96b2015-01-19 14:49:31 -08001637 main.step( "Compare current intents with intents before the failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001638 # NOTE: this requires case 5 to pass for intentState to be set.
Jon Hall94fd0472014-12-08 11:52:42 -08001639 # maybe we should stop the test if that fails?
Jon Hall1b8f54a2015-02-04 13:24:20 -08001640 sameIntents = main.TRUE
Jon Hall65844a32015-03-09 19:09:37 -07001641 if intentState and intentState == ONOSIntents[ 0 ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001642 sameIntents = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001643 main.log.report( "Intents are consistent with before failure" )
1644 # TODO: possibly the states have changed? we may need to figure out
Jon Hall65844a32015-03-09 19:09:37 -07001645 # what the acceptable states are
Jon Hallb1290e82014-11-18 16:17:48 -05001646 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001647 try:
Jon Hall65844a32015-03-09 19:09:37 -07001648 main.log.warn( "ONOS intents: " )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001649 main.log.warn( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1650 sort_keys=True, indent=4,
1651 separators=( ',', ': ' ) ) )
1652 except ( ValueError, TypeError ):
Jon Hall65844a32015-03-09 19:09:37 -07001653 main.log.exception( "Exception printing intents" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001654 main.log.warn( repr( ONOSIntents[0] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001655 sameIntents = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001656 utilities.assert_equals(
1657 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001658 actual=sameIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001659 onpass="Intents are consistent with before failure",
1660 onfail="The Intents changed during failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001661 intentCheck = intentCheck and sameIntents
Jon Hallb1290e82014-11-18 16:17:48 -05001662
Jon Hall6aec96b2015-01-19 14:49:31 -08001663 main.step( "Get the OF Table entries and compare to before " +
1664 "component failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001665 FlowTables = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001666 flows2 = []
1667 for i in range( 28 ):
1668 main.log.info( "Checking flow table on s" + str( i + 1 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001669 tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
1670 flows2.append( tmpFlows )
1671 tempResult = main.Mininet2.flowComp(
Jon Hall6aec96b2015-01-19 14:49:31 -08001672 flow1=flows[ i ],
Jon Hall8f89dda2015-01-22 16:03:33 -08001673 flow2=tmpFlows )
1674 FlowTables = FlowTables and tempResult
1675 if FlowTables == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001676 main.log.info( "Differences in flow table for switch: s" +
1677 str( i + 1 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001678 if FlowTables == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001679 main.log.report( "No changes were found in the flow tables" )
1680 utilities.assert_equals(
1681 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001682 actual=FlowTables,
Jon Hall6aec96b2015-01-19 14:49:31 -08001683 onpass="No changes were found in the flow tables",
1684 onfail="Changes were found in the flow tables" )
Jon Hallb1290e82014-11-18 16:17:48 -05001685
Jon Hall6aec96b2015-01-19 14:49:31 -08001686 main.step( "Check the continuous pings to ensure that no packets " +
1687 "were dropped during component failure" )
Jon Hall65844a32015-03-09 19:09:37 -07001688 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
1689 main.params[ 'TESTONIP' ] )
Jon Hall8f89dda2015-01-22 16:03:33 -08001690 LossInPings = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001691 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
1692 for i in range( 8, 18 ):
1693 main.log.info(
1694 "Checking for a loss in pings along flow from s" +
1695 str( i ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001696 LossInPings = main.Mininet2.checkForLoss(
Jon Hall6aec96b2015-01-19 14:49:31 -08001697 "/tmp/ping.h" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001698 str( i ) ) or LossInPings
1699 if LossInPings == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001700 main.log.info( "Loss in ping detected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001701 elif LossInPings == main.ERROR:
Jon Hall6aec96b2015-01-19 14:49:31 -08001702 main.log.info( "There are multiple mininet process running" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001703 elif LossInPings == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001704 main.log.info( "No Loss in the pings" )
1705 main.log.report( "No loss of dataplane connectivity" )
1706 utilities.assert_equals(
1707 expect=main.FALSE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001708 actual=LossInPings,
Jon Hall6aec96b2015-01-19 14:49:31 -08001709 onpass="No Loss of connectivity",
1710 onfail="Loss of dataplane connectivity detected" )
Jon Hallb1290e82014-11-18 16:17:48 -05001711
Jon Hall6aec96b2015-01-19 14:49:31 -08001712 # Test of LeadershipElection
1713 # NOTE: this only works for the sanity test. In case of failures,
Jon Hall58c76b72015-02-23 11:09:24 -08001714 # leader will likely change
Jon Hall65844a32015-03-09 19:09:37 -07001715 leader = nodes[ 0 ].ip_address
Jon Hall8f89dda2015-01-22 16:03:33 -08001716 leaderResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001717 for cli in CLIs:
1718 leaderN = cli.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08001719 # verify leader is ONOS1
Jon Hall669173b2014-12-17 11:36:30 -08001720 if leaderN == leader:
Jon Hall6aec96b2015-01-19 14:49:31 -08001721 # all is well
1722 # NOTE: In failure scenario, this could be a new node, maybe
1723 # check != ONOS1
Jon Hall669173b2014-12-17 11:36:30 -08001724 pass
1725 elif leaderN == main.FALSE:
Jon Hall65844a32015-03-09 19:09:37 -07001726 # error in response
Jon Hall6aec96b2015-01-19 14:49:31 -08001727 main.log.report( "Something is wrong with " +
Jon Hall58c76b72015-02-23 11:09:24 -08001728 "electionTestLeader function, check the" +
1729 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001730 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08001731 elif leader != leaderN:
Jon Hall8f89dda2015-01-22 16:03:33 -08001732 leaderResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001733 main.log.report( cli.name + " sees " + str( leaderN ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08001734 " as the leader of the election app. " +
1735 "Leader should be " + str( leader ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001736 if leaderResult:
1737 main.log.report( "Leadership election tests passed( consistent " +
Jon Hall6aec96b2015-01-19 14:49:31 -08001738 "view of leader across listeners and a new " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001739 "leader was re-elected if applicable )" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001740 utilities.assert_equals(
1741 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001742 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001743 onpass="Leadership election passed",
1744 onfail="Something went wrong with Leadership election" )
Jon Hallb1290e82014-11-18 16:17:48 -05001745
Jon Hall58c76b72015-02-23 11:09:24 -08001746 result = ( mastershipCheck and intentCheck and FlowTables and
1747 ( not LossInPings ) and rolesNotNull and leaderResult )
Jon Hall6aec96b2015-01-19 14:49:31 -08001748 result = int( result )
Jon Hallb1290e82014-11-18 16:17:48 -05001749 if result == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001750 main.log.report( "Constant State Tests Passed" )
1751 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall58c76b72015-02-23 11:09:24 -08001752 onpass="Constant State Tests Passed",
1753 onfail="Constant state tests failed" )
Jon Hallb1290e82014-11-18 16:17:48 -05001754
Jon Hall6aec96b2015-01-19 14:49:31 -08001755 def CASE8( self, main ):
1756 """
Jon Hallb1290e82014-11-18 16:17:48 -05001757 Compare topo
Jon Hall6aec96b2015-01-19 14:49:31 -08001758 """
Jon Hallb1290e82014-11-18 16:17:48 -05001759 import sys
Jon Hall6aec96b2015-01-19 14:49:31 -08001760 # FIXME add this path to params
1761 sys.path.append( "/home/admin/sts" )
1762 # assumes that sts is already in you PYTHONPATH
1763 from sts.topology.teston_topology import TestONTopology
Jon Hallb1290e82014-11-18 16:17:48 -05001764 import json
Jon Hall73cf9cc2014-11-20 22:28:38 -08001765 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001766 assert numControllers, "numControllers not defined"
1767 assert main, "main not defined"
1768 assert utilities.assert_equals, "utilities.assert_equals not defined"
1769 assert CLIs, "CLIs not defined"
1770 assert nodes, "nodes not defined"
Jon Hallb1290e82014-11-18 16:17:48 -05001771
Jon Hall6aec96b2015-01-19 14:49:31 -08001772 description = "Compare ONOS Topology view to Mininet topology"
1773 main.case( description )
1774 main.log.report( description )
1775 main.step( "Create TestONTopology object" )
Jon Hallb1290e82014-11-18 16:17:48 -05001776 ctrls = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001777 for node in nodes:
1778 temp = ( node, node.name, node.ip_address, 6633 )
1779 ctrls.append( temp )
Jon Hall65844a32015-03-09 19:09:37 -07001780 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hallb1290e82014-11-18 16:17:48 -05001781
Jon Hall6aec96b2015-01-19 14:49:31 -08001782 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001783 devicesResults = main.TRUE
1784 portsResults = main.TRUE
1785 linksResults = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08001786 hostsResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -08001787 topoResult = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001788 elapsed = 0
Jon Hallffb386d2014-11-21 13:43:38 -08001789 count = 0
Jon Hall6aec96b2015-01-19 14:49:31 -08001790 main.step( "Collecting topology information from ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001791 startTime = time.time()
Jon Hall21270ac2015-02-16 17:59:55 -08001792 # Give time for Gossip to work
Jon Hall8f89dda2015-01-22 16:03:33 -08001793 while topoResult == main.FALSE and elapsed < 60:
Jon Hall65844a32015-03-09 19:09:37 -07001794 count += 1
Jon Hall94fd0472014-12-08 11:52:42 -08001795 if count > 1:
Jon Hall65844a32015-03-09 19:09:37 -07001796 # TODO: Deprecate STS usage
Jon Hall58c76b72015-02-23 11:09:24 -08001797 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall8f89dda2015-01-22 16:03:33 -08001798 cliStart = time.time()
Jon Hall94fd0472014-12-08 11:52:42 -08001799 devices = []
Jon Hall65844a32015-03-09 19:09:37 -07001800 threads = []
1801 for i in range( numControllers ):
1802 t = main.Thread( target=CLIs[i].devices,
Jon Hall65844a32015-03-09 19:09:37 -07001803 name="devices-" + str( i ),
1804 args=[ ] )
1805 threads.append( t )
1806 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001807
1808 for t in threads:
1809 t.join()
1810 devices.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001811 hosts = []
Jon Hall58c76b72015-02-23 11:09:24 -08001812 ipResult = main.TRUE
Jon Hall65844a32015-03-09 19:09:37 -07001813 threads = []
1814 for i in range( numControllers ):
1815 t = main.Thread( target=CLIs[i].hosts,
Jon Hall65844a32015-03-09 19:09:37 -07001816 name="hosts-" + str( i ),
1817 args=[ ] )
1818 threads.append( t )
1819 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001820
1821 for t in threads:
1822 t.join()
Jon Hall5cfd23c2015-03-19 11:40:57 -07001823 try:
1824 hosts.append( json.loads( t.result ) )
1825 except ( ValueError, TypeError ):
1826 main.log.exception( "Error parsing hosts results" )
1827 main.log.error( repr( t.result ) )
Jon Hall529a37f2015-01-28 10:02:00 -08001828 for controller in range( 0, len( hosts ) ):
1829 controllerStr = str( controller + 1 )
1830 for host in hosts[ controller ]:
Jon Hall58c76b72015-02-23 11:09:24 -08001831 if host is None or host.get( 'ips', [] ) == []:
Jon Hall529a37f2015-01-28 10:02:00 -08001832 main.log.error(
1833 "DEBUG:Error with host ips on controller" +
1834 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001835 ipResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001836 ports = []
Jon Hall65844a32015-03-09 19:09:37 -07001837 threads = []
1838 for i in range( numControllers ):
1839 t = main.Thread( target=CLIs[i].ports,
Jon Hall65844a32015-03-09 19:09:37 -07001840 name="ports-" + str( i ),
1841 args=[ ] )
1842 threads.append( t )
1843 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001844
1845 for t in threads:
1846 t.join()
1847 ports.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001848 links = []
Jon Hall65844a32015-03-09 19:09:37 -07001849 threads = []
1850 for i in range( numControllers ):
1851 t = main.Thread( target=CLIs[i].links,
Jon Hall65844a32015-03-09 19:09:37 -07001852 name="links-" + str( i ),
1853 args=[ ] )
1854 threads.append( t )
1855 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001856
1857 for t in threads:
1858 t.join()
1859 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001860 clusters = []
Jon Hall65844a32015-03-09 19:09:37 -07001861 threads = []
1862 for i in range( numControllers ):
1863 t = main.Thread( target=CLIs[i].clusters,
Jon Hall65844a32015-03-09 19:09:37 -07001864 name="clusters-" + str( i ),
1865 args=[ ] )
1866 threads.append( t )
1867 t.start()
Jon Hall65844a32015-03-09 19:09:37 -07001868
1869 for t in threads:
1870 t.join()
1871 clusters.append( t.result )
Jon Hallb1290e82014-11-18 16:17:48 -05001872
Jon Hall8f89dda2015-01-22 16:03:33 -08001873 elapsed = time.time() - startTime
1874 cliTime = time.time() - cliStart
1875 print "CLI time: " + str( cliTime )
Jon Hallb1290e82014-11-18 16:17:48 -05001876
Jon Hall21270ac2015-02-16 17:59:55 -08001877 for controller in range( numControllers ):
1878 controllerStr = str( controller + 1 )
1879 if devices[ controller ] or "Error" not in devices[
1880 controller ]:
1881 currentDevicesResult = main.Mininet1.compareSwitches(
1882 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08001883 json.loads( devices[ controller ] ) )
Jon Hall21270ac2015-02-16 17:59:55 -08001884 else:
1885 currentDevicesResult = main.FALSE
1886 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001887 actual=currentDevicesResult,
1888 onpass="ONOS" + controllerStr +
1889 " Switches view is correct",
1890 onfail="ONOS" + controllerStr +
1891 " Switches view is incorrect" )
Jon Hallb1290e82014-11-18 16:17:48 -05001892
Jon Hall21270ac2015-02-16 17:59:55 -08001893 if ports[ controller ] or "Error" not in ports[ controller ]:
1894 currentPortsResult = main.Mininet1.comparePorts(
1895 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08001896 json.loads( ports[ controller ] ) )
Jon Hall21270ac2015-02-16 17:59:55 -08001897 else:
1898 currentPortsResult = main.FALSE
1899 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001900 actual=currentPortsResult,
1901 onpass="ONOS" + controllerStr +
1902 " ports view is correct",
1903 onfail="ONOS" + controllerStr +
1904 " ports view is incorrect" )
Jon Hall94fd0472014-12-08 11:52:42 -08001905
Jon Hall21270ac2015-02-16 17:59:55 -08001906 if links[ controller ] or "Error" not in links[ controller ]:
1907 currentLinksResult = main.Mininet1.compareLinks(
1908 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08001909 json.loads( links[ controller ] ) )
Jon Hall21270ac2015-02-16 17:59:55 -08001910 else:
1911 currentLinksResult = main.FALSE
1912 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001913 actual=currentLinksResult,
1914 onpass="ONOS" + controllerStr +
1915 " links view is correct",
1916 onfail="ONOS" + controllerStr +
1917 " links view is incorrect" )
1918
1919 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1920 currentHostsResult = main.Mininet1.compareHosts(
1921 MNTopo, hosts[ controller ] )
1922 else:
1923 currentHostsResult = main.FALSE
1924 utilities.assert_equals( expect=main.TRUE,
1925 actual=currentHostsResult,
1926 onpass="ONOS" + controllerStr +
1927 " hosts exist in Mininet",
1928 onfail="ONOS" + controllerStr +
1929 " hosts don't match Mininet" )
1930
1931 devicesResults = devicesResults and currentDevicesResult
1932 portsResults = portsResults and currentPortsResult
1933 linksResults = linksResults and currentLinksResult
1934 hostsResults = hostsResults and currentHostsResult
Jon Hall94fd0472014-12-08 11:52:42 -08001935
Jon Hall21270ac2015-02-16 17:59:55 -08001936 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08001937
Jon Hall21270ac2015-02-16 17:59:55 -08001938 # hosts
1939 consistentHostsResult = main.TRUE
1940 for controller in range( len( hosts ) ):
1941 controllerStr = str( controller + 1 )
1942 if "Error" not in hosts[ controller ]:
1943 if hosts[ controller ] == hosts[ 0 ]:
1944 continue
1945 else: # hosts not consistent
1946 main.log.report( "hosts from ONOS" + controllerStr +
1947 " is inconsistent with ONOS1" )
1948 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001949 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001950
Jon Hall21270ac2015-02-16 17:59:55 -08001951 else:
1952 main.log.report( "Error in getting ONOS hosts from ONOS" +
1953 controllerStr )
1954 consistentHostsResult = main.FALSE
1955 main.log.warn( "ONOS" + controllerStr +
1956 " hosts response: " +
1957 repr( hosts[ controller ] ) )
1958 utilities.assert_equals(
1959 expect=main.TRUE,
1960 actual=consistentHostsResult,
1961 onpass="Hosts view is consistent across all ONOS nodes",
1962 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08001963
Jon Hall21270ac2015-02-16 17:59:55 -08001964 # Strongly connected clusters of devices
1965 consistentClustersResult = main.TRUE
1966 for controller in range( len( clusters ) ):
1967 controllerStr = str( controller + 1 )
1968 if "Error" not in clusters[ controller ]:
1969 if clusters[ controller ] == clusters[ 0 ]:
1970 continue
1971 else: # clusters not consistent
1972 main.log.report( "clusters from ONOS" +
1973 controllerStr +
1974 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001975 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001976
Jon Hall21270ac2015-02-16 17:59:55 -08001977 else:
1978 main.log.report( "Error in getting dataplane clusters " +
1979 "from ONOS" + controllerStr )
1980 consistentClustersResult = main.FALSE
1981 main.log.warn( "ONOS" + controllerStr +
1982 " clusters response: " +
1983 repr( clusters[ controller ] ) )
1984 utilities.assert_equals(
1985 expect=main.TRUE,
1986 actual=consistentClustersResult,
1987 onpass="Clusters view is consistent across all ONOS nodes",
1988 onfail="ONOS nodes have different views of clusters" )
1989 # there should always only be one cluster
Jon Hall5cfd23c2015-03-19 11:40:57 -07001990 try:
1991 numClusters = len( json.loads( clusters[ 0 ] ) )
1992 except ( ValueError, TypeError ):
1993 main.log.exception( "Error parsing clusters[0]: " +
1994 repr( clusters[0] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001995 clusterResults = main.FALSE
1996 if numClusters == 1:
1997 clusterResults = main.TRUE
Jon Hall21270ac2015-02-16 17:59:55 -08001998 utilities.assert_equals(
1999 expect=1,
2000 actual=numClusters,
2001 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08002002 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08002003
Jon Hall21270ac2015-02-16 17:59:55 -08002004 topoResult = ( devicesResults and portsResults and linksResults
Jon Hall58c76b72015-02-23 11:09:24 -08002005 and hostsResults and consistentHostsResult
2006 and consistentClustersResult and clusterResults
2007 and ipResult )
Jon Hall94fd0472014-12-08 11:52:42 -08002008
Jon Hall21270ac2015-02-16 17:59:55 -08002009 topoResult = topoResult and int( count <= 2 )
2010 note = "note it takes about " + str( int( cliTime ) ) + \
2011 " seconds for the test to make all the cli calls to fetch " +\
2012 "the topology from each ONOS instance"
2013 main.log.info(
2014 "Very crass estimate for topology discovery/convergence( " +
2015 str( note ) + " ): " + str( elapsed ) + " seconds, " +
2016 str( count ) + " tries" )
2017 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08002018 onpass="Topology Check Test successful",
2019 onfail="Topology Check Test NOT successful" )
Jon Hall21270ac2015-02-16 17:59:55 -08002020 if topoResult == main.TRUE:
2021 main.log.report( "ONOS topology view matches Mininet topology" )
Jon Hallb1290e82014-11-18 16:17:48 -05002022
Jon Hall5cfd23c2015-03-19 11:40:57 -07002023 #FIXME: move this to an ONOS state case
2024 main.step( "Checking ONOS nodes" )
2025 nodesOutput = []
2026 threads = []
2027 for i in range( numControllers ):
2028 t = main.Thread( target=CLIs[i].nodes,
2029 name="nodes-" + str( i ),
2030 args=[ ] )
2031 threads.append( t )
2032 t.start()
2033
2034 for t in threads:
2035 t.join()
2036 nodesOutput.append( t.result )
2037 ips = [ node.ip_address for node in nodes ]
2038 for i in nodesOutput:
2039 try:
2040 current = json.loads( i )
2041 for node in current:
2042 if node['ip'] in ips: # node in nodes() output is in cell
2043 if node['state'] == 'ACTIVE':
2044 pass # as it should be
2045 else:
2046 main.log.error( "Error in ONOS node availability" )
2047 main.log.error(
2048 json.dumps( current,
2049 sort_keys=True,
2050 indent=4,
2051 separators=( ',', ': ' ) ) )
2052 break
2053 except ( ValueError, TypeError ):
2054 main.log.error( "Error parsing nodes output" )
2055 main.log.warn( repr( i ) )
2056
Jon Hall6aec96b2015-01-19 14:49:31 -08002057 def CASE9( self, main ):
2058 """
Jon Hallb1290e82014-11-18 16:17:48 -05002059 Link s3-s28 down
Jon Hall6aec96b2015-01-19 14:49:31 -08002060 """
2061 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002062 assert numControllers, "numControllers not defined"
2063 assert main, "main not defined"
2064 assert utilities.assert_equals, "utilities.assert_equals not defined"
2065 assert CLIs, "CLIs not defined"
2066 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002067 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002068
Jon Hall8f89dda2015-01-22 16:03:33 -08002069 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hallb1290e82014-11-18 16:17:48 -05002070
Jon Hall6aec96b2015-01-19 14:49:31 -08002071 description = "Turn off a link to ensure that Link Discovery " +\
Jon Hall58c76b72015-02-23 11:09:24 -08002072 "is working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002073 main.log.report( description )
2074 main.case( description )
Jon Hallb1290e82014-11-18 16:17:48 -05002075
Jon Hall6aec96b2015-01-19 14:49:31 -08002076 main.step( "Kill Link between s3 and s28" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002077 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
Jon Hall58c76b72015-02-23 11:09:24 -08002078 main.log.info( "Waiting " + str( linkSleep ) +
2079 " seconds for link down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002080 time.sleep( linkSleep )
2081 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
Jon Hall65844a32015-03-09 19:09:37 -07002082 onpass="Link down successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002083 onfail="Failed to bring link down" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002084 # TODO do some sort of check here
Jon Hallb1290e82014-11-18 16:17:48 -05002085
Jon Hall6aec96b2015-01-19 14:49:31 -08002086 def CASE10( self, main ):
2087 """
Jon Hallb1290e82014-11-18 16:17:48 -05002088 Link s3-s28 up
Jon Hall6aec96b2015-01-19 14:49:31 -08002089 """
2090 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 Hall6aec96b2015-01-19 14:49:31 -08002096 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002097
Jon Hall8f89dda2015-01-22 16:03:33 -08002098 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hallb1290e82014-11-18 16:17:48 -05002099
Jon Hall6aec96b2015-01-19 14:49:31 -08002100 description = "Restore a link to ensure that Link Discovery is " + \
Jon Hall63604932015-02-26 17:09:50 -08002101 "working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002102 main.log.report( description )
2103 main.case( description )
Jon Hallb1290e82014-11-18 16:17:48 -05002104
Jon Hall6aec96b2015-01-19 14:49:31 -08002105 main.step( "Bring link between s3 and s28 back up" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002106 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
Jon Hall58c76b72015-02-23 11:09:24 -08002107 main.log.info( "Waiting " + str( linkSleep ) +
2108 " seconds for link up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002109 time.sleep( linkSleep )
2110 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
Jon Hall65844a32015-03-09 19:09:37 -07002111 onpass="Link up successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002112 onfail="Failed to bring link up" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002113 # TODO do some sort of check here
Jon Hallb1290e82014-11-18 16:17:48 -05002114
Jon Hall6aec96b2015-01-19 14:49:31 -08002115 def CASE11( self, main ):
2116 """
Jon Hallb1290e82014-11-18 16:17:48 -05002117 Switch Down
Jon Hall6aec96b2015-01-19 14:49:31 -08002118 """
2119 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002120 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002121 assert numControllers, "numControllers not defined"
2122 assert main, "main not defined"
2123 assert utilities.assert_equals, "utilities.assert_equals not defined"
2124 assert CLIs, "CLIs not defined"
2125 assert nodes, "nodes not defined"
Jon Hallb1290e82014-11-18 16:17:48 -05002126
Jon Hall8f89dda2015-01-22 16:03:33 -08002127 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hallb1290e82014-11-18 16:17:48 -05002128
2129 description = "Killing a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002130 main.log.report( description )
2131 main.case( description )
2132 switch = main.params[ 'kill' ][ 'switch' ]
2133 switchDPID = main.params[ 'kill' ][ 'dpid' ]
Jon Hallb1290e82014-11-18 16:17:48 -05002134
Jon Hall6aec96b2015-01-19 14:49:31 -08002135 # TODO: Make this switch parameterizable
2136 main.step( "Kill " + switch )
2137 main.log.report( "Deleting " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002138 main.Mininet1.delSwitch( switch )
2139 main.log.info( "Waiting " + str( switchSleep ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002140 " seconds for switch down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002141 time.sleep( switchSleep )
2142 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002143 # Peek at the deleted switch
2144 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002145 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002146 if device and device[ 'available' ] is False:
Jon Hall94fd0472014-12-08 11:52:42 -08002147 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002148 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall65844a32015-03-09 19:09:37 -07002149 onpass="Kill switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002150 onfail="Failed to kill switch?" )
Jon Hallb1290e82014-11-18 16:17:48 -05002151
Jon Hall6aec96b2015-01-19 14:49:31 -08002152 def CASE12( self, main ):
2153 """
Jon Hallb1290e82014-11-18 16:17:48 -05002154 Switch Up
Jon Hall6aec96b2015-01-19 14:49:31 -08002155 """
2156 # NOTE: You should probably run a topology check after this
Jon Hallb1290e82014-11-18 16:17:48 -05002157 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002158 assert numControllers, "numControllers not defined"
2159 assert main, "main not defined"
2160 assert utilities.assert_equals, "utilities.assert_equals not defined"
2161 assert CLIs, "CLIs not defined"
2162 assert nodes, "nodes not defined"
2163 assert ONOS1Port, "ONOS1Port not defined"
2164 assert ONOS2Port, "ONOS2Port not defined"
2165 assert ONOS3Port, "ONOS3Port not defined"
2166 assert ONOS4Port, "ONOS4Port not defined"
2167 assert ONOS5Port, "ONOS5Port not defined"
2168 assert ONOS6Port, "ONOS6Port not defined"
2169 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall669173b2014-12-17 11:36:30 -08002170
Jon Hall8f89dda2015-01-22 16:03:33 -08002171 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall6aec96b2015-01-19 14:49:31 -08002172 switch = main.params[ 'kill' ][ 'switch' ]
2173 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2174 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hallb1290e82014-11-18 16:17:48 -05002175 description = "Adding a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002176 main.log.report( description )
2177 main.case( description )
Jon Hallb1290e82014-11-18 16:17:48 -05002178
Jon Hall6aec96b2015-01-19 14:49:31 -08002179 main.step( "Add back " + switch )
2180 main.log.report( "Adding back " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002181 main.Mininet1.addSwitch( switch, dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002182 for peer in links:
Jon Hall8f89dda2015-01-22 16:03:33 -08002183 main.Mininet1.addLink( switch, peer )
Jon Hall58c76b72015-02-23 11:09:24 -08002184 main.Mininet1.assignSwController( sw=switch.split( 's' )[ 1 ],
2185 count=numControllers,
Jon Hall65844a32015-03-09 19:09:37 -07002186 ip1=nodes[ 0 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002187 port1=ONOS1Port,
Jon Hall65844a32015-03-09 19:09:37 -07002188 ip2=nodes[ 1 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002189 port2=ONOS2Port,
Jon Hall65844a32015-03-09 19:09:37 -07002190 ip3=nodes[ 2 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002191 port3=ONOS3Port,
Jon Hall65844a32015-03-09 19:09:37 -07002192 ip4=nodes[ 3 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002193 port4=ONOS4Port,
Jon Hall65844a32015-03-09 19:09:37 -07002194 ip5=nodes[ 4 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002195 port5=ONOS5Port,
Jon Hall65844a32015-03-09 19:09:37 -07002196 ip6=nodes[ 5 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002197 port6=ONOS6Port,
Jon Hall65844a32015-03-09 19:09:37 -07002198 ip7=nodes[ 6 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002199 port7=ONOS7Port )
2200 main.log.info( "Waiting " + str( switchSleep ) +
2201 " seconds for switch up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002202 time.sleep( switchSleep )
2203 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002204 # Peek at the deleted switch
2205 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002206 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002207 if device and device[ 'available' ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002208 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002209 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall65844a32015-03-09 19:09:37 -07002210 onpass="add switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002211 onfail="Failed to add switch?" )
Jon Hallb1290e82014-11-18 16:17:48 -05002212
Jon Hall6aec96b2015-01-19 14:49:31 -08002213 def CASE13( self, main ):
2214 """
Jon Hallb1290e82014-11-18 16:17:48 -05002215 Clean up
Jon Hall6aec96b2015-01-19 14:49:31 -08002216 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002217 import os
2218 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002219 assert numControllers, "numControllers not defined"
2220 assert main, "main not defined"
2221 assert utilities.assert_equals, "utilities.assert_equals not defined"
2222 assert CLIs, "CLIs not defined"
2223 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002224
2225 # printing colors to terminal
Jon Hall65844a32015-03-09 19:09:37 -07002226 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2227 'blue': '\033[94m', 'green': '\033[92m',
2228 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
Jon Hall368769f2014-11-19 15:43:35 -08002229 description = "Test Cleanup"
Jon Hall6aec96b2015-01-19 14:49:31 -08002230 main.log.report( description )
2231 main.case( description )
2232 main.step( "Killing tcpdumps" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002233 main.Mininet2.stopTcpdump()
Jon Hallb1290e82014-11-18 16:17:48 -05002234
Jon Hall6aec96b2015-01-19 14:49:31 -08002235 main.step( "Copying MN pcap and ONOS log files to test station" )
Jon Hallb1290e82014-11-18 16:17:48 -05002236 testname = main.TEST
Jon Hall8f89dda2015-01-22 16:03:33 -08002237 teststationUser = main.params[ 'TESTONUSER' ]
2238 teststationIP = main.params[ 'TESTONIP' ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002239 # NOTE: MN Pcap file is being saved to ~/packet_captures
Jon Hall73cf9cc2014-11-20 22:28:38 -08002240 # scp this file as MN and TestON aren't necessarily the same vm
Jon Hall6aec96b2015-01-19 14:49:31 -08002241 # FIXME: scp
2242 # mn files
2243 # TODO: Load these from params
2244 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002245 logFolder = "/opt/onos/log/"
2246 logFiles = [ "karaf.log", "karaf.log.1" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002247 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002248 dstDir = "~/packet_captures/"
2249 for f in logFiles:
Jon Hall65844a32015-03-09 19:09:37 -07002250 for node in nodes:
2251 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2252 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002253 teststationUser + "@" +
2254 teststationIP + ":" +
2255 dstDir + str( testname ) +
Jon Hall65844a32015-03-09 19:09:37 -07002256 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002257 main.ONOSbench.handle.expect( "\$" )
2258
Jon Hall6aec96b2015-01-19 14:49:31 -08002259 # std*.log's
2260 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002261 logFolder = "/opt/onos/var/"
2262 logFiles = [ "stderr.log", "stdout.log" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002263 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002264 dstDir = "~/packet_captures/"
2265 for f in logFiles:
Jon Hall65844a32015-03-09 19:09:37 -07002266 for node in nodes:
2267 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2268 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002269 teststationUser + "@" +
2270 teststationIP + ":" +
2271 dstDir + str( testname ) +
Jon Hall65844a32015-03-09 19:09:37 -07002272 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002273 main.ONOSbench.handle.expect( "\$" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002274 # sleep so scp can finish
2275 time.sleep( 10 )
Jon Hall65844a32015-03-09 19:09:37 -07002276
2277 main.step( "Stopping Mininet" )
Jon Hall58c76b72015-02-23 11:09:24 -08002278 main.Mininet1.stopNet()
Jon Hall65844a32015-03-09 19:09:37 -07002279
2280 main.step( "Checking ONOS Logs for errors" )
2281 for node in nodes:
2282 print colors[ 'purple' ] + "Checking logs for errors on " + \
2283 node.name + ":" + colors[ 'end' ]
2284 print main.ONOSbench.checkLogs( node.ip_address )
2285
Jon Hall6aec96b2015-01-19 14:49:31 -08002286 main.step( "Packing and rotating pcap archives" )
2287 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002288
Jon Hall6aec96b2015-01-19 14:49:31 -08002289 # TODO: actually check something here
2290 utilities.assert_equals( expect=main.TRUE, actual=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002291 onpass="Test cleanup successful",
2292 onfail="Test cleanup NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002293
Jon Hall6aec96b2015-01-19 14:49:31 -08002294 def CASE14( self, main ):
2295 """
Jon Hall94fd0472014-12-08 11:52:42 -08002296 start election app on all onos nodes
Jon Hall6aec96b2015-01-19 14:49:31 -08002297 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07002298 assert numControllers, "numControllers not defined"
2299 assert main, "main not defined"
2300 assert utilities.assert_equals, "utilities.assert_equals not defined"
2301 assert CLIs, "CLIs not defined"
2302 assert nodes, "nodes not defined"
2303
Jon Hall8f89dda2015-01-22 16:03:33 -08002304 leaderResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002305 # install app on onos 1
2306 main.log.info( "Install leadership election app" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002307 main.ONOScli1.featureInstall( "onos-app-election" )
Jon Hall65844a32015-03-09 19:09:37 -07002308 leader = nodes[0].ip_address
Jon Hall6aec96b2015-01-19 14:49:31 -08002309 # wait for election
2310 # check for leader
Jon Hall65844a32015-03-09 19:09:37 -07002311 leader1 = main.ONOScli1.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08002312 # verify leader is ONOS1
Jon Hall65844a32015-03-09 19:09:37 -07002313 if leader1 == leader:
Jon Hall6aec96b2015-01-19 14:49:31 -08002314 # all is well
Jon Hall669173b2014-12-17 11:36:30 -08002315 pass
Jon Hall65844a32015-03-09 19:09:37 -07002316 elif leader1 is None:
Jon Hall6aec96b2015-01-19 14:49:31 -08002317 # No leader elected
2318 main.log.report( "No leader was elected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002319 leaderResult = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07002320 elif leader1 == 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
Jon Hall8f89dda2015-01-22 16:03:33 -08002324 main.log.report( "Something is wrong with electionTestLeader" +
Jon Hall6aec96b2015-01-19 14:49:31 -08002325 " function, check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002326 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002327 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08002328 # error in response
2329 main.log.report(
Jon Hall8f89dda2015-01-22 16:03:33 -08002330 "Unexpected response from electionTestLeader function:'" +
Jon Hall65844a32015-03-09 19:09:37 -07002331 str( leader1 ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002332 leaderResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002333
Jon Hall6aec96b2015-01-19 14:49:31 -08002334 # install on other nodes and check for leader.
Jon Hall65844a32015-03-09 19:09:37 -07002335 # Leader should be ONOS1 and each app should show the same leader
Jon Hall5cfd23c2015-03-19 11:40:57 -07002336 for cli in CLIs[ 1: ]:
2337 cli.featureInstall( "onos-app-election" )
2338 leaderN = cli.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08002339 # verify leader is ONOS1
Jon Hall65844a32015-03-09 19:09:37 -07002340 if leaderN == leader:
Jon Hall6aec96b2015-01-19 14:49:31 -08002341 # all is well
Jon Hall669173b2014-12-17 11:36:30 -08002342 pass
2343 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002344 # error in response
2345 # TODO: add check for "Command not found:" in the driver, this
2346 # means the app isn't loaded
2347 main.log.report( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002348 "electionTestLeader function, check the" +
Jon Hall6aec96b2015-01-19 14:49:31 -08002349 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002350 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002351 elif leader != leaderN:
Jon Hall8f89dda2015-01-22 16:03:33 -08002352 leaderResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002353 main.log.report( cli.name + " sees " + str( leaderN ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002354 " as the leader of the election app. Leader" +
2355 " should be " +
2356 str( leader ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08002357 if leaderResult:
Jon Hall6aec96b2015-01-19 14:49:31 -08002358 main.log.report( "Leadership election tests passed( consistent " +
2359 "view of leader across listeners and a leader " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002360 "was elected )" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002361 utilities.assert_equals(
2362 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002363 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002364 onpass="Leadership election passed",
2365 onfail="Something went wrong with Leadership election" )
Jon Hall94fd0472014-12-08 11:52:42 -08002366
Jon Hall6aec96b2015-01-19 14:49:31 -08002367 def CASE15( self, main ):
2368 """
Jon Hall669173b2014-12-17 11:36:30 -08002369 Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -08002370 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07002371 assert numControllers, "numControllers not defined"
2372 assert main, "main not defined"
2373 assert utilities.assert_equals, "utilities.assert_equals not defined"
2374 assert CLIs, "CLIs not defined"
2375 assert nodes, "nodes not defined"
2376
Jon Hall8f89dda2015-01-22 16:03:33 -08002377 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002378 description = "Check that Leadership Election is still functional"
Jon Hall6aec96b2015-01-19 14:49:31 -08002379 main.log.report( description )
2380 main.case( description )
2381 main.step( "Find current leader and withdraw" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002382 leader = main.ONOScli1.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08002383 # TODO: do some sanity checking on leader before using it
Jon Hall8f89dda2015-01-22 16:03:33 -08002384 withdrawResult = main.FALSE
Jon Hall65844a32015-03-09 19:09:37 -07002385 if leader is None or leader == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002386 main.log.report(
2387 "Leader for the election app should be an ONOS node," +
Jon Hall58c76b72015-02-23 11:09:24 -08002388 "instead got '" + str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002389 leaderResult = main.FALSE
Jon Hall63604932015-02-26 17:09:50 -08002390 oldLeader = None
Jon Hall65844a32015-03-09 19:09:37 -07002391 for i in range( len( CLIs ) ):
2392 if leader == nodes[ i ].ip_address:
2393 oldLeader = CLIs[ i ]
2394 break
Jon Hall63604932015-02-26 17:09:50 -08002395 else:
Jon Hall65844a32015-03-09 19:09:37 -07002396 main.log.error( "Leader election, could not find current leader" )
Jon Hall63604932015-02-26 17:09:50 -08002397 if oldLeader:
2398 withdrawResult = oldLeader.electionTestWithdraw()
Jon Hall6aec96b2015-01-19 14:49:31 -08002399 utilities.assert_equals(
2400 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002401 actual=withdrawResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002402 onpass="App was withdrawn from election",
2403 onfail="App was not withdrawn from election" )
Jon Hall669173b2014-12-17 11:36:30 -08002404
Jon Hall6aec96b2015-01-19 14:49:31 -08002405 main.step( "Make sure new leader is elected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002406 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002407 for cli in CLIs:
2408 leaderN = cli.electionTestLeader()
Jon Hall65844a32015-03-09 19:09:37 -07002409 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08002410 if leaderN == leader:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002411 main.log.report( cli.name + " still sees " + str( leader ) +
Jon Hall65844a32015-03-09 19:09:37 -07002412 " as leader after they withdrew" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002413 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002414 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002415 # error in response
2416 # TODO: add check for "Command not found:" in the driver, this
Jon Hall65844a32015-03-09 19:09:37 -07002417 # means the app isn't loaded
Jon Hall6aec96b2015-01-19 14:49:31 -08002418 main.log.report( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002419 "electionTestLeader function, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002420 "check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002421 leaderResult = main.FALSE
2422 consistentLeader = main.FALSE
2423 if len( set( leaderList ) ) == 1:
Jon Hall6aec96b2015-01-19 14:49:31 -08002424 main.log.info( "Each Election-app sees '" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002425 str( leaderList[ 0 ] ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002426 "' as the leader" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002427 consistentLeader = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002428 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08002429 main.log.report(
2430 "Inconsistent responses for leader of Election-app:" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002431 for n in range( len( leaderList ) ):
Jon Hall6aec96b2015-01-19 14:49:31 -08002432 main.log.report( "ONOS" + str( n + 1 ) + " response: " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002433 str( leaderList[ n ] ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002434 leaderResult = leaderResult and consistentLeader
Jon Hall8f89dda2015-01-22 16:03:33 -08002435 if leaderResult:
2436 main.log.report( "Leadership election tests passed( consistent " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002437 "view of leader across listeners and a new " +
2438 "leader was elected when the old leader " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002439 "resigned )" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002440 utilities.assert_equals(
2441 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002442 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002443 onpass="Leadership election passed",
2444 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002445
Jon Hall58c76b72015-02-23 11:09:24 -08002446 main.step( "Run for election on old leader( just so everyone " +
2447 "is in the hat )" )
Jon Hall63604932015-02-26 17:09:50 -08002448 if oldLeader:
2449 runResult = oldLeader.electionTestRun()
2450 else:
2451 runResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002452 utilities.assert_equals(
2453 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002454 actual=runResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002455 onpass="App re-ran for election",
2456 onfail="App failed to run for election" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002457 if consistentLeader == main.TRUE:
2458 afterRun = main.ONOScli1.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08002459 # verify leader didn't just change
Jon Hall8f89dda2015-01-22 16:03:33 -08002460 if afterRun == leaderList[ 0 ]:
2461 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002462 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002463 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002464 # TODO: assert on run and withdraw results?
Jon Hall669173b2014-12-17 11:36:30 -08002465
Jon Hall6aec96b2015-01-19 14:49:31 -08002466 utilities.assert_equals(
2467 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002468 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002469 onpass="Leadership election passed",
2470 onfail="Something went wrong with Leadership election after " +
2471 "the old leader re-ran for election" )