aboutsummaryrefslogtreecommitdiffstats
path: root/yardstick/network_services/vnf_generic/vnf/prox_helpers.py
diff options
context:
space:
mode:
Diffstat (limited to 'yardstick/network_services/vnf_generic/vnf/prox_helpers.py')
-rw-r--r--yardstick/network_services/vnf_generic/vnf/prox_helpers.py517
1 files changed, 447 insertions, 70 deletions
diff --git a/yardstick/network_services/vnf_generic/vnf/prox_helpers.py b/yardstick/network_services/vnf_generic/vnf/prox_helpers.py
index 285ead3b6..3507315f2 100644
--- a/yardstick/network_services/vnf_generic/vnf/prox_helpers.py
+++ b/yardstick/network_services/vnf_generic/vnf/prox_helpers.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2017 Intel Corporation
+# Copyright (c) 2018-2019 Intel Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@ import re
import select
import socket
import time
+
from collections import OrderedDict, namedtuple
from contextlib import contextmanager
from itertools import repeat, chain
@@ -30,12 +31,12 @@ import six
from six.moves import cStringIO
from six.moves import zip, StringIO
-from yardstick.benchmark.scenarios.networking.vnf_generic import find_relative_file
from yardstick.common import utils
from yardstick.common.utils import SocketTopology, join_non_strings, try_int
from yardstick.network_services.helpers.iniparser import ConfigParser
from yardstick.network_services.vnf_generic.vnf.sample_vnf import ClientResourceHelper
from yardstick.network_services.vnf_generic.vnf.sample_vnf import DpdkVnfSetupEnvHelper
+from yardstick.network_services import constants
PROX_PORT = 8474
@@ -44,8 +45,9 @@ SECTION_CONTENTS = 1
LOG = logging.getLogger(__name__)
LOG.setLevel(logging.DEBUG)
+LOG_RESULT = logging.getLogger('yardstick')
+LOG_RESULT.setLevel(logging.DEBUG)
-TEN_GIGABIT = 1e10
BITS_PER_BYTE = 8
RETRY_SECONDS = 60
RETRY_INTERVAL = 1
@@ -124,7 +126,8 @@ class TotStatsTuple(namedtuple('TotStats', 'rx,tx,tsc,hz')):
class ProxTestDataTuple(namedtuple('ProxTestDataTuple', 'tolerated,tsc_hz,delta_rx,'
'delta_tx,delta_tsc,'
- 'latency,rx_total,tx_total,pps')):
+ 'latency,rx_total,tx_total,'
+ 'requested_pps')):
@property
def pkt_loss(self):
try:
@@ -133,11 +136,16 @@ class ProxTestDataTuple(namedtuple('ProxTestDataTuple', 'tolerated,tsc_hz,delta_
return 100.0
@property
- def mpps(self):
+ def tx_mpps(self):
# calculate the effective throughput in Mpps
return float(self.delta_tx) * self.tsc_hz / self.delta_tsc / 1e6
@property
+ def rx_mpps(self):
+ # calculate the effective throughput in Mpps
+ return float(self.delta_rx) * self.tsc_hz / self.delta_tsc / 1e6
+
+ @property
def can_be_lost(self):
return int(self.tx_total * self.tolerated / 1e2)
@@ -163,11 +171,12 @@ class ProxTestDataTuple(namedtuple('ProxTestDataTuple', 'tolerated,tsc_hz,delta_
]
samples = {
- "Throughput": self.mpps,
+ "Throughput": self.rx_mpps,
+ "RxThroughput": self.rx_mpps,
"DropPackets": pkt_loss,
"CurrentDropPackets": pkt_loss,
- "TxThroughput": self.pps / 1e6,
- "RxThroughput": self.mpps,
+ "RequestedTxThroughput": self.requested_pps / 1e6,
+ "TxThroughput": self.tx_mpps,
"PktSize": pkt_size,
}
if port_samples:
@@ -178,11 +187,12 @@ class ProxTestDataTuple(namedtuple('ProxTestDataTuple', 'tolerated,tsc_hz,delta_
def log_data(self, logger=None):
if logger is None:
- logger = LOG
+ logger = LOG_RESULT
template = "RX: %d; TX: %d; dropped: %d (tolerated: %d)"
- logger.debug(template, self.rx_total, self.tx_total, self.drop_total, self.can_be_lost)
- logger.debug("Mpps configured: %f; Mpps effective %f", self.pps / 1e6, self.mpps)
+ logger.info(template, self.rx_total, self.tx_total, self.drop_total, self.can_be_lost)
+ logger.info("Mpps configured: %f; Mpps generated %f; Mpps received %f",
+ self.requested_pps / 1e6, self.tx_mpps, self.rx_mpps)
class PacketDump(object):
@@ -289,7 +299,7 @@ class ProxSocketHelper(object):
if mode != 'pktdump':
# Regular 1-line message. Stop reading from the socket.
LOG.debug("Regular response read")
- return ret_str
+ return ret_str, True
LOG.debug("Packet dump header read: [%s]", ret_str)
@@ -310,13 +320,34 @@ class ProxSocketHelper(object):
# Return boolean instead of string to signal
# successful reception of the packet dump.
LOG.debug("Packet dump stored, returning")
- return True
+ return True, False
index = data_end + 1
- return ret_str
+ return ret_str, False
- def get_data(self, pkt_dump_only=False, timeout=1):
+ def get_string(self, pkt_dump_only=False, timeout=0.01):
+
+ def is_ready_string():
+ # recv() is blocking, so avoid calling it when no data is waiting.
+ ready = select.select([self._sock], [], [], timeout)
+ return bool(ready[0])
+
+ status = False
+ ret_str = ""
+ while status is False:
+ for status in iter(is_ready_string, False):
+ decoded_data = self._sock.recv(256).decode('utf-8')
+ ret_str, done = self._parse_socket_data(decoded_data,
+ pkt_dump_only)
+ if (done):
+ status = True
+ break
+
+ LOG.debug("Received data from socket: [%s]", ret_str)
+ return status, ret_str
+
+ def get_data(self, pkt_dump_only=False, timeout=10.0):
""" read data from the socket """
# This method behaves slightly differently depending on whether it is
@@ -353,7 +384,9 @@ class ProxSocketHelper(object):
ret_str = ""
for status in iter(is_ready, False):
decoded_data = self._sock.recv(256).decode('utf-8')
- ret_str = self._parse_socket_data(decoded_data, pkt_dump_only)
+ ret_str, done = self._parse_socket_data(decoded_data, pkt_dump_only)
+ if (done):
+ break
LOG.debug("Received data from socket: [%s]", ret_str)
return ret_str if status else ''
@@ -383,13 +416,17 @@ class ProxSocketHelper(object):
""" stop all cores on the remote instance """
LOG.debug("Stop all")
self.put_command("stop all\n")
- time.sleep(3)
def stop(self, cores, task=''):
""" stop specific cores on the remote instance """
- LOG.debug("Stopping cores %s", cores)
- self.put_command("stop {} {}\n".format(join_non_strings(',', cores), task))
- time.sleep(3)
+
+ tmpcores = []
+ for core in cores:
+ if core not in tmpcores:
+ tmpcores.append(core)
+
+ LOG.debug("Stopping cores %s", tmpcores)
+ self.put_command("stop {} {}\n".format(join_non_strings(',', tmpcores), task))
def start_all(self):
""" start all cores on the remote instance """
@@ -398,15 +435,19 @@ class ProxSocketHelper(object):
def start(self, cores):
""" start specific cores on the remote instance """
- LOG.debug("Starting cores %s", cores)
- self.put_command("start {}\n".format(join_non_strings(',', cores)))
- time.sleep(3)
+
+ tmpcores = []
+ for core in cores:
+ if core not in tmpcores:
+ tmpcores.append(core)
+
+ LOG.debug("Starting cores %s", tmpcores)
+ self.put_command("start {}\n".format(join_non_strings(',', tmpcores)))
def reset_stats(self):
""" reset the statistics on the remote instance """
LOG.debug("Reset stats")
self.put_command("reset stats\n")
- time.sleep(1)
def _run_template_over_cores(self, template, cores, *args):
for core in cores:
@@ -417,7 +458,6 @@ class ProxSocketHelper(object):
LOG.debug("Set packet size for core(s) %s to %d", cores, pkt_size)
pkt_size -= 4
self._run_template_over_cores("pkt_size {} 0 {}\n", cores, pkt_size)
- time.sleep(1)
def set_value(self, cores, offset, value, length):
""" set value on the remote instance """
@@ -467,13 +507,14 @@ class ProxSocketHelper(object):
core_data['current'] = core_data[key1] + core_data[key2]
self.set_speed(core_data['cores'], core_data['current'])
- def set_pps(self, cores, pps, pkt_size):
+ def set_pps(self, cores, pps, pkt_size,
+ line_speed=(constants.ONE_GIGABIT_IN_BITS * constants.NIC_GBPS_DEFAULT)):
""" set packets per second for specific cores on the remote instance """
msg = "Set packets per sec for core(s) %s to %g%% of line rate (packet size: %d)"
LOG.debug(msg, cores, pps, pkt_size)
# speed in percent of line-rate
- speed = float(pps) * (pkt_size + 20) / TEN_GIGABIT / BITS_PER_BYTE
+ speed = float(pps) * (pkt_size + 20) / line_speed / BITS_PER_BYTE
self._run_template_over_cores("speed {} 0 {}\n", cores, speed)
def lat_stats(self, cores, task=0):
@@ -520,6 +561,174 @@ class ProxSocketHelper(object):
tsc = int(ret[3])
return rx, tx, drop, tsc
+ def irq_core_stats(self, cores_tasks):
+ """ get IRQ stats per core"""
+
+ stat = {}
+ core = 0
+ task = 0
+ for core, task in cores_tasks:
+ self.put_command("stats task.core({}).task({}).max_irq,task.core({}).task({}).irq(0),"
+ "task.core({}).task({}).irq(1),task.core({}).task({}).irq(2),"
+ "task.core({}).task({}).irq(3),task.core({}).task({}).irq(4),"
+ "task.core({}).task({}).irq(5),task.core({}).task({}).irq(6),"
+ "task.core({}).task({}).irq(7),task.core({}).task({}).irq(8),"
+ "task.core({}).task({}).irq(9),task.core({}).task({}).irq(10),"
+ "task.core({}).task({}).irq(11),task.core({}).task({}).irq(12)"
+ "\n".format(core, task, core, task, core, task, core, task,
+ core, task, core, task, core, task, core, task,
+ core, task, core, task, core, task, core, task,
+ core, task, core, task))
+ in_data_str = self.get_data().split(",")
+ ret = [try_int(s, 0) for s in in_data_str]
+ key = "core_" + str(core)
+ try:
+ stat[key] = {"cpu": core, "max_irq": ret[0], "bucket_0" : ret[1],
+ "bucket_1" : ret[2], "bucket_2" : ret[3],
+ "bucket_3" : ret[4], "bucket_4" : ret[5],
+ "bucket_5" : ret[6], "bucket_6" : ret[7],
+ "bucket_7" : ret[8], "bucket_8" : ret[9],
+ "bucket_9" : ret[10], "bucket_10" : ret[11],
+ "bucket_11" : ret[12], "bucket_12" : ret[13],
+ "overflow": ret[10] + ret[11] + ret[12] + ret[13]}
+ except (KeyError, IndexError):
+ LOG.error("Corrupted PACKET %s", in_data_str)
+
+ return stat
+
+ def multi_port_stats(self, ports):
+ """get counter values from all ports at once"""
+
+ ports_str = ",".join(map(str, ports))
+ ports_all_data = []
+ tot_result = [0] * len(ports)
+
+ port_index = 0
+ while (len(ports) is not len(ports_all_data)):
+ self.put_command("multi port stats {}\n".format(ports_str))
+ status, ports_all_data_str = self.get_string()
+
+ if not status:
+ return False, []
+
+ ports_all_data = ports_all_data_str.split(";")
+
+ if len(ports) is len(ports_all_data):
+ for port_data_str in ports_all_data:
+
+ tmpdata = []
+ try:
+ tmpdata = [try_int(s, 0) for s in port_data_str.split(",")]
+ except (IndexError, TypeError):
+ LOG.error("Unpacking data error %s", port_data_str)
+ return False, []
+
+ if (len(tmpdata) < 6) or tmpdata[0] not in ports:
+ LOG.error("Corrupted PACKET %s - retrying", port_data_str)
+ return False, []
+ else:
+ tot_result[port_index] = tmpdata
+ port_index = port_index + 1
+ else:
+ LOG.error("Empty / too much data - retry -%s-", ports_all_data)
+ return False, []
+
+ LOG.debug("Multi port packet ..OK.. %s", tot_result)
+ return True, tot_result
+
+ @staticmethod
+ def multi_port_stats_tuple(stats, ports):
+ """
+ Create a statistics tuple from port stats.
+
+ Returns a dict with contains the port stats indexed by port name
+
+ :param stats: (List) - List of List of port stats in pps
+ :param ports (Iterator) - to List of Ports
+
+ :return: (Dict) of port stats indexed by port_name
+ """
+
+ samples = {}
+ port_names = {}
+ try:
+ port_names = {port_num: port_name for port_name, port_num in ports}
+ except (TypeError, IndexError, KeyError):
+ LOG.critical("Ports are not initialized or number of port is ZERO ... CRITICAL ERROR")
+ return {}
+
+ try:
+ for stat in stats:
+ port_num = stat[0]
+ samples[port_names[port_num]] = {
+ "in_packets": stat[1],
+ "out_packets": stat[2]}
+ except (TypeError, IndexError, KeyError):
+ LOG.error("Ports data and samples data is incompatable ....")
+ return {}
+
+ return samples
+
+ @staticmethod
+ def multi_port_stats_diff(prev_stats, new_stats, hz):
+ """
+ Create a statistics tuple from difference between prev port stats
+ and current port stats. And store results in pps.
+
+ :param prev_stats: (List) - Previous List of port statistics
+ :param new_stats: (List) - Current List of port statistics
+ :param hz (float) - speed of system in Hz
+
+ :return: sample (List) - Difference of prev_port_stats and
+ new_port_stats in pps
+ """
+
+ RX_TOTAL_INDEX = 1
+ TX_TOTAL_INDEX = 2
+ TSC_INDEX = 5
+
+ stats = []
+
+ if len(prev_stats) is not len(new_stats):
+ for port_index, stat in enumerate(new_stats):
+ stats.append([port_index, float(0), float(0), 0, 0, 0])
+ return stats
+
+ try:
+ for port_index, stat in enumerate(new_stats):
+ if stat[RX_TOTAL_INDEX] > prev_stats[port_index][RX_TOTAL_INDEX]:
+ rx_total = stat[RX_TOTAL_INDEX] - \
+ prev_stats[port_index][RX_TOTAL_INDEX]
+ else:
+ rx_total = stat[RX_TOTAL_INDEX]
+
+ if stat[TX_TOTAL_INDEX] > prev_stats[port_index][TX_TOTAL_INDEX]:
+ tx_total = stat[TX_TOTAL_INDEX] - prev_stats[port_index][TX_TOTAL_INDEX]
+ else:
+ tx_total = stat[TX_TOTAL_INDEX]
+
+ if stat[TSC_INDEX] > prev_stats[port_index][TSC_INDEX]:
+ tsc = stat[TSC_INDEX] - prev_stats[port_index][TSC_INDEX]
+ else:
+ tsc = stat[TSC_INDEX]
+
+ if tsc is 0:
+ rx_total = tx_total = float(0)
+ else:
+ if hz is 0:
+ LOG.error("HZ is ZERO ..")
+ rx_total = tx_total = float(0)
+ else:
+ rx_total = float(rx_total * hz / tsc)
+ tx_total = float(tx_total * hz / tsc)
+
+ stats.append([port_index, rx_total, tx_total, 0, 0, tsc])
+ except (TypeError, IndexError, KeyError):
+ stats = []
+ LOG.info("Current Port Stats incompatable to previous Port stats .. Discarded")
+
+ return stats
+
def port_stats(self, ports):
"""get counter values from a specific port"""
tot_result = [0] * 12
@@ -580,7 +789,6 @@ class ProxSocketHelper(object):
self.put_command("quit_force\n")
time.sleep(3)
-
_LOCAL_OBJECT = object()
@@ -662,6 +870,30 @@ class ProxDpdkVnfSetupEnvHelper(DpdkVnfSetupEnvHelper):
file_str[1] = self.additional_files[base_name]
return '"'.join(file_str)
+ def _make_core_list(self, inputStr):
+
+ my_input = inputStr.split("core ", 1)[1]
+ ok_list = set()
+
+ substrs = [x.strip() for x in my_input.split(',')]
+ for i in substrs:
+ try:
+ ok_list.add(int(i))
+
+ except ValueError:
+ try:
+ substr = [int(k.strip()) for k in i.split('-')]
+ if len(substr) > 1:
+ startstr = substr[0]
+ endstr = substr[len(substr) - 1]
+ for z in range(startstr, endstr + 1):
+ ok_list.add(z)
+ except ValueError:
+ LOG.error("Error in cores list ... resuming ")
+ return ok_list
+
+ return ok_list
+
def generate_prox_config_file(self, config_path):
sections = []
prox_config = ConfigParser(config_path, sections)
@@ -681,6 +913,18 @@ class ProxDpdkVnfSetupEnvHelper(DpdkVnfSetupEnvHelper):
if section_data[0] == "mac":
section_data[1] = "hardware"
+ # adjust for range of cores
+ new_sections = []
+ for section_name, section in sections:
+ if section_name.startswith('core') and section_name.find('$') == -1:
+ core_list = self._make_core_list(section_name)
+ for core in core_list:
+ new_sections.append(["core " + str(core), section])
+ else:
+ new_sections.append([section_name, section])
+
+ sections = new_sections
+
# search for dst mac
for _, section in sections:
for section_data in section:
@@ -699,6 +943,20 @@ class ProxDpdkVnfSetupEnvHelper(DpdkVnfSetupEnvHelper):
mac = intf["virtual-interface"]["dst_mac"]
section_data[1] = mac
+ if item_val.startswith("@@src_mac"):
+ tx_port_iter = re.finditer(r'\d+', item_val)
+ tx_port_no = int(next(tx_port_iter).group(0))
+ intf = self.vnfd_helper.find_interface_by_port(tx_port_no)
+ mac = intf["virtual-interface"]["local_mac"]
+ section_data[1] = mac.replace(":", " ", 6)
+
+ if item_key == "src mac" and item_val.startswith("@@"):
+ tx_port_iter = re.finditer(r'\d+', item_val)
+ tx_port_no = int(next(tx_port_iter).group(0))
+ intf = self.vnfd_helper.find_interface_by_port(tx_port_no)
+ mac = intf["virtual-interface"]["local_mac"]
+ section_data[1] = mac
+
# if addition file specified in prox config
if not self.additional_files:
return sections
@@ -798,7 +1056,7 @@ class ProxDpdkVnfSetupEnvHelper(DpdkVnfSetupEnvHelper):
options = self.scenario_helper.options
config_path = options['prox_config']
config_file = os.path.basename(config_path)
- config_path = find_relative_file(config_path, task_path)
+ config_path = utils.find_relative_file(config_path, task_path)
self.additional_files = {}
try:
@@ -815,7 +1073,7 @@ class ProxDpdkVnfSetupEnvHelper(DpdkVnfSetupEnvHelper):
prox_files = [prox_files]
for key_prox_file in prox_files:
base_prox_file = os.path.basename(key_prox_file)
- key_prox_path = find_relative_file(key_prox_file, task_path)
+ key_prox_path = utils.find_relative_file(key_prox_file, task_path)
remote_prox_file = self.copy_to_target(key_prox_path, base_prox_file)
self.additional_files[base_prox_file] = remote_prox_file
@@ -873,6 +1131,8 @@ class ProxResourceHelper(ClientResourceHelper):
self.step_delta = 1
self.step_time = 0.5
self._test_type = None
+ self.prev_multi_port = []
+ self.prev_hz = 0
@property
def sut(self):
@@ -901,7 +1161,7 @@ class ProxResourceHelper(ClientResourceHelper):
def _run_traffic_once(self, traffic_profile):
traffic_profile.execute_traffic(self)
- if traffic_profile.done:
+ if traffic_profile.done.is_set():
self._queue.put({'done': True})
LOG.debug("tg_prox done")
self._terminated.value = 1
@@ -911,11 +1171,40 @@ class ProxResourceHelper(ClientResourceHelper):
def collect_collectd_kpi(self):
return self._collect_resource_kpi()
+ def collect_live_stats(self):
+ ports = []
+ for _, port_num in self.vnfd_helper.ports_iter():
+ ports.append(port_num)
+
+ ok, curr_port_stats = self.sut.multi_port_stats(ports)
+ if not ok:
+ return False, {}
+
+ hz = self.sut.hz()
+ if hz is 0:
+ hz = self.prev_hz
+ else:
+ self.prev_hz = hz
+
+ new_all_port_stats = \
+ self.sut.multi_port_stats_diff(self.prev_multi_port, curr_port_stats, hz)
+
+ self.prev_multi_port = curr_port_stats
+
+ live_stats = self.sut.multi_port_stats_tuple(new_all_port_stats,
+ self.vnfd_helper.ports_iter())
+ return True, live_stats
+
def collect_kpi(self):
result = super(ProxResourceHelper, self).collect_kpi()
# add in collectd kpis manually
if result:
result['collect_stats'] = self._collect_resource_kpi()
+
+ ok, live_stats = self.collect_live_stats()
+ if ok:
+ result.update({'live_stats': live_stats})
+
return result
def terminate(self):
@@ -929,6 +1218,7 @@ class ProxResourceHelper(ClientResourceHelper):
func = getattr(self.sut, cmd, None)
if func:
return func(*args, **kwargs)
+ return None
def _connect(self, client=None):
"""Run and connect to prox on the remote system """
@@ -967,12 +1257,13 @@ class ProxResourceHelper(ClientResourceHelper):
class ProxDataHelper(object):
- def __init__(self, vnfd_helper, sut, pkt_size, value, tolerated_loss):
+ def __init__(self, vnfd_helper, sut, pkt_size, value, tolerated_loss, line_speed):
super(ProxDataHelper, self).__init__()
self.vnfd_helper = vnfd_helper
self.sut = sut
self.pkt_size = pkt_size
self.value = value
+ self.line_speed = line_speed
self.tolerated_loss = tolerated_loss
self.port_count = len(self.vnfd_helper.port_pairs.all_ports)
self.tsc_hz = None
@@ -984,32 +1275,71 @@ class ProxDataHelper(object):
@property
def totals_and_pps(self):
if self._totals_and_pps is None:
- rx_total, tx_total = self.sut.port_stats(range(self.port_count))[6:8]
- pps = self.value / 100.0 * self.line_rate_to_pps()
- self._totals_and_pps = rx_total, tx_total, pps
+ rx_total = tx_total = 0
+ ok = False
+ timeout = time.time() + constants.RETRY_TIMEOUT
+ while not ok:
+ ok, all_ports = self.sut.multi_port_stats([
+ self.vnfd_helper.port_num(port_name)
+ for port_name in self.vnfd_helper.port_pairs.all_ports])
+ if time.time() > timeout:
+ break
+ if ok:
+ for port in all_ports:
+ rx_total = rx_total + port[1]
+ tx_total = tx_total + port[2]
+ requested_pps = self.value / 100.0 * self.line_rate_to_pps()
+ self._totals_and_pps = rx_total, tx_total, requested_pps
return self._totals_and_pps
@property
def rx_total(self):
- return self.totals_and_pps[0]
+ try:
+ ret_val = self.totals_and_pps[0]
+ except (AttributeError, ValueError, TypeError, LookupError):
+ ret_val = 0
+ return ret_val
@property
def tx_total(self):
- return self.totals_and_pps[1]
+ try:
+ ret_val = self.totals_and_pps[1]
+ except (AttributeError, ValueError, TypeError, LookupError):
+ ret_val = 0
+ return ret_val
@property
- def pps(self):
- return self.totals_and_pps[2]
+ def requested_pps(self):
+ try:
+ ret_val = self.totals_and_pps[2]
+ except (AttributeError, ValueError, TypeError, LookupError):
+ ret_val = 0
+ return ret_val
@property
def samples(self):
samples = {}
+ ports = []
+ port_names = {}
for port_name, port_num in self.vnfd_helper.ports_iter():
- port_rx_total, port_tx_total = self.sut.port_stats([port_num])[6:8]
- samples[port_name] = {
- "in_packets": port_rx_total,
- "out_packets": port_tx_total,
- }
+ ports.append(port_num)
+ port_names[port_num] = port_name
+
+ ok = False
+ timeout = time.time() + constants.RETRY_TIMEOUT
+ while not ok:
+ ok, results = self.sut.multi_port_stats(ports)
+ if time.time() > timeout:
+ break
+ if ok:
+ for result in results:
+ port_num = result[0]
+ try:
+ samples[port_names[port_num]] = {
+ "in_packets": result[1],
+ "out_packets": result[2]}
+ except (IndexError, KeyError):
+ pass
return samples
def __enter__(self):
@@ -1032,7 +1362,7 @@ class ProxDataHelper(object):
self.latency,
self.rx_total,
self.tx_total,
- self.pps,
+ self.requested_pps,
)
self.result_tuple.log_data()
@@ -1051,9 +1381,7 @@ class ProxDataHelper(object):
self.tsc_hz = float(self.sut.hz())
def line_rate_to_pps(self):
- # NOTE: to fix, don't hardcode 10Gb/s
- return self.port_count * TEN_GIGABIT / BITS_PER_BYTE / (self.pkt_size + 20)
-
+ return self.port_count * self.line_speed / BITS_PER_BYTE / (self.pkt_size + 20)
class ProxProfileHelper(object):
@@ -1113,6 +1441,7 @@ class ProxProfileHelper(object):
self.sut.set_pkt_size(self.test_cores, pkt_size)
self.sut.set_speed(self.test_cores, value)
self.sut.start_all()
+ time.sleep(1)
yield
finally:
self.sut.stop_all()
@@ -1127,15 +1456,37 @@ class ProxProfileHelper(object):
for key, value in section:
if key == "mode" and value == mode:
core_tuple = CoreSocketTuple(section_name)
- core = core_tuple.find_in_topology(self.cpu_topology)
+ core = core_tuple.core_id
cores.append(core)
return cores
- def run_test(self, pkt_size, duration, value, tolerated_loss=0.0):
- data_helper = ProxDataHelper(self.vnfd_helper, self.sut, pkt_size, value, tolerated_loss)
+ def pct_10gbps(self, percent, line_speed):
+ """Get rate in percent of 10 Gbps.
+
+ Returns the rate in percent of 10 Gbps.
+ For instance 100.0 = 10 Gbps; 400.0 = 40 Gbps.
+
+ This helper method isrequired when setting interface_speed option in
+ the testcase because NSB/PROX considers 10Gbps as 100% of line rate,
+ this means that the line rate must be expressed as a percentage of
+ 10Gbps.
+
+ :param percent: (float) Percent of line rate (100.0 = line rate).
+ :param line_speed: (int) line rate speed, in bits per second.
+
+ :return: (float) Represents the rate in percent of 10Gbps.
+ """
+ return (percent * line_speed / (
+ constants.ONE_GIGABIT_IN_BITS * constants.NIC_GBPS_DEFAULT))
- with data_helper, self.traffic_context(pkt_size, value):
+ def run_test(self, pkt_size, duration, value, tolerated_loss=0.0,
+ line_speed=(constants.ONE_GIGABIT_IN_BITS * constants.NIC_GBPS_DEFAULT)):
+ data_helper = ProxDataHelper(self.vnfd_helper, self.sut, pkt_size,
+ value, tolerated_loss, line_speed)
+
+ with data_helper, self.traffic_context(pkt_size,
+ self.pct_10gbps(value, line_speed)):
with data_helper.measure_tot_stats():
time.sleep(duration)
# Getting statistics to calculate PPS at right speed....
@@ -1149,6 +1500,10 @@ class ProxProfileHelper(object):
:return: return lat_min, lat_max, lat_avg
:rtype: list
"""
+
+ if not self._latency_cores:
+ self._latency_cores = self.get_cores(self.PROX_CORE_LAT_MODE)
+
if self._latency_cores:
return self.sut.lat_stats(self._latency_cores)
return []
@@ -1198,12 +1553,12 @@ class ProxMplsProfileHelper(ProxProfileHelper):
if item_value.startswith("tag"):
core_tuple = CoreSocketTuple(section_name)
- core_tag = core_tuple.find_in_topology(self.cpu_topology)
+ core_tag = core_tuple.core_id
cores_tagged.append(core_tag)
elif item_value.startswith("udp"):
core_tuple = CoreSocketTuple(section_name)
- core_udp = core_tuple.find_in_topology(self.cpu_topology)
+ core_udp = core_tuple.core_id
cores_plain.append(core_udp)
return cores_tagged, cores_plain
@@ -1219,6 +1574,7 @@ class ProxMplsProfileHelper(ProxProfileHelper):
ratio = 1.0 * (pkt_size - 4 + 20) / (pkt_size + 20)
self.sut.set_speed(self.plain_cores, value * ratio)
self.sut.start_all()
+ time.sleep(1)
yield
finally:
self.sut.stop_all()
@@ -1276,23 +1632,23 @@ class ProxBngProfileHelper(ProxProfileHelper):
if item_value.startswith("cpe"):
core_tuple = CoreSocketTuple(section_name)
- cpe_core = core_tuple.find_in_topology(self.cpu_topology)
+ cpe_core = core_tuple.core_id
cpe_cores.append(cpe_core)
elif item_value.startswith("inet"):
core_tuple = CoreSocketTuple(section_name)
- inet_core = core_tuple.find_in_topology(self.cpu_topology)
+ inet_core = core_tuple.core_id
inet_cores.append(inet_core)
elif item_value.startswith("arp"):
core_tuple = CoreSocketTuple(section_name)
- arp_core = core_tuple.find_in_topology(self.cpu_topology)
+ arp_core = core_tuple.core_id
arp_cores.append(arp_core)
# We check the tasks/core separately
if item_value.startswith("arp_task"):
core_tuple = CoreSocketTuple(section_name)
- arp_task_core = core_tuple.find_in_topology(self.cpu_topology)
+ arp_task_core = core_tuple.core_id
arp_tasks_core.append(arp_task_core)
return cpe_cores, inet_cores, arp_cores, arp_tasks_core
@@ -1385,10 +1741,13 @@ class ProxBngProfileHelper(ProxProfileHelper):
time.sleep(3)
self.sut.stop(self.all_rx_cores)
- def run_test(self, pkt_size, duration, value, tolerated_loss=0.0):
- data_helper = ProxDataHelper(self.vnfd_helper, self.sut, pkt_size, value, tolerated_loss)
+ def run_test(self, pkt_size, duration, value, tolerated_loss=0.0,
+ line_speed=(constants.ONE_GIGABIT_IN_BITS * constants.NIC_GBPS_DEFAULT)):
+ data_helper = ProxDataHelper(self.vnfd_helper, self.sut, pkt_size,
+ value, tolerated_loss, line_speed)
- with data_helper, self.traffic_context(pkt_size, value):
+ with data_helper, self.traffic_context(pkt_size,
+ self.pct_10gbps(value, line_speed)):
with data_helper.measure_tot_stats():
time.sleep(duration)
# Getting statistics to calculate PPS at right speed....
@@ -1455,12 +1814,12 @@ class ProxVpeProfileHelper(ProxProfileHelper):
if item_value.startswith("cpe"):
core_tuple = CoreSocketTuple(section_name)
- core_tag = core_tuple.find_in_topology(self.cpu_topology)
+ core_tag = core_tuple.core_id
cpe_cores.append(core_tag)
elif item_value.startswith("inet"):
core_tuple = CoreSocketTuple(section_name)
- inet_core = core_tuple.find_in_topology(self.cpu_topology)
+ inet_core = core_tuple.core_id
inet_cores.append(inet_core)
return cpe_cores, inet_cores
@@ -1572,10 +1931,13 @@ class ProxVpeProfileHelper(ProxProfileHelper):
time.sleep(3)
self.sut.stop(self.all_rx_cores)
- def run_test(self, pkt_size, duration, value, tolerated_loss=0.0):
- data_helper = ProxDataHelper(self.vnfd_helper, self.sut, pkt_size, value, tolerated_loss)
+ def run_test(self, pkt_size, duration, value, tolerated_loss=0.0,
+ line_speed=(constants.ONE_GIGABIT_IN_BITS * constants.NIC_GBPS_DEFAULT)):
+ data_helper = ProxDataHelper(self.vnfd_helper, self.sut, pkt_size,
+ value, tolerated_loss, line_speed)
- with data_helper, self.traffic_context(pkt_size, value):
+ with data_helper, self.traffic_context(pkt_size,
+ self.pct_10gbps(value, line_speed)):
with data_helper.measure_tot_stats():
time.sleep(duration)
# Getting statistics to calculate PPS at right speed....
@@ -1639,7 +2001,7 @@ class ProxlwAFTRProfileHelper(ProxProfileHelper):
continue
core_tuple = CoreSocketTuple(section_name)
- core_tag = core_tuple.find_in_topology(self.cpu_topology)
+ core_tag = core_tuple.core_id
for item_value in (v for k, v in section if k == 'name'):
if item_value.startswith('tun'):
tun_cores.append(core_tag)
@@ -1761,10 +2123,13 @@ class ProxlwAFTRProfileHelper(ProxProfileHelper):
time.sleep(3)
self.sut.stop(self.all_rx_cores)
- def run_test(self, pkt_size, duration, value, tolerated_loss=0.0):
- data_helper = ProxDataHelper(self.vnfd_helper, self.sut, pkt_size, value, tolerated_loss)
+ def run_test(self, pkt_size, duration, value, tolerated_loss=0.0,
+ line_speed=(constants.ONE_GIGABIT_IN_BITS * constants.NIC_GBPS_DEFAULT)):
+ data_helper = ProxDataHelper(self.vnfd_helper, self.sut, pkt_size,
+ value, tolerated_loss, line_speed)
- with data_helper, self.traffic_context(pkt_size, value):
+ with data_helper, self.traffic_context(pkt_size,
+ self.pct_10gbps(value, line_speed)):
with data_helper.measure_tot_stats():
time.sleep(duration)
# Getting statistics to calculate PPS at right speed....
@@ -1772,3 +2137,15 @@ class ProxlwAFTRProfileHelper(ProxProfileHelper):
data_helper.latency = self.get_latency()
return data_helper.result_tuple, data_helper.samples
+
+
+class ProxIrqProfileHelper(ProxProfileHelper):
+
+ __prox_profile_type__ = "IRQ Query"
+
+ def __init__(self, resource_helper):
+ super(ProxIrqProfileHelper, self).__init__(resource_helper)
+ self._cores_tuple = None
+ self._ports_tuple = None
+ self.step_delta = 5
+ self.step_time = 0.5