blob: 45e9d8ce7b9e71943cdaa18e5ae55a71e28d1393 [file] [log] [blame]
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.saveOnosDiagsIfFailure(main)
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