1 # Copyright (c) 2016-2017 Intel Corporation
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 """ PING acts as traffic generation and vnf definitions based on IETS Spec """
16 from __future__ import absolute_import
17 from __future__ import print_function
21 from multiprocessing import Queue
22 from ipaddress import IPv4Interface
24 from yardstick.network_services.vnf_generic.vnf.sample_vnf import SampleVNFTrafficGen
25 from yardstick.network_services.vnf_generic.vnf.sample_vnf import DpdkVnfSetupEnvHelper
26 from yardstick.network_services.vnf_generic.vnf.sample_vnf import ClientResourceHelper
28 LOG = logging.getLogger(__name__)
31 class PingParser(object):
32 """ Class providing file-like API for talking with SSH connection """
34 def __init__(self, q_out):
38 def write(self, chunk):
39 """ 64 bytes from 10.102.22.93: icmp_seq=1 ttl=64 time=0.296 ms """
40 match = re.search(r"icmp_seq=(\d+).*time=([0-9.]+)", chunk)
41 LOG.debug("Parser called on %s", chunk)
43 # IMPORTANT: in order for the data to be properly taken
44 # in by InfluxDB, it needs to be converted to numeric types
46 "packets_received": float(match.group(1)),
47 "rtt": float(match.group(2)),
51 """ close the ssh connection """
55 """ clear queue till Empty """
56 while self.queue.qsize() > 0:
60 class PingSetupEnvHelper(DpdkVnfSetupEnvHelper):
62 def setup_vnf_environment(self):
63 for intf in self.vnfd_helper.interfaces:
64 vi = intf['virtual-interface']
65 vi['local_iface_name'] = self.get_local_iface_name_by_vpci(vi['vpci'])
68 class PingResourceHelper(ClientResourceHelper):
70 def __init__(self, setup_helper):
71 super(PingResourceHelper, self).__init__(setup_helper)
73 self._parser = PingParser(self._queue)
75 def run_traffic(self, traffic_profile):
76 # drop the connection in order to force a new one
77 self.ssh_helper.drop_connection()
79 self.client_started.value = 1
81 "sudo ip addr flush {local_if_name}",
82 "sudo ip addr add {local_ip}/24 dev {local_if_name}",
83 "sudo ip link set {local_if_name} up",
86 self.cmd_kwargs['packet_size'] = traffic_profile.params['traffic_profile']['frame_size']
89 self.ssh_helper.execute(cmd.format(**self.cmd_kwargs))
91 ping_cmd = "nohup ping -s {packet_size} {target_ip}&"
92 self.ssh_helper.run(ping_cmd.format(**self.cmd_kwargs),
94 keep_stdin_open=True, pty=True)
97 class PingTrafficGen(SampleVNFTrafficGen):
99 This traffic generator can ping a single IP with pingsize
100 and target given in traffic profile
107 def __init__(self, name, vnfd, setup_env_helper_type=None, resource_helper_type=None):
108 if setup_env_helper_type is None:
109 setup_env_helper_type = PingSetupEnvHelper
110 if resource_helper_type is None:
111 resource_helper_type = PingResourceHelper
113 super(PingTrafficGen, self).__init__(name, vnfd, setup_env_helper_type,
114 resource_helper_type)
117 def scale(self, flavor=""):
118 """ scale vnf-based on flavor input """
121 def _check_status(self):
122 return self._tg_process.is_alive()
124 def instantiate(self, scenario_cfg, context_cfg):
127 "packets_received": 0,
130 intf = self.vnfd_helper.interfaces[0]["virtual-interface"]
131 self.resource_helper.cmd_kwargs = {
132 'target_ip': IPv4Interface(intf["dst_ip"]).ip.exploded,
133 'local_ip': IPv4Interface(intf["local_ip"]).ip.exploded,
134 'local_if_name': intf["local_iface_name"].split('/')[0],
137 self.setup_helper.setup_vnf_environment()
139 def wait_for_instantiate(self):
142 def listen_traffic(self, traffic_profile):
143 """ Not needed for ping
145 :param traffic_profile: