X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=yardstick%2Fnetwork_services%2Fvnf_generic%2Fvnf%2Ftg_ping.py;h=a989543f50821cfe1774159848fccbba1830a47c;hb=9008c4f324b368dcd8594b7af76875e9b2720917;hp=2844a5c01ba7f688c19c5692c77bb8f4a78779f0;hpb=d45d6aacdd769f07bfc2bad92be57a1c2ccf5d1f;p=yardstick.git diff --git a/yardstick/network_services/vnf_generic/vnf/tg_ping.py b/yardstick/network_services/vnf_generic/vnf/tg_ping.py index 2844a5c01..a989543f5 100644 --- a/yardstick/network_services/vnf_generic/vnf/tg_ping.py +++ b/yardstick/network_services/vnf_generic/vnf/tg_ping.py @@ -14,16 +14,15 @@ """ PING acts as traffic generation and vnf definitions based on IETS Spec """ from __future__ import absolute_import -from __future__ import print_function import logging -import multiprocessing import re -import time -import os -from yardstick import ssh -from yardstick.network_services.vnf_generic.vnf.base import GenericTrafficGen -from yardstick.network_services.utils import provision_tool +from multiprocessing import Queue +from ipaddress import IPv4Interface + +from yardstick.network_services.vnf_generic.vnf.sample_vnf import SampleVNFTrafficGen +from yardstick.network_services.vnf_generic.vnf.sample_vnf import DpdkVnfSetupEnvHelper +from yardstick.network_services.vnf_generic.vnf.sample_vnf import ClientResourceHelper LOG = logging.getLogger(__name__) @@ -42,126 +41,91 @@ class PingParser(object): if match: # IMPORTANT: in order for the data to be properly taken # in by InfluxDB, it needs to be converted to numeric types - self.queue.put({"packets_received": float(match.group(1)), - "rtt": float(match.group(2))}) + self.queue.put({ + "packets_received": float(match.group(1)), + "rtt": float(match.group(2)), + }) def close(self): - ''' close the ssh connection ''' - pass + """ close the ssh connection """ + self.closed = True def clear(self): - ''' clear queue till Empty ''' + """ clear queue till Empty """ while self.queue.qsize() > 0: self.queue.get() -class PingTrafficGen(GenericTrafficGen): +class PingSetupEnvHelper(DpdkVnfSetupEnvHelper): + + def setup_vnf_environment(self): + for intf in self.vnfd_helper.interfaces: + vi = intf['virtual-interface'] + vi['local_iface_name'] = self.get_local_iface_name_by_vpci(vi['vpci']) + + +class PingResourceHelper(ClientResourceHelper): + + def __init__(self, setup_helper): + super(PingResourceHelper, self).__init__(setup_helper) + self._queue = Queue() + self._parser = PingParser(self._queue) + + def run_traffic(self, traffic_profile): + # drop the connection in order to force a new one + self.ssh_helper.drop_connection() + + self.client_started.value = 1 + cmd_list = [ + "sudo ip addr flush {local_if_name}", + "sudo ip addr add {local_ip}/24 dev {local_if_name}", + "sudo ip link set {local_if_name} up", + ] + + self.cmd_kwargs['packet_size'] = traffic_profile.params['traffic_profile']['frame_size'] + + for cmd in cmd_list: + self.ssh_helper.execute(cmd.format(**self.cmd_kwargs)) + + ping_cmd = "nohup ping -s {packet_size} {target_ip}&" + self.ssh_helper.run(ping_cmd.format(**self.cmd_kwargs), + stdout=self._parser, + keep_stdin_open=True, pty=True) + + +class PingTrafficGen(SampleVNFTrafficGen): """ This traffic generator can ping a single IP with pingsize and target given in traffic profile """ - def __init__(self, vnfd): - super(PingTrafficGen, self).__init__(vnfd) - self._result = {} - self._parser = None - self._queue = None - self._traffic_process = None - - mgmt_interface = vnfd["mgmt-interface"] - ssh_port = mgmt_interface.get("ssh_port", ssh.DEFAULT_PORT) - LOG.debug("Connecting to %s", mgmt_interface["ip"]) - - self.connection = ssh.SSH(mgmt_interface["user"], mgmt_interface["ip"], - password=mgmt_interface["password"], - port=ssh_port) - self.connection.wait() - - def _bind_device_kernel(self, connection): - dpdk_nic_bind = \ - provision_tool(self.connection, - os.path.join(self.bin_path, "dpdk_nic_bind.py")) - - drivers = {intf["virtual-interface"]["vpci"]: - intf["virtual-interface"]["driver"] - for intf in self.vnfd["vdu"][0]["external-interface"]} - - commands = \ - ['"{0}" --force -b "{1}" "{2}"'.format(dpdk_nic_bind, value, key) - for key, value in drivers.items()] - for command in commands: - connection.execute(command) - - for index, out in enumerate(self.vnfd["vdu"][0]["external-interface"]): - vpci = out["virtual-interface"]["vpci"] - net = "find /sys/class/net -lname '*{}*' -printf '%f'".format(vpci) - out = connection.execute(net)[1] - ifname = out.split('/')[-1].strip('\n') - self.vnfd["vdu"][0]["external-interface"][index][ - "virtual-interface"]["local_iface_name"] = ifname - - def scale(self, flavor=""): - ''' scale vnfbased on flavor input ''' - super(PingTrafficGen, self).scale(flavor) + TG_NAME = 'Ping' + APP_NAME = 'Ping' + RUN_WAIT = 4 - def instantiate(self, scenario_cfg, context_cfg): - self._result = {"packets_received": 0, "rtt": 0} - self._bind_device_kernel(self.connection) + def __init__(self, name, vnfd, setup_env_helper_type=None, resource_helper_type=None): + if setup_env_helper_type is None: + setup_env_helper_type = PingSetupEnvHelper + if resource_helper_type is None: + resource_helper_type = PingResourceHelper - def run_traffic(self, traffic_profile): - self._queue = multiprocessing.Queue() - self._parser = PingParser(self._queue) - self._traffic_process = \ - multiprocessing.Process(target=self._traffic_runner, - args=(traffic_profile, self._parser)) - self._traffic_process.start() - # Wait for traffic process to start - time.sleep(4) - return self._traffic_process.is_alive() - - def listen_traffic(self, traffic_profile): - """ Not needed for ping - - :param traffic_profile: - :return: - """ - pass - - def _traffic_runner(self, traffic_profile, filewrapper): - - mgmt_interface = self.vnfd["mgmt-interface"] - ssh_port = mgmt_interface.get("ssh_port", ssh.DEFAULT_PORT) - self.connection = ssh.SSH(mgmt_interface["user"], mgmt_interface["ip"], - password=mgmt_interface["password"], - port=ssh_port) - self.connection.wait() - external_interface = self.vnfd["vdu"][0]["external-interface"] - virtual_interface = external_interface[0]["virtual-interface"] - target_ip = virtual_interface["dst_ip"].split('/')[0] - local_ip = virtual_interface["local_ip"].split('/')[0] - local_if_name = \ - virtual_interface["local_iface_name"].split('/')[0] - packet_size = traffic_profile.params["traffic_profile"]["frame_size"] - - run_cmd = [] - - run_cmd.append("ip addr flush %s" % local_if_name) - run_cmd.append("ip addr add %s/24 dev %s" % (local_ip, local_if_name)) - run_cmd.append("ip link set %s up" % local_if_name) - - for cmd in run_cmd: - self.connection.execute(cmd) - - ping_cmd = ("ping -s %s %s" % (packet_size, target_ip)) - self.connection.run(ping_cmd, stdout=filewrapper, - keep_stdin_open=True, pty=True) + super(PingTrafficGen, self).__init__(name, vnfd, setup_env_helper_type, + resource_helper_type) + self._result = {} - def collect_kpi(self): - if not self._queue.empty(): - kpi = self._queue.get() - self._result.update(kpi) - return self._result + def _check_status(self): + return self._tg_process.is_alive() - def terminate(self): - if self._traffic_process is not None: - self._traffic_process.terminate() + def instantiate(self, scenario_cfg, context_cfg): + self._start_server() + self._result = { + "packets_received": 0, + "rtt": 0, + } + self.setup_helper.setup_vnf_environment() + intf = self.vnfd_helper.interfaces[0]["virtual-interface"] + self.resource_helper.cmd_kwargs = { + 'target_ip': IPv4Interface(intf["dst_ip"]).ip.exploded, + 'local_ip': IPv4Interface(intf["local_ip"]).ip.exploded, + 'local_if_name': intf["local_iface_name"].split('/')[0], + }