From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 1ABE4A04C1; Fri, 22 Nov 2019 09:57:05 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 0BD1D5B32; Fri, 22 Nov 2019 09:57:04 +0100 (CET) Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) by dpdk.org (Postfix) with ESMTP id 05CC72C28 for ; Fri, 22 Nov 2019 09:57:00 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 22 Nov 2019 00:57:00 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,229,1571727600"; d="scan'208";a="407513690" Received: from dpdk-moyufen06.sh.intel.com ([10.67.116.222]) by fmsmga005.fm.intel.com with ESMTP; 22 Nov 2019 00:56:59 -0800 From: yufengmx To: dts@dpdk.org, yinan.wang@intel.com Cc: yufengmx Date: Fri, 22 Nov 2019 16:58:41 +0800 Message-Id: <20191122085843.97671-4-yufengx.mo@intel.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20191122085843.97671-1-yufengx.mo@intel.com> References: <20191122085843.97671-1-yufengx.mo@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [dts] [PATCH V2 3/5] framework/pktgen_base: measure throughput supports multiple 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: , Errors-To: dts-bounces@dpdk.org Sender: "dts" return values *. add test method(latency/loss/throughput) delay/duration options new usage definition and relevant process source code. *. set delay option to be the warm up time after start transmission. *. add __get_single_throughput_statistic/__get_multi_throughput_statistic methods to realize measure_throughput support return several throughput numbers in a duration. *. set duration option default value to 10 second. *. add test method(latency/loss/throughput/rfc2544) options parameter usage comment, which is the same as doc pktgen_prog_guide.rst. *. add a callback to deal with executing other tools query actions in throughput traffic lasting status. Signed-off-by: yufengmx --- framework/pktgen_base.py | 162 +++++++++++++++++++++++++++++++++++---- 1 file changed, 148 insertions(+), 14 deletions(-) diff --git a/framework/pktgen_base.py b/framework/pktgen_base.py index 7855f6f..26f2f1a 100644 --- a/framework/pktgen_base.py +++ b/framework/pktgen_base.py @@ -157,39 +157,119 @@ class PacketGenerator(object): def reset_streams(self): self.__streams = [] - def measure_throughput(self, stream_ids=[], options={}): - """ - Measure throughput on each tx ports - """ - bps_rx = [] - pps_rx = [] - self._prepare_transmission(stream_ids=stream_ids) + def __warm_up_pktgen(self, stream_ids, options, delay): + ''' run warm up traffic before start main traffic ''' + if not delay: + return + msg = '{1} packet generator: run traffic {0}s to warm up ... '.format( + delay, self.pktgen_type) + self.logger.info(msg) self._start_transmission(stream_ids, options) - - delay = options.get('delay') or 5 time.sleep(delay) + self._stop_transmission(stream_ids) + + def __get_single_throughput_statistic(self, stream_ids): + bps_rx = [] + pps_rx = [] used_rx_port = [] + msg = 'begin get port statistic ...' + self.logger.info(msg) for stream_id in stream_ids: if self.__streams[stream_id]['rx_port'] not in used_rx_port: rxbps_rates, rxpps_rates = self._retrieve_port_statistic( - stream_id, 'throughput') + stream_id, 'throughput') used_rx_port.append(self.__streams[stream_id]['rx_port']) bps_rx.append(rxbps_rates) pps_rx.append(rxpps_rates) - self._stop_transmission(stream_id) - bps_rx_total = self._summary_statistic(bps_rx) pps_rx_total = self._summary_statistic(pps_rx) - self.logger.info("throughput: pps_rx %f, bps_rx %f" % (pps_rx_total, bps_rx_total)) + self.logger.info( + "throughput: pps_rx %f, bps_rx %f" % (pps_rx_total, bps_rx_total)) return bps_rx_total, pps_rx_total + def __get_multi_throughput_statistic( + self, stream_ids, duration, interval, callback=None): + """ + duration: traffic duration (second) + interval: interval of get throughput statistics (second) + callback: a callback method of suite, which is used to do some actions + during traffic lasting. + + Return: a list of throughput instead of a single tuple of pps/bps rate + """ + time_elapsed = 0 + stats = [] + while time_elapsed < duration: + time.sleep(interval) + stats.append(self.__get_single_throughput_statistic(stream_ids)) + if callback and callable(callback): + callback() + time_elapsed += interval + return stats + + def measure_throughput(self, stream_ids=[], options={}): + """ + Measure throughput on each tx ports + + options usage: + rate: + port rate percent, float(0--100). Default value is 100. + + delay: + warm up time before start main traffic. If it is set, it will start + a delay time traffic to make sure packet generator under good status. + Warm up flow is ignored by default. + + interval: + a interval time of get throughput statistic (second) + If set this key value, pktgen will return several throughput statistic + data within a duration traffic. If not set this key value, only + return one statistic data. It is ignored by default. + + callback: + this key works with ``interval`` key. If it is set, the callback + of suite level will be executed after getting throughput statistic. + callback method should define as below, don't add sleep in this method. + + def callback(self): + xxxx() + + duration: + traffic lasting time(second). Default value is 10 second. + """ + interval = options.get('interval') + callback = options.get('callback') + duration = options.get('duration') or 10 + delay = options.get('delay') + self._prepare_transmission(stream_ids=stream_ids) + # start warm up traffic + self.__warm_up_pktgen(stream_ids, options, delay) + # main traffic + self._start_transmission(stream_ids) + # keep traffic within a duration time and get throughput statistic + if interval and duration: + stats = self.__get_multi_throughput_statistic( + stream_ids, duration, interval, callback) + else: + time.sleep(duration) + stats = self.__get_single_throughput_statistic(stream_ids) + self._stop_transmission(stream_ids) + return stats + def _measure_loss(self, stream_ids=[], options={}): """ Measure lost rate on each tx/rx ports """ + delay = options.get('delay') + duration = options.get('duration') or 10 self._prepare_transmission(stream_ids=stream_ids) + # start warm up traffic + self.__warm_up_pktgen(stream_ids, options, delay) + # main traffic self._start_transmission(stream_ids, options) + # keep traffic within a duration time + time.sleep(duration) self._stop_transmission(None) result = {} used_rx_port = [] @@ -210,6 +290,19 @@ class PacketGenerator(object): return result def measure_loss(self, stream_ids=[], options={}): + ''' + options usage: + rate: + port rate percent, float(0--100). Default value is 100. + + delay: + warm up time before start main traffic. If it is set, it will + start a delay time traffic to make sure packet generator + under good status. Warm up flow is ignored by default. + + duration: + traffic lasting time(second). Default value is 10 second. + ''' result = self._measure_loss(stream_ids, options) # here only to make sure that return value is the same as dts/etgen format # In real testing scenario, this method can offer more data than it @@ -218,9 +311,28 @@ class PacketGenerator(object): def measure_latency(self, stream_ids=[], options={}): """ Measure latency on each tx/rx ports + + options usage: + rate: + port rate percent, float(0--100). Default value is 100. + + delay: + warm up time before start main traffic. If it is set, it will + start a delay time transmission to make sure packet generator + under correct status. Warm up flow is ignored by default. + + duration: + traffic lasting time(second). Default value is 10 second. """ + delay = options.get('delay') + duration = options.get('duration') or 10 self._prepare_transmission(stream_ids=stream_ids, latency=True) + # start warm up traffic + self.__warm_up_pktgen(stream_ids, options, delay) + # main traffic self._start_transmission(stream_ids, options) + # keep traffic within a duration time + time.sleep(duration) self._stop_transmission(None) result = {} @@ -248,7 +360,26 @@ class PacketGenerator(object): return True def measure_rfc2544(self, stream_ids=[], options={}): - """ check loss rate with rate percent dropping """ + """ check loss rate with rate percent dropping + + options usage: + rate: + port rate percent at first round testing(0 ~ 100), default is 100. + + pdr: + permit packet drop rate, , default is 0. + + drop_step: + port rate percent drop step(0 ~ 100), default is 1. + + delay: + warm up time before start main traffic. If it is set, it will + start a delay time traffic to make sure packet generator + under good status. Warm up flow is ignored by default. + + duration: + traffic lasting time(second). Default value is 10 second. + """ loss_rate_table = [] rate_percent = options.get('rate') or float(100) permit_loss_rate = options.get('pdr') or 0 @@ -265,6 +396,9 @@ class PacketGenerator(object): tx_num, rx_num = result.values()[0][1:] return rate_percent, tx_num, rx_num _options = deepcopy(options) + # if warm up option 'delay' is set, ignore it in next work flow + if 'delay' in _options: + _options.pop('delay') if 'rate' in _options: _options.pop('rate') while not status and rate_percent > 0: -- 2.21.0