[ONOS-7747] Add router failure test cases to SRRouting

Change-Id: I06706c36caa181fff50c0f13c5976298e017940f
diff --git a/TestON/tests/USECASE/SegmentRouting/SRRouting/SRRouting.params b/TestON/tests/USECASE/SegmentRouting/SRRouting/SRRouting.params
index 027aeb1..72d8925 100644
--- a/TestON/tests/USECASE/SegmentRouting/SRRouting/SRRouting.params
+++ b/TestON/tests/USECASE/SegmentRouting/SRRouting/SRRouting.params
@@ -1,5 +1,5 @@
 <PARAMS>
-    <testcases>101,102,103,104,105,106,107,108,109,201,202,203,204,205,206,207,208,209,301,302,303,304,305,306,307,308,309,601,602,603,604,605,606,620,621,622,630,640,641,642,643,651,652,653</testcases>
+    <testcases>101,102,103,104,105,106,107,108,109,201,202,203,204,205,206,207,208,209,301,302,303,304,305,306,307,308,309,601,602,603,604,605,606,620,621,622,630,640,641,642,643,651,652,653,660,661,662,663,664,665</testcases>
 
     <GRAPH>
         <nodeCluster>Fabric</nodeCluster>
diff --git a/TestON/tests/USECASE/SegmentRouting/SRRouting/SRRouting.py b/TestON/tests/USECASE/SegmentRouting/SRRouting/SRRouting.py
index 281e7a5..f379896 100644
--- a/TestON/tests/USECASE/SegmentRouting/SRRouting/SRRouting.py
+++ b/TestON/tests/USECASE/SegmentRouting/SRRouting/SRRouting.py
@@ -1446,3 +1446,173 @@
         lib.verifyTraffic( main, main.internalIpv4Hosts, "10.2.21.1", "h5v4Scapy", "h5v4-bond1" )
 
         lib.cleanup( main, copyKarafLog=False, removeHostComponent=True )
+
+    def CASE660( self, main ):
+        """
+        External router failure
+        - Bring down quagga external router-1. Hosts that are behind router-2 should still be reachable. Hosts that are behind router-1 should not be reachable.
+        - Bring router up again, all external hosts are reachable again.
+        - Repeat this with external router-2.
+        """
+        from tests.USECASE.SegmentRouting.SRRouting.dependencies.SRRoutingTest import *
+        from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
+        main.case( "External router failure with cross-link" )
+        setupTest( main, test_idx=660, onosNodes=3, static=True )
+        main.externalIpv4Hosts += main.staticIpv4Hosts
+        main.externalIpv6Hosts += main.staticIpv6Hosts
+        verify( main, disconnected=False )
+        # Bring down/up external router-1
+        verifyRouterFailure( main, "r1", [ "rh5v4" ], [ "rh11v6", "rh5v6" ] )
+        # Bring down/up external router-2
+        verifyRouterFailure( main, "r2", [], [ "rh22v6" ] )
+        lib.cleanup( main, copyKarafLog=False, removeHostComponent=True )
+
+    def CASE661( self, main ):
+        """
+        External router link failure
+        - Drop a non-cross-link for external router-1. All external hosts should be reachable (via cross-link).
+        - Bring up the link. All external hosts should be reachable.
+        - Repeat the steps above with the cross-link of external router-1
+        - Repeat all steps above with external router-2
+        """
+        from tests.USECASE.SegmentRouting.SRRouting.dependencies.SRRoutingTest import *
+        from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
+        main.case( "External router link failure with cross-link" )
+        setupTest( main, test_idx=661, onosNodes=3, static=True )
+        main.externalIpv4Hosts += main.staticIpv4Hosts
+        main.externalIpv6Hosts += main.staticIpv6Hosts
+        verify( main, disconnected=False )
+        # Bring down/up a non-cross-link for external router-1
+        portsToDisable = [ [ "of:0000000000000005", 13 ] ]
+        lib.disablePortBatch( main, portsToDisable, 10, 48 )
+        verify( main, disconnected=False, internal=False )
+        lib.enablePortBatch( main, portsToDisable, 10, 48 )
+        verify( main, disconnected=False, internal=False )
+        # Bring down/up a cross-link for external router-1
+        portsToDisable = [ [ "of:0000000000000005", 14 ] ]
+        lib.disablePortBatch( main, portsToDisable, 10, 48 )
+        verify( main, disconnected=False, internal=False )
+        lib.enablePortBatch( main, portsToDisable, 10, 48 )
+        verify( main, disconnected=False, internal=False )
+        # Bring down/up a non-cross-link for external router-2
+        portsToDisable = [ [ "of:0000000000000004", 14 ] ]
+        lib.disablePortBatch( main, portsToDisable, 10, 48 )
+        verify( main, disconnected=False, internal=False )
+        lib.enablePortBatch( main, portsToDisable, 10, 48 )
+        verify( main, disconnected=False, internal=False )
+        # Bring down/up a cross-link for external router-2
+        portsToDisable = [ [ "of:0000000000000004", 13 ] ]
+        lib.disablePortBatch( main, portsToDisable, 10, 48 )
+        verify( main, disconnected=False, internal=False )
+        lib.enablePortBatch( main, portsToDisable, 10, 48 )
+        verify( main, disconnected=False, internal=False )
+        lib.cleanup( main, copyKarafLog=False, removeHostComponent=True )
+
+    def CASE662( self, main ):
+        """
+        Internal router failure
+        - Bring down quagga internal router-1. All external hosts should be reachable (via cross-link).
+        - Bring the router up. All external hosts should be reachable.
+        - Repeat this with internal router-2.
+        """
+        from tests.USECASE.SegmentRouting.SRRouting.dependencies.SRRoutingTest import *
+        from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
+        main.case( "Internal router failure with cross-link" )
+        setupTest( main, test_idx=662, onosNodes=3, static=True )
+        main.externalIpv4Hosts += main.staticIpv4Hosts
+        main.externalIpv6Hosts += main.staticIpv6Hosts
+        verify( main, disconnected=False )
+        # Bring down/up internal router-1
+        verifyRouterFailure( main, "bgp1" )
+        # Bring down/up internal router-2
+        verifyRouterFailure( main, "bgp2" )
+        lib.cleanup( main, copyKarafLog=False, removeHostComponent=True )
+
+    def CASE663( self, main ):
+        """
+        External router failure without cross-link
+        - Drop the cross-link for both external routers. All external hosts should be reachable.
+        - Bring down quagga external router-1. Hosts that are behind router-2 should still be reachable. Hosts that are behind router-1 should not be reachable.
+        - Bring router up again, all external hosts are reachable again.
+        - Repeat this with external router-2.
+        """
+        from tests.USECASE.SegmentRouting.SRRouting.dependencies.SRRoutingTest import *
+        from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
+        main.case( "External router failure without cross-link" )
+        setupTest( main, test_idx=663, onosNodes=3, static=True )
+        main.externalIpv4Hosts += main.staticIpv4Hosts
+        main.externalIpv6Hosts += main.staticIpv6Hosts
+        verify( main, disconnected=False )
+        # Drop the cross-link
+        portsToDisable = [ [ "of:0000000000000004", 13 ], [ "of:0000000000000005", 14 ] ]
+        lib.disablePortBatch( main, portsToDisable, 10, 48 )
+        verify( main, disconnected=False, internal=False )
+        # Bring down/up external router-1
+        verifyRouterFailure( main, "r1", [ "rh5v4" ], [ "rh11v6", "rh5v6" ] )
+        # Bring down/up external router-2
+        verifyRouterFailure( main, "r2", [], [ "rh22v6" ] )
+        lib.cleanup( main, copyKarafLog=False, removeHostComponent=True )
+
+    def CASE664( self, main ):
+        """
+        External router link failure without cross-link
+        - Drop the cross-link for both external routers. All external hosts should be reachable.
+        - Drop an extra link for external router-1. Only hosts connected to router-2 should be reachable.
+        - Bring up single link for external router-1. All external hosts should be reachable.
+        - Repeat the two steps above with external router-2
+        """
+        from tests.USECASE.SegmentRouting.SRRouting.dependencies.SRRoutingTest import *
+        from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
+        main.case( "External router link failure without cross-link" )
+        setupTest( main, test_idx=664, onosNodes=3, static=True )
+        main.externalIpv4Hosts += main.staticIpv4Hosts
+        main.externalIpv6Hosts += main.staticIpv6Hosts
+        verify( main, disconnected=False )
+        # Drop the cross-link
+        portsToDisable = [ [ "of:0000000000000004", 13 ], [ "of:0000000000000005", 14 ] ]
+        lib.disablePortBatch( main, portsToDisable, 10, 48 )
+        verify( main, disconnected=False, internal=False )
+        # Bring down/up a non-cross-link for external router-1
+        portsToDisable = [ [ "of:0000000000000005", 13 ] ]
+        lib.disablePortBatch( main, portsToDisable, 10, 48 )
+        main.disconnectedExternalIpv4Hosts = [ 'rh5v4' ]
+        main.disconnectedExternalIpv6Hosts = [ "rh11v6", "rh5v6" ]
+        verify( main, internal=False )
+        lib.enablePortBatch( main, portsToDisable, 10, 48 )
+        main.disconnectedExternalIpv4Hosts = []
+        main.disconnectedExternalIpv6Hosts = []
+        verify( main, disconnected=False, internal=False )
+        # Bring down/up a non-cross-link for external router-2
+        portsToDisable = [ [ "of:0000000000000004", 14 ] ]
+        lib.disablePortBatch( main, portsToDisable, 10, 48 )
+        main.disconnectedExternalIpv6Hosts = [ "rh22v6" ]
+        verify( main, internal=False )
+        lib.enablePortBatch( main, portsToDisable, 10, 48 )
+        main.disconnectedExternalIpv6Hosts = []
+        verify( main, disconnected=False, internal=False )
+        lib.cleanup( main, copyKarafLog=False, removeHostComponent=True )
+
+    def CASE665( self, main ):
+        """
+        Internal router failure without cross-link
+        - Drop the cross-link for both external routers. All external hosts should be reachable.
+        - Bring down quagga internal router-1. Hosts that are behind router-2 should still be reachable. Hosts that are behind router-1 should not be reachable.
+        - Bring router up again, all external hosts are reachable again.
+        - Repeat this with internal router-2.
+        """
+        from tests.USECASE.SegmentRouting.SRRouting.dependencies.SRRoutingTest import *
+        from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
+        main.case( "Internal router failure without cross-link" )
+        setupTest( main, test_idx=665, onosNodes=3, static=True )
+        main.externalIpv4Hosts += main.staticIpv4Hosts
+        main.externalIpv6Hosts += main.staticIpv6Hosts
+        verify( main, disconnected=False )
+        # Drop the cross-link
+        portsToDisable = [ [ "of:0000000000000004", 13 ], [ "of:0000000000000005", 14 ] ]
+        lib.disablePortBatch( main, portsToDisable, 10, 48 )
+        verify( main, disconnected=False, internal=False )
+        # Bring down/up internal router-1
+        verifyRouterFailure( main, "bgp1", [], [ "rh22v6" ] )
+        # Bring down/up internal router-2
+        verifyRouterFailure( main, "bgp2", [ "rh5v4" ], [ "rh11v6", "rh5v6" ] )
+        lib.cleanup( main, copyKarafLog=False, removeHostComponent=True )
diff --git a/TestON/tests/USECASE/SegmentRouting/SRRouting/dependencies/SRRoutingTest.py b/TestON/tests/USECASE/SegmentRouting/SRRouting/dependencies/SRRoutingTest.py
index 0611abc..738b6b4 100644
--- a/TestON/tests/USECASE/SegmentRouting/SRRouting/dependencies/SRRoutingTest.py
+++ b/TestON/tests/USECASE/SegmentRouting/SRRouting/dependencies/SRRoutingTest.py
@@ -67,8 +67,10 @@
     if static:
         if ipv4:
             lib.addStaticOnosRoute( main, "10.0.88.0/24", "10.0.1.1")
+            lib.addStaticOnosRoute( main, "10.0.88.0/24", "10.0.5.1")
         if ipv6:
             lib.addStaticOnosRoute( main, "2000::8700/120", "2000::101")
+            lib.addStaticOnosRoute( main, "2000::8700/120", "2000::501")
     if countFlowsGroups:
         lib.loadCount( main )
 
@@ -248,3 +250,18 @@
         lib.checkFlowsGroupsFromFile( main )
     # ping hosts
     verifyPing( main, ipv4, ipv6, disconnected, internal, external )
+
+def verifyRouterFailure( main, routerToKill, affectedIpv4Hosts=[], affectedIpv6Hosts=[],
+                         ipv4=True, ipv6=True, countFlowsGroups=False ):
+    """
+    Kill and recover a quagga router and verify connectivities to external hosts
+    """
+    from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
+    lib.killRouter( main, routerToKill, 5 )
+    main.disconnectedExternalIpv4Hosts = affectedIpv4Hosts
+    main.disconnectedExternalIpv6Hosts = affectedIpv6Hosts
+    verify( main, ipv4, ipv6, True if (affectedIpv4Hosts or affectedIpv6Hosts) else False, False, True, countFlowsGroups )
+    lib.recoverRouter( main, routerToKill, 5 )
+    main.disconnectedExternalIpv4Hosts = []
+    main.disconnectedExternalIpv6Hosts = []
+    verify( main, ipv4, ipv6, False, False, True, countFlowsGroups )