Merge "Introduced timeout to post method of HttpClient"
[yardstick.git] / yardstick / network_services / vnf_generic / vnf / prox_helpers.py
index d6ec271..d247101 100644 (file)
@@ -28,6 +28,7 @@ from contextlib import contextmanager
 from itertools import repeat, chain
 
 import six
+from multiprocessing import Queue
 from six.moves import zip, StringIO
 from six.moves import cStringIO
 
@@ -597,8 +598,9 @@ class ProxDpdkVnfSetupEnvHelper(DpdkVnfSetupEnvHelper):
         self.remote_path = None
         super(ProxDpdkVnfSetupEnvHelper, self).__init__(vnfd_helper, ssh_helper, scenario_helper)
         self.remote_prox_file_name = None
-        self.prox_config_dict = None
+        self._prox_config_data = None
         self.additional_files = {}
+        self.config_queue = Queue()
 
     def _build_pipeline_kwargs(self):
         tool_path = self.ssh_helper.provision_tool(tool_file=self.APP_NAME)
@@ -639,9 +641,10 @@ class ProxDpdkVnfSetupEnvHelper(DpdkVnfSetupEnvHelper):
         prox_config.parse()
 
         # Ensure MAC is set "hardware"
-        ext_intf = self.vnfd_helper.interfaces
-        # we are using enumeration to map logical port numbers to interfaces
-        for port_num, intf in enumerate(ext_intf):
+        all_ports = self.vnfd_helper.port_pairs.all_ports
+        # use dpdk port number
+        for port_name in all_ports:
+            port_num = self.vnfd_helper.port_num(port_name)
             port_section_name = "port {}".format(port_num)
             for section_name, section in sections:
                 if port_section_name != section_name:
@@ -659,13 +662,15 @@ class ProxDpdkVnfSetupEnvHelper(DpdkVnfSetupEnvHelper):
                 if item_val.startswith("@@dst_mac"):
                     tx_port_iter = re.finditer(r'\d+', item_val)
                     tx_port_no = int(next(tx_port_iter).group(0))
-                    mac = ext_intf[tx_port_no]["virtual-interface"]["dst_mac"]
+                    intf = self.vnfd_helper.find_interface_by_port(tx_port_no)
+                    mac = intf["virtual-interface"]["dst_mac"]
                     section_data[1] = mac.replace(":", " ", 6)
 
                 if item_key == "dst mac" and item_val.startswith("@@"):
                     tx_port_iter = re.finditer(r'\d+', item_val)
                     tx_port_no = int(next(tx_port_iter).group(0))
-                    mac = ext_intf[tx_port_no]["virtual-interface"]["dst_mac"]
+                    intf = self.vnfd_helper.find_interface_by_port(tx_port_no)
+                    mac = intf["virtual-interface"]["dst_mac"]
                     section_data[1] = mac
 
         # if addition file specified in prox config
@@ -714,13 +719,15 @@ class ProxDpdkVnfSetupEnvHelper(DpdkVnfSetupEnvHelper):
 
     def generate_prox_lua_file(self):
         p = OrderedDict()
-        ext_intf = self.vnfd_helper.interfaces
+        all_ports = self.vnfd_helper.port_pairs.all_ports
         lua_param = self.LUA_PARAMETER_NAME
-        for intf in ext_intf:
+        for port_name in all_ports:
             peer = self.LUA_PARAMETER_PEER[lua_param]
-            port_num = intf["virtual-interface"]["dpdk_port_num"]
-            local_ip = intf["local_ip"]
-            dst_ip = intf["dst_ip"]
+            port_num = self.vnfd_helper.port_num(port_name)
+            intf = self.vnfd_helper.find_interface(name=port_name)
+            vintf = intf['virtual-interface']
+            local_ip = vintf["local_ip"]
+            dst_ip = vintf["dst_ip"]
             local_ip_hex = ip_to_hex(local_ip, separator=' ')
             dst_ip_hex = ip_to_hex(dst_ip, separator=' ')
             p.update([
@@ -753,6 +760,15 @@ class ProxDpdkVnfSetupEnvHelper(DpdkVnfSetupEnvHelper):
 
         return remote_path
 
+    CONFIG_QUEUE_TIMEOUT = 120
+
+    @property
+    def prox_config_data(self):
+        if self._prox_config_data is None:
+            # this will block, but it needs too
+            self._prox_config_data = self.config_queue.get(True, self.CONFIG_QUEUE_TIMEOUT)
+        return self._prox_config_data
+
     def build_config_file(self):
         task_path = self.scenario_helper.task_path
         options = self.scenario_helper.options
@@ -766,13 +782,17 @@ class ProxDpdkVnfSetupEnvHelper(DpdkVnfSetupEnvHelper):
             prox_files = [prox_files]
         for key_prox_file in prox_files:
             base_prox_file = os.path.basename(key_prox_file)
-            remote_prox_file = self.copy_to_target(key_prox_file, base_prox_file)
+            key_prox_path = 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
 
-        self.prox_config_dict = self.generate_prox_config_file(config_path)
-        self.remote_path = self.upload_prox_config(config_file, self.prox_config_dict)
+        self._prox_config_data = self.generate_prox_config_file(config_path)
+        # copy config to queue so we can read it from traffic_runner process
+        self.config_queue.put(self._prox_config_data)
+        self.remote_path = self.upload_prox_config(config_file, self._prox_config_data)
 
     def build_config(self):
+        self.build_config_file()
 
         options = self.scenario_helper.options
 
@@ -788,6 +808,7 @@ class ProxDpdkVnfSetupEnvHelper(DpdkVnfSetupEnvHelper):
         return prox_cmd
 
 
+# this might be bad, sometimes we want regular ResourceHelper methods, like collect_kpi
 class ProxResourceHelper(ClientResourceHelper):
 
     RESOURCE_WORD = 'prox'
@@ -880,14 +901,23 @@ class ProxResourceHelper(ClientResourceHelper):
             self._run_traffic_once(traffic_profile)
 
     def _run_traffic_once(self, traffic_profile):
-        traffic_profile.execute(self)
+        traffic_profile.execute_traffic(self)
         if traffic_profile.done:
             self._queue.put({'done': True})
             LOG.debug("tg_prox done")
             self._terminated.value = 1
 
-    def start_collect(self):
-        pass
+    # For VNF use ResourceHelper method to collect KPIs directly.
+    # for TG leave the superclass ClientResourceHelper collect_kpi_method intact
+    def collect_collectd_kpi(self):
+        return self._collect_resource_kpi()
+
+    def collect_kpi(self):
+        result = super(ProxResourceHelper, self).collect_kpi()
+        # add in collectd kpis manually
+        if result:
+            result['collect_stats'] = self._collect_resource_kpi()
+        return result
 
     def terminate(self):
         # should not be called, use VNF terminate
@@ -922,12 +952,11 @@ class ProxResourceHelper(ClientResourceHelper):
             self.sut.stop_all()
 
     def run_test(self, pkt_size, duration, value, tolerated_loss=0.0):
-        # type: (object, object, object, object) -> object
         # do this assert in init?  unless we expect interface count to
         # change from one run to another run...
-        interfaces = self.vnfd_helper.interfaces
-        interface_count = len(interfaces)
-        assert interface_count in {1, 2, 4}, \
+        ports = self.vnfd_helper.port_pairs.all_ports
+        port_count = len(ports)
+        assert port_count in {1, 2, 4}, \
             "Invalid number of ports: 1, 2 or 4 ports only supported at this time"
 
         with self.traffic_context(pkt_size, value):
@@ -942,15 +971,18 @@ class ProxResourceHelper(ClientResourceHelper):
             latency = self.get_latency()
 
         deltas = data['delta']
-        rx_total, tx_total = self.sut.port_stats(range(interface_count))[6:8]
-        pps = value / 100.0 * self.line_rate_to_pps(pkt_size, interface_count)
+        rx_total, tx_total = self.sut.port_stats(range(port_count))[6:8]
+        pps = value / 100.0 * self.line_rate_to_pps(pkt_size, port_count)
 
         samples = {}
         # we are currently using enumeration to map logical port num to interface
-        for index, iface in enumerate(interfaces):
-            port_rx_total, port_tx_total = self.sut.port_stats([index])[6:8]
-            samples[iface["name"]] = {"in_packets": port_rx_total,
-                                      "out_packets": port_tx_total}
+        for port_name in ports:
+            port = self.vnfd_helper.port_num(port_name)
+            port_rx_total, port_tx_total = self.sut.port_stats([port])[6:8]
+            samples[port_name] = {
+                "in_packets": port_rx_total,
+                "out_packets": port_tx_total,
+            }
 
         result = ProxTestDataTuple(tolerated_loss, tsc_hz, deltas.rx, deltas.tx,
                                    deltas.tsc, latency, rx_total, tx_total, pps)
@@ -959,7 +991,7 @@ class ProxResourceHelper(ClientResourceHelper):
 
     def get_test_type(self):
         test_type = None
-        for section_name, section in self.setup_helper.prox_config_dict:
+        for section_name, section in self.setup_helper.prox_config_data:
             if section_name != "global":
                 continue
 
@@ -972,7 +1004,7 @@ class ProxResourceHelper(ClientResourceHelper):
     def get_cores(self, mode):
         cores = []
 
-        for section_name, section in self.setup_helper.prox_config_dict:
+        for section_name, section in self.setup_helper.prox_config_data:
             if not section_name.startswith("core"):
                 continue
 
@@ -987,7 +1019,7 @@ class ProxResourceHelper(ClientResourceHelper):
     def get_cores_mpls(self, mode=PROX_CORE_GEN_MODE):
         cores_tagged = []
         cores_plain = []
-        for section_name, section in self.setup_helper.prox_config_dict:
+        for section_name, section in self.setup_helper.prox_config_data:
             if not section_name.startswith("core"):
                 continue
 
@@ -1016,9 +1048,6 @@ class ProxResourceHelper(ClientResourceHelper):
             return self.sut.lat_stats(self._latency_cores)
         return []
 
-    def _get_logical_if_name(self, vpci):
-        return self._vpci_to_if_name_map[vpci]
-
     def _connect(self, client=None):
         """Run and connect to prox on the remote system """
         # De-allocating a large amount of hugepages takes some time. If a new