diff options
Diffstat (limited to 'yardstick/network_services')
8 files changed, 80 insertions, 95 deletions
diff --git a/yardstick/network_services/vnf_generic/vnf/acl_vnf.py b/yardstick/network_services/vnf_generic/vnf/acl_vnf.py index 3ba38dec2..1390dd02e 100644 --- a/yardstick/network_services/vnf_generic/vnf/acl_vnf.py +++ b/yardstick/network_services/vnf_generic/vnf/acl_vnf.py @@ -61,9 +61,6 @@ class AclApproxVnf(SampleVNF): super(AclApproxVnf, self).__init__(name, vnfd, setup_env_helper_type, resource_helper_type) self.acl_rules = None - def scale(self, flavor=""): - raise NotImplementedError - def _start_vnf(self): yang_model_path = find_relative_file(self.scenario_helper.options['rules'], self.scenario_helper.task_path) diff --git a/yardstick/network_services/vnf_generic/vnf/base.py b/yardstick/network_services/vnf_generic/vnf/base.py index 8ed754dce..a776b0989 100644 --- a/yardstick/network_services/vnf_generic/vnf/base.py +++ b/yardstick/network_services/vnf_generic/vnf/base.py @@ -138,76 +138,62 @@ class VnfdHelper(dict): yield port_name, port_num -class VNFObject(object): +@six.add_metaclass(abc.ABCMeta) +class GenericVNF(object): + """Class providing file-like API for generic VNF implementation + + Currently the only class implementing this interface is + yardstick/network_services/vnf_generic/vnf/sample_vnf:SampleVNF. + """ # centralize network naming convention UPLINK = PortPairs.UPLINK DOWNLINK = PortPairs.DOWNLINK def __init__(self, name, vnfd): - super(VNFObject, self).__init__() self.name = name - self.vnfd_helper = VnfdHelper(vnfd) # fixme: parse this into a structure - - -class GenericVNF(VNFObject): - - """ Class providing file-like API for generic VNF implementation """ - def __init__(self, name, vnfd): - super(GenericVNF, self).__init__(name, vnfd) + self.vnfd_helper = VnfdHelper(vnfd) # List of statistics we can obtain from this VNF # - ETSI MANO 6.3.1.1 monitoring_parameter - self.kpi = self._get_kpi_definition() + self.kpi = self.vnfd_helper.kpi # Standard dictionary containing params like thread no, buffer size etc self.config = {} self.runs_traffic = False - def _get_kpi_definition(self): - """ Get list of KPIs defined in VNFD - - :param vnfd: - :return: list of KPIs, e.g. ['throughput', 'latency'] - """ - return self.vnfd_helper.kpi - + @abc.abstractmethod def instantiate(self, scenario_cfg, context_cfg): - """ Prepare VNF for operation and start the VNF process/VM + """Prepare VNF for operation and start the VNF process/VM - :param scenario_cfg: - :param context_cfg: + :param scenario_cfg: Scenario config + :param context_cfg: Context config :return: True/False """ - raise NotImplementedError() + @abc.abstractmethod def wait_for_instantiate(self): - """ Wait for VNF to start + """Wait for VNF to start :return: True/False """ - raise NotImplementedError() + @abc.abstractmethod def terminate(self): - """ Kill all VNF processes - - :return: - """ - raise NotImplementedError() + """Kill all VNF processes""" + @abc.abstractmethod def scale(self, flavor=""): - """ + """rest - :param flavor: + :param flavor: Name of the flavor. :return: """ - raise NotImplementedError() + @abc.abstractmethod def collect_kpi(self): - """This method should return a dictionary containing the - selected KPI at a given point of time. + """Return a dict containing the selected KPI at a given point of time :return: {"kpi": value, "kpi2": value} """ - raise NotImplementedError() @six.add_metaclass(abc.ABCMeta) diff --git a/yardstick/network_services/vnf_generic/vnf/prox_helpers.py b/yardstick/network_services/vnf_generic/vnf/prox_helpers.py index ba066333d..285ead3b6 100644 --- a/yardstick/network_services/vnf_generic/vnf/prox_helpers.py +++ b/yardstick/network_services/vnf_generic/vnf/prox_helpers.py @@ -11,7 +11,6 @@ # 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. -from __future__ import absolute_import import array import io @@ -363,9 +362,9 @@ class ProxSocketHelper(object): """ send data to the remote instance """ LOG.debug("Sending data to socket: [%s]", to_send.rstrip('\n')) try: - # TODO: sendall will block, we need a timeout + # NOTE: sendall will block, we need a timeout self._sock.sendall(to_send.encode('utf-8')) - except: + except: # pylint: disable=bare-except pass def get_packet_dump(self): @@ -539,7 +538,7 @@ class ProxSocketHelper(object): finally: container['end_tot'] = end = self.get_all_tot_stats() - container['delta'] = TotStatsTuple(end - start for start, end in zip(start, end)) + container['delta'] = TotStatsTuple(e - s for s, e in zip(start, end)) def tot_stats(self): """Get the total statistics from the remote system""" @@ -637,13 +636,6 @@ class ProxDpdkVnfSetupEnvHelper(DpdkVnfSetupEnvHelper): raise KeyError(template.format(section_key, section_name)) return result - def _build_pipeline_kwargs(self): - tool_path = self.ssh_helper.provision_tool(tool_file=self.APP_NAME) - self.pipeline_kwargs = { - 'tool_path': tool_path, - 'tool_dir': os.path.dirname(tool_path), - } - def copy_to_target(self, config_file_path, prox_file): remote_path = os.path.join("/tmp", prox_file) self.ssh_helper.put(config_file_path, remote_path) @@ -685,14 +677,13 @@ class ProxDpdkVnfSetupEnvHelper(DpdkVnfSetupEnvHelper): if port_section_name != section_name: continue - for index, section_data in enumerate(section): + for section_data in section: if section_data[0] == "mac": section_data[1] = "hardware" # search for dst mac for _, section in sections: - # for index, (item_key, item_val) in enumerate(section): - for index, section_data in enumerate(section): + for section_data in section: item_key, item_val = section_data if item_val.startswith("@@dst_mac"): tx_port_iter = re.finditer(r'\d+', item_val) @@ -713,14 +704,14 @@ class ProxDpdkVnfSetupEnvHelper(DpdkVnfSetupEnvHelper): return sections for section_name, section in sections: - for index, section_data in enumerate(section): + for section_data in section: try: if section_data[0].startswith("dofile"): section_data[0] = self._insert_additional_file(section_data[0]) if section_data[1].startswith("dofile"): section_data[1] = self._insert_additional_file(section_data[1]) - except: + except: # pylint: disable=bare-except pass return sections @@ -753,9 +744,9 @@ class ProxDpdkVnfSetupEnvHelper(DpdkVnfSetupEnvHelper): a custom method """ out = [] - for i, (section_name, section) in enumerate(prox_config): + for (section_name, section) in prox_config: out.append("[{}]".format(section_name)) - for index, item in enumerate(section): + for item in section: key, value = item if key == "__name__": continue @@ -816,7 +807,7 @@ class ProxDpdkVnfSetupEnvHelper(DpdkVnfSetupEnvHelper): self.lua = self.generate_prox_lua_file() if len(self.lua) > 0: self.upload_prox_lua("parameters.lua", self.lua) - except: + except: # pylint: disable=bare-except pass prox_files = options.get('prox_files', []) @@ -837,17 +828,20 @@ class ProxDpdkVnfSetupEnvHelper(DpdkVnfSetupEnvHelper): self.build_config_file() options = self.scenario_helper.options - prox_args = options['prox_args'] - LOG.info("Provision and start the %s", self.APP_NAME) - self._build_pipeline_kwargs() - self.pipeline_kwargs["args"] = " ".join( - " ".join([k, v if v else ""]) for k, v in prox_args.items()) - self.pipeline_kwargs["cfg_file"] = self.remote_path + tool_path = self.ssh_helper.join_bin_path(self.APP_NAME) + + self.pipeline_kwargs = { + 'tool_path': tool_path, + 'tool_dir': os.path.dirname(tool_path), + 'cfg_file': self.remote_path, + 'args': ' '.join(' '.join([str(k), str(v) if v else '']) + for k, v in prox_args.items()) + } - cmd_template = "sudo bash -c 'cd {tool_dir}; {tool_path} -o cli {args} -f {cfg_file} '" - prox_cmd = cmd_template.format(**self.pipeline_kwargs) - return prox_cmd + cmd_template = ("sudo bash -c 'cd {tool_dir}; {tool_path} -o cli " + "{args} -f {cfg_file} '") + return cmd_template.format(**self.pipeline_kwargs) # this might be bad, sometimes we want regular ResourceHelper methods, like collect_kpi @@ -1057,7 +1051,7 @@ class ProxDataHelper(object): self.tsc_hz = float(self.sut.hz()) def line_rate_to_pps(self): - # FIXME Don't hardcode 10Gb/s + # NOTE: to fix, don't hardcode 10Gb/s return self.port_count * TEN_GIGABIT / BITS_PER_BYTE / (self.pkt_size + 20) @@ -1658,7 +1652,7 @@ class ProxlwAFTRProfileHelper(ProxProfileHelper): tun_ports = [] inet_ports = [] - re_port = re.compile('port (\d+)') + re_port = re.compile(r'port (\d+)') for section_name, section in self.resource_helper.setup_helper.prox_config_data: match = re_port.search(section_name) if not match: diff --git a/yardstick/network_services/vnf_generic/vnf/sample_vnf.py b/yardstick/network_services/vnf_generic/vnf/sample_vnf.py index 20e5895ee..5eeb6c889 100644 --- a/yardstick/network_services/vnf_generic/vnf/sample_vnf.py +++ b/yardstick/network_services/vnf_generic/vnf/sample_vnf.py @@ -28,6 +28,7 @@ from six.moves import cStringIO from yardstick.benchmark.contexts.base import Context from yardstick.benchmark.scenarios.networking.vnf_generic import find_relative_file +from yardstick.common import exceptions as y_exceptions from yardstick.common.process import check_if_process_failed from yardstick.network_services.helpers.samplevnf_helper import PortPairs from yardstick.network_services.helpers.samplevnf_helper import MultiPortConfig @@ -308,7 +309,7 @@ class DpdkVnfSetupEnvHelper(SetupEnvHelper): if vpci == v['virtual-interface']['vpci']) # force to int intf['virtual-interface']['dpdk_port_num'] = int(dpdk_port_num) - except: + except: # pylint: disable=bare-except pass time.sleep(2) @@ -472,6 +473,11 @@ class ClientResourceHelper(ResourceHelper): self.client.clear_stats(ports=ports) def start(self, ports=None, *args, **kwargs): + # pylint: disable=keyword-arg-before-vararg + # NOTE(ralonsoh): defining keyworded arguments before variable + # positional arguments is a bug. This function definition doesn't work + # in Python 2, although it works in Python 3. Reference: + # https://www.python.org/dev/peps/pep-3102/ if ports is None: ports = self.all_ports self.client.start(ports=ports, *args, **kwargs) @@ -480,8 +486,8 @@ class ClientResourceHelper(ResourceHelper): if not self._queue.empty(): kpi = self._queue.get() self._result.update(kpi) - LOG.debug("Got KPIs from _queue for {0} {1}".format( - self.scenario_helper.name, self.RESOURCE_WORD)) + LOG.debug('Got KPIs from _queue for %s %s', + self.scenario_helper.name, self.RESOURCE_WORD) return self._result def _connect(self, client=None): @@ -670,7 +676,7 @@ class SampleVNF(GenericVNF): self.pipeline_kwargs = {} self.uplink_ports = None self.downlink_ports = None - # TODO(esm): make QueueFileWrapper invert-able so that we + # NOTE(esm): make QueueFileWrapper invert-able so that we # never have to manage the queues self.q_in = Queue() self.q_out = Queue() @@ -751,7 +757,7 @@ class SampleVNF(GenericVNF): if not self._vnf_process.is_alive(): raise RuntimeError("%s VNF process died." % self.APP_NAME) - # TODO(esm): move to QueueFileWrapper + # NOTE(esm): move to QueueFileWrapper while self.q_out.qsize() > 0: buf.append(self.q_out.get()) message = ''.join(buf) @@ -821,12 +827,12 @@ class SampleVNF(GenericVNF): self._vnf_process.terminate() # no terminate children here because we share processes with tg - def get_stats(self, *args, **kwargs): - """ - Method for checking the statistics + def get_stats(self, *args, **kwargs): # pylint: disable=unused-argument + """Method for checking the statistics + + This method could be overridden in children classes. - :return: - VNF statistics + :return: VNF statistics """ cmd = 'p {0} stats'.format(self.APP_WORD) out = self.vnf_execute(cmd) @@ -849,6 +855,11 @@ class SampleVNF(GenericVNF): LOG.debug("%s collect KPIs %s", self.APP_NAME, result) return result + def scale(self, flavor=""): + """The SampleVNF base class doesn't provide the 'scale' feature""" + raise y_exceptions.FunctionNotImplemented( + function_name='scale', class_name='SampleVNFTrafficGen') + class SampleVNFTrafficGen(GenericTrafficGen): """ Class providing file-like API for generic traffic generator """ @@ -964,3 +975,8 @@ class SampleVNFTrafficGen(GenericTrafficGen): self._tg_process.join(PROCESS_JOIN_TIMEOUT) self._tg_process.terminate() # no terminate children here because we share processes with vnf + + def scale(self, flavor=""): + """A traffic generator VFN doesn't provide the 'scale' feature""" + raise y_exceptions.FunctionNotImplemented( + function_name='scale', class_name='SampleVNFTrafficGen') diff --git a/yardstick/network_services/vnf_generic/vnf/tg_ixload.py b/yardstick/network_services/vnf_generic/vnf/tg_ixload.py index 61c045405..3ab30b53e 100644 --- a/yardstick/network_services/vnf_generic/vnf/tg_ixload.py +++ b/yardstick/network_services/vnf_generic/vnf/tg_ixload.py @@ -91,7 +91,7 @@ class IxLoadResourceHelper(ClientResourceHelper): self.result[key].append(value) def setup(self): - # TODO: fixupt scenario_helper to hanlde ixia + # NOTE: fixup scenario_helper to hanlde ixia self.resource_file_name = \ find_relative_file(self.scenario_helper.scenario_cfg['ixia_profile'], self.scenario_helper.scenario_cfg["task_path"]) @@ -113,7 +113,7 @@ class IxLoadResourceHelper(ClientResourceHelper): def collect_kpi(self): if self.data: self._result.update(self.data) - LOG.info("Collect {0} KPIs {1}".format(self.RESOURCE_WORD, self._result)) + LOG.info("Collect %s KPIs %s", self.RESOURCE_WORD, self._result) return self._result def log(self): @@ -170,9 +170,6 @@ class IxLoadTrafficGen(SampleVNFTrafficGen): self.resource_helper.log() self.resource_helper.data = self.resource_helper.make_aggregates() - def instantiate(self, scenario_cfg, context_cfg): - super(IxLoadTrafficGen, self).instantiate(scenario_cfg, context_cfg) - def terminate(self): call(["pkill", "-9", "http_ixload.py"]) super(IxLoadTrafficGen, self).terminate() diff --git a/yardstick/network_services/vnf_generic/vnf/tg_ping.py b/yardstick/network_services/vnf_generic/vnf/tg_ping.py index 5238a5f02..a989543f5 100644 --- a/yardstick/network_services/vnf_generic/vnf/tg_ping.py +++ b/yardstick/network_services/vnf_generic/vnf/tg_ping.py @@ -113,10 +113,6 @@ class PingTrafficGen(SampleVNFTrafficGen): resource_helper_type) self._result = {} - def scale(self, flavor=""): - """ scale vnf-based on flavor input """ - pass - def _check_status(self): return self._tg_process.is_alive() diff --git a/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_ixia.py b/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_ixia.py index a8b19cfba..630c8b9c0 100644 --- a/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_ixia.py +++ b/yardstick/network_services/vnf_generic/vnf/tg_rfc2544_ixia.py @@ -174,7 +174,7 @@ class IxiaResourceHelper(ClientResourceHelper): break self.client.ix_stop_traffic() - except Exception: + except Exception: # pylint: disable=broad-except LOG.exception("Run Traffic terminated") self._terminated.value = 1 @@ -201,9 +201,6 @@ class IxiaTrafficGen(SampleVNFTrafficGen): def _check_status(self): pass - def scale(self, flavor=""): - pass - def terminate(self): self.resource_helper.stop_collect() super(IxiaTrafficGen, self).terminate() diff --git a/yardstick/network_services/vnf_generic/vnf/tg_trex.py b/yardstick/network_services/vnf_generic/vnf/tg_trex.py index 4250cb7a6..0084a124c 100644 --- a/yardstick/network_services/vnf_generic/vnf/tg_trex.py +++ b/yardstick/network_services/vnf_generic/vnf/tg_trex.py @@ -126,6 +126,11 @@ class TrexResourceHelper(ClientResourceHelper): self.ssh_helper.execute(self.MAKE_INSTALL.format(ko_src)) def start(self, ports=None, *args, **kwargs): + # pylint: disable=keyword-arg-before-vararg + # NOTE(ralonsoh): defining keyworded arguments before variable + # positional arguments is a bug. This function definition doesn't work + # in Python 2, although it works in Python 3. Reference: + # https://www.python.org/dev/peps/pep-3102/ cmd = "sudo fuser -n tcp {0.SYNC_PORT} {0.ASYNC_PORT} -k > /dev/null 2>&1" self.ssh_helper.execute(cmd.format(self)) @@ -186,9 +191,6 @@ class TrexTrafficGen(SampleVNFTrafficGen): super(TrexTrafficGen, self)._start_server() self.resource_helper.start() - def scale(self, flavor=""): - pass - def terminate(self): self.resource_helper.terminate() |