aboutsummaryrefslogtreecommitdiffstats
path: root/resources/libraries/python
diff options
context:
space:
mode:
Diffstat (limited to 'resources/libraries/python')
-rw-r--r--resources/libraries/python/Constants.py61
-rw-r--r--resources/libraries/python/InterfaceUtil.py10
-rw-r--r--resources/libraries/python/TrafficGenerator.py72
-rw-r--r--resources/libraries/python/autogen/DefaultTestcase.py2
-rw-r--r--resources/libraries/python/autogen/Regenerator.py152
-rw-r--r--resources/libraries/python/autogen/Testcase.py10
6 files changed, 232 insertions, 75 deletions
diff --git a/resources/libraries/python/Constants.py b/resources/libraries/python/Constants.py
index 506b71af69..9822f1c3a0 100644
--- a/resources/libraries/python/Constants.py
+++ b/resources/libraries/python/Constants.py
@@ -84,3 +84,64 @@ class Constants(object):
# Core dump directory
CORE_DUMP_DIR = '/tmp'
+
+ # Mapping from NIC name to its bps limit.
+ # TODO: Implement logic to lower limits to TG NIC or software. Or PCI.
+ NIC_NAME_TO_LIMIT = {
+ # TODO: Explain why ~40Gbps NICs are using ~25Gbps limit.
+ "Cisco-VIC-1227": 10000000000,
+ "Cisco-VIC-1385": 24500000000,
+ "Intel-X520-DA2": 10000000000,
+ "Intel-X553": 10000000000,
+ "Intel-X710": 10000000000,
+ "Intel-XL710": 24500000000,
+ "Intel-XXV710": 24500000000,
+ }
+
+ # Suite file names use somewhat more rich (less readable) codes for NICs.
+ NIC_NAME_TO_CODE = {
+ "Cisco-VIC-1227": "10ge2p1vic1227",
+ "Cisco-VIC-1385": "40ge2p1vic1385",
+ "Intel-X520-DA2": "10ge2p1x520",
+ "Intel-X553": "10ge2p1x553",
+ "Intel-X710": "10ge2p1x710",
+ "Intel-XL710": "40ge2p1xl710",
+ "Intel-XXV710": "25ge2p1xxv710",
+ }
+
+ # TODO CSIT-1481: Crypto HW should be read from topology file instead.
+ NIC_NAME_TO_CRYPTO_HW = {
+ "Intel-X553": "HW_C3xxx",
+ "Intel-X710": "HW_DH895xcc",
+ "Intel-XL710": "HW_DH895xcc",
+ }
+
+ PERF_TYPE_TO_KEYWORD = {
+ "mrr": "Traffic should pass with maximum rate",
+ "ndrpdr": "Find NDR and PDR intervals using optimized search",
+ "soak": "Find critical load using PLRsearch",
+ }
+
+ PERF_TYPE_TO_SUITE_DOC_VER = {
+ "mrr" : '''fication:* In MaxReceivedRate tests TG sends traffic\\
+| ... | at line rate and reports total received packets over trial period.\\''',
+ # TODO: Figure out how to include the full "*[Ver] TG verification:*"
+ # while keeping this readable and without breaking line length limit.
+ "ndrpdr": '''fication:* TG finds and reports throughput NDR (Non Drop\\
+| ... | Rate) with zero packet loss tolerance and throughput PDR (Partial Drop\\
+| ... | Rate) with non-zero packet loss tolerance (LT) expressed in percentage\\
+| ... | of packets transmitted. NDR and PDR are discovered for different\\
+| ... | Ethernet L2 frame sizes using MLRsearch library.\\''',
+ "soak": '''fication:* TG sends traffic at dynamically computed\\
+| ... | rate as PLRsearch algorithm gathers data and improves its estimate\\
+| ... | of a rate at which a prescribed small fraction of packets\\
+| ... | would be lost. After set time, the serarch stops\\
+| ... | and the algorithm reports its current estimate.\\''',
+ }
+
+ PERF_TYPE_TO_TEMPLATE_DOC_VER = {
+ "mrr": '''Measure MaxReceivedRate for ${frame_size}B frames\\
+| | ... | using burst trials throughput test.\\''',
+ "ndrpdr": '''Measure NDR and PDR values using MLRsearch algorithm.\\''',
+ "soak": '''Estimate critical rate using PLRsearch algorithm.\\''',
+ }
diff --git a/resources/libraries/python/InterfaceUtil.py b/resources/libraries/python/InterfaceUtil.py
index a1a9b739e0..df45e39560 100644
--- a/resources/libraries/python/InterfaceUtil.py
+++ b/resources/libraries/python/InterfaceUtil.py
@@ -1325,18 +1325,20 @@ class InterfaceUtil(object):
exec_cmd_no_error(node, cmd, sudo=True)
@staticmethod
- def init_avf_interface(node, ifc_key, numvfs=1, topology_type='L2'):
+ def init_avf_interface(node, ifc_key, numvfs=1, traffic_type='L2'):
"""Init PCI device by creating VFs and bind them to vfio-pci for AVF
driver testing on DUT.
:param node: DUT node.
:param ifc_key: Interface key from topology file.
:param numvfs: Number of VFs to initialize, 0 - disable the VFs.
- :param topology_type: Topology type.
+ :param traffic_type: Expected type of traffic, affects spoofing.
+ Default value "L2" sets linux interface spoof off.
+ Other values do not do that.
:type node: dict
:type ifc_key: str
:type numvfs: int
- :type topology_type: str
+ :type traffic_type: str
:returns: Virtual Function topology interface keys.
:rtype: list
"""
@@ -1375,7 +1377,7 @@ class InterfaceUtil(object):
format(pci=pf_pci_addr)
InterfaceUtil.set_linux_interface_trust_on(node, pf_dev,
vf_id=vf_id)
- if topology_type == 'L2':
+ if traffic_type == 'L2':
InterfaceUtil.set_linux_interface_spoof_off(node, pf_dev,
vf_id=vf_id)
InterfaceUtil.set_linux_interface_mac(node, pf_dev, vf_mac_addr,
diff --git a/resources/libraries/python/TrafficGenerator.py b/resources/libraries/python/TrafficGenerator.py
index ea587d7558..5f92888fe8 100644
--- a/resources/libraries/python/TrafficGenerator.py
+++ b/resources/libraries/python/TrafficGenerator.py
@@ -37,21 +37,21 @@ class TGDropRateSearchImpl(DropRateSearch):
super(TGDropRateSearchImpl, self).__init__()
def measure_loss(self, rate, frame_size, loss_acceptance,
- loss_acceptance_type, traffic_type, skip_warmup=False):
+ loss_acceptance_type, traffic_profile, skip_warmup=False):
"""Runs the traffic and evaluate the measured results.
:param rate: Offered traffic load.
:param frame_size: Size of frame.
:param loss_acceptance: Permitted drop ratio or frames count.
:param loss_acceptance_type: Type of permitted loss.
- :param traffic_type: Module name as a traffic type identifier.
+ :param traffic_profile: Module name as a traffic profile identifier.
See resources/traffic_profiles/trex for implemented modules.
:param skip_warmup: Start TRex without warmup traffic if true.
:type rate: float
:type frame_size: str
:type loss_acceptance: float
:type loss_acceptance_type: LossAcceptanceType
- :type traffic_type: str
+ :type traffic_profile: str
:type skip_warmup: bool
:returns: Drop threshold exceeded? (True/False)
:rtype: bool
@@ -70,12 +70,12 @@ class TGDropRateSearchImpl(DropRateSearch):
if skip_warmup:
tg_instance.trex_stl_start_remote_exec(self.get_duration(),
unit_rate, frame_size,
- traffic_type,
+ traffic_profile,
warmup_time=0.0)
else:
tg_instance.trex_stl_start_remote_exec(self.get_duration(),
unit_rate, frame_size,
- traffic_type)
+ traffic_profile)
loss = tg_instance.get_loss()
sent = tg_instance.get_sent()
if self.loss_acceptance_type_is_percentage():
@@ -124,7 +124,7 @@ class TrafficGenerator(AbstractMeasurer):
self._ifaces_reordered = False
# Parameters not given by measure().
self.frame_size = None
- self.traffic_type = None
+ self.traffic_profile = None
self.warmup_time = None
@property
@@ -388,15 +388,15 @@ class TrafficGenerator(AbstractMeasurer):
raise RuntimeError('TRex stateless runtime error')
def trex_stl_start_remote_exec(
- self, duration, rate, framesize, traffic_type, async_call=False,
+ self, duration, rate, frame_size, traffic_profile, async_call=False,
latency=True, warmup_time=5.0, unidirection=False, tx_port=0,
rx_port=1):
"""Execute script on remote node over ssh to start traffic.
:param duration: Time expresed in seconds for how long to send traffic.
:param rate: Traffic rate expressed with units (pps, %)
- :param framesize: L2 frame size to send (without padding and IPG).
- :param traffic_type: Module name as a traffic type identifier.
+ :param frame_size: L2 frame size to send (without padding and IPG).
+ :param traffic_profile: Module name as a traffic profile identifier.
See resources/traffic_profiles/trex for implemented modules.
:param async_call: If enabled then don't wait for all incomming trafic.
:param latency: With latency measurement.
@@ -408,8 +408,8 @@ class TrafficGenerator(AbstractMeasurer):
Default: 1
:type duration: float
:type rate: str
- :type framesize: str
- :type traffic_type: str
+ :type frame_size: str
+ :type traffic_profile: str
:type async_call: bool
:type latency: bool
:type warmup_time: float
@@ -425,11 +425,12 @@ class TrafficGenerator(AbstractMeasurer):
command = (
"sh -c '{tool}/resources/tools/trex/trex_stateless_profile.py"
" --profile {prof}/resources/traffic_profiles/trex/{traffic}.py"
- " --duration {duration} --frame_size {framesize} --rate {rate}"
+ " --duration {duration} --frame_size {frame_size} --rate {rate}"
" --warmup_time {warmup} --port_0 {p_0} --port_1 {p_1}").format(
tool=Constants.REMOTE_FW_DIR, prof=Constants.REMOTE_FW_DIR,
- traffic=traffic_type, duration=duration, framesize=framesize,
- rate=rate, warmup=warmup_time, p_0=p_0, p_1=p_1)
+ traffic=traffic_profile, duration=duration,
+ frame_size=frame_size, rate=rate, warmup=warmup_time, p_0=p_0,
+ p_1=p_1)
if async_call:
command += " --async"
if latency:
@@ -473,7 +474,7 @@ class TrafficGenerator(AbstractMeasurer):
self.trex_stl_stop_remote_exec(self._node)
def send_traffic_on_tg(
- self, duration, rate, framesize, traffic_type, warmup_time=5,
+ self, duration, rate, frame_size, traffic_profile, warmup_time=5,
async_call=False, latency=True, unidirection=False, tx_port=0,
rx_port=1):
"""Send traffic from all configured interfaces on TG.
@@ -489,12 +490,13 @@ class TrafficGenerator(AbstractMeasurer):
TODO: Is it better to have less descriptive argument names
just to make them less probable to be viewed as misleading or confusing?
- See https://gerrit.fd.io/r/#/c/17625/11/resources/libraries/python/TrafficGenerator.py@406
+ See https://gerrit.fd.io/r/#/c/17625/11/resources/libraries/python\
+ /TrafficGenerator.py@406
:param duration: Duration of test traffic generation in seconds.
:param rate: Offered load per interface (e.g. 1%, 3gbps, 4mpps, ...).
- :param framesize: Frame size (L2) in Bytes.
- :param traffic_type: Module name as a traffic type identifier.
+ :param frame_size: Frame size (L2) in Bytes.
+ :param traffic_profile: Module name as a traffic profile identifier.
See resources/traffic_profiles/trex for implemented modules.
:param warmup_time: Warmup phase in seconds.
:param async_call: Async mode.
@@ -506,8 +508,8 @@ class TrafficGenerator(AbstractMeasurer):
Default: 1
:type duration: str
:type rate: str
- :type framesize: str
- :type traffic_type: str
+ :type frame_size: str
+ :type traffic_profile: str
:type warmup_time: float
:type async_call: bool
:type latency: bool
@@ -532,8 +534,8 @@ class TrafficGenerator(AbstractMeasurer):
raise RuntimeError('TG subtype not defined')
elif node['subtype'] == NodeSubTypeTG.TREX:
self.trex_stl_start_remote_exec(
- duration, rate, framesize, traffic_type, async_call, latency,
- warmup_time, unidirection, tx_port, rx_port)
+ duration, rate, frame_size, traffic_profile, async_call,
+ latency, warmup_time, unidirection, tx_port, rx_port)
else:
raise NotImplementedError("TG subtype not supported")
@@ -586,20 +588,20 @@ class TrafficGenerator(AbstractMeasurer):
raise Exception("Traffic loss {} above loss acceptance: {}".format(
loss, loss_acceptance))
- def set_rate_provider_defaults(self, frame_size, traffic_type,
+ def set_rate_provider_defaults(self, frame_size, traffic_profile,
warmup_time=0.0):
"""Store values accessed by measure().
:param frame_size: Frame size identifier or value [B].
- :param traffic_type: Module name as a traffic type identifier.
+ :param traffic_profile: Module name as a traffic profile identifier.
See resources/traffic_profiles/trex for implemented modules.
:param warmup_time: Traffic duration before measurement starts [s].
:type frame_size: str or int
- :type traffic_type: str
+ :type traffic_profile: str
:type warmup_time: float
"""
self.frame_size = frame_size
- self.traffic_type = str(traffic_type)
+ self.traffic_profile = str(traffic_profile)
self.warmup_time = float(warmup_time)
def measure(self, duration, transmit_rate):
@@ -620,7 +622,7 @@ class TrafficGenerator(AbstractMeasurer):
# Trex needs target Tr per stream, but reports aggregate Tx and Dx.
unit_rate = str(transmit_rate / 2.0) + "pps"
self.send_traffic_on_tg(
- duration, unit_rate, self.frame_size, self.traffic_type,
+ duration, unit_rate, self.frame_size, self.traffic_profile,
warmup_time=self.warmup_time, latency=True)
transmit_count = int(self.get_sent())
loss_count = int(self.get_loss())
@@ -635,7 +637,7 @@ class OptimizedSearch(object):
@staticmethod
def perform_optimized_ndrpdr_search(
- frame_size, traffic_type, minimum_transmit_rate,
+ frame_size, traffic_profile, minimum_transmit_rate,
maximum_transmit_rate, packet_loss_ratio=0.005,
final_relative_width=0.005, final_trial_duration=30.0,
initial_trial_duration=1.0, number_of_intermediate_phases=2,
@@ -643,7 +645,7 @@ class OptimizedSearch(object):
"""Setup initialized TG, perform optimized search, return intervals.
:param frame_size: Frame size identifier or value [B].
- :param traffic_type: Module name as a traffic type identifier.
+ :param traffic_profile: Module name as a traffic profile identifier.
See resources/traffic_profiles/trex for implemented modules.
:param minimum_transmit_rate: Minimal bidirectional
target transmit rate [pps].
@@ -663,7 +665,7 @@ class OptimizedSearch(object):
Default 1 is suitable for fairly stable tests,
less stable tests might get better overal duration with 2 or more.
:type frame_size: str or int
- :type traffic_type: str
+ :type traffic_profile: str
:type minimum_transmit_rate: float
:type maximum_transmit_rate: float
:type packet_loss_ratio: float
@@ -682,7 +684,7 @@ class OptimizedSearch(object):
# to be able to use trex_stl-*()
tg_instance = BuiltIn().get_library_instance(
'resources.libraries.python.TrafficGenerator')
- tg_instance.set_rate_provider_defaults(frame_size, traffic_type)
+ tg_instance.set_rate_provider_defaults(frame_size, traffic_profile)
algorithm = MultipleLossRatioSearch(
measurer=tg_instance, final_trial_duration=final_trial_duration,
final_relative_width=final_relative_width,
@@ -695,13 +697,13 @@ class OptimizedSearch(object):
@staticmethod
def perform_soak_search(
- frame_size, traffic_type, minimum_transmit_rate,
+ frame_size, traffic_profile, minimum_transmit_rate,
maximum_transmit_rate, plr_target=1e-7, tdpt=0.2,
initial_count=50, timeout=1800.0):
"""Setup initialized TG, perform soak search, return avg and stdev.
:param frame_size: Frame size identifier or value [B].
- :param traffic_type: Module name as a traffic type identifier.
+ :param traffic_profile: Module name as a traffic profile identifier.
See resources/traffic_profiles/trex for implemented modules.
:param minimum_transmit_rate: Minimal bidirectional
target transmit rate [pps].
@@ -717,7 +719,7 @@ class OptimizedSearch(object):
takes significant time even without any trial results.
:param timeout: The search will stop after this overall time [s].
:type frame_size: str or int
- :type traffic_type: str
+ :type traffic_profile: str
:type minimum_transmit_rate: float
:type maximum_transmit_rate: float
:type plr_target: float
@@ -728,7 +730,7 @@ class OptimizedSearch(object):
"""
tg_instance = BuiltIn().get_library_instance(
'resources.libraries.python.TrafficGenerator')
- tg_instance.set_rate_provider_defaults(frame_size, traffic_type)
+ tg_instance.set_rate_provider_defaults(frame_size, traffic_profile)
algorithm = PLRsearch(
measurer=tg_instance, trial_duration_per_trial=tdpt,
packet_loss_ratio_target=plr_target,
diff --git a/resources/libraries/python/autogen/DefaultTestcase.py b/resources/libraries/python/autogen/DefaultTestcase.py
index 0aaf40d7ca..5db81a80d4 100644
--- a/resources/libraries/python/autogen/DefaultTestcase.py
+++ b/resources/libraries/python/autogen/DefaultTestcase.py
@@ -30,6 +30,6 @@ class DefaultTestcase(Testcase):
template_string = r'''
| ${tc_num}-${frame_str}-${cores_str}c-''' + suite_id + r'''
| | [Tags] | ${frame_str} | ${cores_str}C
-| | framesize=${frame_num} | phy_cores=${cores_num}
+| | frame_size=${frame_num} | phy_cores=${cores_num}
'''
super(DefaultTestcase, self).__init__(template_string)
diff --git a/resources/libraries/python/autogen/Regenerator.py b/resources/libraries/python/autogen/Regenerator.py
index bae0e4f9fe..f47c88b022 100644
--- a/resources/libraries/python/autogen/Regenerator.py
+++ b/resources/libraries/python/autogen/Regenerator.py
@@ -20,6 +20,7 @@ from os import getcwd
import sys
from .DefaultTestcase import DefaultTestcase
+from resources.libraries.python.Constants import Constants
# Copied from https://stackoverflow.com/a/14981125
@@ -63,18 +64,18 @@ class Regenerator(object):
When None, default list is used.
List item is a dict, argument names are keys.
The initialized testcase_class should accept those, and "num".
- DefaultTestcase accepts "framesize" and "phy_cores".
+ DefaultTestcase accepts "frame_size" and "phy_cores".
:type pattern: str
:type is_ip6: boolean
:type tc_kwargs_list: list of tuple or None
"""
- protocol_to_min_framesize = {
+ protocol_to_min_frame_size = {
"ip4": 64,
"ip6": 78,
"vxlan+ip4": 114 # What is the real minimum for latency stream?
}
- min_framesize_values = protocol_to_min_framesize.values()
+ min_frame_size_values = protocol_to_min_frame_size.values()
def get_iface_and_suite_id(filename):
"""Get interface and suite ID.
@@ -110,7 +111,7 @@ class Regenerator(object):
"""
# TODO: Is there a better way to disable some combinations?
emit = True
- if kwargs["framesize"] == 9000:
+ if kwargs["frame_size"] == 9000:
if "vic1227" in iface:
# Not supported in HW.
emit = False
@@ -127,7 +128,7 @@ class Regenerator(object):
# Soak test take too long, do not risk other than tc01.
if kwargs["phy_cores"] != 1:
emit = False
- if kwargs["framesize"] not in min_framesize_values:
+ if kwargs["frame_size"] not in min_frame_size_values:
emit = False
if emit:
file_out.write(testcase.generate(num=num, **kwargs))
@@ -151,37 +152,128 @@ class Regenerator(object):
"""
num = 1
for tc_kwargs in tc_kwargs_list:
- num = add_testcase(testcase, iface, suite_id, file_out, num,
- **tc_kwargs)
+ num = add_testcase(
+ testcase, iface, suite_id, file_out, num, **tc_kwargs)
+
+ def replace_defensively(
+ whole, to_replace, replace_with, how_many, msg, in_filename):
+ """Replace substrings while checking the number of occurences.
+
+ Return edited copy of the text (so original string is not affected).
+
+ :param whole: The text to perform replacements on.
+ :param to_replace: Substring occurences of which to replace.
+ :param replace_with: Substring to replace occurences with.
+ :param how_many: Number of occurences to expect.
+ :param msg: Error message to raise.
+ :param in_filename: File name in which the error occured.
+ :type whole: str
+ :type to_replace: str
+ :type replace_with: str
+ :type how_many: int
+ :type msg: str
+ :type in_filename: str
+ :return: The whole text after replacements are done.
+ :rtype: str
+ :raise ValueError: If number of occurences does not match.
+ """
+ found = whole.count(to_replace)
+ if found != how_many:
+ raise ValueError(in_filename + ": " + msg)
+ return whole.replace(to_replace, replace_with)
+
+ def write_files(in_filename, in_prolog, kwargs_list):
+ """Using given filename and prolog, write all generated suites.
+
+ :param in_filename: Template filename to derive real filenames from.
+ :param in_prolog: Template content to derive real content from.
+ :param kwargs_list: List of kwargs for add_testcase.
+ :type in_filename: str
+ :type in_prolog: str
+ :type kwargs_list: list of dict
+ """
+ for suite_type in Constants.PERF_TYPE_TO_KEYWORD.keys():
+ tmp_filename = replace_defensively(
+ in_filename, "ndrpdr", suite_type, 1,
+ "File name should contain suite type once.", in_filename)
+ tmp_prolog = replace_defensively(
+ in_prolog, "ndrpdr".upper(), suite_type.upper(), 1,
+ "Suite type should appear once in uppercase (as tag).",
+ in_filename)
+ tmp_prolog = replace_defensively(
+ tmp_prolog,
+ "Find NDR and PDR intervals using optimized search",
+ Constants.PERF_TYPE_TO_KEYWORD[suite_type], 1,
+ "Main search keyword should appear once in suite.",
+ in_filename)
+ tmp_prolog = replace_defensively(
+ tmp_prolog,
+ Constants.PERF_TYPE_TO_SUITE_DOC_VER["ndrpdr"],
+ Constants.PERF_TYPE_TO_SUITE_DOC_VER[suite_type],
+ 1, "Exact suite type doc not found.", in_filename)
+ tmp_prolog = replace_defensively(
+ tmp_prolog,
+ Constants.PERF_TYPE_TO_TEMPLATE_DOC_VER["ndrpdr"],
+ Constants.PERF_TYPE_TO_TEMPLATE_DOC_VER[suite_type],
+ 1, "Exact template type doc not found.", in_filename)
+ _, suite_id = get_iface_and_suite_id(tmp_filename)
+ testcase = self.testcase_class(suite_id)
+ for nic_name in Constants.NIC_NAME_TO_CODE.keys():
+ out_filename = replace_defensively(
+ tmp_filename, "10ge2p1x710",
+ Constants.NIC_NAME_TO_CODE[nic_name], 1,
+ "File name should contain NIC code once.", in_filename)
+ out_prolog = replace_defensively(
+ tmp_prolog, "Intel-X710", nic_name, 2,
+ "NIC name should appear twice (tag and variable).",
+ in_filename)
+ if out_prolog.count("HW_") == 2:
+ # TODO CSIT-1481: Crypto HW should be read
+ # from topology file instead.
+ if nic_name in Constants.NIC_NAME_TO_CRYPTO_HW.keys():
+ out_prolog = replace_defensively(
+ out_prolog, "HW_DH895xcc",
+ Constants.NIC_NAME_TO_CRYPTO_HW[nic_name], 1,
+ "HW crypto name should appear.", in_filename)
+ iface, suite_id = get_iface_and_suite_id(out_filename)
+ with open(out_filename, "w") as file_out:
+ file_out.write(out_prolog)
+ add_testcases(
+ testcase, iface, suite_id, file_out, kwargs_list)
if not self.quiet:
eprint("Regenerator starts at {cwd}".format(cwd=getcwd()))
- min_framesize = protocol_to_min_framesize[protocol]
+ min_frame_size = protocol_to_min_frame_size[protocol]
kwargs_list = tc_kwargs_list if tc_kwargs_list else [
- {"framesize": min_framesize, "phy_cores": 1},
- {"framesize": min_framesize, "phy_cores": 2},
- {"framesize": min_framesize, "phy_cores": 4},
- {"framesize": 1518, "phy_cores": 1},
- {"framesize": 1518, "phy_cores": 2},
- {"framesize": 1518, "phy_cores": 4},
- {"framesize": 9000, "phy_cores": 1},
- {"framesize": 9000, "phy_cores": 2},
- {"framesize": 9000, "phy_cores": 4},
- {"framesize": "IMIX_v4_1", "phy_cores": 1},
- {"framesize": "IMIX_v4_1", "phy_cores": 2},
- {"framesize": "IMIX_v4_1", "phy_cores": 4}
+ {"frame_size": min_frame_size, "phy_cores": 1},
+ {"frame_size": min_frame_size, "phy_cores": 2},
+ {"frame_size": min_frame_size, "phy_cores": 4},
+ {"frame_size": 1518, "phy_cores": 1},
+ {"frame_size": 1518, "phy_cores": 2},
+ {"frame_size": 1518, "phy_cores": 4},
+ {"frame_size": 9000, "phy_cores": 1},
+ {"frame_size": 9000, "phy_cores": 2},
+ {"frame_size": 9000, "phy_cores": 4},
+ {"frame_size": "IMIX_v4_1", "phy_cores": 1},
+ {"frame_size": "IMIX_v4_1", "phy_cores": 2},
+ {"frame_size": "IMIX_v4_1", "phy_cores": 4}
]
- for filename in glob(pattern):
+ for in_filename in glob(pattern):
if not self.quiet:
- eprint("Regenerating filename:", filename)
- with open(filename, "r") as file_in:
- text = file_in.read()
- text_prolog = "".join(text.partition("*** Test Cases ***")[:-1])
- iface, suite_id = get_iface_and_suite_id(filename)
- testcase = self.testcase_class(suite_id)
- with open(filename, "w") as file_out:
- file_out.write(text_prolog)
- add_testcases(testcase, iface, suite_id, file_out, kwargs_list)
+ eprint("Regenerating in_filename:", in_filename)
+ if not in_filename.endswith("ndrpdr.robot"):
+ eprint("Error in {fil}: non-primary suite type encountered."
+ .format(fil=in_filename))
+ sys.exit(1)
+ iface, _ = get_iface_and_suite_id(in_filename)
+ if not iface.endswith("10ge2p1x710"):
+ eprint("Error in {fil}: non-primary NIC encountered."
+ .format(fil=in_filename))
+ sys.exit(1)
+ with open(in_filename, "r") as file_in:
+ in_prolog = "".join(
+ file_in.read().partition("*** Test Cases ***")[:-1])
+ write_files(in_filename, in_prolog, kwargs_list)
if not self.quiet:
eprint("Regenerator ends.")
eprint() # To make autogen check output more readable.
diff --git a/resources/libraries/python/autogen/Testcase.py b/resources/libraries/python/autogen/Testcase.py
index dd58547f33..7d0a29b0ad 100644
--- a/resources/libraries/python/autogen/Testcase.py
+++ b/resources/libraries/python/autogen/Testcase.py
@@ -34,29 +34,29 @@ class Testcase(object):
"""
self.template = Template(template_string)
- def generate(self, num, framesize, phy_cores):
+ def generate(self, num, frame_size, phy_cores):
"""Return string of test case code with placeholders filled.
Fail if there are placeholders left unfilled.
:param num: Test case number. Example value: 4.
- :param framesize: Imix string or numeric frame size. Example: 74.
+ :param frame_size: Imix string or numeric frame size. Example: 74.
:param phy_cores: Number of physical cores to use. Example: 2.
:type num: int
- :type framesize: str or int
+ :type frame_size: str or int
:type phy_cores: int or str
:returns: Filled template, usable as test case code.
:rtype: str
"""
try:
- fsize = int(framesize)
+ fsize = int(frame_size)
subst_dict = {
"frame_num": "${%d}" % fsize,
"frame_str": "%dB" % fsize
}
except ValueError: # Assuming an IMIX string.
subst_dict = {
- "frame_num": str(framesize),
+ "frame_num": str(frame_size),
"frame_str": "IMIX"
}
cores_str = str(phy_cores)