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 """ Base class implementation for generic vnf implementation """
16 from __future__ import absolute_import
19 from yardstick.network_services.helpers.samplevnf_helper import PortPairs
21 LOG = logging.getLogger(__name__)
24 class QueueFileWrapper(object):
25 """ Class providing file-like API for talking with SSH connection """
27 def __init__(self, q_in, q_out, prompt):
36 """ read chunk from input queue """
37 if self.q_in.qsize() > 0 and size:
38 in_data = self.q_in.get()
41 def write(self, chunk):
42 """ write chunk to output queue """
43 self.buf.append(chunk)
44 # flush on prompt or if we exceed bufsize
46 size = sum(len(c) for c in self.buf)
47 if self.prompt in chunk or size > self.bufsize:
48 out = ''.join(self.buf)
53 """ close multiprocessing queue """
58 while self.q_out.qsize() > 0:
62 class VnfdHelper(dict):
64 def __init__(self, *args, **kwargs):
65 super(VnfdHelper, self).__init__(*args, **kwargs)
66 self.port_pairs = PortPairs(self['vdu'][0]['external-interface'])
69 def mgmt_interface(self):
70 return self["mgmt-interface"]
82 return self.vdu0['external-interface']
86 return self['benchmark']['kpi']
88 def find_virtual_interface(self, **kwargs):
89 key, value = next(iter(kwargs.items()))
90 for interface in self.interfaces:
91 virtual_intf = interface["virtual-interface"]
92 if virtual_intf[key] == value:
95 def find_interface(self, **kwargs):
96 key, value = next(iter(kwargs.items()))
97 for interface in self.interfaces:
98 if interface[key] == value:
101 # hide dpdk_port_num key so we can abstract
102 def find_interface_by_port(self, port):
103 for interface in self.interfaces:
104 virtual_intf = interface["virtual-interface"]
105 # we have to convert to int to compare
106 if int(virtual_intf['dpdk_port_num']) == port:
109 def port_num(self, name):
110 # we need interface name -> DPDK port num (PMD ID) -> LINK ID
111 # LINK ID -> PMD ID is governed by the port mask
117 intf = self.find_interface(name=name)
118 return int(intf["virtual-interface"]["dpdk_port_num"])
120 def port_nums(self, intfs):
121 return [self.port_num(i) for i in intfs]
124 class VNFObject(object):
126 # centralize network naming convention
127 UPLINK = PortPairs.UPLINK
128 DOWNLINK = PortPairs.DOWNLINK
130 def __init__(self, name, vnfd):
131 super(VNFObject, self).__init__()
133 self.vnfd_helper = VnfdHelper(vnfd) # fixme: parse this into a structure
136 class GenericVNF(VNFObject):
138 """ Class providing file-like API for generic VNF implementation """
139 def __init__(self, name, vnfd):
140 super(GenericVNF, self).__init__(name, vnfd)
141 # List of statistics we can obtain from this VNF
142 # - ETSI MANO 6.3.1.1 monitoring_parameter
143 self.kpi = self._get_kpi_definition()
144 # Standard dictionary containing params like thread no, buffer size etc
146 self.runs_traffic = False
148 def _get_kpi_definition(self):
149 """ Get list of KPIs defined in VNFD
152 :return: list of KPIs, e.g. ['throughput', 'latency']
154 return self.vnfd_helper.kpi
156 def instantiate(self, scenario_cfg, context_cfg):
157 """ Prepare VNF for operation and start the VNF process/VM
163 raise NotImplementedError()
166 """ Kill all VNF processes
170 raise NotImplementedError()
172 def scale(self, flavor=""):
178 raise NotImplementedError()
180 def collect_kpi(self):
181 """This method should return a dictionary containing the
182 selected KPI at a given point of time.
184 :return: {"kpi": value, "kpi2": value}
186 raise NotImplementedError()
189 class GenericTrafficGen(GenericVNF):
190 """ Class providing file-like API for generic traffic generator """
192 def __init__(self, name, vnfd):
193 super(GenericTrafficGen, self).__init__(name, vnfd)
194 self.runs_traffic = True
195 self.traffic_finished = False
197 def run_traffic(self, traffic_profile):
198 """ Generate traffic on the wire according to the given params.
199 Method is non-blocking, returns immediately when traffic process
200 is running. Mandatory.
202 :param traffic_profile:
205 raise NotImplementedError()
207 def listen_traffic(self, traffic_profile):
208 """ Listen to traffic with the given parameters.
209 Method is non-blocking, returns immediately when traffic process
210 is running. Optional.
212 :param traffic_profile:
217 def verify_traffic(self, traffic_profile):
218 """ Verify captured traffic after it has ended. Optional.
220 :param traffic_profile:
226 """ After this method finishes, all traffic processes should stop. Mandatory.
230 raise NotImplementedError()