From 490256818796108eb9fc169fc477517c490c5d6a Mon Sep 17 00:00:00 2001 From: Miroslav Miklus Date: Wed, 14 Sep 2016 14:51:33 +0200 Subject: [PATCH] CSIT-408 sub-NDR latency measurements - measure latency at 10% and 50% of found NDR. - fix the accuracy reported by T-REX (round to usec) Change-Id: I9fe2b5f942cb816db6fd0bb4262b48b8da6dac2f Signed-off-by: Miroslav Miklus --- resources/libraries/python/DropRateSearch.py | 11 +++- resources/libraries/python/TrafficGenerator.py | 31 +++++++++--- resources/libraries/robot/performance.robot | 70 +++++++++++++++++++++++--- resources/tools/t-rex/t-rex-stateless.py | 4 +- 4 files changed, 99 insertions(+), 17 deletions(-) diff --git a/resources/libraries/python/DropRateSearch.py b/resources/libraries/python/DropRateSearch.py index b0f15b25db..6346125592 100644 --- a/resources/libraries/python/DropRateSearch.py +++ b/resources/libraries/python/DropRateSearch.py @@ -98,6 +98,15 @@ class DropRateSearch(object): self._search_result = None self._search_result_rate = None + @abstractmethod + def get_latency(self): + """Return min/avg/max latency. + + :return: Latency stats. + :rtype: list + """ + pass + @abstractmethod def measure_loss(self, rate, frame_size, loss_acceptance, loss_acceptance_type, traffic_type): @@ -460,7 +469,7 @@ class DropRateSearch(object): raise Exception('Search FAILED') elif self._search_result in [SearchResults.SUCCESS, SearchResults.SUSPICIOUS]: - return self._search_result_rate, self._latency_stats + return self._search_result_rate, self.get_latency() def binary_search(self, b_min, b_max, traffic_type, skip_max_rate=False): """Binary search of rate with loss below acceptance criteria. diff --git a/resources/libraries/python/TrafficGenerator.py b/resources/libraries/python/TrafficGenerator.py index 0388179876..2a94912860 100644 --- a/resources/libraries/python/TrafficGenerator.py +++ b/resources/libraries/python/TrafficGenerator.py @@ -47,9 +47,6 @@ class TGDropRateSearchImpl(DropRateSearch): tg_instance.trex_stl_start_remote_exec(self.get_duration(), unit_rate, frame_size, traffic_type) - # Get latency stats from stream - self._latency_stats = tg_instance.get_latency() - loss = tg_instance.get_loss() sent = tg_instance.get_sent() if self.loss_acceptance_type_is_percentage(): @@ -66,6 +63,16 @@ class TGDropRateSearchImpl(DropRateSearch): else: raise NotImplementedError("TG subtype not supported") + def get_latency(self): + """Return min/avg/max latency. + + :return: Latency stats. + :rtype: list + """ + + tg_instance = BuiltIn().get_library_instance( + 'resources.libraries.python.TrafficGenerator') + return tg_instance.get_latency_int() class TrafficGenerator(object): """Traffic Generator.""" @@ -107,8 +114,8 @@ class TrafficGenerator(object): """ return self._received - def get_latency(self): - """Return min/avg/max latency. + def get_latency_int(self): + """Return rounded min/avg/max latency. :return: Latency stats. :rtype: list @@ -476,9 +483,19 @@ class TrafficGenerator(object): self._received = self._result.split(', ')[1].split('=')[1] self._sent = self._result.split(', ')[2].split('=')[1] self._loss = self._result.split(', ')[3].split('=')[1] + self._latency = [] - self._latency.append(self._result.split(', ')[4].split('=')[1]) - self._latency.append(self._result.split(', ')[5].split('=')[1]) + lat_int_list = [] + #round latency numbers + lat_str = self._result.split(', ')[4].split('=')[1] + for lat in lat_str.split("/"): + lat_int_list.append(int(float(lat))) + self._latency.append("/".join(str(tmp) for tmp in lat_int_list)) + lat_int_list = [] + lat_str = self._result.split(', ')[5].split('=')[1] + for lat in lat_str.split("/"): + lat_int_list.append(int(float(lat))) + self._latency.append("/".join(str(tmp) for tmp in lat_int_list)) def stop_traffic_on_tg(self): """Stop all traffic on TG diff --git a/resources/libraries/robot/performance.robot b/resources/libraries/robot/performance.robot index c33905bc9a..ce4433c9cc 100644 --- a/resources/libraries/robot/performance.robot +++ b/resources/libraries/robot/performance.robot @@ -909,7 +909,19 @@ | | Set Search Frame Size | ${framesize} | | Set Search Rate Type pps | | Linear Search | ${start_rate} | ${topology_type} -| | ${rate_per_stream} | ${latency}= | Verify Search Result +| | ${rate_per_stream} | ${lat}= | Verify Search Result +| | ${tmp}= | Create List | 100%NDR | ${lat} +| | ${latency}= | Create List | ${tmp} +| | ${rate_50p}= | Evaluate | int(${rate_per_stream}*0.5) +| | ${lat_50p}= | Measure latency | ${duration} | ${rate_50p}pps +| | ... | ${framesize} | ${topology_type} +| | ${tmp}= | Create List | 50%NDR | ${lat_50p} +| | Append To List | ${latency} | ${tmp} +| | ${rate_10p}= | Evaluate | int(${rate_per_stream}*0.1) +| | ${lat_10p}= | Measure latency | ${duration} | ${rate_10p}pps +| | ... | ${framesize} | ${topology_type} +| | ${tmp}= | Create List | 10%NDR | ${lat_10p} +| | Append To List | ${latency} | ${tmp} | | Display result of NDR search | ${rate_per_stream} | ${framesize} | 2 | | ... | ${latency} | | Traffic should pass with no loss | ${duration} | ${rate_per_stream}pps @@ -984,7 +996,19 @@ | | Set Search Rate Type pps | | Set Binary Convergence Threshold | ${threshold} | | Binary Search | ${binary_min} | ${binary_max} | ${topology_type} -| | ${rate_per_stream} | ${latency}= | Verify Search Result +| | ${rate_per_stream} | ${lat}= | Verify Search Result +| | ${tmp}= | Create List | 100%NDR | ${lat} +| | ${latency}= | Create List | ${tmp} +| | ${rate_50p}= | Evaluate | int(${rate_per_stream}*0.5) +| | ${lat_50p}= | Measure latency | ${duration} | ${rate_50p}pps +| | ... | ${framesize} | ${topology_type} +| | ${tmp}= | Create List | 50%NDR | ${lat_50p} +| | Append To List | ${latency} | ${tmp} +| | ${rate_10p}= | Evaluate | int(${rate_per_stream}*0.1) +| | ${lat_10p}= | Measure latency | ${duration} | ${rate_10p}pps +| | ... | ${framesize} | ${topology_type} +| | ${tmp}= | Create List | 10%NDR | ${lat_10p} +| | Append To List | ${latency} | ${tmp} | | Display result of NDR search | ${rate_per_stream} | ${framesize} | 2 | | ... | ${latency} | | Traffic should pass with no loss | ${duration} | ${rate_per_stream}pps @@ -1063,7 +1087,19 @@ | | Set Search Rate Type pps | | Set Binary Convergence Threshold | ${threshold} | | Combined Search | ${start_rate} | ${topology_type} -| | ${rate_per_stream} | ${latency}= | Verify Search Result +| | ${rate_per_stream} | ${lat}= | Verify Search Result +| | ${tmp}= | Create List | 100%NDR | ${lat} +| | ${latency}= | Create List | ${tmp} +| | ${rate_50p}= | Evaluate | int(${rate_per_stream}*0.5) +| | ${lat_50p}= | Measure latency | ${duration} | ${rate_50p}pps +| | ... | ${framesize} | ${topology_type} +| | ${tmp}= | Create List | 50%NDR | ${lat_50p} +| | Append To List | ${latency} | ${tmp} +| | ${rate_10p}= | Evaluate | int(${rate_per_stream}*0.1) +| | ${lat_10p}= | Measure latency | ${duration} | ${rate_10p}pps +| | ... | ${framesize} | ${topology_type} +| | ${tmp}= | Create List | 10%NDR | ${lat_10p} +| | Append To List | ${latency} | ${tmp} | | Display result of NDR search | ${rate_per_stream} | ${framesize} | 2 | | ... | ${latency} | | Traffic should pass with no loss | ${duration} | ${rate_per_stream}pps @@ -1133,7 +1169,7 @@ | | ... | *Example:* | | ... | | ... | \| Display result of NDR search \| 4400000 \| 64 \| 2 \ -| | ... | \| (0, 10/10/10) \| +| | ... | \| [100%NDR, [10/10/10, 1/2/3]] \| | | [Arguments] | ${rate_per_stream} | ${framesize} | ${nr_streams} | | ... | ${latency} | | ${framesize}= | Get Frame Size | ${framesize} @@ -1144,9 +1180,9 @@ | | ... | append=yes | | Set Test Message | ${\n}FINAL_BANDWIDTH: ${bandwidth_total} Gbps (untagged) | | ... | append=yes -| | :FOR | ${idx} | ${lat} | IN ENUMERATE | @{latency} -| | | Set Test Message | ${\n}LATENCY_STREAM_${idx}: ${lat} usec (min/avg/max) -| | ... | append=yes +| | Set Test Message | ${\n}LATENCY usec [min/avg/max] | append=yes +| | :FOR | ${lat} | IN | @{latency} +| | | Set Test Message | ${\n}LAT_${lat[0]}: ${lat[1]} | append=yes | Display result of PDR search | | [Documentation] @@ -1185,6 +1221,26 @@ | | Set Test Message | ${\n}LOSS_ACCEPTANCE: ${loss_acceptance} ${loss_acceptance_type} | | ... | append=yes +| Measure latency +| | [Documentation] +| | ... | Send traffic at specified rate. Measure min/avg/max latency +| | ... +| | ... | *Arguments:* +| | ... | - duration - Duration of traffic run [s]. Type: integer +| | ... | - rate - Rate for sending packets. Type: string +| | ... | - framesize - L2 Frame Size [B]. Type: integer +| | ... | - topology_type - Topology type. Type: string +| | ... +| | ... | *Example:* +| | ... +| | ... | \| Measure latency \| 10 \| 4.0mpps \| 64 \| 3-node-IPv4 +| | [Arguments] | ${duration} | ${rate} | ${framesize} | ${topology_type} +| | Clear all counters on all DUTs +| | Send traffic on tg | ${duration} | ${rate} | ${framesize} +| | ... | ${topology_type} | warmup_time=0 +| | Show statistics on all DUTs +| | Run keyword and return | Get latency + | Traffic should pass with no loss | | [Documentation] | | ... | Send traffic at specified rate. No packet loss is accepted at loss diff --git a/resources/tools/t-rex/t-rex-stateless.py b/resources/tools/t-rex/t-rex-stateless.py index 8a7f34b27a..95c6cb150a 100755 --- a/resources/tools/t-rex/t-rex-stateless.py +++ b/resources/tools/t-rex/t-rex-stateless.py @@ -347,8 +347,8 @@ def simple_burst(stream_a, stream_b, stream_lat_a, stream_lat_b, duration, rate, total_sent = 0 lost_a = 0 lost_b = 0 - lat_a = 'NA' - lat_b = 'NA' + lat_a = "0/0/0" + lat_b = "0/0/0" try: # turn this off if too many logs -- 2.16.6