From: Bruce McCulloch <bruce.mcculloch@oracle.com>
To: dwarves@vger.kernel.org
Cc: elena.zannoni@oracle.com, Bruce McCulloch <bruce.mcculloch@oracle.com>
Subject: [PATCHv3 dwarves] Refactor selftests
Date: Mon, 9 Mar 2026 13:56:44 -0700 [thread overview]
Message-ID: <20260309205643.1985134-2-bruce.mcculloch@oracle.com> (raw)
Hello,
Here is a rebased version of the patch that is in line with upstream,
and contains gcc_true_signatures,sh. Sorry about the mixup on this one,
someone should probably sync the github sometime soon :-).
Bruce
---
Simple refactoring of the testsuite with the creation of a shared
library (tests/test_lib.sh).
Additions include:
* Getters to find vmlinux.
* Functions to open tmp dirs and tmp files.
* Functions to automatically clean tmp dirs and files on pass.
* On fail, tmp dirs are preserved.
* Functions to pass/fail/skip/softfail tests (works with CI).
* Logging functions with varying verbosity levels.
* Compatible with non-bash interpreters (for perf tests).
* Colors.
Signed-off-by: Bruce McCulloch <bruce.mcculloch@oracle.com>
---
tests/btf_functions.sh | 143 ++++++++++----------------
tests/default_vmlinux_btf.sh | 18 ++--
tests/flexible_arrays.sh | 48 +++++----
tests/gcc_true_signatures.sh | 48 +++------
tests/pfunct-btf-decl-tags.sh | 34 ++++---
tests/prettify_perf.data.sh | 51 ++++++----
tests/reproducible_build.sh | 47 ++++-----
tests/test_lib.sh | 182 ++++++++++++++++++++++++++++++++++
tests/tests | 28 +++---
9 files changed, 367 insertions(+), 232 deletions(-)
create mode 100755 tests/test_lib.sh
diff --git a/tests/btf_functions.sh b/tests/btf_functions.sh
index ee0f9ff..127640e 100755
--- a/tests/btf_functions.sh
+++ b/tests/btf_functions.sh
@@ -8,45 +8,22 @@
# also should have been.
#
-outdir=
-
-fail()
-{
- # Do not remove test dir; might be useful for analysis
- trap - EXIT
- if [[ -d "$outdir" ]]; then
- echo "Test data is in $outdir"
- fi
- exit 1
-}
-
-cleanup()
-{
- rm ${outdir}/*
- rmdir $outdir
-}
-
-vmlinux=${vmlinux:-$1}
-
-if [ -z "$vmlinux" ] ; then
- vmlinux=$(pahole --running_kernel_vmlinux)
- if [ -z "$vmlinux" ] ; then
- echo "Please specify a vmlinux file to operate on"
- exit 2
- fi
-fi
+source test_lib.sh
-if [ ! -f "$vmlinux" ] ; then
- echo "$vmlinux file not available, please specify another"
- exit 2
+vmlinux=$(get_vmlinux $1)
+if [ $? -ne 0 ] ; then
+ info_log "$vmlinux"
+ test_fail
fi
-outdir=$(mktemp -d /tmp/btf_functions.sh.XXXXXX)
+outdir=$(make_tmpdir)
+# Comment this out to save test data.
trap cleanup EXIT
-echo -n "Validation of BTF encoding of functions; this may take some time: "
-test -n "$VERBOSE" && printf "\nEncoding..."
+title_log "Validation of BTF encoding of functions."
+info_log "This may take some time."
+verbose_log "Encoding..."
# Here we use both methods so that we test pahole --lang_exclude, that is
# used in the Linux kernel BTF encoding phase, and as well to make sure all
@@ -57,7 +34,7 @@ export PAHOLE_LANG_EXCLUDE=rust
pahole --btf_features=default --lang_exclude=rust --btf_encode_detached=$outdir/vmlinux.btf --verbose $vmlinux |\
grep "skipping BTF encoding of function" > ${outdir}/skipped_fns
-test -n "$VERBOSE" && printf "done.\n"
+verbose_log "done."
funcs=$(pfunct --format_path=btf $outdir/vmlinux.btf 2>/dev/null|sort)
@@ -87,8 +64,8 @@ while IFS= read -r btf ; do
if [[ "$dwarf_noconst" =~ "$btf_noconst" ]]; then
const_insensitive=$((const_insensitive+1))
else
- echo "ERROR: mismatch : BTF '$btf' not found; DWARF '$dwarf'"
- fail
+ error_log "ERROR: mismatch : BTF '$btf' not found; DWARF '$dwarf'"
+ test_fail
fi
else
inline=$((inline+1))
@@ -98,13 +75,11 @@ while IFS= read -r btf ; do
fi
done < $outdir/btf.funcs
-if [[ -n "$VERBOSE" ]]; then
- echo "Matched $exact functions exactly."
- echo "Matched $inline functions with inlines."
- echo "Matched $const_insensitive functions with multiple const/non-const instances."
- echo "Ok"
- echo "Validation of skipped function logic..."
-fi
+verbose_log "Matched $exact functions exactly."
+verbose_log "Matched $inline functions with inlines."
+verbose_log "Matched $const_insensitive functions with multiple const/non-const instances."
+verbose_log "Ok"
+verbose_log "Validation of skipped function logic..."
skipped_cnt=$(wc -l ${outdir}/skipped_fns | awk '{ print $1}')
@@ -113,16 +88,14 @@ for s in $skipped_fns ; do
# Ensure the skipped function are not in BTF
inbtf=$(grep " $s(" $outdir/btf.funcs)
if [[ -n "$inbtf" ]]; then
- echo "ERROR: '${s}()' was added incorrectly to BTF: '$inbtf'"
- fail
+ error_log "ERROR: '${s}()' was added incorrectly to BTF: '$inbtf'"
+ test_fail
fi
done
-if [[ -n "$VERBOSE" ]]; then
- echo "Skipped encoding $skipped_cnt functions in BTF."
- echo "Ok"
- echo "Validating skipped functions have incompatible return values..."
-fi
+verbose_log "Skipped encoding $skipped_cnt functions in BTF."
+verbose_log "Ok"
+verbose_log "Validating skipped functions have incompatible return values..."
return_mismatches=$(awk '/return type mismatch/ { print $1 }' $outdir/skipped_fns)
return_count=0
@@ -134,17 +107,15 @@ for r in $return_mismatches ; do
| uniq > ${outdir}/retvals.$r
cnt=$(wc -l ${outdir}/retvals.$r | awk '{ print $1 }')
if [[ $cnt -lt 2 ]]; then
- echo "ERROR: '${r}()' has only one return value; it should not be reported as having incompatible return values"
- fail
+ error_log "ERROR: '${r}()' has only one return value; it should not be reported as having incompatible return values"
+ test_fail
fi
return_count=$((return_count+1))
done
-if [[ -n "$VERBOSE" ]]; then
- echo "Found $return_count functions with multiple incompatible return values."
- echo "Ok"
- echo "Validating skipped functions have incompatible params/counts..."
-fi
+verbose_log "Found $return_count functions with multiple incompatible return values."
+verbose_log "Ok"
+verbose_log "Validating skipped functions have incompatible params/counts..."
param_mismatches=$(awk '/due to param / { print $1 }' $outdir/skipped_fns)
@@ -169,10 +140,8 @@ for p in $param_mismatches ; do
if [[ -n "$inlined" ]]; then
multiple_inline=$((multiple_inline+1))
else
- if [[ -n "$VERBOSE" ]]; then
- echo "WARN: '${p}()' has only one prototype; if it was subject to late optimization, pfunct may not reflect inconsistencies pahole found."
- echo "Full skip message from pahole: $skipmsg"
- fi
+ verbose_log "WARN: '${p}()' has only one prototype; if it was subject to late optimization, pfunct may not reflect inconsistencies pahole found."
+ verbose_log "Full skip message from pahole: $skipmsg"
warnings=$((warnings+1))
fi
else
@@ -180,24 +149,22 @@ for p in $param_mismatches ; do
fi
done
-if [[ -n "$VERBOSE" ]]; then
- echo "Found $multiple instances with multiple instances with incompatible parameters."
- echo "Found $multiple_inline instances where inline functions were not inlined and had incompatible parameters."
- echo "Found $optimized instances where the function name suggests optimizations led to inconsistent parameters."
- echo "Found $warnings instances where pfunct did not notice inconsistencies."
-fi
+verbose_log "Found $multiple instances with multiple instances with incompatible parameters."
+verbose_log "Found $multiple_inline instances where inline functions were not inlined and had incompatible parameters."
+verbose_log "Found $optimized instances where the function name suggests optimizations led to inconsistent parameters."
+verbose_log "Found $warnings instances where pfunct did not notice inconsistencies."
# Some specific cases can not be tested directly with a standard kernel.
# We can use the small binary in bin/ to test those cases, like packed
# structs passed on the stack.
-test -n "$VERBOSE" && echo -n "Validation of BTF encoding corner cases with test_bin functions; this may take some time: "
+verbose_log "Validation of BTF encoding corner cases with test_bin functions; this may take some time: "
-test -n "$VERBOSE" && printf "\nBuilding test_bin..."
+verbose_log "Building test_bin..."
tests_dir=$(realpath $(dirname $0))
make -C ${tests_dir}/bin >/dev/null
-test -n "$VERBOSE" && printf "\nEncoding..."
+verbose_log "Encoding..."
pahole --btf_features=default --lang_exclude=rust --btf_encode_detached=$outdir/test_bin.btf \
--verbose ${tests_dir}/bin/test_bin | grep "skipping BTF encoding of function" \
> ${outdir}/test_bin_skipped_fns
@@ -214,18 +181,16 @@ while IFS= read -r btf ; do
# specifically tailored for tests
dwarf=$(grep -F "$btf" $outdir/test_bin_dwarf.funcs)
if [[ "$btf" != "$dwarf" ]]; then
- echo "ERROR: mismatch : BTF '$btf' not found; DWARF '$dwarf'"
- fail
+ error_log "ERROR: mismatch : BTF '$btf' not found; DWARF '$dwarf'"
+ test_fail
else
exact=$((exact+1))
fi
done < $outdir/test_bin_btf.funcs
-if [[ -n "$VERBOSE" ]]; then
- echo "Matched $exact functions exactly."
- echo "Ok"
- echo "Validation of skipped function logic..."
-fi
+verbose_log "Matched $exact functions exactly."
+verbose_log "Ok"
+verbose_log "Validation of skipped function logic..."
skipped_cnt=$(wc -l ${outdir}/test_bin_skipped_fns | awk '{ print $1}')
@@ -234,16 +199,14 @@ for s in $skipped_fns ; do
# Ensure the skipped function are not in BTF
inbtf=$(grep " $s(" $outdir/test_bin_btf.funcs)
if [[ -n "$inbtf" ]]; then
- echo "ERROR: '${s}()' was added incorrectly to BTF: '$inbtf'"
- fail
+ error_log "ERROR: '${s}()' was added incorrectly to BTF: '$inbtf'"
+ test_fail
fi
done
-if [[ -n "$VERBOSE" ]]; then
- echo "Skipped encoding $skipped_cnt functions in BTF."
- echo "Ok"
- echo "Validating skipped functions have uncertain parameter location..."
-fi
+verbose_log "Skipped encoding $skipped_cnt functions in BTF."
+verbose_log "Ok"
+verbose_log "Validating skipped functions have uncertain parameter location..."
uncertain_loc=$(awk '/due to uncertain parameter location/ { print $1 }' $outdir/test_bin_skipped_fns)
legitimate_skip=0
@@ -266,12 +229,10 @@ for f in $uncertain_loc ; do
fi
fi
done
- echo "ERROR: '${f}()' should not have been skipped; it has no parameter with uncertain location"
- fail
+ error_log "ERROR: '${f}()' should not have been skipped; it has no parameter with uncertain location"
+ test_fail
done
-if [[ -n "$VERBOSE" ]]; then
- echo "Found ${legitimate_skip} legitimately skipped function due to uncertain loc"
-fi
-echo "Ok"
-exit 0
+verbose_log "Found ${legitimate_skip} legitimately skipped function due to uncertain loc"
+
+test_pass
diff --git a/tests/default_vmlinux_btf.sh b/tests/default_vmlinux_btf.sh
index a855ca7..496e840 100755
--- a/tests/default_vmlinux_btf.sh
+++ b/tests/default_vmlinux_btf.sh
@@ -1,6 +1,7 @@
#!/bin/bash
+source test_lib.sh
-echo -n "Default BTF on a system without BTF: "
+title_log "Default BTF on a system without BTF."
ulimit -c 0
@@ -13,8 +14,7 @@ ulimit -c 0
nr_lines=$(PAHOLE_VMLINUX_BTF_FILENAME=foobar pahole -F btf list_head 2>&1 | wc -l)
if [ $nr_lines -eq 0 ] ; then
- echo "FAILED"
- exit 1
+ test_softfail
fi
# There is also the case where no debugging info is available, be it DWARF of
@@ -22,11 +22,15 @@ fi
# that as well
#
nr_lines=$(PAHOLE_VMLINUX_BTF_FILENAME=foobar pahole 2>&1 | wc -l)
+nr_lines=0
if [ $nr_lines -eq 0 ] ; then
- echo "FAILED"
- exit 1
+ test_softfail
fi
-echo "Ok"
-exit 0
+check_softfail
+if [ $? -eq 2 ] ; then
+ test_fail
+else
+ test_pass
+fi
\ No newline at end of file
diff --git a/tests/flexible_arrays.sh b/tests/flexible_arrays.sh
index 59fa38e..4e9e995 100755
--- a/tests/flexible_arrays.sh
+++ b/tests/flexible_arrays.sh
@@ -5,22 +5,23 @@
#
# Arnaldo Carvalho de Melo <acme@redhat.com> (C) 2024-
-vmlinux=${vmlinux:-$1}
+source test_lib.sh
-if [ -z "$vmlinux" ] ; then
- vmlinux=$(pahole --running_kernel_vmlinux)
+vmlinux=$(get_vmlinux $1)
+if [ $? -ne 0 ] ; then
+ info_log "$vmlinux"
+ test_fail
fi
-if [ ! -f "$vmlinux" ] ; then
- echo "$vmlinux file not available, please specify another"
- exit 2
-fi
+outdir=$(make_tmpdir)
-pretty=$(mktemp /tmp/flexible_arrays.data.sh.XXXXXX.c)
+# Comment this out to save test data.
+trap cleanup EXIT
-echo -n "Flexible arrays accounting: "
+title_log "Flexible arrays accounting."
for struct in $(pahole -F btf --sizes --with_embedded_flexible_array $vmlinux | cut -f1) ; do
+ pretty=$(make_tmpsrc)
pahole $struct $vmlinux > $pretty
# We need to check for just one tab before the comment as when expanding unnamed
@@ -48,30 +49,27 @@ for struct in $(pahole -F btf --sizes --with_embedded_flexible_array $vmlinux |
[ -z "$stat_nr_flexible_arrays" ] && stat_nr_flexible_arrays=0
stat_nr_embedded_flexible_arrays=$(grep "flexible array members:.*middle:" $pretty | sed -r 's/.*middle: *([[:digit:]]+).*/\1/g')
[ -z "$stat_nr_embedded_flexible_arrays" ] && stat_nr_embedded_flexible_arrays=0
- test -n "$VERBOSE" && echo "end: $struct: $nr_flexible_arrays $stat_nr_flexible_arrays"
- test -n "$VERBOSE" && echo "middle: $struct: $nr_embedded_flexible_arrays $stat_nr_embedded_flexible_arrays"
+ verbose_log "end: $struct: $nr_flexible_arrays $stat_nr_flexible_arrays"
+ verbose_log "middle: $struct: $nr_embedded_flexible_arrays $stat_nr_embedded_flexible_arrays"
if [ "$nr_embedded_flexible_arrays" != "$stat_nr_embedded_flexible_arrays" ] ; then
- test -n "$VERBOSE" && printf "struct %s: The number of embedded flexible arrays (%s) doesn't match the number of members marked as such (%s)\n" \
+ verbose_log "struct %s: The number of embedded flexible arrays (%s) doesn't match the number of members marked as such (%s)\n" \
"$struct" "$stat_nr_embedded_flexible_arrays" "$nr_embedded_flexible_arrays"
- test -n "$VERBOSE" && pahole $struct $vmlinux
- FAILED=1
+ verbose_log pahole $struct $vmlinux
+ test_softfail
fi
if [ "$nr_flexible_arrays" != "$stat_nr_flexible_arrays" ] ; then
- test -n "$VERBOSE" && printf "struct %s: The number of flexible arrays (%s) doesn't match the number of members marked as such (%s)\n" \
+ verbose_log printf "struct %s: The number of flexible arrays (%s) doesn't match the number of members marked as such (%s)\n" \
"$struct" "$stat_nr_flexible_arrays" "$nr_flexible_arrays"
- test -n "$VERBOSE" && pahole $struct $vmlinux
- FAILED=1
+ verbose_log pahole $struct $vmlinux
+ test_softfail
fi
-
- rm -f $pretty
done
-if [ -n "$FAILED" ] ; then
- echo "FAILED"
- exit 1
+check_softfail
+if [ $? -ne 0 ] ; then
+ test_fail
+else
+ test_pass
fi
-
-echo "Ok"
-exit 0
diff --git a/tests/gcc_true_signatures.sh b/tests/gcc_true_signatures.sh
index 57cbe3f..9ebe1fa 100755
--- a/tests/gcc_true_signatures.sh
+++ b/tests/gcc_true_signatures.sh
@@ -1,36 +1,21 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0-only
-outdir=
+source test_lib.sh
-fail()
-{
- # Do not remove test dir; might be useful for analysis
- trap - EXIT
- if [[ -d "$outdir" ]]; then
- echo "Test data is in $outdir"
- fi
- exit 1
-}
-
-cleanup()
-{
- rm ${outdir}/*
- rmdir $outdir
-}
-
-outdir=$(mktemp -d /tmp/gcc_true.sh.XXXXXX)
+outdir=$(make_tmpdir)
+# Comment this out to save test data.
trap cleanup EXIT
-echo -n "Validation of BTF encoding of true_signatures: "
+title_log "Validation of BTF encoding of true_signatures."
gcc_true="${outdir}/gcc_true"
CC=$(which gcc 2>/dev/null)
if [[ -z "$CC" ]]; then
- echo "skip: gcc not available"
- exit 2
+ info_log "skip: gcc not available"
+ test_skip
fi
cat > ${gcc_true}.c << EOF
@@ -63,30 +48,29 @@ EOF
CFLAGS="$CFLAGS -g -O2"
${CC} ${CFLAGS} -o $gcc_true ${gcc_true}.c
if [[ $? -ne 0 ]]; then
- echo "Could not compile ${gcc_true}.c" >& 2
- exit 1
+ error_log "Could not compile ${gcc_true}.c"
+ test_fail
fi
LLVM_OBJCOPY=objcopy pahole -J --btf_features=+true_signature $gcc_true
if [[ $? -ne 0 ]]; then
- echo "Could not encode BTF for $gcc_true"
- exit 1
+ error_log "Could not encode BTF for $gcc_true"
+ test_fail
fi
btf_optimized=$(pfunct --all --format_path=btf $gcc_true |grep "foo\.")
if [[ -z "$btf_optimized" ]]; then
- echo "skip: no optimizations applied."
- exit 2
+ info_log "skip: no optimizations applied."
+ test_skip
fi
# Convert foo.[constprop|isra].0 to foo to allow comparison.
btf_cmp="$(echo $btf_optimized \
awk '/foo/ {sub(/\.constprop.0/,""); sub(/\.isra.0/,""); print $0 }')"
dwarf=$(pfunct --all $gcc_true |grep "foo")
-test -n "$VERBOSE" && printf "\nBTF: $btf_optimized DWARF: $dwarf \n"
+verbose_log "BTF: $btf_optimized DWARF: $dwarf"
if [[ "$btf_cmp" == "$dwarf" ]]; then
- echo "BTF and DWARF signatures should be different and they are not: BTF: $btf_optimized ; DWARF $dwarf"
- exit 1
+ error_log "BTF and DWARF signatures should be different and they are not: BTF: $btf_optimized ; DWARF $dwarf"
+ test_fail
fi
-echo "Ok"
-exit 0
+test_pass
diff --git a/tests/pfunct-btf-decl-tags.sh b/tests/pfunct-btf-decl-tags.sh
index 69babef..35884b4 100755
--- a/tests/pfunct-btf-decl-tags.sh
+++ b/tests/pfunct-btf-decl-tags.sh
@@ -3,21 +3,24 @@
# Check that pfunct can print btf_decl_tags read from BTF
-tmpobj=$(mktemp /tmp/pfunct-btf-decl-tags.sh.XXXXXX.o)
+source test_lib.sh
-cleanup()
-{
- rm $tmpobj
-}
+outdir=$(make_tmpdir)
+tmpobj=$(make_tmpobj)
+# Comment this out to save test data.
trap cleanup EXIT
-echo -n "Check that pfunct can print btf_decl_tags read from BTF: "
+title_log "Check that pfunct can print btf_decl_tags read from BTF."
+
+# gcc now also supports decl tags as of gcc commit 43dcea48b8c,
+# in upstream version 16.
+# UPTODO: add a check here for that.
CLANG=${CLANG:-clang}
if ! command -v $CLANG > /dev/null; then
- echo "Need clang for test $0"
- exit 1
+ error_log "Need clang for test $0"
+ test_fail
fi
(cat <<EOF
@@ -55,13 +58,12 @@ out=$(pfunct -P -F btf $tmpobj | awk "$sort_tags" | sort)
d=$(diff -u <(echo "$expected") <(echo "$out"))
if [[ "$d" == "" ]]; then
- echo "Ok"
- exit 0
+ test_pass
else
- echo "pfunct output does not match expected:"
- echo "$d"
- echo
- echo "Complete output:"
- echo "$out"
- exit 1
+ error_log "pfunct output does not match expected:"
+ info_log "$d"
+ info_log
+ info_log "Complete output:"
+ info_log "$out"
+ test_fail
fi
diff --git a/tests/prettify_perf.data.sh b/tests/prettify_perf.data.sh
index 2d16cf5..1fae951 100755
--- a/tests/prettify_perf.data.sh
+++ b/tests/prettify_perf.data.sh
@@ -7,30 +7,35 @@
# Check if the perf binary is available, if it is from a distro, normally it
# will get the needed DWARF info using libddebuginfod, we'll check if the
# needed types are available, skipping the test and informing the reason.
+. ./test_lib.sh
-echo -n "Pretty printing of files using DWARF type information: "
+outdir=$(make_tmpdir)
+
+# Comment this out to save test data.
+trap cleanup EXIT
+
+title_log "Pretty printing of files using DWARF type information."
perf=$(which perf 2> /dev/null)
if [ -z "$perf" ] ; then
- echo "skip: No 'perf' binary available"
- exit 2
+ info_log "skip: No 'perf' binary available"
+ test_skip
fi
perf_lacks_type_info() {
local type_keyword=$1
local type_name=$2
if ! pahole -C $type_name $perf | grep -q "^$type_keyword $type_name {"; then
- echo "skip: $perf doesn't have '$type_keyword $type_name' type info"
- return 1
+ info_log "skip: $perf doesn't have '$type_keyword $type_name' type info"
+ test_skip
fi
- return 0
}
-perf_data=$(mktemp /tmp/prettify_perf.data.sh.XXXXXX.perf.data)
+perf_data=$(make_tmpfile)
-perf_lacks_type_info struct perf_event_header || exit 2
-perf_lacks_type_info enum perf_event_type || exit 2
-perf_lacks_type_info enum perf_user_event_type || exit 2
+perf_lacks_type_info struct perf_event_header
+perf_lacks_type_info enum perf_event_type
+perf_lacks_type_info enum perf_user_event_type
$perf record --quiet -o $perf_data sleep 0.00001
@@ -46,21 +51,23 @@ check_expected_number_of_filtered_perf_record_metadata() {
local nr_records=$(number_of_filtered_perf_record_metadata $metadata_record)
if [ "$nr_records" != "$expected_records" ] ; then
- echo "FAIL: expected $expected_records PERF_RECORD_$metadata_record metadata records, got $nr_records"
- return 1;
+ error_log "FAIL: expected $expected_records PERF_RECORD_$metadata_record metadata records, got $nr_records"
+ test_softfail
fi
- return 0
}
-check_expected_number_of_filtered_perf_record_metadata COMM 2 || exit 1
-check_expected_number_of_filtered_perf_record_metadata EXIT 1 || exit 1
-check_expected_number_of_filtered_perf_record_metadata TIME_CONV 1 || exit 1
-check_expected_number_of_filtered_perf_record_metadata THREAD_MAP 1 || exit 1
-check_expected_number_of_filtered_perf_record_metadata CPU_MAP 1 || exit 1
-check_expected_number_of_filtered_perf_record_metadata FINISHED_INIT 1 || exit 1
+check_expected_number_of_filtered_perf_record_metadata COMM 2
+check_expected_number_of_filtered_perf_record_metadata EXIT 1
+check_expected_number_of_filtered_perf_record_metadata TIME_CONV 1
+check_expected_number_of_filtered_perf_record_metadata THREAD_MAP 1
+check_expected_number_of_filtered_perf_record_metadata CPU_MAP 1
+check_expected_number_of_filtered_perf_record_metadata FINISHED_INIT 1
# XXX write more tests that look at the events contents, not just for the presence of a known number of them
-echo "Ok"
-
-rm -f $perf_data
+check_softfail
+if [ $? -ne 0 ] ; then
+ test_fail
+else
+ test_pass
+fi
diff --git a/tests/reproducible_build.sh b/tests/reproducible_build.sh
index a940d93..d8c6507 100755
--- a/tests/reproducible_build.sh
+++ b/tests/reproducible_build.sh
@@ -4,22 +4,22 @@
# Test if BTF generated serially matches reproducible parallel DWARF loading + serial BTF encoding
# Arnaldo Carvalho de Melo <acme@redhat.com> (C) 2024-
-vmlinux=${vmlinux:-$1}
+source test_lib.sh
-if [ -z "$vmlinux" ] ; then
- vmlinux=$(pahole --running_kernel_vmlinux)
+vmlinux=$(get_vmlinux $1)
+if [ $? -ne 0 ]; then
+ info_log "$vmlinux"
+ test_fail
fi
-if [ ! -f "$vmlinux" ] ; then
- echo "$vmlinux file not available, please specify another"
- exit 2
-fi
+outdir=$(make_tmpdir)
-outdir=$(mktemp -d /tmp/reproducible_build.sh.XXXXXX)
+# Comment this out to save test data.
+trap cleanup EXIT
-echo -n "Parallel reproducible DWARF Loading/Serial BTF encoding: "
+title_log "Parallel reproducible DWARF Loading/Serial BTF encoding."
-test -n "$VERBOSE" && printf "\nserial encoding...\n"
+verbose_log "Begin serial encoding..."
# This will make pahole and pfunct to skip rust CUs
export PAHOLE_LANG_EXCLUDE=rust
@@ -30,37 +30,32 @@ bpftool btf dump file $outdir/vmlinux.btf.serial > $outdir/bpftool.output.vmlinu
nr_proc=$(getconf _NPROCESSORS_ONLN)
for threads in $(seq $nr_proc) ; do
- test -n "$VERBOSE" && echo $threads threads encoding
+ verbose_log "$threads threads encoding"
pahole -j$threads --btf_features=default,reproducible_build --btf_encode_detached=$outdir/vmlinux.btf.parallel.reproducible $vmlinux &
pahole=$!
# HACK: Wait a bit for pahole to start its threads
- sleep 0.3s
+ sleep 1s
# PID part to remove ps output headers
nr_threads_started=$(ps -L -C pahole | grep -v PID | wc -l)
- ((nr_threads_started -= 1)) # main thread doesn't count, it waits to join
+ ((nr_threads_started -= 1)) # main thread doesn't count, it waits to join
if [ $threads != $nr_threads_started ] ; then
- echo "ERROR: pahole asked to start $threads encoding threads, started $nr_threads_started"
- exit 1;
+ error_log "ERROR: pahole asked to start $threads encoding threads, started $nr_threads_started"
+ test_fail
fi
# ps -L -C pahole | grep -v PID | nl
- test -n "$VERBOSE" && echo $nr_threads_started threads started
+ verbose_log "$nr_threads_started threads started"
wait $pahole
rm -f $outdir/bpftool.output.vmlinux.btf.parallel.reproducible
bpftool btf dump file $outdir/vmlinux.btf.parallel.reproducible > $outdir/bpftool.output.vmlinux.btf.parallel.reproducible
- test -n "$VERBOSE" && echo "diff from serial encoding:"
+ verbose_log "diff from serial encoding:"
diff -u $outdir/bpftool.output.vmlinux.btf.serial $outdir/bpftool.output.vmlinux.btf.parallel.reproducible > $outdir/diff
if [ -s $outdir/diff ] ; then
- echo "ERROR: BTF generated from DWARF in parallel is different from the one generated in serial!"
- exit 1
+ error_log "ERROR: BTF generated from DWARF in parallel is different from the one generated in serial!"
+ test_fail
fi
- test -n "$VERBOSE" && echo -----------------------------
+ verbose_log -----------------------------
done
-rm $outdir/*
-rmdir $outdir
-
-echo "Ok"
-
-exit 0
+test_pass
diff --git a/tests/test_lib.sh b/tests/test_lib.sh
new file mode 100755
index 0000000..fb72432
--- /dev/null
+++ b/tests/test_lib.sh
@@ -0,0 +1,182 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (c) 2026, Oracle and/or its affiliates.
+#
+# Common helper functions for the testsuite.
+#
+
+# if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
+# echo "This script is meant to be sourced. Please use 'source test_lib.sh'."
+# exit 1
+# fi
+
+check_color_support()
+{
+ if [ ! -z "$color_support" ] ; then
+ return $color_support
+ else
+ if tput colors >/dev/null 2>&1; then
+ num_colors=$(tput colors)
+ if [ $num_colors -gt 0 ] && [ -n "$BASH_VERSION" ] ; then
+ RED='\033[0;31m'
+ GREEN='\033[0;32m'
+ YELLOW='\033[0;33m'
+ NC='\033[0m'
+ color_support=1
+ else
+ RED=''
+ GREEN=''
+ YELLOW=''
+ NC=''
+ color_support=0
+ fi
+ else
+ RED=''
+ GREEN=''
+ YELLOW=''
+ NC=''
+ color_support=0
+ fi
+ fi
+ return $color_support
+}
+
+color_print()
+{
+ if [ $color_support -eq 1 ] ; then
+ echo -e "$1$2${NC}"
+ else
+ echo $1
+ fi
+}
+
+get_vmlinux()
+{
+
+ vmlinux=${vmlinux:-$1}
+
+ if [ -z "$vmlinux" ] ; then
+ vmlinux=$(pahole --running_kernel_vmlinux)
+ if [ -z "$vmlinux" ] ; then
+ check_color_support
+ color_print ${RED} "Please specify a vmlinux file to operate on"
+ exit 2
+ fi
+ fi
+
+ if [ ! -f "$vmlinux" ] ; then
+ echo ${RED} "$vmlinux file not available, please specify another"
+ exit 2
+ fi
+
+ echo $vmlinux
+ return 0
+}
+
+make_tmpdir()
+{
+ outdir=$(mktemp -d /tmp/$(basename "$0").XXXXXX)
+ echo $outdir
+ return 0
+}
+
+make_tmpobj()
+{
+ outobj=$(mktemp $outdir/$0.obj.XXXXXX.o)
+ echo $outobj
+ return 0
+}
+
+make_tmpsrc()
+{
+ outsrc=$(mktemp $outdir/$0.src.XXXXXX.c)
+ echo $outsrc
+ return 0
+}
+
+make_tmpfile()
+{
+ outfile=$(mktemp $outdir/$0.data.XXXXXX)
+ echo $outfile
+ return 0
+}
+
+info_log()
+{
+ printf " "
+ echo $1
+}
+
+title_log()
+{
+ check_color_support
+ color_print ${YELLOW} "$1"
+}
+
+verbose_log()
+{
+ if [[ -n "$VERBOSE" ]]; then
+ printf " "
+ echo $1
+ fi
+}
+
+error_log()
+{
+ printf " "
+ check_color_support
+ color_print $RED "${1}"
+}
+
+test_softfail()
+{
+ if [ -z "$softfail_count" ] ; then
+ softfail_count=1
+ else
+ softfail_count=$((softfail_count + 1))
+ fi
+}
+
+test_fail()
+{
+ trap - EXIT
+ check_color_support
+ color_print ${RED} "Test $0 failed"
+ if [ -d "$outdir" ]; then
+ color_print ${RED} "Test data is in $outdir"
+ fi
+ exit 1
+}
+
+check_softfail()
+{
+ if [ ! -z "$softfail_count" ] ; then
+ check_color_support
+ color_print ${RED} "Soft failures: $softfail_count"
+ return 1
+ else
+ return 0
+ fi
+}
+
+test_pass()
+{
+ check_color_support
+ color_print ${GREEN} "Test $0 passed"
+ exit 0
+}
+
+test_skip()
+{
+ check_color_support
+ color_print ${YELLOW} "Skipping test ..."
+ exit 2
+}
+
+cleanup()
+{
+ rm ${outdir}/*
+ rmdir $outdir
+ return 0
+}
diff --git a/tests/tests b/tests/tests
index 11921ad..b4116ce 100755
--- a/tests/tests
+++ b/tests/tests
@@ -8,19 +8,21 @@ cd $tests_dir
let status=0
let nr=1
for test in *.sh ; do
- printf "%3d: " $nr
- ./$test
- case $? in
- 0)
- ;;
- 2)
- echo "skipping..."
- ;;
- *)
- status=1
- ;;
- esac
- let nr+=1
+ if [ $test != "test_lib.sh" ]; then
+ printf "%d: $test\n" $nr
+ ./$test $1
+ case $? in
+ 0)
+ ;;
+ 2)
+ ;;
+ *)
+ status=1
+ ;;
+ esac
+ let nr+=1
+ echo "---"
+ fi
done
cd -
--
2.47.3
next reply other threads:[~2026-03-09 20:58 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-09 20:56 Bruce McCulloch [this message]
2026-03-10 10:38 ` [PATCHv3 dwarves] Refactor selftests Alan Maguire
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260309205643.1985134-2-bruce.mcculloch@oracle.com \
--to=bruce.mcculloch@oracle.com \
--cc=dwarves@vger.kernel.org \
--cc=elena.zannoni@oracle.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox