diff options
Diffstat (limited to 'scripts/automation/trex_control_plane/stf')
-rwxr-xr-x | scripts/automation/trex_control_plane/stf/examples/stf_example.py | 54 | ||||
-rwxr-xr-x | scripts/automation/trex_control_plane/stf/examples/stf_path.py | 4 | ||||
-rwxr-xr-x | scripts/automation/trex_control_plane/stf/trex_stf_lib/CCustomLogger.py (renamed from scripts/automation/trex_control_plane/stf/CCustomLogger.py) | 0 | ||||
-rwxr-xr-x | scripts/automation/trex_control_plane/stf/trex_stf_lib/__init__.py (renamed from scripts/automation/trex_control_plane/stf/__init__.py) | 0 | ||||
-rwxr-xr-x | scripts/automation/trex_control_plane/stf/trex_stf_lib/external_packages.py (renamed from scripts/automation/trex_control_plane/stf/external_packages.py) | 0 | ||||
-rwxr-xr-x | scripts/automation/trex_control_plane/stf/trex_stf_lib/general_utils.py (renamed from scripts/automation/trex_control_plane/stf/general_utils.py) | 0 | ||||
-rwxr-xr-x | scripts/automation/trex_control_plane/stf/trex_stf_lib/outer_packages.py (renamed from scripts/automation/trex_control_plane/stf/outer_packages.py) | 10 | ||||
-rwxr-xr-x | scripts/automation/trex_control_plane/stf/trex_stf_lib/text_opts.py (renamed from scripts/automation/trex_control_plane/stf/text_opts.py) | 0 | ||||
-rwxr-xr-x | scripts/automation/trex_control_plane/stf/trex_stf_lib/trex_client.py (renamed from scripts/automation/trex_control_plane/stf/trex_client.py) | 62 | ||||
-rwxr-xr-x | scripts/automation/trex_control_plane/stf/trex_stf_lib/trex_daemon_server.py (renamed from scripts/automation/trex_control_plane/stf/trex_daemon_server.py) | 0 | ||||
-rwxr-xr-x | scripts/automation/trex_control_plane/stf/trex_stf_lib/trex_exceptions.py (renamed from scripts/automation/trex_control_plane/stf/trex_exceptions.py) | 0 | ||||
-rw-r--r-- | scripts/automation/trex_control_plane/stf/trex_stf_lib/trex_status.py (renamed from scripts/automation/trex_control_plane/stf/trex_status.py) | 0 | ||||
-rwxr-xr-x | scripts/automation/trex_control_plane/stf/trex_stf_lib/trex_status_e.py (renamed from scripts/automation/trex_control_plane/stf/trex_status_e.py) | 0 |
13 files changed, 107 insertions, 23 deletions
diff --git a/scripts/automation/trex_control_plane/stf/examples/stf_example.py b/scripts/automation/trex_control_plane/stf/examples/stf_example.py new file mode 100755 index 00000000..f57435bf --- /dev/null +++ b/scripts/automation/trex_control_plane/stf/examples/stf_example.py @@ -0,0 +1,54 @@ +import argparse +import stf_path +from trex_stf_lib.trex_client import CTRexClient +from pprint import pprint + +# sample TRex stateful run +# assuming server daemon is running. + +def minimal_stateful_test(server): + print('Connecting to %s' % server) + trex_client = CTRexClient(server) + + print('Connected, start TRex') + trex_client.start_trex( + c = 1, + m = 700, + f = 'cap2/http_simple.yaml', + d = 30, + l = 1000, + ) + + print('Sample until end') + result = trex_client.sample_to_run_finish() + + print('Test results:') + print(result) + + print('TX by ports:') + tx_ptks_dict = result.get_last_value('trex-global.data', 'opackets-*') + print(' | '.join(['%s: %s' % (k.split('-')[-1], tx_ptks_dict[k]) for k in sorted(tx_ptks_dict.keys())])) + + print('RX by ports:') + rx_ptks_dict = result.get_last_value('trex-global.data', 'ipackets-*') + print(' | '.join(['%s: %s' % (k.split('-')[-1], rx_ptks_dict[k]) for k in sorted(rx_ptks_dict.keys())])) + + print('CPU utilization:') + print(result.get_value_list('trex-global.data.m_cpu_util')) + + #Dump of *latest* result sample, uncomment to see it all + #print('Latest result dump:') + #pprint(result.get_latest_dump()) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description="Example for TRex Stateful, assuming server daemon is running.") + parser.add_argument('-s', '--server', + dest='server', + help='Remote trex address', + default='127.0.0.1', + type = str) + args = parser.parse_args() + + minimal_stateful_test(args.server) + diff --git a/scripts/automation/trex_control_plane/stf/examples/stf_path.py b/scripts/automation/trex_control_plane/stf/examples/stf_path.py new file mode 100755 index 00000000..bb401148 --- /dev/null +++ b/scripts/automation/trex_control_plane/stf/examples/stf_path.py @@ -0,0 +1,4 @@ +import sys + +# FIXME to the write path for trex_stf_lib +sys.path.insert(0, "../") diff --git a/scripts/automation/trex_control_plane/stf/CCustomLogger.py b/scripts/automation/trex_control_plane/stf/trex_stf_lib/CCustomLogger.py index ecf7d519..ecf7d519 100755 --- a/scripts/automation/trex_control_plane/stf/CCustomLogger.py +++ b/scripts/automation/trex_control_plane/stf/trex_stf_lib/CCustomLogger.py diff --git a/scripts/automation/trex_control_plane/stf/__init__.py b/scripts/automation/trex_control_plane/stf/trex_stf_lib/__init__.py index 5a1da046..5a1da046 100755 --- a/scripts/automation/trex_control_plane/stf/__init__.py +++ b/scripts/automation/trex_control_plane/stf/trex_stf_lib/__init__.py diff --git a/scripts/automation/trex_control_plane/stf/external_packages.py b/scripts/automation/trex_control_plane/stf/trex_stf_lib/external_packages.py index 7353c397..7353c397 100755 --- a/scripts/automation/trex_control_plane/stf/external_packages.py +++ b/scripts/automation/trex_control_plane/stf/trex_stf_lib/external_packages.py diff --git a/scripts/automation/trex_control_plane/stf/general_utils.py b/scripts/automation/trex_control_plane/stf/trex_stf_lib/general_utils.py index d2521f02..d2521f02 100755 --- a/scripts/automation/trex_control_plane/stf/general_utils.py +++ b/scripts/automation/trex_control_plane/stf/trex_stf_lib/general_utils.py diff --git a/scripts/automation/trex_control_plane/stf/outer_packages.py b/scripts/automation/trex_control_plane/stf/trex_stf_lib/outer_packages.py index 5e29f8d6..f8d50ce6 100755 --- a/scripts/automation/trex_control_plane/stf/outer_packages.py +++ b/scripts/automation/trex_control_plane/stf/trex_stf_lib/outer_packages.py @@ -5,8 +5,8 @@ import os CURRENT_PATH = os.path.dirname(os.path.realpath(__file__)) -PARENT_PATH = os.path.abspath(os.path.join(CURRENT_PATH, os.pardir, 'external_libs')) -SCRIPTS_PATH = os.path.abspath(os.path.join(CURRENT_PATH, os.pardir, os.pardir, os.pardir, 'external_libs')) +PACKAGE_PATH = os.path.abspath(os.path.join(CURRENT_PATH, os.pardir, os.pardir, 'external_libs')) +SCRIPTS_PATH = os.path.abspath(os.path.join(CURRENT_PATH, os.pardir, os.pardir, os.pardir, os.pardir, 'external_libs')) CLIENT_MODULES = ['enum34-1.0.4', 'jsonrpclib-pelix-0.2.5', @@ -22,9 +22,9 @@ def import_module_list(ext_libs_path): raise Exception('Library %s is absent in path %s' % (p, ext_libs_path)) sys.path.insert(1, full_path) -if os.path.exists(PARENT_PATH): - import_module_list(PARENT_PATH) +if os.path.exists(PACKAGE_PATH): + import_module_list(PACKAGE_PATH) elif os.path.exists(SCRIPTS_PATH): import_module_list(SCRIPTS_PATH) else: - raise Exception('Could not find external libs in path: %s' % [PARENT_PATH, SCRIPTS_PATH]) + raise Exception('Could not find external libs in path: %s' % [PACKAGE_PATH, SCRIPTS_PATH]) diff --git a/scripts/automation/trex_control_plane/stf/text_opts.py b/scripts/automation/trex_control_plane/stf/trex_stf_lib/text_opts.py index 78a0ab1f..78a0ab1f 100755 --- a/scripts/automation/trex_control_plane/stf/text_opts.py +++ b/scripts/automation/trex_control_plane/stf/trex_stf_lib/text_opts.py diff --git a/scripts/automation/trex_control_plane/stf/trex_client.py b/scripts/automation/trex_control_plane/stf/trex_stf_lib/trex_client.py index 919253d1..074d9060 100755 --- a/scripts/automation/trex_control_plane/stf/trex_client.py +++ b/scripts/automation/trex_control_plane/stf/trex_stf_lib/trex_client.py @@ -39,7 +39,7 @@ class CTRexClient(object): This class defines the client side of the RESTfull interaction with TRex """ - def __init__(self, trex_host, max_history_size = 100, trex_daemon_port = 8090, trex_zmq_port = 4500, verbose = False): + def __init__(self, trex_host, max_history_size = 100, filtered_latency_amount = 0.001, trex_daemon_port = 8090, trex_zmq_port = 4500, verbose = False): """ Instantiate a TRex client object, and connecting it to listening daemon-server @@ -50,6 +50,12 @@ class CTRexClient(object): a number to set the maximum history size of a single TRex run. Each sampling adds a new item to history. default value : **100** + + filtered_latency_amount : float + Ignore high latency for this ammount of packets. (by default take value of 99.9% measurements) + + default value : **0.001** + trex_daemon_port : int the port number on which the trex-daemon server can be reached @@ -75,7 +81,7 @@ class CTRexClient(object): self.trex_zmq_port = trex_zmq_port self.seq = None self.verbose = verbose - self.result_obj = CTRexResult(max_history_size) + self.result_obj = CTRexResult(max_history_size, filtered_latency_amount) self.decoder = JSONDecoder() self.trex_server_path = "http://{hostname}:{port}/".format( hostname = self.trex_host, port = trex_daemon_port ) self.__verbose_print("Connecting to TRex @ {trex_path} ...".format( trex_path = self.trex_server_path ) ) @@ -834,22 +840,25 @@ class CTRexResult(object): Ontop to containing the results, this class offers easier data access and extended results processing options """ - def __init__(self, max_history_size): + def __init__(self, max_history_size, filtered_latency_amount = 0.001): """ Instatiate a TRex result object :parameters: max_history_size : int - a number to set the maximum history size of a single TRex run. Each sampling adds a new item to history. + A number to set the maximum history size of a single TRex run. Each sampling adds a new item to history. + filtered_latency_amount : float + Ignore high latency for this ammount of packets. (by default take into account 99.9%) """ self._history = deque(maxlen = max_history_size) self.clear_results() self.latency_checked = True + self.filtered_latency_amount = filtered_latency_amount def __repr__(self): return ("Is valid history? {arg}\n".format( arg = self.is_valid_hist() ) + - "Done warmup? {arg}\n".format( arg = self.is_done_warmup() ) + + "Done warmup? {arg}\n".format( arg = self.is_done_warmup() ) + "Expected tx rate: {arg}\n".format( arg = self.get_expected_tx_rate() ) + "Current tx rate: {arg}\n".format( arg = self.get_current_tx_rate() ) + "Maximum latency: {arg}\n".format( arg = self.get_max_latency() ) + @@ -1107,22 +1116,16 @@ class CTRexResult(object): self._current_tx_rate = CTRexResult.__get_value_by_path(latest_dump, "trex-global.data", "m_tx_(?!expected_)\w+") if not self._done_warmup and self._expected_tx_rate is not None: # check for up to 2% change between expected and actual - if (self._current_tx_rate['m_tx_bps']/self._expected_tx_rate['m_tx_expected_bps'] > 0.98): + if (self._current_tx_rate['m_tx_bps'] > 0.98 * self._expected_tx_rate['m_tx_expected_bps']): self._done_warmup = True - + # handle latency data if self.latency_checked: - latency_pre = "trex-latency" - self._max_latency = self.get_last_value("{latency}.data".format(latency = latency_pre), "max-")#None # TBC - # support old typo - if self._max_latency is None: - latency_pre = "trex-latecny" - self._max_latency = self.get_last_value("{latency}.data".format(latency = latency_pre), "max-") - - self._avg_latency = self.get_last_value("{latency}.data".format(latency = latency_pre), "avg-")#None # TBC - self._avg_latency = CTRexResult.__avg_all_and_rename_keys(self._avg_latency) - - avg_win_latency_list = self.get_value_list("{latency}.data".format(latency = latency_pre), "avg-") + latency_per_port = self.get_last_value("trex-latecny-v2.data", "port-") + self._max_latency = self.__get_filtered_max_latency(latency_per_port, self.filtered_latency_amount) + avg_latency = self.get_last_value("trex-latecny.data", "avg-") + self._avg_latency = CTRexResult.__avg_all_and_rename_keys(avg_latency) + avg_win_latency_list = self.get_value_list("trex-latecny.data", "avg-") self._avg_window_latency = CTRexResult.__calc_latency_win_stats(avg_win_latency_list) tx_pkts = CTRexResult.__get_value_by_path(latest_dump, "trex-global.data.m_total_tx_pkts") @@ -1209,6 +1212,29 @@ class CTRexResult(object): res[tmp_key] = val # don't touch original fields values return res + @staticmethod + def __get_filtered_max_latency (src_dict, filtered_latency_amount = 0.001): + result = {} + for port, data in src_dict.items(): + if port.startswith('port-'): + max_port = 'max-%s' % port[5:] + res = data['hist'] + if not len(res['histogram']): + result[max_port] = 0 + continue + hist_last_keys = deque([res['histogram'][-1]['key']], maxlen = 2) + sum_high = 0.0 + + for i, elem in enumerate(reversed(res['histogram'])): + sum_high += elem['val'] + hist_last_keys.append(elem['key']) + if sum_high / res['cnt'] >= filtered_latency_amount: + break + result[max_port] = sum(hist_last_keys) / len(hist_last_keys) + else: + return {} + return result + if __name__ == "__main__": diff --git a/scripts/automation/trex_control_plane/stf/trex_daemon_server.py b/scripts/automation/trex_control_plane/stf/trex_stf_lib/trex_daemon_server.py index 9784d42a..9784d42a 100755 --- a/scripts/automation/trex_control_plane/stf/trex_daemon_server.py +++ b/scripts/automation/trex_control_plane/stf/trex_stf_lib/trex_daemon_server.py diff --git a/scripts/automation/trex_control_plane/stf/trex_exceptions.py b/scripts/automation/trex_control_plane/stf/trex_stf_lib/trex_exceptions.py index 0de38411..0de38411 100755 --- a/scripts/automation/trex_control_plane/stf/trex_exceptions.py +++ b/scripts/automation/trex_control_plane/stf/trex_stf_lib/trex_exceptions.py diff --git a/scripts/automation/trex_control_plane/stf/trex_status.py b/scripts/automation/trex_control_plane/stf/trex_stf_lib/trex_status.py index f132720c..f132720c 100644 --- a/scripts/automation/trex_control_plane/stf/trex_status.py +++ b/scripts/automation/trex_control_plane/stf/trex_stf_lib/trex_status.py diff --git a/scripts/automation/trex_control_plane/stf/trex_status_e.py b/scripts/automation/trex_control_plane/stf/trex_stf_lib/trex_status_e.py index 79a25acc..79a25acc 100755 --- a/scripts/automation/trex_control_plane/stf/trex_status_e.py +++ b/scripts/automation/trex_control_plane/stf/trex_stf_lib/trex_status_e.py |