Re: [PATCH 1/8] test: Allow aggpercpu test to omit some CPUs

Kris Van Hees
2024-08-19T23:12:05Z

On Tue, Jun 04, 2024 at 02:00:01PM -0400, eugene.loh@oracle.com wrote:
> From: Eugene Loh <eugene.loh@oracle.com>
>
> The aggpercpu test uses profile-* to fire aggregations on every CPU.
> But whether for good (offline CPUs) or bad (unreliable probe) reasons,
> a CPU might not aggregate any values.
>
> Allow this test to skip over such CPUs. That is, while a BPF agg map
> might have the correct default value for the aggregation function, it
> may not see any anticipated data. The quality of profile-* probes
> should be checked by a different test.
>
> Also, when computing avg() and stddev() in the awk check program,
> truncate results to ints more often to mimic the algorithms in DTrace
> for more robust checks.
>
> Signed-off-by: Eugene Loh <eugene.loh@oracle.com>

Reviewed-by: Kris Van Hees <kris.van.hees@oracle.com>

> ---
> test/unittest/aggs/tst.aggpercpu.sh | 62 +++++++++++++++++++++--------
> 1 file changed, 45 insertions(+), 17 deletions(-)
>
> diff --git a/test/unittest/aggs/tst.aggpercpu.sh b/test/unittest/aggs/tst.aggpercpu.sh
> index be74890a..6092bd17 100755
> --- a/test/unittest/aggs/tst.aggpercpu.sh
> +++ b/test/unittest/aggs/tst.aggpercpu.sh
> @@ -46,7 +46,8 @@ fi
> awk '
> # The expected value for the aggregation is aggval.
> # The expected value on a CPU is (m * cpu + b).
> - function check(label, aggval, m, b) {
> + # The default value on a CPU that did not fire is defval.
> + function check(label, aggval, m, b, defval) {
> # Check the aggregation over all CPUs.
> getline;
> print "check:", $0;
> @@ -54,12 +55,38 @@ awk '
>
> # Check the per-CPU values.
> for (i = 1; i <= ncpu; i++) {
> - getline;
> - print "check:", $0;
> - if (match($0, "^ \\[CPU ") != 1 ||
> - strtonum($2) != cpu[i] ||
> - strtonum($3) != m * cpu[i] + b)
> - printf("ERROR: %s, agg per cpu %d, line: %s\n", label, cpu[i], $0);
> + do {
> + getline;
> + print "check:", $0;
> +
> + # pass is +1 for pass, -1 for error, 0 for skip CPU
> + pass = 0;
> +
> + if (match($0, "^ \\[CPU ") != 1) {
> + print "ERROR: no CPU to read"
> + pass = -1;
> + } else if (strtonum($2) > cpu[i]) {
> + print "ERROR: skipped over expected CPU"
> + pass = -1;
> + } else if (strtonum($2) == cpu[i]) {
> + if (strtonum($3) != m * cpu[i] + b) {
> + print "ERROR: wrong value"
> + pass = -1;
> + } else {
> + # right value
> + pass = +1;
> + }
> + } else if ($3 != defval) {
> + print "ERROR: wrong default value"
> + pass = -1;
> + } else {
> + # skip over CPU that apparently did not fire
> + pass = 0;
> + }
> +
> + if (pass == -1)
> + printf("ERROR: %s, agg per cpu %d, line: %s\n", label, cpu[i], $0);
> + } while (pass == 0);
> }
> }
>
> @@ -99,13 +126,14 @@ awk '
> {
> # First we finish computing our estimates for avg and stddev.
> # (The other results require no further action.)
> + # (We keep truncating to ints to mimic DTrace algorithms.)
>
> - xavg /= xcnt;
> + xavg /= xcnt; xavg = int(xavg);
>
> - xstm /= xcnt;
> - xstd /= xcnt;
> + xstm /= xcnt; xstm = int(xstm);
> + xstd /= xcnt; xstd = int(xstd);
> xstd -= xstm * xstm;
> - xstd = int(sqrt(xstd));
> + xstd = sqrt(xstd); xstd = int(xstd);
>
> # Sort the cpus.
>
> @@ -113,12 +141,12 @@ awk '
>
> # Now read the results and compare.
>
> - check("cnt", xcnt, 0, 1);
> - check("avg", xavg, 10, 3);
> - check("std", xstd, 0, 0);
> - check("min", xmin, 30, -10);
> - check("max", xmax, 40, -15);
> - check("sum", xsum, 50, 0);
> + check("cnt", xcnt, 0, 1, "0");
> + check("avg", xavg, 10, 3, "0");
> + check("std", xstd, 0, 0, "0");
> + check("min", xmin, 30, -10, "9223372036854775807");
> + check("max", xmax, 40, -15, "-9223372036854775808");
> + check("sum", xsum, 50, 0, "0");
>
> printf("done\n");
> }
> --
> 2.18.4
>