diff options
author | Martin Banszel <martinx.banszel@intel.com> | 2017-07-19 19:35:02 +0000 |
---|---|---|
committer | Ross Brattain <ross.b.brattain@intel.com> | 2017-09-05 17:48:02 -0700 |
commit | d3ee35dc0015e073b7138f3b02508b40fc6288b1 (patch) | |
tree | d5350f427a7ba6dcea8d36b00ae217d0074f0511 /yardstick | |
parent | 79e811f096f8640189fc75862535f1f0cc4773c5 (diff) |
Add fixes for heat deployed UDP_Replay and TRex
- Added a PROTOCOL_MAP to map the protocol names to codes -- the scapy
requires the code, it fails if the proto is set e.g. to 'udp'
- ip addresses must be str, not unicode -- explicit conversion to str
added
- removed unittest for setup_vnf_environment in test_tg_trex.py as
it is the same function as already tested in test_sample_vnf.py
- traffic_profile refactored -- code repetition decreased, unittest
adapted
Known issues:
- there is a an attempt to stop already stopped trex. It fires an
exception that stop command is issued on the disconnected client.
Change-Id: I87e9029630f48b30e8f5b4f9d88ab3b25fd65f03
Signed-off-by: Martin Banszel <martinx.banszel@intel.com>
Diffstat (limited to 'yardstick')
6 files changed, 239 insertions, 250 deletions
diff --git a/yardstick/network_services/helpers/samplevnf_helper.py b/yardstick/network_services/helpers/samplevnf_helper.py index dfc5cb972..9d89d4188 100644 --- a/yardstick/network_services/helpers/samplevnf_helper.py +++ b/yardstick/network_services/helpers/samplevnf_helper.py @@ -229,10 +229,15 @@ class MultiPortConfig(object): @staticmethod def get_port_pairs(interfaces): port_pair_list = [] - networks = defaultdict(list) + networks = {} for private_intf in interfaces: vintf = private_intf['virtual-interface'] - networks[vintf['vld_id']].append(vintf) + try: + vld_id = vintf['vld_id'] + except KeyError: + pass + else: + networks.setdefault(vld_id, []).append(vintf) for name, net in networks.items(): # partition returns a tuple diff --git a/yardstick/network_services/nfvi/resource.py b/yardstick/network_services/nfvi/resource.py index f0ae67616..055fdba7e 100644 --- a/yardstick/network_services/nfvi/resource.py +++ b/yardstick/network_services/nfvi/resource.py @@ -203,6 +203,7 @@ class ResourceProfile(object): self._provide_config_file(bin_path, 'collectd.conf', kwargs) def _start_collectd(self, connection, bin_path): + LOG.debug("Starting collectd to collect NFVi stats") connection.execute('sudo pkill -9 collectd') bin_path = get_nsb_option("bin_path") collectd_path = os.path.join(bin_path, "collectd", "collectd") diff --git a/yardstick/network_services/traffic_profile/traffic_profile.py b/yardstick/network_services/traffic_profile/traffic_profile.py index 7bbe89268..4c6595d94 100644 --- a/yardstick/network_services/traffic_profile/traffic_profile.py +++ b/yardstick/network_services/traffic_profile/traffic_profile.py @@ -33,203 +33,86 @@ from trex_stl_lib.trex_stl_packet_builder_scapy import STLScVmRaw from trex_stl_lib.trex_stl_packet_builder_scapy import STLVmFixIpv4 from trex_stl_lib import api as Pkt +SRC = 'src' +DST = 'dst' +ETHERNET = 'Ethernet' +IP = 'IP' +IPv6 = 'IPv6' +UDP = 'UDP' +DSCP = 'DSCP' +SRC_PORT = 'sport' +DST_PORT = 'dport' +TYPE_OF_SERVICE = 'tos' + class TrexProfile(TrafficProfile): """ This class handles Trex Traffic profile generation and execution """ - def __init__(self, yaml_data): - super(TrexProfile, self).__init__(yaml_data) - self.flows = 100 - self.pps = 100 - self.pg_id = 0 - self.first_run = True - self.streams = 1 - self.profile_data = [] - self.profile = None - self.base_pkt = None - self.fsize = None - self.trex_vm = None - self.vms = [] - self.rate = None - self.ip_packet = None - self.ip6_packet = None - self.udp_packet = None - self.udp_dport = '' - self.udp_sport = '' - self.qinq_packet = None - self.qinq = False - self.vm_flow_vars = [] - self.packets = [] - self.ether_packet = [] - - def execute(self, traffic_generator): - """ Generate the stream and run traffic on the given ports """ - pass - - def _set_ether_fields(self, **kwargs): - """ set ethernet protocol fields """ - if not self.ether_packet: - self.ether_packet = Pkt.Ether() - for key, value in six.iteritems(kwargs): - setattr(self.ether_packet, key, value) - - def _set_ip_fields(self, **kwargs): - """ set l3 ipv4 protocol fields """ - - if not self.ip_packet: - self.ip_packet = Pkt.IP() - for key in kwargs: - setattr(self.ip_packet, key, kwargs[key]) - - def _set_ip6_fields(self, **kwargs): - """ set l3 ipv6 protocol fields """ - if not self.ip6_packet: - self.ip6_packet = Pkt.IPv6() - for key in kwargs: - setattr(self.ip6_packet, key, kwargs[key]) - - def _set_udp_fields(self, **kwargs): - """ set l4 udp ports fields """ - if not self.udp_packet: - self.udp_packet = Pkt.UDP() - for key in kwargs: - setattr(self.udp_packet, key, kwargs[key]) - - def set_src_mac(self, src_mac): - """ set source mac address fields """ - src_macs = src_mac.split('-') - min_value = src_macs[0] - if len(src_macs) == 1: - src_mac = min_value - self._set_ether_fields(src=src_mac) - else: - stl_vm_flow_var = STLVmFlowVar(name="mac_src", + PROTO_MAP = { + ETHERNET: ('ether_packet', Pkt.Ether), + IP: ('ip_packet', Pkt.IP), + IPv6: ('ip6_packet', Pkt.IPv6), + UDP: ('udp_packet', Pkt.UDP), + } + + def _general_single_action_partial(self, protocol): + def f(field): + def partial(value): + kwargs = { + field: value + } + self._set_proto_fields(protocol, **kwargs) + return partial + return f + + def _ethernet_range_action_partial(self, direction, _): + def partial(min_value, max_value): + stl_vm_flow_var = STLVmFlowVar(name="mac_{}".format(direction), min_value=1, max_value=30, size=4, op='inc', step=1) self.vm_flow_vars.append(stl_vm_flow_var) - stl_vm_wr_flow_var = STLVmWrFlowVar(fv_name='mac_src', - pkt_offset='Ether.src') + stl_vm_wr_flow_var = STLVmWrFlowVar(fv_name='mac_{}'.format(direction), + pkt_offset='Ether.{}'.format(direction)) self.vm_flow_vars.append(stl_vm_wr_flow_var) + return partial - def set_dst_mac(self, dst_mac): - """ set destination mac address fields """ - dst_macs = dst_mac.split('-') - min_value = dst_macs[0] - if len(dst_macs) == 1: - dst_mac = min_value - self._set_ether_fields(dst=dst_mac) - else: - stl_vm_flow_var = STLVmFlowVar(name="mac_dst", - min_value=1, - max_value=30, - size=4, - op='inc', - step=1) - self.vm_flow_vars.append(stl_vm_flow_var) - stl_vm_wr_flow_var = STLVmWrFlowVar(fv_name='mac_dst', - pkt_offset='Ether.dst') - self.vm_flow_vars.append(stl_vm_wr_flow_var) - - def set_src_ip4(self, src_ip4, count=1): - """ set source ipv4 address fields """ - src_ips = src_ip4.split('-') - min_value = src_ips[0] - max_value = src_ips[1] if len(src_ips) == 2 else src_ips[0] - if len(src_ips) == 1: - src_ip4 = min_value - self._set_ip_fields(src=src_ip4) - else: - stl_vm_flow_var = STLVmFlowVarRepeatableRandom(name="ip4_src", + def _ip_range_action_partial(self, direction, count=1): + def partial(min_value, max_value): + stl_vm_flow_var = STLVmFlowVarRepeatableRandom(name="ip4_{}".format(direction), min_value=min_value, max_value=max_value, size=4, limit=int(count), seed=0x1235) self.vm_flow_vars.append(stl_vm_flow_var) - stl_vm_wr_flow_var = STLVmWrFlowVar(fv_name='ip4_src', - pkt_offset='IP.src') + stl_vm_wr_flow_var = STLVmWrFlowVar(fv_name='ip4_{}'.format(direction), + pkt_offset='IP.{}'.format(direction)) self.vm_flow_vars.append(stl_vm_wr_flow_var) stl_vm_fix_ipv4 = STLVmFixIpv4(offset="IP") self.vm_flow_vars.append(stl_vm_fix_ipv4) + return partial - def set_dst_ip4(self, dst_ip4, count=1): - """ set destination ipv4 address fields """ - dst_ips = dst_ip4.split('-') - min_value = dst_ips[0] - max_value = dst_ips[1] if len(dst_ips) == 2 else dst_ips[0] - if len(dst_ips) == 1: - dst_ip4 = min_value - self._set_ip_fields(dst=dst_ip4) - else: - stl_vm_flow_var = STLVmFlowVarRepeatableRandom(name="dst_ip4", - min_value=min_value, - max_value=max_value, - size=4, - limit=int(count), - seed=0x1235) - self.vm_flow_vars.append(stl_vm_flow_var) - stl_vm_wr_flow_var = STLVmWrFlowVar(fv_name='dst_ip4', - pkt_offset='IP.dst') - self.vm_flow_vars.append(stl_vm_wr_flow_var) - stl_vm_fix_ipv4 = STLVmFixIpv4(offset="IP") - self.vm_flow_vars.append(stl_vm_fix_ipv4) - - def set_src_ip6(self, src_ip6): - """ set source ipv6 address fields """ - src_ips = src_ip6.split('-') - min_value = src_ips[0] - max_value = src_ips[1] if len(src_ips) == 2 else src_ips[0] - src_ip6 = min_value - self._set_ip6_fields(src=src_ip6) - if len(src_ips) == 2: - min_value, max_value = \ - self._get_start_end_ipv6(min_value, max_value) - stl_vm_flow_var = STLVmFlowVar(name="ip6_src", + def _ip6_range_action_partial(self, direction, _): + def partial(min_value, max_value): + min_value, max_value = self._get_start_end_ipv6(min_value, max_value) + stl_vm_flow_var = STLVmFlowVar(name="ip6_{}".format(direction), min_value=min_value, max_value=max_value, size=8, op='random', step=1) self.vm_flow_vars.append(stl_vm_flow_var) - stl_vm_wr_flow_var = STLVmWrFlowVar(fv_name='ip6_src', - pkt_offset='IPv6.src', + stl_vm_wr_flow_var = STLVmWrFlowVar(fv_name='ip6_{}'.format(direction), + pkt_offset='IPv6.{}'.format(direction), offset_fixup=8) self.vm_flow_vars.append(stl_vm_wr_flow_var) + return partial - def set_dst_ip6(self, dst_ip6): - """ set destination ipv6 address fields """ - dst_ips = dst_ip6.split('-') - min_value = dst_ips[0] - max_value = dst_ips[1] if len(dst_ips) == 2 else dst_ips[0] - dst_ip6 = min_value - self._set_ip6_fields(dst=dst_ip6) - if len(dst_ips) == 2: - min_value, max_value = \ - self._get_start_end_ipv6(min_value, max_value) - stl_vm_flow_var = STLVmFlowVar(name="dst_ip6", - min_value=min_value, - max_value=max_value, - size=8, - op='random', - step=1) - self.vm_flow_vars.append(stl_vm_flow_var) - stl_vm_wr_flow_var = STLVmWrFlowVar(fv_name='dst_ip6', - pkt_offset='IPv6.dst', - offset_fixup=8) - self.vm_flow_vars.append(stl_vm_wr_flow_var) - - def set_dscp(self, dscp): - """ set dscp for trex """ - dscps = str(dscp).split('-') - min_value = int(dscps[0]) - max_value = int(dscps[1]) if len(dscps) == 2 else int(dscps[0]) - if len(dscps) == 1: - dscp = min_value - self._set_ip_fields(tos=dscp) - else: + def _dscp_range_action_partial(self, *_): + def partial(min_value, max_value): stl_vm_flow_var = STLVmFlowVar(name="dscp", min_value=min_value, max_value=max_value, @@ -241,54 +124,110 @@ class TrexProfile(TrafficProfile): pkt_offset='IP.tos') self.vm_flow_vars.append(stl_vm_wr_flow_var) - def set_src_port(self, src_port, count=1): - """ set packet source port """ - src_ports = str(src_port).split('-') - min_value = int(src_ports[0]) - if len(src_ports) == 1: - max_value = int(src_ports[0]) - src_port = min_value - self._set_udp_fields(sport=src_port) - else: - max_value = int(src_ports[1]) - stl_vm_flow_var = STLVmFlowVarRepeatableRandom(name="port_src", + def _udp_range_action_partial(self, field, count=1): + def partial(min_value, max_value): + stl_vm_flow_var = STLVmFlowVarRepeatableRandom(name="port_{}".format(field), min_value=min_value, max_value=max_value, size=2, limit=int(count), seed=0x1235) self.vm_flow_vars.append(stl_vm_flow_var) - stl_vm_wr_flow_var = STLVmWrFlowVar(fv_name='port_src', + stl_vm_wr_flow_var = STLVmWrFlowVar(fv_name='port_{}'.format(field), pkt_offset=self.udp_sport) self.vm_flow_vars.append(stl_vm_wr_flow_var) + return partial - def set_dst_port(self, dst_port, count=1): - """ set packet destnation port """ - dst_ports = str(dst_port).split('-') - min_value = int(dst_ports[0]) - if len(dst_ports) == 1: - max_value = int(dst_ports[0]) - dst_port = min_value - self._set_udp_fields(dport=dst_port) + def __init__(self, yaml_data): + super(TrexProfile, self).__init__(yaml_data) + self.flows = 100 + self.pps = 100 + self.pg_id = 0 + self.first_run = True + self.streams = 1 + self.profile_data = [] + self.profile = None + self.base_pkt = None + self.fsize = None + self.trex_vm = None + self.vms = [] + self.rate = None + self.ether_packet = None + self.ip_packet = None + self.ip6_packet = None + self.udp_packet = None + self.udp_dport = '' + self.udp_sport = '' + self.qinq_packet = None + self.qinq = False + self.vm_flow_vars = [] + self.packets = [] + + self._map_proto_actions = { + # the tuple is (single value function, range value function, if the values should be + # converted to integer). + ETHERNET: (self._general_single_action_partial(ETHERNET), + self._ethernet_range_action_partial, + False, + ), + IP: (self._general_single_action_partial(IP), + self._ip_range_action_partial, + False, + ), + IPv6: (self._general_single_action_partial(IPv6), + self._ip6_range_action_partial, + False, + ), + DSCP: (self._general_single_action_partial(IP), + self._dscp_range_action_partial, + True, + ), + UDP: (self._general_single_action_partial(UDP), + self._udp_range_action_partial, + True, + ), + } + + def execute(self, traffic_generator): + """ Generate the stream and run traffic on the given ports """ + pass + + def _call_on_range(self, range, single_action, range_action, count=1, to_int=False): + def convert_to_int(val): + return int(val) if to_int else val + + range_iter = iter(str(range).split('-')) + min_value = convert_to_int(next(range_iter)) + try: + max_value = convert_to_int(next(range_iter)) + except StopIteration: + single_action(min_value) else: - max_value = int(dst_ports[1]) - stl_vm_flow_var = \ - STLVmFlowVarRepeatableRandom(name="port_dst", - min_value=min_value, - max_value=max_value, - size=2, - limit=int(count), - seed=0x1235) - self.vm_flow_vars.append(stl_vm_flow_var) - stl_vm_wr_flow_var = STLVmWrFlowVar(fv_name='port_dst', - pkt_offset=self.udp_dport) - self.vm_flow_vars.append(stl_vm_wr_flow_var) + range_action(min_value=min_value, max_value=max_value) + + def _set_proto_addr(self, protocol, field, address, count=1): + single_action, range_action, to_int = self._map_proto_actions[protocol] + self._call_on_range(address, + single_action(field), + range_action(field, count), + to_int=to_int, + ) + + def _set_proto_fields(self, protocol, **kwargs): + _attr_name, _class = self.PROTO_MAP[protocol] + + if not getattr(self, _attr_name): + setattr(self, _attr_name, _class()) + + _attr = getattr(self, _attr_name) + for key, value in six.iteritems(kwargs): + setattr(_attr, key, value) def set_svlan_cvlan(self, svlan, cvlan): """ set svlan & cvlan """ self.qinq = True ether_params = {'type': 0x8100} - self._set_ether_fields(**ether_params) + self._set_proto_fields(ETHERNET, **ether_params) svlans = str(svlan['id']).split('-') svlan_min = int(svlans[0]) svlan_max = int(svlans[1]) if len(svlans) == 2 else int(svlans[0]) @@ -309,42 +248,42 @@ class TrexProfile(TrafficProfile): """ set qinq in packet """ self.set_svlan_cvlan(qinq['S-VLAN'], qinq['C-VLAN']) - def set_outer_l2_fields(self, outer_l2): + def _set_outer_l2_fields(self, outer_l2): """ setup outer l2 fields from traffic profile """ ether_params = {'type': 0x800} - self._set_ether_fields(**ether_params) + self._set_proto_fields(ETHERNET, **ether_params) if 'srcmac' in outer_l2: - self.set_src_mac(outer_l2['srcmac']) + self._set_proto_addr(ETHERNET, SRC, outer_l2['srcmac']) if 'dstmac' in outer_l2: - self.set_dst_mac(outer_l2['dstmac']) + self._set_proto_addr(ETHERNET, DST, outer_l2['dstmac']) if 'QinQ' in outer_l2: self.set_qinq(outer_l2['QinQ']) - def set_outer_l3v4_fields(self, outer_l3v4): + def _set_outer_l3v4_fields(self, outer_l3v4): """ setup outer l3v4 fields from traffic profile """ ip_params = {} if 'proto' in outer_l3v4: - ip_params['proto'] = outer_l3v4['proto'] + ip_params['proto'] = socket.getprotobyname(outer_l3v4['proto']) if outer_l3v4['proto'] == 'tcp': self.udp_packet = Pkt.TCP() self.udp_dport = 'TCP.dport' self.udp_sport = 'TCP.sport' tcp_params = {'flags': '', 'window': 0} - self._set_udp_fields(**tcp_params) + self._set_proto_fields(UDP, **tcp_params) if 'ttl' in outer_l3v4: ip_params['ttl'] = outer_l3v4['ttl'] - self._set_ip_fields(**ip_params) + self._set_proto_fields(IP, **ip_params) if 'dscp' in outer_l3v4: - self.set_dscp(outer_l3v4['dscp']) + self._set_proto_addr(DSCP, TYPE_OF_SERVICE, outer_l3v4['dscp']) if 'srcip4' in outer_l3v4: - self.set_src_ip4(outer_l3v4['srcip4'], outer_l3v4['count']) + self._set_proto_addr(IP, SRC, outer_l3v4['srcip4'], outer_l3v4['count']) if 'dstip4' in outer_l3v4: - self.set_dst_ip4(outer_l3v4['dstip4'], outer_l3v4['count']) + self._set_proto_addr(IP, DST, outer_l3v4['dstip4'], outer_l3v4['count']) - def set_outer_l3v6_fields(self, outer_l3v6): + def _set_outer_l3v6_fields(self, outer_l3v6): """ setup outer l3v6 fields from traffic profile """ ether_params = {'type': 0x86dd} - self._set_ether_fields(**ether_params) + self._set_proto_fields(ETHERNET, **ether_params) ip6_params = {} if 'proto' in outer_l3v6: ip6_params['proto'] = outer_l3v6['proto'] @@ -353,25 +292,25 @@ class TrexProfile(TrafficProfile): self.udp_dport = 'TCP.dport' self.udp_sport = 'TCP.sport' tcp_params = {'flags': '', 'window': 0} - self._set_udp_fields(**tcp_params) + self._set_proto_fields(UDP, **tcp_params) if 'ttl' in outer_l3v6: ip6_params['ttl'] = outer_l3v6['ttl'] if 'tc' in outer_l3v6: ip6_params['tc'] = outer_l3v6['tc'] if 'hlim' in outer_l3v6: ip6_params['hlim'] = outer_l3v6['hlim'] - self._set_ip6_fields(**ip6_params) + self._set_proto_fields(IPv6, **ip6_params) if 'srcip6' in outer_l3v6: - self.set_src_ip6(outer_l3v6['srcip6']) + self._set_proto_addr(IPv6, SRC, outer_l3v6['srcip6']) if 'dstip6' in outer_l3v6: - self.set_dst_ip6(outer_l3v6['dstip6']) + self._set_proto_addr(IPv6, DST, outer_l3v6['dstip6']) - def set_outer_l4_fields(self, outer_l4): + def _set_outer_l4_fields(self, outer_l4): """ setup outer l4 fields from traffic profile """ if 'srcport' in outer_l4: - self.set_src_port(outer_l4['srcport'], outer_l4['count']) + self._set_proto_addr(UDP, SRC_PORT, outer_l4['srcport'], outer_l4['count']) if 'dstport' in outer_l4: - self.set_dst_port(outer_l4['dstport'], outer_l4['count']) + self._set_proto_addr(UDP, DST_PORT, outer_l4['dstport'], outer_l4['count']) def generate_imix_data(self, packet_definition): """ generate packet size for a given traffic profile """ @@ -434,13 +373,13 @@ class TrexProfile(TrafficProfile): outer_l3v6 = packet_definition.get('outer_l3v6', None) outer_l4 = packet_definition.get('outer_l4', None) if outer_l2: - self.set_outer_l2_fields(outer_l2) + self._set_outer_l2_fields(outer_l2) if outer_l3v4: - self.set_outer_l3v4_fields(outer_l3v4) + self._set_outer_l3v4_fields(outer_l3v4) if outer_l3v6: - self.set_outer_l3v6_fields(outer_l3v6) + self._set_outer_l3v6_fields(outer_l3v6) if outer_l4: - self.set_outer_l4_fields(outer_l4) + self._set_outer_l4_fields(outer_l4) self.trex_vm = STLScVmRaw(self.vm_flow_vars) def generate_packets(self): diff --git a/yardstick/network_services/vnf_generic/vnf/sample_vnf.py b/yardstick/network_services/vnf_generic/vnf/sample_vnf.py index 9a7d39913..1b2533aad 100644 --- a/yardstick/network_services/vnf_generic/vnf/sample_vnf.py +++ b/yardstick/network_services/vnf_generic/vnf/sample_vnf.py @@ -680,19 +680,19 @@ class ScenarioHelper(object): @property def task_path(self): - return self.scenario_cfg["task_path"] + return self.scenario_cfg['task_path'] @property def nodes(self): - return self.scenario_cfg['nodes'] + return self.scenario_cfg.get('nodes') @property def all_options(self): - return self.scenario_cfg["options"] + return self.scenario_cfg.get('options', {}) @property def options(self): - return self.all_options[self.name] + return self.all_options.get(self.name, {}) @property def vnf_cfg(self): @@ -742,7 +742,6 @@ class SampleVNF(GenericVNF): self.q_out = Queue() self.queue_wrapper = None self.run_kwargs = {} - self.scenario_cfg = None self.tg_port_pairs = None self.used_drivers = {} self.vnf_port_pairs = None @@ -937,7 +936,6 @@ class SampleVNFTrafficGen(GenericTrafficGen): def instantiate(self, scenario_cfg, context_cfg): self.scenario_helper.scenario_cfg = scenario_cfg self.resource_helper.generate_cfg() - self.setup_helper.setup_vnf_environment() self.resource_helper.setup() LOG.info("Starting %s server...", self.APP_NAME) diff --git a/yardstick/network_services/vnf_generic/vnf/tg_trex.py b/yardstick/network_services/vnf_generic/vnf/tg_trex.py index 616b331ba..1fe790f08 100644 --- a/yardstick/network_services/vnf_generic/vnf/tg_trex.py +++ b/yardstick/network_services/vnf_generic/vnf/tg_trex.py @@ -25,10 +25,19 @@ from yardstick.common.utils import mac_address_to_hex_list from yardstick.network_services.utils import get_nsb_option from yardstick.network_services.vnf_generic.vnf.sample_vnf import SampleVNFTrafficGen from yardstick.network_services.vnf_generic.vnf.sample_vnf import ClientResourceHelper +from yardstick.network_services.vnf_generic.vnf.sample_vnf import DpdkVnfSetupEnvHelper LOG = logging.getLogger(__name__) +class TrexDpdkVnfSetupEnvHelper(DpdkVnfSetupEnvHelper): + APP_NAME = "t-rex-64" + CFG_CONFIG = "" + CFG_SCRIPT = "" + PIPELINE_COMMAND = "" + VNF_TYPE = "TG" + + class TrexResourceHelper(ClientResourceHelper): CONF_FILE = '/tmp/trex_cfg.yaml' @@ -36,16 +45,14 @@ class TrexResourceHelper(ClientResourceHelper): RESOURCE_WORD = 'trex' RUN_DURATION = 0 - SYNC_PORT = 4500 - ASYNC_PORT = 4501 + ASYNC_PORT = 4500 + SYNC_PORT = 4501 def generate_cfg(self): ext_intf = self.vnfd_helper.interfaces vpci_list = [] port_list = [] trex_cfg = { - 'port_limit': 0, - 'version': '2', 'interfaces': vpci_list, 'port_info': port_list, "port_limit": len(ext_intf), @@ -79,6 +86,7 @@ class TrexResourceHelper(ClientResourceHelper): DISABLE_DEPLOY = True def setup(self): + super(TrexResourceHelper, self).setup() if self.DISABLE_DEPLOY: return @@ -130,6 +138,9 @@ class TrexTrafficGen(SampleVNFTrafficGen): if resource_helper_type is None: resource_helper_type = TrexResourceHelper + if setup_env_helper_type is None: + setup_env_helper_type = TrexDpdkVnfSetupEnvHelper + super(TrexTrafficGen, self).__init__(name, vnfd, setup_env_helper_type, resource_helper_type) diff --git a/yardstick/network_services/vnf_generic/vnf/udp_replay.py b/yardstick/network_services/vnf_generic/vnf/udp_replay.py index 6e206f2b2..a9bc204d5 100644 --- a/yardstick/network_services/vnf_generic/vnf/udp_replay.py +++ b/yardstick/network_services/vnf_generic/vnf/udp_replay.py @@ -16,6 +16,8 @@ from __future__ import absolute_import import logging from yardstick.network_services.vnf_generic.vnf.sample_vnf import SampleVNF +from yardstick.network_services.vnf_generic.vnf.sample_vnf import DpdkVnfSetupEnvHelper +from yardstick.network_services.vnf_generic.vnf.sample_vnf import ClientResourceHelper LOG = logging.getLogger(__name__) @@ -27,38 +29,65 @@ REPLAY_PIPELINE_COMMAND = ( # {tool_path} -p {ports_len_hex} -f {cfg_file} -s {script}' +class UdpReplaySetupEnvHelper(DpdkVnfSetupEnvHelper): + + APP_NAME = "UDP_Replay" + + +class UdpReplayResourceHelper(ClientResourceHelper): + pass + + class UdpReplayApproxVnf(SampleVNF): APP_NAME = "UDP_Replay" APP_WORD = "UDP_Replay" - PIPELINE_COMMAND = REPLAY_PIPELINE_COMMAND VNF_PROMPT = 'Replay>' - CSUM_MAP = { - 'baremetal': '', - 'sriov': '', - } + VNF_TYPE = 'UdpReplay' + + HW_OFFLOADING_NFVI_TYPES = {'baremetal', 'sriov'} + + PIPELINE_COMMAND = REPLAY_PIPELINE_COMMAND + + def __init__(self, name, vnfd, setup_env_helper_type=None, resource_helper_type=None): + if resource_helper_type is None: + resource_helper_type = UdpReplayResourceHelper + + if setup_env_helper_type is None: + setup_env_helper_type = UdpReplaySetupEnvHelper + + super(UdpReplayApproxVnf, self).__init__(name, vnfd, setup_env_helper_type, + resource_helper_type) + + def _start_server(self): + super(UdpReplayApproxVnf, self)._start_server() + self.resource_helper.start() def scale(self, flavor=""): """ scale vnfbased on flavor input """ raise NotImplementedError - def _build_config(self): - pass - def _deploy(self): self.generate_port_pairs() super(UdpReplayApproxVnf, self)._deploy() def _build_pipeline_kwargs(self): - tool_path = self.ssh_helper.provision_tool(self.APP_NAME) - ports_mask = 2 ** len(self.all_ports) - 1 + all_ports = [i for i, _ in enumerate(self.vnfd_helper.interfaces)] + number_of_ports = len(all_ports) + + tool_path = self.ssh_helper.provision_tool(tool_file=self.APP_NAME) + ports_mask = 2 ** number_of_ports - 1 ports_mask_hex = hex(ports_mask) - cpu_mask_hex = hex(ports_mask * 2) - hw_csum = self.CSUM_MAP.get(self.nfvi_type, "--no-hw-csum") - config_value = "".join(str((port, 0, port + 1)) for port in self.all_ports) + cpu_mask_hex = hex(2 ** (number_of_ports + 1) - 1) + hw_csum = "" + if (not self.scenario_helper.options.get('hw_csum', False) or + self.nfvi_context.attrs.get('nfvi_type') not in self.HW_OFFLOADING_NFVI_TYPES): + hw_csum = '--no-hw-csum' + + config_value = "".join(str((port, 0, port + 1)) for port in all_ports) - whitelist = " -w ".join(self.bound_pci) + whitelist = " -w ".join(self.setup_helper.bound_pci) self.pipeline_kwargs = { 'ports_len_hex': ports_mask_hex, 'tool_path': tool_path, @@ -68,13 +97,19 @@ class UdpReplayApproxVnf(SampleVNF): 'config': config_value, } + def _build_config(self): + self._build_pipeline_kwargs() + return self.PIPELINE_COMMAND.format(**self.pipeline_kwargs) + def collect_kpi(self): def get_sum(offset): return sum(int(i) for i in split_stats[offset::5]) + number_of_ports = len(self.vnfd_helper.interfaces) + stats = self.get_stats() stats_words = stats.split() - split_stats = stats_words[stats_words.index('0'):][:len(self.all_ports) * 5] + split_stats = stats_words[stats_words.index('0'):][:number_of_ports * 5] result = { "packets_in": get_sum(1), "packets_fwd": get_sum(2), |