From: Christos Sfakianakis csfakian@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@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
On Wed, Mar 20, 2019 at 05:24:47PM +0100, csfakian@redhat.com wrote:
From: Christos Sfakianakis csfakian@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@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 _______________________________________________ LNST-developers mailing list -- lnst-developers@lists.fedorahosted.org To unsubscribe send an email to lnst-developers-leave@lists.fedorahosted.org Fedora Code of Conduct: https://getfedora.org/code-of-conduct.html List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedorahosted.org/archives/list/lnst-developers@lists.fedorahos...
pushed, thanks
-Ondrej
lnst-developers@lists.fedorahosted.org