[SDFAB-644] QoS test for with non-mobile traffic classification
Change-Id: I69e4617fbee1628b3427f2f8be60dec2c8aa95e8
diff --git a/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/QOSNonMobile.params b/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/QOSNonMobile.params
new file mode 100644
index 0000000..8ef7e1b
--- /dev/null
+++ b/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/QOSNonMobile.params
@@ -0,0 +1,175 @@
+<PARAMS>
+ <testcases>1,2</testcases>
+
+ <GRAPH>
+ <nodeCluster>pairedleaves</nodeCluster>
+ <builds>20</builds>
+ <jobName>QOS</jobName>
+ <branch>master</branch>
+ </GRAPH>
+
+ <persistent_setup>True</persistent_setup>
+
+ <kubernetes>
+ <appName>onos-classic</appName>
+ <namespace>tost</namespace>
+ </kubernetes>
+
+ <SLICING>
+ <slices>
+ <slice1>
+ <slice_id>1</slice_id>
+ <traffic_classes>BEST_EFFORT,REAL_TIME</traffic_classes>
+ </slice1>
+ </slices>
+ <traffic_classification>
+ <slice_1_be>
+ <slice_id>1</slice_id>
+ <traffic_class>BEST_EFFORT</traffic_class>
+ <traffic_selector>
+ <criteria1>
+ <type>UDP_DST</type>
+ <udpPort>100</udpPort>
+ </criteria1>
+ </traffic_selector>
+ </slice_1_be>
+ <slice_1_rt>
+ <slice_id>1</slice_id>
+ <traffic_class>REAL_TIME</traffic_class>
+ <traffic_selector>
+ <criteria1>
+ <type>UDP_DST</type>
+ <udpPort>200</udpPort>
+ </criteria1>
+ </traffic_selector>
+ </slice_1_rt>
+ </traffic_classification>
+ </SLICING>
+
+ <TREX>
+ <port_stats>0,2,3</port_stats>
+ <flows>
+ <BE_TO_ENB>
+ <name>Best Effort</name>
+ <l1_bps>2000000000</l1_bps>
+ <trex_port>0</trex_port>
+ <packet>
+ <pktlen>1400</pktlen>
+ <ip_src>10.32.11.125</ip_src>
+ <ip_dst>10.32.11.124</ip_dst>
+ <eth_src>40:A6:B7:22:AB:40</eth_src>
+ <eth_dst>00:00:0A:4C:1C:46</eth_dst>
+ <udp_dport>100</udp_dport>
+ </packet>
+ </BE_TO_ENB>
+ <RT_TO_ENB>
+ <name>Real Time</name>
+ <l1_bps>24000000</l1_bps> <!-- Smaller than the smaller RT max BW -->
+ <trex_port>0</trex_port>
+ <packet>
+ <pktlen>1400</pktlen>
+ <ip_src>10.32.11.125</ip_src>
+ <ip_dst>10.32.11.124</ip_dst>
+ <eth_src>40:A6:B7:22:AB:40</eth_src>
+ <eth_dst>00:00:0A:4C:1C:46</eth_dst>
+ <udp_dport>200</udp_dport>
+ </packet>
+ <latency_stats>true</latency_stats>
+ <flow_id>10</flow_id> <!-- Mandatory when latency_stats=true -->
+ <delay>50000</delay> <!-- wait 50 ms till start to let queues fill up -->
+ <expected_min_received>1</expected_min_received>
+ <expected_max_dropped>0</expected_max_dropped>
+ <expected_99_9_percentile_latency>100</expected_99_9_percentile_latency>
+ </RT_TO_ENB>
+ <BE_1_TO_PDN>
+ <name>Best Effort 1</name>
+ <l1_bps>40000000000</l1_bps>
+ <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>00:00:0A:4C:1C:46</eth_dst>
+ <udp_dport>100</udp_dport>
+ </packet>
+ </BE_1_TO_PDN>
+ <BE_2_TO_PDN>
+ <name>Best Effort 2</name>
+ <l1_bps>25000000000</l1_bps>
+ <trex_port>3</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:21</eth_src>
+ <eth_dst>00:00:0A:4C:1C:46</eth_dst>
+ <udp_dport>100</udp_dport>
+ </packet>
+ </BE_2_TO_PDN>
+ <RT_TO_PDN>
+ <name>Real Time</name>
+ <l1_bps>24000000</l1_bps> <!-- Smaller than the smaller RT max BW -->
+ <trex_port>3</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:21</eth_src>
+ <eth_dst>00:00:0A:4C:1C:46</eth_dst>
+ <udp_dport>200</udp_dport>
+ </packet>
+ <latency_stats>true</latency_stats>
+ <flow_id>10</flow_id> <!-- Mandatory when latency_stats=true -->
+ <delay>50000</delay> <!-- wait 50 ms till start to let queues fill up -->
+ <expected_min_received>1</expected_min_received>
+ <expected_max_dropped>0</expected_max_dropped>
+ <expected_99_9_percentile_latency>100</expected_99_9_percentile_latency>
+ </RT_TO_PDN>
+ </flows>
+ </TREX>
+
+ <TOPO>
+ <switchNum>2</switchNum>
+ <linkNum>2</linkNum>
+ </TOPO>
+
+ <ONOS_Logging>
+ <org.onosproject.p4runtime.ctl.client>DEBUG</org.onosproject.p4runtime.ctl.client>
+ <org.onosproject.p4runtime.ctl.client.writerequestimpl>TRACE</org.onosproject.p4runtime.ctl.client.writerequestimpl>
+ <org.onosproject.segmentrouting>DEBUG</org.onosproject.segmentrouting>
+ <org.onosproject.gnmi.ctl>TRACE</org.onosproject.gnmi.ctl>
+ <org.omecproject.up4>TRACE</org.omecproject.up4>
+ <org.stratumproject.fabric.tna.slicing>TRACE</org.stratumproject.fabric.tna.slicing>
+ </ONOS_Logging>
+ <ONOS_Logging_Reset>
+ <org.onosproject.p4runtime.ctl.client>INFO</org.onosproject.p4runtime.ctl.client>
+ <org.onosproject.p4runtime.ctl.client.writerequestimpl>INFO</org.onosproject.p4runtime.ctl.client.writerequestimpl>
+ <org.onosproject.segmentrouting>DEBUG</org.onosproject.segmentrouting>
+ <org.onosproject.gnmi.ctl>INFO</org.onosproject.gnmi.ctl>
+ <org.omecproject.up4>INFO</org.omecproject.up4>
+ <org.stratumproject.fabric.tna.slicing>INFO</org.stratumproject.fabric.tna.slicing>
+ </ONOS_Logging_Reset>
+
+ <ENV>
+ <cellName>productionCell</cellName>
+ <cellApps>drivers,fpm,lldpprovider,hostprovider,netcfghostprovider,drivers.bmv2,org.opencord.fabric-tofino,pipelines.fabric,org.stratumproject.fabric-tna,drivers.barefoot,segmentrouting,t3,up4</cellApps>
+ </ENV>
+
+ <DEPENDENCY>
+ <useCommonConf>False</useCommonConf>
+ <useCommonTopo>True</useCommonTopo>
+ <useBmv2>True</useBmv2>
+ <bmv2SwitchType>stratum</bmv2SwitchType>
+ <switchPrefix></switchPrefix>
+ <stratumRoot>~/stratum</stratumRoot>
+ <topology>trellis_fabric.py</topology>
+ <lib></lib>
+ </DEPENDENCY>
+
+ <SCALE>
+ <size>3</size>
+ <max>3</max>
+ </SCALE>
+
+</PARAMS>
diff --git a/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/QOSNonMobile.py b/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/QOSNonMobile.py
new file mode 100644
index 0000000..6615a25
--- /dev/null
+++ b/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/QOSNonMobile.py
@@ -0,0 +1,28 @@
+class QOSNonMobile:
+
+ def __init__(self):
+ self.default = ''
+
+ def CASE1(self):
+ main.case("Leaf Edge with NON-Mobile Traffic Classification")
+ try:
+ from tests.USECASE.SegmentRouting.QOSNonMobile.dependencies.QOSNonMobileTest import QOSNonMobileTest
+ except ImportError as e:
+ main.log.error("Import not found. Exiting the test")
+ main.log.error(e)
+ main.cleanAndExit()
+
+ test = QOSNonMobileTest()
+ test.runTest(main, test_idx=1, n_switches=2)
+
+ def CASE2(self):
+ main.case("Leaf Pair Link with NON-Mobile Traffic Classification")
+ try:
+ from tests.USECASE.SegmentRouting.QOSNonMobile.dependencies.QOSNonMobileTest import QOSNonMobileTest
+ except ImportError as e:
+ main.log.error("Import not found. Exiting the test")
+ main.log.error(e)
+ main.cleanAndExit()
+
+ test = QOSNonMobileTest()
+ test.runTest(main, test_idx=2, n_switches=2)
diff --git a/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/QOSNonMobile.topo b/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/QOSNonMobile.topo
new file mode 100644
index 0000000..377a168
--- /dev/null
+++ b/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/QOSNonMobile.topo
@@ -0,0 +1,56 @@
+<TOPOLOGY>
+ <COMPONENT>
+ <ONOScell>
+ <host>localhost</host> # ONOS "bench" machine
+ <user>jenkins</user>
+ <password></password>
+ <type>OnosClusterDriver</type>
+ <connect_order>50</connect_order>
+ <jump_host></jump_host>
+ <home>~/onos</home> # defines where onos home is on the build machine. Defaults to "~/onos/" if empty.
+ <COMPONENTS>
+ <kubeConfig>~/.kube/dev-pairedleaves-tucson</kubeConfig> # If set, will attempt to use this file for setting up port-forwarding
+ <useDocker>True</useDocker> # Whether to use docker for ONOS nodes
+ <docker_prompt>\$</docker_prompt>
+ <cluster_name></cluster_name> # Used as a prefix for cluster components. Defaults to 'ONOS'
+ <diff_clihost>True</diff_clihost> # if it has different host other than localhost for CLI. True or empty. OC# will be used if True.
+ <karaf_username>karaf</karaf_username>
+ <karaf_password>karaf</karaf_password>
+ <web_user>karaf</web_user>
+ <web_pass>karaf</web_pass>
+ <karafPrompt_username>karaf</karafPrompt_username>
+ <rest_port></rest_port>
+ <prompt></prompt> # TODO: we technically need a few of these, one per component
+ <onos_home>~/onos/</onos_home> # defines where onos home is on the target cell machine. Defaults to entry in "home" if empty.
+ <nodes> 3 </nodes> # number of nodes in the cluster
+ <up4_port>51001</up4_port> # Port where the UP4 P4Runtime server is listening
+ </COMPONENTS>
+ </ONOScell>
+
+ <!-- No need for any HostDriver components, traffic is being generated by TRex-->
+ <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>False</software_mode>
+ <trex_library_python_path>/home/jenkins/trex_python</trex_library_python_path>
+ </COMPONENTS>
+ </TRexClient>
+
+ <!-- This component is not needed, but required to use the Testcaselib -->
+ <NetworkBench>
+ <host>10.76.28.66</host>
+ <user>jenkins</user>
+ <password></password>
+ <type>NetworkDriver</type>
+ <connect_order>1</connect_order>
+ <COMPONENTS>
+ </COMPONENTS>
+ </NetworkBench>
+
+ </COMPONENT>
+</TOPOLOGY>
diff --git a/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/__init__.py b/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/__init__.py
diff --git a/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/dependencies/QOSNonMobileTest.py b/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/dependencies/QOSNonMobileTest.py
new file mode 100644
index 0000000..9a52313
--- /dev/null
+++ b/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/dependencies/QOSNonMobileTest.py
@@ -0,0 +1,190 @@
+from tests.USECASE.SegmentRouting.dependencies.Testcaselib import \
+ Testcaselib as run
+from tests.USECASE.SegmentRouting.dependencies.trex import Trex
+import json
+
+
+class QOSNonMobileTest:
+
+ def runTest(self, main, test_idx, n_switches):
+ run.initTest(main)
+ main.log.info(main.Cluster.numCtrls)
+ main.Cluster.setRunningNode(3)
+ run.installOnos(main, skipPackage=True, cliSleep=5)
+
+ # Use the first available ONOS instance CLI
+ onos_rest = main.Cluster.active(0).REST
+ onos_cli = main.Cluster.active(0).CLI
+
+ # Load traffic config for the current test case
+ cfgFile = "%s/tests/CASE_%d.json" % (main.configPath, test_idx)
+ with open(cfgFile) as cfg:
+ testCfg = json.load(cfg)
+
+ trex = Trex()
+ trex.setup(main.TRexClient)
+
+ original_flows_number = onos_cli.checkFlowCount()
+
+ main.step("Add and verify Slices and Traffic Classes")
+ added_slices = True
+ new_flows = 0 # one for every new TC in SLICE and 1 for every Flow Classifier
+ for slice_name in main.params["SLICING"]["slices"]:
+ slice = main.params["SLICING"]["slices"][slice_name]
+ if "slice_id" not in slice:
+ continue
+ slice_id = int(slice["slice_id"])
+ onos_rest.addSlice(slice_id=slice_id, debug=True)
+ slices_onos = onos_rest.getSlices(debug=True)
+ # Verify the slice has been added
+ added_slices = added_slices and \
+ {"SliceId": slice_id} in json.loads(slices_onos)
+
+ tcs = []
+ for tc in slice.get("traffic_classes", "").split(","):
+ onos_rest.addTrafficClassToSlice(slice_id=slice_id,
+ traffic_class=tc,
+ debug=True)
+ tcs.append({"TrafficClass": tc})
+ new_flows += 1
+ tcs_onos = onos_rest.getTrafficClasses(slice_id=slice_id,
+ debug=True)
+ # Verify the TC has been added to the slice
+ added_slices = added_slices and \
+ sorted(json.loads(tcs_onos)) == sorted(tcs)
+ utilities.assert_equal(
+ expect=True,
+ actual=added_slices,
+ onpass="Slices and Traffic Classes installed in slicing service",
+ onfail="Error in installing Slices and Traffic Classes in slicing service"
+ )
+
+ main.step("Add and verify slicing traffic classifier")
+ flows_in_slicing = True
+ for slicing_cfg_name in main.params["SLICING"]["traffic_classification"]:
+ new_flows += 1
+ slicing_config = main.params["SLICING"]["traffic_classification"][
+ slicing_cfg_name]
+
+ traffic_selector = self.__cleanupTrafficSelector(slicing_config.get("traffic_selector", []))
+ onos_rest.addSlicingClassifierFlow(
+ slice_id=int(slicing_config.get("slice_id", "0")),
+ traffic_class=slicing_config.get("traffic_class",
+ "BEST_EFFORT"),
+ traffic_selector=traffic_selector,
+ debug=True
+ )
+ # Verify classifier flows
+ onos_flows = json.loads(onos_rest.getSlicingClassifierFlow(
+ slice_id=int(slicing_config.get("slice_id", "0")),
+ traffic_class=slicing_config.get("traffic_class",
+ "BEST_EFFORT"),
+ debug=True
+ ))
+ flows_in_slicing = flows_in_slicing and traffic_selector in onos_flows
+
+ utilities.assert_equal(
+ expect=True,
+ actual=flows_in_slicing,
+ onpass="Traffic Classifier Flows installed in slicing service",
+ onfail="Error in installing Classifier Flows in slicing service"
+ )
+
+ run.checkFlows(
+ main,
+ minFlowCount=original_flows_number + (new_flows * n_switches)
+ )
+
+ main.step("Send traffic with TRex")
+ for flow in testCfg["flows"]:
+ trex.createFlow(flow)
+ trex.sendAndReceiveTraffic(testCfg["duration"])
+
+ trex.logPortStats()
+ for flow in testCfg["flows"]:
+ trex.logFlowStats(flow)
+
+ # Assert Flow Stats
+ for flow in testCfg["flows"]:
+ if trex.isFlowStats(flow):
+ main.step("{}: Assert RX Packets".format(flow))
+ trex.assertRxPackets(flow)
+ main.step("{}: Assert Dropped Packets".format(flow))
+ trex.assertDroppedPacket(flow)
+ main.step("{}: Assert 99.9 Percentile Latency".format(flow))
+ trex.assert99_9PercentileLatency(flow)
+
+ main.step("Remove and verify slicing traffic classifier")
+ no_flows_in_slicing = True
+ for slicing_cfg_name in main.params["SLICING"]["traffic_classification"]:
+ slicing_config = main.params["SLICING"]["traffic_classification"][
+ slicing_cfg_name]
+
+ traffic_selector = self.__cleanupTrafficSelector(slicing_config.get("traffic_selector", []))
+ onos_rest.removeSlicingClassifierFlow(
+ slice_id=int(slicing_config.get("slice_id", "0")),
+ traffic_class=slicing_config.get("traffic_class",
+ "BEST_EFFORT"),
+ traffic_selector=traffic_selector,
+ debug=True
+ )
+ flow = onos_rest.getSlicingClassifierFlow(
+ slice_id=int(slicing_config.get("slice_id", "0")),
+ traffic_class=slicing_config.get("traffic_class",
+ "BEST_EFFORT"),
+ debug=True
+ )
+ no_flows_in_slicing = no_flows_in_slicing and flow == "[]"
+
+ utilities.assert_equal(
+ expect=True,
+ actual=no_flows_in_slicing,
+ onpass="Traffic Classifier Flows removed in slicing service",
+ onfail="Error in removing Classifier Flows in slicing service"
+ )
+
+ main.step("Remove and verify Slices and Traffic Classes")
+ removed_slices = []
+ for slice_name in main.params["SLICING"]["slices"]:
+ slice = main.params["SLICING"]["slices"][slice_name]
+ if "slice_id" not in slice:
+ continue
+ slice_id = int(slice["slice_id"])
+ for tc in slice.get("traffic_classes", "").split(","):
+ # BEST_EFFORT must be removed as last, or we can leave it,
+ # it will be removed when removing the slice
+ if tc != "BEST_EFFORT":
+ onos_rest.removeTrafficClassToSlice(slice_id=slice_id,
+ traffic_class=tc,
+ debug=True)
+ # Do not try to remove the Default Slice!
+ if slice_id != 0:
+ onos_rest.removeSlice(slice_id=slice_id, debug=True)
+ removed_slices.append(slice_id)
+
+ slices_onos = json.loads(onos_rest.getSlices(debug=True))
+ utilities.assert_equal(
+ expect=True,
+ actual=not any([{"SliceId": slice_id} in slices_onos for slice_id in
+ removed_slices]),
+ onpass="Slices and Traffic Classes removed from slicing service",
+ onfail="Error in removing Slices and Traffic Classes from slicing service"
+ )
+
+ run.checkFlows(main, minFlowCount=original_flows_number)
+
+ main.step("Teardown")
+ trex.teardown()
+ run.cleanup(main)
+
+ def __cleanupTrafficSelector(self, traffic_selector):
+ ts = {
+ "criteria": [traffic_selector[criteria] for criteria in
+ traffic_selector]}
+ # Cleanup the traffic selector, by converting into integer the
+ # required fields, conversion is required for checking the result
+ # from ONOS
+ for criteria in ts["criteria"]:
+ if "udpPort" in criteria:
+ criteria["udpPort"] = int(criteria["udpPort"])
+ return ts
diff --git a/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/dependencies/__init__.py b/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/dependencies/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/dependencies/__init__.py
diff --git a/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/dependencies/tests/CASE_1.json b/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/dependencies/tests/CASE_1.json
new file mode 100644
index 0000000..e1a540d
--- /dev/null
+++ b/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/dependencies/tests/CASE_1.json
@@ -0,0 +1,5 @@
+{
+ "flows": ["BE_TO_ENB", "RT_TO_ENB"],
+ "duration": 10
+}
+
diff --git a/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/dependencies/tests/CASE_2.json b/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/dependencies/tests/CASE_2.json
new file mode 100644
index 0000000..bf312d3
--- /dev/null
+++ b/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/dependencies/tests/CASE_2.json
@@ -0,0 +1,5 @@
+{
+ "flows": ["BE_1_TO_PDN","BE_2_TO_PDN", "RT_TO_PDN"],
+ "duration": 10
+}
+
diff --git a/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/dependencies/trex_config.yaml b/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/dependencies/trex_config.yaml
new file mode 100644
index 0000000..6fbeddb
--- /dev/null
+++ b/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/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: 20
+ 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 9b15811..d710d07 100644
--- a/TestON/tests/USECASE/SegmentRouting/dependencies/trex.py
+++ b/TestON/tests/USECASE/SegmentRouting/dependencies/trex.py
@@ -173,6 +173,10 @@
packet["gtp_teid"] = int(packet["gtp_teid"])
if "pktlen" in packet.keys():
packet["pktlen"] = int(packet["pktlen"])
+ if "udp_dport" in packet.keys():
+ packet["udp_dport"] = int(packet["udp_dport"])
+ if "udp_sport" in packet.keys():
+ packet["udp_sport"] = int(packet["udp_sport"])
return packet
@staticmethod