diff options
Diffstat (limited to 'yardstick/benchmark/scenarios/networking/vnf_generic.py')
-rw-r--r-- | yardstick/benchmark/scenarios/networking/vnf_generic.py | 134 |
1 files changed, 92 insertions, 42 deletions
diff --git a/yardstick/benchmark/scenarios/networking/vnf_generic.py b/yardstick/benchmark/scenarios/networking/vnf_generic.py index 599835d56..4510bcfba 100644 --- a/yardstick/benchmark/scenarios/networking/vnf_generic.py +++ b/yardstick/benchmark/scenarios/networking/vnf_generic.py @@ -14,13 +14,17 @@ """ NSPerf specific scenario definition """ from __future__ import absolute_import -import logging +import logging import errno -import os +import ipaddress +import os +import sys import re from itertools import chain + +import six from operator import itemgetter from collections import defaultdict @@ -31,8 +35,10 @@ from yardstick.network_services.collector.subscriber import Collector from yardstick.network_services.vnf_generic import vnfdgen from yardstick.network_services.vnf_generic.vnf.base import GenericVNF from yardstick.network_services.traffic_profile.base import TrafficProfile +from yardstick.network_services.utils import get_nsb_option from yardstick import ssh + LOG = logging.getLogger(__name__) @@ -126,19 +132,50 @@ class NetworkServiceTestCase(base.Scenario): self.collector = None self.traffic_profile = None + def _get_ip_flow_range(self, ip_start_range): + + node_name, range_or_interface = next(iter(ip_start_range.items()), (None, '0.0.0.0')) + if node_name is not None: + node = self.context_cfg["nodes"].get(node_name, {}) + try: + # the ip_range is the interface name + interface = node.get("interfaces", {})[range_or_interface] + except KeyError: + ip = "0.0.0.0" + mask = "255.255.255.0" + else: + ip = interface["local_ip"] + # we can't default these values, they must both exist to be valid + mask = interface["netmask"] + + ipaddr = ipaddress.ip_network(six.text_type('{}/{}'.format(ip, mask)), strict=False) + hosts = list(ipaddr.hosts()) + ip_addr_range = "{}-{}".format(hosts[0], hosts[-1]) + else: + # we are manually specifying the range + ip_addr_range = range_or_interface + return ip_addr_range + def _get_traffic_flow(self): + flow = {} try: - with open(self.scenario_cfg["traffic_options"]["flow"]) as fflow: - flow = yaml_load(fflow) - except (KeyError, IOError, OSError): + fflow = self.scenario_cfg["options"]["flow"] + for index, src in enumerate(fflow.get("src_ip", [])): + flow["src_ip{}".format(index)] = self._get_ip_flow_range(src) + + for index, dst in enumerate(fflow.get("dst_ip", [])): + flow["dst_ip{}".format(index)] = self._get_ip_flow_range(dst) + + for index, publicip in enumerate(fflow.get("publicip", [])): + flow["public_ip{}".format(index)] = publicip + except KeyError: flow = {} - return flow + return {"flow": flow} def _get_traffic_imix(self): try: - with open(self.scenario_cfg["traffic_options"]["imix"]) as fimix: - imix = yaml_load(fimix) - except (KeyError, IOError, OSError): + imix = {"imix": self.scenario_cfg['options']['framesize']} + except KeyError: imix = {} return imix @@ -265,8 +302,25 @@ class NetworkServiceTestCase(base.Scenario): for dpdk_port_num, netdev in enumerate(s): netdev['dpdk_port_num'] = dpdk_port_num + def _probe_netdevs(self, node, node_dict): + cmd = "PATH=$PATH:/sbin:/usr/sbin ip addr show" + netdevs = {} + with SshManager(node_dict) as conn: + if conn: + exit_status = conn.execute(cmd)[0] + if exit_status != 0: + raise IncorrectSetup("Node's %s lacks ip tool." % node) + exit_status, stdout, _ = conn.execute( + self.FIND_NETDEVICE_STRING) + if exit_status != 0: + raise IncorrectSetup( + "Cannot find netdev info in sysfs" % node) + netdevs = node_dict['netdevs'] = self.parse_netdev_info(stdout) + return netdevs + @classmethod - def _probe_missing_values(cls, netdevs, network, missing): + def _probe_missing_values(cls, netdevs, network): + mac_lower = network['local_mac'].lower() for netdev in netdevs.values(): if netdev['address'].lower() != mac_lower: @@ -288,36 +342,30 @@ class NetworkServiceTestCase(base.Scenario): """ for node, node_dict in self.context_cfg["nodes"].items(): - cmd = "PATH=$PATH:/sbin:/usr/sbin ip addr show" - with SshManager(node_dict) as conn: - exit_status = conn.execute(cmd)[0] - if exit_status != 0: - raise IncorrectSetup("Node's %s lacks ip tool." % node) - exit_status, stdout, _ = conn.execute( - self.FIND_NETDEVICE_STRING) - if exit_status != 0: - raise IncorrectSetup( - "Cannot find netdev info in sysfs" % node) - netdevs = node_dict['netdevs'] = self.parse_netdev_info( - stdout) - - for network in node_dict["interfaces"].values(): - missing = self.TOPOLOGY_REQUIRED_KEYS.difference(network) - if not missing: - continue - - try: - self._probe_missing_values(netdevs, network, - missing) - except KeyError: - pass - else: - missing = self.TOPOLOGY_REQUIRED_KEYS.difference( - network) - if missing: - raise IncorrectConfig( - "Require interface fields '%s' not found, topology file " - "corrupted" % ', '.join(missing)) + for network in node_dict["interfaces"].values(): + missing = self.TOPOLOGY_REQUIRED_KEYS.difference(network) + if not missing: + continue + + # only ssh probe if there are missing values + # ssh probe won't work on Ixia, so we had better define all our values + try: + netdevs = self._probe_netdevs(node, node_dict) + except (SSHError, SSHTimeout): + raise IncorrectConfig( + "Unable to probe missing interface fields '%s', on node %s " + "SSH Error" % (', '.join(missing), node)) + try: + self._probe_missing_values(netdevs, network) + except KeyError: + pass + else: + missing = self.TOPOLOGY_REQUIRED_KEYS.difference( + network) + if missing: + raise IncorrectConfig( + "Require interface fields '%s' not found, topology file " + "corrupted" % ', '.join(missing)) # 3. Use topology file to find connections & resolve dest address self._resolve_topology() @@ -393,6 +441,9 @@ printf "%s/driver:" $1 ; basename $(readlink -s $1/device/driver); } \ :param context_cfg: :return: """ + trex_lib_path = get_nsb_option('trex_client_lib') + sys.path[:] = list(chain([trex_lib_path], (x for x in sys.path if x != trex_lib_path))) + if scenario_cfg is None: scenario_cfg = self.scenario_cfg @@ -440,7 +491,6 @@ printf "%s/driver:" $1 ; basename $(readlink -s $1/device/driver); } \ for vnf in chain(traffic_runners, non_traffic_runners): LOG.info("Instantiating %s", vnf.name) vnf.instantiate(self.scenario_cfg, self.context_cfg) - for vnf in chain(traffic_runners, non_traffic_runners): LOG.info("Waiting for %s to instantiate", vnf.name) vnf.wait_for_instantiate() except RuntimeError: @@ -473,7 +523,7 @@ printf "%s/driver:" $1 ; basename $(readlink -s $1/device/driver); } \ for vnf in self.vnfs: # Result example: # {"VNF1: { "tput" : [1000, 999] }, "VNF2": { "latency": 100 }} - LOG.debug("vnf") + LOG.debug("collect KPI for %s", vnf.name) result.update(self.collector.get_kpi(vnf)) def teardown(self): |