Decrease Sampling interval 61/58261/21
authorDanielMartinBuckley <daniel.m.buckley@intel.com>
Tue, 5 Jun 2018 18:06:38 +0000 (19:06 +0100)
committerAbhijit Sinha <abhijit.sinha@intel.com>
Tue, 26 Jun 2018 17:40:07 +0000 (17:40 +0000)
JIRA: YARDSTICK-1219

Currently NSB for NFVI using PROX returns sampling information every 13
seconds.

This is too slow.

It is required to return sampling information form Generator AND VNF at
least every  1 second.

This change is depandant on JIRA: YARDSTICK-1212 and YARDSTICK-1220

Change-Id: Ica7ab795a2919d191d8cd846d028e15739e33fb7
Signed-off-by: Daniel Martin Buckley <daniel.m.buckley@intel.com>
yardstick/network_services/vnf_generic/vnf/prox_helpers.py
yardstick/network_services/vnf_generic/vnf/prox_vnf.py
yardstick/tests/unit/common/test_utils.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 7816c6d..ad826f9 100644 (file)
@@ -325,7 +325,7 @@ class ProxSocketHelper(object):
 
         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
@@ -532,6 +532,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
@@ -1012,7 +1057,11 @@ 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]
+            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
@@ -1032,19 +1081,18 @@ class ProxDataHelper(object):
     @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):
index 36f1a19..63295c2 100644 (file)
@@ -89,14 +89,15 @@ class ProxApproxVnf(SampleVNF):
             raise RuntimeError("Failed ..Invalid no of ports .. "
                                "1, 2 or 4 ports only supported at this time")
 
-        self.port_stats = self.vnf_execute('port_stats', range(port_count))
+        all_port_stats = self.vnf_execute('multi_port_stats', range(port_count))
+        rx_total = tx_total = 0
         try:
-            rx_total = self.port_stats[6]
-            tx_total = self.port_stats[7]
-            tsc = self.port_stats[10]
-        except IndexError:
-            LOG.debug("port_stats parse fail ")
-            # return empty dict so we don't mess up existing KPIs
+            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 = single_port_stats[5]
+        except (TypeError, IndexError):
+            LOG.error("Invalid data ...")
             return {}
 
         result = {
@@ -107,10 +108,19 @@ class ProxApproxVnf(SampleVNF):
             # collectd KPIs here and not TG KPIs, so use a different method name
             "collect_stats": self.resource_helper.collect_collectd_kpi(),
         }
-        curr_packets_in = int(((rx_total - self.prev_packets_in) * self.tsc_hz)
+        try:
+            curr_packets_in = int(((rx_total - self.prev_packets_in) * self.tsc_hz)
                                 / (tsc - self.prev_tsc) * port_count)
-        curr_packets_fwd = int(((tx_total - self.prev_packets_sent) * self.tsc_hz)
+        except ZeroDivisionError:
+            LOG.error("Error.... Divide by Zero")
+            curr_packets_in = 0
+
+        try:
+            curr_packets_fwd = int(((tx_total - self.prev_packets_sent) * self.tsc_hz)
                                 / (tsc - self.prev_tsc) * port_count)
+        except ZeroDivisionError:
+            LOG.error("Error.... Divide by Zero")
+            curr_packets_fwd = 0
 
         result["curr_packets_in"] = curr_packets_in
         result["curr_packets_fwd"] = curr_packets_fwd
index 6e7a0bf..6247afd 100644 (file)
@@ -19,6 +19,7 @@ from six.moves import configparser
 import time
 import unittest
 
+import yardstick
 from yardstick import ssh
 from yardstick.common import constants
 from yardstick.common import utils
index cc695a5..1c3acb6 100644 (file)
@@ -560,6 +560,31 @@ class TestProxSocketHelper(unittest.TestCase):
         result = prox.core_stats([3, 4, 5], 16)
         self.assertEqual(result, expected)
 
+    def test_multi_port_stats(self):
+
+        mock_socket = mock.MagicMock()
+        prox = ProxSocketHelper(mock_socket)
+        prox.get_data = mock.MagicMock(return_value='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])
+        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(result, expected)
+
+
     def test_port_stats(self):
         port_stats = [
             ','.join(str(n) for n in range(3, 15)),
@@ -1546,34 +1571,34 @@ class TestProxDataHelper(unittest.TestCase):
         vnfd_helper.port_pairs.all_ports = list(range(4))
 
         sut = mock.MagicMock()
-        sut.port_stats.return_value = list(range(10))
+        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]]
 
         data_helper = ProxDataHelper(
             vnfd_helper, sut, pkt_size, 25, None,
             constants.NIC_GBPS_DEFAULT * constants.ONE_GIGABIT_IN_BITS)
 
-        self.assertEqual(data_helper.rx_total, 6)
-        self.assertEqual(data_helper.tx_total, 7)
+        self.assertEqual(data_helper.rx_total, 4)
+        self.assertEqual(data_helper.tx_total, 8)
         self.assertEqual(data_helper.requested_pps, 6.25e6)
 
     def test_samples(self):
         vnfd_helper = mock.MagicMock()
-        vnfd_helper.port_pairs.all_ports = list(range(4))
-        vnfd_helper.ports_iter.return_value = [('xe1', 3), ('xe2', 7)]
+        vnfd_helper.ports_iter.return_value = [('xe0', 0), ('xe1', 1)]
 
         sut = mock.MagicMock()
-        sut.port_stats.return_value = list(range(10))
+        sut.multi_port_stats.return_value = [[0, 1, 2, 3, 4, 5], [1, 11, 12, 3, 4, 5]]
 
         data_helper = ProxDataHelper(vnfd_helper, sut, None, None, None, None)
 
         expected = {
-            'xe1': {
-                'in_packets': 6,
-                'out_packets': 7,
+            'xe0': {
+                'in_packets': 1,
+                'out_packets': 2,
             },
-            'xe2': {
-                'in_packets': 6,
-                'out_packets': 7,
+            'xe1': {
+                'in_packets': 11,
+                'out_packets': 12,
             },
         }
         result = data_helper.samples
index f5f4b39..b23854e 100644 (file)
@@ -339,16 +339,17 @@ class TestProxApproxVnf(unittest.TestCase):
         mock_ssh(ssh)
 
         resource_helper = mock.MagicMock()
-        resource_helper.execute.return_value = list(range(12))
+        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.collect_collectd_kpi.return_value = {'core': {'result': 234}}
 
         prox_approx_vnf = ProxApproxVnf(NAME, self.VNFD0)
         prox_approx_vnf.resource_helper = resource_helper
 
         expected = {
-            'packets_in': 6,
-            'packets_dropped': 1,
-            'packets_fwd': 7,
+            'packets_in': 4,
+            'packets_dropped': 4,
+            'packets_fwd': 8,
             'collect_stats': {'core': {'result': 234}},
         }
         result = prox_approx_vnf.collect_kpi()