aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVratko Polak <vrpolak@cisco.com>2019-09-06 10:14:45 +0200
committerVratko Polak <vrpolak@cisco.com>2019-09-12 18:14:55 +0200
commit4fa06bcfa9ef951b9062ddfc85ce58dcb742bcf7 (patch)
tree0bf7a98cf1cbfe808c97984aefdbec58323a7c1c
parent84bbb1ef886173f8e5a2234681e135ea524c3b99 (diff)
Support unidirection in all searches
+ Rename bool unidirection to int traffic_directions. + Rename "untagged" to "initial" for bandwidth calculation. + Fix latency measurement for unidirectional traffic. + Remove duplicate colon in soak test message. + Edit PAL to accept both forms. + Fix minor documentation issues. Change-Id: I6c76f2dc090ae493f2fbd7e9ccd45229d2306dea Signed-off-by: Vratko Polak <vrpolak@cisco.com>
-rw-r--r--resources/libraries/python/TrafficGenerator.py83
-rw-r--r--resources/libraries/robot/performance/performance_utils.robot145
-rw-r--r--resources/tools/presentation/input_data_parser.py4
-rwxr-xr-xresources/tools/trex/trex_stateless_profile.py50
4 files changed, 166 insertions, 116 deletions
diff --git a/resources/libraries/python/TrafficGenerator.py b/resources/libraries/python/TrafficGenerator.py
index 2e59459773..f6020299c5 100644
--- a/resources/libraries/python/TrafficGenerator.py
+++ b/resources/libraries/python/TrafficGenerator.py
@@ -428,7 +428,7 @@ class TrafficGenerator(AbstractMeasurer):
def trex_stl_start_remote_exec(
self, duration, rate, frame_size, traffic_profile, async_call=False,
- latency=True, warmup_time=5.0, unidirection=False, tx_port=0,
+ latency=True, warmup_time=5.0, traffic_directions=2, tx_port=0,
rx_port=1):
"""Execute script on remote node over ssh to start traffic.
@@ -440,7 +440,8 @@ class TrafficGenerator(AbstractMeasurer):
:param async_call: If enabled then don't wait for all incomming trafic.
:param latency: With latency measurement.
:param warmup_time: Warmup time period.
- :param unidirection: Traffic is unidirectional. Default: False
+ :param traffic_directions: Traffic is bi- (2) or uni- (1) directional.
+ Default: 2
:param tx_port: Traffic generator transmit port for first flow.
Default: 0
:param rx_port: Traffic generator receive port for first flow.
@@ -452,7 +453,7 @@ class TrafficGenerator(AbstractMeasurer):
:type async_call: bool
:type latency: bool
:type warmup_time: float
- :type unidirection: bool
+ :type traffic_directions: int
:type tx_port: int
:type rx_port: int
:raises RuntimeError: In case of TG driver issue.
@@ -472,17 +473,16 @@ class TrafficGenerator(AbstractMeasurer):
"sh -c '{tool}/resources/tools/trex/trex_stateless_profile.py"
" --profile {prof}/resources/traffic_profiles/trex/{traffic}.py"
" --duration {duration!r} --frame_size {frame_size} --rate {rate!r}"
- " --warmup_time {warmup!r} --port_0 {p_0} --port_1 {p_1}").format(
+ " --warmup_time {warmup!r} --port_0 {p_0} --port_1 {p_1}"
+ " --traffic_directions {dirs}").format(
tool=Constants.REMOTE_FW_DIR, prof=Constants.REMOTE_FW_DIR,
traffic=traffic_profile, duration=duration,
frame_size=frame_size, rate=rate, warmup=warmup_time, p_0=p_0,
- p_1=p_1)
+ p_1=p_1, dirs=traffic_directions)
if async_call:
command += " --async"
if latency:
command += " --latency"
- if unidirection:
- command += " --unidirection"
command += "'"
stdout, _ = exec_cmd_no_error(
@@ -514,7 +514,7 @@ class TrafficGenerator(AbstractMeasurer):
def send_traffic_on_tg(
self, duration, rate, frame_size, traffic_profile, warmup_time=5,
- async_call=False, latency=True, unidirection=False, tx_port=0,
+ async_call=False, latency=True, traffic_directions=2, tx_port=0,
rx_port=1):
"""Send traffic from all configured interfaces on TG.
@@ -540,7 +540,8 @@ class TrafficGenerator(AbstractMeasurer):
:param warmup_time: Warmup phase in seconds.
:param async_call: Async mode.
:param latency: With latency measurement.
- :param unidirection: Traffic is unidirectional. Default: False
+ :param traffic_directions: Traffic is bi- (2) or uni- (1) directional.
+ Default: 2
:param tx_port: Traffic generator transmit port for first flow.
Default: 0
:param rx_port: Traffic generator receive port for first flow.
@@ -552,7 +553,7 @@ class TrafficGenerator(AbstractMeasurer):
:type warmup_time: float
:type async_call: bool
:type latency: bool
- :type unidirection: bool
+ :type traffic_directions: int
:type tx_port: int
:type rx_port: int
:returns: TG output.
@@ -565,7 +566,7 @@ class TrafficGenerator(AbstractMeasurer):
if subtype == NodeSubTypeTG.TREX:
self.trex_stl_start_remote_exec(
duration, rate, frame_size, traffic_profile, async_call,
- latency, warmup_time, unidirection, tx_port, rx_port)
+ latency, warmup_time, traffic_directions, tx_port, rx_port)
return self._result
@@ -617,20 +618,24 @@ class TrafficGenerator(AbstractMeasurer):
loss, loss_acceptance))
def set_rate_provider_defaults(self, frame_size, traffic_profile,
- warmup_time=0.0):
+ warmup_time=0.0, traffic_directions=2):
"""Store values accessed by measure().
:param frame_size: Frame size identifier or value [B].
:param traffic_profile: Module name as a traffic profile identifier.
See resources/traffic_profiles/trex for implemented modules.
:param warmup_time: Traffic duration before measurement starts [s].
+ :param traffic_directions: Traffic is bi- (2) or uni- (1) directional.
+ Default: 2
:type frame_size: str or int
:type traffic_profile: str
:type warmup_time: float
+ :type traffic_directions: int
"""
self.frame_size = frame_size
self.traffic_profile = str(traffic_profile)
self.warmup_time = float(warmup_time)
+ self.traffic_directions = traffic_directions
def get_measurement_result(self, duration=None, transmit_rate=None):
"""Return the result of last measurement as ReceiveRateMeasurement.
@@ -653,8 +658,7 @@ class TrafficGenerator(AbstractMeasurer):
duration = time.time() - self._start_time
self._start_time = None
if transmit_rate is None:
- # Assuming bi-directional traffic here.
- transmit_rate = self._rate * 2.0
+ transmit_rate = self._rate * (1.0 if self.uinidirection else 2.0)
transmit_count = int(self.get_sent())
loss_count = int(self.get_loss())
measurement = ReceiveRateMeasurement(
@@ -663,10 +667,12 @@ class TrafficGenerator(AbstractMeasurer):
return measurement
def measure(self, duration, transmit_rate):
- """Run bi-directional measurement, parse and return results.
+ """Run trial measurement, parse and return aggregate results.
+
+ Aggregate means sum over traffic directions.
:param duration: Trial duration [s].
- :param transmit_rate: Target bidirectional transmit rate [pps].
+ :param transmit_rate: Target aggregate transmit rate [pps].
:type duration: float
:type transmit_rate: float
:returns: Structure containing the result of the measurement.
@@ -678,15 +684,21 @@ class TrafficGenerator(AbstractMeasurer):
duration = float(duration)
transmit_rate = float(transmit_rate)
# TG needs target Tr per stream, but reports aggregate Tx and Dx.
- unit_rate = str(transmit_rate / 2.0) + "pps"
+ unit_rate_int = transmit_rate / float(self.traffic_directions)
+ unit_rate_str = str(unit_rate_int) + "pps"
self.send_traffic_on_tg(
- duration, unit_rate, self.frame_size, self.traffic_profile,
- warmup_time=self.warmup_time, latency=True)
+ duration, unit_rate_str, self.frame_size, self.traffic_profile,
+ warmup_time=self.warmup_time, latency=True,
+ traffic_directions=self.traffic_directions)
return self.get_measurement_result(duration, transmit_rate)
class OptimizedSearch(object):
- """Class to be imported as Robot Library, containing a single keyword."""
+ """Class to be imported as Robot Library, containing search keywords.
+
+ Aside of setting up measurer and forwarding arguments,
+ the main business is to translate min/max rate from unidir to aggregate.
+ """
@staticmethod
def perform_optimized_ndrpdr_search(
@@ -694,15 +706,15 @@ class OptimizedSearch(object):
maximum_transmit_rate, packet_loss_ratio=0.005,
final_relative_width=0.005, final_trial_duration=30.0,
initial_trial_duration=1.0, number_of_intermediate_phases=2,
- timeout=720.0, doublings=1):
+ timeout=720.0, doublings=1, traffic_directions=2):
"""Setup initialized TG, perform optimized search, return intervals.
:param frame_size: Frame size identifier or value [B].
:param traffic_profile: Module name as a traffic profile identifier.
See resources/traffic_profiles/trex for implemented modules.
- :param minimum_transmit_rate: Minimal bidirectional
+ :param minimum_transmit_rate: Minimal uni-directional
target transmit rate [pps].
- :param maximum_transmit_rate: Maximal bidirectional
+ :param maximum_transmit_rate: Maximal uni-directional
target transmit rate [pps].
:param packet_loss_ratio: Fraction of packets lost, for PDR [1].
:param final_relative_width: Final lower bound transmit rate
@@ -717,6 +729,8 @@ class OptimizedSearch(object):
:param doublings: How many doublings to do in external search step.
Default 1 is suitable for fairly stable tests,
less stable tests might get better overal duration with 2 or more.
+ :param traffic_directions: Traffic is bi- (2) or uni- (1) directional.
+ Default: 2
:type frame_size: str or int
:type traffic_profile: str
:type minimum_transmit_rate: float
@@ -728,16 +742,20 @@ class OptimizedSearch(object):
:type number_of_intermediate_phases: int
:type timeout: float
:type doublings: int
+ :type traffic_directions: int
:returns: Structure containing narrowed down NDR and PDR intervals
and their measurements.
:rtype: NdrPdrResult
:raises RuntimeError: If total duration is larger than timeout.
"""
+ minimum_transmit_rate *= traffic_directions
+ maximum_transmit_rate *= traffic_directions
# we need instance of TrafficGenerator instantiated by Robot Framework
# to be able to use trex_stl-*()
tg_instance = BuiltIn().get_library_instance(
'resources.libraries.python.TrafficGenerator')
- tg_instance.set_rate_provider_defaults(frame_size, traffic_profile)
+ tg_instance.set_rate_provider_defaults(
+ frame_size, traffic_profile, traffic_directions=traffic_directions)
algorithm = MultipleLossRatioSearch(
measurer=tg_instance, final_trial_duration=final_trial_duration,
final_relative_width=final_relative_width,
@@ -752,15 +770,16 @@ class OptimizedSearch(object):
def perform_soak_search(
frame_size, traffic_profile, minimum_transmit_rate,
maximum_transmit_rate, plr_target=1e-7, tdpt=0.1,
- initial_count=50, timeout=1800.0, trace_enabled=False):
+ initial_count=50, timeout=1800.0, trace_enabled=False,
+ traffic_directions=2):
"""Setup initialized TG, perform soak search, return avg and stdev.
:param frame_size: Frame size identifier or value [B].
:param traffic_profile: Module name as a traffic profile identifier.
See resources/traffic_profiles/trex for implemented modules.
- :param minimum_transmit_rate: Minimal bidirectional
+ :param minimum_transmit_rate: Minimal uni-directional
target transmit rate [pps].
- :param maximum_transmit_rate: Maximal bidirectional
+ :param maximum_transmit_rate: Maximal uni-directional
target transmit rate [pps].
:param plr_target: Fraction of packets lost to achieve [1].
:param tdpt: Trial duration per trial.
@@ -771,6 +790,8 @@ class OptimizedSearch(object):
This is needed because initial "search" phase of integrator
takes significant time even without any trial results.
:param timeout: The search will stop after this overall time [s].
+ :param traffic_directions: Traffic is bi- (2) or uni- (1) directional.
+ Default: 2
:type frame_size: str or int
:type traffic_profile: str
:type minimum_transmit_rate: float
@@ -778,12 +799,16 @@ class OptimizedSearch(object):
:type plr_target: float
:type initial_count: int
:type timeout: float
- :returns: Average and stdev of estimated bidirectional rate giving PLR.
+ :type traffic_directions: int
+ :returns: Average and stdev of estimated aggregate rate giving PLR.
:rtype: 2-tuple of float
"""
+ minimum_transmit_rate *= traffic_directions
+ maximum_transmit_rate *= traffic_directions
tg_instance = BuiltIn().get_library_instance(
'resources.libraries.python.TrafficGenerator')
- tg_instance.set_rate_provider_defaults(frame_size, traffic_profile)
+ tg_instance.set_rate_provider_defaults(
+ frame_size, traffic_profile, traffic_directions=traffic_directions)
algorithm = PLRsearch(
measurer=tg_instance, trial_duration_per_trial=tdpt,
packet_loss_ratio_target=plr_target,
diff --git a/resources/libraries/robot/performance/performance_utils.robot b/resources/libraries/robot/performance/performance_utils.robot
index 8ac7155605..198147be5d 100644
--- a/resources/libraries/robot/performance/performance_utils.robot
+++ b/resources/libraries/robot/performance/performance_utils.robot
@@ -36,7 +36,7 @@
| | ... | Display findings as a formatted test message.
| | ... | Fail if a resulting lower bound has too high loss fraction.
| | ... | Input rates are understood as uni-directional,
-| | ... | reported result contains bi-directional rates.
+| | ... | reported result contains aggregate rates.
| | ... | Currently, the min_rate value is hardcoded to match test teardowns.
| | ...
| | ... | TODO: Should the trial duration of the additional
@@ -59,24 +59,27 @@
| | ... | - intermediate phases - Number of intermediate phases [1]. Type: int
| | ... | - timeout - Fail if search duration is longer [s]. Type: float
| | ... | - doublings - How many doublings to do when expanding [1]. Type: int
+| | ... | - traffic_directions - Bi- (2) or uni- (1) directional traffic.
+| | ... | Type: int
| | ...
| | ... | *Example:*
| | ...
| | ... | \| Find NDR and PDR intervals using optimized search \| \${0.005} \
-| | ... | \| \${0.005} \| \${30.0} \| \${1.0} \| \${2} \| ${600.0} \| ${2} \|
+| | ... | \| \${0.005} \| \${30.0} \| \${1.0} \| \${2} \| \${600.0} \| \${2} \
+| | ... | \| \${2} \|
| | ...
| | [Arguments] | ${packet_loss_ratio}=${0.005}
| | ... | ${final_relative_width}=${0.005} | ${final_trial_duration}=${30.0}
| | ... | ${initial_trial_duration}=${1.0}
| | ... | ${number_of_intermediate_phases}=${2} | ${timeout}=${720.0}
-| | ... | ${doublings}=${2}
+| | ... | ${doublings}=${2} | ${traffic_directions}=${2}
| | ...
| | ${result} = | Perform optimized ndrpdr search | ${frame_size}
-| | ... | ${traffic_profile} | ${20000} | ${max_rate*2}
+| | ... | ${traffic_profile} | ${10000} | ${max_rate}
| | ... | ${packet_loss_ratio} | ${final_relative_width}
| | ... | ${final_trial_duration} | ${initial_trial_duration}
| | ... | ${number_of_intermediate_phases} | timeout=${timeout}
-| | ... | doublings=${doublings}
+| | ... | doublings=${doublings} | traffic_directions=${traffic_directions}
| | Display result of NDRPDR search | ${result}
| | Check NDRPDR interval validity | ${result.pdr_interval}
| | ... | ${packet_loss_ratio}
@@ -106,9 +109,8 @@
| Find Throughput Using MLRsearch
| | [Documentation]
| | ... | Find and return lower bound PDR (zero PLR by default)
-| | ... | bi-directional throughput using MLRsearch algorithm.
-| | ... | Input rates are understood as uni-directional,
-| | ... | reported result contains bi-directional rates.
+| | ... | aggregate throughput using MLRsearch algorithm.
+| | ... | Input rates are understood as uni-directional.
| | ... | Currently, the min_rate value is hardcoded to match test teardowns.
| | ...
| | ... | TODO: Should the trial duration of the additional
@@ -131,6 +133,8 @@
| | ... | - intermediate phases - Number of intermediate phases [1]. Type: int
| | ... | - timeout - Fail if search duration is longer [s]. Type: float
| | ... | - doublings - How many doublings to do when expanding [1]. Type: int
+| | ... | - traffic_directions - Bi- (2) or uni- (1) directional traffic.
+| | ... | Type: int
| | ...
| | ... | *Returns:*
| | ... | - Lower bound for bi-directional throughput at given PLR. Type: float
@@ -138,20 +142,21 @@
| | ... | *Example:*
| | ...
| | ... | \| \${throughpt}= \| Find Throughput Using MLRsearch \| \${0} \
-| | ... | \| \${0.001} \| \${10.0}\| \${1.0} \| \${1} \| ${720.0} \| ${2} \|
+| | ... | \| \${0.001} \| \${10.0}\| \${1.0} \| \${1} \| \${720.0} \| \${2} \
+| | ... | \| \${2} \|
| | ...
| | [Arguments] | ${packet_loss_ratio}=${0.0}
| | ... | ${final_relative_width}=${0.001} | ${final_trial_duration}=${10.0}
| | ... | ${initial_trial_duration}=${1.0}
| | ... | ${number_of_intermediate_phases}=${1} | ${timeout}=${720.0}
-| | ... | ${doublings}=${2}
+| | ... | ${doublings}=${2} | ${traffic_directions}=${2}
| | ...
| | ${result} = | Perform optimized ndrpdr search | ${frame_size}
-| | ... | ${traffic_profile} | ${20000} | ${max_rate*2}
+| | ... | ${traffic_profile} | ${10000} | ${max_rate}
| | ... | ${packet_loss_ratio} | ${final_relative_width}
| | ... | ${final_trial_duration} | ${initial_trial_duration}
| | ... | ${number_of_intermediate_phases} | timeout=${timeout}
-| | ... | doublings=${doublings}
+| | ... | doublings=${doublings} | traffic_directions=${traffic_directions}
| | Return From Keyword | ${result.pdr_interval.measured_low.transmit_rate}
| Find critical load using PLRsearch
@@ -161,7 +166,7 @@
| | ... | Display results as formatted test message.
| | ... | Fail if computed lower bound is below minimal rate.
| | ... | Input rates are understood as uni-directional,
-| | ... | reported result contains bi-directional rates.
+| | ... | reported result contains aggregate rates.
| | ... | Currently, the min_rate value is hardcoded to match test teardowns.
| | ... | Some inputs are read from variables to streamline suites.
| | ...
@@ -175,31 +180,36 @@
| | ... | *Arguments:*
| | ... | - packet_loss_ratio - Accepted loss during search. Type: float
| | ... | - timeout - Stop when search duration is longer [s]. Type: float
+| | ... | - traffic_directions - Bi- (2) or uni- (1) directional traffic.
+| | ... | Type: int
| | ...
| | ... | *Example:*
| | ...
-| | ... | \| Find critical load using PLR search \| \${1e-7} \| \${120} \|
+| | ... | \| Find critical load using PLR search \| \${1e-7} \| \${120} \
+| | ... | \| \${2} \|
| | ...
| | [Arguments] | ${packet_loss_ratio}=${1e-7} | ${timeout}=${1800.0}
+| | ... | ${traffic_directions}=${2}
| | ...
-| | ${min_rate} = | Set Variable | ${20000}
+| | ${min_rate} = | Set Variable | ${10000}
| | ${average} | ${stdev} = | Perform soak search | ${frame_size}
-| | ... | ${traffic_profile} | ${min_rate} | ${max_rate*2}
+| | ... | ${traffic_profile} | ${min_rate} | ${max_rate}
| | ... | ${packet_loss_ratio} | timeout=${timeout}
+| | ... | traffic_directions=${traffic_directions}
| | ${lower} | ${upper} = | Display result of soak search
| | ... | ${average} | ${stdev}
| | Should Not Be True | ${lower} < ${min_rate}
-| | ... | Lower bound ${lower} is below bidirectional minimum ${min_rate}.
+| | ... | Lower bound ${lower} is below unidirectional minimum ${min_rate}.
| Display single bound
| | [Documentation]
| | ... | Display one bound of NDR+PDR search,
| | ... | in packet per seconds (total and per stream)
-| | ... | and Gbps total bandwidth with untagged packet.
+| | ... | and Gbps total bandwidth (for initial packet size).
| | ... | Througput is calculated as:
-| | ... | Measured rate per stream * Total number of streams
+| | ... | Sum of measured rates over streams
| | ... | Bandwidth is calculated as:
-| | ... | (Throughput * (L2 Frame Size + IPG) * 8) / Max bitrate of NIC
+| | ... | (Throughput * (L2 Frame Size + IPG) * 8)
| | ... | The given result should contain latency data as well.
| | ...
| | ... | *Arguments:*
@@ -217,7 +227,7 @@
| | ...
| | ${bandwidth_total} = | Evaluate | ${rate_total} * (${frame_size}+20)*8 / 1e9
| | Set Test Message | ${\n}${text}: ${rate_total} pps, | append=yes
-| | Set Test Message | ${bandwidth_total} Gbps (untagged) | append=yes
+| | Set Test Message | ${bandwidth_total} Gbps (initial) | append=yes
| | Return From Keyword If | not """${latency}"""
| | Set Test Message | ${\n}LATENCY usec [min/avg/max] per stream: ${latency}
| | ... | append=yes
@@ -225,12 +235,12 @@
| Display result of NDRPDR search
| | [Documentation]
| | ... | Display result of NDR+PDR search, both quantities, both bounds,
-| | ... | in packet per seconds (total and per stream)
-| | ... | and Gbps total bandwidth with untagged packet.
+| | ... | aggregate in packet per seconds
+| | ... | and Gbps total bandwidth (for initial packet size).
| | ... | Througput is calculated as:
-| | ... | Measured rate per stream * Total number of streams
+| | ... | Sum of measured rate over streams
| | ... | Bandwidth is calculated as:
-| | ... | (Throughput * (L2 Frame Size + IPG) * 8) / Max bitrate of NIC
+| | ... | (Throughput * (L2 Frame Size + IPG) * 8)
| | ... | The given result should contain latency data as well.
| | ...
| | ... | *Test (or broader scope) variables read:*
@@ -259,12 +269,12 @@
| Display result of soak search
| | [Documentation]
| | ... | Display result of soak search, avg+-stdev, as upper/lower bounds,
-| | ... | in packet per seconds (total and per stream)
-| | ... | and Gbps total bandwidth with untagged packet.
+| | ... | in aggregate packets per seconds
+| | ... | and Gbps total bandwidth (for initial packet size).
| | ... | Througput is calculated as:
-| | ... | Measured rate per stream * Total number of streams
+| | ... | Sum of measured rates over streams
| | ... | Bandwidth is calculated as:
-| | ... | (Throughput * (L2 Frame Size + IPG) * 8) / Max bitrate of NIC
+| | ... | (Throughput * (L2 Frame Size + IPG) * 8)
| | ... | TODO: Do we want to report some latency data,
| | ... | even if not measured at the reported bounds?.
| | ...
@@ -288,8 +298,8 @@
| | ${stdev} = | Convert To Number | ${stdev}
| | ${lower} = | Evaluate | ${avg} - ${stdev}
| | ${upper} = | Evaluate | ${avg} + ${stdev}
-| | Display single bound | PLRsearch lower bound: | ${lower} | ${frame_size}
-| | Display single bound | PLRsearch upper bound: | ${upper} | ${frame_size}
+| | Display single bound | PLRsearch lower bound | ${lower} | ${frame_size}
+| | Display single bound | PLRsearch upper bound | ${upper} | ${frame_size}
| | Return From Keyword | ${lower} | ${upper}
| Check NDRPDR interval validity
@@ -332,18 +342,22 @@
| | ... | - result - Measured result data per stream [pps]. Type: NdrPdrResult
| | ... | - frame_size - L2 Frame Size [B] or IMIX string. Type: int or str
| | ... | - traffic_profile - Topology profile. Type: string
+| | ... | - traffic_directions - Bi- (2) or uni- (1) directional traffic.
+| | ... | Type: int
| | ...
| | ... | *Example:*
| | ... | \| Perform additional measurements based on NDRPDR result \
-| | ... | \| \${result} \| ${64} \| 3-node-IPv4 \|
+| | ... | \| \${result} \| \${64} \| 3-node-IPv4 \| \${2} \|
| | ...
| | [Arguments] | ${result} | ${framesize} | ${traffic_profile}
+| | ... | ${traffic_directions}=${2}
| | ...
-| | ${duration}= | Set Variable | 2.0
-| | ${rate_per_stream}= | Evaluate
-| | ... | ${result.ndr_interval.measured_low.target_tr} / 2.0
+| | ${duration}= | Set Variable | ${2.0}
+| | ${rate_sum}= | Set Variable | ${result.ndr_interval.measured_low.target_tr}
+| | ${rate_per_stream}= | Evaluate | ${rate_sum} / float(${traffic_directions})
| | Traffic should pass with no loss | ${duration} | ${rate_per_stream}pps
| | ... | ${framesize} | ${traffic_profile} | fail_on_loss=${False}
+| | ... | traffic_directions=${traffic_directions}
| Traffic should pass with no loss
| | [Documentation]
@@ -358,17 +372,19 @@
| | ... | Type: string
| | ... | - fail_on_loss - If True, the keyword fails if loss occurred.
| | ... | Type: boolean
+| | ... | - traffic_directions - Bi- (2) or uni- (1) directional traffic.
+| | ... | Type: int
| | ...
| | ... | *Example:*
| | ...
-| | ... | \| Traffic should pass with no loss \| 10 \| 4.0mpps \| 64 \
-| | ... | \| 3-node-IPv4 \|
+| | ... | \| Traffic should pass with no loss \| \${10} \| 4.0mpps \| \${64} \
+| | ... | \| 3-node-IPv4 \| \${2} \|
| | ...
| | [Arguments] | ${duration} | ${rate} | ${frame_size} | ${traffic_profile}
-| | ... | ${fail_on_loss}=${True}
+| | ... | ${fail_on_loss}=${True} | ${traffic_directions}=${2}
| | ...
| | Send traffic at specified rate | ${duration} | ${rate} | ${frame_size}
-| | ... | ${traffic_profile}
+| | ... | ${traffic_profile} | traffic_directions=${traffic_directions}
| | Run Keyword If | ${fail_on_loss} | No traffic loss occurred
| Traffic should pass with maximum rate
@@ -388,22 +404,23 @@
| | ... | - subsamples - How many trials in this measurement. Type: int
| | ... | - trial_duration - Duration of single trial [s]. Type: float
| | ... | - fail_no_traffic - Whether to fail on zero receive count. Type: boolean
-| | ... | - unidirection - False if traffic is bidirectional. Type: boolean
+| | ... | - traffic_directions - Bi- (2) or uni- (1) directional traffic.
+| | ... | Type: int
| | ... | - tx_port - TX port of TG, default 0. Type: integer
| | ... | - rx_port - RX port of TG, default 1. Type: integer
| | ...
| | ... | *Example:*
| | ...
-| | ... | \| Traffic should pass with maximum rate \| ${1} \| ${10.0} \
-| | ... | \| ${False} \| ${False} \| ${0} \| ${1} \|
+| | ... | \| Traffic should pass with maximum rate \| \${1} \| \${10.0} \
+| | ... | \| \${False} \| \${2} \| \${0} \| \${1} \|
| | ...
| | [Arguments] | ${trial_duration}=${PERF_TRIAL_DURATION}
| | ... | ${fail_no_traffic}=${True} | ${subsamples}=${PERF_TRIAL_MULTIPLICITY}
-| | ... | ${unidirection}=${False} | ${tx_port}=${0} | ${rx_port}=${1}
+| | ... | ${traffic_directions}=${2} | ${tx_port}=${0} | ${rx_port}=${1}
| | ...
| | ${results} = | Send traffic at specified rate | ${trial_duration}
| | ... | ${max_rate}pps | ${frame_size} | ${traffic_profile} | ${subsamples}
-| | ... | ${unidirection} | ${tx_port} | ${rx_port}
+| | ... | ${traffic_directions} | ${tx_port} | ${rx_port}
| | Set Test Message | ${\n}Maximum Receive Rate trial results
| | Set Test Message | in packets per second: ${results}
| | ... | append=yes
@@ -424,23 +441,24 @@
| | ... | - traffic_profile - Name of module defining traffc for measurements.
| | ... | Type: string
| | ... | - subsamples - How many trials in this measurement. Type: int
-| | ... | - unidirection - False if traffic is bidirectional. Type: boolean
+| | ... | - traffic_directions - Bi- (2) or uni- (1) directional traffic.
+| | ... | Type: int
| | ... | - tx_port - TX port of TG, default 0. Type: integer
| | ... | - rx_port - RX port of TG, default 1. Type: integer
| | ... | - pkt_trace - True to enable packet trace. Type: boolean
| | ...
| | ... | *Example:*
| | ...
-| | ... | \| Send traffic at specified rate \| ${1.0} \| 4.0mpps \| 64 \
-| | ... | \| 3-node-IPv4 \| ${10} \| ${False} \| ${0} | ${1} \| ${False}
+| | ... | \| Send traffic at specified rate \| \${1.0} \| 4.0mpps \| \${64} \
+| | ... | \| 3-node-IPv4 \| \${10} \| \${2} \| \${0} | \${1} \| \${False}
| | ...
| | [Arguments] | ${trial_duration} | ${rate} | ${frame_size}
-| | ... | ${traffic_profile} | ${subsamples}=${1} | ${unidirection}=${False}
+| | ... | ${traffic_profile} | ${subsamples}=${1} | ${traffic_directions}=${2}
| | ... | ${tx_port}=${0} | ${rx_port}=${1} | ${pkt_trace}=${False}
| | ...
| | Clear and show runtime counters with running traffic | ${trial_duration}
| | ... | ${rate} | ${frame_size} | ${traffic_profile}
-| | ... | ${unidirection} | ${tx_port} | ${rx_port}
+| | ... | ${traffic_directions} | ${tx_port} | ${rx_port}
| | Run Keyword If | ${dut_stats}==${True}
| | ... | Clear statistics on all DUTs | ${nodes}
| | Run Keyword If | ${dut_stats}==${True} and ${pkt_trace}==${True}
@@ -452,8 +470,9 @@
| | | # The following line is skipping some default arguments,
| | | # that is why subsequent arguments have to be named.
| | | Send traffic on tg | ${trial_duration} | ${rate} | ${frame_size}
-| | | ... | ${traffic_profile} | warmup_time=${0} | unidirection=${unidirection}
-| | | ... | tx_port=${tx_port} | rx_port=${rx_port}
+| | | ... | ${traffic_profile} | warmup_time=${0}
+| | | ... | traffic_directions=${traffic_directions} | tx_port=${tx_port}
+| | | ... | rx_port=${rx_port}
| | | ${rx} = | Get Received
| | | ${rr} = | Evaluate | ${rx} / ${trial_duration}
| | | Append To List | ${results} | ${rr}
@@ -477,22 +496,24 @@
| | ... | - frame_size - L2 Frame Size [B] or IMIX_v4_1. Type: integer/string
| | ... | - traffic_profile - Name of module defining traffc for measurements.
| | ... | Type: string
-| | ... | - unidirection - False if traffic is bidirectional. Type: boolean
+| | ... | - traffic_directions - Bi- (2) or uni- (1) directional traffic.
+| | ... | Type: int
| | ... | - tx_port - TX port of TG, default 0. Type: integer
| | ... | - rx_port - RX port of TG, default 1. Type: integer
| | ...
| | ... | *Example:*
| | ...
-| | ... | \| Clear and show runtime counters with running traffic \| 10 \
-| | ... | \| 4.0mpps \| 64 \| 3-node-IPv4 \| ${False} \| ${0} | ${1} \|
+| | ... | \| Clear and show runtime counters with running traffic \| \${10} \
+| | ... | \| 4.0mpps \| \${64} \| 3-node-IPv4 \| \${2} \| \${0} \| \${1} \|
| | ...
| | [Arguments] | ${duration} | ${rate} | ${frame_size} | ${traffic_profile}
-| | ... | ${unidirection}=${False} | ${tx_port}=${0} | ${rx_port}=${1}
+| | ... | ${traffic_directions}=${2} | ${tx_port}=${0} | ${rx_port}=${1}
| | ...
| | # Duration of -1 means we will stop traffic manually.
| | Send traffic on tg | ${-1} | ${rate} | ${frame_size} | ${traffic_profile}
| | ... | warmup_time=${0} | async_call=${True} | latency=${False}
-| | ... | unidirection=${unidirection} | tx_port=${tx_port} | rx_port=${rx_port}
+| | ... | traffic_directions=${traffic_directions} | tx_port=${tx_port}
+| | ... | rx_port=${rx_port}
| | Run Keyword If | ${dut_stats}==${True}
| | ... | VPP clear runtime counters on all DUTs | ${nodes}
| | Sleep | ${duration}
@@ -514,22 +535,24 @@
| | ... | - frame_size - L2 Frame Size [B] or IMIX string. Type: int or str
| | ... | *Arguments:*
| | ... | - rate - Unidirectional rate for sending packets. Type: string
-| | ... | - unidirection - False if traffic is bidirectional. Type: boolean
+| | ... | - traffic_directions - Bi- (2) or uni- (1) directional traffic.
+| | ... | Type: int
| | ... | - tx_port - TX port of TG, default 0. Type: integer
| | ... | - rx_port - RX port of TG, default 1. Type: integer
| | ...
| | ... | *Example:*
| | ...
-| | ... | \| Start Traffic on Background \| 4.0mpps \| ${False} \| ${0} \
-| | ... | \| ${1} \|
+| | ... | \| Start Traffic on Background \| 4.0mpps \| \${2} \| \${0} \
+| | ... | \| \${1} \|
| | ...
-| | [Arguments] | ${rate} | ${unidirection}=${False} | ${tx_port}=${0}
+| | [Arguments] | ${rate} | ${traffic_directions}=${2} | ${tx_port}=${0}
| | ... | ${rx_port}=${1}
| | ...
| | # Duration of -1 means we will stop traffic manually.
| | Send traffic on tg | ${-1} | ${rate} | ${frame_size} | ${traffic_profile}
| | ... | warmup_time=${0} | async_call=${True} | latency=${False}
-| | ... | unidirection=${unidirection} | tx_port=${tx_port} | rx_port=${rx_port}
+| | ... | traffic_directions=${traffic_directions} | tx_port=${tx_port}
+| | ... | rx_port=${rx_port}
| Stop Running Traffic
| | [Documentation]
diff --git a/resources/tools/presentation/input_data_parser.py b/resources/tools/presentation/input_data_parser.py
index 24a24f669f..670cb3248a 100644
--- a/resources/tools/presentation/input_data_parser.py
+++ b/resources/tools/presentation/input_data_parser.py
@@ -251,8 +251,8 @@ class ExecutionChecker(ResultVisitor):
# TODO: Remove when definitely no NDRPDRDISC tests are used:
REGEX_RATE = re.compile(r'^[\D\d]*FINAL_RATE:\s(\d+\.\d+)\s(\w+)')
- REGEX_PLR_RATE = re.compile(r'PLRsearch lower bound::\s(\d+.\d+).*\n'
- r'PLRsearch upper bound::\s(\d+.\d+)')
+ REGEX_PLR_RATE = re.compile(r'PLRsearch lower bound::?\s(\d+.\d+).*\n'
+ r'PLRsearch upper bound::?\s(\d+.\d+)')
REGEX_NDRPDR_RATE = re.compile(r'NDR_LOWER:\s(\d+.\d+).*\n.*\n'
r'NDR_UPPER:\s(\d+.\d+).*\n'
diff --git a/resources/tools/trex/trex_stateless_profile.py b/resources/tools/trex/trex_stateless_profile.py
index b8ee77c69a..2837778f7a 100755
--- a/resources/tools/trex/trex_stateless_profile.py
+++ b/resources/tools/trex/trex_stateless_profile.py
@@ -56,7 +56,7 @@ def fmt_latency(lat_min, lat_avg, lat_max):
def simple_burst(profile_file, duration, framesize, rate, warmup_time, port_0,
- port_1, latency, async_start=False, unidirection=False):
+ port_1, latency, async_start=False, traffic_directions=2):
"""Send traffic and measure packet loss and latency.
Procedure:
@@ -83,7 +83,7 @@ def simple_burst(profile_file, duration, framesize, rate, warmup_time, port_0,
:param port_1: Port 1 on the traffic generator.
:param latency: With latency stats.
:param async_start: Start the traffic and exit.
- :param unidirection: Traffic is unidirectional.
+ :param traffic_directions: Bidirectional (2) or unidirectional (1) traffic.
:type profile_file: str
:type framesize: int or str
:type duration: float
@@ -93,7 +93,7 @@ def simple_burst(profile_file, duration, framesize, rate, warmup_time, port_0,
:type port_1: int
:type latency: bool
:type async_start: bool
- :type unidirection: bool
+ :type traffic_directions: int
"""
client = None
total_rcvd = 0
@@ -126,17 +126,17 @@ def simple_burst(profile_file, duration, framesize, rate, warmup_time, port_0,
client.set_port_attr(ports=[port_0, port_1], promiscuous=True)
if isinstance(framesize, int):
client.add_streams(streams[0], ports=[port_0])
- if not unidirection:
+ if traffic_directions > 1:
client.add_streams(streams[1], ports=[port_1])
elif isinstance(framesize, str):
client.add_streams(streams[0:3], ports=[port_0])
- if not unidirection:
+ if traffic_directions > 1:
client.add_streams(streams[3:6], ports=[port_1])
if latency:
try:
if isinstance(framesize, int):
client.add_streams(streams[2], ports=[port_0])
- if not unidirection:
+ if traffic_directions > 1:
client.add_streams(streams[3], ports=[port_1])
elif isinstance(framesize, str):
latency = False
@@ -145,7 +145,7 @@ def simple_burst(profile_file, duration, framesize, rate, warmup_time, port_0,
print("##### FAILED to add latency streams #####")
latency = False
ports = [port_0]
- if not unidirection:
+ if traffic_directions > 1:
ports.append(port_1)
# Warm-up phase:
if warmup_time > 0:
@@ -169,12 +169,12 @@ def simple_burst(profile_file, duration, framesize, rate, warmup_time, port_0,
print(json.dumps(stats, indent=4, separators=(',', ': ')))
lost_a = stats[port_0]["opackets"] - stats[port_1]["ipackets"]
- if not unidirection:
+ if traffic_directions > 1:
lost_b = stats[port_1]["opackets"] - stats[port_0]["ipackets"]
print("\npackets lost from {p_0} --> {p_1}: {v} pkts".format(
p_0=port_0, p_1=port_1, v=lost_a))
- if not unidirection:
+ if traffic_directions > 1:
print("packets lost from {p_1} --> {p_0}: {v} pkts".format(
p_0=port_0, p_1=port_1, v=lost_b))
@@ -201,21 +201,23 @@ def simple_burst(profile_file, duration, framesize, rate, warmup_time, port_0,
print(json.dumps(stats, indent=4, separators=(',', ': ')))
lost_a = stats[port_0]["opackets"] - stats[port_1]["ipackets"]
- if not unidirection:
+ if traffic_directions > 1:
lost_b = stats[port_1]["opackets"] - stats[port_0]["ipackets"]
+ # Stats index is not a port number, but "pgid".
+ # TODO: Find out what "pgid" means.
if latency:
lat_a = fmt_latency(
- str(stats["latency"][port_0]["latency"]["total_min"]),
- str(stats["latency"][port_0]["latency"]["average"]),
- str(stats["latency"][port_0]["latency"]["total_max"]))
- if not unidirection:
+ str(stats["latency"][0]["latency"]["total_min"]),
+ str(stats["latency"][0]["latency"]["average"]),
+ str(stats["latency"][0]["latency"]["total_max"]))
+ if traffic_directions > 1:
lat_b = fmt_latency(
- str(stats["latency"][port_1]["latency"]["total_min"]),
- str(stats["latency"][port_1]["latency"]["average"]),
- str(stats["latency"][port_1]["latency"]["total_max"]))
+ str(stats["latency"][1]["latency"]["total_min"]),
+ str(stats["latency"][1]["latency"]["average"]),
+ str(stats["latency"][1]["latency"]["total_max"]))
- if not unidirection:
+ if traffic_directions > 1:
total_sent = stats[0]["opackets"] + stats[1]["opackets"]
total_rcvd = stats[0]["ipackets"] + stats[1]["ipackets"]
else:
@@ -224,7 +226,7 @@ def simple_burst(profile_file, duration, framesize, rate, warmup_time, port_0,
print("\npackets lost from {p_0} --> {p_1}: {v} pkts".format(
p_0=port_0, p_1=port_1, v=lost_a))
- if not unidirection:
+ if traffic_directions > 1:
print("packets lost from {p_1} --> {p_0}: {v} pkts".format(
p_0=port_0, p_1=port_1, v=lost_b))
@@ -287,10 +289,10 @@ def main():
action="store_true",
default=False,
help="Add latency stream.")
- parser.add_argument("--unidirection",
- action="store_true",
- default=False,
- help="Send unidirection traffic.")
+ parser.add_argument("--traffic_directions",
+ type=int,
+ default=2,
+ help="Send bi- (2) or uni- (1) directional traffic.")
args = parser.parse_args()
@@ -308,7 +310,7 @@ def main():
port_1=args.port_1,
latency=args.latency,
async_start=args.async,
- unidirection=args.unidirection)
+ traffic_directions=args.traffic_directions)
if __name__ == '__main__':