blob: faaeb04ab3918945a2d700d139332d4b31f53e9f [file] [log] [blame]
Daniele Moro04a62d12021-10-06 17:37:36 +02001from tests.USECASE.SegmentRouting.dependencies.Testcaselib import \
2 Testcaselib as run
3from tests.USECASE.SegmentRouting.dependencies.trex import Trex
4import json
5
6
7class QOSNonMobileTest:
8
9 def runTest(self, main, test_idx, n_switches):
Jon Halldd05bbc2022-01-27 12:14:50 -080010 try:
11 run.initTest(main)
12 main.log.info(main.Cluster.numCtrls)
13 main.Cluster.setRunningNode(3)
14 run.installOnos(main, skipPackage=True, cliSleep=5)
Daniele Moro04a62d12021-10-06 17:37:36 +020015
Jon Halldd05bbc2022-01-27 12:14:50 -080016 # Use the first available ONOS instance CLI
17 onos_rest = main.Cluster.active(0).REST
18 onos_cli = main.Cluster.active(0).CLI
Daniele Moro04a62d12021-10-06 17:37:36 +020019
Jon Halldd05bbc2022-01-27 12:14:50 -080020 # Load traffic config for the current test case
21 cfgFile = "%s/tests/CASE_%d.json" % (main.configPath, test_idx)
22 with open(cfgFile) as cfg:
23 testCfg = json.load(cfg)
Daniele Moro04a62d12021-10-06 17:37:36 +020024
Jon Halldd05bbc2022-01-27 12:14:50 -080025 trex = Trex()
26 trex.setup(main.TRexClient)
Daniele Moro04a62d12021-10-06 17:37:36 +020027
Jon Halldd05bbc2022-01-27 12:14:50 -080028 original_flows_number = onos_cli.checkFlowCount()
Daniele Moro04a62d12021-10-06 17:37:36 +020029
Carmelo Cascone848d1f52022-01-27 18:15:58 -080030 main.step("Verify slices and traffic Classes")
31
32 slices_onos = onos_rest.getSlices(debug=True)
33
34 # Sanity check for the API, at least the default slice should be there.
35 utilities.assert_equal(
36 expect=True,
37 actual={"SliceId": 0} in json.loads(slices_onos),
38 onpass="Default slice verified in slicing service",
39 onfail="Error in verifying default slice in slicing service"
40 )
41
Jon Halldd05bbc2022-01-27 12:14:50 -080042 for slice_name in main.params["SLICING"]["slices"]:
43 slice = main.params["SLICING"]["slices"][slice_name]
44 if "slice_id" not in slice:
45 continue
46 slice_id = int(slice["slice_id"])
Carmelo Cascone848d1f52022-01-27 18:15:58 -080047 utilities.assert_equal(
48 expect=True,
49 actual={"SliceId": slice_id} in json.loads(slices_onos),
50 onpass="Verified presence of slice %s in slicing service" % slice_id,
51 onfail="Slice %s not found in slicing service" % slice_id
52 )
Daniele Moro04a62d12021-10-06 17:37:36 +020053
Carmelo Cascone848d1f52022-01-27 18:15:58 -080054 tcs = slice.get("traffic_classes", "").split(",")
55
Jon Halldd05bbc2022-01-27 12:14:50 -080056 tcs_onos = onos_rest.getTrafficClasses(slice_id=slice_id,
57 debug=True)
Carmelo Cascone848d1f52022-01-27 18:15:58 -080058 for tc in tcs:
59 utilities.assert_equal(
60 expect=True,
61 actual={"TrafficClass": tc} in json.loads(tcs_onos),
62 onpass="Verified presence of TC %s for slice %s in slicing service" % (tc, slice_id),
63 onfail="TC %s not found for slice %s in slicing service" % (tc, slice_id)
64 )
Jon Halldd05bbc2022-01-27 12:14:50 -080065
Carmelo Cascone848d1f52022-01-27 18:15:58 -080066 main.step("Add and verify traffic classifier flows")
67 new_flows = 0
68 for flow_name in main.params["SLICING"]["traffic_classification"]:
Daniele Moro04a62d12021-10-06 17:37:36 +020069 new_flows += 1
Carmelo Cascone848d1f52022-01-27 18:15:58 -080070 flow_config = main.params["SLICING"]["traffic_classification"][
71 flow_name]
Daniele Moro04a62d12021-10-06 17:37:36 +020072
Carmelo Cascone848d1f52022-01-27 18:15:58 -080073 traffic_selector = self.__cleanupTrafficSelector(flow_config.get("traffic_selector", []))
Jon Halldd05bbc2022-01-27 12:14:50 -080074 onos_rest.addSlicingClassifierFlow(
Carmelo Cascone848d1f52022-01-27 18:15:58 -080075 slice_id=int(flow_config.get("slice_id")),
76 traffic_class=flow_config.get("traffic_class"),
Jon Halldd05bbc2022-01-27 12:14:50 -080077 traffic_selector=traffic_selector,
78 debug=True
79 )
Carmelo Cascone848d1f52022-01-27 18:15:58 -080080
Jon Halldd05bbc2022-01-27 12:14:50 -080081 onos_flows = json.loads(onos_rest.getSlicingClassifierFlow(
Carmelo Cascone848d1f52022-01-27 18:15:58 -080082 slice_id=int(flow_config.get("slice_id")),
83 traffic_class=flow_config.get("traffic_class"),
Jon Halldd05bbc2022-01-27 12:14:50 -080084 debug=True
85 ))
Carmelo Cascone848d1f52022-01-27 18:15:58 -080086 utilities.assert_equal(
87 expect=True,
88 actual=traffic_selector in onos_flows,
89 onpass="Classifier flow %s installed" % flow_name,
90 onfail="Classifier flow %s not found after insert" % flow_name
91 )
Daniele Moro04a62d12021-10-06 17:37:36 +020092
Jon Halldd05bbc2022-01-27 12:14:50 -080093 run.checkFlows(
94 main,
95 minFlowCount=original_flows_number + (new_flows * n_switches)
Daniele Moro04a62d12021-10-06 17:37:36 +020096 )
Jon Halldd05bbc2022-01-27 12:14:50 -080097
98 main.step("Send traffic with TRex")
99 for flow in testCfg["flows"]:
100 trex.createFlow(flow)
101 results = trex.sendAndReceiveTraffic(testCfg["duration"])
102 trex.verifyCongestion(results)
103
104 trex.logPortStats()
105 for flow in testCfg["flows"]:
106 trex.logFlowStats(flow)
107
108 # Assert Flow Stats
109 for flow in testCfg["flows"]:
110 if trex.isFlowStats(flow):
111 main.step("{}: Assert RX Packets".format(flow))
112 trex.assertRxPackets(flow)
113 main.step("{}: Assert Dropped Packets".format(flow))
114 trex.assertDroppedPacket(flow)
115 main.step("{}: Assert 99.9 Percentile Latency".format(flow))
116 trex.assert99_9PercentileLatency(flow)
117
Carmelo Cascone848d1f52022-01-27 18:15:58 -0800118 main.step("Remove and verify traffic classifier flows")
119 for flow_name in main.params["SLICING"]["traffic_classification"]:
120 flow_config = main.params["SLICING"]["traffic_classification"][
121 flow_name]
Jon Halldd05bbc2022-01-27 12:14:50 -0800122
Carmelo Cascone848d1f52022-01-27 18:15:58 -0800123 traffic_selector = self.__cleanupTrafficSelector(flow_config.get("traffic_selector", []))
Jon Halldd05bbc2022-01-27 12:14:50 -0800124 onos_rest.removeSlicingClassifierFlow(
Carmelo Cascone848d1f52022-01-27 18:15:58 -0800125 slice_id=int(flow_config.get("slice_id")),
126 traffic_class=flow_config.get("traffic_class"),
Jon Halldd05bbc2022-01-27 12:14:50 -0800127 traffic_selector=traffic_selector,
128 debug=True
129 )
Carmelo Cascone848d1f52022-01-27 18:15:58 -0800130 onos_flow = onos_rest.getSlicingClassifierFlow(
131 slice_id=int(flow_config.get("slice_id")),
132 traffic_class=flow_config.get("traffic_class"),
Jon Halldd05bbc2022-01-27 12:14:50 -0800133 debug=True
134 )
Carmelo Cascone848d1f52022-01-27 18:15:58 -0800135 utilities.assert_equal(
136 expect="[]",
137 actual=onos_flow,
138 onpass="Classifier flow %s removed from slicing service" % flow_name,
139 onfail="Unable to remove classifier flow %s from slicing service" % flow_name
140 )
Daniele Moro04a62d12021-10-06 17:37:36 +0200141
Jon Halldd05bbc2022-01-27 12:14:50 -0800142 run.checkFlows(main, minFlowCount=original_flows_number)
143 finally:
144 main.step("Teardown")
145 trex.teardown()
146 run.cleanup(main)
Daniele Moro04a62d12021-10-06 17:37:36 +0200147
148 def __cleanupTrafficSelector(self, traffic_selector):
149 ts = {
150 "criteria": [traffic_selector[criteria] for criteria in
151 traffic_selector]}
152 # Cleanup the traffic selector, by converting into integer the
153 # required fields, conversion is required for checking the result
154 # from ONOS
155 for criteria in ts["criteria"]:
156 if "udpPort" in criteria:
157 criteria["udpPort"] = int(criteria["udpPort"])
158 return ts