X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=yardstick%2Fnetwork_services%2Fvnf_generic%2Fvnf%2Fbase.py;h=a776b0989a7ebd58c2e4711b26bf798fb2cc8450;hb=fc231560d75a2736bf4f78c7b4688de5411025fe;hp=67634a79c69d8b8f7be23caf30eb82e5170f71a3;hpb=c305d24c1499a5aef51c05e94fc9737878548c75;p=yardstick.git diff --git a/yardstick/network_services/vnf_generic/vnf/base.py b/yardstick/network_services/vnf_generic/vnf/base.py index 67634a79c..a776b0989 100644 --- a/yardstick/network_services/vnf_generic/vnf/base.py +++ b/yardstick/network_services/vnf_generic/vnf/base.py @@ -13,11 +13,14 @@ # limitations under the License. """ Base class implementation for generic vnf implementation """ -from __future__ import absolute_import +import abc + import logging +import six from yardstick.network_services.helpers.samplevnf_helper import PortPairs + LOG = logging.getLogger(__name__) @@ -64,6 +67,8 @@ class VnfdHelper(dict): def __init__(self, *args, **kwargs): super(VnfdHelper, self).__init__(*args, **kwargs) self.port_pairs = PortPairs(self['vdu'][0]['external-interface']) + # port num is not present until binding so we have to memoize + self._port_num_map = {} @property def mgmt_interface(self): @@ -91,12 +96,14 @@ class VnfdHelper(dict): virtual_intf = interface["virtual-interface"] if virtual_intf[key] == value: return interface + raise KeyError() def find_interface(self, **kwargs): key, value = next(iter(kwargs.items())) for interface in self.interfaces: if interface[key] == value: return interface + raise KeyError() # hide dpdk_port_num key so we can abstract def find_interface_by_port(self, port): @@ -105,6 +112,7 @@ class VnfdHelper(dict): # we have to convert to int to compare if int(virtual_intf['dpdk_port_num']) == port: return interface + raise KeyError() def port_num(self, port): # we need interface name -> DPDK port num (PMD ID) -> LINK ID @@ -118,7 +126,8 @@ class VnfdHelper(dict): intf = port else: intf = self.find_interface(name=port) - return int(intf["virtual-interface"]["dpdk_port_num"]) + return self._port_num_map.setdefault(intf["name"], + int(intf["virtual-interface"]["dpdk_port_num"])) def port_nums(self, intfs): return [self.port_num(i) for i in intfs] @@ -129,71 +138,65 @@ class VnfdHelper(dict): yield port_name, port_num -class VNFObject(object): +@six.add_metaclass(abc.ABCMeta) +class GenericVNF(object): + """Class providing file-like API for generic VNF implementation + + Currently the only class implementing this interface is + yardstick/network_services/vnf_generic/vnf/sample_vnf:SampleVNF. + """ # centralize network naming convention UPLINK = PortPairs.UPLINK DOWNLINK = PortPairs.DOWNLINK def __init__(self, name, vnfd): - super(VNFObject, self).__init__() self.name = name - self.vnfd_helper = VnfdHelper(vnfd) # fixme: parse this into a structure - - -class GenericVNF(VNFObject): - - """ Class providing file-like API for generic VNF implementation """ - def __init__(self, name, vnfd): - super(GenericVNF, self).__init__(name, vnfd) + self.vnfd_helper = VnfdHelper(vnfd) # List of statistics we can obtain from this VNF # - ETSI MANO 6.3.1.1 monitoring_parameter - self.kpi = self._get_kpi_definition() + self.kpi = self.vnfd_helper.kpi # Standard dictionary containing params like thread no, buffer size etc self.config = {} self.runs_traffic = False - def _get_kpi_definition(self): - """ Get list of KPIs defined in VNFD + @abc.abstractmethod + def instantiate(self, scenario_cfg, context_cfg): + """Prepare VNF for operation and start the VNF process/VM - :param vnfd: - :return: list of KPIs, e.g. ['throughput', 'latency'] + :param scenario_cfg: Scenario config + :param context_cfg: Context config + :return: True/False """ - return self.vnfd_helper.kpi - def instantiate(self, scenario_cfg, context_cfg): - """ Prepare VNF for operation and start the VNF process/VM + @abc.abstractmethod + def wait_for_instantiate(self): + """Wait for VNF to start - :param scenario_cfg: - :param context_cfg: :return: True/False """ - raise NotImplementedError() + @abc.abstractmethod def terminate(self): - """ Kill all VNF processes - - :return: - """ - raise NotImplementedError() + """Kill all VNF processes""" + @abc.abstractmethod def scale(self, flavor=""): - """ + """rest - :param flavor: + :param flavor: Name of the flavor. :return: """ - raise NotImplementedError() + @abc.abstractmethod def collect_kpi(self): - """This method should return a dictionary containing the - selected KPI at a given point of time. + """Return a dict containing the selected KPI at a given point of time :return: {"kpi": value, "kpi2": value} """ - raise NotImplementedError() +@six.add_metaclass(abc.ABCMeta) class GenericTrafficGen(GenericVNF): """ Class providing file-like API for generic traffic generator """ @@ -202,18 +205,29 @@ class GenericTrafficGen(GenericVNF): self.runs_traffic = True self.traffic_finished = False + @abc.abstractmethod def run_traffic(self, traffic_profile): - """ Generate traffic on the wire according to the given params. - Method is non-blocking, returns immediately when traffic process + """Generate traffic on the wire according to the given params. + + This method is non-blocking, returns immediately when traffic process is running. Mandatory. :param traffic_profile: :return: True/False """ - raise NotImplementedError() + + @abc.abstractmethod + def terminate(self): + """After this method finishes, all traffic processes should stop. + + Mandatory. + + :return: True/False + """ def listen_traffic(self, traffic_profile): - """ Listen to traffic with the given parameters. + """Listen to traffic with the given parameters. + Method is non-blocking, returns immediately when traffic process is running. Optional. @@ -223,16 +237,20 @@ class GenericTrafficGen(GenericVNF): pass def verify_traffic(self, traffic_profile): - """ Verify captured traffic after it has ended. Optional. + """Verify captured traffic after it has ended. + + Optional. :param traffic_profile: :return: dict """ pass - def terminate(self): - """ After this method finishes, all traffic processes should stop. Mandatory. + def wait_for_instantiate(self): + """Wait for an instance to load. + + Optional. :return: True/False """ - raise NotImplementedError() + pass