From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by dpdk.org (Postfix) with ESMTP id 91D721B7BD for ; Wed, 6 Jun 2018 07:37:03 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 05 Jun 2018 22:37:02 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.49,482,1520924400"; d="scan'208";a="235032687" Received: from shecgisg006.sh.intel.com ([10.239.39.68]) by fmsmga006.fm.intel.com with ESMTP; 05 Jun 2018 22:37:01 -0700 Received: from shecgisg006.sh.intel.com (localhost [127.0.0.1]) by shecgisg006.sh.intel.com with ESMTP id w565b1pV025523; Wed, 6 Jun 2018 13:37:01 +0800 Received: (from yufengmx@localhost) by shecgisg006.sh.intel.com with œ id w565b1Kn025519; Wed, 6 Jun 2018 13:37:01 +0800 From: yufengx.mo@intel.com To: dts@dpdk.org Cc: yufengmx Date: Wed, 6 Jun 2018 13:36:59 +0800 Message-Id: <1528263420-25329-4-git-send-email-yufengx.mo@intel.com> X-Mailer: git-send-email 1.7.0.7 In-Reply-To: <1528263420-25329-1-git-send-email-yufengx.mo@intel.com> References: <1528263420-25329-1-git-send-email-yufengx.mo@intel.com> Subject: [dts] [PATCH V1 3/3] metrics: framework ixia function extend X-BeenThere: dts@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: test suite reviews and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 06 Jun 2018 05:37:04 -0000 From: yufengmx *. extend ixia class to support continuous sending stream, app will stop it after app complete sample statistics data. *. add a class to save statistcis data for history data comparison. Signed-off-by: yufengmx --- framework/etgen.py | 96 ++++++++++++++++++++++++++++++++++++++++++++++++- framework/serializer.py | 70 +++++++++++++++++++++++++++++++++++- framework/tester.py | 37 ++++++++++++++++++- 3 files changed, 200 insertions(+), 3 deletions(-) mode change 100755 => 100644 framework/tester.py diff --git a/framework/etgen.py b/framework/etgen.py index 2856a28..a6e977b 100644 --- a/framework/etgen.py +++ b/framework/etgen.py @@ -1,6 +1,6 @@ # BSD LICENSE # -# Copyright(c) 2010-2014 Intel Corporation. All rights reserved. +# Copyright(c) 2010-2018 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -168,6 +168,8 @@ class IxiaPacketGenerator(SSHConnection): """ def __init__(self, tester): + self.bpsRate, self.oversize, self.rate = 0, 0, 0 + self.rxPortlist, self.txPortlist = None, None self.tester = tester self.NAME = 'ixia' self.logger = getLogger(self.NAME) @@ -560,6 +562,39 @@ class IxiaPacketGenerator(SSHConnection): return float(sendNumber - revNumber) / sendNumber, sendNumber, revNumber + def loop_latency(self, portList, ratePercent, delay=5): + """ + Run latency performance test and return latency statistics. + """ + rxPortlist, txPortlist = self._configure_everything(portList, ratePercent, True) + self.rxPortlist, self.txPortlist = rxPortlist, txPortlist + return True + + def stop_latency(self, portList, ratePercent, delay=5): + """ + Run latency performance test and return latency statistics. + """ + return self.loop_get_packet_latency(self.rxPortlist) + + def loop_get_packet_latency(self, rxPortlist): + """ + Stop IXIA transmit and return latency statistics. + """ + latencyList = [] + time.sleep(10) + + self.send_expect("ixStopTransmit portList", "%", 10) + for rx_port in rxPortlist: + self.pktGroup_get_stat_all_stats(rx_port) + latency = {"port": rx_port, + "stdDeviation": self.get_standard_deviation(), + "avgDeviation": self.get_average_deviation(), + "min": self.get_min_latency(), + "max": self.get_max_latency(), + "average": self.get_average_latency()} + latencyList.append(latency) + return latencyList + def latency(self, portList, ratePercent, delay=5): """ Run latency performance test and return latency statistics. @@ -579,6 +614,8 @@ class IxiaPacketGenerator(SSHConnection): latency = {"port": rx_port, "min": self.get_min_latency(), "max": self.get_max_latency(), + "stdDeviation": self.get_standard_deviation(), + "avgDeviation": self.get_average_deviation(), "average": self.get_average_latency()} latencyList.append(latency) return latencyList @@ -589,6 +626,21 @@ class IxiaPacketGenerator(SSHConnection): """ rxPortlist, txPortlist = self._configure_everything(port_list, rate_percent) return self.get_transmission_results(rxPortlist, txPortlist, delay) + + def loop_throughput(self, port_list, rate_percent=100, delay=5): + """ + Run throughput performance test and return throughput statistics. + """ + rxPortlist, txPortlist = self._configure_everything(port_list, rate_percent) + self.rxPortlist, self.txPortlist = rxPortlist, txPortlist + return True + + def stop_loop_throughput(self, port_list, rate_percent=100, delay=5): + """ + Run throughput performance test and return throughput statistics. + """ + + return self.stop_loop_transmission(self.rxPortlist, self.txPortlist, delay) """ This function could be used to check the packets' order whether same as the receive sequence. @@ -686,6 +738,36 @@ class IxiaPacketGenerator(SSHConnection): def hook_transmission_func(self): pass + def loop_get_transmission_results(self, rx_port_list, + tx_port_list, delay=5): + """ + Override this method if you want to change the way of getting results + back from IXIA. + """ + time.sleep(delay) + bpsRate = self.bpsRate + rate = self.rate + oversize = self.oversize + for port in rx_port_list: + self.stat_get_rate_stat_all_stats(port) + out = self.send_expect("stat cget -framesReceived", '%', 10) + rate += int(out.strip()) + out = self.send_expect("stat cget -bitsReceived", '% ', 10) + self.logger.debug("port %d bits rate:" % (port) + out) + bpsRate += int(out.strip()) + out = self.send_expect("stat cget -oversize", '%', 10) + oversize += int(out.strip()) + + self.logger.info("Rate: %f Mpps" % (rate * 1.0 / 1000000)) + self.logger.info("Mbps rate: %f Mbps" % (bpsRate * 1.0 / 1000000)) + self.hook_transmissoin_func() + + return True + + def stop_loop_transmission(self, rx_port_list, tx_port_list, delay=5): + return self.get_transmission_results(self.rxPortlist, + self.txPortlist, delay) + def get_transmission_results(self, rx_port_list, tx_port_list, delay=5): """ Override this method if you want to change the way of getting results @@ -924,6 +1006,18 @@ class IxiaPacketGenerator(SSHConnection): """ return self._packetgroup_cget_value('averageLatency') + def get_standard_deviation(self): + """ + Return the time stamp of the first packet received + """ + return self._packetgroup_cget_value('firstTimeStamp') + + def get_average_deviation(self): + """ + Return the time stamp of the last packet received + """ + return self._packetgroup_cget_value('lastTimeStamp') + def _transmission_pre_config(self, port_list, rate_percent, latency=False): """ Prepare and configure IXIA ports for performance test. And remove the transmission step in this config sequence. diff --git a/framework/serializer.py b/framework/serializer.py index 2f0545d..1a2e2c4 100644 --- a/framework/serializer.py +++ b/framework/serializer.py @@ -1,6 +1,6 @@ # BSD LICENSE # -# Copyright(c) 2010-2014 Intel Corporation. All rights reserved. +# Copyright(c) 2010-2018 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -116,3 +116,71 @@ class Serializer(object): self.volatile_cache.clear() if os.path.exists(self.filename): os.remove(self.filename) + +class SerializerBase(object): + + """ + Two-levels cache implementation for storing/retrieving any kind of object + using using a key-value model. It uses the pickle module to store objects + into a file. + """ + + def __init__(self): + self.volatile_cache = {} + self.filename = 'serializerBase.cache' + + def save(self, object_name, object_to_save): + """ + Saves an object into the volatile dictionary cache - which + resides in memory. + """ + self.volatile_cache[object_name] = object_to_save + + def load(self, object_name): + """ + Loads and returns an object from the volatile cache. + """ + return self.volatile_cache.get(object_name, None) + + def set_serialized_filename(self, filename): + """ + Sets the name of the non-volatile cache file to be used in the future + """ + self.filename = filename + + def save_to_file(self): + """ + Saves the volatile cache to a file (non-volatile) using the pickle + module. Returns True in case everything went OK, False otherwise. + """ + try: + serialized_file = open(self.filename, 'w') + pickle.dump(self.volatile_cache, serialized_file) + serialized_file.close() + return True + except: + return False + + def load_from_file(self): + """ + Reads from a pickle-like file using pickle module and populates the + volatile cache. Returns True in case everything went OK, False + otherwise. + """ + try: + serialized_file = open(self.filename, 'r') + self.volatile_cache = pickle.load(serialized_file) + serialized_file.close() + return True + except: + self.volatile_cache.clear() + return False + + def discard_cache(self): + """ + Discards both volatile and non-volatile cache. + """ + self.volatile_cache.clear() + if os.path.exists(self.filename): + os.remove(self.filename) + diff --git a/framework/tester.py b/framework/tester.py old mode 100755 new mode 100644 index a775f68..2327d52 --- a/framework/tester.py +++ b/framework/tester.py @@ -1,6 +1,6 @@ # BSD LICENSE # -# Copyright(c) 2010-2014 Intel Corporation. All rights reserved. +# Copyright(c) 2010-2018 Intel Corporation. All rights reserved. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -524,6 +524,23 @@ class Tester(Crb): self.logger.info("zero loss rate is %s" % test_rate) return test_rate, tx_num, rx_num + def loop_traffic_generator_throughput(self, portList, rate_percent=100, delay=5): + """ + Run throughput performance test on specified ports. + """ + if self.check_port_list(portList, 'ixia'): + return self.ixia_packet_gen.loop_throughput(portList, rate_percent, delay) + if not self.check_port_list(portList): + self.logger.warning("exception by mixed port types") + return None + result = self.packet_gen.loop_throughput(portList, rate_percent) + return result + + def stop_traffic_generator_throughput_loop(self, portList, rate_percent=100, delay=5): + """ + Run throughput performance test on specified ports. + """ + return self.ixia_packet_gen.stop_loop_throughput(portList, rate_percent, delay) def traffic_generator_loss(self, portList, ratePercent, delay=60): """ @@ -536,6 +553,24 @@ class Tester(Crb): return None return self.packet_gen.loss(portList, ratePercent, delay) + def loop_traffic_generator_latency(self, portList, ratePercent=100, delay=5): + """ + Run latency performance test on specified ports. + """ + if self.check_port_list(portList, 'ixia'): + return self.ixia_packet_gen.loop_latency(portList, ratePercent, delay) + else: + return None + + def stop_traffic_generator_latency(self, portList, ratePercent=100, delay=5): + """ + Run latency performance test on specified ports. + """ + if self.check_port_list(portList, 'ixia'): + return self.ixia_packet_gen.stop_latency(portList, ratePercent, delay) + else: + return None + def traffic_generator_latency(self, portList, ratePercent=100, delay=5): """ Run latency performance test on specified ports. -- 1.9.3