2015-11-10 17:44 GMT+01:00 Jan Tluka <jtluka(a)redhat.com>:
Tue, Nov 10, 2015 at 05:11:41PM CET, jprochaz(a)redhat.com wrote:
>2015-11-10 15:51 GMT+01:00 Jan Tluka <jtluka(a)redhat.com>:
>
>> Mon, Nov 09, 2015 at 11:07:44AM CET, jprochaz(a)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(a)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(a)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(a)redhat.com
>Red Hat Czech | Purkyňova 71/99, 612 00 Brno
--
Best regards,
Jiri Prochazka
LNST Developer
|
www.lnst-project.org
+420 532 294 633 | jprochaz(a)redhat.com
Red Hat Czech | Purkyňova 71/99, 612 00 Brno