Update Multi Port Stats reading for PROX 85/64585/1
authorDanielMartinBuckley <daniel.m.buckley@intel.com>
Thu, 5 Jul 2018 16:55:29 +0000 (17:55 +0100)
committerAbhijit Sinha <abhijit.sinha@intel.com>
Tue, 6 Nov 2018 11:28:28 +0000 (11:28 +0000)
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 <daniel.m.buckley@intel.com>
(cherry picked from commit b2fd601c33e3322ccc9e675242f091dba2eeb644)

yardstick/network_services/constants.py
yardstick/network_services/traffic_profile/prox_profile.py
yardstick/network_services/vnf_generic/vnf/prox_helpers.py
yardstick/network_services/vnf_generic/vnf/prox_vnf.py
yardstick/tests/unit/network_services/vnf_generic/vnf/test_prox_helpers.py
yardstick/tests/unit/network_services/vnf_generic/vnf/test_prox_vnf.py

index 0064b4f..5a186be 100644 (file)
@@ -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
index de4b3f9..be450c9 100644 (file)
@@ -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
 
index 321c057..8d721c0 100644 (file)
@@ -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):
index 839f309..c3b5036 100644 (file)
@@ -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
index 3d6ebb2..894b16e 100644 (file)
@@ -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)
index f144e8c..62cbea0 100644 (file)
@@ -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)