[SDFAB-581] Create TestON test for INT queue report

Change-Id: I059f071ff37bdc724ca875087bda60397d4ac64f
diff --git a/TestON/tests/USECASE/SegmentRouting/INT/INT.params b/TestON/tests/USECASE/SegmentRouting/INT/INT.params
index b4be343..63ff5c7 100644
--- a/TestON/tests/USECASE/SegmentRouting/INT/INT.params
+++ b/TestON/tests/USECASE/SegmentRouting/INT/INT.params
@@ -3,4 +3,45 @@
 <PARAMS>
     <testcases>1,2,3</testcases>
     <routerMac>00:00:0A:4C:1C:46</routerMac>
+    <TREX>
+        <flows>
+            <RESET_QUEUE_REPORT_FILTER>
+                <!-- A low-throughput flow to reset the queue report filter -->
+                <name>Low throughput flow</name>
+                <l1_bps>10000</l1_bps>
+                <trex_port>0</trex_port>
+                <packet>
+                    <pktlen>1400</pktlen>
+                    <ip_src>10.32.11.123</ip_src>
+                    <ip_dst>10.32.11.125</ip_dst>
+                    <eth_src>40:A6:B7:22:AB:40</eth_src>
+                    <eth_dst>40:A6:B7:22:AB:21</eth_dst>
+                </packet>
+            </RESET_QUEUE_REPORT_FILTER>
+            <FLOW1>
+                <name>Flow 1</name>
+                <l1_bps>25000000000</l1_bps> <!-- 25G -->
+                <trex_port>0</trex_port>
+                <packet>
+                    <pktlen>1400</pktlen>
+                    <ip_src>10.32.11.123</ip_src>
+                    <ip_dst>10.32.11.125</ip_dst>
+                    <eth_src>40:A6:B7:22:AB:40</eth_src>
+                    <eth_dst>40:A6:B7:22:AB:21</eth_dst>
+                </packet>
+            </FLOW1>
+            <FLOW2>
+                <name>Flow 2</name>
+                <l1_bps>25000000000</l1_bps> <!-- 25G -->
+                <trex_port>2</trex_port>
+                <packet>
+                    <pktlen>1400</pktlen>
+                    <ip_src>10.32.11.124</ip_src>
+                    <ip_dst>10.32.11.125</ip_dst>
+                    <eth_src>40:A6:B7:22:AB:20</eth_src>
+                    <eth_dst>40:A6:B7:22:AB:21</eth_dst>
+                </packet>
+            </FLOW2>
+        </flows>
+    </TREX>
 </PARAMS>
diff --git a/TestON/tests/USECASE/SegmentRouting/INT/INT.py b/TestON/tests/USECASE/SegmentRouting/INT/INT.py
index c902af3..9295a29 100644
--- a/TestON/tests/USECASE/SegmentRouting/INT/INT.py
+++ b/TestON/tests/USECASE/SegmentRouting/INT/INT.py
@@ -221,3 +221,63 @@
 
         main.step("Clean up the test")
         intTest.cleanUp(main)
+
+    def CASE4(self, main):
+        """
+        Generate traffic at high rate and expect queue congestion reports in DeepInsight.
+        """
+        from core import utilities
+        import time
+        from tests.USECASE.SegmentRouting.INT.dependencies.IntTest import IntTest
+        from tests.USECASE.SegmentRouting.dependencies.trex import Trex
+        main.cfgName = 'CASE4'
+
+        main.step("Setting up the test")
+        intTest = IntTest(scapy=False)
+        intTest.setUpTest(main)
+        dstIp = main.params["TREX"]["flows"]["FLOW1"]["packet"]["ip_dst"]
+
+        main.step("Set up TRex client")
+        trex = Trex()
+        trex.setup(main.TRexClient)
+
+        # See SRpairedLeaves.param for the detail of each flow.
+        main.step("Reset queue report filter")
+        # Here we are using a low-latency(no congestion) traffic to reset the queue.
+        # report filter.
+        trex.createFlow("RESET_QUEUE_REPORT_FILTER")
+        trex.sendAndReceiveTraffic(5)
+        trex.resetFlows()
+        main.step("Generating traffic")
+        startTimeMs = (time.time() - 5) * 1000
+        trex.createFlow("FLOW1")
+        trex.createFlow("FLOW2")
+        trex.sendAndReceiveTraffic(10)
+        endTimeMs = (time.time() + 5) * 1000
+
+        main.step("Checking queue report from DeepInsight")
+        def getQueueAnomaly(*args, **kwargs):
+            return main.DeepInsight.getAnomalyRecords(
+                startTime=startTimeMs,
+                endTime=endTimeMs,
+                dstIp=dstIp,
+                anomalyType="congested_flow",
+            )
+
+        # Need to wait few seconds until DeepInsight database updated.
+        queueAnomalies = utilities.retry(
+            f=getQueueAnomaly,
+            retValue=[[]],
+            attempts=60,
+        )
+
+        # We should get at least two congestion records
+        utilities.assert_lesser(
+            expect=2, actual=len(queueAnomalies),
+            onpass="Got %d anomalies with 'congested_flow' type as expcted." % (len(queueAnomalies)),
+            onfail="Did not get any anomaly with 'congested_flow' type."
+        )
+
+        main.step("Clean up the test")
+        trex.teardown()
+        intTest.cleanUp(main)
diff --git a/TestON/tests/USECASE/SegmentRouting/INT/INT.topo b/TestON/tests/USECASE/SegmentRouting/INT/INT.topo
index 559d041..e54c546 100644
--- a/TestON/tests/USECASE/SegmentRouting/INT/INT.topo
+++ b/TestON/tests/USECASE/SegmentRouting/INT/INT.topo
@@ -100,6 +100,19 @@
             </COMPONENTS>
         </DeepInsight>
 
+        <TRexClient>
+            <host>localhost</host>
+            <type>TrexClientDriver</type>
+            <connect_order>5</connect_order>
+            <COMPONENTS>
+                <trex_address>10.76.28.72</trex_address> <!-- Compute2 -->
+                <trex_config>trex_config.yaml</trex_config> <!-- relative path starting from ./dependencies-->
+                <force_restart>True</force_restart>
+                <software_mode>True</software_mode>
+                <trex_library_python_path>/home/jenkins/trex_python</trex_library_python_path>
+            </COMPONENTS>
+        </TRexClient>
+
         <!-- A NetworkDriver to provide functions such as "createHostComponent" -->
         <INTNetwork>
             <host>localhost</host>
diff --git a/TestON/tests/USECASE/SegmentRouting/INT/dependencies/IntTest.py b/TestON/tests/USECASE/SegmentRouting/INT/dependencies/IntTest.py
index 2c6a99e..e10248f 100644
--- a/TestON/tests/USECASE/SegmentRouting/INT/dependencies/IntTest.py
+++ b/TestON/tests/USECASE/SegmentRouting/INT/dependencies/IntTest.py
@@ -1,6 +1,7 @@
 # SPDX-FileCopyrightText: Copyright 2021-present Open Networking Foundation.
 # SPDX-License-Identifier: GPL-2.0-or-later
 
+import os
 from tests.dependencies.Network import Network
 
 class IntTest:
@@ -12,6 +13,7 @@
     def setUpTest(self, main):
         main.Network = Network()
         main.Network.connectToNet()
+        main.configPath = os.path.join(os.path.dirname(main.testFile), "dependencies")
 
         for host in self.hosts:
             main.Network.createHostComponent(host)
diff --git a/TestON/tests/USECASE/SegmentRouting/INT/dependencies/trex_config.yaml b/TestON/tests/USECASE/SegmentRouting/INT/dependencies/trex_config.yaml
new file mode 100644
index 0000000..00a1f85
--- /dev/null
+++ b/TestON/tests/USECASE/SegmentRouting/INT/dependencies/trex_config.yaml
@@ -0,0 +1,19 @@
+# TRex Port ID=0 --> PCI BUS: d8:00.0, Linux Intf: enp216s0f0 connected to leaf1/0 (PDN)
+# TRex Port ID=1 --> PCI BUS: d8:00.1, Linux Intf: enp216s0f1 not connected, but required by TRex to have an even number of interfaces
+# TRex Port ID=2 --> PCI BUS: 5e:00.0, Linux Intf: enp94s0f0 connected to leaf2/0 (eNodeB)
+# TRex Port ID=3 --> PCI BUS: 5e:00.1, Linux Intf: enp94s0f1 connected to leaf2/4
+
+- version: 2
+  port_limit: 4
+  interfaces: [ 'd8:00.0', 'd8:00.1', '5e:00.0', '5e:00.1']
+  port_bandwidth_gb: 40
+  c: 16
+  port_info:
+    - src_mac: 40:A6:B7:22:AB:40
+      dest_mac: 00:00:0A:4C:1C:46
+    - src_mac: 40:A6:B7:22:AB:41
+      dest_mac: 00:00:0A:4C:1C:46
+    - src_mac: 40:A6:B7:22:AB:20
+      dest_mac: 00:00:0A:4C:1C:46
+    - src_mac: 40:A6:B7:22:AB:21
+      dest_mac: 00:00:0A:4C:1C:46
diff --git a/TestON/tests/USECASE/SegmentRouting/dependencies/trex.py b/TestON/tests/USECASE/SegmentRouting/dependencies/trex.py
index 9245f16..9b15811 100644
--- a/TestON/tests/USECASE/SegmentRouting/dependencies/trex.py
+++ b/TestON/tests/USECASE/SegmentRouting/dependencies/trex.py
@@ -67,6 +67,9 @@
             self.packets[flow_name] = scapy_helper.simple_udp_packet(
                 **self.traffic_flows[flow_name]["packet"])
 
+    def resetFlows(self):
+        self.packets = {}
+
     def sendAndReceiveTraffic(self, duration):
         """
         Connect the client, create the flows in trex (with packets created with