Merge "Fix missing IP_PROTO in slicing classifier flows"
diff --git a/TestON/drivers/common/api/controller/onosrestdriver.py b/TestON/drivers/common/api/controller/onosrestdriver.py
index 7ce7749..927cd25 100755
--- a/TestON/drivers/common/api/controller/onosrestdriver.py
+++ b/TestON/drivers/common/api/controller/onosrestdriver.py
@@ -2465,7 +2465,7 @@
self.__slicingClassifierFlow( slice_id, traffic_class, traffic_selector,
ip, port, debug, method="DELETE" )
- def getSlicingClassifierFlow( self, slice_id, traffic_class, ip="DEFAULT",
+ def getSlicingClassifierFlows( self, slice_id, traffic_class, ip="DEFAULT",
port="DEFAULT", debug=False ):
try:
if ip == "DEFAULT":
@@ -2482,9 +2482,11 @@
output = response[ 1 ]
if debug:
main.log.debug(self.name + ": read: " + output)
- traffic_selector = json.loads( output ).get( 'TrafficSelector' )
- assert traffic_selector is not None, "Error parsing json object"
- return json.dumps( traffic_selector )
+ # FIXME: use plural in slicing service API
+ # TrafficSelector actually points to an array of selectors.
+ traffic_selectors = json.loads( output ).get( 'TrafficSelector' )
+ assert traffic_selectors is not None, "Error parsing json object"
+ return json.dumps( traffic_selectors )
else:
main.log.error( "Error with REST request, response was: %s: %s" %
( response[ 0 ], response[ 1 ] ) )
@@ -2496,75 +2498,6 @@
main.log.exception( self.name + ": Uncaught exception!" )
main.cleanAndExit()
- def __slices( self, slice_id, ip="DEFAULT", port="DEFAULT", debug=False,
- method="POST" ):
- try:
- if debug:
- main.log.debug( self.name + ": %s Slice" % method )
- main.log.debug( self.name + ": Slice ID: %d" % slice_id )
- if ip == "DEFAULT":
- main.log.warn( self.name + ": No ip given, reverting to ip from topo file" )
- ip = self.ip_address
- if port == "DEFAULT":
- main.log.warn( self.name + ": No port given, reverting to port " +
- "from topo file" )
- port = self.port
- url = "/fabrictna/slicing/slice/%d" % slice_id
- response = self.send( method=method,
- url=url, ip = ip, port = port,
- base="/onos", data = {} )
- if response:
- if "200" in str( response[ 0 ] ):
- main.log.info( self.name + ": Successfully %s Slice ID: %d " % ( method, slice_id ) )
- return main.TRUE
- else:
- main.log.error( "Error with REST request, response was: %s: %s" %
- ( response[ 0 ], response[ 1 ] ) )
- return main.FALSE
- except NotImplementedError as e:
- raise # Inform the caller
- except ( AttributeError, TypeError ):
- main.log.exception( self.name + ": Object not as expected" )
- return None
- except Exception:
- main.log.exception( self.name + ": Uncaught exception!" )
- main.cleanAndExit()
-
- def __trafficClass( self, slice_id, traffic_class, ip="DEFAULT", port="DEFAULT",
- debug=False, method="POST" ):
- try:
- if debug:
- main.log.debug( self.name + ": %s Traffic Class" % method )
- main.log.debug( self.name + ": Slice ID: %d, Traffic Class: %s" % ( slice_id, traffic_class ) )
- if ip == "DEFAULT":
- main.log.warn( self.name + ": No ip given, reverting to ip from topo file" )
- ip = self.ip_address
- if port == "DEFAULT":
- main.log.warn( self.name + ": No port given, reverting to port " +
- "from topo file" )
- port = self.port
- url = "/fabrictna/slicing/tc/%d/%s" % ( slice_id, traffic_class )
- response = self.send( method=method,
- url=url, ip = ip, port = port,
- base="/onos", data = {} )
- if response:
- if "200" in str( response[ 0 ] ):
- main.log.info( self.name + ": Successfully %s " % method +
- "Slice ID: %d, Traffic Class: %s" % ( slice_id, traffic_class ) )
- return main.TRUE
- else:
- main.log.error( "Error with REST request, response was: %s: %s" %
- ( response[ 0 ], response[ 1 ] ) )
- return main.FALSE
- except NotImplementedError as e:
- raise # Inform the caller
- except ( AttributeError, TypeError ):
- main.log.exception( self.name + ": Object not as expected" )
- return None
- except Exception:
- main.log.exception( self.name + ": Uncaught exception!" )
- main.cleanAndExit()
-
def __slicingClassifierFlow( self, slice_id, traffic_class, traffic_selector,
ip="DEFAULT", port="DEFAULT", debug=False,
method="POST" ):
diff --git a/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/QOSNonMobile.params b/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/QOSNonMobile.params
index 56e859a..51c916e 100644
--- a/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/QOSNonMobile.params
+++ b/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/QOSNonMobile.params
@@ -41,20 +41,28 @@
<slice_id>1</slice_id>
<traffic_class>BEST_EFFORT</traffic_class>
<traffic_selector>
- <criteria1>
+ <ipProto>
+ <type>IP_PROTO</type>
+ <protocol>17</protocol>
+ </ipProto>
+ <udpDst>
<type>UDP_DST</type>
<udpPort>100</udpPort>
- </criteria1>
+ </udpDst>
</traffic_selector>
</slice_1_be>
<slice_1_rt>
<slice_id>1</slice_id>
<traffic_class>REAL_TIME</traffic_class>
<traffic_selector>
- <criteria1>
+ <ipProto>
+ <type>IP_PROTO</type>
+ <protocol>17</protocol>
+ </ipProto>
+ <udpDst>
<type>UDP_DST</type>
<udpPort>200</udpPort>
- </criteria1>
+ </udpDst>
</traffic_selector>
</slice_1_rt>
</traffic_classification>
diff --git a/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/dependencies/QOSNonMobileTest.py b/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/dependencies/QOSNonMobileTest.py
index faaeb04..d53b3f8 100644
--- a/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/dependencies/QOSNonMobileTest.py
+++ b/TestON/tests/USECASE/SegmentRouting/QOSNonMobile/dependencies/QOSNonMobileTest.py
@@ -70,7 +70,7 @@
flow_config = main.params["SLICING"]["traffic_classification"][
flow_name]
- traffic_selector = self.__cleanupTrafficSelector(flow_config.get("traffic_selector", []))
+ traffic_selector = self.__normalizeTrafficSelector(flow_config.get("traffic_selector"))
onos_rest.addSlicingClassifierFlow(
slice_id=int(flow_config.get("slice_id")),
traffic_class=flow_config.get("traffic_class"),
@@ -78,14 +78,14 @@
debug=True
)
- onos_flows = json.loads(onos_rest.getSlicingClassifierFlow(
+ actual_selectors = json.loads(onos_rest.getSlicingClassifierFlows(
slice_id=int(flow_config.get("slice_id")),
traffic_class=flow_config.get("traffic_class"),
debug=True
))
utilities.assert_equal(
expect=True,
- actual=traffic_selector in onos_flows,
+ actual=self.__containsTrafficSelector(actual_selectors, traffic_selector),
onpass="Classifier flow %s installed" % flow_name,
onfail="Classifier flow %s not found after insert" % flow_name
)
@@ -120,21 +120,21 @@
flow_config = main.params["SLICING"]["traffic_classification"][
flow_name]
- traffic_selector = self.__cleanupTrafficSelector(flow_config.get("traffic_selector", []))
+ traffic_selector = self.__normalizeTrafficSelector(flow_config.get("traffic_selector"))
onos_rest.removeSlicingClassifierFlow(
slice_id=int(flow_config.get("slice_id")),
traffic_class=flow_config.get("traffic_class"),
traffic_selector=traffic_selector,
debug=True
)
- onos_flow = onos_rest.getSlicingClassifierFlow(
+ actual_selectors = json.loads(onos_rest.getSlicingClassifierFlows(
slice_id=int(flow_config.get("slice_id")),
traffic_class=flow_config.get("traffic_class"),
debug=True
- )
+ ))
utilities.assert_equal(
- expect="[]",
- actual=onos_flow,
+ expect=False,
+ actual=self.__containsTrafficSelector(actual_selectors, traffic_selector),
onpass="Classifier flow %s removed from slicing service" % flow_name,
onfail="Unable to remove classifier flow %s from slicing service" % flow_name
)
@@ -145,14 +145,32 @@
trex.teardown()
run.cleanup(main)
- def __cleanupTrafficSelector(self, traffic_selector):
+ def __normalizeTrafficSelector(self, traffic_selector):
ts = {
- "criteria": [traffic_selector[criteria] for criteria in
+ "criteria": [traffic_selector[criterion] for criterion 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"])
+ # Converts the required fields into integer, required to compare them
+ # with the API result from ONOS.
+ for criterion in ts["criteria"]:
+ if "udpPort" in criterion:
+ criterion["udpPort"] = int(criterion["udpPort"])
+ elif "protocol" in criterion:
+ criterion["protocol"] = int(criterion["protocol"])
return ts
+
+ def __containsTrafficSelector(self, actual_selectors, expected_selector):
+ # actual_selectors = [{"criteria":[{"type":"IP_PROTO","protocol":17},{"type":"UDP_DST","udpPort":200}]}]
+ expected_criteria = expected_selector["criteria"]
+ for actual_selector in actual_selectors:
+ actual_criteria = actual_selector["criteria"]
+ if len(actual_criteria) != len(expected_criteria):
+ continue
+ for actual_criterion in actual_criteria:
+ # actual_criterion = {"type":"IP_PROTO","protocol":17}
+ if actual_criterion not in expected_criteria:
+ # Next selector
+ break
+ else:
+ # We found all criteria in this selector.
+ return True
+ return False