On Tue, Nov 03, 2015 at 05:02:26PM +0100, Jiri Prochazka wrote:
This patch adds support for measuring both local and remote CPU
utilization:
Two new options for netperf client have been added:
loc_cpu_util - when set to True, netperf is run with -c argument, enabling measure of
local CPU utilization during run
rem_cpu_util - same as above but for remote host with -C argument
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.
Signed-off-by: Jiri Prochazka <jprochaz(a)redhat.com>
---
test_modules/Netperf.py | 91 +++++++++++++++++++++++++------------------------
1 file changed, 47 insertions(+), 44 deletions(-)
diff --git a/test_modules/Netperf.py b/test_modules/Netperf.py
index 868cca0..05e99e2 100644
--- a/test_modules/Netperf.py
+++ b/test_modules/Netperf.py
@@ -11,7 +11,7 @@ import errno
import re
from lnst.Common.TestsCommon import TestGeneric
from lnst.Common.ShellProcess import ShellProcess
-from lnst.Common.Utils import std_deviation, is_installed
+from lnst.Common.Utils import std_deviation, is_installed, bool_it
class Netperf(TestGeneric):
@@ -34,6 +34,8 @@ 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._loc_cpu_util = self.get_opt("loc_cpu_util", default=False)
+ self._rem_cpu_util = self.get_opt("rem_cpu_util", default=False)
self._runs = self.get_opt("runs", default=1)
if self._runs > 1 and self._confidence is not None:
@@ -61,7 +63,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 +92,26 @@ class Netperf(TestGeneric):
"""
cmd += " -I %s" % self._confidence
+ if bool_it(self._loc_cpu_util):
+ """
+ measure local CPU utilization
+ """
+ cmd += " -c"
+
+ if bool_it(self._rem_cpu_util):
+ """
+ measure remote CPU utilization
+ """
+ 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,
THROUGHPUT_CONFID"'
+
elif self._role == "server":
cmd = "netserver -D"
if self._bind is not None:
@@ -114,58 +132,44 @@ 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 bool_it(self._loc_cpu_util):
+ pattern_loc_cpu_util = "LOCAL_CPU_UTIL=([-]?\d+\.\d+)"
+ loc_cpu_util = re.search(pattern_loc_cpu_util, output)
+ res_val["loc_cpu_util"] = float(loc_cpu_util.group(1))
+
+ if bool_it(self._rem_cpu_util):
+ pattern_rem_cpu_util = "REMOTE_CPU_UTIL=([-]?\d+\.\d+)"
+ rem_cpu_util = re.search(pattern_rem_cpu_util, output)
+ res_val["rem_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+)"
+ throughput_confid = float(re.search(pattern_throughput_confid,
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 = (throughput_confid, throughput_confid/2)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
You've changed the semantics of this tuple compared to what we had
before. We set the confidence for Netperf for e.g. -I 99,5 which
translates to 99% confidence that the result is within +-2.5% around the
average throughput and Netperf reported the average giving us
information about the achieved confidence for e.g. "I'm 99% confident
that the result is within +-7.2% aroung the measured average" which we
returned in the real_confidence tuple as (99, 7.2). What you've done is
that you're returning (14.4, 7.2), effectively redundantly reporting the
same information twice.
NACK until this is fixed.
return real_confidence
@@ -216,7 +220,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(a)lists.fedorahosted.org
https://lists.fedorahosted.org/mailman/listinfo/lnst-developers