Merge "Initial commit of basic IPv6 coverage in CHOtest"
diff --git a/TestON/drivers/common/cli/onosclidriver.py b/TestON/drivers/common/cli/onosclidriver.py
index e8e5d64..b33a5a9 100644
--- a/TestON/drivers/common/cli/onosclidriver.py
+++ b/TestON/drivers/common/cli/onosclidriver.py
@@ -1761,6 +1761,32 @@
             main.cleanup()
             main.exit()
 
+    def ipv4RouteNumber( self ):
+        """
+        NOTE: This method should be used after installing application:
+              onos-app-sdnip
+        Description:
+            Obtain the total IPv4 routes number in the system
+        """
+        try:
+            cmdStr = "routes -s -j"
+            handle = self.sendline( cmdStr )
+            jsonResult = json.loads( handle )
+            return jsonResult['totalRoutes4']
+
+        except TypeError:
+            main.log.exception( self.name + ": Object not as expected" )
+            return None
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":    " + self.handle.before )
+            main.cleanup()
+            main.exit()
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
     def intents( self, jsonFormat=True ):
         """
         Optional:
@@ -1787,6 +1813,31 @@
             main.cleanup()
             main.exit()
 
+    def m2SIntentInstalledNumber( self ):
+        """
+        Description:
+            Obtain the number of multiple point to single point intents
+            installed
+        """
+        try:
+            cmdStr = "intents -s -j"
+            handle = self.sendline( cmdStr )
+            jsonResult = json.loads( handle )
+            return jsonResult['multiPointToSinglePoint']['installed']
+
+        except TypeError:
+            main.log.exception( self.name + ": Object not as expected" )
+            return None
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":    " + self.handle.before )
+            main.cleanup()
+            main.exit()
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
     def getIntentState(self, intentsId, intentsJson=None):
         """
             Check intent state.
diff --git a/TestON/tests/FUNCintentRest/Dependency/FuncIntentFunction.py b/TestON/tests/FUNCintentRest/Dependency/FuncIntentFunction.py
index 6bbbb84..9ce16fe 100644
--- a/TestON/tests/FUNCintentRest/Dependency/FuncIntentFunction.py
+++ b/TestON/tests/FUNCintentRest/Dependency/FuncIntentFunction.py
@@ -6,6 +6,7 @@
 import time
 import copy
 import json
+import types
 
 def __init__( self ):
     self.default = ''
@@ -125,9 +126,9 @@
     intent1 = main.CLIs[ onosNode ].addHostIntent( hostIdOne=h1Id,
                                                    hostIdTwo=h2Id )
 
-    time.sleep( main.hostIntentSleep )
+    # Get all intents ID in the system, time delay right after intents are added
+    time.sleep( main.addIntentSleep )
     intentsId = main.CLIs[ 0 ].getIntentsId()
-    print intentsId
 
     # Check intents state
     time.sleep( main.checkIntentSleep )
@@ -332,8 +333,10 @@
                                                     ipDst=ip1,
                                                     tcpSrc=tcp2,
                                                     tcpDst=tcp1 )
+
+    # Get all intents ID in the system, time delay right after intents are added
+    time.sleep( main.addIntentSleep )
     intentsId = main.CLIs[ 0 ].getIntentsId()
-    print intentsId
 
     # Check intents state
     time.sleep( main.checkIntentSleep )
@@ -415,6 +418,242 @@
 
     return stepResult
 
+def pointIntentTcp( main,
+                    name,
+                    host1,
+                    host2,
+                    onosNode=0,
+                    deviceId1="",
+                    deviceId2="",
+                    port1="",
+                    port2="",
+                    ethType="",
+                    mac1="",
+                    mac2="",
+                    bandwidth="",
+                    lambdaAlloc=False,
+                    ipProto="",
+                    ip1="",
+                    ip2="",
+                    tcp1="",
+                    tcp2="",
+                    sw1="",
+                    sw2="",
+                    expectedLink=0 ):
+
+    """
+    Description:
+        Verify add-point-intent only for TCP
+    Steps:
+        - Get device ids | ports
+        - Add point intents
+        - Check intents
+        - Verify flows
+        - Ping hosts
+        - Reroute
+            - Link down
+            - Verify flows
+            - Check topology
+            - Ping hosts
+            - Link up
+            - Verify flows
+            - Check topology
+            - Ping hosts
+        - Remove intents
+    Required:
+        name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
+        host1 - Name of first host
+        host2 - Name of second host
+    Optional:
+        onosNode - ONOS node to install the intents in main.CLIs[ ]
+                   0 by default so that it will always use the first
+                   ONOS node
+        deviceId1 - ONOS device id of the first switch, the same as the
+                    location of the first host eg. of:0000000000000001/1,
+                    located at device 1 port 1
+        deviceId2 - ONOS device id of the second switch
+        port1 - The port number where the first host is attached
+        port2 - The port number where the second host is attached
+        ethType - Ethernet type eg. IPV4, IPV6
+        mac1 - Mac address of first host
+        mac2 - Mac address of the second host
+        bandwidth - Bandwidth capacity
+        lambdaAlloc - Allocate lambda, defaults to False
+        ipProto - IP protocol
+        ip1 - IP address of first host
+        ip2 - IP address of second host
+        tcp1 - TCP port of first host
+        tcp2 - TCP port of second host
+        sw1 - First switch to bring down & up for rerouting purpose
+        sw2 - Second switch to bring down & up for rerouting purpose
+        expectedLink - Expected link when the switches are down, it should
+                       be two links lower than the links before the two
+                       switches are down
+    """
+
+    assert main, "There is no main variable"
+    assert name, "variable name is empty"
+    assert host1 and host2, "You must specify hosts"
+
+    global itemName
+    itemName = name
+    host1 = host1
+    host2 = host2
+    hostNames = [ host1, host2 ]
+    intentsId = []
+
+    iperfResult = main.TRUE
+    intentResult = main.TRUE
+    removeIntentResult = main.TRUE
+    flowResult = main.TRUE
+    topoResult = main.TRUE
+    linkDownResult = main.TRUE
+    linkUpResult = main.TRUE
+    onosNode = int( onosNode )
+
+    # Adding bidirectional point  intents
+    main.log.info( itemName + ": Adding point intents" )
+    intent1 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId1,
+                                                    egressDevice=deviceId2,
+                                                    ingressPort=port1,
+                                                    egressPort=port2,
+                                                    ethType=ethType,
+                                                    ethSrc=mac1,
+                                                    ethDst=mac2,
+                                                    bandwidth=bandwidth,
+                                                    lambdaAlloc=lambdaAlloc,
+                                                    ipProto=ipProto,
+                                                    ipSrc=ip1,
+                                                    ipDst=ip2,
+                                                    tcpSrc=tcp1,
+                                                    tcpDst="" )
+
+    intent2 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId2,
+                                                    egressDevice=deviceId1,
+                                                    ingressPort=port2,
+                                                    egressPort=port1,
+                                                    ethType=ethType,
+                                                    ethSrc=mac2,
+                                                    ethDst=mac1,
+                                                    bandwidth=bandwidth,
+                                                    lambdaAlloc=lambdaAlloc,
+                                                    ipProto=ipProto,
+                                                    ipSrc=ip2,
+                                                    ipDst=ip1,
+                                                    tcpSrc=tcp2,
+                                                    tcpDst="" )
+
+    intent3 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId1,
+                                                    egressDevice=deviceId2,
+                                                    ingressPort=port1,
+                                                    egressPort=port2,
+                                                    ethType=ethType,
+                                                    ethSrc=mac1,
+                                                    ethDst=mac2,
+                                                    bandwidth=bandwidth,
+                                                    lambdaAlloc=lambdaAlloc,
+                                                    ipProto=ipProto,
+                                                    ipSrc=ip1,
+                                                    ipDst=ip2,
+                                                    tcpSrc="",
+                                                    tcpDst=tcp2 )
+
+    intent4 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId2,
+                                                    egressDevice=deviceId1,
+                                                    ingressPort=port2,
+                                                    egressPort=port1,
+                                                    ethType=ethType,
+                                                    ethSrc=mac2,
+                                                    ethDst=mac1,
+                                                    bandwidth=bandwidth,
+                                                    lambdaAlloc=lambdaAlloc,
+                                                    ipProto=ipProto,
+                                                    ipSrc=ip2,
+                                                    ipDst=ip1,
+                                                    tcpSrc="",
+                                                    tcpDst=tcp1 )
+
+    # Get all intents ID in the system, time delay right after intents are added
+    time.sleep( main.addIntentSleep )
+    intentsId = main.CLIs[ 0 ].getIntentsId()
+    # Check intents state
+    time.sleep( main.checkIntentSleep )
+    intentResult = checkIntentState( main, intentsId )
+    # Check flows count in each node
+    checkFlowsCount( main )
+
+    # Check intents state again if first check fails...
+    if not intentResult:
+        intentResult = checkIntentState( main, intentsId )
+
+    # Check flows count in each node
+    checkFlowsCount( main )
+
+    # Verify flows
+    checkFlowsState( main )
+
+    # Run iperf to both host
+    iperfResult = iperfResult and main.Mininet1.iperftcp( host1,
+                                                          host2, 10 )
+
+    # Test rerouting if these variables exist
+    if sw1 and sw2 and expectedLink:
+        # link down
+        linkDownResult = link( main, sw1, sw2, "down" )
+        intentResult = intentResult and checkIntentState( main, intentsId )
+
+        # Check flows count in each node
+        checkFlowsCount( main )
+        # Verify flows
+        checkFlowsState( main )
+
+        # Check OnosTopology
+        topoResult = checkTopology( main, expectedLink )
+
+        # Run iperf to both host
+        iperfResult = iperfResult and main.Mininet1.iperftcp( host1,
+                                                              host2, 10 )
+
+        intentResult = checkIntentState( main, intentsId )
+
+        # Checks ONOS state in link down
+        if linkDownResult and topoResult and iperfResult and intentResult:
+            main.log.info( itemName + ": Successfully brought link down" )
+        else:
+            main.log.error( itemName + ": Failed to bring link down" )
+
+        # link up
+        linkUpResult = link( main, sw1, sw2, "up" )
+        time.sleep( main.rerouteSleep )
+
+        # Check flows count in each node
+        checkFlowsCount( main )
+        # Verify flows
+        checkFlowsState( main )
+
+        # Check OnosTopology
+        topoResult = checkTopology( main, main.numLinks )
+
+        # Run iperf to both host
+        iperfResult = iperfResult and main.Mininet1.iperftcp( host1,
+                                                              host2, 10 )
+
+        intentResult = checkIntentState( main, intentsId )
+
+        # Checks ONOS state in link up
+        if linkUpResult and topoResult and iperfResult and intentResult:
+            main.log.info( itemName + ": Successfully brought link back up" )
+        else:
+            main.log.error( itemName + ": Failed to bring link back up" )
+
+    # Remove all intents
+    removeIntentResult = removeAllIntents( main )
+
+    stepResult = iperfResult and linkDownResult and linkUpResult \
+                 and intentResult and removeIntentResult
+
+    return stepResult
+
 def singleToMultiIntent( main,
                          name,
                          hostNames,
@@ -901,14 +1140,14 @@
 
     return stepResult
 
-def pingallHosts( main, hostList, pingType="ipv4" ):
+def pingallHosts( main, hostList ):
     # Ping all host in the hosts list variable
     print "Pinging : ", hostList
     pingResult = main.TRUE
-    pingResult = main.Mininet1.pingallHosts( hostList, pingType )
+    pingResult = main.Mininet1.pingallHosts( hostList )
     return pingResult
 
-def getHostsData( main ):
+def getHostsData( main, hostList ):
     """
         Use fwd app and pingall to discover all the hosts
     """
@@ -921,7 +1160,12 @@
     if not activateResult:
         main.log.error( "Something went wrong installing fwd app" )
     time.sleep( main.fwdSleep )
-    pingResult = main.Mininet1.pingall( timeout = 600 )
+    if isinstance( hostList[ 0 ], types.StringType ):
+        main.Mininet1.pingallHosts( hostList )
+    elif isinstance( hostList[ 0 ], types.ListType ):
+        for i in xrange( len( hostList ) ):
+            main.Mininet1.pingallHosts( hostList[ i ] )
+
     hostsJson = json.loads( main.CLIs[ 0 ].hosts() )
     hosts = main.Mininet1.getHosts().keys()
     # TODO: Make better use of new getHosts function
diff --git a/TestON/tests/FUNCintentRest/FUNCintentRest.params b/TestON/tests/FUNCintentRest/FUNCintentRest.params
index edb8c85..4158f33 100644
--- a/TestON/tests/FUNCintentRest/FUNCintentRest.params
+++ b/TestON/tests/FUNCintentRest/FUNCintentRest.params
@@ -39,7 +39,7 @@
         <reroute>5</reroute>
         <checkintent>5</checkintent>
         <fwd>5</fwd>
-        <hostintent>3</hostintent>
+        <addIntent>3</addIntent>
     </SLEEP>
 
     <MININET>
diff --git a/TestON/tests/FUNCintentRest/FUNCintentRest.py b/TestON/tests/FUNCintentRest/FUNCintentRest.py
index ef204e9..0bc5c3c 100644
--- a/TestON/tests/FUNCintentRest/FUNCintentRest.py
+++ b/TestON/tests/FUNCintentRest/FUNCintentRest.py
@@ -52,7 +52,7 @@
                     [ 'checkintent' ] )
             main.rerouteSleep = int( main.params[ 'SLEEP' ][ 'reroute' ] )
             main.fwdSleep = int( main.params[ 'SLEEP' ][ 'fwd' ] )
-            main.hostIntentSleep = int( main.params[ 'SLEEP' ][ 'hostintent' ] )
+            main.addIntentSleep = int( main.params[ 'SLEEP' ][ 'addIntent' ] )
             gitPull = main.params[ 'GIT' ][ 'pull' ]
             main.numSwitch = int( main.params[ 'MININET' ][ 'switch' ] )
             main.numLinks = int( main.params[ 'MININET' ][ 'links' ] )
@@ -411,8 +411,22 @@
         main.case( "Discover all hosts" )
 
         stepResult = main.TRUE
-        main.step( "Discover all hosts using pingall " )
-        stepResult = main.intentFunction.getHostsData( main )
+        main.step( "Discover all ipv4 host hosts " )
+        hostList = []
+        # List of host with default vlan
+        defaultHosts = [ "h1", "h3", "h8", "h9", "h11", "h16", "h17", "h19", "h24" ]
+        # Lists of host with unique vlan
+        vlanHosts1 = [ "h4", "h12", "h20" ]
+        vlanHosts2 = [ "h5", "h13", "h21" ]
+        vlanHosts3 = [ "h6", "h14", "h22" ]
+        vlanHosts4 = [ "h7", "h15", "h23" ]
+        hostList.append( defaultHosts )
+        hostList.append( vlanHosts1 )
+        hostList.append( vlanHosts2 )
+        hostList.append( vlanHosts3 )
+        hostList.append( vlanHosts4 )
+
+        stepResult = main.intentFunction.getHostsData( main, hostList )
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
                                  onpass="Successfully discovered hosts",
@@ -716,13 +730,13 @@
                                         "failed using IPV4 type with " +
                                         "no MAC addresses" )
 
-        main.step( "SDNIP-TCP: Add point intents between h1 and h9" )
+        main.step( "SDNIP-ICMP: Add point intents between h1 and h9" )
         stepResult = main.TRUE
         mac1 = main.hostsData[ 'h1' ][ 'mac' ]
         mac2 = main.hostsData[ 'h9' ][ 'mac' ]
         try:
-            ip1 = str( main.hostsData[ 'h1' ][ 'ipAddresses' ][ 0 ] ) + "/24"
-            ip2 = str( main.hostsData[ 'h9' ][ 'ipAddresses' ][ 0 ] ) + "/24"
+            ip1 = str( main.hostsData[ 'h1' ][ 'ipAddresses' ][ 0 ] ) + "/32"
+            ip2 = str( main.hostsData[ 'h9' ][ 'ipAddresses' ][ 0 ] ) + "/32"
         except KeyError:
             main.log.debug( "Key Error getting IP addresses of h1 | h9 in" +
                             "main.hostsData" )
@@ -736,7 +750,7 @@
 
         stepResult = main.intentFunction.pointIntent(
                                            main,
-                                           name="SDNIP-TCP",
+                                           name="SDNIP-ICMP",
                                            host1="h1",
                                            host2="h9",
                                            deviceId1="of:0000000000000005/1",
@@ -750,26 +764,26 @@
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
-                                 onpass="SDNIP-TCP: Point intent test " +
+                                 onpass="SDNIP-ICMP: Point intent test " +
                                         "successful using IPV4 type with " +
                                         "IP protocol TCP enabled",
-                                 onfail="SDNIP-TCP: Point intent test " +
+                                 onfail="SDNIP-ICMP: Point intent test " +
                                         "failed using IPV4 type with " +
                                         "IP protocol TCP enabled" )
 
-        main.step( "SDNIP-ICMP: Add point intents between h1 and h9" )
+        main.step( "SDNIP-TCP: Add point intents between h1 and h9" )
         stepResult = main.TRUE
         mac1 = main.hostsData[ 'h1' ][ 'mac' ]
         mac2 = main.hostsData[ 'h9' ][ 'mac' ]
-        ip1 = str( main.hostsData[ 'h1' ][ 'ipAddresses' ][ 0 ] ) + "/24"
-        ip2 = str( main.hostsData[ 'h9' ][ 'ipAddresses' ][ 0 ] ) + "/24"
+        ip1 = str( main.hostsData[ 'h1' ][ 'ipAddresses' ][ 0 ] ) + "/32"
+        ip2 = str( main.hostsData[ 'h9' ][ 'ipAddresses' ][ 0 ] ) + "/32"
         ipProto = main.params[ 'SDNIP' ][ 'tcpProto' ]
         tcp1 = main.params[ 'SDNIP' ][ 'srcPort' ]
         tcp2 = main.params[ 'SDNIP' ][ 'dstPort' ]
 
-        stepResult = main.intentFunction.pointIntent(
+        stepResult = main.intentFunction.pointIntentTcp(
                                            main,
-                                           name="SDNIP-ICMP",
+                                           name="SDNIP-TCP",
                                            host1="h1",
                                            host2="h9",
                                            deviceId1="of:0000000000000005/1",
@@ -777,16 +791,20 @@
                                            mac1=mac1,
                                            mac2=mac2,
                                            ethType="IPV4",
-                                           ipProto=ipProto )
+                                           ipProto=ipProto,
+                                           ip1=ip1,
+                                           ip2=ip2,
+                                           tcp1=tcp1,
+                                           tcp2=tcp2 )
 
         utilities.assert_equals( expect=main.TRUE,
                              actual=stepResult,
-                                 onpass="SDNIP-ICMP: Point intent test " +
+                                 onpass="SDNIP-TCP: Point intent test " +
                                         "successful using IPV4 type with " +
-                                        "IP protocol ICMP enabled",
-                                 onfail="SDNIP-ICMP: Point intent test " +
+                                        "IP protocol TCP enabled",
+                                 onfail="SDNIP-TCP: Point intent test " +
                                         "failed using IPV4 type with " +
-                                        "IP protocol ICMP enabled" )
+                                        "IP protocol TCP enabled" )
 
         main.step( "DUALSTACK1: Add point intents between h1 and h9" )
         stepResult = main.TRUE
diff --git a/TestON/tests/FUNCintentRest/__init__.py b/TestON/tests/FUNCintentRest/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/FUNCintentRest/__init__.py