Implement moveDualHomedHost for SR tests
Change-Id: I90631f69aab0a6c294c1167703872dc4baf75066
diff --git a/TestON/drivers/common/cli/emulator/mininetclidriver.py b/TestON/drivers/common/cli/emulator/mininetclidriver.py
index 0cea933..9c2f2e8 100644
--- a/TestON/drivers/common/cli/emulator/mininetclidriver.py
+++ b/TestON/drivers/common/cli/emulator/mininetclidriver.py
@@ -4049,6 +4049,91 @@
main.log.warn( "Interface status should be up or down!" )
return main.FALSE
+ def moveDualHomedHost( self, host, oldSw, oldPairSw, newSw, newPairSw,
+ macAddr=None, prefixLen=None, bondedName='bond1' ):
+ """
+ Moves a dual-homed host from one switch-pair to another pair on the fly
+ If macAddr is specified, change MAC address of the bonded host interface
+ to specified MAC address.
+ Assumes that the host has two interfaces (eth0 and eth1) originally.
+ """
+
+ bond1 = "%s-%s" % ( host, bondedName )
+ newIntf = host + '-eth2'
+ newIntfPair = host + '-eth3'
+ commands = [
+ # Bring link between oldSw-host down
+ "py net.configLinkStatus('" + oldSw + "'," + "'" + host + "'," + "'down')",
+ # Bring link between oldPairSw-host down
+ "py net.configLinkStatus('" + oldPairSw + "'," + "'" + host + "'," + "'down')",
+ # Determine hostintf and Oldswitchintf
+ "px hintf,sintf = " + host + ".connectionsTo(" + oldSw + ")[0]",
+ # Determine ip and mac address of the host-oldSw interface
+ "px ipaddr = hintf.IP()",
+ "px macaddr = hintf.MAC()" if macAddr is None else 'px macaddr = "%s"' % macAddr,
+ # Detach interface between oldSw-host
+ "px " + oldSw + ".detach( sintf )",
+ # Determine hostintf and Oldpairswitchintf
+ "px sintfpair,hintfpair = " + oldPairSw + ".connectionsTo(" + host + ")[0]",
+ # Detach interface between oldPairSw-host
+ "px " + oldPairSw + ".detach( sintfpair )",
+ # Add link between host-newSw
+ "py net.addLink(" + host + "," + newSw + ", 2)",
+ # Add link between host-newPairSw
+ "py net.addLink(" + host + "," + newPairSw + ")",
+ # Determine hostintf and Newswitchintf
+ "px hintf,sintf = " + host + ".connectionsTo(" + newSw + ")[-1]",
+ # Determine hostintf and NewPairswitchintf
+ "px hintfpair,sintfpair = " + host + ".connectionsTo(" + newPairSw + ")[-1]",
+ # Attach interface between newSw-host
+ "px " + newSw + ".attach( sintf )",
+ # Attach interface between newPairSw-host
+ "px " + newPairSw + ".attach( sintfpair )",
+ # Bond two interfaces
+ host + ' ip link add %s type bond' % bond1,
+ host + ' ip link set %s down' % newIntf,
+ host + ' ip link set %s down' % newIntfPair,
+ host + ' ip link set %s master %s' % ( newIntf, bond1 ),
+ host + ' ip link set %s master %s' % ( newIntfPair, bond1 ),
+ host + ' ip addr flush dev %s' % newIntf,
+ host + ' ip addr flush dev %s' % newIntfPair,
+ host + ' ip link set %s up' % bond1,
+ "px lowestIntf = min( [ hintf, hintfpair ] )",
+ "px highestIntf = max( [ hintf, hintfpair ] )",
+ "px lowestIntf.name = '" + bond1 + "'",
+ "px " + host + ".nameToIntf['" + bond1 + "'] = lowestIntf",
+ "px del " + host + ".intfs[ " + host + ".ports[ highestIntf ] ]",
+ "px del " + host + ".ports[ highestIntf ]",
+ # Set ipaddress of the host-newSw interface
+ "px " + host + ".setIP( ip = ipaddr, intf = lowestIntf " +
+ ( ", prefixLen = %s )" % str( prefixLen ) if prefixLen is not None else " )" ),
+ # Set macaddress of the host-newSw interface
+ "px " + host + ".setMAC( mac = macaddr, intf = lowestIntf)",
+ "net",
+ # Determine ipaddress of the bonded host interface
+ host + " ifconfig",
+ ]
+
+ if self.handle:
+ try:
+ for cmd in commands:
+ print "cmd= ", cmd
+ self.handle.sendline( cmd )
+ self.handle.expect( "mininet>" )
+ main.log.info( "====> %s ", self.handle.before )
+ return main.TRUE
+
+ except pexpect.TIMEOUT:
+ main.log.error( self.name + ": TIMEOUT exception found" )
+ main.log.error( self.name + ": " + self.handle.before )
+ main.cleanAndExit()
+ except pexpect.EOF:
+ main.log.error( self.name + ": EOF exception found" )
+ main.log.error( self.name + ": " + self.handle.before )
+ return main.FALSE
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
+ return main.FALSE
if __name__ != "__main__":
sys.modules[ __name__ ] = MininetCliDriver()
diff --git a/TestON/tests/USECASE/SegmentRouting/dependencies/Testcaselib.py b/TestON/tests/USECASE/SegmentRouting/dependencies/Testcaselib.py
index c3c5dbc..e9bb8fe 100644
--- a/TestON/tests/USECASE/SegmentRouting/dependencies/Testcaselib.py
+++ b/TestON/tests/USECASE/SegmentRouting/dependencies/Testcaselib.py
@@ -1277,3 +1277,53 @@
del main.expectedHosts[ "onos" ][ hostName ]
main.expectedHosts[ "onos" ][ "{}/{}".format( macAddr, vlan ) ] = ip
break
+
+ @staticmethod
+ def moveDualHomedHost( main, hostName, srcSw, srcPairSw, dstSw, dstPairSw, gw,
+ macAddr=None, prefixLen=24, cfg='', ipv6=False ):
+ """
+ Move specified dual-homed host from srcSw-srcPairSw to dstSw-dstPairSw.
+ If srcSw-srcPairSw and dstSw-dstPairSw are same, the host will be moved from current port
+ to next available port.
+ Required:
+ hostName: name of the host. e.g., "h1"
+ srcSw: name of the switch that the host is attached to. e.g., "leaf1"
+ srcPairSw: name of the paired-switch that the host is attached to. e.g., "leaf2"
+ dstSw: name of the switch that the host will be moved to. e.g., "leaf1"
+ dstPairSw: name of the paired-switch that the host will be moved to. e.g., "leaf2"
+ gw: ip address of the gateway of the new location
+ Optional:
+ macAddr: if specified, change MAC address of the host to the specified MAC address.
+ prefixLen: prefix length
+ cfg: port configurations as JSON string
+ ipv6: Use True to move IPv6 host (IPv6 is not supported now.)
+ """
+ # TODO: support IPv6 hosts and vlan-tagged hosts.
+ if not hasattr( main, 'Mininet1' ):
+ main.log.warn( "moveDualHomedHost is supposed to be used only in Mininet." )
+ return
+
+ if ipv6:
+ main.log.warn( "Moving IPv6 host is not implemented yet." )
+ return
+
+ main.Mininet1.moveDualHomedHost( hostName, srcSw, srcPairSw, dstSw, dstPairSw,
+ macAddr=macAddr, prefixLen=prefixLen )
+
+ main.Mininet1.changeDefaultGateway( hostName, gw )
+
+ if cfg:
+ main.Cluster.active( 0 ).REST.setNetCfg( json.loads( cfg ),
+ subjectClass="ports" )
+
+ main.Mininet1.discoverHosts( [ hostName, ] )
+
+ # Update expectedHost when MAC address is changed.
+ if macAddr is not None:
+ ipAddr = main.expectedHosts[ "network" ][ hostName ]
+ if ipAddr is not None:
+ for hostName, ip in main.expectedHosts[ "onos" ].items():
+ if ip == ipAddr:
+ vlan = hostName.split( "/" )[ -1 ]
+ del main.expectedHosts[ "onos" ][ hostName ]
+ main.expectedHosts[ "onos" ][ "{}/{}".format( macAddr, vlan ) ] = ip