From ff2c03ef209b4412d00ec772dbdd6b02c5a3bae5 Mon Sep 17 00:00:00 2001 From: Frey Alfredsson Date: Sat, 6 Apr 2024 20:03:04 +0200 Subject: [PATCH 1/2] Added targeted missing plots to the unit tests Some of the test Flent files lack data for specific plots. This lack of data occurs either because the file did not include the parameter to create them or because the feature did not exist when it was created. The unit test framework ignores all plots that might lack data to ensure they will not fail when unintentional changes break these tests. However, this also means it will not catch changes that accidentally break them. This commit adds functionality to allow defining which plots should be omitted by the unit tests on a per-file basis, allowing testing of files that do include the plots. Signed-off-by: Frey Alfredsson --- unittests/test_plotters.py | 97 +++++++++++++++++++++++++++++++++++--- 1 file changed, 91 insertions(+), 6 deletions(-) diff --git a/unittests/test_plotters.py b/unittests/test_plotters.py index aad9e477..55ce9fd4 100644 --- a/unittests/test_plotters.py +++ b/unittests/test_plotters.py @@ -68,10 +68,86 @@ 'ytick.minor.size': 0, } -# Plots that may fail validation -PLOTS_MAY_FAIL = set(('tcp_cwnd', 'tcp_rtt', 'tcp_rtt_cdf', - 'tcp_rtt_box_combine', 'tcp_rtt_bar_combine', 'tcp_pacing', - 'all_scaled_delivery', 'tcp_delivery_rate', 'tcp_delivery_with_rtt')) +# Some flent test files intentionally lack plots. This list contains the empty +# plots to ensure that they do not fail. The lack of data is either because the +# test did not run with the required flag or because the file is simply older +# than the feature. +MISSING_PLOTS = { + 'test-http-1up.flent.gz': set(( + 'tcp_cwnd', + 'tcp_delivery_rate', + 'tcp_pacing', + 'tcp_rtt', + 'tcp_rtt_bar_combine', + 'tcp_rtt_box_combine', + 'tcp_rtt_cdf', + )), + 'test-http.flent.gz': set(( + 'tcp_cwnd', + 'tcp_delivery_rate', + 'tcp_pacing', + 'tcp_rtt', + 'tcp_rtt_bar_combine', + 'tcp_rtt_box_combine', + 'tcp_rtt_cdf', + )), + 'test-rrul-icmp.flent.gz': set(( + 'tcp_cwnd', + 'tcp_delivery_rate', + 'tcp_pacing', + 'tcp_rtt', + 'tcp_rtt_bar_combine', + 'tcp_rtt_box_combine', + 'tcp_rtt_cdf', + )), + 'test-rrul.flent.gz': set(( + 'tcp_delivery_rate', + 'tcp_pacing', + 'tcp_rtt_bar_combine', + 'tcp_rtt_box_combine', + 'tcp_rtt_cdf', + )), + 'test-rrul_be-socket_stats.flent.gz': set(( + 'tcp_rtt_bar_combine', + 'tcp_rtt_box_combine', + 'tcp_rtt_cdf', + )), + 'test-rtt-fair.flent.gz': set(( + 'tcp_cwnd', + 'tcp_delivery_rate', + 'tcp_pacing', + 'tcp_rtt', + 'tcp_rtt_bar_combine', + 'tcp_rtt_box_combine', + 'tcp_rtt_cdf', + )), + 'test-tcp_nup.flent.gz': set(( + 'tcp_delivery_rate', + 'tcp_pacing', + 'tcp_rtt_bar_combine', + 'tcp_rtt_box_combine', + 'tcp_rtt_cdf', + )), + 'test-voip-1up.flent.gz': set(( + 'tcp_cwnd', + 'tcp_delivery_rate', + 'tcp_pacing', + 'tcp_rtt', + 'tcp_rtt_bar_combine', + 'tcp_rtt_box_combine', + 'tcp_rtt_cdf', + )), + 'test-voip-rrul.flent.gz': set(( + 'tcp_cwnd', + 'tcp_delivery_rate', + 'tcp_pacing', + 'tcp_rtt', + 'tcp_rtt_bar_combine', + 'tcp_rtt_box_combine', + 'tcp_rtt_cdf', + )), +} + class PlottersTestCase(ForkingTestCase): @@ -235,7 +311,11 @@ def runTest(self): formatter = formatters.new(self.settings) formatter.format([r]) res, plen = formatter.verify() - if not res and p not in PLOTS_MAY_FAIL: + filename = os.path.basename(self.filename) + if filename in MISSING_PLOTS and p in MISSING_PLOTS[filename]: + continue + + if not res: raise self.failureException( "Verification of plot '%s' failed: %s" % (p, plen)) except self.failureException: @@ -279,7 +359,12 @@ def runTest(self): for p in self.settings.PLOTS.keys(): plot = pool.apply(plot_one, (self.settings, p, results)) res, plen = plot.verify() - if not res and p not in PLOTS_MAY_FAIL: + + filename = os.path.basename(self.filename) + if filename in MISSING_PLOTS and p in MISSING_PLOTS[filename]: + continue + + if not res: raise self.failureException( "Verification of plot '%s' failed: %s" % (p, plen)) From 594725353e05f69c8aff6098616412015bae450a Mon Sep 17 00:00:00 2001 From: Frey Alfredsson Date: Tue, 2 Apr 2024 13:20:20 +0200 Subject: [PATCH 2/2] Added support for per CPU core monitoring This commit adds multicore support to the stat_iterate.sh script and to the CpuStatsRunner. The previous script only read the first entry of the /proc/stat, which gave the average CPU usage for all cores. This modified script reads all cpu[0-9]+ records, including the average. It retains the output format of the original script; however, the implementation has some minor optimizations, which are not that significant due to how seldom the script runs. 1. It primarily relies on the awk command for the heavy lifting, making it easier to read. Awk handles reading the /proc/stat instead of the cat command. 2. The previous script used the seq command, which consumes more memory when multiple iterations occur. Awk handles this instead with a loop. I tested the script using gawk with and without the Posix compliance flag (-P), BusyBox v1.36.1 awk, and mawk 1.3.4. Signed-off-by: Frey Alfredsson --- flent/runners.py | 15 ++++-- flent/scripts/stat_iterate.sh | 49 +++++++++++++++--- flent/tests/cpu_stats.inc | 21 ++++++++ .../test-tcp_1up_noping-cpu_stats.flent.gz | Bin 0 -> 19576 bytes unittests/test_plotters.py | 11 ++++ 5 files changed, 83 insertions(+), 13 deletions(-) create mode 100644 unittests/test_data/test-tcp_1up_noping-cpu_stats.flent.gz diff --git a/flent/runners.py b/flent/runners.py index a5770e36..5a85a042 100644 --- a/flent/runners.py +++ b/flent/runners.py @@ -2326,9 +2326,12 @@ class CpuStatsRunner(ProcessRunner): separated by '\n---\n and a timestamp to be present in the form 'Time: xxxxxx.xxx' (e.g. the output of `date '+Time: %s.%N'`). + The first line is the total CPU load, and the following lines are the load of + each core. """ + time_re = re.compile(r"^Time: (?P\d+\.\d+)", re.MULTILINE) - value_re = re.compile(r"^\d+ \d+ (?P\d+\.\d+)$", re.MULTILINE) + value_re = re.compile(r"^cpu(?P\d+)?: (?P\d+\.\d+)", re.MULTILINE) def __init__(self, interval, length, host='localhost', **kwargs): self.interval = interval @@ -2341,8 +2344,6 @@ def parse(self, output, error): raw_values = [] metadata = {} for part in self.split_stream(output): - # Split out individual qdisc entries (in case there are more than - # one). If so, discard the root qdisc and sum the rest. timestamp = self.time_re.search(part) if timestamp is None: continue @@ -2351,10 +2352,14 @@ def parse(self, output, error): if value is None: continue + matches = {} - for k, v in list(value.groupdict().items()): - v = float(v) + for m in self.value_re.finditer(part): + core_nr = m.group("core_nr") + load = m.group("load") + k = f'cpu{core_nr}' if core_nr is not None else 'load' + v = float(load) if k not in matches: matches[k] = v else: diff --git a/flent/scripts/stat_iterate.sh b/flent/scripts/stat_iterate.sh index 087580fc..8bd03576 100755 --- a/flent/scripts/stat_iterate.sh +++ b/flent/scripts/stat_iterate.sh @@ -14,17 +14,50 @@ done # $5 is IDLE, $6 is IOWAIT; we count both as idle time command_string=$(cat <0) {print \$5+\$6-idle " " sum-total " " 1-(\$5+\$6-idle)/(sum-total);} - idle=\$5+\$6; total=sum - } -\$1 == "Time:" { print "---\n" \$0 }' +set -o noglob +awk -v COUNT=$count -v INTERVAL=$interval ' +function get_cpu_usage(count) { + FS = " "; + IDLE_FIELD = 5; + IOWAIT_FIELD = 6; + PROC_CPU = "/proc/stat"; + while ((getline < PROC_CPU) > 0) { + if (\$0 !~ /^cpu/) + break; + cpu_idle_prev[\$1] = cpu_idle[\$1]; + cpu_total_prev[\$1] = cpu_total[\$1]; + cpu_idle[\$1] = 0; + cpu_total[\$1] = 0; + for (i = 2; i <= NF; i++) { + if (i == IDLE_FIELD || i == IOWAIT_FIELD) + cpu_idle[\$1] += \$i; + cpu_total[\$1] += \$i; + } + idle = cpu_idle[\$1] - cpu_idle_prev[\$1]; + total = cpu_total[\$1] - cpu_total_prev[\$1]; + cpu_usage = (total != 0) ? (1 - (idle / total)) : 0 + if (count) + printf("%s: %f\n", \$1, cpu_usage); + } + close(PROC_CPU); +} + +BEGIN { + date_cmd = "date \"+Time: %s.%N\"" + for (loop = 0; loop < COUNT; loop++) { + print("---"); + (date_cmd) | getline date; + print(date); + close(date_cmd); + get_cpu_usage(loop); + system("sleep " INTERVAL); + } +}' EOF ) if [ "$host" == "localhost" ]; then - eval $command_string + eval "$command_string" else - echo $command_string | ssh $host sh + echo "$command_string" | ssh "$host" sh fi diff --git a/flent/tests/cpu_stats.inc b/flent/tests/cpu_stats.inc index c67af13a..6875eda6 100644 --- a/flent/tests/cpu_stats.inc +++ b/flent/tests/cpu_stats.inc @@ -14,6 +14,7 @@ for host in CPU_STATS_HOSTS: if CPU_STATS_HOSTS: + # Average CPU load PLOTS['cpu'] = {'description': 'CPU stats', 'type': 'timeseries', 'axis_labels': ['Load'], @@ -26,6 +27,7 @@ if CPU_STATS_HOSTS: PLOTS['cpu_box'] = {'description': 'CPU stats (box plot)', 'type': 'box', 'parent': 'cpu'} + PLOTS['cpu_bar'] = {'description': 'CPU stats (bar plot)', 'type': 'bar', 'parent': 'cpu'} @@ -42,3 +44,22 @@ if CPU_STATS_HOSTS: PLOTS['cpu_bar_combine'] = {'description': 'CPU stats (bar combine plot)', 'type': 'bar_combine', 'parent': 'cpu_box_combine'} + + + # Per core CPU load + PLOTS['cpu_core'] = {'description': 'Per core CPU stats', + 'type': 'timeseries', + 'axis_labels': ['Load'], + 'series': [ + {'data': glob('cpu_stats_*'), + 'raw_key': glob('cpu*'), + 'label': 'CPU core load'}, + ]} + + PLOTS['cpu_core_box'] = {'description': 'Per core CPU stats (box plot)', + 'type': 'box', + 'parent': 'cpu_core'} + + PLOTS['cpu_core_bar'] = {'description': 'Per core CPU stats (bar plot)', + 'type': 'bar', + 'parent': 'cpu_core'} diff --git a/unittests/test_data/test-tcp_1up_noping-cpu_stats.flent.gz b/unittests/test_data/test-tcp_1up_noping-cpu_stats.flent.gz new file mode 100644 index 0000000000000000000000000000000000000000..6d404e8ec09db85bb72b9857bd9ce5e9e5f08ec8 GIT binary patch literal 19576 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 I5i(u^09#&Z8~^|S literal 0 HcmV?d00001 diff --git a/unittests/test_plotters.py b/unittests/test_plotters.py index 55ce9fd4..60b57e21 100644 --- a/unittests/test_plotters.py +++ b/unittests/test_plotters.py @@ -101,6 +101,9 @@ 'tcp_rtt_cdf', )), 'test-rrul.flent.gz': set(( + 'cpu_core', + 'cpu_core_bar', + 'cpu_core_box', 'tcp_delivery_rate', 'tcp_pacing', 'tcp_rtt_bar_combine', @@ -128,6 +131,14 @@ 'tcp_rtt_box_combine', 'tcp_rtt_cdf', )), + 'test-tcp_1up_noping-cpu_stats.flent.gz': set(( + 'tcp_cwnd', + 'tcp_pacing', + 'tcp_rtt', + 'tcp_rtt_cdf', + 'tcp_rtt_box_combine', + 'tcp_rtt_bar_combine', + )), 'test-voip-1up.flent.gz': set(( 'tcp_cwnd', 'tcp_delivery_rate',