aboutsummaryrefslogtreecommitdiffstats
path: root/yardstick/network_services/vnf_generic/vnf/tg_ping.py
blob: e65296287bd3b35d5da6d7fadf4497761255a660 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# Copyright (c) 2016-2017 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.
""" 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 re

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

LOG = logging.getLogger(__name__)


class PingParser(object):
    """ Class providing file-like API for talking with SSH connection """

    def __init__(self, q_out):
        self.queue = q_out
        self.closed = False

    def write(self, chunk):
        """ 64 bytes from 10.102.22.93: icmp_seq=1 ttl=64 time=0.296 ms """
        match = re.search(r"icmp_seq=(\d+).*time=([0-9.]+)", chunk)
        LOG.debug("Parser called on %s", chunk)
        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)),
            })

    def close(self):
        """ close the ssh connection """
        self.closed = True

    def clear(self):
        """ clear queue till Empty """
        while self.queue.qsize() > 0:
            self.queue.get()


class PingSetupEnvHelper(DpdkVnfSetupEnvHelper):

    def setup_vnf_environment(self):
        self._bind_kernel_devices()


class PingTrafficGen(SampleVNFTrafficGen):
    """
    This traffic generator can ping a single IP with pingsize
    and target given in traffic profile
    """

    TG_NAME = 'Ping'
    RUN_WAIT = 4

    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

        super(PingTrafficGen, self).__init__(name, vnfd, setup_env_helper_type,
                                             resource_helper_type)
        self._queue = Queue()
        self._parser = PingParser(self._queue)
        self._result = {}

    def scale(self, flavor=""):
        """ scale vnf-based on flavor input """
        pass

    def _check_status(self):
        return self._tg_process.is_alive()

    def instantiate(self, scenario_cfg, context_cfg):
        self._result = {
            "packets_received": 0,
            "rtt": 0,
        }
        self.setup_helper.setup_vnf_environment()

    def listen_traffic(self, traffic_profile):
        """ Not needed for ping

        :param traffic_profile:
        :return:
        """
        pass

    def _traffic_runner(self, traffic_profile):
        intf = self.vnfd_helper.interfaces[0]["virtual-interface"]
        profile = traffic_profile.params["traffic_profile"]
        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],
            'packet_size': profile["frame_size"],
        }

        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",
        ]

        for cmd in cmd_list:
            self.ssh_helper.execute(cmd.format(**cmd_kwargs))

        ping_cmd = "ping -s {packet_size} {target_ip}"
        self.ssh_helper.run(ping_cmd.format(**cmd_kwargs),
                            stdout=self._parser,
                            keep_stdin_open=True, pty=True)