blob: 2dadea4d774603afce4c52409ff858c416c69e81 [file] [log] [blame]
kelvin-onlab44147802015-07-27 17:57:31 -07001"""
2 Wrapper functions for FuncIntent
3 This functions include Onosclidriver and Mininetclidriver driver functions
4 Author: kelvin@onlab.us
5"""
6import time
7import copy
8import json
kelvin-onlab0e684682015-08-11 18:51:41 -07009import types
kelvin-onlab44147802015-07-27 17:57:31 -070010
11def __init__( self ):
12 self.default = ''
13
14def hostIntent( main,
15 name,
16 host1,
17 host2,
18 onosNode=0,
19 host1Id="",
20 host2Id="",
21 mac1="",
22 mac2="",
23 vlan1="-1",
24 vlan2="-1",
25 sw1="",
26 sw2="",
27 expectedLink=0 ):
28 """
29 Description:
30 Verify add-host-intent
31 Steps:
32 - Discover hosts
33 - Add host intents
34 - Check intents
35 - Verify flows
36 - Ping hosts
37 - Reroute
38 - Link down
39 - Verify flows
40 - Check topology
41 - Ping hosts
42 - Link up
43 - Verify flows
44 - Check topology
45 - Ping hosts
46 - Remove intents
47 Required:
48 name - Type of host intent to add eg. IPV4 | VLAN | Dualstack
49 host1 - Name of first host
50 host2 - Name of second host
51 Optional:
52 onosNode - ONOS node to install the intents in main.CLIs[ ]
53 0 by default so that it will always use the first
54 ONOS node
55 host1Id - ONOS id of the first host eg. 00:00:00:00:00:01/-1
56 host2Id - ONOS id of the second host
57 mac1 - Mac address of first host
58 mac2 - Mac address of the second host
59 vlan1 - Vlan tag of first host, defaults to -1
60 vlan2 - Vlan tag of second host, defaults to -1
61 sw1 - First switch to bring down & up for rerouting purpose
62 sw2 - Second switch to bring down & up for rerouting purpose
63 expectedLink - Expected link when the switches are down, it should
64 be two links lower than the links before the two
65 switches are down
66 """
67
68 # Assert variables
69 assert main, "There is no main variable"
70 assert name, "variable name is empty"
71 assert host1 and host2, "You must specify hosts"
72
73 global itemName
74 itemName = name
75 h1Id = host1Id
76 h2Id = host2Id
77 h1Mac = mac1
78 h2Mac = mac2
79 vlan1 = vlan1
80 vlan2 = vlan2
81 hostNames = [ host1 , host2 ]
82 intentsId = []
83 stepResult = main.TRUE
84 pingResult = main.TRUE
85 intentResult = main.TRUE
86 removeIntentResult = main.TRUE
87 flowResult = main.TRUE
88 topoResult = main.TRUE
89 linkDownResult = main.TRUE
90 linkUpResult = main.TRUE
91 onosNode = int( onosNode )
92
93 if main.hostsData:
94 if not h1Mac:
95 h1Mac = main.hostsData[ host1 ][ 'mac' ]
96 if not h2Mac:
97 h2Mac = main.hostsData[ host2 ][ 'mac' ]
98 if main.hostsData[ host1 ][ 'vlan' ] != '-1':
99 vlan1 = main.hostsData[ host1 ][ 'vlan' ]
100 if main.hostsData[ host2 ][ 'vlan' ] != '-1':
101 vlan2 = main.hostsData[ host2 ][ 'vlan' ]
102 if not h1Id:
103 h1Id = main.hostsData[ host1 ][ 'id' ]
104 if not h2Id:
105 h2Id = main.hostsData[ host2 ][ 'id' ]
106
107 assert h1Id and h2Id, "You must specify host IDs"
108 if not ( h1Id and h2Id ):
109 main.log.info( "There are no host IDs" )
110 return main.FALSE
111
112 # Discover hosts using arping
113 if not main.hostsData:
114 main.log.info( itemName + ": Discover host using arping" )
Jon Halla5cb3412015-08-18 14:08:22 -0700115 main.Mininet1.arping( srcHost=host1, dstHost=host2 )
116 main.Mininet1.arping( srcHost=host2, dstHost=host1 )
kelvin-onlab44147802015-07-27 17:57:31 -0700117 h1Id = main.CLIs[ 0 ].getHost( mac=h1Mac )
118 h2Id = main.CLIs[ 0 ].getHost( mac=h2Mac )
119
120 # Check flows count in each node
121 checkFlowsCount( main )
122
123 # Adding host intents
124 main.log.info( itemName + ": Adding host intents" )
125
126 intent1 = main.CLIs[ onosNode ].addHostIntent( hostIdOne=h1Id,
127 hostIdTwo=h2Id )
128
kelvin-onlab0e684682015-08-11 18:51:41 -0700129 # Get all intents ID in the system, time delay right after intents are added
130 time.sleep( main.addIntentSleep )
kelvin-onlab44147802015-07-27 17:57:31 -0700131 intentsId = main.CLIs[ 0 ].getIntentsId()
kelvin-onlab44147802015-07-27 17:57:31 -0700132
133 # Check intents state
134 time.sleep( main.checkIntentSleep )
135 intentResult = checkIntentState( main, intentsId )
136 checkFlowsCount( main )
137
138 # Check intents state again if first check fails...
139 if not intentResult:
140 intentResult = checkIntentState( main, intentsId )
141
142 # Check flows count in each node
143 checkFlowsCount( main )
144 # Verify flows
145 checkFlowsState( main )
146
147 # Ping hosts
148 firstPingResult = pingallHosts( main, hostNames )
149 if not firstPingResult:
150 main.log.debug( "First ping failed, there must be" +
151 " something wrong with ONOS performance" )
152
153 # Ping hosts again...
154 pingResult = pingResult and pingallHosts( main, hostNames )
155
156 # Test rerouting if these variables exist
157 if sw1 and sw2 and expectedLink:
158 # link down
159 linkDownResult = link( main, sw1, sw2, "down" )
160 intentResult = intentResult and checkIntentState( main, intentsId )
161
162 # Check flows count in each node
163 checkFlowsCount( main )
164 # Verify flows
165 checkFlowsState( main )
166
167 # Check OnosTopology
168 topoResult = checkTopology( main, expectedLink )
169
170 # Ping hosts
171 pingResult = pingResult and pingallHosts( main, hostNames )
172
173 intentResult = checkIntentState( main, intentsId )
174
175 # Checks ONOS state in link down
176 if linkDownResult and topoResult and pingResult and intentResult:
177 main.log.info( itemName + ": Successfully brought link down" )
178 else:
179 main.log.error( itemName + ": Failed to bring link down" )
180
181 # link up
182 linkUpResult = link( main, sw1, sw2, "up" )
183 time.sleep( main.rerouteSleep )
184
185 # Check flows count in each node
186 checkFlowsCount( main )
187 # Verify flows
188 checkFlowsState( main )
189
190 # Check OnosTopology
191 topoResult = checkTopology( main, main.numLinks )
192
193 # Ping hosts
194 pingResult = pingResult and pingallHosts( main, hostNames )
195
196 intentResult = checkIntentState( main, intentsId )
197
198 # Checks ONOS state in link up
199 if linkUpResult and topoResult and pingResult and intentResult:
200 main.log.info( itemName + ": Successfully brought link back up" )
201 else:
202 main.log.error( itemName + ": Failed to bring link back up" )
203
204 # Remove all intents
205 removeIntentResult = removeAllIntents( main )
206
207 stepResult = pingResult and linkDownResult and linkUpResult \
208 and intentResult and removeIntentResult
209
210 return stepResult
211
212def pointIntent( main,
213 name,
214 host1,
215 host2,
216 onosNode=0,
217 deviceId1="",
218 deviceId2="",
219 port1="",
220 port2="",
221 ethType="",
222 mac1="",
223 mac2="",
224 bandwidth="",
225 lambdaAlloc=False,
226 ipProto="",
227 ip1="",
228 ip2="",
229 tcp1="",
230 tcp2="",
231 sw1="",
232 sw2="",
233 expectedLink=0 ):
234
235 """
236 Description:
237 Verify add-point-intent
238 Steps:
239 - Get device ids | ports
240 - Add point intents
241 - Check intents
242 - Verify flows
243 - Ping hosts
244 - Reroute
245 - Link down
246 - Verify flows
247 - Check topology
248 - Ping hosts
249 - Link up
250 - Verify flows
251 - Check topology
252 - Ping hosts
253 - Remove intents
254 Required:
255 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
256 host1 - Name of first host
257 host2 - Name of second host
258 Optional:
259 onosNode - ONOS node to install the intents in main.CLIs[ ]
260 0 by default so that it will always use the first
261 ONOS node
262 deviceId1 - ONOS device id of the first switch, the same as the
263 location of the first host eg. of:0000000000000001/1,
264 located at device 1 port 1
265 deviceId2 - ONOS device id of the second switch
266 port1 - The port number where the first host is attached
267 port2 - The port number where the second host is attached
268 ethType - Ethernet type eg. IPV4, IPV6
269 mac1 - Mac address of first host
270 mac2 - Mac address of the second host
271 bandwidth - Bandwidth capacity
272 lambdaAlloc - Allocate lambda, defaults to False
273 ipProto - IP protocol
274 ip1 - IP address of first host
275 ip2 - IP address of second host
276 tcp1 - TCP port of first host
277 tcp2 - TCP port of second host
278 sw1 - First switch to bring down & up for rerouting purpose
279 sw2 - Second switch to bring down & up for rerouting purpose
280 expectedLink - Expected link when the switches are down, it should
281 be two links lower than the links before the two
282 switches are down
283 """
284
285 assert main, "There is no main variable"
286 assert name, "variable name is empty"
287 assert host1 and host2, "You must specify hosts"
288
289 global itemName
290 itemName = name
291 host1 = host1
292 host2 = host2
293 hostNames = [ host1, host2 ]
294 intentsId = []
295
296 pingResult = main.TRUE
297 intentResult = main.TRUE
298 removeIntentResult = main.TRUE
299 flowResult = main.TRUE
300 topoResult = main.TRUE
301 linkDownResult = main.TRUE
302 linkUpResult = main.TRUE
303 onosNode = int( onosNode )
304
305 # Adding bidirectional point intents
306 main.log.info( itemName + ": Adding point intents" )
307 intent1 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId1,
308 egressDevice=deviceId2,
309 ingressPort=port1,
310 egressPort=port2,
311 ethType=ethType,
312 ethSrc=mac1,
313 ethDst=mac2,
314 bandwidth=bandwidth,
315 lambdaAlloc=lambdaAlloc,
316 ipProto=ipProto,
317 ipSrc=ip1,
318 ipDst=ip2,
319 tcpSrc=tcp1,
320 tcpDst=tcp2 )
321
322 intent2 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId2,
323 egressDevice=deviceId1,
324 ingressPort=port2,
325 egressPort=port1,
326 ethType=ethType,
327 ethSrc=mac2,
328 ethDst=mac1,
329 bandwidth=bandwidth,
330 lambdaAlloc=lambdaAlloc,
331 ipProto=ipProto,
332 ipSrc=ip2,
333 ipDst=ip1,
334 tcpSrc=tcp2,
335 tcpDst=tcp1 )
kelvin-onlab0e684682015-08-11 18:51:41 -0700336
337 # Get all intents ID in the system, time delay right after intents are added
338 time.sleep( main.addIntentSleep )
kelvin-onlab44147802015-07-27 17:57:31 -0700339 intentsId = main.CLIs[ 0 ].getIntentsId()
kelvin-onlab44147802015-07-27 17:57:31 -0700340
341 # Check intents state
342 time.sleep( main.checkIntentSleep )
343 intentResult = checkIntentState( main, intentsId )
344 # Check flows count in each node
345 checkFlowsCount( main )
346
347 # Check intents state again if first check fails...
348 if not intentResult:
349 intentResult = checkIntentState( main, intentsId )
350
351 # Check flows count in each node
352 checkFlowsCount( main )
353 # Verify flows
354 checkFlowsState( main )
355
356 # Ping hosts
357 firstPingResult = pingallHosts( main, hostNames )
358 if not firstPingResult:
359 main.log.debug( "First ping failed, there must be" +
360 " something wrong with ONOS performance" )
361
362 # Ping hosts again...
363 pingResult = pingResult and pingallHosts( main, hostNames )
364
365 # Test rerouting if these variables exist
366 if sw1 and sw2 and expectedLink:
367 # link down
368 linkDownResult = link( main, sw1, sw2, "down" )
369 intentResult = intentResult and checkIntentState( main, intentsId )
370
371 # Check flows count in each node
372 checkFlowsCount( main )
373 # Verify flows
374 checkFlowsState( main )
375
376 # Check OnosTopology
377 topoResult = checkTopology( main, expectedLink )
378
379 # Ping hosts
380 pingResult = pingResult and pingallHosts( main, hostNames )
381
382 intentResult = checkIntentState( main, intentsId )
383
384 # Checks ONOS state in link down
385 if linkDownResult and topoResult and pingResult and intentResult:
386 main.log.info( itemName + ": Successfully brought link down" )
387 else:
388 main.log.error( itemName + ": Failed to bring link down" )
389
390 # link up
391 linkUpResult = link( main, sw1, sw2, "up" )
392 time.sleep( main.rerouteSleep )
393
394 # Check flows count in each node
395 checkFlowsCount( main )
396 # Verify flows
397 checkFlowsState( main )
398
399 # Check OnosTopology
400 topoResult = checkTopology( main, main.numLinks )
401
402 # Ping hosts
403 pingResult = pingResult and pingallHosts( main, hostNames )
404
405 intentResult = checkIntentState( main, intentsId )
406
407 # Checks ONOS state in link up
408 if linkUpResult and topoResult and pingResult and intentResult:
409 main.log.info( itemName + ": Successfully brought link back up" )
410 else:
411 main.log.error( itemName + ": Failed to bring link back up" )
412
413 # Remove all intents
414 removeIntentResult = removeAllIntents( main )
415
416 stepResult = pingResult and linkDownResult and linkUpResult \
417 and intentResult and removeIntentResult
418
419 return stepResult
420
kelvin-onlab0e684682015-08-11 18:51:41 -0700421def pointIntentTcp( main,
422 name,
423 host1,
424 host2,
425 onosNode=0,
426 deviceId1="",
427 deviceId2="",
428 port1="",
429 port2="",
430 ethType="",
431 mac1="",
432 mac2="",
433 bandwidth="",
434 lambdaAlloc=False,
435 ipProto="",
436 ip1="",
437 ip2="",
438 tcp1="",
439 tcp2="",
440 sw1="",
441 sw2="",
442 expectedLink=0 ):
443
444 """
445 Description:
446 Verify add-point-intent only for TCP
447 Steps:
448 - Get device ids | ports
449 - Add point intents
450 - Check intents
451 - Verify flows
452 - Ping hosts
453 - Reroute
454 - Link down
455 - Verify flows
456 - Check topology
457 - Ping hosts
458 - Link up
459 - Verify flows
460 - Check topology
461 - Ping hosts
462 - Remove intents
463 Required:
464 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
465 host1 - Name of first host
466 host2 - Name of second host
467 Optional:
468 onosNode - ONOS node to install the intents in main.CLIs[ ]
469 0 by default so that it will always use the first
470 ONOS node
471 deviceId1 - ONOS device id of the first switch, the same as the
472 location of the first host eg. of:0000000000000001/1,
473 located at device 1 port 1
474 deviceId2 - ONOS device id of the second switch
475 port1 - The port number where the first host is attached
476 port2 - The port number where the second host is attached
477 ethType - Ethernet type eg. IPV4, IPV6
478 mac1 - Mac address of first host
479 mac2 - Mac address of the second host
480 bandwidth - Bandwidth capacity
481 lambdaAlloc - Allocate lambda, defaults to False
482 ipProto - IP protocol
483 ip1 - IP address of first host
484 ip2 - IP address of second host
485 tcp1 - TCP port of first host
486 tcp2 - TCP port of second host
487 sw1 - First switch to bring down & up for rerouting purpose
488 sw2 - Second switch to bring down & up for rerouting purpose
489 expectedLink - Expected link when the switches are down, it should
490 be two links lower than the links before the two
491 switches are down
492 """
493
494 assert main, "There is no main variable"
495 assert name, "variable name is empty"
496 assert host1 and host2, "You must specify hosts"
497
498 global itemName
499 itemName = name
500 host1 = host1
501 host2 = host2
502 hostNames = [ host1, host2 ]
503 intentsId = []
504
505 iperfResult = main.TRUE
506 intentResult = main.TRUE
507 removeIntentResult = main.TRUE
508 flowResult = main.TRUE
509 topoResult = main.TRUE
510 linkDownResult = main.TRUE
511 linkUpResult = main.TRUE
512 onosNode = int( onosNode )
513
514 # Adding bidirectional point intents
515 main.log.info( itemName + ": Adding point intents" )
516 intent1 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId1,
517 egressDevice=deviceId2,
518 ingressPort=port1,
519 egressPort=port2,
520 ethType=ethType,
521 ethSrc=mac1,
522 ethDst=mac2,
523 bandwidth=bandwidth,
524 lambdaAlloc=lambdaAlloc,
525 ipProto=ipProto,
526 ipSrc=ip1,
527 ipDst=ip2,
528 tcpSrc=tcp1,
529 tcpDst="" )
530
531 intent2 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId2,
532 egressDevice=deviceId1,
533 ingressPort=port2,
534 egressPort=port1,
535 ethType=ethType,
536 ethSrc=mac2,
537 ethDst=mac1,
538 bandwidth=bandwidth,
539 lambdaAlloc=lambdaAlloc,
540 ipProto=ipProto,
541 ipSrc=ip2,
542 ipDst=ip1,
543 tcpSrc=tcp2,
544 tcpDst="" )
545
546 intent3 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId1,
547 egressDevice=deviceId2,
548 ingressPort=port1,
549 egressPort=port2,
550 ethType=ethType,
551 ethSrc=mac1,
552 ethDst=mac2,
553 bandwidth=bandwidth,
554 lambdaAlloc=lambdaAlloc,
555 ipProto=ipProto,
556 ipSrc=ip1,
557 ipDst=ip2,
558 tcpSrc="",
559 tcpDst=tcp2 )
560
561 intent4 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId2,
562 egressDevice=deviceId1,
563 ingressPort=port2,
564 egressPort=port1,
565 ethType=ethType,
566 ethSrc=mac2,
567 ethDst=mac1,
568 bandwidth=bandwidth,
569 lambdaAlloc=lambdaAlloc,
570 ipProto=ipProto,
571 ipSrc=ip2,
572 ipDst=ip1,
573 tcpSrc="",
574 tcpDst=tcp1 )
575
576 # Get all intents ID in the system, time delay right after intents are added
577 time.sleep( main.addIntentSleep )
578 intentsId = main.CLIs[ 0 ].getIntentsId()
579 # Check intents state
580 time.sleep( main.checkIntentSleep )
581 intentResult = checkIntentState( main, intentsId )
582 # Check flows count in each node
583 checkFlowsCount( main )
584
585 # Check intents state again if first check fails...
586 if not intentResult:
587 intentResult = checkIntentState( main, intentsId )
588
589 # Check flows count in each node
590 checkFlowsCount( main )
591
592 # Verify flows
593 checkFlowsState( main )
594
595 # Run iperf to both host
596 iperfResult = iperfResult and main.Mininet1.iperftcp( host1,
597 host2, 10 )
598
599 # Test rerouting if these variables exist
600 if sw1 and sw2 and expectedLink:
601 # link down
602 linkDownResult = link( main, sw1, sw2, "down" )
603 intentResult = intentResult and checkIntentState( main, intentsId )
604
605 # Check flows count in each node
606 checkFlowsCount( main )
607 # Verify flows
608 checkFlowsState( main )
609
610 # Check OnosTopology
611 topoResult = checkTopology( main, expectedLink )
612
613 # Run iperf to both host
614 iperfResult = iperfResult and main.Mininet1.iperftcp( host1,
615 host2, 10 )
616
617 intentResult = checkIntentState( main, intentsId )
618
619 # Checks ONOS state in link down
620 if linkDownResult and topoResult and iperfResult and intentResult:
621 main.log.info( itemName + ": Successfully brought link down" )
622 else:
623 main.log.error( itemName + ": Failed to bring link down" )
624
625 # link up
626 linkUpResult = link( main, sw1, sw2, "up" )
627 time.sleep( main.rerouteSleep )
628
629 # Check flows count in each node
630 checkFlowsCount( main )
631 # Verify flows
632 checkFlowsState( main )
633
634 # Check OnosTopology
635 topoResult = checkTopology( main, main.numLinks )
636
637 # Run iperf to both host
638 iperfResult = iperfResult and main.Mininet1.iperftcp( host1,
639 host2, 10 )
640
641 intentResult = checkIntentState( main, intentsId )
642
643 # Checks ONOS state in link up
644 if linkUpResult and topoResult and iperfResult and intentResult:
645 main.log.info( itemName + ": Successfully brought link back up" )
646 else:
647 main.log.error( itemName + ": Failed to bring link back up" )
648
649 # Remove all intents
650 removeIntentResult = removeAllIntents( main )
651
652 stepResult = iperfResult and linkDownResult and linkUpResult \
653 and intentResult and removeIntentResult
654
655 return stepResult
656
kelvin-onlab44147802015-07-27 17:57:31 -0700657def singleToMultiIntent( main,
658 name,
659 hostNames,
660 onosNode=0,
661 devices="",
662 ports=None,
663 ethType="",
664 macs=None,
665 bandwidth="",
666 lambdaAlloc=False,
667 ipProto="",
668 ipAddresses="",
669 tcp="",
670 sw1="",
671 sw2="",
672 expectedLink=0 ):
673 """
674 Verify Single to Multi Point intents
675 NOTE:If main.hostsData is not defined, variables data should be passed
676 in the same order index wise. All devices in the list should have the
677 same format, either all the devices have its port or it doesn't.
678 eg. hostName = [ 'h1', 'h2' ,.. ]
679 devices = [ 'of:0000000000000001', 'of:0000000000000002', ...]
680 ports = [ '1', '1', ..]
681 ...
682 Description:
683 Verify add-single-to-multi-intent iterates through the list of given
684 host | devices and add intents
685 Steps:
686 - Get device ids | ports
687 - Add single to multi point intents
688 - Check intents
689 - Verify flows
690 - Ping hosts
691 - Reroute
692 - Link down
693 - Verify flows
694 - Check topology
695 - Ping hosts
696 - Link up
697 - Verify flows
698 - Check topology
699 - Ping hosts
700 - Remove intents
701 Required:
702 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
703 hostNames - List of host names
704 Optional:
705 onosNode - ONOS node to install the intents in main.CLIs[ ]
706 0 by default so that it will always use the first
707 ONOS node
708 devices - List of device ids in the same order as the hosts
709 in hostNames
710 ports - List of port numbers in the same order as the device in
711 devices
712 ethType - Ethernet type eg. IPV4, IPV6
713 macs - List of hosts mac address in the same order as the hosts in
714 hostNames
715 bandwidth - Bandwidth capacity
716 lambdaAlloc - Allocate lambda, defaults to False
717 ipProto - IP protocol
718 ipAddresses - IP addresses of host in the same order as the hosts in
719 hostNames
720 tcp - TCP ports in the same order as the hosts in hostNames
721 sw1 - First switch to bring down & up for rerouting purpose
722 sw2 - Second switch to bring down & up for rerouting purpose
723 expectedLink - Expected link when the switches are down, it should
724 be two links lower than the links before the two
725 switches are down
726 """
727
728 assert main, "There is no main variable"
729 assert hostNames, "You must specify hosts"
730 assert devices or main.hostsData, "You must specify devices"
731
732 global itemName
733 itemName = name
734 tempHostsData = {}
735 intentsId = []
736 onosNode = int( onosNode )
737
738 macsDict = {}
739 ipDict = {}
740 if hostNames and devices:
741 if len( hostNames ) != len( devices ):
742 main.log.debug( "hosts and devices does not have the same length" )
743 #print "len hostNames = ", len( hostNames )
744 #print "len devices = ", len( devices )
745 return main.FALSE
746 if ports:
747 if len( ports ) != len( devices ):
748 main.log.error( "Ports and devices does " +
749 "not have the same length" )
750 #print "len devices = ", len( devices )
751 #print "len ports = ", len( ports )
752 return main.FALSE
753 else:
754 main.log.info( "Device Ports are not specified" )
755 if macs:
756 for i in range( len( devices ) ):
757 macsDict[ devices[ i ] ] = macs[ i ]
758
759 elif hostNames and not devices and main.hostsData:
760 devices = []
761 main.log.info( "singleToMultiIntent function is using main.hostsData" )
762 for host in hostNames:
763 devices.append( main.hostsData.get( host ).get( 'location' ) )
764 macsDict[ main.hostsData.get( host ).get( 'location' ) ] = \
765 main.hostsData.get( host ).get( 'mac' )
766 ipDict[ main.hostsData.get( host ).get( 'location' ) ] = \
767 main.hostsData.get( host ).get( 'ipAddresses' )
768 #print main.hostsData
769
770 #print 'host names = ', hostNames
771 #print 'devices = ', devices
772 #print "macsDict = ", macsDict
773
774 pingResult = main.TRUE
775 intentResult = main.TRUE
776 removeIntentResult = main.TRUE
777 flowResult = main.TRUE
778 topoResult = main.TRUE
779 linkDownResult = main.TRUE
780 linkUpResult = main.TRUE
781
782 devicesCopy = copy.copy( devices )
783 if ports:
784 portsCopy = copy.copy( ports )
785 main.log.info( itemName + ": Adding single point to multi point intents" )
786
787 # Check flows count in each node
788 checkFlowsCount( main )
789
790 # Adding bidirectional point intents
791 for i in range( len( devices ) ):
792 ingressDevice = devicesCopy[ i ]
793 egressDeviceList = copy.copy( devicesCopy )
794 egressDeviceList.remove( ingressDevice )
795 if ports:
796 portIngress = portsCopy[ i ]
797 portEgressList = copy.copy( portsCopy )
798 del portEgressList[ i ]
799 else:
800 portIngress = ""
801 portEgressList = None
802 if not macsDict:
803 srcMac = ""
804 else:
805 srcMac = macsDict[ ingressDevice ]
806 if srcMac == None:
807 main.log.debug( "There is no MAC in device - " + ingressDevice )
808 srcMac = ""
809
810 intentsId.append(
811 main.CLIs[ onosNode ].addSinglepointToMultipointIntent(
812 ingressDevice=ingressDevice,
813 egressDeviceList=egressDeviceList,
814 portIngress=portIngress,
815 portEgressList=portEgressList,
816 ethType=ethType,
817 ethSrc=srcMac,
818 bandwidth=bandwidth,
819 lambdaAlloc=lambdaAlloc,
820 ipProto=ipProto,
821 ipSrc="",
822 ipDst="",
823 tcpSrc="",
824 tcpDst="" ) )
825
826 # Wait some time for the flow to go through when using multi instance
827 pingResult = pingallHosts( main, hostNames )
828
829 # Check intents state
830 time.sleep( main.checkIntentSleep )
831 intentResult = checkIntentState( main, intentsId )
832
833 # Check intents state again if first check fails...
834 if not intentResult:
835 intentResult = checkIntentState( main, intentsId )
836
837 # Check flows count in each node
838 checkFlowsCount( main )
839 # Verify flows
840 checkFlowsState( main )
841
842 pingResult = pingResult and pingallHosts( main, hostNames )
843
844 # Test rerouting if these variables exist
845 if sw1 and sw2 and expectedLink:
846 # link down
847 linkDownResult = link( main, sw1, sw2, "down" )
848 intentResult = intentResult and checkIntentState( main, intentsId )
849
850 # Check flows count in each node
851 checkFlowsCount( main )
852 # Verify flows
853 checkFlowsState( main )
854
855 # Check OnosTopology
856 topoResult = checkTopology( main, expectedLink )
857
858 # Ping hosts
859 pingResult = pingResult and pingallHosts( main, hostNames )
860
861 intentResult = checkIntentState( main, intentsId )
862
863 # Checks ONOS state in link down
864 if linkDownResult and topoResult and pingResult and intentResult:
865 main.log.info( itemName + ": Successfully brought link down" )
866 else:
867 main.log.error( itemName + ": Failed to bring link down" )
868
869 # link up
870 linkUpResult = link( main, sw1, sw2, "up" )
871 time.sleep( main.rerouteSleep )
872
873 # Check flows count in each node
874 checkFlowsCount( main )
875 # Verify flows
876 checkFlowsState( main )
877
878 # Check OnosTopology
879 topoResult = checkTopology( main, main.numLinks )
880
881 # Ping hosts
882 pingResult = pingResult and pingallHosts( main, hostNames )
883
884 intentResult = checkIntentState( main, intentsId )
885
886 # Checks ONOS state in link up
887 if linkUpResult and topoResult and pingResult and intentResult:
888 main.log.info( itemName + ": Successfully brought link back up" )
889 else:
890 main.log.error( itemName + ": Failed to bring link back up" )
891
892 # Remove all intents
893 removeIntentResult = removeAllIntents( main, intentsId )
894
895 stepResult = pingResult and linkDownResult and linkUpResult \
896 and intentResult and removeIntentResult
897
898 return stepResult
899
900def multiToSingleIntent( main,
901 name,
902 hostNames,
903 onosNode=0,
904 devices="",
905 ports=None,
906 ethType="",
907 macs=None,
908 bandwidth="",
909 lambdaAlloc=False,
910 ipProto="",
911 ipAddresses="",
912 tcp="",
913 sw1="",
914 sw2="",
915 expectedLink=0 ):
916 """
917 Verify Single to Multi Point intents
918 NOTE:If main.hostsData is not defined, variables data should be passed in the
919 same order index wise. All devices in the list should have the same
920 format, either all the devices have its port or it doesn't.
921 eg. hostName = [ 'h1', 'h2' ,.. ]
922 devices = [ 'of:0000000000000001', 'of:0000000000000002', ...]
923 ports = [ '1', '1', ..]
924 ...
925 Description:
926 Verify add-multi-to-single-intent
927 Steps:
928 - Get device ids | ports
929 - Add multi to single point intents
930 - Check intents
931 - Verify flows
932 - Ping hosts
933 - Reroute
934 - Link down
935 - Verify flows
936 - Check topology
937 - Ping hosts
938 - Link up
939 - Verify flows
940 - Check topology
941 - Ping hosts
942 - Remove intents
943 Required:
944 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
945 hostNames - List of host names
946 Optional:
947 onosNode - ONOS node to install the intents in main.CLIs[ ]
948 0 by default so that it will always use the first
949 ONOS node
950 devices - List of device ids in the same order as the hosts
951 in hostNames
952 ports - List of port numbers in the same order as the device in
953 devices
954 ethType - Ethernet type eg. IPV4, IPV6
955 macs - List of hosts mac address in the same order as the hosts in
956 hostNames
957 bandwidth - Bandwidth capacity
958 lambdaAlloc - Allocate lambda, defaults to False
959 ipProto - IP protocol
960 ipAddresses - IP addresses of host in the same order as the hosts in
961 hostNames
962 tcp - TCP ports in the same order as the hosts in hostNames
963 sw1 - First switch to bring down & up for rerouting purpose
964 sw2 - Second switch to bring down & up for rerouting purpose
965 expectedLink - Expected link when the switches are down, it should
966 be two links lower than the links before the two
967 switches are down
968 """
969
970 assert main, "There is no main variable"
971 assert hostNames, "You must specify hosts"
972 assert devices or main.hostsData, "You must specify devices"
973
974 global itemName
975 itemName = name
976 tempHostsData = {}
977 intentsId = []
978 onosNode = int( onosNode )
979
980 macsDict = {}
981 ipDict = {}
982 if hostNames and devices:
983 if len( hostNames ) != len( devices ):
984 main.log.debug( "hosts and devices does not have the same length" )
985 #print "len hostNames = ", len( hostNames )
986 #print "len devices = ", len( devices )
987 return main.FALSE
988 if ports:
989 if len( ports ) != len( devices ):
990 main.log.error( "Ports and devices does " +
991 "not have the same length" )
992 #print "len devices = ", len( devices )
993 #print "len ports = ", len( ports )
994 return main.FALSE
995 else:
996 main.log.info( "Device Ports are not specified" )
997 if macs:
998 for i in range( len( devices ) ):
999 macsDict[ devices[ i ] ] = macs[ i ]
1000 elif hostNames and not devices and main.hostsData:
1001 devices = []
1002 main.log.info( "multiToSingleIntent function is using main.hostsData" )
1003 for host in hostNames:
1004 devices.append( main.hostsData.get( host ).get( 'location' ) )
1005 macsDict[ main.hostsData.get( host ).get( 'location' ) ] = \
1006 main.hostsData.get( host ).get( 'mac' )
1007 ipDict[ main.hostsData.get( host ).get( 'location' ) ] = \
1008 main.hostsData.get( host ).get( 'ipAddresses' )
1009 #print main.hostsData
1010
1011 #print 'host names = ', hostNames
1012 #print 'devices = ', devices
1013 #print "macsDict = ", macsDict
1014
1015 pingResult = main.TRUE
1016 intentResult = main.TRUE
1017 removeIntentResult = main.TRUE
1018 flowResult = main.TRUE
1019 topoResult = main.TRUE
1020 linkDownResult = main.TRUE
1021 linkUpResult = main.TRUE
1022
1023 devicesCopy = copy.copy( devices )
1024 if ports:
1025 portsCopy = copy.copy( ports )
1026 main.log.info( itemName + ": Adding multi point to single point intents" )
1027
1028 # Check flows count in each node
1029 checkFlowsCount( main )
1030
1031 # Adding bidirectional point intents
1032 for i in range( len( devices ) ):
1033 egressDevice = devicesCopy[ i ]
1034 ingressDeviceList = copy.copy( devicesCopy )
1035 ingressDeviceList.remove( egressDevice )
1036 if ports:
1037 portEgress = portsCopy[ i ]
1038 portIngressList = copy.copy( portsCopy )
1039 del portIngressList[ i ]
1040 else:
1041 portEgress = ""
1042 portIngressList = None
1043 if not macsDict:
1044 dstMac = ""
1045 else:
1046 dstMac = macsDict[ egressDevice ]
1047 if dstMac == None:
1048 main.log.debug( "There is no MAC in device - " + egressDevice )
1049 dstMac = ""
1050
1051 intentsId.append(
1052 main.CLIs[ onosNode ].addMultipointToSinglepointIntent(
1053 ingressDeviceList=ingressDeviceList,
1054 egressDevice=egressDevice,
1055 portIngressList=portIngressList,
1056 portEgress=portEgress,
1057 ethType=ethType,
1058 ethDst=dstMac,
1059 bandwidth=bandwidth,
1060 lambdaAlloc=lambdaAlloc,
1061 ipProto=ipProto,
1062 ipSrc="",
1063 ipDst="",
1064 tcpSrc="",
1065 tcpDst="" ) )
1066
1067 pingResult = pingallHosts( main, hostNames )
1068
1069 # Check intents state
1070 time.sleep( main.checkIntentSleep )
1071 intentResult = checkIntentState( main, intentsId )
1072
1073 # Check intents state again if first check fails...
1074 if not intentResult:
1075 intentResult = checkIntentState( main, intentsId )
1076
1077 # Check flows count in each node
1078 checkFlowsCount( main )
1079 # Verify flows
1080 checkFlowsState( main )
1081
1082 # Ping hosts
1083 pingResult = pingResult and pingallHosts( main, hostNames )
1084 # Ping hosts again...
1085 pingResult = pingResult and pingallHosts( main, hostNames )
1086
1087 # Test rerouting if these variables exist
1088 if sw1 and sw2 and expectedLink:
1089 # link down
1090 linkDownResult = link( main, sw1, sw2, "down" )
1091 intentResult = intentResult and checkIntentState( main, intentsId )
1092
1093 # Check flows count in each node
1094 checkFlowsCount( main )
1095 # Verify flows
1096 checkFlowsState( main )
1097
1098 # Check OnosTopology
1099 topoResult = checkTopology( main, expectedLink )
1100
1101 # Ping hosts
1102 pingResult = pingResult and pingallHosts( main, hostNames )
1103
1104 intentResult = checkIntentState( main, intentsId )
1105
1106 # Checks ONOS state in link down
1107 if linkDownResult and topoResult and pingResult and intentResult:
1108 main.log.info( itemName + ": Successfully brought link down" )
1109 else:
1110 main.log.error( itemName + ": Failed to bring link down" )
1111
1112 # link up
1113 linkUpResult = link( main, sw1, sw2, "up" )
1114 time.sleep( main.rerouteSleep )
1115
1116 # Check flows count in each node
1117 checkFlowsCount( main )
1118 # Verify flows
1119 checkFlowsState( main )
1120
1121 # Check OnosTopology
1122 topoResult = checkTopology( main, main.numLinks )
1123
1124 # Ping hosts
1125 pingResult = pingResult and pingallHosts( main, hostNames )
1126
1127 intentResult = checkIntentState( main, intentsId )
1128
1129 # Checks ONOS state in link up
1130 if linkUpResult and topoResult and pingResult and intentResult:
1131 main.log.info( itemName + ": Successfully brought link back up" )
1132 else:
1133 main.log.error( itemName + ": Failed to bring link back up" )
1134
1135 # Remove all intents
1136 removeIntentResult = removeAllIntents( main, intentsId )
1137
1138 stepResult = pingResult and linkDownResult and linkUpResult \
1139 and intentResult and removeIntentResult
1140
1141 return stepResult
1142
kelvin-onlab0e684682015-08-11 18:51:41 -07001143def pingallHosts( main, hostList ):
kelvin-onlab44147802015-07-27 17:57:31 -07001144 # Ping all host in the hosts list variable
1145 print "Pinging : ", hostList
1146 pingResult = main.TRUE
kelvin-onlab0e684682015-08-11 18:51:41 -07001147 pingResult = main.Mininet1.pingallHosts( hostList )
kelvin-onlab44147802015-07-27 17:57:31 -07001148 return pingResult
1149
kelvin-onlab0e684682015-08-11 18:51:41 -07001150def getHostsData( main, hostList ):
kelvin-onlab44147802015-07-27 17:57:31 -07001151 """
1152 Use fwd app and pingall to discover all the hosts
1153 """
1154
1155 activateResult = main.TRUE
1156 appCheck = main.TRUE
1157 getDataResult = main.TRUE
1158 main.log.info( "Activating reactive forwarding app " )
1159 activateResult = main.CLIs[ 0 ].activateApp( "org.onosproject.fwd" )
1160 if not activateResult:
1161 main.log.error( "Something went wrong installing fwd app" )
1162 time.sleep( main.fwdSleep )
kelvin-onlab0e684682015-08-11 18:51:41 -07001163 if isinstance( hostList[ 0 ], types.StringType ):
1164 main.Mininet1.pingallHosts( hostList )
1165 elif isinstance( hostList[ 0 ], types.ListType ):
1166 for i in xrange( len( hostList ) ):
1167 main.Mininet1.pingallHosts( hostList[ i ] )
1168
kelvin-onlab44147802015-07-27 17:57:31 -07001169 hostsJson = json.loads( main.CLIs[ 0 ].hosts() )
1170 hosts = main.Mininet1.getHosts().keys()
1171 # TODO: Make better use of new getHosts function
1172 for host in hosts:
1173 main.hostsData[ host ] = {}
1174 main.hostsData[ host ][ 'mac' ] = \
1175 main.Mininet1.getMacAddress( host ).upper()
1176 for hostj in hostsJson:
1177 if main.hostsData[ host ][ 'mac' ] == hostj[ 'mac' ]:
1178 main.hostsData[ host ][ 'id' ] = hostj[ 'id' ]
1179 main.hostsData[ host ][ 'vlan' ] = hostj[ 'vlan' ]
1180 main.hostsData[ host ][ 'location' ] = \
1181 hostj[ 'location' ][ 'elementId' ] + '/' + \
1182 hostj[ 'location' ][ 'port' ]
1183 main.hostsData[ host ][ 'ipAddresses' ] = hostj[ 'ipAddresses' ]
1184
1185 main.log.info( "Deactivating reactive forwarding app " )
1186 deactivateResult = main.CLIs[ 0 ].deactivateApp( "org.onosproject.fwd" )
1187 if activateResult and deactivateResult and main.hostsData:
1188 main.log.info( "Successfully used fwd app to discover hosts " )
1189 getDataResult = main.TRUE
1190 else:
1191 main.log.info( "Failed to use fwd app to discover hosts " )
1192 getDataResult = main.FALSE
1193
1194 print main.hostsData
1195
1196 return getDataResult
1197
1198def checkTopology( main, expectedLink ):
1199 statusResult = main.TRUE
1200 # Check onos topology
1201 main.log.info( itemName + ": Checking ONOS topology " )
1202
1203 for i in range( main.numCtrls ):
1204 topologyResult = main.CLIs[ i ].topology()
1205 statusResult = main.ONOSbench.checkStatus( topologyResult,
1206 main.numSwitch,
1207 expectedLink )\
1208 and statusResult
1209 if not statusResult:
1210 main.log.error( itemName + ": Topology mismatch" )
1211 else:
1212 main.log.info( itemName + ": Topology match" )
1213 return statusResult
1214
1215def checkIntentState( main, intentsId ):
1216 """
1217 This function will check intent state to make sure all the intents
1218 are in INSTALLED state
1219 """
1220
1221 intentResult = main.TRUE
1222 results = []
1223
1224 main.log.info( itemName + ": Checking intents state" )
1225 # First check of intents
1226 for i in range( main.numCtrls ):
1227 tempResult = main.CLIs[ i ].checkIntentState( intentsId=intentsId )
1228 results.append( tempResult )
1229
1230 expectedState = [ 'INSTALLED', 'INSTALLING' ]
1231
1232 if all( result == main.TRUE for result in results ):
1233 main.log.info( itemName + ": Intents are installed correctly" )
1234 else:
1235 # Wait for at least 5 second before checking the intents again
1236 time.sleep( 5 )
1237 results = []
1238 # Second check of intents since some of the intents may be in
1239 # INSTALLING state, they should be in INSTALLED at this time
1240 for i in range( main.numCtrls ):
1241 tempResult = main.CLIs[ i ].checkIntentState(
1242 intentsId=intentsId )
1243 results.append( tempResult )
1244 if all( result == main.TRUE for result in results ):
1245 main.log.info( itemName + ": Intents are installed correctly" )
1246 else:
1247 main.log.error( itemName + ": Intents are NOT installed correctly" )
1248 intentResult = main.FALSE
1249
1250 return intentResult
1251
1252def checkFlowsState( main ):
1253
1254 main.log.info( itemName + ": Check flows state" )
1255 checkFlowsResult = main.CLIs[ 0 ].checkFlowsState()
1256 return checkFlowsResult
1257
1258def link( main, sw1, sw2, option):
1259
1260 # link down
1261 main.log.info( itemName + ": Bring link " + option + "between " +
1262 sw1 + " and " + sw2 )
1263 linkResult = main.Mininet1.link( end1=sw1, end2=sw2, option=option )
1264 return linkResult
1265
1266def removeAllIntents( main ):
1267 """
1268 Remove all intents in the intentsId
1269 """
1270
1271 onosSummary = []
1272 removeIntentResult = main.TRUE
1273 # Remove intents
1274 removeIntentResult = main.CLIs[ 0 ].removeAllIntents( )
1275
1276 if removeIntentResult:
1277 main.log.info( itemName + ": There are no more intents remaining, " +
1278 "successfully removed all the intents." )
1279
1280 return removeIntentResult
1281
1282def checkFlowsCount( main ):
1283 """
1284 Check flows count in each node
1285 """
1286
1287 flowsCount = []
1288 main.log.info( itemName + ": Checking flows count in each ONOS node" )
1289 for i in range( main.numCtrls ):
1290 flowsCount.append( len( json.loads( main.CLIs[ i ].flows() ) ) )
1291
1292 if flowsCount:
1293 if all( flows==flowsCount[ 0 ] for flows in flowsCount ):
1294 main.log.info( itemName + ": There are " + str( flowsCount[ 0 ] ) +
1295 " flows in all ONOS node" )
1296 else:
1297 for i in range( main.numCtrls ):
1298 main.log.debug( itemName + ": ONOS node " + str( i + 1 ) +
1299 " has " + flowsCount[ i ] + " flows" )
1300 else:
1301 main.log.error( "Checking flows count failed, check summary command" )
1302 return main.FALSE
1303
1304 return main.TRUE
1305