X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;ds=sidebyside;f=yardstick%2Fnetwork_services%2Fvnf_generic%2Fvnf%2Fprox_helpers.py;h=3241719e898056bc30f1920e4a2ed938c81eab6c;hb=caee6b2a603388c02e961582d78244a2e9e98372;hp=e42431f94faaf58ccf9d3e995c06b18c18f2efab;hpb=b367a8efbd894fb9b9f7eb084a002644be41998d;p=yardstick.git diff --git a/yardstick/network_services/vnf_generic/vnf/prox_helpers.py b/yardstick/network_services/vnf_generic/vnf/prox_helpers.py index e42431f94..3241719e8 100644 --- a/yardstick/network_services/vnf_generic/vnf/prox_helpers.py +++ b/yardstick/network_services/vnf_generic/vnf/prox_helpers.py @@ -44,6 +44,8 @@ SECTION_CONTENTS = 1 LOG = logging.getLogger(__name__) LOG.setLevel(logging.DEBUG) +LOG_RESULT = logging.getLogger('yardstick') +LOG_RESULT.setLevel(logging.DEBUG) BITS_PER_BYTE = 8 RETRY_SECONDS = 60 @@ -123,7 +125,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: @@ -132,10 +135,15 @@ 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) @@ -162,11 +170,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: @@ -177,11 +186,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): @@ -288,7 +298,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) @@ -309,13 +319,13 @@ 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_data(self, pkt_dump_only=False, timeout=0.01): """ read data from the socket """ # This method behaves slightly differently depending on whether it is @@ -352,7 +362,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 '' @@ -386,8 +398,14 @@ class ProxSocketHelper(object): 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)) + + 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)) time.sleep(3) def start_all(self): @@ -397,8 +415,14 @@ 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))) + + 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))) time.sleep(3) def reset_stats(self): @@ -520,6 +544,51 @@ class ProxSocketHelper(object): tsc = int(ret[3]) return rx, tx, drop, tsc + def multi_port_stats(self, ports): + """get counter values from all ports port""" + + ports_str = "" + for port in ports: + ports_str = ports_str + str(port) + "," + ports_str = ports_str[:-1] + + ports_all_data = [] + tot_result = [0] * len(ports) + + retry_counter = 0 + port_index = 0 + while (len(ports) is not len(ports_all_data)) and (retry_counter < 10): + self.put_command("multi port stats {}\n".format(ports_str)) + ports_all_data = self.get_data().split(";") + + if len(ports) is len(ports_all_data): + for port_data_str in ports_all_data: + + try: + tot_result[port_index] = [try_int(s, 0) for s in port_data_str.split(",")] + except (IndexError, TypeError): + LOG.error("Port Index error %d %s - retrying ", port_index, port_data_str) + + if (len(tot_result[port_index]) is not 6) or \ + tot_result[port_index][0] is not ports[port_index]: + ports_all_data = [] + tot_result = [0] * len(ports) + port_index = 0 + time.sleep(0.1) + LOG.error("Corrupted PACKET %s - retrying", port_data_str) + break + else: + port_index = port_index + 1 + else: + LOG.error("Empty / too much data - retry -%s-", ports_all_data) + ports_all_data = [] + tot_result = [0] * len(ports) + port_index = 0 + time.sleep(0.1) + + retry_counter = retry_counter + 1 + return tot_result + def port_stats(self, ports): """get counter values from a specific port""" tot_result = [0] * 12 @@ -699,6 +768,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 @@ -886,7 +969,7 @@ class ProxResourceHelper(ClientResourceHelper): self._test_type = self.setup_helper.find_in_section('global', 'name', None) return self._test_type - def run_traffic(self, traffic_profile): + def run_traffic(self, traffic_profile, *args): self._queue.cancel_join_thread() self.lower = 0.0 self.upper = 100.0 @@ -986,9 +1069,13 @@ 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 + all_ports = self.sut.multi_port_stats(range(self.port_count)) + 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 @@ -1000,25 +1087,24 @@ class ProxDataHelper(object): return self.totals_and_pps[1] @property - def pps(self): + def requested_pps(self): return self.totals_and_pps[2] @property def samples(self): samples = {} + ports = [] + port_names = [] for port_name, port_num in self.vnfd_helper.ports_iter(): - try: - 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, - } - except (KeyError, TypeError, NameError, MemoryError, ValueError, - SystemError, BufferError): - samples[port_name] = { - "in_packets": 0, - "out_packets": 0, - } + ports.append(port_num) + port_names.append(port_name) + + results = self.sut.multi_port_stats(ports) + for result in results: + port_num = result[0] + samples[port_names[port_num]] = { + "in_packets": result[1], + "out_packets": result[2]} return samples def __enter__(self): @@ -1041,7 +1127,7 @@ class ProxDataHelper(object): self.latency, self.rx_total, self.tx_total, - self.pps, + self.requested_pps, ) self.result_tuple.log_data() @@ -1120,6 +1206,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() @@ -1139,12 +1226,32 @@ class ProxProfileHelper(object): return cores + 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)) + 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.... @@ -1232,6 +1339,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() @@ -1403,7 +1511,8 @@ class ProxBngProfileHelper(ProxProfileHelper): 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.... @@ -1592,7 +1701,8 @@ class ProxVpeProfileHelper(ProxProfileHelper): 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.... @@ -1783,7 +1893,8 @@ class ProxlwAFTRProfileHelper(ProxProfileHelper): 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....