This patch adds support for measuring both local and remote CPU utilization: New option for netperf client have been added: cpu_util - when set to "local", netperf is run with -c argument, enabling measure of local CPU utilization during run, when set to "remote", netperf is run with -C argument, enabling measure of remote CPU utilization during run, when set to "both", netperf is run with both -c and -C arguments
Parsing of throughput and confidence interval has been made cleaner: Using omni netperf output, all relevant data are now stored in key=val format, which can be parsed more easily and is the same for all netperf test types.
Changes in v2: Changed format of cpu_util argument (described above)
Renamed keys in res_val dict to from loc_cpu_util and rem_cpu util to LOCAL_CPU_UTIL and REMOTE_CPU_UTIL
Fixed incorrect real confidence value, now the touple correctly returns (CONFIDENCE_LEVEL, THROUGHPUT_CONFIDENCE_INTERVAL/2)
Signed-off-by: Jiri Prochazka jprochaz@redhat.com --- test_modules/Netperf.py | 87 +++++++++++++++++++++++++------------------------ 1 file changed, 44 insertions(+), 43 deletions(-)
diff --git a/test_modules/Netperf.py b/test_modules/Netperf.py index 868cca0..9a20ad2 100644 --- a/test_modules/Netperf.py +++ b/test_modules/Netperf.py @@ -34,6 +34,7 @@ class Netperf(TestGeneric): self._confidence = self.get_opt("confidence") self._bind = self.get_opt("bind", opt_type="addr") self._family = self.get_opt("family") + self._cpu_util = self.get_opt("cpu_util")
self._runs = self.get_opt("runs", default=1) if self._runs > 1 and self._confidence is not None: @@ -61,7 +62,8 @@ class Netperf(TestGeneric): composes commands for netperf and netserver based on xml recipe """ if self._role == "client": - cmd = "netperf -H %s -f k" % self._netperf_server + # -P 0 disables banner header of output + cmd = "netperf -H %s -f k -P 0" % self._netperf_server if self._port is not None: """ client connects on this port @@ -89,11 +91,22 @@ class Netperf(TestGeneric): """ cmd += " -I %s" % self._confidence
+ if self._cpu_util is not None: + if self._cpu_util.lower() == "both": + cmd += " -c -C" + elif self._cpu_util.lower() == "local": + cmd += " -c" + elif self._cpu_util.lower() == "remote": + cmd += " -C" + if self._netperf_opts is not None: """ custom options for netperf """ cmd += " %s" % self._netperf_opts + # Print only relevant output + cmd += ' -- -k "THROUGHPUT, LOCAL_CPU_UTIL, REMOTE_CPU_UTIL, CONFIDENCE_LEVEL, THROUGHPUT_CONFID"' + elif self._role == "server": cmd = "netserver -D" if self._bind is not None: @@ -114,58 +127,47 @@ class Netperf(TestGeneric): return cmd
def _parse_output(self, output): - if self._testname == "UDP_STREAM": - # pattern for UDP_STREAM throughput output - # decimal float decimal (float) - pattern_udp_stream = "\d+\s+\d+.\d+\s+\d+\s+(\d+(.\d+){0,1})\n" - r2 = re.search(pattern_udp_stream, output.lower()) - elif self._testname == "TCP_STREAM": - # pattern for TCP_STREAM throughput output - # decimal decimal decimal float (float) - pattern_tcp_stream = "\d+\s+\d+\s+\d+\s+\d+.\d+\s+(\d+(.\d+){0,1})" - r2 = re.search(pattern_tcp_stream, output.lower()) - elif self._testname == "TCP_RR" or self._testname == "UDP_RR"\ - or self._testname == "SCTP_RR": - # pattern for TCP_RR, UDP_RR and SCTP_RR throughput output - # decimal decimal decimal decimal float (float) - pattern_tcp_rr = "\d+\s+\d+\s+\d+\s+\d+\s+\d+.\d+\s+(\d+(.\d+){0,1})" - r2 = re.search(pattern_tcp_rr, output.lower()) - else: - # pattern for SCTP streams and other tests - # decimal decimal decimal float (float) - pattern_sctp = "\d+\s+\d+\s+\d+\s+\d+.\d+\s+(\d+(.\d+){0,1})" - r2 = re.search(pattern_sctp, output.lower()) + res_val = {}
- if r2 is None: + pattern_throughput = "THROUGHPUT=(\d+.\d+)" + throughput = re.search(pattern_throughput, output) + + if throughput is None: rate_in_kb = 0.0 else: - rate_in_kb = float(r2.group(1)) + rate_in_kb = float(throughput.group(1)) + + res_val["rate"] = rate_in_kb*1000 + res_val["unit"] = "bps" + + if self._cpu_util is not None: + if self._cpu_util == "local" or self._cpu_util == "both": + pattern_loc_cpu_util = "LOCAL_CPU_UTIL=([-]?\d+.\d+)" + loc_cpu_util = re.search(pattern_loc_cpu_util, output) + res_val["LOCAL_CPU_UTIL"] = float(loc_cpu_util.group(1)) + + if self._cpu_util == "remote" or self._cpu_util == "both": + pattern_rem_cpu_util = "REMOTE_CPU_UTIL=([-]?\d+.\d+)" + rem_cpu_util = re.search(pattern_rem_cpu_util, output) + res_val["REMOTE_CPU_UTIL"] = float(rem_cpu_util.group(1))
if self._confidence is not None: confidence = self._parse_confidence(output) - return {"rate": rate_in_kb*1000, - "unit": "bps", - "confidence": confidence} - else: - return {"rate": rate_in_kb*1000, - "unit": "bps"} + res_val["confidence"] = confidence + + return res_val
def _parse_confidence(self, output): - normal_pattern = r'+/-(\d+.\d*)% @ (\d+)% conf.' - warning_pattern = r'!!! Confidence intervals: Throughput\s+: (\d+.\d*)%' - normal_confidence = re.search(normal_pattern, output) - warning_confidence = re.search(warning_pattern, output) + pattern_throughput_confid = "THROUGHPUT_CONFID=([-]?\d+.\d+)" + pattern_confidence_level = "CONFIDENCE_LEVEL=(\d+)" + throughput_confid = float(re.search(pattern_throughput_confid, output).group(1)) + confidence_level = int(re.search(pattern_confidence_level, output).group(1))
- if normal_confidence is None: - logging.error("Failed to parse confidence!!") + if throughput_confid == -1.00: + logging.error("Failed to parse confidence!") return (0, 0.0)
- if warning_confidence is None: - real_confidence = (float(normal_confidence.group(2)), - float(normal_confidence.group(1))) - else: - real_confidence = (float(normal_confidence.group(2)), - float(warning_confidence.group(1))/2) + real_confidence = (confidence_level, throughput_confid/2)
return real_confidence
@@ -216,7 +218,6 @@ class Netperf(TestGeneric): "throughput option" return (False, res_data) threshold_rate = float(r1.group(1)) - threshold_unit_size = "" threshold_unit_type = "tps"
return {"rate": threshold_rate,
Mon, Nov 09, 2015 at 11:07:44AM CET, jprochaz@redhat.com wrote:
This patch adds support for measuring both local and remote CPU utilization: New option for netperf client have been added: cpu_util - when set to "local", netperf is run with -c argument, enabling measure of local CPU utilization during run, when set to "remote", netperf is run with -C argument, enabling measure of remote CPU utilization during run, when set to "both", netperf is run with both -c and -C arguments
Parsing of throughput and confidence interval has been made cleaner: Using omni netperf output, all relevant data are now stored in key=val format, which can be parsed more easily and is the same for all netperf test types.
Changes in v2: Changed format of cpu_util argument (described above)
Renamed keys in res_val dict to from loc_cpu_util and rem_cpu util to LOCAL_CPU_UTIL and REMOTE_CPU_UTIL
Fixed incorrect real confidence value, now the touple correctly returns (CONFIDENCE_LEVEL, THROUGHPUT_CONFIDENCE_INTERVAL/2)
Signed-off-by: Jiri Prochazka jprochaz@redhat.com
test_modules/Netperf.py | 87 +++++++++++++++++++++++++------------------------ 1 file changed, 44 insertions(+), 43 deletions(-)
diff --git a/test_modules/Netperf.py b/test_modules/Netperf.py index 868cca0..9a20ad2 100644 --- a/test_modules/Netperf.py +++ b/test_modules/Netperf.py @@ -34,6 +34,7 @@ class Netperf(TestGeneric): self._confidence = self.get_opt("confidence") self._bind = self.get_opt("bind", opt_type="addr") self._family = self.get_opt("family")
self._cpu_util = self.get_opt("cpu_util") self._runs = self.get_opt("runs", default=1) if self._runs > 1 and self._confidence is not None:
@@ -61,7 +62,8 @@ class Netperf(TestGeneric): composes commands for netperf and netserver based on xml recipe """ if self._role == "client":
cmd = "netperf -H %s -f k" % self._netperf_server
# -P 0 disables banner header of output
cmd = "netperf -H %s -f k -P 0" % self._netperf_server if self._port is not None: """ client connects on this port
@@ -89,11 +91,22 @@ class Netperf(TestGeneric): """ cmd += " -I %s" % self._confidence
if self._cpu_util is not None:
if self._cpu_util.lower() == "both":
cmd += " -c -C"
elif self._cpu_util.lower() == "local":
cmd += " -c"
elif self._cpu_util.lower() == "remote":
cmd += " -C"
if self._netperf_opts is not None: """ custom options for netperf """ cmd += " %s" % self._netperf_opts
# Print only relevant output
cmd += ' -- -k "THROUGHPUT, LOCAL_CPU_UTIL, REMOTE_CPU_UTIL, CONFIDENCE_LEVEL, THROUGHPUT_CONFID"'
elif self._role == "server": cmd = "netserver -D" if self._bind is not None:
@@ -114,58 +127,47 @@ class Netperf(TestGeneric): return cmd
def _parse_output(self, output):
if self._testname == "UDP_STREAM":
# pattern for UDP_STREAM throughput output
# decimal float decimal (float)
pattern_udp_stream = "\d+\s+\d+\.\d+\s+\d+\s+(\d+(\.\d+){0,1})\n"
r2 = re.search(pattern_udp_stream, output.lower())
elif self._testname == "TCP_STREAM":
# pattern for TCP_STREAM throughput output
# decimal decimal decimal float (float)
pattern_tcp_stream = "\d+\s+\d+\s+\d+\s+\d+\.\d+\s+(\d+(\.\d+){0,1})"
r2 = re.search(pattern_tcp_stream, output.lower())
elif self._testname == "TCP_RR" or self._testname == "UDP_RR"\
or self._testname == "SCTP_RR":
# pattern for TCP_RR, UDP_RR and SCTP_RR throughput output
# decimal decimal decimal decimal float (float)
pattern_tcp_rr = "\d+\s+\d+\s+\d+\s+\d+\s+\d+\.\d+\s+(\d+(\.\d+){0,1})"
r2 = re.search(pattern_tcp_rr, output.lower())
else:
# pattern for SCTP streams and other tests
# decimal decimal decimal float (float)
pattern_sctp = "\d+\s+\d+\s+\d+\s+\d+\.\d+\s+(\d+(\.\d+){0,1})"
r2 = re.search(pattern_sctp, output.lower())
res_val = {}
if r2 is None:
pattern_throughput = "THROUGHPUT=(\d+\.\d+)"
throughput = re.search(pattern_throughput, output)
if throughput is None: rate_in_kb = 0.0 else:
rate_in_kb = float(r2.group(1))
rate_in_kb = float(throughput.group(1))
res_val["rate"] = rate_in_kb*1000
res_val["unit"] = "bps"
if self._cpu_util is not None:
if self._cpu_util == "local" or self._cpu_util == "both":
pattern_loc_cpu_util = "LOCAL_CPU_UTIL=([-]?\d+\.\d+)"
loc_cpu_util = re.search(pattern_loc_cpu_util, output)
res_val["LOCAL_CPU_UTIL"] = float(loc_cpu_util.group(1))
if self._cpu_util == "remote" or self._cpu_util == "both":
pattern_rem_cpu_util = "REMOTE_CPU_UTIL=([-]?\d+\.\d+)"
rem_cpu_util = re.search(pattern_rem_cpu_util, output)
res_val["REMOTE_CPU_UTIL"] = float(rem_cpu_util.group(1)) if self._confidence is not None: confidence = self._parse_confidence(output)
return {"rate": rate_in_kb*1000,
"unit": "bps",
"confidence": confidence}
else:
return {"rate": rate_in_kb*1000,
"unit": "bps"}
res_val["confidence"] = confidence
return res_val
def _parse_confidence(self, output):
normal_pattern = r'\+/-(\d+\.\d*)% @ (\d+)% conf\.'
warning_pattern = r'!!! Confidence intervals: Throughput\s+: (\d+\.\d*)%'
normal_confidence = re.search(normal_pattern, output)
warning_confidence = re.search(warning_pattern, output)
pattern_throughput_confid = "THROUGHPUT_CONFID=([-]?\d+\.\d+)"
pattern_confidence_level = "CONFIDENCE_LEVEL=(\d+)"
throughput_confid = float(re.search(pattern_throughput_confid, output).group(1))
confidence_level = int(re.search(pattern_confidence_level, output).group(1))
if normal_confidence is None:
logging.error("Failed to parse confidence!!")
if throughput_confid == -1.00:
^ What is this magic number? --------'
logging.error("Failed to parse confidence!") return (0, 0.0)
if warning_confidence is None:
real_confidence = (float(normal_confidence.group(2)),
float(normal_confidence.group(1)))
else:
real_confidence = (float(normal_confidence.group(2)),
float(warning_confidence.group(1))/2)
real_confidence = (confidence_level, throughput_confid/2) return real_confidence
@@ -216,7 +218,6 @@ class Netperf(TestGeneric): "throughput option" return (False, res_data) threshold_rate = float(r1.group(1))
threshold_unit_size = "" threshold_unit_type = "tps" return {"rate": threshold_rate,
-- 2.4.3
LNST-developers mailing list LNST-developers@lists.fedorahosted.org https://lists.fedorahosted.org/mailman/listinfo/lnst-developers
2015-11-10 15:51 GMT+01:00 Jan Tluka jtluka@redhat.com:
Mon, Nov 09, 2015 at 11:07:44AM CET, jprochaz@redhat.com wrote:
This patch adds support for measuring both local and remote CPU
utilization:
New option for netperf client have been added: cpu_util - when set to "local", netperf is run with -c argument,
enabling measure of local CPU utilization during run,
when set to "remote", netperf is run with -C argument,
enabling measure of remote CPU utilization during run,
when set to "both", netperf is run with both -c and -C
arguments
Parsing of throughput and confidence interval has been made cleaner: Using omni netperf output, all relevant data are now stored in
key=val format,
which can be parsed more easily and is the same for all netperf test
types.
Changes in v2: Changed format of cpu_util argument (described above)
Renamed keys in res_val dict to from loc_cpu_util and rem_cpu util to LOCAL_CPU_UTIL and REMOTE_CPU_UTIL
Fixed incorrect real confidence value, now the touple correctly returns (CONFIDENCE_LEVEL, THROUGHPUT_CONFIDENCE_INTERVAL/2)
Signed-off-by: Jiri Prochazka jprochaz@redhat.com
test_modules/Netperf.py | 87
+++++++++++++++++++++++++------------------------
1 file changed, 44 insertions(+), 43 deletions(-)
diff --git a/test_modules/Netperf.py b/test_modules/Netperf.py index 868cca0..9a20ad2 100644 --- a/test_modules/Netperf.py +++ b/test_modules/Netperf.py @@ -34,6 +34,7 @@ class Netperf(TestGeneric): self._confidence = self.get_opt("confidence") self._bind = self.get_opt("bind", opt_type="addr") self._family = self.get_opt("family")
self._cpu_util = self.get_opt("cpu_util") self._runs = self.get_opt("runs", default=1) if self._runs > 1 and self._confidence is not None:
@@ -61,7 +62,8 @@ class Netperf(TestGeneric): composes commands for netperf and netserver based on xml recipe """ if self._role == "client":
cmd = "netperf -H %s -f k" % self._netperf_server
# -P 0 disables banner header of output
cmd = "netperf -H %s -f k -P 0" % self._netperf_server if self._port is not None: """ client connects on this port
@@ -89,11 +91,22 @@ class Netperf(TestGeneric): """ cmd += " -I %s" % self._confidence
if self._cpu_util is not None:
if self._cpu_util.lower() == "both":
cmd += " -c -C"
elif self._cpu_util.lower() == "local":
cmd += " -c"
elif self._cpu_util.lower() == "remote":
cmd += " -C"
if self._netperf_opts is not None: """ custom options for netperf """ cmd += " %s" % self._netperf_opts
# Print only relevant output
cmd += ' -- -k "THROUGHPUT, LOCAL_CPU_UTIL, REMOTE_CPU_UTIL,
CONFIDENCE_LEVEL, THROUGHPUT_CONFID"'
elif self._role == "server": cmd = "netserver -D" if self._bind is not None:
@@ -114,58 +127,47 @@ class Netperf(TestGeneric): return cmd
def _parse_output(self, output):
if self._testname == "UDP_STREAM":
# pattern for UDP_STREAM throughput output
# decimal float decimal (float)
pattern_udp_stream =
"\d+\s+\d+.\d+\s+\d+\s+(\d+(.\d+){0,1})\n"
r2 = re.search(pattern_udp_stream, output.lower())
elif self._testname == "TCP_STREAM":
# pattern for TCP_STREAM throughput output
# decimal decimal decimal float (float)
pattern_tcp_stream =
"\d+\s+\d+\s+\d+\s+\d+.\d+\s+(\d+(.\d+){0,1})"
r2 = re.search(pattern_tcp_stream, output.lower())
elif self._testname == "TCP_RR" or self._testname == "UDP_RR"\
or self._testname == "SCTP_RR":
# pattern for TCP_RR, UDP_RR and SCTP_RR throughput output
# decimal decimal decimal decimal float (float)
pattern_tcp_rr =
"\d+\s+\d+\s+\d+\s+\d+\s+\d+.\d+\s+(\d+(.\d+){0,1})"
r2 = re.search(pattern_tcp_rr, output.lower())
else:
# pattern for SCTP streams and other tests
# decimal decimal decimal float (float)
pattern_sctp =
"\d+\s+\d+\s+\d+\s+\d+.\d+\s+(\d+(.\d+){0,1})"
r2 = re.search(pattern_sctp, output.lower())
res_val = {}
if r2 is None:
pattern_throughput = "THROUGHPUT=(\d+\.\d+)"
throughput = re.search(pattern_throughput, output)
if throughput is None: rate_in_kb = 0.0 else:
rate_in_kb = float(r2.group(1))
rate_in_kb = float(throughput.group(1))
res_val["rate"] = rate_in_kb*1000
res_val["unit"] = "bps"
if self._cpu_util is not None:
if self._cpu_util == "local" or self._cpu_util == "both":
pattern_loc_cpu_util = "LOCAL_CPU_UTIL=([-]?\d+\.\d+)"
loc_cpu_util = re.search(pattern_loc_cpu_util, output)
res_val["LOCAL_CPU_UTIL"] = float(loc_cpu_util.group(1))
if self._cpu_util == "remote" or self._cpu_util == "both":
pattern_rem_cpu_util = "REMOTE_CPU_UTIL=([-]?\d+\.\d+)"
rem_cpu_util = re.search(pattern_rem_cpu_util, output)
res_val["REMOTE_CPU_UTIL"] = float(rem_cpu_util.group(1)) if self._confidence is not None: confidence = self._parse_confidence(output)
return {"rate": rate_in_kb*1000,
"unit": "bps",
"confidence": confidence}
else:
return {"rate": rate_in_kb*1000,
"unit": "bps"}
res_val["confidence"] = confidence
return res_val
def _parse_confidence(self, output):
normal_pattern = r'\+/-(\d+\.\d*)% @ (\d+)% conf\.'
warning_pattern = r'!!! Confidence intervals: Throughput\s+:
(\d+.\d*)%'
normal_confidence = re.search(normal_pattern, output)
warning_confidence = re.search(warning_pattern, output)
pattern_throughput_confid = "THROUGHPUT_CONFID=([-]?\d+\.\d+)"
pattern_confidence_level = "CONFIDENCE_LEVEL=(\d+)"
throughput_confid = float(re.search(pattern_throughput_confid,
output).group(1))
confidence_level = int(re.search(pattern_confidence_level,
output).group(1))
if normal_confidence is None:
logging.error("Failed to parse confidence!!")
if throughput_confid == -1.00:
^
What is this magic number? --------'
Omni output selectors return value -1.00 when the actual value is not obtained.
logging.error("Failed to parse confidence!") return (0, 0.0)
if warning_confidence is None:
real_confidence = (float(normal_confidence.group(2)),
float(normal_confidence.group(1)))
else:
real_confidence = (float(normal_confidence.group(2)),
float(warning_confidence.group(1))/2)
real_confidence = (confidence_level, throughput_confid/2) return real_confidence
@@ -216,7 +218,6 @@ class Netperf(TestGeneric): "throughput option" return (False, res_data) threshold_rate = float(r1.group(1))
threshold_unit_size = "" threshold_unit_type = "tps" return {"rate": threshold_rate,
-- 2.4.3
LNST-developers mailing list LNST-developers@lists.fedorahosted.org https://lists.fedorahosted.org/mailman/listinfo/lnst-developers
Tue, Nov 10, 2015 at 05:11:41PM CET, jprochaz@redhat.com wrote:
2015-11-10 15:51 GMT+01:00 Jan Tluka jtluka@redhat.com:
Mon, Nov 09, 2015 at 11:07:44AM CET, jprochaz@redhat.com wrote:
This patch adds support for measuring both local and remote CPU
utilization:
New option for netperf client have been added: cpu_util - when set to "local", netperf is run with -c argument,
enabling measure of local CPU utilization during run,
when set to "remote", netperf is run with -C argument,
enabling measure of remote CPU utilization during run,
when set to "both", netperf is run with both -c and -C
arguments
Parsing of throughput and confidence interval has been made cleaner: Using omni netperf output, all relevant data are now stored in
key=val format,
which can be parsed more easily and is the same for all netperf test
types.
Changes in v2: Changed format of cpu_util argument (described above)
Renamed keys in res_val dict to from loc_cpu_util and rem_cpu util to LOCAL_CPU_UTIL and REMOTE_CPU_UTIL
Fixed incorrect real confidence value, now the touple correctly returns (CONFIDENCE_LEVEL, THROUGHPUT_CONFIDENCE_INTERVAL/2)
Signed-off-by: Jiri Prochazka jprochaz@redhat.com
test_modules/Netperf.py | 87
+++++++++++++++++++++++++------------------------
1 file changed, 44 insertions(+), 43 deletions(-)
diff --git a/test_modules/Netperf.py b/test_modules/Netperf.py index 868cca0..9a20ad2 100644 --- a/test_modules/Netperf.py +++ b/test_modules/Netperf.py @@ -34,6 +34,7 @@ class Netperf(TestGeneric): self._confidence = self.get_opt("confidence") self._bind = self.get_opt("bind", opt_type="addr") self._family = self.get_opt("family")
self._cpu_util = self.get_opt("cpu_util") self._runs = self.get_opt("runs", default=1) if self._runs > 1 and self._confidence is not None:
@@ -61,7 +62,8 @@ class Netperf(TestGeneric): composes commands for netperf and netserver based on xml recipe """ if self._role == "client":
cmd = "netperf -H %s -f k" % self._netperf_server
# -P 0 disables banner header of output
cmd = "netperf -H %s -f k -P 0" % self._netperf_server if self._port is not None: """ client connects on this port
@@ -89,11 +91,22 @@ class Netperf(TestGeneric): """ cmd += " -I %s" % self._confidence
if self._cpu_util is not None:
if self._cpu_util.lower() == "both":
cmd += " -c -C"
elif self._cpu_util.lower() == "local":
cmd += " -c"
elif self._cpu_util.lower() == "remote":
cmd += " -C"
if self._netperf_opts is not None: """ custom options for netperf """ cmd += " %s" % self._netperf_opts
# Print only relevant output
cmd += ' -- -k "THROUGHPUT, LOCAL_CPU_UTIL, REMOTE_CPU_UTIL,
CONFIDENCE_LEVEL, THROUGHPUT_CONFID"'
elif self._role == "server": cmd = "netserver -D" if self._bind is not None:
@@ -114,58 +127,47 @@ class Netperf(TestGeneric): return cmd
def _parse_output(self, output):
if self._testname == "UDP_STREAM":
# pattern for UDP_STREAM throughput output
# decimal float decimal (float)
pattern_udp_stream =
"\d+\s+\d+.\d+\s+\d+\s+(\d+(.\d+){0,1})\n"
r2 = re.search(pattern_udp_stream, output.lower())
elif self._testname == "TCP_STREAM":
# pattern for TCP_STREAM throughput output
# decimal decimal decimal float (float)
pattern_tcp_stream =
"\d+\s+\d+\s+\d+\s+\d+.\d+\s+(\d+(.\d+){0,1})"
r2 = re.search(pattern_tcp_stream, output.lower())
elif self._testname == "TCP_RR" or self._testname == "UDP_RR"\
or self._testname == "SCTP_RR":
# pattern for TCP_RR, UDP_RR and SCTP_RR throughput output
# decimal decimal decimal decimal float (float)
pattern_tcp_rr =
"\d+\s+\d+\s+\d+\s+\d+\s+\d+.\d+\s+(\d+(.\d+){0,1})"
r2 = re.search(pattern_tcp_rr, output.lower())
else:
# pattern for SCTP streams and other tests
# decimal decimal decimal float (float)
pattern_sctp =
"\d+\s+\d+\s+\d+\s+\d+.\d+\s+(\d+(.\d+){0,1})"
r2 = re.search(pattern_sctp, output.lower())
res_val = {}
if r2 is None:
pattern_throughput = "THROUGHPUT=(\d+\.\d+)"
throughput = re.search(pattern_throughput, output)
if throughput is None: rate_in_kb = 0.0 else:
rate_in_kb = float(r2.group(1))
rate_in_kb = float(throughput.group(1))
res_val["rate"] = rate_in_kb*1000
res_val["unit"] = "bps"
if self._cpu_util is not None:
if self._cpu_util == "local" or self._cpu_util == "both":
pattern_loc_cpu_util = "LOCAL_CPU_UTIL=([-]?\d+\.\d+)"
loc_cpu_util = re.search(pattern_loc_cpu_util, output)
res_val["LOCAL_CPU_UTIL"] = float(loc_cpu_util.group(1))
if self._cpu_util == "remote" or self._cpu_util == "both":
pattern_rem_cpu_util = "REMOTE_CPU_UTIL=([-]?\d+\.\d+)"
rem_cpu_util = re.search(pattern_rem_cpu_util, output)
res_val["REMOTE_CPU_UTIL"] = float(rem_cpu_util.group(1)) if self._confidence is not None: confidence = self._parse_confidence(output)
return {"rate": rate_in_kb*1000,
"unit": "bps",
"confidence": confidence}
else:
return {"rate": rate_in_kb*1000,
"unit": "bps"}
res_val["confidence"] = confidence
return res_val
def _parse_confidence(self, output):
normal_pattern = r'\+/-(\d+\.\d*)% @ (\d+)% conf\.'
warning_pattern = r'!!! Confidence intervals: Throughput\s+:
(\d+.\d*)%'
normal_confidence = re.search(normal_pattern, output)
warning_confidence = re.search(warning_pattern, output)
pattern_throughput_confid = "THROUGHPUT_CONFID=([-]?\d+\.\d+)"
pattern_confidence_level = "CONFIDENCE_LEVEL=(\d+)"
throughput_confid = float(re.search(pattern_throughput_confid,
output).group(1))
confidence_level = int(re.search(pattern_confidence_level,
output).group(1))
if normal_confidence is None:
logging.error("Failed to parse confidence!!")
if throughput_confid == -1.00:
^
What is this magic number? --------'
Omni output selectors return value -1.00 when the actual value is not obtained.
Hmm, this looks like a code that will never get executed since _parse_confidence() is called only if user specifies desired confidence level and netperf succeeds, the value other than -1.00 will be there whenever you run the test I guess.
When the situation can happen?
logging.error("Failed to parse confidence!") return (0, 0.0)
if warning_confidence is None:
real_confidence = (float(normal_confidence.group(2)),
float(normal_confidence.group(1)))
else:
real_confidence = (float(normal_confidence.group(2)),
float(warning_confidence.group(1))/2)
real_confidence = (confidence_level, throughput_confid/2) return real_confidence
@@ -216,7 +218,6 @@ class Netperf(TestGeneric): "throughput option" return (False, res_data) threshold_rate = float(r1.group(1))
threshold_unit_size = "" threshold_unit_type = "tps" return {"rate": threshold_rate,
-- 2.4.3
LNST-developers mailing list LNST-developers@lists.fedorahosted.org https://lists.fedorahosted.org/mailman/listinfo/lnst-developers
-- Best regards,
Jiri Prochazka LNST Developer | www.lnst-project.org
+420 532 294 633 | jprochaz@redhat.com Red Hat Czech | Purkyňova 71/99, 612 00 Brno
2015-11-10 17:44 GMT+01:00 Jan Tluka jtluka@redhat.com:
Tue, Nov 10, 2015 at 05:11:41PM CET, jprochaz@redhat.com wrote:
2015-11-10 15:51 GMT+01:00 Jan Tluka jtluka@redhat.com:
Mon, Nov 09, 2015 at 11:07:44AM CET, jprochaz@redhat.com wrote:
This patch adds support for measuring both local and remote CPU
utilization:
New option for netperf client have been added: cpu_util - when set to "local", netperf is run with -c argument,
enabling measure of local CPU utilization during run,
when set to "remote", netperf is run with -C argument,
enabling measure of remote CPU utilization during run,
when set to "both", netperf is run with both -c and -C
arguments
Parsing of throughput and confidence interval has been made cleaner: Using omni netperf output, all relevant data are now stored in
key=val format,
which can be parsed more easily and is the same for all netperf
test
types.
Changes in v2: Changed format of cpu_util argument (described above)
Renamed keys in res_val dict to from loc_cpu_util and rem_cpu util to LOCAL_CPU_UTIL and REMOTE_CPU_UTIL
Fixed incorrect real confidence value, now the touple correctly returns (CONFIDENCE_LEVEL, THROUGHPUT_CONFIDENCE_INTERVAL/2)
Signed-off-by: Jiri Prochazka jprochaz@redhat.com
test_modules/Netperf.py | 87
+++++++++++++++++++++++++------------------------
1 file changed, 44 insertions(+), 43 deletions(-)
diff --git a/test_modules/Netperf.py b/test_modules/Netperf.py index 868cca0..9a20ad2 100644 --- a/test_modules/Netperf.py +++ b/test_modules/Netperf.py @@ -34,6 +34,7 @@ class Netperf(TestGeneric): self._confidence = self.get_opt("confidence") self._bind = self.get_opt("bind", opt_type="addr") self._family = self.get_opt("family")
self._cpu_util = self.get_opt("cpu_util") self._runs = self.get_opt("runs", default=1) if self._runs > 1 and self._confidence is not None:
@@ -61,7 +62,8 @@ class Netperf(TestGeneric): composes commands for netperf and netserver based on xml
recipe
""" if self._role == "client":
cmd = "netperf -H %s -f k" % self._netperf_server
# -P 0 disables banner header of output
cmd = "netperf -H %s -f k -P 0" % self._netperf_server if self._port is not None: """ client connects on this port
@@ -89,11 +91,22 @@ class Netperf(TestGeneric): """ cmd += " -I %s" % self._confidence
if self._cpu_util is not None:
if self._cpu_util.lower() == "both":
cmd += " -c -C"
elif self._cpu_util.lower() == "local":
cmd += " -c"
elif self._cpu_util.lower() == "remote":
cmd += " -C"
if self._netperf_opts is not None: """ custom options for netperf """ cmd += " %s" % self._netperf_opts
# Print only relevant output
cmd += ' -- -k "THROUGHPUT, LOCAL_CPU_UTIL,
REMOTE_CPU_UTIL,
CONFIDENCE_LEVEL, THROUGHPUT_CONFID"'
elif self._role == "server": cmd = "netserver -D" if self._bind is not None:
@@ -114,58 +127,47 @@ class Netperf(TestGeneric): return cmd
def _parse_output(self, output):
if self._testname == "UDP_STREAM":
# pattern for UDP_STREAM throughput output
# decimal float decimal (float)
pattern_udp_stream =
"\d+\s+\d+.\d+\s+\d+\s+(\d+(.\d+){0,1})\n"
r2 = re.search(pattern_udp_stream, output.lower())
elif self._testname == "TCP_STREAM":
# pattern for TCP_STREAM throughput output
# decimal decimal decimal float (float)
pattern_tcp_stream =
"\d+\s+\d+\s+\d+\s+\d+.\d+\s+(\d+(.\d+){0,1})"
r2 = re.search(pattern_tcp_stream, output.lower())
elif self._testname == "TCP_RR" or self._testname == "UDP_RR"\
or self._testname == "SCTP_RR":
# pattern for TCP_RR, UDP_RR and SCTP_RR throughput output
# decimal decimal decimal decimal float (float)
pattern_tcp_rr =
"\d+\s+\d+\s+\d+\s+\d+\s+\d+.\d+\s+(\d+(.\d+){0,1})"
r2 = re.search(pattern_tcp_rr, output.lower())
else:
# pattern for SCTP streams and other tests
# decimal decimal decimal float (float)
pattern_sctp =
"\d+\s+\d+\s+\d+\s+\d+.\d+\s+(\d+(.\d+){0,1})"
r2 = re.search(pattern_sctp, output.lower())
res_val = {}
if r2 is None:
pattern_throughput = "THROUGHPUT=(\d+\.\d+)"
throughput = re.search(pattern_throughput, output)
if throughput is None: rate_in_kb = 0.0 else:
rate_in_kb = float(r2.group(1))
rate_in_kb = float(throughput.group(1))
res_val["rate"] = rate_in_kb*1000
res_val["unit"] = "bps"
if self._cpu_util is not None:
if self._cpu_util == "local" or self._cpu_util == "both":
pattern_loc_cpu_util = "LOCAL_CPU_UTIL=([-]?\d+\.\d+)"
loc_cpu_util = re.search(pattern_loc_cpu_util, output)
res_val["LOCAL_CPU_UTIL"] =
float(loc_cpu_util.group(1))
if self._cpu_util == "remote" or self._cpu_util == "both":
pattern_rem_cpu_util =
"REMOTE_CPU_UTIL=([-]?\d+.\d+)"
rem_cpu_util = re.search(pattern_rem_cpu_util, output)
res_val["REMOTE_CPU_UTIL"] =
float(rem_cpu_util.group(1))
if self._confidence is not None: confidence = self._parse_confidence(output)
return {"rate": rate_in_kb*1000,
"unit": "bps",
"confidence": confidence}
else:
return {"rate": rate_in_kb*1000,
"unit": "bps"}
res_val["confidence"] = confidence
return res_val
def _parse_confidence(self, output):
normal_pattern = r'\+/-(\d+\.\d*)% @ (\d+)% conf\.'
warning_pattern = r'!!! Confidence intervals: Throughput\s+:
(\d+.\d*)%'
normal_confidence = re.search(normal_pattern, output)
warning_confidence = re.search(warning_pattern, output)
pattern_throughput_confid = "THROUGHPUT_CONFID=([-]?\d+\.\d+)"
pattern_confidence_level = "CONFIDENCE_LEVEL=(\d+)"
throughput_confid = float(re.search(pattern_throughput_confid,
output).group(1))
confidence_level = int(re.search(pattern_confidence_level,
output).group(1))
if normal_confidence is None:
logging.error("Failed to parse confidence!!")
if throughput_confid == -1.00:
^
What is this magic number? --------'
Omni output selectors return value -1.00 when the actual value is not obtained.
Hmm, this looks like a code that will never get executed since _parse_confidence() is called only if user specifies desired confidence level and netperf succeeds, the value other than -1.00 will be there whenever you run the test I guess.
When the situation can happen?
You are right, that shouldn't ever happen, thanks for the feedback, I'll send v3 patch where this code is removed
logging.error("Failed to parse confidence!") return (0, 0.0)
if warning_confidence is None:
real_confidence = (float(normal_confidence.group(2)),
float(normal_confidence.group(1)))
else:
real_confidence = (float(normal_confidence.group(2)),
float(warning_confidence.group(1))/2)
real_confidence = (confidence_level, throughput_confid/2) return real_confidence
@@ -216,7 +218,6 @@ class Netperf(TestGeneric): "throughput option" return (False, res_data) threshold_rate = float(r1.group(1))
threshold_unit_size = "" threshold_unit_type = "tps" return {"rate": threshold_rate,
-- 2.4.3
LNST-developers mailing list LNST-developers@lists.fedorahosted.org https://lists.fedorahosted.org/mailman/listinfo/lnst-developers
-- Best regards,
Jiri Prochazka LNST Developer | www.lnst-project.org
+420 532 294 633 | jprochaz@redhat.com Red Hat Czech | Purkyňova 71/99, 612 00 Brno
lnst-developers@lists.fedorahosted.org