[WIP] Added test 604/605 for routing tests.

Further added functionality for re-discovering hosts after a
switch failure.

Change-Id: I266918bb7286328af52ac90c9588b5c2078c2009
diff --git a/TestON/drivers/common/cli/emulator/mininetclidriver.py b/TestON/drivers/common/cli/emulator/mininetclidriver.py
index 3f7e6dd..54d9747 100644
--- a/TestON/drivers/common/cli/emulator/mininetclidriver.py
+++ b/TestON/drivers/common/cli/emulator/mininetclidriver.py
@@ -571,6 +571,75 @@
             main.cleanAndExit()
         except Exception:
             main.log.exception( self.name + ": Uncaught exception!" )
+
+            main.cleanAndExit()
+
+    def discoverIpv4Hosts( self, hostList, wait=1 , dstIp="6.6.6.6"):
+        '''
+        Can only be used if hosts already have ipv4 addresses.
+
+        Hosts in hostList will do a single ping to a non-existent (dstIp) address for ONOS
+        to discover them again.
+        '''
+        try:
+            main.log.info( "Issuing dumb pings for ipv6 hosts to be discovered" )
+            cmd = " ping -c 1 -i 1 -W " + str( wait ) + " "
+            for host in hostList:
+                pingCmd = str( host ) + cmd + dstIp
+                self.handle.sendline( pingCmd )
+                self.handle.expect( "mininet>", timeout=wait + 1 )
+
+        except pexpect.TIMEOUT:
+            main.log.exception( self.name + ": TIMEOUT exception" )
+            response = self.handle.before
+            # NOTE: Send ctrl-c to make sure command is stopped
+            self.handle.send( "\x03" )
+            self.handle.expect( "Interrupt" )
+            response += self.handle.before + self.handle.after
+            self.handle.expect( "mininet>" )
+            response += self.handle.before + self.handle.after
+            main.log.debug( response )
+            return main.FALSE
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":     " + self.handle.before )
+            main.cleanAndExit()
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanAndExit()
+
+    def discoverIpv6Hosts( self, hostList, wait=1, dstIp="1020::3fe" ):
+        '''
+        Can only be used if hosts already have ipv6 addresses.
+
+        Hosts in hostList will do a single ping to a non-existent address (dstIp) for ONOS
+        to discover them again.
+        '''
+        try:
+            main.log.info( "Issuing dump pings for ipv6 hosts to be discovered" )
+            cmd = " ping6 -c 1 -i 1 -W " + str( wait ) + " "
+            for host in hostList:
+                pingCmd = str( host ) + cmd + dstIp
+                self.handle.sendline( pingCmd )
+                self.handle.expect( "mininet>", timeout=wait + 1 )
+
+        except pexpect.TIMEOUT:
+            main.log.exception( self.name + ": TIMEOUT exception" )
+            response = self.handle.before
+            # NOTE: Send ctrl-c to make sure command is stopped
+            self.handle.send( "\x03" )
+            self.handle.expect( "Interrupt" )
+            response += self.handle.before + self.handle.after
+            self.handle.expect( "mininet>" )
+            response += self.handle.before + self.handle.after
+            main.log.debug( response )
+            return main.FALSE
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":     " + self.handle.before )
+            main.cleanAndExit()
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanAndExit()
 
     def pingallHostsUnidirectional( self, srcList, dstList, ipv6=False, wait=1, acceptableFailed=0 ):
diff --git a/TestON/tests/USECASE/SegmentRouting/SRRouting/SRRouting.py b/TestON/tests/USECASE/SegmentRouting/SRRouting/SRRouting.py
index de05514..66f2145 100644
--- a/TestON/tests/USECASE/SegmentRouting/SRRouting/SRRouting.py
+++ b/TestON/tests/USECASE/SegmentRouting/SRRouting/SRRouting.py
@@ -468,6 +468,76 @@
         verifyOnosFailure( main, internal=False )
         lib.cleanup( main, copyKarafLog=False, removeHostComponent=True )
 
+    def CASE603( self, main ):
+        """"
+        Drop HAGG-1 device and test connectivity.
+        Drop DAAS-1 device and test connectivity (some hosts lost it)
+        Bring up DAAS-1 and test connectivity (all hosts gained it again)
+
+        Repeat the same with HAGG-2 and DAAS-2.
+        """
+        import time
+        from tests.USECASE.SegmentRouting.SRRouting.dependencies.SRRoutingTest import *
+        from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
+        main.case( "Drop hagg spine switch along with dass leaf switch." )
+        setupTest( main, test_idx=603, onosNodes=3 )
+        main.disconnectedIpv4Hosts = []
+        main.disconnectedIpv6Hosts = []
+
+        verify( main )
+        lib.killSwitch( main, "spine103", int( main.params[ "TOPO" ]["switchNum" ] ) - 1, int( main.params[ "TOPO" ][ "linkNum" ] ) - 6 )
+        verify( main )
+        lib.killSwitch( main, "leaf6", int( main.params[ "TOPO" ]["switchNum" ] ) - 2, int( main.params[ "TOPO" ][ "linkNum" ] ) - 8 )
+        main.disconnectedIpv4Hosts = [ 'h12v4', 'h13v4']
+        main.disconnectedIpv6Hosts = [ 'h12v6', 'h13v6']
+        verify( main )
+        lib.recoverSwitch( main, "leaf6", int( main.params[ "TOPO" ]["switchNum" ] ) - 1, int( main.params[ "TOPO" ][ "linkNum" ] ) - 6, rediscoverHosts=True)
+        main.disconnectedIpv4Hosts = []
+        main.disconnectedIpv6Hosts = []
+        verify( main )
+        lib.recoverSwitch( main, "spine103", int( main.params[ "TOPO" ][ "switchNum" ] ), int( main.params[ "TOPO" ][ "linkNum" ] ))
+        verify( main )
+
+        lib.killSwitch( main, "spine104", int( main.params[ "TOPO" ]["switchNum" ] ) - 1, int( main.params[ "TOPO" ][ "linkNum" ] ) - 6 )
+        verify( main )
+        lib.killSwitch( main, "leaf1", int( main.params[ "TOPO" ]["switchNum" ] ) - 2, int( main.params[ "TOPO" ][ "linkNum" ] ) - 8 )
+        main.disconnectedIpv4Hosts = [ 'h1v4', 'h2v4']
+        main.disconnectedIpv6Hosts = [ 'h1v6', 'h2v6']
+        verify( main )
+        lib.recoverSwitch( main, "leaf1", int( main.params[ "TOPO" ]["switchNum" ] ) - 1, int( main.params[ "TOPO" ][ "linkNum" ] ) - 6, rediscoverHosts=True)
+        main.disconnectedIpv4Hosts = []
+        main.disconnectedIpv6Hosts = []
+        verify( main )
+        lib.recoverSwitch( main, "spine104", int( main.params[ "TOPO" ][ "switchNum" ] ), int( main.params[ "TOPO" ][ "linkNum" ] ))
+        verify( main )
+
+        lib.cleanup( main, copyKarafLog=False, removeHostComponent=True )
+
+    def CASE604( self, main ):
+        """"
+        Drop HAGG-1 device and test connectivity.
+        Bring up HAGG-1 and test connectivity.
+        Drop HAGG-2 device and test connectivity.
+        Bring up HAGG-2 device and test connectivity
+        """
+        import time
+        from tests.USECASE.SegmentRouting.SRRouting.dependencies.SRRoutingTest import *
+        from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as lib
+        main.case( "Drop hagg spine switches." )
+        setupTest( main, test_idx=604, onosNodes=3 )
+        main.disconnectedIpv4Hosts = []
+        main.disconnectedIpv6Hosts = []
+        verify( main )
+        lib.killSwitch( main, "spine103", int( main.params[ "TOPO" ]["switchNum" ] ) - 1, int( main.params[ "TOPO" ][ "linkNum" ] ) - 6 )
+        verify( main )
+        lib.recoverSwitch( main, "spine103", int( main.params[ "TOPO" ][ "switchNum" ] ), int( main.params[ "TOPO" ][ "linkNum" ] ))
+        verify( main )
+        lib.killSwitch( main, "spine104", int( main.params[ "TOPO" ]["switchNum" ] ) - 1, int( main.params[ "TOPO" ][ "linkNum" ] ) - 6 )
+        verify( main )
+        lib.recoverSwitch( main, "spine104", int( main.params[ "TOPO" ][ "switchNum" ] ), int( main.params[ "TOPO" ][ "linkNum" ] ))
+        verify( main )
+        lib.cleanup( main, copyKarafLog=False, removeHostComponent=True )
+
     def CASE606( self, main ):
         """
         Drop SPINE-1 and test connectivity
diff --git a/TestON/tests/USECASE/SegmentRouting/SRRouting/dependencies/conf/zebradbgp1.conf b/TestON/tests/USECASE/SegmentRouting/SRRouting/dependencies/conf/zebradbgp1.conf
index d3dac23..d4f09ea 100644
--- a/TestON/tests/USECASE/SegmentRouting/SRRouting/dependencies/conf/zebradbgp1.conf
+++ b/TestON/tests/USECASE/SegmentRouting/SRRouting/dependencies/conf/zebradbgp1.conf
@@ -6,4 +6,4 @@
 !
 ip route 0.0.0.0/0 172.16.0.1
 !
-fpm connection ip 10.192.19.41 port 2620
+fpm connection ip 10.128.100.67 port 2620
diff --git a/TestON/tests/USECASE/SegmentRouting/SRRouting/dependencies/conf/zebradbgp2.conf b/TestON/tests/USECASE/SegmentRouting/SRRouting/dependencies/conf/zebradbgp2.conf
index 147bcbc..95e97fd 100644
--- a/TestON/tests/USECASE/SegmentRouting/SRRouting/dependencies/conf/zebradbgp2.conf
+++ b/TestON/tests/USECASE/SegmentRouting/SRRouting/dependencies/conf/zebradbgp2.conf
@@ -6,4 +6,4 @@
 !
 ip route 0.0.0.0/0 172.16.0.1
 !
-fpm connection ip 10.192.19.41 port 2620
+fpm connection ip 10.128.100.69 port 2620
diff --git a/TestON/tests/USECASE/SegmentRouting/dependencies/Testcaselib.py b/TestON/tests/USECASE/SegmentRouting/dependencies/Testcaselib.py
index 298eb35..44055d3 100644
--- a/TestON/tests/USECASE/SegmentRouting/dependencies/Testcaselib.py
+++ b/TestON/tests/USECASE/SegmentRouting/dependencies/Testcaselib.py
@@ -650,7 +650,7 @@
                                  onfail="Failed to kill switch?" )
 
     @staticmethod
-    def recoverSwitch( main, switch, switches, links ):
+    def recoverSwitch( main, switch, switches, links, rediscoverHosts=False ):
         """
         Params: switches, links: number of expected switches and links after SwitchUp, ex.: '4', '6'
         Recover a switch and verify ONOS can see the proper change
@@ -664,6 +664,13 @@
         main.log.info( "Waiting %s seconds for switch up to be discovered" % (
             main.switchSleep ) )
         time.sleep( main.switchSleep )
+        if rediscoverHosts:
+            main.Network.discoverIpv4Hosts( main.internalIpv4Hosts )
+            main.Network.discoverIpv6Hosts( main.internalIpv6Hosts )
+            main.log.info( "Waiting %s seconds for hosts to get re-discovered" % (
+                           main.switchSleep ) )
+            time.sleep( main.switchSleep )
+
         topology = utilities.retry( main.Cluster.active( 0 ).CLI.checkStatus,
                                     main.FALSE,
                                     kwargs={ 'numoswitch': switches,