From: Christos Sfakianakis <csfakian(a)redhat.com>
Add/edit methods in PingTestAndEvaluate to handle parallel scenarios:
a) added "ping_init" to initiate a Tests.Ping instance for all
scenarios
b) edited "ping_test" to split between default and parallel
scenarios
c) added "parallel_ping_evaluate_and_report" as the analogous of
"ping_evaluate_and_report" for the parallel case
d) added "single_ping_evaluate_and_report" to report which ip's
are used each time in the parallel case
v2:
lnst.Recipes.ENRT.BaseEnrtRecipe: add _create _reverse_ping method to
return reverse ping configs. Use it in 'generate_ping_configurations'
and yield a list from the latter in all cases. Reverse the order of
assigned IPv6 addresses in 'generate_ping_configurations' as they are
saved in LIFO fashion by the underlying modules.
lnst.RecipeCommon.Ping:
Remove checks for type 'list' in 'ping_test', since this type has been
ensured above. Merge {,parallel_}ping_evaluate_and_report into a single
method.
Signed-off-by: Christos Sfakianakis <csfakian(a)redhat.com>
---
lnst/RecipeCommon/Ping.py | 43 ++++++++++++++++----
lnst/Recipes/ENRT/BaseEnrtRecipe.py | 62 ++++++++++++++++++++++++-----
2 files changed, 87 insertions(+), 18 deletions(-)
diff --git a/lnst/RecipeCommon/Ping.py b/lnst/RecipeCommon/Ping.py
index f5cd652..31f1b38 100644
--- a/lnst/RecipeCommon/Ping.py
+++ b/lnst/RecipeCommon/Ping.py
@@ -44,21 +44,48 @@ class PingConf(object):
class PingTestAndEvaluate(BaseRecipe):
def ping_test(self, ping_config):
+ results = {}
+
+ running_ping_array = []
+ for pingconf in ping_config:
+ ping, client = self.ping_init(pingconf)
+ running_ping = client.prepare_job(ping)
+ running_ping.start(bg = True)
+ running_ping_array.append((pingconf, running_ping))
+
+ for _, pingjob in running_ping_array:
+ try:
+ pingjob.wait()
+ finally:
+ pingjob.kill()
+
+ for pingconf, pingjob in running_ping_array:
+ result = pingjob.result
+ results[pingconf] = result
+
+ return results
+
+ def ping_init(self, ping_config):
client = ping_config.client
destination = ping_config.destination
-
kwargs = self._generate_ping_kwargs(ping_config)
ping = Ping(**kwargs)
-
- ping_job = client.run(ping)
- return ping_job.result
+ return (ping, client)
def ping_evaluate_and_report(self, ping_config, results):
- # do we want to use the "perf" measurements (store a baseline etc...) as well?
- if results["rate"] > 50:
- self.add_result(True, "Ping succesful", results)
+ for pingconf, result in results.items():
+ self.single_ping_evaluate_and_report(pingconf, result)
+
+ def single_ping_evaluate_and_report(self, ping_config, result):
+ fmt = "From: <{0.client.hostid} ({0.client_bind})> To: " \
+ "<{0.destination.hostid} ({0.destination_address})>"
+ description = fmt.format(ping_config)
+ if result["rate"] > 50:
+ message = "Ping successful --- " + description
+ self.add_result(True, message, result)
else:
- self.add_result(False, "Ping unsuccesful", results)
+ message = "Ping unsuccessful --- " + description
+ self.add_result(False, message, result)
def _generate_ping_kwargs(self, ping_config):
kwargs = dict(dst=ping_config.destination_address,
diff --git a/lnst/Recipes/ENRT/BaseEnrtRecipe.py b/lnst/Recipes/ENRT/BaseEnrtRecipe.py
index d21d4bd..4d57b74 100644
--- a/lnst/Recipes/ENRT/BaseEnrtRecipe.py
+++ b/lnst/Recipes/ENRT/BaseEnrtRecipe.py
@@ -66,6 +66,13 @@ class EnrtSubConfiguration(object):
class BaseEnrtRecipe(PingTestAndEvaluate, PerfRecipe):
ip_versions = Param(default=("ipv4", "ipv6"))
+
+ ping_parallel = BoolParam(default=False)
+ ping_bidirect = BoolParam(default=False)
+ ping_count = IntParam(default = 100)
+ ping_interval = StrParam(default = 0.2)
+ ping_psize = IntParam(default = None)
+
perf_tests = Param(default=("tcp_stream", "udp_stream", "sctp_stream"))
offload_combinations = Param(default=(
@@ -176,22 +183,47 @@ class BaseEnrtRecipe(PingTestAndEvaluate, PerfRecipe):
def generate_ping_configurations(self, main_config, sub_config):
client_nic = main_config.endpoint1
server_nic = main_config.endpoint2
- client_netns = client_nic.netns
- server_netns = server_nic.netns
+
+ count = self.params.ping_count
+ interval = self.params.ping_interval
+ size = self.params.ping_psize
+ common_args = {'count' : count, 'interval' : interval, 'size' : size}
for ipv in self.params.ip_versions:
+ kwargs = {}
if ipv == "ipv4":
- family = AF_INET
+ kwargs.update(family = AF_INET)
elif ipv == "ipv6":
- family = AF_INET6
+ kwargs.update(family = AF_INET6)
+ kwargs.update(link_local = False)
- client_bind = client_nic.ips_filter(family=family)[0]
- server_bind = server_nic.ips_filter(family=family)[0]
+ client_ips = client_nic.ips_filter(**kwargs)
+ server_ips = server_nic.ips_filter(**kwargs)
+ if ipv == "ipv6":
+ client_ips = client_ips[::-1]
+ server_ips = server_ips[::-1]
+
+ if len(client_ips) != len(server_ips) or len(client_ips) * len(server_ips) == 0:
+ raise LnstError("Source/destination ip lists are of different size or empty.")
+
+ ping_conf_list = []
+ for src_addr, dst_addr in zip(client_ips, server_ips):
+ pconf = PingConf(client = client_nic.netns,
+ client_bind = src_addr,
+ destination = server_nic.netns,
+ destination_address = dst_addr,
+ **common_args)
+
+ ping_conf_list.append(pconf)
- yield PingConf(client = client_netns,
- client_bind = client_bind,
- destination = server_netns,
- destination_address = server_bind)
+ if self.params.ping_bidirect:
+ rev_pconf = self._create_reverse_ping(pconf, common_args)
+ ping_conf_list.append(rev_pconf)
+
+ if not self.params.ping_parallel:
+ break
+
+ yield ping_conf_list
def generate_perf_configurations(self, main_config, sub_config):
client_nic = main_config.endpoint1
@@ -261,6 +293,16 @@ class BaseEnrtRecipe(PingTestAndEvaluate, PerfRecipe):
)
return rev_flow
+ def _create_reverse_ping(self, pconf, args):
+ rev_pconf = PingConf(
+ client = pconf.destination,
+ client_bind = pconf.destination_address,
+ destination = pconf.client,
+ destination_address = pconf.client_bind,
+ **args
+ )
+ return rev_pconf
+
def _pin_dev_interrupts(self, dev, cpu):
netns = dev.netns
cpu_info = netns.run("lscpu").stdout
--
2.17.1