From d3d4d83a420438f5ebfe453ab7ac63211bf0101f Mon Sep 17 00:00:00 2001 From: DanielMartinBuckley Date: Wed, 14 Nov 2018 17:09:51 +0000 Subject: Addition of IRQ Mode to NSB NFVI (PROX) JIRA: YARDSTICK-1524 Add dashboard, Traffic Profile support, PROX IRQ support, topology Change-Id: I0c0cde66f4f4d3d25aa77c502bd4349cc1b3eca2 Signed-off-by: Daniel Martin Buckley --- .../network_services/traffic_profile/__init__.py | 1 + .../network_services/traffic_profile/prox_irq.py | 48 +++++ .../vnf_generic/vnf/prox_helpers.py | 48 ++++- .../network_services/vnf_generic/vnf/prox_irq.py | 200 +++++++++++++++++++++ 4 files changed, 296 insertions(+), 1 deletion(-) create mode 100644 yardstick/network_services/traffic_profile/prox_irq.py create mode 100644 yardstick/network_services/vnf_generic/vnf/prox_irq.py (limited to 'yardstick/network_services') diff --git a/yardstick/network_services/traffic_profile/__init__.py b/yardstick/network_services/traffic_profile/__init__.py index 91d8a665f..72a61b6b4 100644 --- a/yardstick/network_services/traffic_profile/__init__.py +++ b/yardstick/network_services/traffic_profile/__init__.py @@ -23,6 +23,7 @@ def register_modules(): 'yardstick.network_services.traffic_profile.http_ixload', 'yardstick.network_services.traffic_profile.ixia_rfc2544', 'yardstick.network_services.traffic_profile.prox_ACL', + 'yardstick.network_services.traffic_profile.prox_irq', 'yardstick.network_services.traffic_profile.prox_binsearch', 'yardstick.network_services.traffic_profile.prox_profile', 'yardstick.network_services.traffic_profile.prox_ramp', diff --git a/yardstick/network_services/traffic_profile/prox_irq.py b/yardstick/network_services/traffic_profile/prox_irq.py new file mode 100644 index 000000000..0ea294914 --- /dev/null +++ b/yardstick/network_services/traffic_profile/prox_irq.py @@ -0,0 +1,48 @@ +# 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. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" Fixed traffic profile definitions """ + +import logging +import time + +from yardstick.network_services.traffic_profile.prox_profile import ProxProfile + +LOG = logging.getLogger(__name__) + + +class ProxIrqProfile(ProxProfile): + """ + This profile adds a single stream at the beginning of the traffic session + """ + + def __init__(self, tp_config): + super(ProxIrqProfile, self).__init__(tp_config) + + def init(self, queue): + self.queue = queue + self.queue.cancel_join_thread() + + def execute_traffic(self, traffic_generator): + LOG.debug("Prox_IRQ Execute Traffic....") + time.sleep(5) + + def is_ended(self): + return False + + def run_test(self): + """Run the test + """ + + LOG.info("Prox_IRQ ....") diff --git a/yardstick/network_services/vnf_generic/vnf/prox_helpers.py b/yardstick/network_services/vnf_generic/vnf/prox_helpers.py index 8d721c045..cd7ce6e9b 100644 --- a/yardstick/network_services/vnf_generic/vnf/prox_helpers.py +++ b/yardstick/network_services/vnf_generic/vnf/prox_helpers.py @@ -561,6 +561,41 @@ class ProxSocketHelper(object): tsc = int(ret[3]) return rx, tx, drop, tsc + def irq_core_stats(self, cores_tasks): + """ get IRQ stats per core""" + + stat = {} + core = 0 + task = 0 + for core, task in cores_tasks: + self.put_command("stats task.core({}).task({}).max_irq,task.core({}).task({}).irq(0)," + "task.core({}).task({}).irq(1),task.core({}).task({}).irq(2)," + "task.core({}).task({}).irq(3),task.core({}).task({}).irq(4)," + "task.core({}).task({}).irq(5),task.core({}).task({}).irq(6)," + "task.core({}).task({}).irq(7),task.core({}).task({}).irq(8)," + "task.core({}).task({}).irq(9),task.core({}).task({}).irq(10)," + "task.core({}).task({}).irq(11),task.core({}).task({}).irq(12)" + "\n".format(core, task, core, task, core, task, core, task, + core, task, core, task, core, task, core, task, + core, task, core, task, core, task, core, task, + core, task, core, task)) + in_data_str = self.get_data().split(",") + ret = [try_int(s, 0) for s in in_data_str] + key = "core_" + str(core) + try: + stat[key] = {"cpu": core, "max_irq": ret[0], "bucket_0" : ret[1], + "bucket_1" : ret[2], "bucket_2" : ret[3], + "bucket_3" : ret[4], "bucket_4" : ret[5], + "bucket_5" : ret[6], "bucket_6" : ret[7], + "bucket_7" : ret[8], "bucket_8" : ret[9], + "bucket_9" : ret[10], "bucket_10" : ret[11], + "bucket_11" : ret[12], "bucket_12" : ret[13], + "overflow": ret[10] + ret[11] + ret[12] + ret[13]} + except (KeyError, IndexError): + LOG.error("Corrupted PACKET %s", in_data_str) + + return stat + def multi_port_stats(self, ports): """get counter values from all ports at once""" @@ -661,7 +696,6 @@ class ProxSocketHelper(object): self.put_command("quit_force\n") time.sleep(3) - _LOCAL_OBJECT = object() @@ -1943,3 +1977,15 @@ class ProxlwAFTRProfileHelper(ProxProfileHelper): data_helper.latency = self.get_latency() return data_helper.result_tuple, data_helper.samples + + +class ProxIrqProfileHelper(ProxProfileHelper): + + __prox_profile_type__ = "IRQ Query" + + def __init__(self, resource_helper): + super(ProxIrqProfileHelper, self).__init__(resource_helper) + self._cores_tuple = None + self._ports_tuple = None + self.step_delta = 5 + self.step_time = 0.5 diff --git a/yardstick/network_services/vnf_generic/vnf/prox_irq.py b/yardstick/network_services/vnf_generic/vnf/prox_irq.py new file mode 100644 index 000000000..dda26b0fe --- /dev/null +++ b/yardstick/network_services/vnf_generic/vnf/prox_irq.py @@ -0,0 +1,200 @@ +# 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. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import errno +import logging +import copy +import time + +from yardstick.common.process import check_if_process_failed +from yardstick.network_services.utils import get_nsb_option +from yardstick.network_services.vnf_generic.vnf.prox_vnf import ProxApproxVnf +from yardstick.network_services.vnf_generic.vnf.sample_vnf import SampleVNFTrafficGen +from yardstick.benchmark.contexts.base import Context +from yardstick.network_services.vnf_generic.vnf.prox_helpers import CoreSocketTuple +LOG = logging.getLogger(__name__) + + +class ProxIrq(SampleVNFTrafficGen): + + def __init__(self, name, vnfd, task_id, setup_env_helper_type=None, + resource_helper_type=None): + vnfd_cpy = copy.deepcopy(vnfd) + super(ProxIrq, self).__init__(name, vnfd_cpy, task_id) + + self._vnf_wrapper = ProxApproxVnf( + name, vnfd, task_id, setup_env_helper_type, resource_helper_type) + self.bin_path = get_nsb_option('bin_path', '') + self.name = self._vnf_wrapper.name + self.ssh_helper = self._vnf_wrapper.ssh_helper + self.setup_helper = self._vnf_wrapper.setup_helper + self.resource_helper = self._vnf_wrapper.resource_helper + self.scenario_helper = self._vnf_wrapper.scenario_helper + self.irq_cores = None + + def terminate(self): + self._vnf_wrapper.terminate() + super(ProxIrq, self).terminate() + + def instantiate(self, scenario_cfg, context_cfg): + self._vnf_wrapper.instantiate(scenario_cfg, context_cfg) + self._tg_process = self._vnf_wrapper._vnf_process + + def wait_for_instantiate(self): + self._vnf_wrapper.wait_for_instantiate() + + def get_irq_cores(self): + cores = [] + mode = "irq" + + for section_name, section in self.setup_helper.prox_config_data: + if not section_name.startswith("core"): + continue + irq_mode = task_present = False + task_present_task = 0 + for key, value in section: + if key == "mode" and value == mode: + irq_mode = True + if key == "task": + task_present = True + task_present_task = int(value) + + if irq_mode: + if not task_present: + task_present_task = 0 + core_tuple = CoreSocketTuple(section_name) + core = core_tuple.core_id + cores.append((core, task_present_task)) + + return cores + +class ProxIrqVNF(ProxIrq, SampleVNFTrafficGen): + + APP_NAME = 'ProxIrqVNF' + + def __init__(self, name, vnfd, task_id, setup_env_helper_type=None, + resource_helper_type=None): + ProxIrq.__init__(self, name, vnfd, task_id, setup_env_helper_type, + resource_helper_type) + + self.start_test_time = None + self.end_test_time = None + + def vnf_execute(self, cmd, *args, **kwargs): + ignore_errors = kwargs.pop("_ignore_errors", False) + try: + return self.resource_helper.execute(cmd, *args, **kwargs) + except OSError as e: + if e.errno in {errno.EPIPE, errno.ESHUTDOWN, errno.ECONNRESET}: + if ignore_errors: + LOG.debug("ignoring vnf_execute exception %s for command %s", e, cmd) + else: + raise + else: + raise + + def collect_kpi(self): + # check if the tg processes have exited + physical_node = Context.get_physical_node_from_server( + self.scenario_helper.nodes[self.name]) + + result = {"physical_node": physical_node} + for proc in (self._tg_process, self._traffic_process): + check_if_process_failed(proc) + + if self.resource_helper is None: + return result + + if self.irq_cores is None: + self.setup_helper.build_config_file() + self.irq_cores = self.get_irq_cores() + + data = self.vnf_execute('irq_core_stats', self.irq_cores) + new_data = copy.deepcopy(data) + + self.end_test_time = time.time() + self.vnf_execute('reset_stats') + + if self.start_test_time is None: + new_data = {} + else: + test_time = self.end_test_time - self.start_test_time + for index, item in data.items(): + for counter, value in item.items(): + if counter.startswith("bucket_")or \ + counter.startswith("overflow"): + if value is 0: + del new_data[index][counter] + else: + new_data[index][counter] = float(value) / test_time + + self.start_test_time = time.time() + + result["collect_stats"] = new_data + LOG.debug("%s collect KPIs %s", self.APP_NAME, result) + + return result + +class ProxIrqGen(ProxIrq, SampleVNFTrafficGen): + + APP_NAME = 'ProxIrqGen' + + def __init__(self, name, vnfd, task_id, setup_env_helper_type=None, + resource_helper_type=None): + ProxIrq.__init__(self, name, vnfd, task_id, setup_env_helper_type, + resource_helper_type) + self.start_test_time = None + self.end_test_time = None + + def collect_kpi(self): + # check if the tg processes have exited + physical_node = Context.get_physical_node_from_server( + self.scenario_helper.nodes[self.name]) + + result = {"physical_node": physical_node} + for proc in (self._tg_process, self._traffic_process): + check_if_process_failed(proc) + + if self.resource_helper is None: + return result + + if self.irq_cores is None: + self.setup_helper.build_config_file() + self.irq_cores = self.get_irq_cores() + + data = self.resource_helper.sut.irq_core_stats(self.irq_cores) + new_data = copy.deepcopy(data) + + self.end_test_time = time.time() + self.resource_helper.sut.reset_stats() + + if self.start_test_time is None: + new_data = {} + else: + test_time = self.end_test_time - self.start_test_time + for index, item in data.items(): + for counter, value in item.items(): + if counter.startswith("bucket_") or \ + counter.startswith("overflow"): + if value is 0: + del new_data[index][counter] + else: + new_data[index][counter] = float(value) / test_time + + self.start_test_time = time.time() + + result["collect_stats"] = new_data + LOG.debug("%s collect KPIs %s", self.APP_NAME, result) + + return result -- cgit 1.2.3-korg