blob: 893657869339224091f6146efc61b5c868c11f1f [file] [log] [blame]
Jon Hallb1290e82014-11-18 16:17:48 -05001'''
2Description: 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.
13CASE7: Check state after failure
14CASE8: Compare topo
15CASE9: Link s3-s28 down
16CASE10: Link s3-s28 up
17CASE11: Switch down
18CASE12: Switch up
19CASE13: Clean up
20'''
21class HATestSanity:
22
23 def __init__(self) :
24 self.default = ''
25
26 def CASE1(self,main) :
27 '''
28 CASE1 is to compile ONOS and push it to the test machines
29
30 Startup sequence:
31 git pull
32 mvn clean install
33 onos-package
34 cell <name>
35 onos-verify-cell
36 NOTE: temporary - onos-remove-raft-logs
37 onos-install -f
38 onos-wait-for-start
39 '''
40 import time
41 main.log.report("ONOS HA Sanity test initialization")
42 main.case("Setting up test environment")
43
44 # load some vairables from the params file
45 PULL_CODE = False
46 if main.params['Git'] == 'True':
47 PULL_CODE = True
48 cell_name = main.params['ENV']['cellName']
49
50 #set global variables
51 global ONOS1_ip
52 global ONOS1_port
53 global ONOS2_ip
54 global ONOS2_port
55 global ONOS3_ip
56 global ONOS3_port
57 global ONOS4_ip
58 global ONOS4_port
59 global ONOS5_ip
60 global ONOS5_port
61 global ONOS6_ip
62 global ONOS6_port
63 global ONOS7_ip
64 global ONOS7_port
65
66 ONOS1_ip = main.params['CTRL']['ip1']
67 ONOS1_port = main.params['CTRL']['port1']
68 ONOS2_ip = main.params['CTRL']['ip2']
69 ONOS2_port = main.params['CTRL']['port2']
70 ONOS3_ip = main.params['CTRL']['ip3']
71 ONOS3_port = main.params['CTRL']['port3']
72 ONOS4_ip = main.params['CTRL']['ip4']
73 ONOS4_port = main.params['CTRL']['port4']
74 ONOS5_ip = main.params['CTRL']['ip5']
75 ONOS5_port = main.params['CTRL']['port5']
76 ONOS6_ip = main.params['CTRL']['ip6']
77 ONOS6_port = main.params['CTRL']['port6']
78 ONOS7_ip = main.params['CTRL']['ip7']
79 ONOS7_port = main.params['CTRL']['port7']
80
81
82 main.step("Applying cell variable to environment")
83 cell_result = main.ONOSbench.set_cell(cell_name)
84 verify_result = main.ONOSbench.verify_cell()
85 #FIXME:this is short term fix
86 main.ONOSbench.onos_remove_raft_logs()
87
88 clean_install_result = main.TRUE
89 git_pull_result = main.TRUE
90
91 main.step("Compiling the latest version of ONOS")
92 if PULL_CODE:
93 main.step("Git checkout and pull master")
94 main.ONOSbench.git_checkout("master")
95 git_pull_result = main.ONOSbench.git_pull()
96
97 main.step("Using mvn clean & install")
98 clean_install_result = main.TRUE
99 if git_pull_result == main.TRUE:
100 clean_install_result = main.ONOSbench.clean_install()
101 else:
102 main.log.report("Did not pull new code so skipping mvn "+ \
103 "clean install")
104 main.ONOSbench.get_version(report=True)
105
106 main.step("Creating ONOS package")
107 package_result = main.ONOSbench.onos_package()
108
109 main.step("Installing ONOS package")
110 onos1_install_result = main.ONOSbench.onos_install(options="-f",
111 node=ONOS1_ip)
112 onos2_install_result = main.ONOSbench.onos_install(options="-f",
113 node=ONOS2_ip)
114 onos3_install_result = main.ONOSbench.onos_install(options="-f",
115 node=ONOS3_ip)
116 onos4_install_result = main.ONOSbench.onos_install(options="-f",
117 node=ONOS4_ip)
118 onos5_install_result = main.ONOSbench.onos_install(options="-f",
119 node=ONOS5_ip)
120 onos6_install_result = main.ONOSbench.onos_install(options="-f",
121 node=ONOS6_ip)
122 onos7_install_result = main.ONOSbench.onos_install(options="-f",
123 node=ONOS7_ip)
124 onos_install_result = onos1_install_result and onos2_install_result\
125 and onos3_install_result and onos4_install_result\
126 and onos5_install_result and onos6_install_result\
127 and onos7_install_result
128
129
130 main.step("Checking if ONOS is up yet")
131 onos1_isup = main.ONOSbench.isup(ONOS1_ip)
132 onos2_isup = main.ONOSbench.isup(ONOS2_ip)
133 onos3_isup = main.ONOSbench.isup(ONOS3_ip)
134 onos4_isup = main.ONOSbench.isup(ONOS4_ip)
135 onos5_isup = main.ONOSbench.isup(ONOS5_ip)
136 onos6_isup = main.ONOSbench.isup(ONOS6_ip)
137 onos7_isup = main.ONOSbench.isup(ONOS7_ip)
138 onos_isup_result = onos1_isup and onos2_isup and onos3_isup\
139 and onos4_isup and onos5_isup and onos6_isup and onos7_isup
140 # TODO: if it becomes an issue, we can retry this step a few times
141
142
143 main.ONOScli1.start_onos_cli(ONOS1_ip)
144 main.ONOScli2.start_onos_cli(ONOS2_ip)
145 main.ONOScli3.start_onos_cli(ONOS3_ip)
146 main.ONOScli4.start_onos_cli(ONOS4_ip)
147 main.ONOScli5.start_onos_cli(ONOS5_ip)
148 main.ONOScli6.start_onos_cli(ONOS6_ip)
149 main.ONOScli7.start_onos_cli(ONOS7_ip)
150
151 #TODO: Enable once test is ready
152 #main.step("Start Packet Capture MN")
153 #main.Mininet2.start_tcpdump(
154 # str(main.params['MNtcpdump']['folder'])+str(main.TEST)+"-MN.pcap",
155 # intf = main.params['MNtcpdump']['intf'],
156 # port = main.params['MNtcpdump']['port'])
157
158
159 case1_result = (clean_install_result and package_result and
160 cell_result and verify_result and onos_install_result and
161 onos_isup_result)
162
163 utilities.assert_equals(expect=main.TRUE, actual=case1_result,
164 onpass="Test startup successful",
165 onfail="Test startup NOT successful")
166
167
168 #if case1_result==main.FALSE:
169 # main.cleanup()
170 # main.exit()
171
172 def CASE2(self,main) :
173 '''
174 Assign mastership to controllers
175 '''
176 import time
177 import json
178 import re
179
180
181 '''
182 ONOS1_ip = main.params['CTRL']['ip1']
183 ONOS1_port = main.params['CTRL']['port1']
184 ONOS2_ip = main.params['CTRL']['ip2']
185 ONOS2_port = main.params['CTRL']['port2']
186 ONOS3_ip = main.params['CTRL']['ip3']
187 ONOS3_port = main.params['CTRL']['port3']
188 ONOS4_ip = main.params['CTRL']['ip4']
189 ONOS4_port = main.params['CTRL']['port4']
190 ONOS5_ip = main.params['CTRL']['ip5']
191 ONOS5_port = main.params['CTRL']['port5']
192 ONOS6_ip = main.params['CTRL']['ip6']
193 ONOS6_port = main.params['CTRL']['port6']
194 ONOS7_ip = main.params['CTRL']['ip7']
195 ONOS7_port = main.params['CTRL']['port7']
196 '''
197
198
199 main.log.report("Assigning switches to controllers")
200 main.case("Assigning Controllers")
201 main.step("Assign switches to controllers")
202
203 for i in range (1,29):
204 main.Mininet1.assign_sw_controller(sw=str(i),count=7,
205 ip1=ONOS1_ip,port1=ONOS1_port,
206 ip2=ONOS2_ip,port2=ONOS2_port,
207 ip3=ONOS3_ip,port3=ONOS3_port,
208 ip4=ONOS4_ip,port4=ONOS4_port,
209 ip5=ONOS5_ip,port5=ONOS5_port,
210 ip6=ONOS6_ip,port6=ONOS6_port,
211 ip7=ONOS7_ip,port7=ONOS7_port)
212
213 mastership_check = main.TRUE
214 for i in range (1,29):
215 response = main.Mininet1.get_sw_controller("s"+str(i))
216 main.log.info(str(response))
217 if re.search("tcp:"+ONOS1_ip,response)\
218 and re.search("tcp:"+ONOS2_ip,response)\
219 and re.search("tcp:"+ONOS3_ip,response)\
220 and re.search("tcp:"+ONOS4_ip,response)\
221 and re.search("tcp:"+ONOS5_ip,response)\
222 and re.search("tcp:"+ONOS6_ip,response)\
223 and re.search("tcp:"+ONOS7_ip,response):
224 mastership_check = mastership_check and main.TRUE
225 else:
226 mastership_check = main.FALSE
227 if mastership_check == main.TRUE:
228 main.log.report("Switch mastership assigned correctly")
229 utilities.assert_equals(expect = main.TRUE,actual=mastership_check,
230 onpass="Switch mastership assigned correctly",
231 onfail="Switches not assigned correctly to controllers")
232
233 #TODO: If assign roles is working reliably then manually
234 # assign mastership to the controller we want
235
236
237 def CASE3(self,main) :
238 """
239 Assign intents
240
241 """
242 import time
243 import json
244 import re
245 main.log.report("Adding host intents")
246 main.case("Adding host Intents")
247
248 main.step("Discovering Hosts( Via pingall for now)")
249 #FIXME: Once we have a host discovery mechanism, use that instead
250
251 #REACTIVE FWD test
252 ping_result = main.FALSE
253 time1 = time.time()
254 ping_result = main.Mininet1.pingall()
255 time2 = time.time()
256 main.log.info("Time for pingall: %2f seconds" % (time2 - time1))
257
258 #uninstall onos-app-fwd
259 main.log.info("Uninstall reactive forwarding app")
260 main.ONOScli1.feature_uninstall("onos-app-fwd")
261 main.ONOScli2.feature_uninstall("onos-app-fwd")
262 main.ONOScli3.feature_uninstall("onos-app-fwd")
263 main.ONOScli4.feature_uninstall("onos-app-fwd")
264 main.ONOScli5.feature_uninstall("onos-app-fwd")
265 main.ONOScli6.feature_uninstall("onos-app-fwd")
266 main.ONOScli7.feature_uninstall("onos-app-fwd")
267
268 main.step("Add host intents")
269 #TODO: move the host numbers to params
270 import json
271 intents_json= json.loads(main.ONOScli1.hosts())
272 intent_add_result = main.FALSE
273 for i in range(8,18):
274 main.log.info("Adding host intent between h"+str(i)+" and h"+str(i+10))
275 host1 = "00:00:00:00:00:" + str(hex(i)[2:]).zfill(2).upper()
276 host2 = "00:00:00:00:00:" + str(hex(i+10)[2:]).zfill(2).upper()
277 #NOTE: get host can return None
278 #TODO: handle this
279 host1_id = main.ONOScli1.get_host(host1)['id']
280 host2_id = main.ONOScli1.get_host(host2)['id']
281 tmp_result = main.ONOScli1.add_host_intent(host1_id, host2_id )
282 intent_add_result = intent_add_result and tmp_result
283 #TODO Check if intents all exist in datastore
284 #NOTE: Do we need to print this once the test is working?
285 #main.log.info(json.dumps(json.loads(main.ONOScli1.intents(json_format=True)),
286 # sort_keys=True, indent=4, separators=(',', ': ') ) )
287
288 def CASE4(self,main) :
289 """
290 Ping across added host intents
291 """
292 Ping_Result = main.TRUE
293 for i in range(8,18):
294 ping = main.Mininet1.pingHost(src="h"+str(i),target="h"+str(i+10))
295 Ping_Result = Ping_Result and ping
296 if ping==main.FALSE:
297 main.log.warn("Ping failed between h"+str(i)+" and h" + str(i+10))
298 elif ping==main.TRUE:
299 main.log.info("Ping test passed!")
300 Ping_Result = main.TRUE
301 if Ping_Result==main.FALSE:
302 main.log.report("Intents have not been installed correctly, pings failed.")
303 if Ping_Result==main.TRUE:
304 main.log.report("Intents have been installed correctly, and verified by pings")
305 utilities.assert_equals(expect = main.TRUE,actual=Ping_Result,
306 onpass="Intents have been installed correctly and pings work")
307
308 def CASE5(self,main) :
309 '''
310 Reading state of ONOS
311 '''
312 import time
313 import json
314 from subprocess import Popen, PIPE
315 from sts.topology.teston_topology import TestONTopology # assumes that sts is already in you PYTHONPATH
316
317 main.log.report("Setting up and gathering data for current state")
318 main.case("Setting up and gathering data for current state")
319 #The general idea for this test case is to pull the state of (intents,flows, topology,...) from each ONOS node
320 #We can then compare them with eachother and also with past states
321
322 main.step("Get the Mastership of each switch from each controller")
323 global mastership_state
324 ONOS1_mastership = main.ONOScli1.roles()
325 ONOS2_mastership = main.ONOScli2.roles()
326 ONOS3_mastership = main.ONOScli3.roles()
327 ONOS4_mastership = main.ONOScli4.roles()
328 ONOS5_mastership = main.ONOScli5.roles()
329 ONOS6_mastership = main.ONOScli6.roles()
330 ONOS7_mastership = main.ONOScli7.roles()
331 #print json.dumps(json.loads(ONOS1_mastership), sort_keys=True, indent=4, separators=(',', ': '))
332 if ONOS1_mastership == ONOS2_mastership\
333 and ONOS1_mastership == ONOS3_mastership\
334 and ONOS1_mastership == ONOS4_mastership\
335 and ONOS1_mastership == ONOS5_mastership\
336 and ONOS1_mastership == ONOS6_mastership\
337 and ONOS1_mastership == ONOS7_mastership:
338 mastership_state = ONOS1_mastership
339 consistent_mastership = main.TRUE
340 main.log.report("Switch roles are consistent across all ONOS nodes")
341 else:
342 main.log.warn("ONOS1 roles: ", json.dumps(json.loads(ONOS1_mastership),
343 sort_keys=True, indent=4, separators=(',', ': ')))
344 main.log.warn("ONOS2 roles: ", json.dumps(json.loads(ONOS2_mastership),
345 sort_keys=True, indent=4, separators=(',', ': ')))
346 main.log.warn("ONOS3 roles: ", json.dumps(json.loads(ONOS3_mastership),
347 sort_keys=True, indent=4, separators=(',', ': ')))
348 main.log.warn("ONOS4 roles: ", json.dumps(json.loads(ONOS4_mastership),
349 sort_keys=True, indent=4, separators=(',', ': ')))
350 main.log.warn("ONOS5 roles: ", json.dumps(json.loads(ONOS5_mastership),
351 sort_keys=True, indent=4, separators=(',', ': ')))
352 main.log.warn("ONOS6 roles: ", json.dumps(json.loads(ONOS6_mastership),
353 sort_keys=True, indent=4, separators=(',', ': ')))
354 main.log.warn("ONOS7 roles: ", json.dumps(json.loads(ONOS7_mastership),
355 sort_keys=True, indent=4, separators=(',', ': ')))
356 consistent_mastership = main.FALSE
357 utilities.assert_equals(expect = main.TRUE,actual=consistent_mastership,
358 onpass="Switch roles are consistent across all ONOS nodes",
359 onfail="ONOS nodes have different views of switch roles")
360
361
362 main.step("Get the intents from each controller")
363 global intent_state
364 ONOS1_intents = main.ONOScli1.intents( json_format=True )
365 ONOS2_intents = main.ONOScli2.intents( json_format=True )
366 ONOS3_intents = main.ONOScli3.intents( json_format=True )
367 ONOS4_intents = main.ONOScli4.intents( json_format=True )
368 ONOS5_intents = main.ONOScli5.intents( json_format=True )
369 ONOS6_intents = main.ONOScli6.intents( json_format=True )
370 ONOS7_intents = main.ONOScli7.intents( json_format=True )
371 intent_check = main.FALSE
372 if "Error" in ONOS1_intents\
373 or "Error" in ONOS2_intents\
374 or "Error" in ONOS3_intents\
375 or "Error" in ONOS4_intents\
376 or "Error" in ONOS5_intents\
377 or "Error" in ONOS6_intents\
378 or "Error" in ONOS7_intents:
379 main.log.error("Error in getting ONOS intents")
380 main.log.warn("ONOS1 intents response: " + str(ONOS1_intents))
381 main.log.warn("ONOS2 intents response: " + str(ONOS2_intents))
382 main.log.warn("ONOS3 intents response: " + str(ONOS3_intents))
383 main.log.warn("ONOS4 intents response: " + str(ONOS4_intents))
384 main.log.warn("ONOS5 intents response: " + str(ONOS5_intents))
385 main.log.warn("ONOS6 intents response: " + str(ONOS6_intents))
386 main.log.warn("ONOS7 intents response: " + str(ONOS7_intents))
387 elif ONOS1_intents == ONOS2_intents\
388 and ONOS1_intents == ONOS3_intents\
389 and ONOS1_intents == ONOS4_intents\
390 and ONOS1_intents == ONOS5_intents\
391 and ONOS1_intents == ONOS6_intents\
392 and ONOS1_intents == ONOS7_intents:
393 intent_state = ONOS1_intents
394 intent_check = main.TRUE
395 main.log.report("Intents are consistent across all ONOS nodes")
396 else:
397 main.log.warn("ONOS1 intents: ", json.dumps(json.loads(ONOS1_intents),
398 sort_keys=True, indent=4, separators=(',', ': ')))
399 main.log.warn("ONOS2 intents: ", json.dumps(json.loads(ONOS2_intents),
400 sort_keys=True, indent=4, separators=(',', ': ')))
401 main.log.warn("ONOS3 intents: ", json.dumps(json.loads(ONOS3_intents),
402 sort_keys=True, indent=4, separators=(',', ': ')))
403 main.log.warn("ONOS4 intents: ", json.dumps(json.loads(ONOS4_intents),
404 sort_keys=True, indent=4, separators=(',', ': ')))
405 main.log.warn("ONOS5 intents: ", json.dumps(json.loads(ONOS5_intents),
406 sort_keys=True, indent=4, separators=(',', ': ')))
407 main.log.warn("ONOS6 intents: ", json.dumps(json.loads(ONOS6_intents),
408 sort_keys=True, indent=4, separators=(',', ': ')))
409 main.log.warn("ONOS7 intents: ", json.dumps(json.loads(ONOS7_intents),
410 sort_keys=True, indent=4, separators=(',', ': ')))
411 utilities.assert_equals(expect = main.TRUE,actual=intent_check,
412 onpass="Intents are consistent across all ONOS nodes",
413 onfail="ONOS nodes have different views of intents")
414
415
416 main.step("Get the flows from each controller")
417 global flow_state
418 ONOS1_flows = main.ONOScli1.flows( json_format=True )
419 ONOS2_flows = main.ONOScli2.flows( json_format=True )
420 ONOS3_flows = main.ONOScli3.flows( json_format=True )
421 ONOS4_flows = main.ONOScli4.flows( json_format=True )
422 ONOS5_flows = main.ONOScli5.flows( json_format=True )
423 ONOS6_flows = main.ONOScli6.flows( json_format=True )
424 ONOS7_flows = main.ONOScli7.flows( json_format=True )
425 flow_check = main.FALSE
426 if "Error" in ONOS1_flows\
427 or "Error" in ONOS2_flows\
428 or "Error" in ONOS3_flows\
429 or "Error" in ONOS4_flows\
430 or "Error" in ONOS5_flows\
431 or "Error" in ONOS6_flows\
432 or "Error" in ONOS7_flows:
433 main.log.error("Error in getting ONOS intents")
434 main.log.warn("ONOS1 flows repsponse: "+ ONOS1_flows)
435 main.log.warn("ONOS2 flows repsponse: "+ ONOS2_flows)
436 main.log.warn("ONOS3 flows repsponse: "+ ONOS3_flows)
437 main.log.warn("ONOS4 flows repsponse: "+ ONOS4_flows)
438 main.log.warn("ONOS5 flows repsponse: "+ ONOS5_flows)
439 main.log.warn("ONOS6 flows repsponse: "+ ONOS6_flows)
440 main.log.warn("ONOS7 flows repsponse: "+ ONOS7_flows)
441 elif len(json.loads(ONOS1_flows)) == len(json.loads(ONOS2_flows))\
442 and len(json.loads(ONOS1_flows)) == len(json.loads(ONOS3_flows))\
443 and len(json.loads(ONOS1_flows)) == len(json.loads(ONOS4_flows))\
444 and len(json.loads(ONOS1_flows)) == len(json.loads(ONOS5_flows))\
445 and len(json.loads(ONOS1_flows)) == len(json.loads(ONOS6_flows))\
446 and len(json.loads(ONOS1_flows)) == len(json.loads(ONOS7_flows)):
447 #TODO: Do a better check, maybe compare flows on switches?
448 flow_state = ONOS1_flows
449 flow_check = main.TRUE
450 main.log.report("Flow count is consistent across all ONOS nodes")
451 else:
452 main.log.warn("ONOS1 flows: "+ json.dumps(json.loads(ONOS1_flows),
453 sort_keys=True, indent=4, separators=(',', ': ')))
454 main.log.warn("ONOS2 flows: "+ json.dumps(json.loads(ONOS2_flows),
455 sort_keys=True, indent=4, separators=(',', ': ')))
456 main.log.warn("ONOS3 flows: "+ json.dumps(json.loads(ONOS3_flows),
457 sort_keys=True, indent=4, separators=(',', ': ')))
458 main.log.warn("ONOS4 flows: "+ json.dumps(json.loads(ONOS4_flows),
459 sort_keys=True, indent=4, separators=(',', ': ')))
460 main.log.warn("ONOS5 flows: "+ json.dumps(json.loads(ONOS5_flows),
461 sort_keys=True, indent=4, separators=(',', ': ')))
462 main.log.warn("ONOS6 flows: "+ json.dumps(json.loads(ONOS6_flows),
463 sort_keys=True, indent=4, separators=(',', ': ')))
464 main.log.warn("ONOS7 flows: "+ json.dumps(json.loads(ONOS7_flows),
465 sort_keys=True, indent=4, separators=(',', ': ')))
466 utilities.assert_equals(expect = main.TRUE,actual=flow_check,
467 onpass="The flow count is consistent across all ONOS nodes",
468 onfail="ONOS nodes have different flow counts")
469
470
471 main.step("Get the OF Table entries")
472 global flows
473 flows=[]
474 for i in range(1,29):
475 flows.append(main.Mininet2.get_flowTable("s"+str(i),1.0))
476
477 #TODO: Compare switch flow tables with ONOS flow tables
478
479 main.step("Start continuous pings")
480 main.Mininet2.pingLong(src=main.params['PING']['source1'],
481 target=main.params['PING']['target1'],pingTime=500)
482 main.Mininet2.pingLong(src=main.params['PING']['source2'],
483 target=main.params['PING']['target2'],pingTime=500)
484 main.Mininet2.pingLong(src=main.params['PING']['source3'],
485 target=main.params['PING']['target3'],pingTime=500)
486 main.Mininet2.pingLong(src=main.params['PING']['source4'],
487 target=main.params['PING']['target4'],pingTime=500)
488 main.Mininet2.pingLong(src=main.params['PING']['source5'],
489 target=main.params['PING']['target5'],pingTime=500)
490 main.Mininet2.pingLong(src=main.params['PING']['source6'],
491 target=main.params['PING']['target6'],pingTime=500)
492 main.Mininet2.pingLong(src=main.params['PING']['source7'],
493 target=main.params['PING']['target7'],pingTime=500)
494 main.Mininet2.pingLong(src=main.params['PING']['source8'],
495 target=main.params['PING']['target8'],pingTime=500)
496 main.Mininet2.pingLong(src=main.params['PING']['source9'],
497 target=main.params['PING']['target9'],pingTime=500)
498 main.Mininet2.pingLong(src=main.params['PING']['source10'],
499 target=main.params['PING']['target10'],pingTime=500)
500
501 main.step("Create TestONTopology object")
502 ctrls = []
503 count = 1
504 while True:
505 temp = ()
506 if ('ip' + str(count)) in main.params['CTRL']:
507 temp = temp + (getattr(main,('ONOS' + str(count))),)
508 temp = temp + ("ONOS"+str(count),)
509 temp = temp + (main.params['CTRL']['ip'+str(count)],)
510 temp = temp + (eval(main.params['CTRL']['port'+str(count)]),)
511 ctrls.append(temp)
512 count = count + 1
513 else:
514 break
515 MNTopo = TestONTopology(main.Mininet1, ctrls) # can also add Intent API info for intent operations
516
517 main.step("Collecting topology information from ONOS")
518 devices = []
519 devices.append( main.ONOScli1.devices() )
520 devices.append( main.ONOScli2.devices() )
521 devices.append( main.ONOScli3.devices() )
522 devices.append( main.ONOScli4.devices() )
523 devices.append( main.ONOScli5.devices() )
524 devices.append( main.ONOScli6.devices() )
525 devices.append( main.ONOScli7.devices() )
526 '''
527 hosts = []
528 hosts.append( main.ONOScli1.hosts() )
529 hosts.append( main.ONOScli2.hosts() )
530 hosts.append( main.ONOScli3.hosts() )
531 hosts.append( main.ONOScli4.hosts() )
532 hosts.append( main.ONOScli5.hosts() )
533 hosts.append( main.ONOScli6.hosts() )
534 hosts.append( main.ONOScli7.hosts() )
535 '''
536 ports = []
537 ports.append( main.ONOScli1.ports() )
538 ports.append( main.ONOScli2.ports() )
539 ports.append( main.ONOScli3.ports() )
540 ports.append( main.ONOScli4.ports() )
541 ports.append( main.ONOScli5.ports() )
542 ports.append( main.ONOScli6.ports() )
543 ports.append( main.ONOScli7.ports() )
544 links = []
545 links.append( main.ONOScli1.links() )
546 links.append( main.ONOScli2.links() )
547 links.append( main.ONOScli3.links() )
548 links.append( main.ONOScli4.links() )
549 links.append( main.ONOScli5.links() )
550 links.append( main.ONOScli6.links() )
551 links.append( main.ONOScli7.links() )
552
553
554 main.step("Comparing ONOS topology to MN")
555 devices_results = main.TRUE
556 ports_results = main.TRUE
557 links_results = main.TRUE
558 for controller in range(7): #TODO parameterize the number of controllers
559 current_devices_result = main.Mininet1.compare_switches(MNTopo, json.loads(devices[controller]))
560 utilities.assert_equals(expect=main.TRUE, actual=current_devices_result,
561 onpass="ONOS"+str(int(controller+1))+" Switches view is correct",
562 onfail="ONOS"+str(int(controller+1))+" Switches view is incorrect")
563
564 current_ports_result = main.Mininet1.compare_ports(MNTopo, json.loads(ports[controller]))
565 utilities.assert_equals(expect=main.TRUE, actual=current_ports_result,
566 onpass="ONOS"+str(int(controller+1))+" ports view is correct",
567 onfail="ONOS"+str(int(controller+1))+" ports view is incorrect")
568
569 current_links_result = main.Mininet1.compare_links(MNTopo, json.loads(links[controller]))
570 utilities.assert_equals(expect=main.TRUE, actual=current_links_result,
571 onpass="ONOS"+str(int(controller+1))+" links view is correct",
572 onfail="ONOS"+str(int(controller+1))+" links view is incorrect")
573
574 devices_results = devices_results and current_devices_result
575 ports_results = ports_results and current_ports_result
576 links_results = links_results and current_links_result
577
578 topo_result = devices_results and ports_results and links_results
579 utilities.assert_equals(expect=main.TRUE, actual=topo_result,
580 onpass="Topology Check Test successful",
581 onfail="Topology Check Test NOT successful")
582
583 final_assert = main.TRUE
584 final_assert = final_assert and topo_result and flow_check \
585 and intent_check and consistent_mastership
586 utilities.assert_equals(expect=main.TRUE, actual=final_assert,
587 onpass="State check successful",
588 onfail="State check NOT successful")
589
590
591 def CASE6(self,main) :
592 '''
593 The Failure case. Since this is the Sanity test, we do nothing.
594 '''
595
596 def CASE7(self,main) :
597 '''
598 Check state after failure
599 '''
600 import os
601 import json
602 main.case("Running ONOS Constant State Tests")
603
604 main.step("Check if switch roles are consistent across all nodes")
605 ONOS1_mastership = main.ONOScli1.roles()
606 ONOS2_mastership = main.ONOScli2.roles()
607 ONOS3_mastership = main.ONOScli3.roles()
608 ONOS4_mastership = main.ONOScli4.roles()
609 ONOS5_mastership = main.ONOScli5.roles()
610 ONOS6_mastership = main.ONOScli6.roles()
611 ONOS7_mastership = main.ONOScli7.roles()
612 #print json.dumps(json.loads(ONOS1_mastership), sort_keys=True, indent=4, separators=(',', ': '))
613 if ONOS1_mastership == ONOS2_mastership\
614 and ONOS1_mastership == ONOS3_mastership\
615 and ONOS1_mastership == ONOS4_mastership\
616 and ONOS1_mastership == ONOS5_mastership\
617 and ONOS1_mastership == ONOS6_mastership\
618 and ONOS1_mastership == ONOS7_mastership:
619 #mastership_state = ONOS1_mastership
620 consistent_mastership = main.TRUE
621 main.log.report("Switch roles are consistent across all ONOS nodes")
622 else:
623 main.log.warn("ONOS1 roles: ", json.dumps(json.loads(ONOS1_mastership),
624 sort_keys=True, indent=4, separators=(',', ': ')))
625 main.log.warn("ONOS2 roles: ", json.dumps(json.loads(ONOS2_mastership),
626 sort_keys=True, indent=4, separators=(',', ': ')))
627 main.log.warn("ONOS3 roles: ", json.dumps(json.loads(ONOS3_mastership),
628 sort_keys=True, indent=4, separators=(',', ': ')))
629 main.log.warn("ONOS4 roles: ", json.dumps(json.loads(ONOS4_mastership),
630 sort_keys=True, indent=4, separators=(',', ': ')))
631 main.log.warn("ONOS5 roles: ", json.dumps(json.loads(ONOS5_mastership),
632 sort_keys=True, indent=4, separators=(',', ': ')))
633 main.log.warn("ONOS6 roles: ", json.dumps(json.loads(ONOS6_mastership),
634 sort_keys=True, indent=4, separators=(',', ': ')))
635 main.log.warn("ONOS7 roles: ", json.dumps(json.loads(ONOS7_mastership),
636 sort_keys=True, indent=4, separators=(',', ': ')))
637 consistent_mastership = main.FALSE
638 utilities.assert_equals(expect = main.TRUE,actual=consistent_mastership,
639 onpass="Switch roles are consistent across all ONOS nodes",
640 onfail="ONOS nodes have different views of switch roles")
641
642
643 description2 = "Compare switch roles from before failure"
644 main.step(description2)
645
646
647
648 current_json = json.loads(ONOS1_mastership)
649 old_json = json.loads(mastership_state)
650 mastership_check = main.TRUE
651 for i in range(1,29):
652 switchDPID = str(main.Mininet1.getSwitchDPID(switch="s"+str(i)))
653
654 current = [switch['master'] for switch in current_json if switchDPID in switch['id']]
655 old = [switch['master'] for switch in old_json if switchDPID in switch['id']]
656 if current == old:
657 mastership_check = mastership_check and main.TRUE
658 else:
659 main.log.warn("Mastership of switch %s changed" % switchDPID)
660 mastership_check = main.FALSE
661 if mastership_check == main.TRUE:
662 main.log.report("Mastership of Switches was not changed")
663 utilities.assert_equals(expect=main.TRUE,actual=mastership_check,
664 onpass="Mastership of Switches was not changed",
665 onfail="Mastership of some switches changed")
666 mastership_check = mastership_check and consistent_mastership
667
668
669
670 main.step("Get the intents and compare across all nodes")
671 ONOS1_intents = main.ONOScli1.intents( json_format=True )
672 ONOS2_intents = main.ONOScli2.intents( json_format=True )
673 ONOS3_intents = main.ONOScli3.intents( json_format=True )
674 ONOS4_intents = main.ONOScli4.intents( json_format=True )
675 ONOS5_intents = main.ONOScli5.intents( json_format=True )
676 ONOS6_intents = main.ONOScli6.intents( json_format=True )
677 ONOS7_intents = main.ONOScli7.intents( json_format=True )
678 intent_check = main.FALSE
679 if "Error" in ONOS1_intents\
680 or "Error" in ONOS2_intents\
681 or "Error" in ONOS3_intents\
682 or "Error" in ONOS4_intents\
683 or "Error" in ONOS5_intents\
684 or "Error" in ONOS6_intents\
685 or "Error" in ONOS7_intents:
686 main.log.error("Error in getting ONOS intents")
687 main.log.warn("ONOS1 intents response: " + str(ONOS1_intents))
688 main.log.warn("ONOS2 intents response: " + str(ONOS2_intents))
689 main.log.warn("ONOS3 intents response: " + str(ONOS3_intents))
690 main.log.warn("ONOS4 intents response: " + str(ONOS4_intents))
691 main.log.warn("ONOS5 intents response: " + str(ONOS5_intents))
692 main.log.warn("ONOS6 intents response: " + str(ONOS6_intents))
693 main.log.warn("ONOS7 intents response: " + str(ONOS7_intents))
694 elif ONOS1_intents == ONOS2_intents\
695 and ONOS1_intents == ONOS3_intents\
696 and ONOS1_intents == ONOS4_intents\
697 and ONOS1_intents == ONOS5_intents\
698 and ONOS1_intents == ONOS6_intents\
699 and ONOS1_intents == ONOS7_intents:
700 intent_state = ONOS1_intents
701 intent_check = main.TRUE
702 main.log.report("Intents are consistent across all ONOS nodes")
703 else:
704 main.log.warn("ONOS1 intents: ", json.dumps(json.loads(ONOS1_intents),
705 sort_keys=True, indent=4, separators=(',', ': ')))
706 main.log.warn("ONOS2 intents: ", json.dumps(json.loads(ONOS2_intents),
707 sort_keys=True, indent=4, separators=(',', ': ')))
708 main.log.warn("ONOS3 intents: ", json.dumps(json.loads(ONOS3_intents),
709 sort_keys=True, indent=4, separators=(',', ': ')))
710 main.log.warn("ONOS4 intents: ", json.dumps(json.loads(ONOS4_intents),
711 sort_keys=True, indent=4, separators=(',', ': ')))
712 main.log.warn("ONOS5 intents: ", json.dumps(json.loads(ONOS5_intents),
713 sort_keys=True, indent=4, separators=(',', ': ')))
714 main.log.warn("ONOS6 intents: ", json.dumps(json.loads(ONOS6_intents),
715 sort_keys=True, indent=4, separators=(',', ': ')))
716 main.log.warn("ONOS7 intents: ", json.dumps(json.loads(ONOS7_intents),
717 sort_keys=True, indent=4, separators=(',', ': ')))
718 utilities.assert_equals(expect = main.TRUE,actual=intent_check,
719 onpass="Intents are consistent across all ONOS nodes",
720 onfail="ONOS nodes have different views of intents")
721
722 main.step("Compare current intents with intents before the failure")
723 if intent_state == ONOS1_intents:
724 same_intents = main.TRUE
725 main.log.report("Intents are consistent with before failure")
726 #TODO: possibly the states have changed? we may need to figure out what the aceptable states are
727 else:
728 same_intents = main.FALSE
729 utilities.assert_equals(expect = main.TRUE,actual=same_intents,
730 onpass="Intents are consistent with before failure",
731 onfail="The Intents changed during failure")
732 intent_check = intent_check and same_intents
733
734
735
736 main.step("Get the OF Table entries and compare to before component failure")
737 Flow_Tables = main.TRUE
738 flows2=[]
739 for i in range(28):
740 main.log.info("Checking flow table on s" + str(i+1))
741 tmp_flows = main.Mininet2.get_flowTable("s"+str(i+1),1.0)
742 flows2.append(tmp_flows)
743 Flow_Tables = Flow_Tables and main.Mininet2.flow_comp(flow1=flows[i],flow2=tmp_flows)
744 if Flow_Tables == main.FALSE:
745 main.log.info("Differences in flow table for switch: "+str(i+1))
746 break
747 if Flow_Tables == main.TRUE:
748 main.log.report("No changes were found in the flow tables")
749 utilities.assert_equals(expect=main.TRUE,actual=Flow_Tables,
750 onpass="No changes were found in the flow tables",
751 onfail="Changes were found in the flow tables")
752
753 main.step("Check the continuous pings to ensure that no packets were dropped during component failure")
754 #FIXME: This check is always failing. Investigate cause
755 #NOTE: this may be something to do with file permsissions
756 # or slight change in format
757 main.Mininet2.pingKill(main.params['TESTONUSER'], main.params['TESTONIP'])
758 Loss_In_Pings = main.FALSE
759 #NOTE: checkForLoss returns main.FALSE with 0% packet loss
760 for i in range(8,18):
761 main.log.info("Checking for a loss in pings along flow from s" + str(i))
762 Loss_In_Pings = Loss_In_Pings or main.Mininet2.checkForLoss("/tmp/ping.h"+str(i))
763 if Loss_In_Pings == main.TRUE:
764 main.log.info("Loss in ping detected")
765 elif Loss_In_Pings == main.ERROR:
766 main.log.info("There are multiple mininet process running")
767 elif Loss_In_Pings == main.FALSE:
768 main.log.info("No Loss in the pings")
769 main.log.report("No loss of dataplane connectivity")
770 utilities.assert_equals(expect=main.FALSE,actual=Loss_In_Pings,
771 onpass="No Loss of connectivity",
772 onfail="Loss of dataplane connectivity detected")
773
774
775 #TODO:add topology to this or leave as a seperate case?
776 result = mastership_check and intent_check and Flow_Tables and (not Loss_In_Pings)
777 result = int(result)
778 if result == main.TRUE:
779 main.log.report("Constant State Tests Passed")
780 utilities.assert_equals(expect=main.TRUE,actual=result,
781 onpass="Constant State Tests Passed",
782 onfail="Constant state tests failed")
783
784 def CASE8 (self,main):
785 '''
786 Compare topo
787 '''
788 import sys
789 sys.path.append("/home/admin/sts") # Trying to remove some dependancies, #FIXME add this path to params
790 from sts.topology.teston_topology import TestONTopology # assumes that sts is already in you PYTHONPATH
791 import json
792
793 description ="Compare ONOS Topology view to Mininet topology"
794 main.case(description)
795 main.log.report(description)
796 main.step("Create TestONTopology object")
797 ctrls = []
798 count = 1
799 while True:
800 temp = ()
801 if ('ip' + str(count)) in main.params['CTRL']:
802 temp = temp + (getattr(main,('ONOS' + str(count))),)
803 temp = temp + ("ONOS"+str(count),)
804 temp = temp + (main.params['CTRL']['ip'+str(count)],)
805 temp = temp + (eval(main.params['CTRL']['port'+str(count)]),)
806 ctrls.append(temp)
807 count = count + 1
808 else:
809 break
810 MNTopo = TestONTopology(main.Mininet1, ctrls) # can also add Intent API info for intent operations
811
812 main.step("Collecting topology information from ONOS")
813 devices = []
814 devices.append( main.ONOScli1.devices() )
815 devices.append( main.ONOScli2.devices() )
816 devices.append( main.ONOScli3.devices() )
817 devices.append( main.ONOScli4.devices() )
818 devices.append( main.ONOScli5.devices() )
819 devices.append( main.ONOScli6.devices() )
820 devices.append( main.ONOScli7.devices() )
821 '''
822 hosts = []
823 hosts.append( main.ONOScli1.hosts() )
824 hosts.append( main.ONOScli2.hosts() )
825 hosts.append( main.ONOScli3.hosts() )
826 hosts.append( main.ONOScli4.hosts() )
827 hosts.append( main.ONOScli5.hosts() )
828 hosts.append( main.ONOScli6.hosts() )
829 hosts.append( main.ONOScli7.hosts() )
830 '''
831 ports = []
832 ports.append( main.ONOScli1.ports() )
833 ports.append( main.ONOScli2.ports() )
834 ports.append( main.ONOScli3.ports() )
835 ports.append( main.ONOScli4.ports() )
836 ports.append( main.ONOScli5.ports() )
837 ports.append( main.ONOScli6.ports() )
838 ports.append( main.ONOScli7.ports() )
839 links = []
840 links.append( main.ONOScli1.links() )
841 links.append( main.ONOScli2.links() )
842 links.append( main.ONOScli3.links() )
843 links.append( main.ONOScli4.links() )
844 links.append( main.ONOScli5.links() )
845 links.append( main.ONOScli6.links() )
846 links.append( main.ONOScli7.links() )
847
848
849 main.step("Comparing ONOS topology to MN")
850 devices_results = main.TRUE
851 ports_results = main.TRUE
852 links_results = main.TRUE
853 for controller in range(7): #TODO parameterize the number of controllers
854 current_devices_result = main.Mininet1.compare_switches(MNTopo, json.loads(devices[controller]))
855 utilities.assert_equals(expect=main.TRUE, actual=current_devices_result,
856 onpass="ONOS"+str(int(controller+1))+" Switches view is correct",
857 onfail="ONOS"+str(int(controller+1))+" Switches view is incorrect")
858
859 current_ports_result = main.Mininet1.compare_ports(MNTopo, json.loads(ports[controller]))
860 utilities.assert_equals(expect=main.TRUE, actual=current_ports_result,
861 onpass="ONOS"+str(int(controller+1))+" ports view is correct",
862 onfail="ONOS"+str(int(controller+1))+" ports view is incorrect")
863
864 current_links_result = main.Mininet1.compare_links(MNTopo, json.loads(links[controller]))
865 utilities.assert_equals(expect=main.TRUE, actual=current_links_result,
866 onpass="ONOS"+str(int(controller+1))+" links view is correct",
867 onfail="ONOS"+str(int(controller+1))+" links view is incorrect")
868
869 devices_results = devices_results and current_devices_result
870 ports_results = ports_results and current_ports_result
871 links_results = links_results and current_links_result
872
873 topo_result = devices_results and ports_results and links_results
874 utilities.assert_equals(expect=main.TRUE, actual=topo_result,
875 onpass="Topology Check Test successful",
876 onfail="Topology Check Test NOT successful")
877 if topo_result == main.TRUE:
878 main.log.report("ONOS topology view matches Mininet topology")
879
880
881 def CASE9 (self,main):
882 '''
883 Link s3-s28 down
884 '''
885 #NOTE: You should probably run a topology check after this
886
887 link_sleep = int(main.params['timers']['LinkDiscovery'])
888
889 description = "Turn off a link to ensure that Link Discovery is working properly"
890 main.log.report(description)
891 main.case(description)
892
893
894 main.step("Kill Link between s3 and s28")
895 Link_Down = main.Mininet1.link(END1="s3",END2="s28",OPTION="down")
896 main.log.info("Waiting " + str(link_sleep) + " seconds for link down to be discovered")
897 time.sleep(link_sleep)
898 utilities.assert_equals(expect=main.TRUE,actual=Link_Down,
899 onpass="Link down succesful",
900 onfail="Failed to bring link down")
901 #TODO do some sort of check here
902
903 def CASE10 (self,main):
904 '''
905 Link s3-s28 up
906 '''
907 #NOTE: You should probably run a topology check after this
908
909 link_sleep = int(main.params['timers']['LinkDiscovery'])
910
911 description = "Restore a link to ensure that Link Discovery is working properly"
912 main.log.report(description)
913 main.case(description)
914
915 main.step("Bring link between s3 and s28 back up")
916 Link_Up = main.Mininet1.link(END1="s3",END2="s28",OPTION="up")
917 main.log.info("Waiting " + str(link_sleep) + " seconds for link up to be discovered")
918 time.sleep(link_sleep)
919 utilities.assert_equals(expect=main.TRUE,actual=Link_Up,
920 onpass="Link up succesful",
921 onfail="Failed to bring link up")
922 #TODO do some sort of check here
923
924
925 def CASE11 (self, main) :
926 '''
927 Switch Down
928 '''
929 #NOTE: You should probably run a topology check after this
930 import time
931
932 switch_sleep = int(main.params['timers']['SwitchDiscovery'])
933
934 description = "Killing a switch to ensure it is discovered correctly"
935 main.log.report(description)
936 main.case(description)
937
938 #TODO: Make this switch parameterizable
939 main.step("Kill s28 ")
940 main.log.report("Deleting s28")
941 #FIXME: use new dynamic topo functions
942 main.Mininet1.del_switch("s28")
943 main.log.info("Waiting " + str(switch_sleep) + " seconds for switch down to be discovered")
944 time.sleep(switch_sleep)
945 #Peek at the deleted switch
946 main.log.warn(main.ONOScli1.get_device(dpid="0028"))
947 #TODO do some sort of check here
948
949 def CASE12 (self, main) :
950 '''
951 Switch Up
952 '''
953 #NOTE: You should probably run a topology check after this
954 import time
955 #FIXME: use new dynamic topo functions
956 description = "Adding a switch to ensure it is discovered correctly"
957 main.log.report(description)
958 main.case(description)
959
960 main.step("Add back s28")
961 main.log.report("Adding back s28")
962 main.Mininet1.add_switch("s28", dpid = '0000000000002800')
963 #TODO: New dpid or same? Ask Thomas?
964 main.Mininet1.add_link('s28', 's3')
965 main.Mininet1.add_link('s28', 's6')
966 main.Mininet1.add_link('s28', 'h28')
967 main.Mininet1.assign_sw_controller(sw="28",count=7,
968 ip1=ONOS1_ip,port1=ONOS1_port,
969 ip2=ONOS2_ip,port2=ONOS2_port,
970 ip3=ONOS3_ip,port3=ONOS3_port,
971 ip4=ONOS4_ip,port4=ONOS4_port,
972 ip5=ONOS5_ip,port5=ONOS5_port,
973 ip6=ONOS6_ip,port6=ONOS6_port,
974 ip7=ONOS7_ip,port7=ONOS7_port)
975 main.log.info("Waiting " + str(switch_sleep) + " seconds for switch up to be discovered")
976 time.sleep(switch_sleep)
977 #Peek at the added switch
978 main.log.warn(main.ONOScli1.get_device(dpid="0028"))
979 #TODO do some sort of check here
980
981 def CASE13 (self, main) :
982 '''
983 Clean up
984 '''
985 main.step("Killing tcpdumps")
986 main.Mininet2.stop_tcpdump()
987
988 #TODO: Enable once test is ready
989 '''
990 main.step("Copying pcap files to test station")
991 testname = main.TEST
992 #FIXME: Do the mininet pcap get archived?
993 #FIXME: also, make sure karaf logs are saved
994
995 #sleep so scp can finish
996 time.sleep(10)
997 main.step("Packing and rotating pcap archives")
998 import os
999 os.system("~/TestON/dependencies/rotate.sh "+ str(testname))
1000 '''
1001
1002 import time
1003
1004 #Stopping ONOS
1005 main.step("Stopping ONOS")
1006 main.ONOScli1.disconnect()
1007 main.ONOScli2.disconnect()
1008 main.ONOScli3.disconnect()
1009 main.ONOScli4.disconnect()
1010 main.ONOScli5.disconnect()
1011 main.ONOScli6.disconnect()
1012 main.ONOScli7.disconnect()
1013 main.ONOSbench.onos_stop(ONOS1_ip)
1014 main.ONOSbench.onos_stop(ONOS2_ip)
1015 main.ONOSbench.onos_stop(ONOS3_ip)
1016 main.ONOSbench.onos_stop(ONOS4_ip)
1017 main.ONOSbench.onos_stop(ONOS5_ip)
1018 main.ONOSbench.onos_stop(ONOS6_ip)
1019 main.ONOSbench.onos_stop(ONOS7_ip)