From 4481df385ac03ece015ccb429201f96189dc5ae2 Mon Sep 17 00:00:00 2001 From: Martin Klozik Date: Wed, 14 Dec 2016 14:02:43 +0000 Subject: traffic: Configurable traffic details Traffic generated by traffic generator is based on default values and their modifications specific to particular testing scenario. Traffic default values were defined inside VSPERF code and it was not possible to change them. This patch introduces new TRAFFIC dictionary inside 03_traffic.conf. Thus user can modify any of TRAFFIC values either in configuration file or by CLI or by 'Parameters' section of testcase definition. Following CLI options were obsoleted by this patch: 'bidirectional', 'traffic_type', 'iload', 'multistream', 'stream_type' and 'pre-installed_flows' Following CLI option was renamed to be consistent with other options: 'tunnel_type' => 'TUNNEL_TYPE' Following sections of testcase definition were obsoleted: "Traffic Type", "biDirectional", "MultiStream", "Stream Type", "Pre-installed Flows", "Flow Type" and "iLoad" New TRAFFIC dictionary should be used instead of old CLI options and old testcase definition sections. Testcase definitons, yardstick sample testcases and documentation were updated to reflect configuration changes. JIRA: VSPERF-433 Change-Id: I03a388c766491d5688e715f6d7b51e8e0377ec27 Signed-off-by: Martin Klozik Reviewed-by: Al Morton Reviewed-by: Christian Trautman Reviewed-by: Bill Michalowski Reviewed-by: Antonio Fischetti Reviewed-by: --- conf/01_testcases.conf | 172 ++++++++++----------- conf/03_traffic.conf | 137 ++++++++++++++++ conf/__init__.py | 67 +++++--- conf/integration/01_testcases.conf | 80 +++++++--- docs/configguide/trafficgen.rst | 17 +- docs/design/trafficgen_integration_guide.rst | 20 ++- docs/design/vswitchperf_design.rst | 124 +++++++++++++++ docs/userguide/integration.rst | 10 +- docs/userguide/teststeps.rst | 26 +++- docs/userguide/testusage.rst | 31 +--- docs/userguide/yardstick.rst | 29 ++-- testcases/testcase.py | 41 ++--- tools/pkt_gen/dummy/dummy.py | 11 +- tools/pkt_gen/ixia/ixia.py | 5 +- tools/pkt_gen/ixnet/ixnet.py | 8 +- tools/pkt_gen/moongen/moongen.py | 18 +-- tools/pkt_gen/trafficgen/__init__.py | 1 - tools/pkt_gen/trafficgen/trafficgen.py | 14 +- tools/pkt_gen/trafficgen/trafficgenhelper.py | 94 ----------- tools/pkt_gen/xena/xena.py | 21 +-- vsperf | 38 ++--- yardstick/tests/p2p_rfc2544_throughput_sample.yaml | 5 +- yardstick/tests/rfc2544_back2back_dummy.yaml | 9 +- yardstick/tests/rfc2544_continuous_dummy.yaml | 6 +- yardstick/tests/rfc2544_throughput_dummy.yaml | 6 +- 25 files changed, 577 insertions(+), 413 deletions(-) delete mode 100644 tools/pkt_gen/trafficgen/trafficgenhelper.py diff --git a/conf/01_testcases.conf b/conf/01_testcases.conf index a8d7a136..bdaeb4da 100755 --- a/conf/01_testcases.conf +++ b/conf/01_testcases.conf @@ -19,60 +19,12 @@ # # "Name": "phy2phy_burst", # A human-readable string identifying the # # test. -# "Traffic Type": "rfc2544_throughput", -# # One of the supported traffic types. -# # It can be overridden by cli option traffic_type. # "Deployment": "p2p", # One of the supported deployment scenarios. # "Description": "Lorem ipsum..." # Optional. A human-readable string # # describing the test. # "Frame Modification": "vlan" # One of the supported frame modifications: # # vlan, mpls, mac, dscp, ttl, ip_addr, # # ip_port. -# "biDirectional": ["True"|"False"] -# # Specifies if generated traffic will be -# # full-duplex (True) or half-duplex (False) -# # It can be overridden by cli option bidirectional. -# # Default value is "False". Must be of type -# # string. -# "MultiStream": 0-65535 # Optional. Defines number of flows simulated -# # by traffic generator. Value 0 disables -# # MultiStream feature -# # It can be overridden by cli option multistream. -# "Stream Type": ["L2"|"L3"|"L4"] # Optional. Stream Type is an extension -# # of the "MultiStream" feature. If MultiStream -# # is disabled, then Stream Type will be ignored. -# # Stream Type defines ISO OSI network layer -# # used for simulation of multiple streams. -# # It can be overridden by cli option stream_type. -# # Values: -# # "L2" - iteration of destination MAC address -# # "L3" - iteration of destination IP address -# # "L4" - iteration of destination port -# # of selected transport protocol -# # Default value is "L4". -# "Pre-installed Flows": ["Yes"|"No"] -# # Optional. Pre-installed Flows is an extension -# # of the "MultiStream" feature. If MultiStream -# # is disabled, then Pre-installed Flows will be -# # ignored. It defines if stream specific flows -# # will be inserted into OVS or not. -# # It can be overridden by cli option -# # pre-installed_flows -# # Values: -# # "Yes" - flows will be inserted into OVS -# # "No" - flows won't be inserted into OVS -# # Default value is "No". -# "Flow Type": ["port"|"IP"] # Optional. Defines flows complexity. In case -# # it isn't specified, then "port" will be used. -# # Values: -# # "port" - flow is defined by ingress ports -# # "IP" - flow is defined by ingress ports -# # and src and dst IP addresses -# "iLoad": 0-100 # Optional. Defines desired percentage -# # of frame rate used during continuous stream -# # tests. Can be overridden by cli option -# # iload. -# # Default value is 100. # "Load": dictionary # Optional. Configures background load # # during testcase execution. # Description of "Load" dictionary keys, their meanings and available values: @@ -115,7 +67,7 @@ # # stated in configuration files or value # # specified on command line through --trafficgen # # parameter. -# "Parameters" : {'TRAFFICGEN_PKT_SIZES' : (512,)} +# "Parameters" : {'TRAFFICGEN_PKT_SIZES' : (512,)}, # # Dictionary with testcase specific configuration # # environment. Specified parameters will be modified # # before the test execution and their original values will @@ -129,128 +81,172 @@ PERFORMANCE_TESTS = [ { "Name": "phy2phy_tput", - "Traffic Type": "rfc2544_throughput", "Deployment": "p2p", - "biDirectional": "True", "Description": "LTD.Throughput.RFC2544.PacketLossRatio", + "Parameters" : { + "TRAFFIC" : { + "traffic_type" : "rfc2544_throughput", + }, + }, }, { "Name": "phy2phy_forwarding", - "Traffic Type": "rfc2889", "Deployment": "p2p", - "biDirectional": "True", "Description": "LTD.Forwarding.RFC2889.MaxForwardingRate", + "Parameters" : { + "TRAFFIC" : { + "traffic_type" : "rfc2889", + }, + }, }, { "Name": "back2back", - "Traffic Type": "rfc2544_back2back", "Deployment": "p2p", - "biDirectional": "True", "Description": "LTD.Throughput.RFC2544.BackToBackFrames", + "Parameters" : { + "TRAFFIC" : { + "traffic_type" : "rfc2544_back2back", + }, + }, }, { "Name": "phy2phy_tput_mod_vlan", - "Traffic Type": "rfc2544_throughput", "Deployment": "p2p", "Frame Modification": "vlan", - "biDirectional": "False", - "Description": "LTD.Throughput.RFC2544.PacketLossRatioFrameModification" + "Description": "LTD.Throughput.RFC2544.PacketLossRatioFrameModification", + "Parameters" : { + "TRAFFIC" : { + "traffic_type" : "rfc2544_throughput", + }, + }, }, { "Name": "phy2phy_cont", - "Traffic Type": "rfc2544_continuous", "Deployment": "p2p", "Description": "Phy2Phy Continuous Stream", - "biDirectional": "True", - "iLoad": "100", + "Parameters" : { + "TRAFFIC" : { + "traffic_type" : "rfc2544_continuous", + "frame_rate" : 100, + }, + }, }, { "Name": "pvp_cont", - "Traffic Type": "rfc2544_continuous", "Deployment": "pvp", "Description": "PVP Continuous Stream", - "biDirectional": "True", - "iLoad": "100", + "Parameters" : { + "TRAFFIC" : { + "traffic_type" : "rfc2544_continuous", + "frame_rate" : 100, + }, + }, }, { "Name": "pvvp_cont", - "Traffic Type": "rfc2544_continuous", "Deployment": "pvvp", "Description": "PVVP Continuous Stream", - "biDirectional": "True", - "iLoad": "100", + "Parameters" : { + "TRAFFIC" : { + "traffic_type" : "rfc2544_continuous", + "frame_rate" : 100, + }, + }, }, { "Name": "pvpv_cont", - "Traffic Type": "rfc2544_continuous", "Deployment": "pvpv", "Description": "Two VMs in parallel with Continuous Stream", - "biDirectional": "True", - "iLoad": "100", + "Parameters" : { + "TRAFFIC" : { + "traffic_type" : "rfc2544_continuous", + "frame_rate" : 100, + }, + }, }, { "Name": "phy2phy_scalability", - "Traffic Type": "rfc2544_throughput", "Deployment": "p2p", - "biDirectional": "True", "Description": "LTD.Scalability.Flows.RFC2544.0PacketLoss", - "MultiStream": "8000", + "Parameters" : { + "TRAFFIC" : { + "traffic_type" : "rfc2544_throughput", + "multistream" : "8000", + }, + }, }, { "Name": "pvp_tput", - "Traffic Type": "rfc2544_throughput", "Deployment": "pvp", "Description": "LTD.Throughput.RFC2544.PacketLossRatio", - "biDirectional": "True", + "Parameters" : { + "TRAFFIC" : { + "traffic_type" : "rfc2544_throughput", + }, + }, }, { "Name": "pvp_back2back", - "Traffic Type": "rfc2544_back2back", "Deployment": "pvp", "Description": "LTD.Throughput.RFC2544.BackToBackFrames", - "biDirectional": "True", + "Parameters" : { + "TRAFFIC" : { + "traffic_type" : "rfc2544_back2back", + }, + }, }, { "Name": "pvvp_tput", - "Traffic Type": "rfc2544_throughput", "Collector": "cpu", "Deployment": "pvvp", "Description": "LTD.Throughput.RFC2544.PacketLossRatio", - "biDirectional": "True", + "Parameters" : { + "TRAFFIC" : { + "traffic_type" : "rfc2544_throughput", + }, + }, }, { "Name": "pvvp_back2back", - "Traffic Type": "rfc2544_back2back", "Collector": "cpu", "Deployment": "pvvp", "Description": "LTD.Throughput.RFC2544.BackToBackFrames", - "biDirectional": "True", + "Parameters" : { + "TRAFFIC" : { + "traffic_type" : "rfc2544_back2back", + }, + }, }, { "Name": "phy2phy_cpu_load", - "Traffic Type": "rfc2544_throughput", "Deployment": "p2p", - "biDirectional": "True", "Description": "LTD.CPU.RFC2544.0PacketLoss", "Load" : { "tool" : "stress-ng", "load" : 100, "reserved" : 4, "pattern" : "c", - } + }, + "Parameters" : { + "TRAFFIC" : { + "traffic_type" : "rfc2544_throughput", + }, + }, }, { "Name": "phy2phy_mem_load", - "Traffic Type": "rfc2544_throughput", "Deployment": "p2p", - "biDirectional": "True", "Description": "LTD.Memory.RFC2544.0PacketLoss", "Load" : { "tool" : "stress-ng", "load" : 50, "pattern" : "m", "load_memory" : 80, - } + }, + "Parameters" : { + "TRAFFIC" : { + "traffic_type" : "rfc2544_throughput", + }, + }, }, - ] diff --git a/conf/03_traffic.conf b/conf/03_traffic.conf index 87210b8d..72324660 100644 --- a/conf/03_traffic.conf +++ b/conf/03_traffic.conf @@ -19,6 +19,143 @@ # log file for all traffic generator related commands LOG_FILE_TRAFFIC_GEN = 'traffic-gen.log' +# TRAFFIC dictionary defines traffic parameters used by all traffic generators. +# Detailed description of TRAFFIC dictionary items follows: +# +# 'traffic_type' - One of the supported traffic types. +# E.g. rfc2544_throughput, rfc2544_back2back +# or rfc2544_continuous +# Data type: str +# Default value: "rfc2544_throughput". +# 'bidir' - Specifies if generated traffic will be full-duplex (True) +# or half-duplex (False) +# Data type: str +# Supported values: "True", "False" +# Default value: "False". +# 'frame_rate' - Defines desired percentage of frame rate used during +# continuous stream tests. +# Data type: int +# Default value: 100. +# 'multistream' - Defines number of flows simulated by traffic generator. +# Value 0 disables multistream feature +# Data type: int +# Supported values: 0-65535 +# Default value: 0. +# 'stream_type' - Stream type is an extension of the "multistream" feature. +# If multistream is disabled, then stream type will be +# ignored. Stream type defines ISO OSI network layer used +# for simulation of multiple streams. +# Data type: str +# Supported values: +# "L2" - iteration of destination MAC address +# "L3" - iteration of destination IP address +# "L4" - iteration of destination port +# of selected transport protocol +# Default value: "L4". +# 'pre_installed_flows' +# - Pre-installed flows is an extension of the multistream" +# feature. If multistream is disabled, then pre-installed +# flows will be ignored. It defines if stream specific flows +# will be inserted into OVS or not. +# Data type: str +# Supported values: +# "Yes" - flows will be inserted into OVS +# "No" - flows won't be inserted into OVS +# Default value: "No". +# 'flow_type' - Defines flows complexity. +# Data type: str +# Supported values: +# "port" - flow is defined by ingress ports +# "IP" - flow is defined by ingress ports +# and src and dst IP addresses +# Default value: "port" +# 'l2' - A dictionary with l2 network layer details. Supported +# values are: +# 'srcmac' - Specifies source MAC address filled by traffic generator. +# NOTE: It can be modified by vsperf in some scenarios. +# Data type: str +# Default value: "00:00:00:00:00:00". +# 'dstmac' - Specifies destination MAC address filled by traffic generator. +# NOTE: It can be modified by vsperf in some scenarios. +# Data type: str +# Default value: "00:00:00:00:00:00". +# 'framesize' - Specifies default frame size. This value should not be +# changed directly. It will be overridden during testcase +# execution by values specified by list TRAFFICGEN_PKT_SIZES. +# Data type: int +# Default value: 64 +# 'l3' - A dictionary with l3 network layer details. Supported +# values are: +# 'srcip' - Specifies source MAC address filled by traffic generator. +# NOTE: It can be modified by vsperf in some scenarios. +# Data type: str +# Default value: "1.1.1.1". +# 'dstip' - Specifies destination MAC address filled by traffic generator. +# NOTE: It can be modified by vsperf in some scenarios. +# Data type: str +# Default value: "90.90.90.90". +# 'proto' - Specifies deflaut protocol type. +# Please check particular traffic generator implementation +# for supported protocol types. +# Data type: str +# Default value: "udp". +# 'l4' - A dictionary with l4 network layer details. Supported +# values are: +# 'srcport' - Specifies source port of selected transport protocol. +# NOTE: It can be modified by vsperf in some scenarios. +# Data type: int +# Default value: 3000 +# 'dstport' - Specifies destination port of selected transport protocol. +# NOTE: It can be modified by vsperf in some scenarios. +# Data type: int +# Default value: 3001 +# 'vlan' - A dictionary with vlan encapsulation details. Supported +# values are: +# 'enabled' - Specifies if vlan encapsulation should be enabled or +# disabled. +# Data type: bool +# Default value: False +# 'id' - Specifies vlan id. +# Data type: int (NOTE: must fit to 12 bits) +# Default value: 0 +# 'priority' - Specifies a vlan priority (PCP header field). +# Data type: int (NOTE: must fit to 3 bits) +# Default value: 0 +# 'cfi' - Specifies if frames can or cannot be dropped during +# congestion (DEI header field). +# Data type: int (NOTE: must fit to 1 bit) +# Default value: 0 +TRAFFIC = { + 'traffic_type' : 'rfc2544_throughput', + 'frame_rate' : 100, + 'bidir' : 'True', # will be passed as string in title format to tgen + 'multistream' : 0, + 'stream_type' : 'L4', + 'pre_installed_flows' : 'No', # used by vswitch implementation + 'flow_type' : 'port', # used by vswitch implementation + + 'l2': { + 'framesize': 64, + 'srcmac': '00:00:00:00:00:00', + 'dstmac': '00:00:00:00:00:00', + }, + 'l3': { + 'proto': 'udp', + 'srcip': '1.1.1.1', + 'dstip': '90.90.90.90', + }, + 'l4': { + 'srcport': 3000, + 'dstport': 3001, + }, + 'vlan': { + 'enabled': False, + 'id': 0, + 'priority': 0, + 'cfi': 0, + }, +} + #path to traffic generators directory. TRAFFICGEN_DIR = os.path.join(ROOT_DIR, 'tools/pkt_gen') diff --git a/conf/__init__.py b/conf/__init__.py index 2448d390..2a2586ff 100644 --- a/conf/__init__.py +++ b/conf/__init__.py @@ -20,6 +20,7 @@ and any user provided settings file. # pylint: disable=invalid-name +import copy import os import re import logging @@ -30,8 +31,7 @@ import netaddr _LOGGER = logging.getLogger(__name__) # Special test parameters which are not part of standard VSPERF configuration -_EXTRA_TEST_PARAMS = ['bidirectional', 'traffic_type', 'iload', 'tunnel_type', - 'multistream', 'stream_type', 'pre-installed_flows'] +_EXTRA_TEST_PARAMS = ['TUNNEL_TYPE'] # regex to parse configuration macros from 04_vnf.conf # it will select all patterns starting with # sign @@ -57,9 +57,19 @@ class Settings(object): return getattr(self, attr) else: master_value = getattr(self, attr) - # Check if parameter value was overridden by CLI option + # Check if parameter value was modified by CLI option cli_value = get_test_param(attr, None) - return cli_value if cli_value else master_value + if cli_value: + # TRAFFIC dictionary is not overridden by CLI option + # but only updated by specified values + if attr == 'TRAFFIC': + tmp_value = copy.deepcopy(master_value) + tmp_value = merge_spec(tmp_value, cli_value) + return tmp_value + else: + return cli_value + else: + return master_value else: raise AttributeError("%r object has no attribute %r" % (self.__class__, attr)) @@ -137,7 +147,12 @@ class Settings(object): """ for key in conf: if conf[key] is not None: - setattr(self, key.upper(), conf[key]) + if isinstance(conf[key], dict): + # recursively update dict items, e.g. TEST_PARAMS + setattr(self, key.upper(), + merge_spec(getattr(self, key.upper()), conf[key])) + else: + setattr(self, key.upper(), conf[key]) def load_from_env(self): """ @@ -271,17 +286,33 @@ def get_test_param(key, default=None): :returns: Value for ``key`` if found, else ``default``. """ test_params = settings.getValue('TEST_PARAMS') - if key in test_params: - if not isinstance(test_params.get(key), str): - return test_params.get(key) + return test_params.get(key, default) if test_params else default + +def merge_spec(orig, new): + """Merges ``new`` dict with ``orig`` dict, and returns orig. + + This takes into account nested dictionaries. Example: + + >>> old = {'foo': 1, 'bar': {'foo': 2, 'bar': 3}} + >>> new = {'foo': 6, 'bar': {'foo': 7}} + >>> merge_spec(old, new) + {'foo': 6, 'bar': {'foo': 7, 'bar': 3}} + + You'll notice that ``bar.bar`` is not removed. This is the desired result. + """ + for key in orig: + if key not in new: + continue + + # Not allowing derived dictionary types for now + # pylint: disable=unidiomatic-typecheck + if type(orig[key]) == dict: + orig[key] = merge_spec(orig[key], new[key]) else: - # values are passed inside string from CLI, so we must retype them accordingly - try: - return ast.literal_eval(test_params.get(key)) - except ValueError: - # for backward compatibility, we have to accept strings without quotes - _LOGGER.warning("Adding missing quotes around string value: %s = %s", - key, str(test_params.get(key))) - return str(test_params.get(key)) - else: - return default + orig[key] = new[key] + + for key in new: + if key not in orig: + orig[key] = new[key] + + return orig diff --git a/conf/integration/01_testcases.conf b/conf/integration/01_testcases.conf index ff05186b..504b4458 100644 --- a/conf/integration/01_testcases.conf +++ b/conf/integration/01_testcases.conf @@ -25,15 +25,15 @@ SUPPORTED_TUNNELING_PROTO = ['vxlan', 'gre', 'geneve'] # # Required for OP2P tests # "Tunnel Type": ["vxlan"|"gre"|"geneve"] # Tunnel Type defines tunneling protocol to use. -# # It can be overridden by cli option tunnel_type. +# # It can be overridden by cli option TUNNEL_TYPE. # # Values: # # "vxlan" - iteration of destination MAC address # # "gre" - iteration of destination IP address # # "geneve" - iteration of destination UDP port # # Default value is "vxlan". # -# biDirectional testing for OP2P is not yet supported. -# biDirectional must be set to False. +# bidirectional testing for OP2P is not yet supported. +# TRAFFIC['bidir'] must be set to 'False'. # # "TestSteps": [] # Definition of integration test steps. # # In case that this list is defined, then @@ -320,55 +320,75 @@ STEP_VSWITCH_2PHY_6VM_FINIT = [ INTEGRATION_TESTS = [ { "Name": "overlay_p2p_mod_tput", - "Traffic Type": "rfc2544_throughput", "Deployment": "ptunp", - "biDirectional": 'True', "Tunnel Type": "vxlan", "Description": ("Tunneling Throughput RFC2544 Test." "The encap and decap are performed inside the " "virtual switch itself in each direction to avoid " "the need of ingress overlay traffic."), - "Parameters": {'TRAFFICGEN_IXNET_TCL_SCRIPT' : 'ixnetrfc2544v2.tcl'}, + "Parameters": { + "TRAFFICGEN_IXNET_TCL_SCRIPT" : "ixnetrfc2544v2.tcl", + "TRAFFIC" : { + "traffic_type" : "rfc2544_throughput", + "bidir" : "False", + }, + }, }, { "Name": "overlay_p2p_tput", - "Traffic Type": "rfc2544_throughput", "Deployment": "op2p", - "biDirectional": 'False', "Tunnel Type": SUPPORTED_TUNNELING_PROTO[0], "Tunnel Operation": "encapsulation", "Description": "Overlay Encapsulation Throughput RFC2544 Test", - "Parameters": {'TRAFFICGEN_IXNET_TCL_SCRIPT' : 'ixnetrfc2544v2.tcl'}, + "Parameters": { + "TRAFFICGEN_IXNET_TCL_SCRIPT" : "ixnetrfc2544v2.tcl", + "TRAFFIC" : { + "traffic_type" : "rfc2544_throughput", + "bidir" : "False", + }, + }, }, { "Name": "overlay_p2p_cont", - "Traffic Type": "rfc2544_continuous", "Deployment": "op2p", - "biDirectional": 'False', "Tunnel Type": SUPPORTED_TUNNELING_PROTO[0], "Tunnel Operation": "encapsulation", "Description": "Overlay Encapsulation RFC2544 Continuous Stream", - "Parameters": {'TRAFFICGEN_IXNET_TCL_SCRIPT' : 'ixnetrfc2544v2.tcl'}, + "Parameters": { + "TRAFFICGEN_IXNET_TCL_SCRIPT" : "ixnetrfc2544v2.tcl", + "TRAFFIC" : { + "traffic_type" : "rfc2544_continuous", + "bidir" : "False", + }, + }, }, { "Name": "overlay_p2p_decap_tput", - "Traffic Type": "rfc2544_throughput", "Deployment": "op2p", - "biDirectional": 'False', "Tunnel Type": SUPPORTED_TUNNELING_PROTO[0], "Tunnel Operation": "decapsulation", "Description": "Overlay Decapsulation Throughput RFC2544 Test", - "Parameters": {'TRAFFICGEN_IXNET_TCL_SCRIPT' : 'ixnetrfc2544v2.tcl'}, + "Parameters": { + "TRAFFICGEN_IXNET_TCL_SCRIPT" : "ixnetrfc2544v2.tcl", + "TRAFFIC" : { + "traffic_type" : "rfc2544_throughput", + "bidir" : "False", + }, + }, }, { "Name": "overlay_p2p_decap_cont", - "Traffic Type": "rfc2544_continuous", "Deployment": "op2p", - "biDirectional": 'False', "Tunnel Type": SUPPORTED_TUNNELING_PROTO[0], "Tunnel Operation": "decapsulation", "Description": "Overlay Decapsulation RFC2544 Continuous Stream", - "Parameters": {'TRAFFICGEN_IXNET_TCL_SCRIPT' : 'ixnetrfc2544v2.tcl'}, + "Parameters": { + "TRAFFICGEN_IXNET_TCL_SCRIPT" : "ixnetrfc2544v2.tcl", + "TRAFFIC" : { + "traffic_type" : "rfc2544_continuous", + "bidir" : "False", + }, + }, }, { "Name": "vswitch_add_del_bridge", @@ -758,8 +778,12 @@ INTEGRATION_TESTS = [ "Name": "2pvp_udp_dest_flows", "Description": "RFC2544 Continuous TC with 2 Parallel VMs, flows on UDP Dest Port", "Deployment": "clean", - "Stream Type": "L4", - "MultiStream": 2, + "Parameters" : { + "TRAFFIC" : { + "multistream" : 2, + "stream_type" : "L4", + }, + }, "TestSteps": STEP_VSWITCH_2PHY_2VM_INIT + STEP_VSWITCH_2_PARALLEL_VM_FLOWS_INIT + [ # Start 2 VMs @@ -781,8 +805,12 @@ INTEGRATION_TESTS = [ "Name": "4pvp_udp_dest_flows", "Description": "RFC2544 Continuous TC with 4 Parallel VMs, flows on UDP Dest Port", "Deployment": "clean", - "Stream Type": "L4", - "MultiStream": 4, + "Parameters" : { + "TRAFFIC" : { + "multistream" : 4, + "stream_type" : "L4", + }, + }, "TestSteps": STEP_VSWITCH_2PHY_4VM_INIT + STEP_VSWITCH_4_PARALLEL_VM_FLOWS_INIT + [ # Start 4 VMs @@ -808,8 +836,12 @@ INTEGRATION_TESTS = [ "Name": "6pvp_udp_dest_flows", "Description": "RFC2544 Continuous TC with 6 Parallel VMs, flows on UDP Dest Port", "Deployment": "clean", - "Stream Type": "L4", - "MultiStream": 6, + "Parameters" : { + "TRAFFIC" : { + "multistream" : 6, + "stream_type" : "L4", + }, + }, "TestSteps": STEP_VSWITCH_2PHY_6VM_INIT + STEP_VSWITCH_6_PARALLEL_VM_FLOWS_INIT + [ # Start VMs diff --git a/docs/configguide/trafficgen.rst b/docs/configguide/trafficgen.rst index 6d75a56f..e1eaf9f3 100644 --- a/docs/configguide/trafficgen.rst +++ b/docs/configguide/trafficgen.rst @@ -28,20 +28,27 @@ and configure the various traffic generators. Background Information ---------------------- -The traffic default configuration can be found in -tools/pkt_gen/trafficgen/trafficgenhelper.py, and is configured as -follows: +The traffic default configuration can be found in **conf/03_traffic.conf**, +and is configured as follows: .. code-block:: console - TRAFFIC_DEFAULTS = { + TRAFFIC = { + 'traffic_type' : 'rfc2544_throughput', + 'frame_rate' : 100, + 'bidir' : 'True', # will be passed as string in title format to tgen + 'multistream' : 0, + 'stream_type' : 'L4', + 'pre_installed_flows' : 'No', # used by vswitch implementation + 'flow_type' : 'port', # used by vswitch implementation + 'l2': { 'framesize': 64, 'srcmac': '00:00:00:00:00:00', 'dstmac': '00:00:00:00:00:00', }, 'l3': { - 'proto': 'tcp', + 'proto': 'udp', 'srcip': '1.1.1.1', 'dstip': '90.90.90.90', }, diff --git a/docs/design/trafficgen_integration_guide.rst b/docs/design/trafficgen_integration_guide.rst index 9bb0e825..1457052b 100644 --- a/docs/design/trafficgen_integration_guide.rst +++ b/docs/design/trafficgen_integration_guide.rst @@ -81,29 +81,28 @@ Step 3 - configuration All configuration values, required for correct traffic generator function, are passed from VSPERF to the traffic generator in a dictionary. Default values shared among -all traffic generators are defined in **tools/pkt_gen/trafficgen/trafficgenhelper.py** -as **TRAFFIC_DEFAULTS** dictionary. Default values are loaded by **ITrafficGenerator** -interface class automatically, so it is not needed to load them explicitly. In case -that there are any traffic generator specific default values, then they should -be set within class specific **__init__** function. +all traffic generators are defined in **conf/03_traffic.conf** within **TRAFFIC** +dictionary. Default values are loaded by **ITrafficGenerator** interface class +automatically, so it is not needed to load them explicitly. In case that there are +any traffic generator specific default values, then they should be set within class +specific **__init__** function. VSPERF passes test specific configuration within **traffic** dictionary to every start and send function. So implementation of these functions must ensure, that default values are updated with the testcase specific values. Proper merge -of values is assured by call of **merge_spec** function from **trafficgenhelper** -module. +of values is assured by call of **merge_spec** function from **conf** module. Example of **merge_spec** usage in **tools/pkt_gen/sample_tg/sample_tg.py** module: .. code-block:: python - from tools.pkt_gen.trafficgen.trafficgenhelper import merge_spec + from conf import merge_spec def start_rfc2544_throughput(self, traffic=None, duration=30): self._params = {} self._params['traffic'] = self.traffic_defaults.copy() if traffic: - self._params['traffic'] = trafficgen.merge_spec( + self._params['traffic'] = merge_spec( self._params['traffic'], traffic) @@ -199,8 +198,7 @@ functions: e.g. **rfc2544_throughput**, **rfc2544_continuous** or **rfc2544_back2back**. * param **frame_rate**: Defines desired percentage of frame - rate used during continuous stream tests. It can be set by test - parameter iLoad or by CLI parameter iload. + rate used during continuous stream tests. * param **bidir**: Specifies if generated traffic will be full-duplex (true) or half-duplex (false). * param **multistream**: Defines number of flows simulated by traffic diff --git a/docs/design/vswitchperf_design.rst b/docs/design/vswitchperf_design.rst index 4f33a99f..96b97631 100755 --- a/docs/design/vswitchperf_design.rst +++ b/docs/design/vswitchperf_design.rst @@ -263,6 +263,130 @@ a section in the ``conf\10_custom.conf`` file that can be used. .. _VSPERF installation scripts: http://artifacts.opnfv.org/vswitchperf/docs/configguide/installation.html#other-requirements +Configuration of TRAFFIC dictionary +----------------------------------- + +TRAFFIC dictionary is used for configuration of traffic generator. Default values +can be found in configuration file ``conf/03_traffic.conf``. These default values +can be modified by (first option has the highest priorty): + + 1. ``Parameters`` section of testcase defintion + 2. command line options specified by ``--test-params`` argument + 3. custom configuration file + +It is to note, that in case of option 1 and 2, it is possible to specify only +values, which should be changed. In case of custom configuration file, it is +required to specify whole ``TRAFFIC`` dictionary with its all values or explicitly +call and update() method of ``TRAFFIC`` dictionary. + +Detailed description of ``TRAFFIC`` dictionary items follows: + +.. code-block:: console + + 'traffic_type' - One of the supported traffic types. + E.g. rfc2544_throughput, rfc2544_back2back + or rfc2544_continuous + Data type: str + Default value: "rfc2544_throughput". + 'bidir' - Specifies if generated traffic will be full-duplex (True) + or half-duplex (False) + Data type: str + Supported values: "True", "False" + Default value: "False". + 'frame_rate' - Defines desired percentage of frame rate used during + continuous stream tests. + Data type: int + Default value: 100. + 'multistream' - Defines number of flows simulated by traffic generator. + Value 0 disables multistream feature + Data type: int + Supported values: 0-65535 + Default value: 0. + 'stream_type' - Stream type is an extension of the "multistream" feature. + If multistream is disabled, then stream type will be + ignored. Stream type defines ISO OSI network layer used + for simulation of multiple streams. + Data type: str + Supported values: + "L2" - iteration of destination MAC address + "L3" - iteration of destination IP address + "L4" - iteration of destination port + of selected transport protocol + Default value: "L4". + 'pre_installed_flows' + - Pre-installed flows is an extension of the multistream" + feature. If multistream is disabled, then pre-installed + flows will be ignored. It defines if stream specific flows + will be inserted into OVS or not. + Data type: str + Supported values: + "Yes" - flows will be inserted into OVS + "No" - flows won't be inserted into OVS + Default value: "No". + 'flow_type' - Defines flows complexity. + Data type: str + Supported values: + "port" - flow is defined by ingress ports + "IP" - flow is defined by ingress ports + and src and dst IP addresses + Default value: "port" + 'l2' - A dictionary with l2 network layer details. Supported + values are: + 'srcmac' - Specifies source MAC address filled by traffic generator. + NOTE: It can be modified by vsperf in some scenarios. + Data type: str + Default value: "00:00:00:00:00:00". + 'dstmac' - Specifies destination MAC address filled by traffic generator. + NOTE: It can be modified by vsperf in some scenarios. + Data type: str + Default value: "00:00:00:00:00:00". + 'framesize' - Specifies default frame size. This value should not be + changed directly. It will be overridden during testcase + execution by values specified by list TRAFFICGEN_PKT_SIZES. + Data type: int + Default value: 64 + 'l3' - A dictionary with l3 network layer details. Supported + values are: + 'srcip' - Specifies source MAC address filled by traffic generator. + NOTE: It can be modified by vsperf in some scenarios. + Data type: str + Default value: "1.1.1.1". + 'dstip' - Specifies destination MAC address filled by traffic generator. + NOTE: It can be modified by vsperf in some scenarios. + Data type: str + Default value: "90.90.90.90". + 'proto' - Specifies deflaut protocol type. + Please check particular traffic generator implementation + for supported protocol types. + Data type: str + Default value: "udp". + 'l4' - A dictionary with l4 network layer details. Supported + values are: + 'srcport' - Specifies source port of selected transport protocol. + NOTE: It can be modified by vsperf in some scenarios. + Data type: int + Default value: 3000 + 'dstport' - Specifies destination port of selected transport protocol. + NOTE: It can be modified by vsperf in some scenarios. + Data type: int + Default value: 3001 + 'vlan' - A dictionary with vlan encapsulation details. Supported + values are: + 'enabled' - Specifies if vlan encapsulation should be enabled or + disabled. + Data type: bool + Default value: False + 'id' - Specifies vlan id. + Data type: int (NOTE: must fit to 12 bits) + Default value: 0 + 'priority' - Specifies a vlan priority (PCP header field). + Data type: int (NOTE: must fit to 3 bits) + Default value: 0 + 'cfi' - Specifies if frames can or cannot be dropped during + congestion (DEI header field). + Data type: int (NOTE: must fit to 1 bit) + Default value: 0 + Configuration of GUEST options ------------------------------ diff --git a/docs/userguide/integration.rst b/docs/userguide/integration.rst index 003e8adb..60ed9245 100755 --- a/docs/userguide/integration.rst +++ b/docs/userguide/integration.rst @@ -82,21 +82,21 @@ To run VXLAN encapsulation tests: .. code-block:: console ./vsperf --conf-file user_settings.py --integration \ - --test-params 'tunnel_type=vxlan' overlay_p2p_tput + --test-params 'TUNNEL_TYPE=vxlan' overlay_p2p_tput To run GRE encapsulation tests: .. code-block:: console ./vsperf --conf-file user_settings.py --integration \ - --test-params 'tunnel_type=gre' overlay_p2p_tput + --test-params 'TUNNEL_TYPE=gre' overlay_p2p_tput To run GENEVE encapsulation tests: .. code-block:: console ./vsperf --conf-file user_settings.py --integration \ - --test-params 'tunnel_type=geneve' overlay_p2p_tput + --test-params 'TUNNEL_TYPE=geneve' overlay_p2p_tput To run OVS NATIVE tunnel tests (VXLAN/GRE/GENEVE): @@ -128,7 +128,7 @@ To run OVS NATIVE tunnel tests (VXLAN/GRE/GENEVE): .. code-block:: console ./vsperf --conf-file user_settings.py --integration \ - --test-params 'tunnel_type=vxlan' overlay_p2p_tput + --test-params 'TUNNEL_TYPE=vxlan' overlay_p2p_tput Executing VXLAN decapsulation tests @@ -189,7 +189,7 @@ To run GRE decapsulation tests: .. code-block:: console - ./vsperf --conf-file user_settings.py --test-params 'tunnel_type=gre' \ + ./vsperf --conf-file user_settings.py --test-params 'TUNNEL_TYPE=gre' \ --integration overlay_p2p_decap_cont diff --git a/docs/userguide/teststeps.rst b/docs/userguide/teststeps.rst index 5e2d9570..5029f538 100644 --- a/docs/userguide/teststeps.rst +++ b/docs/userguide/teststeps.rst @@ -374,8 +374,12 @@ That is accomplished by using "Stream Type" and "MultiStream" keywords. "Name": "multistream_l4", "Description": "Multistream on UDP ports", "Deployment": "clean", - "Stream Type": "L4", - "MultiStream": 4, + "Parameters": { + 'TRAFFIC' : { + "multistream": 4, + "stream_type": "L4", + }, + }, "TestSteps": [ ['vswitch', 'add_switch', 'int_br0'], # STEP 0 ['vswitch', 'add_phy_port', 'int_br0'], # STEP 1 @@ -542,8 +546,12 @@ destination UDP port. "Name": "ex_2pvp_rule_l4dp", "Description": "2 PVP with flows on L4 Dest Port", "Deployment": "clean", - "Stream Type": "L4", # loop UDP ports - "MultiStream": 2, + "Parameters": { + 'TRAFFIC' : { + "multistream": 2, + "stream_type": "L4", + }, + }, "TestSteps": [ ['vswitch', 'add_switch', 'int_br0'], # STEP 0 ['vswitch', 'add_phy_port', 'int_br0'], # STEP 1 @@ -622,12 +630,14 @@ and available in both csv and rst report files. { "Name": "pvvp_pvp_cont", - "Traffic Type": "continuous", "Deployment": "pvvp", "Description": "PVVP and PVP in parallel with Continuous Stream", - "biDirectional": "True", - "iLoad": "100", - "MultiStream": "2", + "Parameters" : { + "TRAFFIC" : { + "traffic_type" : "rfc2544_continuous", + "multistream": 2, + }, + }, "TestSteps": [ ['vswitch', 'add_vport', 'br0'], ['vswitch', 'add_vport', 'br0'], diff --git a/docs/userguide/testusage.rst b/docs/userguide/testusage.rst index 379618d2..9a9a23c0 100755 --- a/docs/userguide/testusage.rst +++ b/docs/userguide/testusage.rst @@ -719,36 +719,19 @@ Mode of operation is driven by configuration parameter -m or --mode "trafficgen-pause" - execute vSwitch and VNF but wait before traffic transmission In case, that VSPERF is executed in "trafficgen" mode, then configuration -of traffic generator should be configured through ``--test-params`` option. -Supported CLI options useful for traffic generator configuration are: - -.. code-block:: console - - 'traffic_type' - One of the supported traffic types. E.g. - rfc2544_throughput, - rfc2544_back2back or rfc2544_continuous - Default value is "rfc2544_throughput". - 'bidirectional' - Specifies if generated traffic will be full-duplex (true) - or half-duplex (false) - Default value is "false". - 'iload' - Defines desired percentage of frame rate used during - continuous stream tests. - Default value is 100. - 'multistream' - Defines number of flows simulated by traffic generator. - Value 0 disables MultiStream feature - Default value is 0. - 'stream_type' - Stream Type is an extension of the "MultiStream" feature. - If MultiStream is disabled, then Stream Type will be - ignored. Stream Type defines ISO OSI network layer used - for simulation of multiple streams. - Default value is "L4". +of traffic generator can be modified through ``TRAFFIC`` dictionary passed to the +``--test-params`` option. It is not needed to specify all values of ``TRAFFIC`` +dictionary. It is sufficient to specify only values, which should be changed. +Detailed description of ``TRAFFIC`` dictionary can be found at +`Configuration of TRAFFIC dictionary +`__ Example of execution of VSPERF in "trafficgen" mode: .. code-block:: console $ ./vsperf -m trafficgen --trafficgen IxNet --conf-file vsperf.conf \ - --test-params "traffic_type=rfc2544_continuous;bidirectional=True;iload=60" + --test-params "TRAFFIC={'traffic_type':'rfc2544_continuous','bidir':'False','framerate':60}" Code change verification by pylint ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/userguide/yardstick.rst b/docs/userguide/yardstick.rst index 985a25ad..c906df8e 100755 --- a/docs/userguide/yardstick.rst +++ b/docs/userguide/yardstick.rst @@ -146,14 +146,10 @@ Example of yaml file: type: Vsperf options: testname: 'p2p_rfc2544_throughput' - traffic_type: 'rfc2544_throughput' - frame_size '64' - bidirectional: 'True' - iload: 100 trafficgen_port1: 'eth1' trafficgen_port2: 'eth3' external_bridge: 'br-ex' - test_params: 'TRAFFICGEN_DURATION=30;' + test_params: 'TRAFFICGEN_DURATION=30;TRAFFIC={'traffic_type':'rfc2544_throughput}' conf_file: '~/vsperf-yardstick.conf' host: vsperf.demo @@ -182,19 +178,9 @@ Section **option** defines details of vswitchperf test scenario. Lot of options are identical to the vswitchperf parameters passed through ``--test-params`` argument. Following options are supported: -- **traffic_type** - specifies the type of traffic executed by traffic generator; - Valid values are ``rfc2544_throughput``, ``rfc2544_continuous`` and ``rfc2544_back2back``. - Default: ``rfc2544_throughput`` - **frame_size** - a packet size for which test should be executed; Multiple packet sizes can be tested by modification of Sequence runner section inside YAML definition. Default: '64' -- **bidirectional** - specifies if traffic will be uni (False) or bi-directional - (True); Default: False -- **iload** - specifies frame rate; Default: 100 -- **multistream** - specifies the number of simulated streams; Default: 0 (i.e. - multistream feature is disabled) -- **stream_type** - specifies network layer used for multistream simulation - the valid values are "L4", "L3" and "L2"; Default: 'L4' - **conf_file** - sets path to the vswitchperf configuration file, which will be uploaded to VM; Default: '~/vsperf-yardstick.conf' - **setup_script** - sets path to the setup script, which will be executed @@ -208,8 +194,10 @@ argument. Following options are supported: - **test_params** - specifies a string with a list of vsperf configuration parameters, which will be passed to the ``--test-params`` CLI argument; Parameters should be stated in the form of ``param=value`` and separated - by a semicolon. Please check VSPERF documentation for details about - available configuration parameters and their data types. + by a semicolon. Configuration of traffic generator is driven by ``TRAFFIC`` + dictionary, which can be also updated by values defined by ``test_params``. + Please check VSPERF documentation for details about available configuration + parameters and their data types. In case that both **test_params** and **conf_file** are specified, then values from **test_params** will override values defined in the configuration file. @@ -220,7 +208,7 @@ expected, that OVS runs at the same node, where the testcase is executed. In cas of more complex OpenStack installation or a need of additional OVS configuration, **setup_script** can be used. -Note: It is essential to specify a configuration for selected traffic generator. +**NOTE** It is essential to specify a configuration for selected traffic generator. In case, that standalone testcase is created, then traffic generator can be selected and configured directly in YAML file by **test_params**. On the other hand, if multiple testcases should be executed with the same traffic generator @@ -259,3 +247,8 @@ In case that any of defined metrics will be lower than defined value, then testcase will be marked as failed. Based on ``action`` policy, yardstick will either stop test execution (value ``assert``) or it will run next test (value ``monitor``). + +**NOTE** The throughput SLA (or any other SLA) cannot be set to a meaningful +value without knowledge of the server and networking environment, possibly +including prior testing in that environment to establish a baseline SLA level +under well-understood circumstances. diff --git a/testcases/testcase.py b/testcases/testcase.py index 55c940a4..425581b7 100644 --- a/testcases/testcase.py +++ b/testcases/testcase.py @@ -25,7 +25,7 @@ import time import subprocess from conf import settings as S -from conf import get_test_param +from conf import get_test_param, merge_spec import core.component_factory as component_factory from core.loader import Loader from core.results.results_constants import ResultsConstants @@ -35,7 +35,6 @@ from tools import functions from tools import namespace from tools import veth from tools.teststepstools import TestStepsTools -from tools.pkt_gen.trafficgen.trafficgenhelper import TRAFFIC_DEFAULTS CHECK_PREFIX = 'validate_' @@ -81,7 +80,7 @@ class TestCase(object): self._update_settings('TRAFFICGEN', cfg.get('Trafficgen', S.getValue('TRAFFICGEN'))) test_params = copy.deepcopy(S.getValue('TEST_PARAMS')) tc_test_params = cfg.get('Parameters', S.getValue('TEST_PARAMS')) - test_params.update(tc_test_params) + test_params = merge_spec(test_params, tc_test_params) self._update_settings('TEST_PARAMS', test_params) S.check_test_params() @@ -101,19 +100,12 @@ class TestCase(object): self.desc = cfg.get('Description', 'No description given.') self.test = cfg.get('TestSteps', None) - bidirectional = cfg.get('biDirectional', TRAFFIC_DEFAULTS['bidir']) - bidirectional = get_test_param('bidirectional', bidirectional) - if not isinstance(bidirectional, str): + bidirectional = S.getValue('TRAFFIC')['bidir'] + if not isinstance(S.getValue('TRAFFIC')['bidir'], str): raise TypeError( - 'Bi-dir value must be of type string in testcase configuration') + 'Bi-dir value must be of type string') bidirectional = bidirectional.title() # Keep things consistent - traffic_type = cfg.get('Traffic Type', TRAFFIC_DEFAULTS['traffic_type']) - traffic_type = get_test_param('traffic_type', traffic_type) - - framerate = cfg.get('iLoad', TRAFFIC_DEFAULTS['frame_rate']) - framerate = get_test_param('iload', framerate) - self.deployment = cfg['Deployment'] self._frame_mod = cfg.get('Frame Modification', None) @@ -125,18 +117,9 @@ class TestCase(object): if 'Tunnel Type' in cfg: self._tunnel_type = cfg['Tunnel Type'] - self._tunnel_type = get_test_param('tunnel_type', + self._tunnel_type = get_test_param('TUNNEL_TYPE', self._tunnel_type) - # read configuration of streams; CLI parameter takes precedence to - # testcase definition - multistream = cfg.get('MultiStream', TRAFFIC_DEFAULTS['multistream']) - multistream = get_test_param('multistream', multistream) - stream_type = cfg.get('Stream Type', TRAFFIC_DEFAULTS['stream_type']) - stream_type = get_test_param('stream_type', stream_type) - pre_installed_flows = cfg.get('Pre-installed Flows', TRAFFIC_DEFAULTS['pre_installed_flows']) - pre_installed_flows = get_test_param('pre-installed_flows', pre_installed_flows) - # check if test requires background load and which generator it uses self._load_cfg = cfg.get('Load', None) if self._load_cfg and 'tool' in self._load_cfg: @@ -150,15 +133,9 @@ class TestCase(object): self._results_dir = S.getValue('RESULTS_PATH') # set traffic details, so they can be passed to vswitch and traffic ctls - self._traffic = copy.deepcopy(TRAFFIC_DEFAULTS) - self._traffic.update({'traffic_type': traffic_type, - 'flow_type': cfg.get('Flow Type', TRAFFIC_DEFAULTS['flow_type']), - 'bidir': bidirectional, - 'tunnel_type': self._tunnel_type, - 'multistream': int(multistream), - 'stream_type': stream_type, - 'pre_installed_flows' : pre_installed_flows, - 'frame_rate': int(framerate)}) + self._traffic = copy.deepcopy(S.getValue('TRAFFIC')) + self._traffic.update({'bidir': bidirectional, + 'tunnel_type': self._tunnel_type,}) # Packet Forwarding mode self._vswitch_none = 'none' == S.getValue('VSWITCH').strip().lower() diff --git a/tools/pkt_gen/dummy/dummy.py b/tools/pkt_gen/dummy/dummy.py index 528b5902..7a4daab6 100755 --- a/tools/pkt_gen/dummy/dummy.py +++ b/tools/pkt_gen/dummy/dummy.py @@ -26,6 +26,7 @@ own. import json from conf import settings +from conf import merge_spec from tools.pkt_gen import trafficgen from core.results.results_constants import ResultsConstants @@ -116,7 +117,7 @@ class Dummy(trafficgen.ITrafficGenerator): result = {} if traffic: - traffic_ = trafficgen.merge_spec(traffic_, traffic) + traffic_ = merge_spec(traffic_, traffic) results = get_user_traffic( 'burst', @@ -135,7 +136,7 @@ class Dummy(trafficgen.ITrafficGenerator): result[ResultsConstants.PAYLOAD_ERR] = results[1] result[ResultsConstants.SEQ_ERR] = results[2] - return trafficgen.BurstResult(*results) + return results def send_cont_traffic(self, traffic=None, duration=30): """ @@ -145,7 +146,7 @@ class Dummy(trafficgen.ITrafficGenerator): result = {} if traffic: - traffic_ = trafficgen.merge_spec(traffic_, traffic) + traffic_ = merge_spec(traffic_, traffic) results = get_user_traffic( 'continuous', @@ -182,7 +183,7 @@ class Dummy(trafficgen.ITrafficGenerator): result = {} if traffic: - traffic_ = trafficgen.merge_spec(traffic_, traffic) + traffic_ = merge_spec(traffic_, traffic) results = get_user_traffic( 'throughput', @@ -219,7 +220,7 @@ class Dummy(trafficgen.ITrafficGenerator): result = {} if traffic: - traffic_ = trafficgen.merge_spec(traffic_, traffic) + traffic_ = merge_spec(traffic_, traffic) results = get_user_traffic( 'back2back', diff --git a/tools/pkt_gen/ixia/ixia.py b/tools/pkt_gen/ixia/ixia.py index 5c5fb3df..ed947e70 100755 --- a/tools/pkt_gen/ixia/ixia.py +++ b/tools/pkt_gen/ixia/ixia.py @@ -42,6 +42,7 @@ from collections import OrderedDict from tools import systeminfo from tools.pkt_gen import trafficgen from conf import settings +from conf import merge_spec from core.results.results_constants import ResultsConstants _ROOT_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -203,7 +204,7 @@ class Ixia(trafficgen.ITrafficGenerator): params['traffic'] = self.traffic_defaults.copy() if traffic: - params['traffic'] = trafficgen.merge_spec( + params['traffic'] = merge_spec( params['traffic'], traffic) for cmd in _build_set_cmds(params): @@ -268,7 +269,7 @@ class Ixia(trafficgen.ITrafficGenerator): params['traffic'] = self.traffic_defaults.copy() if traffic: - params['traffic'] = trafficgen.merge_spec( + params['traffic'] = merge_spec( params['traffic'], traffic) for cmd in _build_set_cmds(params): diff --git a/tools/pkt_gen/ixnet/ixnet.py b/tools/pkt_gen/ixnet/ixnet.py index 6262a10a..f84ab668 100755 --- a/tools/pkt_gen/ixnet/ixnet.py +++ b/tools/pkt_gen/ixnet/ixnet.py @@ -88,6 +88,7 @@ import csv from collections import OrderedDict from tools.pkt_gen import trafficgen from conf import settings +from conf import merge_spec from core.results.results_constants import ResultsConstants _ROOT_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -155,6 +156,7 @@ class IxNet(trafficgen.ITrafficGenerator): def __init__(self): """Initialize IXNET members """ + super().__init__() self._script = os.path.join(settings.getValue('TRAFFICGEN_IXIA_3RD_PARTY'), settings.getValue('TRAFFICGEN_IXNET_TCL_SCRIPT')) self._tclsh = tkinter.Tcl() @@ -227,7 +229,7 @@ class IxNet(trafficgen.ITrafficGenerator): self._params['traffic'] = self.traffic_defaults.copy() if traffic: - self._params['traffic'] = trafficgen.merge_spec( + self._params['traffic'] = merge_spec( self._params['traffic'], traffic) self._cfg['bidir'] = self._bidir @@ -281,7 +283,7 @@ class IxNet(trafficgen.ITrafficGenerator): self._params['traffic'] = self.traffic_defaults.copy() if traffic: - self._params['traffic'] = trafficgen.merge_spec( + self._params['traffic'] = merge_spec( self._params['traffic'], traffic) self._cfg['bidir'] = self._bidir @@ -418,7 +420,7 @@ class IxNet(trafficgen.ITrafficGenerator): self._params['traffic'] = self.traffic_defaults.copy() if traffic: - self._params['traffic'] = trafficgen.merge_spec( + self._params['traffic'] = merge_spec( self._params['traffic'], traffic) self._cfg['bidir'] = self._bidir diff --git a/tools/pkt_gen/moongen/moongen.py b/tools/pkt_gen/moongen/moongen.py index 7fd67661..9d604db2 100644 --- a/tools/pkt_gen/moongen/moongen.py +++ b/tools/pkt_gen/moongen/moongen.py @@ -28,19 +28,17 @@ import subprocess # VSPerf imports from conf import settings +from conf import merge_spec from core.results.results_constants import ResultsConstants -from tools.pkt_gen.trafficgen.trafficgenhelper import ( - TRAFFIC_DEFAULTS, - merge_spec) from tools.pkt_gen.trafficgen.trafficgen import ITrafficGenerator class Moongen(ITrafficGenerator): """Moongen Traffic generator wrapper.""" - _traffic_defaults = TRAFFIC_DEFAULTS.copy() _logger = logging.getLogger(__name__) def __init__(self): """Moongen class constructor.""" + super().__init__() self._logger.info("In moongen __init__ method") self._params = {} self._moongen_host_ip_addr = ( @@ -57,18 +55,6 @@ class Moongen(ITrafficGenerator): 'MOONGEN: Invalid line speed in configuration ' + \ 'file (today 10Gbps supported)') - @property - def traffic_defaults(self): - """Default traffic values. - - These can be expected to be constant across traffic generators, - so no setter is provided. Changes to the structure or contents - will likely break traffic generator implementations or tests - respectively. - """ - self._logger.info("In Moongen traffic_defaults method") - return self._traffic_defaults - def create_moongen_cfg_file(self, traffic, duration=60, acceptable_loss_pct=1, one_shot=0): """Create the Moongen configuration file from VSPERF's traffic profile diff --git a/tools/pkt_gen/trafficgen/__init__.py b/tools/pkt_gen/trafficgen/__init__.py index 2a3b9bd3..34d8ebe1 100755 --- a/tools/pkt_gen/trafficgen/__init__.py +++ b/tools/pkt_gen/trafficgen/__init__.py @@ -16,4 +16,3 @@ """ from tools.pkt_gen.trafficgen.trafficgen import * -from tools.pkt_gen.trafficgen.trafficgenhelper import * diff --git a/tools/pkt_gen/trafficgen/trafficgen.py b/tools/pkt_gen/trafficgen/trafficgen.py index fb40cd92..262df71d 100755 --- a/tools/pkt_gen/trafficgen/trafficgen.py +++ b/tools/pkt_gen/trafficgen/trafficgen.py @@ -15,16 +15,18 @@ This is an abstract class for traffic generators. """ +import copy +from conf import settings -#TODO update Back2Back method description when Result implementation will -#be ready. - -from tools.pkt_gen.trafficgen.trafficgenhelper import TRAFFIC_DEFAULTS +CMD_PREFIX = 'gencmd : ' class ITrafficGenerator(object): """Model of a traffic generator device. """ - _traffic_defaults = TRAFFIC_DEFAULTS.copy() + def __init__(self): + """Initialization of interface + """ + self._default_traffic = copy.deepcopy(settings.getValue('TRAFFIC')) @property def traffic_defaults(self): @@ -35,7 +37,7 @@ class ITrafficGenerator(object): will likely break traffic generator implementations or tests respectively. """ - return self._traffic_defaults + return self._default_traffic def __enter__(self): """Connect to the traffic generator. diff --git a/tools/pkt_gen/trafficgen/trafficgenhelper.py b/tools/pkt_gen/trafficgen/trafficgenhelper.py deleted file mode 100644 index 47f8b262..00000000 --- a/tools/pkt_gen/trafficgen/trafficgenhelper.py +++ /dev/null @@ -1,94 +0,0 @@ -# Copyright 2015-2016 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. -"""Helper methods collection. - -Collection of helper methods used by traffic generators -implementation. -""" - -from collections import namedtuple - -CMD_PREFIX = 'gencmd : ' -TRAFFIC_DEFAULTS = { - 'traffic_type' : 'rfc2544_throughput', - 'frame_rate' : 100, - 'bidir' : 'False', # will be passed as string in title format to tgen - 'multistream' : 0, - 'stream_type' : 'L4', - 'pre_installed_flows' : 'No', # used by vswitch implementation - 'flow_type' : 'port', # used by vswitch implementation - - 'l2': { - 'framesize': 64, - 'srcmac': '00:00:00:00:00:00', - 'dstmac': '00:00:00:00:00:00', - }, - 'l3': { - 'proto': 'udp', - 'srcip': '1.1.1.1', - 'dstip': '90.90.90.90', - }, - 'l4': { - 'srcport': 3000, - 'dstport': 3001, - }, - 'vlan': { - 'enabled': False, - 'id': 0, - 'priority': 0, - 'cfi': 0, - }, -} - -#TODO remove namedtuples and implement results through IResult interface found -#in core/results - -BurstResult = namedtuple( - 'BurstResult', - 'frames_tx frames_rx bytes_tx bytes_rx payload_err seq_err') -Back2BackResult = namedtuple( - 'Back2BackResult', - 'rx_fps rx_mbps tx_percent rx_percent tx_count b2b_frames ' - 'frame_loss_frames frame_loss_percent') - - -def merge_spec(orig, new): - """Merges ``new`` dict with ``orig`` dict, and return orig. - - This takes into account nested dictionaries. Example: - - >>> old = {'foo': 1, 'bar': {'foo': 2, 'bar': 3}} - >>> new = {'foo': 6, 'bar': {'foo': 7}} - >>> merge_spec(old, new) - {'foo': 6, 'bar': {'foo': 7, 'bar': 3}} - - You'll notice that ``bar.bar`` is not removed. This is the desired result. - """ - for key in orig: - if key not in new: - continue - - # Not allowing derived dictionary types for now - # pylint: disable=unidiomatic-typecheck - if type(orig[key]) == dict: - orig[key] = merge_spec(orig[key], new[key]) - else: - orig[key] = new[key] - - for key in new: - if key not in orig: - orig[key] = new[key] - - return orig - diff --git a/tools/pkt_gen/xena/xena.py b/tools/pkt_gen/xena/xena.py index 798bb832..20577e8d 100755 --- a/tools/pkt_gen/xena/xena.py +++ b/tools/pkt_gen/xena/xena.py @@ -36,10 +36,8 @@ import scapy.layers.inet as inet # VSPerf imports from conf import settings +from conf import merge_spec from core.results.results_constants import ResultsConstants -from tools.pkt_gen.trafficgen.trafficgenhelper import ( - TRAFFIC_DEFAULTS, - merge_spec) from tools.pkt_gen.trafficgen.trafficgen import ITrafficGenerator # Xena module imports @@ -56,10 +54,10 @@ class Xena(ITrafficGenerator): """ Xena Traffic generator wrapper class """ - _traffic_defaults = TRAFFIC_DEFAULTS.copy() _logger = logging.getLogger(__name__) def __init__(self): + super().__init__() self.mono_pipe = None self.xmanager = None self._params = {} @@ -71,7 +69,7 @@ class Xena(ITrafficGenerator): user_home = os.path.expanduser('~') self._log_path = '{}/Xena/Xena2544-2G/Logs/xena2544.log'.format( - user_home) + user_home) # make the folder and log file if they doesn't exist if not os.path.exists(self._log_path): @@ -80,18 +78,6 @@ class Xena(ITrafficGenerator): # empty the file contents open(self._log_path, 'w').close() - - @property - def traffic_defaults(self): - """Default traffic values. - - These can be expected to be constant across traffic generators, - so no setter is provided. Changes to the structure or contents - will likely break traffic generator implementations or tests - respectively. - """ - return self._traffic_defaults - @staticmethod def _create_throughput_result(root): """ @@ -703,4 +689,3 @@ class Xena(ITrafficGenerator): if __name__ == "__main__": pass - diff --git a/vsperf b/vsperf index 44e45425..cf639a30 100755 --- a/vsperf +++ b/vsperf @@ -26,16 +26,14 @@ import time import datetime import shutil import unittest -import xmlrunner import locale import copy import glob import subprocess - -sys.dont_write_bytecode = True - +import ast +import xmlrunner from conf import settings -from conf import get_test_param +import core.component_factory as component_factory from core.loader import Loader from testcases import PerformanceTestCase from testcases import IntegrationTestCase @@ -44,8 +42,8 @@ from tools import networkcard from tools import functions from tools.pkt_gen import trafficgen from tools.opnfvdashboard import opnfvdashboard -from tools.pkt_gen.trafficgen.trafficgenhelper import TRAFFIC_DEFAULTS -import core.component_factory as component_factory + +sys.dont_write_bytecode = True VERBOSITY_LEVELS = { 'debug': logging.DEBUG, @@ -86,7 +84,14 @@ def parse_arguments(): value = value.strip() if len(param): if len(value): - results[param] = value + # values are passed inside string from CLI, so we must retype them accordingly + try: + results[param] = ast.literal_eval(value) + except ValueError: + # for backward compatibility, we have to accept strings without quotes + _LOGGER.warning("Adding missing quotes around string value: %s = %s", + param, str(value)) + results[param] = str(value) else: results[param] = True @@ -345,8 +350,7 @@ def enable_sriov(nic_list): or networkcard.get_sriov_numvfs(nic) <= sriov_nic[nic]: # if not, enable and set appropriate number of VFs if not networkcard.set_sriov_numvfs(nic, sriov_nic[nic] + 1): - _LOGGER.error("SRIOV cannot be enabled for NIC %s", nic) - raise + raise RuntimeError('SRIOV cannot be enabled for NIC {}'.format(nic)) else: _LOGGER.debug("SRIOV enabled for NIC %s", nic) @@ -375,8 +379,7 @@ def disable_sriov(nic_list): for nic in nic_list: if networkcard.is_sriov_nic(nic): if not networkcard.set_sriov_numvfs(nic.split('|')[0], 0): - _LOGGER.error("SRIOV cannot be disabled for NIC %s", nic) - raise + raise RuntimeError('SRIOV cannot be disabled for NIC {}'.format(nic)) else: _LOGGER.debug("SRIOV disabled for NIC %s", nic.split('|')[0]) @@ -579,9 +582,8 @@ def main(): 'driver' : networkcard.get_driver(tmp_nic), 'device' : networkcard.get_device_name(tmp_nic)}) else: - _LOGGER.error("Invalid network card PCI ID: '%s'", nic) vsperf_finalize() - raise + raise RuntimeError("Invalid network card PCI ID: '{}'".format(nic)) settings.setValue('NICS', nic_list) # for backward compatibility @@ -603,12 +605,7 @@ def main(): _LOGGER.debug("Executing traffic generator:") loader = Loader() # set traffic details, so they can be passed to traffic ctl - traffic = copy.deepcopy(TRAFFIC_DEFAULTS) - traffic.update({'traffic_type': get_test_param('traffic_type', TRAFFIC_DEFAULTS['traffic_type']), - 'bidir': get_test_param('bidirectional', TRAFFIC_DEFAULTS['bidir']), - 'multistream': int(get_test_param('multistream', TRAFFIC_DEFAULTS['multistream'])), - 'stream_type': get_test_param('stream_type', TRAFFIC_DEFAULTS['stream_type']), - 'frame_rate': int(get_test_param('iload', TRAFFIC_DEFAULTS['frame_rate']))}) + traffic = copy.deepcopy(settings.getValue('TRAFFIC')) traffic_ctl = component_factory.create_traffic( traffic['traffic_type'], @@ -689,4 +686,3 @@ def main(): if __name__ == "__main__": main() - diff --git a/yardstick/tests/p2p_rfc2544_throughput_sample.yaml b/yardstick/tests/p2p_rfc2544_throughput_sample.yaml index 91aa5d00..32b42187 100644 --- a/yardstick/tests/p2p_rfc2544_throughput_sample.yaml +++ b/yardstick/tests/p2p_rfc2544_throughput_sample.yaml @@ -28,11 +28,8 @@ scenarios: type: Vsperf options: testname: 'p2p_rfc2544_throughput' - traffic_type: 'rfc2544_throughput' frame_size: '64' - bidirectional: 'True' - iload: 100 - test_params: 'TRAFFICGEN_DURATION=30;' + test_params: 'TRAFFICGEN_DURATION=30;TRAFFIC={"traffic_type":"rfc2544_throughput"}' trafficgen_port1: 'eth1' trafficgen_port2: 'eth3' external_bridge: 'br-ex' diff --git a/yardstick/tests/rfc2544_back2back_dummy.yaml b/yardstick/tests/rfc2544_back2back_dummy.yaml index 9fe834c5..a45c4f61 100644 --- a/yardstick/tests/rfc2544_back2back_dummy.yaml +++ b/yardstick/tests/rfc2544_back2back_dummy.yaml @@ -30,14 +30,15 @@ scenarios: type: Vsperf options: testname: 'rfc2544_back2back' - traffic_type: 'rfc2544_back2back' frame_size: '64' - bidirectional: 'True' - iload: 100 test_params: 'TRAFFICGEN="Dummy"; + TRAFFIC={ + "traffic_type":"rfc2544_back2back" + }; TRAFFICGEN_DUMMY_RESULTS={ "b2b frames":"10000", - "b2b frame loss %":"0.0"}' + "b2b frame loss %":"0.0", + }' host: vsperf.demo diff --git a/yardstick/tests/rfc2544_continuous_dummy.yaml b/yardstick/tests/rfc2544_continuous_dummy.yaml index 9d189c80..2d02fce2 100644 --- a/yardstick/tests/rfc2544_continuous_dummy.yaml +++ b/yardstick/tests/rfc2544_continuous_dummy.yaml @@ -30,12 +30,12 @@ scenarios: type: Vsperf options: testname: 'rfc2544_continuous' - traffic_type: 'rfc2544_continuous' frame_size: '64' - bidirectional: 'True' - iload: 100 test_params: 'TRAFFICGEN_DURATION=30; TRAFFICGEN="Dummy"; + TRAFFIC={ + "traffic_type":"rfc2544_continuous" + }; TRAFFICGEN_DUMMY_RESULTS={ "frames tx":15000000, "frames rx":15000000, diff --git a/yardstick/tests/rfc2544_throughput_dummy.yaml b/yardstick/tests/rfc2544_throughput_dummy.yaml index 9ebf28c4..1abbea63 100644 --- a/yardstick/tests/rfc2544_throughput_dummy.yaml +++ b/yardstick/tests/rfc2544_throughput_dummy.yaml @@ -30,12 +30,12 @@ scenarios: type: Vsperf options: testname: 'rfc2544_throughput' - traffic_type: 'rfc2544_throughput' frame_size: '64' - bidirectional: 'True' - iload: 100 test_params: 'TRAFFICGEN_DURATION=30; TRAFFICGEN="Dummy"; + TRAFFIC={ + "traffic_type":"rfc2544_throughput" + }; TRAFFICGEN_DUMMY_RESULTS={ "frames tx":15000000, "frames rx":15000000, -- cgit 1.2.3-korg