[SDFAB-644] QoS test for with non-mobile traffic classification
Change-Id: I69e4617fbee1628b3427f2f8be60dec2c8aa95e8
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