From 0eb15b2e851b5f50669633678143c5a1d3a7d95b Mon Sep 17 00:00:00 2001 From: Yaroslav Brustinov Date: Sun, 3 Apr 2016 21:53:51 +0300 Subject: remove timeouts from trex_client pkg tests, filter out 0.1% of highest latencies, increase priority of TRex process --- .../stateful_tests/trex_client_pkg_test.py | 2 +- .../stateless_tests/trex_client_pkg_test.py | 2 +- .../trex_control_plane/server/trex_server.py | 15 ++++-- .../trex_control_plane/stf/examples/stf_example.py | 11 ++-- .../stf/trex_stf_lib/trex_client.py | 62 +++++++++++++++------- 5 files changed, 64 insertions(+), 28 deletions(-) (limited to 'scripts') diff --git a/scripts/automation/regression/stateful_tests/trex_client_pkg_test.py b/scripts/automation/regression/stateful_tests/trex_client_pkg_test.py index 0b53ea08..e2040e73 100755 --- a/scripts/automation/regression/stateful_tests/trex_client_pkg_test.py +++ b/scripts/automation/regression/stateful_tests/trex_client_pkg_test.py @@ -20,7 +20,7 @@ class CTRexClientPKG_Test(CTRexGeneral_Test): 'cd trex_client/stf/examples', '$PYTHON stf_example.py -s %s' % self.configuration.trex['trex_name'], ] - return_code, _, stderr = run_command("timeout 60 bash -ce '%s'" % '; '.join(commands)) + return_code, _, stderr = run_command("bash -ce '%s'" % '; '.join(commands)) if return_code: self.fail('Error in running stf_example using %s: %s' % (python_version, stderr)) diff --git a/scripts/automation/regression/stateless_tests/trex_client_pkg_test.py b/scripts/automation/regression/stateless_tests/trex_client_pkg_test.py index 779544e3..6e2de230 100755 --- a/scripts/automation/regression/stateless_tests/trex_client_pkg_test.py +++ b/scripts/automation/regression/stateless_tests/trex_client_pkg_test.py @@ -20,7 +20,7 @@ class CTRexClientPKG_Test(CStlGeneral_Test): 'cd trex_client/stl/examples', '$PYTHON stl_imix.py -s %s' % self.configuration.trex['trex_name'], ] - return_code, _, stderr = run_command("timeout 60 bash -ce '%s'" % '; '.join(commands)) + return_code, _, stderr = run_command("bash -ce '%s'" % '; '.join(commands)) if return_code: self.fail('Error in running stf_example using %s: %s' % (python_version, stderr)) diff --git a/scripts/automation/trex_control_plane/server/trex_server.py b/scripts/automation/trex_control_plane/server/trex_server.py index bf788d35..3f8bc374 100755 --- a/scripts/automation/trex_control_plane/server/trex_server.py +++ b/scripts/automation/trex_control_plane/server/trex_server.py @@ -39,7 +39,7 @@ class CTRexServer(object): TREX_START_CMD = './t-rex-64' DEFAULT_FILE_PATH = '/tmp/trex_files/' - def __init__(self, trex_path, trex_files_path, trex_host='0.0.0.0', trex_daemon_port=8090, trex_zmq_port=4500): + def __init__(self, trex_path, trex_files_path, trex_host='0.0.0.0', trex_daemon_port=8090, trex_zmq_port=4500, trex_nice=-19): """ Parameters ---------- @@ -68,6 +68,12 @@ class CTRexServer(object): self.start_lock = threading.Lock() self.__reservation = None self.zmq_monitor = ZmqMonitorSession(self.trex, self.trex_zmq_port) # intiate single ZMQ monitor thread for server usage + self.trex_nice = int(trex_nice) + if self.trex_nice < -20 or self.trex_nice > 19: + err = "Parameter 'nice' should be integer in range [-20, 19]" + print(err) + logger.error(err) + raise Exception(err) def add(self, x, y): print "server function add ",x,y @@ -366,7 +372,8 @@ class CTRexServer(object): else: trex_cmd_options += (dash + '{k} {val}'.format( k = tmp_key, val = value )) - cmd = "{run_command} -f {gen_file} -d {duration} --iom {io} {cmd_options} --no-key > {export}".format( # -- iom 0 disables the periodic log to the screen (not needed) + cmd = "{nice}{run_command} -f {gen_file} -d {duration} --iom {io} {cmd_options} --no-key > {export}".format( # -- iom 0 disables the periodic log to the screen (not needed) + nice = '' if self.trex_nice == 0 else 'nice -n %s ' % self.trex_nice, run_command = self.TREX_START_CMD, gen_file = f, duration = d, @@ -508,6 +515,8 @@ trex_daemon_server [options] action="store", help="Specify a hostname to be registered as the TRex server.\n" "Default is to bind all IPs using '0.0.0.0'.", metavar="HOST", default = '0.0.0.0') + parser.add_argument('-n', '--nice', dest='nice', action="store", default = -19, type = int, + help="Determine the priority TRex process [-20, 19] (lower = higher priority)\nDefault is -19.") return parser trex_parser = generate_trex_parser() @@ -517,7 +526,7 @@ def do_main_program (): args = trex_parser.parse_args() server = CTRexServer(trex_path = args.trex_path, trex_files_path = args.files_path, trex_host = args.trex_host, trex_daemon_port = args.daemon_port, - trex_zmq_port = args.zmq_port) + trex_zmq_port = args.zmq_port, trex_nice = args.nice) server.start() diff --git a/scripts/automation/trex_control_plane/stf/examples/stf_example.py b/scripts/automation/trex_control_plane/stf/examples/stf_example.py index f6ebffe7..f57435bf 100755 --- a/scripts/automation/trex_control_plane/stf/examples/stf_example.py +++ b/scripts/automation/trex_control_plane/stf/examples/stf_example.py @@ -1,8 +1,9 @@ import argparse import stf_path from trex_stf_lib.trex_client import CTRexClient +from pprint import pprint -# sample TRex stateless run +# sample TRex stateful run # assuming server daemon is running. def minimal_stateful_test(server): @@ -14,9 +15,8 @@ def minimal_stateful_test(server): c = 1, m = 700, f = 'cap2/http_simple.yaml', - d = 5, + d = 30, l = 1000, - trex_development = True, ) print('Sample until end') @@ -36,8 +36,9 @@ def minimal_stateful_test(server): print('CPU utilization:') print(result.get_value_list('trex-global.data.m_cpu_util')) - #print('Dump of *latest* result sample, uncomment to see it all') - #print(result.get_latest_dump()) + #Dump of *latest* result sample, uncomment to see it all + #print('Latest result dump:') + #pprint(result.get_latest_dump()) if __name__ == '__main__': diff --git a/scripts/automation/trex_control_plane/stf/trex_stf_lib/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_stf_lib/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__": -- cgit 1.2.3-korg