Merge "[SDFAB-506] Add QoS test for on edge ports with GTP encapped traffic"
diff --git a/TestON/drivers/common/api/deepinsightapidriver.py b/TestON/drivers/common/api/deepinsightapidriver.py
new file mode 100644
index 0000000..af02256
--- /dev/null
+++ b/TestON/drivers/common/api/deepinsightapidriver.py
@@ -0,0 +1,93 @@
+from deepinsight.client import DeepInsightClient
+from drivers.common.apidriver import API
+
+class DeepInsightApiDriver( API ):
+ def __init__( self ):
+ self.name = None
+ self.serverUrl = None
+ self.accessToken = None
+ self.refreshToken = None
+ self.requestAuthHeader = None
+ self.verifySsl = False
+ self.client = None
+ super( DeepInsightApiDriver, self ).__init__()
+
+ def connect(
+ self,
+ **connectargs
+ ):
+ for key in connectargs:
+ vars(self)[key] = connectargs[key]
+ self.name = self.options["name"]
+ self.client = DeepInsightClient(
+ server_url = self.options["server_url"],
+ username = self.options["username"],
+ password = self.options["password"],
+ verify_ssl = self.options["verify_ssl"] == "True",
+ )
+ self.handle = super( DeepInsightApiDriver, self ).connect()
+ return self.handle
+
+ def disconnect( self, **connectargs ):
+ self.client.logout()
+
+ def getFlows(
+ self,
+ startTimeMs = None,
+ endTimeMs = None,
+ maxResults = 100,
+ srcIp = None,
+ dstIp = None,
+ srcPort = None,
+ dstPort = None,
+ ipProto = None,
+ ):
+ return self.client.get_flows(
+ startTimeMs,
+ endTimeMs,
+ maxResults,
+ srcIp,
+ dstIp,
+ srcPort,
+ dstPort,
+ ipProto,
+ )
+
+ def getSwitchPacketDrop(
+ self,
+ switchId,
+ egressPort = 0,
+ queueId = 0,
+ startTime = None,
+ endTime = None,
+ numBuckets = 100,
+ ):
+ return self.client.get_switch_packet_drop(
+ switchId,
+ egressPort,
+ queueId,
+ startTime,
+ endTime,
+ numBuckets,
+ )
+
+ def getSwitchAnomalies(
+ self, switchId, startTime = None, endTime = None
+ ):
+ return self.client.get_switch_anomalies(
+ switchId, startTime, endTime
+ )
+
+ def getSwitchLatencies(
+ self,
+ switchId,
+ startTime = None,
+ endTime = None,
+ granularity = 1000,
+ ):
+ return self.client.get_switch_latencies(
+ switchId,
+ startTime,
+ endTime,
+ granularity,
+ )
diff --git a/TestON/drivers/common/cli/hostdriver.py b/TestON/drivers/common/cli/hostdriver.py
index a4ab31c..5bfe274 100644
--- a/TestON/drivers/common/cli/hostdriver.py
+++ b/TestON/drivers/common/cli/hostdriver.py
@@ -248,7 +248,7 @@
main.log.error( self.name + ": " + self.handle.before )
return main.FALSE
- def addRouteToHost( self, route, gw, interface=None, sudoRequired=True, purgeOnDisconnect=True ):
+ def addRouteToHost( self, route, gw, interface=None, sudoRequired=True, purgeOnDisconnect=True, cmdPath='/sbin/ip' ):
"""
Adds a static route to the host
Arguments:
@@ -260,7 +260,11 @@
* purgeOnDisconnect - Boolean, remove this route before disconnecting from component
"""
try:
- cmd = "ip route add %s via %s" % ( route, gw )
+ if cmdPath:
+ cmd = cmdPath
+ else:
+ cmd = "ip"
+ cmd += " route add %s via %s" % ( route, gw )
if sudoRequired:
cmd = "sudo %s" % cmd
if interface:
@@ -300,7 +304,7 @@
main.log.error( self.name + ": " + self.handle.before )
return main.FALSE
- def deleteRoute( self, route, gw, interface=None, sudoRequired=True ):
+ def deleteRoute( self, route, gw, interface=None, sudoRequired=True, cmdPath='/sbin/ip' ):
"""
Deletess a static route from the host
Arguments:
@@ -311,7 +315,11 @@
* sudoRequired - Boolean, whether sudo is needed for this command, defaults to True
"""
try:
- cmd = "ip route del %s via %s" % ( route, gw )
+ if cmdPath:
+ cmd = cmdPath
+ else:
+ cmd = "ip"
+ cmd += " route del %s via %s" % ( route, gw )
if sudoRequired:
cmd = "sudo %s" % cmd
if interface:
diff --git a/TestON/tests/USECASE/SegmentRouting/SRStaging/SRStaging.topo b/TestON/tests/USECASE/SegmentRouting/SRStaging/SRStaging.topo
index 2f4c8f2..b9d705e 100644
--- a/TestON/tests/USECASE/SegmentRouting/SRStaging/SRStaging.topo
+++ b/TestON/tests/USECASE/SegmentRouting/SRStaging/SRStaging.topo
@@ -183,7 +183,7 @@
</Host3>
<ng40vm>
- <host>192.168.122.102</host>
+ <host>10.92.1.95</host>
<user>ng40</user>
<password>ng40</password>
<type>HostDriver</type>
diff --git a/TestON/tests/USECASE/SegmentRouting/SRStaging/SRpairedLeaves/SRpairedLeaves.params b/TestON/tests/USECASE/SegmentRouting/SRStaging/SRpairedLeaves/SRpairedLeaves.params
index 2cb31b3..85f3fd6 100644
--- a/TestON/tests/USECASE/SegmentRouting/SRStaging/SRpairedLeaves/SRpairedLeaves.params
+++ b/TestON/tests/USECASE/SegmentRouting/SRStaging/SRpairedLeaves/SRpairedLeaves.params
@@ -1,5 +1,5 @@
<PARAMS>
- <testcases>1,2,101,102,103,104,201,202,203,204,205,206,207,208,301</testcases>
+ <testcases>1,2,101,102,103,104,301,302</testcases>
<GRAPH>
<nodeCluster>pairedleaves</nodeCluster>
diff --git a/TestON/tests/USECASE/SegmentRouting/SRStaging/SRpairedLeaves/SRpairedLeaves.py b/TestON/tests/USECASE/SegmentRouting/SRStaging/SRpairedLeaves/SRpairedLeaves.py
index 96618cf..5911832 100644
--- a/TestON/tests/USECASE/SegmentRouting/SRStaging/SRpairedLeaves/SRpairedLeaves.py
+++ b/TestON/tests/USECASE/SegmentRouting/SRStaging/SRpairedLeaves/SRpairedLeaves.py
@@ -48,6 +48,7 @@
"""
try:
from tests.USECASE.SegmentRouting.SRStaging.dependencies.SRStagingTest import SRStagingTest
+ from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as run
import json
except ImportError:
main.log.error( "SRStagingTest not found. Exiting the test" )
@@ -63,6 +64,7 @@
topology='0x2',
onosNodes=3,
description="%s tests on the %s pod" % ( descPrefix, pod ) )
+ hosts = [ 'h1', 'h2', 'h3', 'mgmt' ]
run.pingAllFabricIntfs( main, hosts, dumpFlows=False )
main.funcs.cleanup( main )
@@ -670,3 +672,61 @@
# Cleanup
main.log.warn( json.dumps( main.downtimeResults, indent=4, sort_keys=True ) )
main.funcs.cleanup( main )
+
+ def CASE302 ( self, main ):
+ """
+ Send ping packets from one host to another host and check flows from DeepInsight.
+ """
+
+ try:
+ from tests.USECASE.SegmentRouting.SRStaging.dependencies.SRStagingTest import SRStagingTest
+ from tests.USECASE.SegmentRouting.dependencies.Testcaselib import Testcaselib as run
+ from core import utilities
+ import time
+ import socket
+ except ImportError as e:
+ main.log.exception( "SRStagingTest not found. Exiting the test" )
+ main.cleanAndExit()
+ try:
+ main.funcs
+ except ( NameError, AttributeError ):
+ main.funcs = SRStagingTest()
+
+ pod = main.params['GRAPH'].get( 'nodeCluster', "hardware" )
+ main.cfgName = 'CASE302'
+ main.funcs.setupTest( main,
+ topology='0x2',
+ onosNodes=3,
+ description="INT flow report tests on %s POD" % ( pod ) )
+ startTimeMs = ( time.time() - 5 ) * 1000
+ run.verifyPing( main, ['h1'], ['h2'] )
+ endTimeMs = ( time.time() + 5 ) * 1000
+ main.step( "Checking flow report from DeepInsight" )
+
+ def getFiveTupleCount(*args, **kwargs):
+ flows = main.DeepInsight.getFlows(
+ startTimeMs=startTimeMs,
+ endTimeMs=endTimeMs,
+ srcIp=main.h1.interfaces[0]['ips'][0],
+ dstIp=main.h2.interfaces[0]['ips'][0],
+ ipProto=socket.IPPROTO_ICMP
+ )
+ if "FiveTupleCount" in flows:
+ return flows["FiveTupleCount"]
+ else:
+ return 0
+
+ # Need to wait few seconds until DeepInsight database updated.
+ fiveTupleCount = utilities.retry(
+ f=getFiveTupleCount,
+ retValue=0,
+ attempts=60,
+ )
+
+ utilities.assert_equals(
+ expect=1, actual=fiveTupleCount,
+ onpass="Got 1 flow report from DeepInsight as expected.",
+ onfail="Got %d flow reports from DeepInsight (expect 1)" % ( fiveTupleCount )
+ )
+
+ main.funcs.cleanup( main )
diff --git a/TestON/tests/USECASE/SegmentRouting/SRStaging/SRpairedLeaves/SRpairedLeaves.topo b/TestON/tests/USECASE/SegmentRouting/SRStaging/SRpairedLeaves/SRpairedLeaves.topo
index 40bf030..e529c6f 100644
--- a/TestON/tests/USECASE/SegmentRouting/SRStaging/SRpairedLeaves/SRpairedLeaves.topo
+++ b/TestON/tests/USECASE/SegmentRouting/SRStaging/SRpairedLeaves/SRpairedLeaves.topo
@@ -184,5 +184,19 @@
</COMPONENTS>
</NetworkBench>
+ <DeepInsight>
+ <host>10.76.28.74</host>
+ <user>jenkins</user>
+ <password></password>
+ <type>DeepInsightApiDriver</type>
+ <connect_order>1</connect_order>
+ <COMPONENTS>
+ <server_url>https://10.76.28.74:30000</server_url>
+ <username>diadmin</username>
+ <password>diadmin</password>
+ <verify_ssl>False</verify_ssl>
+ </COMPONENTS>
+ </DeepInsight>
+
</COMPONENT>
</TOPOLOGY>
diff --git a/TestON/tests/USECASE/SegmentRouting/SRStaging/dependencies/SRStagingTest.py b/TestON/tests/USECASE/SegmentRouting/SRStaging/dependencies/SRStagingTest.py
index a3ab6ba..f0f30a5 100644
--- a/TestON/tests/USECASE/SegmentRouting/SRStaging/dependencies/SRStagingTest.py
+++ b/TestON/tests/USECASE/SegmentRouting/SRStaging/dependencies/SRStagingTest.py
@@ -1353,8 +1353,9 @@
def cleanup( self, main, headerOrder=None ):
try:
- for component in main.trafficComponents:
- main.Network.removeComponent( component.name )
+ if hasattr( main, "trafficComponents" ):
+ for component in main.trafficComponents:
+ main.Network.removeComponent( component.name )
main.trafficComponents = []
except Exception:
main.log.exception( "Error cleaning up traffic components" )
diff --git a/TestON/tests/dependencies/topology.py b/TestON/tests/dependencies/topology.py
index 9d20cda..56a29a9 100644
--- a/TestON/tests/dependencies/topology.py
+++ b/TestON/tests/dependencies/topology.py
@@ -263,6 +263,15 @@
srcIpList[ src ] = main.Network.getIPAddress( src, proto='IPV6' if ipv6 else 'IPV4', iface=hostHandle.interfaces[0].get("name") )
unexpectedPings = []
for dst in dstList:
+ if not hasattr( main, dst ):
+ main.log.info( "Creating component for host {}".format( dst ) )
+ main.Network.createHostComponent( dst )
+ hostHandle = getattr( main, dst )
+ if hasattr( main, 'Mininet1' ):
+ main.log.info( "Starting CLI on host {}".format( dst ) )
+ hostHandle.startHostCli()
+ else:
+ hostHandle.connectInband()
hostHandle = getattr( main, dst )
dstIp = main.Network.getIPAddress( dst, proto='IPV6' if ipv6 else 'IPV4', iface=hostHandle.interfaces[0].get("name") )
# Start pings from src hosts in parallel