Create a SampleVNF MQ consumer class
[yardstick.git] / yardstick / network_services / vnf_generic / vnf / tg_ping.py
1 # Copyright (c) 2016-2017 Intel Corporation
2 #
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
6 #
7 #      http://www.apache.org/licenses/LICENSE-2.0
8 #
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 """
15
16 from __future__ import absolute_import
17 import logging
18 import re
19
20 from multiprocessing import Queue
21 from ipaddress import IPv4Interface
22
23 from yardstick.network_services.vnf_generic.vnf.sample_vnf import SampleVNFTrafficGen
24 from yardstick.network_services.vnf_generic.vnf.sample_vnf import DpdkVnfSetupEnvHelper
25 from yardstick.network_services.vnf_generic.vnf.sample_vnf import ClientResourceHelper
26
27 LOG = logging.getLogger(__name__)
28
29
30 class PingParser(object):
31     """ Class providing file-like API for talking with SSH connection """
32
33     def __init__(self, q_out):
34         self.queue = q_out
35         self.closed = False
36
37     def write(self, chunk):
38         """ 64 bytes from 10.102.22.93: icmp_seq=1 ttl=64 time=0.296 ms """
39         match = re.search(r"icmp_seq=(\d+).*time=([0-9.]+)", chunk)
40         LOG.debug("Parser called on %s", chunk)
41         if match:
42             # IMPORTANT: in order for the data to be properly taken
43             # in by InfluxDB, it needs to be converted to numeric types
44             self.queue.put({
45                 "packets_received": float(match.group(1)),
46                 "rtt": float(match.group(2)),
47             })
48
49     def close(self):
50         """ close the ssh connection """
51         self.closed = True
52
53     def clear(self):
54         """ clear queue till Empty """
55         while self.queue.qsize() > 0:
56             self.queue.get()
57
58
59 class PingSetupEnvHelper(DpdkVnfSetupEnvHelper):
60
61     def setup_vnf_environment(self):
62         for intf in self.vnfd_helper.interfaces:
63             vi = intf['virtual-interface']
64             vi['local_iface_name'] = self.get_local_iface_name_by_vpci(vi['vpci'])
65
66
67 class PingResourceHelper(ClientResourceHelper):
68
69     def __init__(self, setup_helper):
70         super(PingResourceHelper, self).__init__(setup_helper)
71         self._queue = Queue()
72         self._parser = PingParser(self._queue)
73
74     def run_traffic(self, traffic_profile, *args):
75         # drop the connection in order to force a new one
76         self.ssh_helper.drop_connection()
77
78         self.client_started.value = 1
79         cmd_list = [
80             "sudo ip addr flush {local_if_name}",
81             "sudo ip addr add {local_ip}/24 dev {local_if_name}",
82             "sudo ip link set {local_if_name} up",
83         ]
84
85         self.cmd_kwargs['packet_size'] = traffic_profile.params['traffic_profile']['frame_size']
86
87         for cmd in cmd_list:
88             self.ssh_helper.execute(cmd.format(**self.cmd_kwargs))
89
90         ping_cmd = "nohup ping -s {packet_size} {target_ip}&"
91         self.ssh_helper.run(ping_cmd.format(**self.cmd_kwargs),
92                             stdout=self._parser,
93                             keep_stdin_open=True, pty=True)
94
95
96 class PingTrafficGen(SampleVNFTrafficGen):
97     """
98     This traffic generator can ping a single IP with pingsize
99     and target given in traffic profile
100     """
101
102     TG_NAME = 'Ping'
103     APP_NAME = 'Ping'
104     RUN_WAIT = 4
105
106     def __init__(self, name, vnfd, task_id, setup_env_helper_type=None,
107                  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
112         super(PingTrafficGen, self).__init__(
113             name, vnfd, task_id, setup_env_helper_type, resource_helper_type)
114         self._result = {}
115
116     def _check_status(self):
117         return self._tg_process.is_alive()
118
119     def instantiate(self, scenario_cfg, context_cfg):
120         self._start_server()
121         self._result = {
122             "packets_received": 0,
123             "rtt": 0,
124         }
125         self.setup_helper.setup_vnf_environment()
126         intf = self.vnfd_helper.interfaces[0]["virtual-interface"]
127         self.resource_helper.cmd_kwargs = {
128             'target_ip': IPv4Interface(intf["dst_ip"]).ip.exploded,
129             'local_ip': IPv4Interface(intf["local_ip"]).ip.exploded,
130             'local_if_name': intf["local_iface_name"].split('/')[0],
131         }