From 01dd86e690b60e5c5faf7ee8c5cf500954c19a9e Mon Sep 17 00:00:00 2001 From: DanielMartinBuckley Date: Thu, 5 Jul 2018 17:55:29 +0100 Subject: Update Multi Port Stats reading for PROX JIRA: YARDSTICK-1458 Removed excessive jitter by removing extra sleeps in start/stop/reset ssh Removed extra retries when bad data returned Added a slep at end of test to give runner a chance to empty the queue on shutdown Added a timeout on port retry attempts Change-Id: Ica60b11c7af242817a83c154157827581f60d16a Signed-off-by: Daniel Martin Buckley (cherry picked from commit b2fd601c33e3322ccc9e675242f091dba2eeb644) --- yardstick/network_services/constants.py | 3 +- .../traffic_profile/prox_profile.py | 4 +- .../vnf_generic/vnf/prox_helpers.py | 139 +++++++---- .../network_services/vnf_generic/vnf/prox_vnf.py | 34 ++- .../vnf_generic/vnf/test_prox_helpers.py | 274 +++++++++++++++++---- .../vnf_generic/vnf/test_prox_vnf.py | 57 ++++- 6 files changed, 395 insertions(+), 116 deletions(-) diff --git a/yardstick/network_services/constants.py b/yardstick/network_services/constants.py index 0064b4fc5..5a186be42 100644 --- a/yardstick/network_services/constants.py +++ b/yardstick/network_services/constants.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016-2017 Intel Corporation +# Copyright (c) 2016-2018 Intel Corporation # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,3 +17,4 @@ DEFAULT_VNF_TIMEOUT = 3600 PROCESS_JOIN_TIMEOUT = 3 ONE_GIGABIT_IN_BITS = 1000000000 NIC_GBPS_DEFAULT = 10 +RETRY_TIMEOUT = 5 diff --git a/yardstick/network_services/traffic_profile/prox_profile.py b/yardstick/network_services/traffic_profile/prox_profile.py index de4b3f9a0..be450c9f7 100644 --- a/yardstick/network_services/traffic_profile/prox_profile.py +++ b/yardstick/network_services/traffic_profile/prox_profile.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016-2017 Intel Corporation +# Copyright (c) 2016-2018 Intel Corporation # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ from __future__ import absolute_import import logging import multiprocessing +import time from yardstick.network_services.traffic_profile.base import TrafficProfile from yardstick.network_services.vnf_generic.vnf.prox_helpers import ProxProfileHelper @@ -117,6 +118,7 @@ class ProxProfile(TrafficProfile): try: pkt_size = next(self.pkt_size_iterator) except StopIteration: + time.sleep(5) self.done.set() return diff --git a/yardstick/network_services/vnf_generic/vnf/prox_helpers.py b/yardstick/network_services/vnf_generic/vnf/prox_helpers.py index 321c05779..8d721c045 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 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 @@ -325,6 +326,27 @@ class ProxSocketHelper(object): return ret_str, False + 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=0.01): """ read data from the socket """ @@ -394,7 +416,6 @@ 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 """ @@ -406,7 +427,6 @@ class ProxSocketHelper(object): LOG.debug("Stopping cores %s", tmpcores) self.put_command("stop {} {}\n".format(join_non_strings(',', tmpcores), task)) - time.sleep(3) def start_all(self): """ start all cores on the remote instance """ @@ -423,13 +443,11 @@ class ProxSocketHelper(object): LOG.debug("Starting cores %s", tmpcores) self.put_command("start {}\n".format(join_non_strings(',', tmpcores))) - time.sleep(3) 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: @@ -440,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 """ @@ -545,49 +562,44 @@ class ProxSocketHelper(object): 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] + """get counter values from all ports at once""" + ports_str = ",".join(map(str, ports)) 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): + while (len(ports) is not len(ports_all_data)): self.put_command("multi port stats {}\n".format(ports_str)) - ports_all_data = self.get_data().split(";") + 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: - tot_result[port_index] = [try_int(s, 0) for s in port_data_str.split(",")] + tmpdata = [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("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) - break + 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) - ports_all_data = [] - tot_result = [0] * len(ports) - port_index = 0 - time.sleep(0.1) + return False, [] - retry_counter = retry_counter + 1 - return tot_result + LOG.debug("Multi port packet ..OK.. %s", tot_result) + return True, tot_result def port_stats(self, ports): """get counter values from a specific port""" @@ -1070,41 +1082,70 @@ class ProxDataHelper(object): def totals_and_pps(self): if self._totals_and_pps is None: 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 + 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 requested_pps(self): - return self.totals_and_pps[2] + 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 = [] + port_names = {} for port_name, port_num in self.vnfd_helper.ports_iter(): 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]} + 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): diff --git a/yardstick/network_services/vnf_generic/vnf/prox_vnf.py b/yardstick/network_services/vnf_generic/vnf/prox_vnf.py index 839f30967..c3b50369b 100644 --- a/yardstick/network_services/vnf_generic/vnf/prox_vnf.py +++ b/yardstick/network_services/vnf_generic/vnf/prox_vnf.py @@ -1,4 +1,4 @@ -# Copyright (c) 2017 Intel Corporation +# Copyright (c) 2018 Intel Corporation # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,6 +15,7 @@ import errno import logging import datetime +import time from yardstick.common.process import check_if_process_failed from yardstick.network_services.vnf_generic.vnf.prox_helpers import ProxDpdkVnfSetupEnvHelper @@ -81,6 +82,8 @@ class ProxApproxVnf(SampleVNF): "packets_in": 0, "packets_dropped": 0, "packets_fwd": 0, + "curr_packets_in": 0, + "curr_packets_fwd": 0, "collect_stats": {"core": {}}, }) return result @@ -97,15 +100,26 @@ class ProxApproxVnf(SampleVNF): raise RuntimeError("Failed ..Invalid no of ports .. " "1, 2 or 4 ports only supported at this time") - all_port_stats = self.vnf_execute('multi_port_stats', range(port_count)) - rx_total = tx_total = tsc = 0 - try: - for single_port_stats in all_port_stats: - rx_total = rx_total + single_port_stats[1] - tx_total = tx_total + single_port_stats[2] - tsc = tsc + single_port_stats[5] - except (TypeError, IndexError): - LOG.error("Invalid data ...") + tmpPorts = [self.vnfd_helper.port_num(port_name) + for port_name in self.vnfd_helper.port_pairs.all_ports] + ok = False + timeout = time.time() + constants.RETRY_TIMEOUT + while not ok: + ok, all_port_stats = self.vnf_execute('multi_port_stats', tmpPorts) + if time.time() > timeout: + break + + if ok: + rx_total = tx_total = tsc = 0 + try: + for single_port_stats in all_port_stats: + rx_total = rx_total + single_port_stats[1] + tx_total = tx_total + single_port_stats[2] + tsc = tsc + single_port_stats[5] + except (TypeError, IndexError): + LOG.error("Invalid data ...") + return {} + else: return {} tsc = tsc / port_count diff --git a/yardstick/tests/unit/network_services/vnf_generic/vnf/test_prox_helpers.py b/yardstick/tests/unit/network_services/vnf_generic/vnf/test_prox_helpers.py index 3d6ebb25b..894b16e13 100644 --- a/yardstick/tests/unit/network_services/vnf_generic/vnf/test_prox_helpers.py +++ b/yardstick/tests/unit/network_services/vnf_generic/vnf/test_prox_helpers.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016-2017 Intel Corporation +# Copyright (c) 2016-2018 Intel Corporation # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -320,7 +320,8 @@ class TestProxSocketHelper(unittest.TestCase): self.assertEqual(len(prox._pkt_dumps), 0) mock_select.select.reset_mock() - mock_select.select.side_effect = chain([['a'], ['']], repeat([1], 3)) + mock_select.select.side_effect = chain([['a'], ['']], + repeat([1], 3)) mock_recv.decode.return_value = PACKET_DUMP_1 ret = prox.get_data() self.assertEqual(mock_select.select.call_count, 2) @@ -328,13 +329,54 @@ class TestProxSocketHelper(unittest.TestCase): self.assertEqual(len(prox._pkt_dumps), 1) mock_select.select.reset_mock() - mock_select.select.side_effect = chain([[object()], [None]], repeat([1], 3)) + mock_select.select.side_effect = chain([[object()], [None]], + repeat([1], 3)) mock_recv.decode.return_value = PACKET_DUMP_2 ret = prox.get_data() self.assertEqual(mock_select.select.call_count, 1) self.assertEqual(ret, 'jumped over') self.assertEqual(len(prox._pkt_dumps), 3) + @mock.patch.object(prox_helpers, 'select') + def test_get_string(self, mock_select): + mock_select.select.side_effect = [[1], [0]] + mock_socket = mock.MagicMock() + mock_recv = mock_socket.recv() + mock_recv.decode.return_value = "" + prox = prox_helpers.ProxSocketHelper(mock_socket) + status, ret = prox.get_string() + self.assertEqual(ret, "") + self.assertTrue(status) + self.assertEqual(len(prox._pkt_dumps), 0) + + @mock.patch.object(prox_helpers, 'select') + def test_get_string2(self, mock_select): + mock_select.select.side_effect = chain([['a'], ['']], + repeat([1], 3)) + mock_socket = mock.MagicMock() + mock_recv = mock_socket.recv() + mock_recv.decode.return_value = PACKET_DUMP_1 + prox = prox_helpers.ProxSocketHelper(mock_socket) + status, ret = prox.get_string() + self.assertEqual(mock_select.select.call_count, 2) + self.assertEqual(ret, 'pktdump,3,11') + self.assertTrue(status) + self.assertEqual(len(prox._pkt_dumps), 1) + + @mock.patch.object(prox_helpers, 'select') + def test_get_string3(self, mock_select): + mock_select.select.side_effect = chain([[object()], [None]], + repeat([1], 3)) + mock_socket = mock.MagicMock() + mock_recv = mock_socket.recv() + mock_recv.decode.return_value = PACKET_DUMP_2 + prox = prox_helpers.ProxSocketHelper(mock_socket) + status, ret = prox.get_string() + self.assertTrue(status) + self.assertTrue(mock_select.select.assert_called_once) + self.assertEqual(ret, 'jumped over') + self.assertEqual(len(prox._pkt_dumps), 2) + def test__parse_socket_data_mixed_data(self): prox = prox_helpers.ProxSocketHelper(mock.MagicMock()) ret, _ = prox._parse_socket_data(PACKET_DUMP_NON_1, False) @@ -551,26 +593,60 @@ class TestProxSocketHelper(unittest.TestCase): def test_multi_port_stats(self, *args): mock_socket = mock.MagicMock() prox = prox_helpers.ProxSocketHelper(mock_socket) - prox.get_data = mock.MagicMock(return_value='0,1,2,3,4,5;1,1,2,3,4,5') + prox.get_string = mock.MagicMock(return_value=(True, '0,1,2,3,4,5;1,1,2,3,4,5')) expected = [[0, 1, 2, 3, 4, 5], [1, 1, 2, 3, 4, 5]] - result = prox.multi_port_stats([0, 1]) + status, result = prox.multi_port_stats([0, 1]) self.assertEqual(result, expected) - - prox.get_data = mock.MagicMock(return_value='0,1,2,3,4,5;1,1,2,3,4,5') - result = prox.multi_port_stats([0]) - expected = [0] - self.assertEqual(result, expected) - - prox.get_data = mock.MagicMock(return_value='0,1,2,3;1,1,2,3,4,5') - result = prox.multi_port_stats([0, 1]) - expected = [0] * 2 - self.assertEqual(result, expected) - - prox.get_data = mock.MagicMock(return_value='99,1,2,3,4,5;1,1,2,3,4,5') - expected = [0] * 2 - result = prox.multi_port_stats([0, 1]) + self.assertEqual(status, True) + + prox.get_string = mock.MagicMock( + return_value=(True, '0,1,2,3,4,5;1,1,2,3,4,5')) + status, result = prox.multi_port_stats([0]) + self.assertEqual(status, False) + + prox.get_string = mock.MagicMock( + return_value=(True, '0,1,2,3,4,5;1,1,2,3,4,5')) + status, result = prox.multi_port_stats([0, 1, 2]) + self.assertEqual(status, False) + + prox.get_string = mock.MagicMock( + return_value=(True, '0,1,2,3;1,1,2,3,4,5')) + status, result = prox.multi_port_stats([0, 1]) + self.assertEqual(status, False) + + prox.get_string = mock.MagicMock( + return_value=(True, '99,1,2,3,4,5;1,1,2,3,4,5')) + status, result = prox.multi_port_stats([0, 1]) + self.assertEqual(status, False) + + prox.get_string = mock.MagicMock( + return_value=(True, '99,1,2,3,4,5;1,1,2,3,4,5')) + status, result = prox.multi_port_stats([99, 1]) + expected = [[99, 1, 2, 3, 4, 5], [1, 1, 2, 3, 4, 5]] + self.assertEqual(status, True) self.assertEqual(result, expected) + prox.get_string = mock.MagicMock( + return_value=(True, + '2,21,22,23,24,25;1,11,12,13,14,15;0,1,2,3,4,5')) + + sample1 = [0, 1, 2, 3, 4, 5] + sample2 = [1, 11, 12, 13, 14, 15] + sample3 = [2, 21, 22, 23, 24, 25] + expected = [sample3, sample2, sample1] + status, result = prox.multi_port_stats([1, 2, 0]) + self.assertTrue(status) + self.assertListEqual(result, expected) + + prox.get_string = mock.MagicMock( + return_value=(True, '6,21,22,23,24,25;1,11,12,13,14,15;0,1,2,3,4,5')) + ok, result = prox.multi_port_stats([1, 6, 0]) + sample1 = [6, 21, 22, 23, 24, 25] + sample2 = [1, 11, 12, 13, 14, 15] + sample3 = [0, 1, 2, 3, 4, 5] + expected = [sample1, sample2, sample3] + self.assertListEqual(result, expected) + self.assertTrue(ok) def test_port_stats(self): port_stats = [ @@ -1584,8 +1660,9 @@ class TestProxDataHelper(unittest.TestCase): vnfd_helper.port_pairs.all_ports = list(range(4)) sut = mock.MagicMock() - sut.multi_port_stats.return_value = [[0, 1, 2, 3, 4, 5], [1, 1, 2, 3, 4, 5], - [2, 1, 2, 3, 4, 5], [3, 1, 2, 3, 4, 5]] + sut.multi_port_stats.return_value = (True, + [[0, 1, 2, 3, 4, 5], [1, 1, 2, 3, 4, 5], + [2, 1, 2, 3, 4, 5], [3, 1, 2, 3, 4, 5]]) data_helper = prox_helpers.ProxDataHelper( vnfd_helper, sut, pkt_size, 25, None, @@ -1593,14 +1670,77 @@ class TestProxDataHelper(unittest.TestCase): self.assertEqual(data_helper.rx_total, 4) self.assertEqual(data_helper.tx_total, 8) - self.assertEqual(data_helper.requested_pps, 6.25e6) + self.assertEqual(data_helper.requested_pps, 6250000.0) + + vnfd_helper = mock.MagicMock() + vnfd_helper.port_pairs.all_ports = [3, 4] + + sut = mock.MagicMock() + sut.multi_port_stats.return_value = (True, + [[3, 1, 2, 3, 4, 5], [4, 1, 2, 3, 4, 5]]) + + data_helper = prox_helpers.ProxDataHelper( + vnfd_helper, sut, pkt_size, 25, None, + constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS) + + self.assertEqual(data_helper.rx_total, 2) + self.assertEqual(data_helper.tx_total, 4) + self.assertEqual(data_helper.requested_pps, 3125000.0) + + vnfd_helper = mock.MagicMock() + vnfd_helper.port_pairs.all_ports = [0, 1, 2, 3, 4, 6, 7] + + sut = mock.MagicMock() + sut.multi_port_stats.return_value = (True, + [[8, 1, 2, 3, 4, 5], [9, 1, 2, 3, 4, 5]]) + + data_helper = prox_helpers.ProxDataHelper( + vnfd_helper, sut, pkt_size, 25, None, + constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS) + + self.assertEqual(data_helper.rx_total, 2) + self.assertEqual(data_helper.tx_total, 4) + self.assertEqual(data_helper.requested_pps, 10937500.0) + + vnfd_helper = mock.MagicMock() + vnfd_helper.port_pairs.all_ports = [] + + sut = mock.MagicMock() + sut.multi_port_stats.return_value = (True, + [[8, 1, 2, 3, 4, 5], [9, 1, 2, 3, 4, 5]]) + + data_helper = prox_helpers.ProxDataHelper( + vnfd_helper, sut, pkt_size, 25, None, + constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS) + + self.assertEqual(data_helper.rx_total, 2) + self.assertEqual(data_helper.tx_total, 4) + self.assertEqual(data_helper.requested_pps, 0.0) + + def test_totals_and_pps2(self): + pkt_size = 180 + vnfd_helper = mock.MagicMock() + vnfd_helper.port_pairs.all_ports = list(range(4)) + + sut = mock.MagicMock() + sut.multi_port_stats.return_value = (True, + [[0, 'A', 2, 3, 4, 5], [1, 'B', 'C', 3, 4, 5], + ['D', 1, 2, 3, 4, 5], [3, 1, 2, 3, 4, 'F']]) + + data_helper = prox_helpers.ProxDataHelper( + vnfd_helper, sut, pkt_size, 25, None, + constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS) + + self.assertEqual(data_helper.rx_total, 0) + self.assertEqual(data_helper.tx_total, 0) + self.assertEqual(data_helper.requested_pps, 0) def test_samples(self): vnfd_helper = mock.MagicMock() vnfd_helper.ports_iter.return_value = [('xe0', 0), ('xe1', 1)] sut = mock.MagicMock() - sut.multi_port_stats.return_value = [[0, 1, 2, 3, 4, 5], [1, 11, 12, 3, 4, 5]] + sut.multi_port_stats.return_value = (True, [[0, 1, 2, 3, 4, 5], [1, 11, 12, 3, 4, 5]]) data_helper = prox_helpers.ProxDataHelper( vnfd_helper, sut, None, None, None, None) @@ -1618,13 +1758,35 @@ class TestProxDataHelper(unittest.TestCase): result = data_helper.samples self.assertDictEqual(result, expected) + def test_samples2(self): + vnfd_helper = mock.MagicMock() + vnfd_helper.ports_iter.return_value = [('xe1', 3), ('xe2', 7)] + + sut = mock.MagicMock() + sut.multi_port_stats.return_value = (True, [[3, 1, 2, 3, 4, 5], [7, 11, 12, 3, 4, 5]]) + + data_helper = prox_helpers.ProxDataHelper( + vnfd_helper, sut, None, None, None, None) + + expected = { + 'xe1': { + 'in_packets': 1, + 'out_packets': 2, + }, + 'xe2': { + 'in_packets': 11, + 'out_packets': 12, + }, + } + result = data_helper.samples + self.assertDictEqual(result, expected) + def test___enter__(self): vnfd_helper = mock.MagicMock() vnfd_helper.port_pairs.all_ports = list(range(4)) vnfd_helper.ports_iter.return_value = [('xe1', 3), ('xe2', 7)] sut = mock.MagicMock() - sut.port_stats.return_value = list(range(10)) data_helper = prox_helpers.ProxDataHelper(vnfd_helper, sut, None, None, 5.4, constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS) @@ -1978,7 +2140,6 @@ class TestProxProfileHelper(unittest.TestCase): client = mock.MagicMock() client.hz.return_value = 2 - client.port_stats.return_value = tuple(range(12)) helper.client = client helper.get_latency = mock.MagicMock(return_value=[3.3, 3.6, 3.8]) @@ -1988,18 +2149,20 @@ class TestProxProfileHelper(unittest.TestCase): with helper.traffic_context(64, 1): pass - @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.time') - def test_run_test(self, _): + def test_run_test(self, *args): resource_helper = mock.MagicMock() resource_helper.step_delta = 0.4 resource_helper.vnfd_helper.port_pairs.all_ports = list(range(2)) - resource_helper.sut.port_stats.return_value = list(range(10)) + resource_helper.sut.multi_port_stats.return_value = (True, [[0, 1, 1, 2, 4, 5], + [1, 1, 2, 3, 4, 5]]) helper = prox_helpers.ProxProfileHelper(resource_helper) - helper.run_test(120, 5, 6.5, - constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS) - + helper.run_test(pkt_size=120, duration=5, value=6.5, tolerated_loss=0.0, + line_speed=constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS) + self.assertTrue(resource_helper.sut.multi_port_stats.called) + self.assertTrue(resource_helper.sut.stop_all.called) + self.assertTrue(resource_helper.sut.reset_stats.called) class TestProxMplsProfileHelper(unittest.TestCase): @@ -2135,22 +2298,30 @@ class TestProxBngProfileHelper(unittest.TestCase): self.assertEqual(helper.arp_task_cores, expected_arp_task) self.assertEqual(helper._cores_tuple, expected_combined) - @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.time') - def test_run_test(self, _): + def test_run_test(self, *args): resource_helper = mock.MagicMock() resource_helper.step_delta = 0.4 resource_helper.vnfd_helper.port_pairs.all_ports = list(range(2)) - resource_helper.sut.port_stats.return_value = list(range(10)) + resource_helper.sut.multi_port_stats.return_value = (True, [[0, 1, 1, 2, 4, 5], + [1, 1, 2, 3, 4, 5]]) helper = prox_helpers.ProxBngProfileHelper(resource_helper) - helper.run_test(120, 5, 6.5, - constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS) + helper.run_test(pkt_size=120, duration=5, value=6.5, tolerated_loss=0.0, + line_speed=constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS) + self.assertTrue(resource_helper.sut.multi_port_stats.called) + self.assertTrue(resource_helper.sut.stop_all.called) + self.assertTrue(resource_helper.sut.reset_stats.called) + + resource_helper.reset_mock() # negative pkt_size is the only way to make ratio > 1 - helper.run_test(-1000, 5, 6.5, - constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS) + helper.run_test(pkt_size=-1000, duration=5, value=6.5, tolerated_loss=0.0, + line_speed=constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS) + self.assertTrue(resource_helper.sut.multi_port_stats.called) + self.assertTrue(resource_helper.sut.stop_all.called) + self.assertTrue(resource_helper.sut.reset_stats.called) class TestProxVpeProfileHelper(unittest.TestCase): @@ -2253,18 +2424,21 @@ class TestProxVpeProfileHelper(unittest.TestCase): self.assertEqual(helper.inet_ports, expected_inet) self.assertEqual(helper._ports_tuple, expected_combined) - @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.time') - def test_run_test(self, _): + def test_run_test(self, *args): resource_helper = mock.MagicMock() resource_helper.step_delta = 0.4 resource_helper.vnfd_helper.port_pairs.all_ports = list(range(2)) - resource_helper.sut.port_stats.return_value = list(range(10)) + resource_helper.sut.multi_port_stats.return_value = (True, [[0, 1, 1, 2, 4, 5], + [1, 1, 2, 3, 4, 5]]) helper = prox_helpers.ProxVpeProfileHelper(resource_helper) - helper.run_test(120, 5, 6.5) - helper.run_test(-1000, 5, 6.5) # negative pkt_size is the only way to make ratio > 1 + helper.run_test(pkt_size=120, duration=5, value=6.5, tolerated_loss=0.0, + line_speed=constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS) + # negative pkt_size is the only way to make ratio > 1 + helper.run_test(pkt_size=-1000, duration=5, value=6.5, tolerated_loss=0.0, + line_speed=constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS) class TestProxlwAFTRProfileHelper(unittest.TestCase): @@ -2367,14 +2541,18 @@ class TestProxlwAFTRProfileHelper(unittest.TestCase): self.assertEqual(helper.inet_ports, expected_inet) self.assertEqual(helper._ports_tuple, expected_combined) - @mock.patch('yardstick.network_services.vnf_generic.vnf.prox_helpers.time') - def test_run_test(self, _): + def test_run_test(self, *args): resource_helper = mock.MagicMock() resource_helper.step_delta = 0.4 resource_helper.vnfd_helper.port_pairs.all_ports = list(range(2)) - resource_helper.sut.port_stats.return_value = list(range(10)) + resource_helper.sut.multi_port_stats.return_value = (True, [[0, 1, 2, 4, 6, 5], + [1, 1, 2, 3, 4, 5]]) helper = prox_helpers.ProxlwAFTRProfileHelper(resource_helper) - helper.run_test(120, 5, 6.5) - helper.run_test(-1000, 5, 6.5) # negative pkt_size is the only way to make ratio > 1 + helper.run_test(pkt_size=120, duration=5, value=6.5, tolerated_loss=0.0, + line_speed=constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS) + + # negative pkt_size is the only way to make ratio > 1 + helper.run_test(pkt_size=-1000, duration=5, value=6.5, tolerated_loss=0.0, + line_speed=constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS) diff --git a/yardstick/tests/unit/network_services/vnf_generic/vnf/test_prox_vnf.py b/yardstick/tests/unit/network_services/vnf_generic/vnf/test_prox_vnf.py index f144e8c42..62cbea0bb 100644 --- a/yardstick/tests/unit/network_services/vnf_generic/vnf/test_prox_vnf.py +++ b/yardstick/tests/unit/network_services/vnf_generic/vnf/test_prox_vnf.py @@ -335,6 +335,8 @@ class TestProxApproxVnf(unittest.TestCase): 'packets_in': 0, 'packets_dropped': 0, 'packets_fwd': 0, + 'curr_packets_in': 0, + 'curr_packets_fwd': 0, 'collect_stats': {'core': {}} } result = prox_approx_vnf.collect_kpi() @@ -346,8 +348,8 @@ class TestProxApproxVnf(unittest.TestCase): mock_ssh(ssh) resource_helper = mock.MagicMock() - resource_helper.execute.return_value = [[0, 1, 2, 3, 4, 5], [1, 1, 2, 3, 4, 5], - [2, 1, 2, 3, 4, 5], [3, 1, 2, 3, 4, 5]] + resource_helper.execute.return_value = (True, + [[0, 1, 2, 3, 4, 5], [1, 1, 2, 3, 4, 5]]) resource_helper.collect_collectd_kpi.return_value = {'core': {'result': 234}} prox_approx_vnf = prox_vnf.ProxApproxVnf(NAME, self.VNFD0, 'task_id') @@ -355,20 +357,61 @@ class TestProxApproxVnf(unittest.TestCase): 'nodes': {prox_approx_vnf.name: "mock"} } prox_approx_vnf.resource_helper = resource_helper + prox_approx_vnf.tsc_hz = 1000 expected = { + 'curr_packets_in': 200, + 'curr_packets_fwd': 400, 'physical_node': 'mock_node', - 'packets_in': 4, - 'packets_dropped': 4, - 'packets_fwd': 8, + 'packets_in': 2, + 'packets_dropped': 2, + 'packets_fwd': 4, 'collect_stats': {'core': {'result': 234}}, } result = prox_approx_vnf.collect_kpi() self.assertEqual(result['packets_in'], expected['packets_in']) self.assertEqual(result['packets_dropped'], expected['packets_dropped']) self.assertEqual(result['packets_fwd'], expected['packets_fwd']) - self.assertNotEqual(result['packets_fwd'], 0) - self.assertNotEqual(result['packets_fwd'], 0) + self.assertEqual(result['curr_packets_in'], expected['curr_packets_in']) + self.assertEqual(result['curr_packets_fwd'], expected['curr_packets_fwd']) + + @mock.patch.object(ctx_base.Context, 'get_physical_node_from_server', return_value='mock_node') + @mock.patch(SSH_HELPER) + def test_collect_kpi_bad_input(self, ssh, *args): + mock_ssh(ssh) + + resource_helper = mock.MagicMock() + resource_helper.execute.return_value = (True, + [[0, 'A', 'B', 'C', 'D', 'E'], + ['F', 1, 2, 3, 4, 5]]) + + prox_approx_vnf = prox_vnf.ProxApproxVnf(NAME, self.VNFD0, 'task_id') + prox_approx_vnf.scenario_helper.scenario_cfg = { + 'nodes': {prox_approx_vnf.name: "mock"} + } + prox_approx_vnf.resource_helper = resource_helper + + result = prox_approx_vnf.collect_kpi() + self.assertDictEqual(result, {}) + + @mock.patch.object(ctx_base.Context, 'get_physical_node_from_server', return_value='mock_node') + @mock.patch(SSH_HELPER) + def test_collect_kpi_bad_input2(self, ssh, *args): + mock_ssh(ssh) + + resource_helper = mock.MagicMock() + resource_helper.execute.return_value = (False, + [[0, 'A', 'B', 'C', 'D', 'E'], + ['F', 1, 2, 3, 4, 5]]) + + prox_approx_vnf = prox_vnf.ProxApproxVnf(NAME, self.VNFD0, 'task_id') + prox_approx_vnf.scenario_helper.scenario_cfg = { + 'nodes': {prox_approx_vnf.name: "mock"} + } + prox_approx_vnf.resource_helper = resource_helper + + result = prox_approx_vnf.collect_kpi() + self.assertDictEqual(result, {}) @mock.patch.object(ctx_base.Context, 'get_physical_node_from_server', return_value='mock_node') @mock.patch(SSH_HELPER) -- cgit 1.2.3-korg