* [PATCH] test/suites: clean up per-test directories
@ 2026-07-03 14:42 Marat Khalili
2026-07-03 15:49 ` Stephen Hemminger
2026-07-03 17:17 ` [PATCH v2] " Marat Khalili
0 siblings, 2 replies; 3+ messages in thread
From: Marat Khalili @ 2026-07-03 14:42 UTC (permalink / raw)
Cc: dev, thomas, stephen
After commit 5ef166838394 ("test: add file-prefix for all fast-tests on
Linux") each test within a suite has its own --file-prefix filled with
the test name to enable parallel execution. It brought a couple of
drawbacks though:
* Solution only applied to one test suite.
* Each working directory occupied ~25MB, with hundreds of tests this
easily overfilled /run filesystems of small VMs. Currently executing
fast-tests suite consumes 2.8GB of RAM, and adding more tests created
problems for github CI.
* While it enabled parallel execution of tests within a single build
directory, --file-prefix argument could no longer be specified
externally (caused duplicate argument error). Specifying custom
--file-prefix was necessary when multiple builds ran in the same
environment, so the corresponding workflow became broken.
Move --file-prefix logic into a separate shell script, preserving
existing argument and cleaning the work directory after the test.
Apply it uniformly to all tests.
Signed-off-by: Marat Khalili <marat.khalili@huawei.com>
---
app/test/suites/meson.build | 34 ++++----
app/test/suites/run_test_with_temp_prefix.sh | 82 ++++++++++++++++++++
2 files changed, 102 insertions(+), 14 deletions(-)
create mode 100755 app/test/suites/run_test_with_temp_prefix.sh
diff --git a/app/test/suites/meson.build b/app/test/suites/meson.build
index 786c459c24b3..3d75a8a66924 100644
--- a/app/test/suites/meson.build
+++ b/app/test/suites/meson.build
@@ -23,6 +23,16 @@ if not has_hugepage
endif
endif
+if is_linux
+ # use wrapper providing per-test work directories to allow parallel runs
+ test_args_prefix = [dpdk_test]
+ dpdk_test = find_program('run_test_with_temp_prefix.sh')
+ dpdk_test_as_arg = dpdk_test.full_path()
+else
+ test_args_prefix = []
+ dpdk_test_as_arg = dpdk_test
+endif
+
# process source files to determine the different unit test suites
# - fast_tests
# - perf_tests
@@ -42,6 +52,7 @@ foreach suite:test_suites
warning('Test "@0@" is not defined in any test suite'.format(t))
endif
test(t, dpdk_test,
+ args: test_args_prefix,
env: ['DPDK_TEST=' + t],
timeout: timeout_seconds,
is_parallel: false)
@@ -49,6 +60,7 @@ foreach suite:test_suites
elif suite_name == 'stress-tests'
foreach t: suite_tests
test(t, dpdk_test,
+ args: test_args_prefix,
env: ['DPDK_TEST=' + t],
timeout: timeout_seconds_stress,
is_parallel: false,
@@ -58,6 +70,7 @@ foreach suite:test_suites
# simple cases - tests without parameters or special handling
foreach t: suite_tests
test(t, dpdk_test,
+ args: test_args_prefix,
env: ['DPDK_TEST=' + t],
timeout: timeout_seconds,
is_parallel: false,
@@ -81,7 +94,7 @@ foreach suite:test_suites
nohuge = params[1] == 'NOHUGE_OK'
asan = params[2] == 'ASAN_OK'
- test_args = []
+ test_args = test_args_prefix
if nohuge
test_args += test_no_huge_args
elif not has_hugepage
@@ -94,25 +107,17 @@ foreach suite:test_suites
test_args += ['-d', dpdk_drivers_build_dir]
endif
- # use unique file-prefix to allow parallel runs
- file_prefix = []
- trace_prefix = []
- if is_linux
- file_prefix = ['--file-prefix=' + test_name.underscorify()]
- trace_prefix = [file_prefix[0] + '_with_traces']
- endif
-
test(test_name, dpdk_test,
- args : test_args + file_prefix,
+ args: test_args,
env: ['DPDK_TEST=' + test_name],
timeout : timeout_seconds_fast,
is_parallel : false,
suite : 'fast-tests')
if not is_windows and test_name == 'trace_autotest'
- trace_extra = ['--trace=.*',
- '--trace-dir=@0@'.format(meson.current_build_dir())]
+ test_args += ['--trace=.*']
+ test_args += ['--trace-dir=@0@'.format(meson.current_build_dir())]
test(test_name + '_with_traces', dpdk_test,
- args : test_args + trace_extra + trace_prefix,
+ args: test_args,
env: ['DPDK_TEST=' + test_name],
timeout : timeout_seconds_fast,
is_parallel : false,
@@ -124,7 +129,7 @@ endforeach
# standalone test for telemetry
if not is_windows and dpdk_conf.has('RTE_LIB_TELEMETRY')
- test_args = [dpdk_test]
+ test_args = [dpdk_test_as_arg] + test_args_prefix
test_args += test_no_huge_args
if get_option('default_library') == 'shared'
test_args += ['-d', dpdk_drivers_build_dir]
@@ -166,6 +171,7 @@ dump_test_names = [
]
foreach arg : dump_test_names
test(arg, dpdk_test,
+ args : test_args,
env : ['DPDK_TEST=' + arg],
timeout : timeout_seconds_fast,
is_parallel : false,
diff --git a/app/test/suites/run_test_with_temp_prefix.sh b/app/test/suites/run_test_with_temp_prefix.sh
new file mode 100755
index 000000000000..0c466ec25ea1
--- /dev/null
+++ b/app/test/suites/run_test_with_temp_prefix.sh
@@ -0,0 +1,82 @@
+#!/bin/bash
+# Run dpdk test with a temporary prefix and clean it up afterwards
+set -eEuo pipefail
+
+# Get value of the long option with name in the first argument, from the rest.
+get_arg_value() {
+ local arg_name="$1"
+ shift 1
+
+ local arg_value=''
+ local grab_next=false
+ local arg
+
+ for arg in "$@"; do
+ if $grab_next; then
+ arg_value="$arg"
+ grab_next=false
+ elif [[ "$arg" == "${arg_name}="* ]]; then
+ arg_value="${arg#*=}"
+ elif [[ "$arg" == "$arg_name" ]]; then
+ grab_next=true
+ fi
+ done
+
+ printf "%s\n" "$arg_value"
+}
+
+# Delete work directory passing through the return code
+delete_work_directory() {
+ local -r test_rc="$1"
+ [[ -z "${WORK_DIRECTORY:-}" ]] || rm -rf "$WORK_DIRECTORY"
+ return "$test_rc"
+}
+
+main() {
+ if [[ $# -eq 0 ]]; then
+ printf "Usage: %s <test_command> [arguments...]\n" "$0" >&2
+ printf "%s %s\n" \
+ "Runs a DPDK test with a temporary file prefix" \
+ "and cleans up the working directory." >&2
+ printf "Ensure the DPDK_TEST environment variable is set.\n" >&2
+ exit 1
+ fi
+ local test_command=("$@")
+
+ if [[ -z "${DPDK_TEST:-}" ]]; then
+ printf "Ensure the DPDK_TEST environment variable is set.\n" >&2
+ exit 1
+ fi
+ local -r dpdk_test="$DPDK_TEST"
+
+ # Make sure file prefix is determined and set in test args
+ local file_prefix="$(get_arg_value --file-prefix "${test_command[@]}")"
+ if [[ -z "$file_prefix" ]]; then
+ # If not yet specified, set --file-prefix to test name
+ file_prefix="$dpdk_test"
+ if [[ -n "$(get_arg_value --trace "${test_command[@]}")" ]]; then
+ # Some tests runs twice, with and without traces
+ file_prefix="${file_prefix}_with_traces"
+ fi
+ test_command+=("--file-prefix=$file_prefix")
+ fi
+
+ # Make sure runtime directory is determined and set in the environment
+ local runtime_directory="${RUNTIME_DIRECTORY:-}"
+ if [[ -z "$runtime_directory" ]]; then
+ # Follow the algorithm in eal_filesystem.c
+ if [[ "$EUID" -eq 0 ]]; then
+ runtime_directory='/var/run'
+ else
+ runtime_directory="${XDG_RUNTIME_DIR:-/tmp}"
+ fi
+ export RUNTIME_DIRECTORY="$runtime_directory"
+ fi
+
+ WORK_DIRECTORY="$runtime_directory/dpdk/$file_prefix"
+ trap 'delete_work_directory "$?"' EXIT
+
+ "${test_command[@]}"
+}
+
+main "$@"
--
2.43.0
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH] test/suites: clean up per-test directories
2026-07-03 14:42 [PATCH] test/suites: clean up per-test directories Marat Khalili
@ 2026-07-03 15:49 ` Stephen Hemminger
2026-07-03 17:17 ` [PATCH v2] " Marat Khalili
1 sibling, 0 replies; 3+ messages in thread
From: Stephen Hemminger @ 2026-07-03 15:49 UTC (permalink / raw)
To: Marat Khalili; +Cc: dev, thomas
On Fri, 3 Jul 2026 15:42:16 +0100
Marat Khalili <marat.khalili@huawei.com> wrote:
> After commit 5ef166838394 ("test: add file-prefix for all fast-tests on
> Linux") each test within a suite has its own --file-prefix filled with
> the test name to enable parallel execution. It brought a couple of
> drawbacks though:
> * Solution only applied to one test suite.
> * Each working directory occupied ~25MB, with hundreds of tests this
> easily overfilled /run filesystems of small VMs. Currently executing
> fast-tests suite consumes 2.8GB of RAM, and adding more tests created
> problems for github CI.
> * While it enabled parallel execution of tests within a single build
> directory, --file-prefix argument could no longer be specified
> externally (caused duplicate argument error). Specifying custom
> --file-prefix was necessary when multiple builds ran in the same
> environment, so the corresponding workflow became broken.
>
> Move --file-prefix logic into a separate shell script, preserving
> existing argument and cleaning the work directory after the test.
> Apply it uniformly to all tests.
>
> Signed-off-by: Marat Khalili <marat.khalili@huawei.com>
> ---
AI review run manually shows:
Error — app/test/suites/meson.build, dump/debug-tests loop
The loop was changed to pass args : test_args, but test_args at that point is leftover state from the telemetry block above ([dpdk_test_as_arg] + test_no_huge_args + --vdev=... + '-a 0000:00:00.0') — or, if RTE_LIB_TELEMETRY is disabled, whatever the last fast-test iteration happened to leave in it. The debug tests previously ran with no extra args. Every other simple loop correctly uses test_args_prefix; this one should as well.
On Linux the effect is worse than just wrong EAL args: test_args begins with dpdk_test_as_arg (the wrapper's own path), so meson invokes the wrapper with the wrapper path as its first argument. The wrapper then re-execs itself before finally running the real binary — with --no-huge, the skeleton --vdev set, and -a 0000:00:00.0 that were only meant for telemetry_all.
Fix:
foreach arg : dump_test_names
test(arg, dpdk_test,
args : test_args_prefix,
env : ['DPDK_TEST=' + arg],
...
On Windows test_args_prefix is [], which also restores the original no-args behavior there.
Info — uid check diverges from the algorithm it cites. eal_filesystem.c keys the /var/run vs XDG_RUNTIME_DIR choice on getuid() (real uid); the script tests $EUID (effective). These only differ under setuid / sudo-with-preserved-ruid, which won't happen in normal CI, but if the goal is to match EAL exactly, use $UID (or id -ru).
Info — mixed indentation in the wrapper: the two runtime_directory=... assignments inside the root check use tab-plus-spaces, while the rest of the script uses hard tabs.
^ permalink raw reply [flat|nested] 3+ messages in thread* [PATCH v2] test/suites: clean up per-test directories
2026-07-03 14:42 [PATCH] test/suites: clean up per-test directories Marat Khalili
2026-07-03 15:49 ` Stephen Hemminger
@ 2026-07-03 17:17 ` Marat Khalili
1 sibling, 0 replies; 3+ messages in thread
From: Marat Khalili @ 2026-07-03 17:17 UTC (permalink / raw)
Cc: dev, thomas, stephen
After commit 5ef166838394 ("test: add file-prefix for all fast-tests on
Linux") each test within a suite has its own --file-prefix filled with
the test name to enable parallel execution. It brought a couple of
drawbacks though:
* Solution only applied to one test suite.
* Each working directory occupied ~25MB, with hundreds of tests this
easily overfilled /run filesystems of small VMs. Currently executing
fast-tests suite consumes 2.8GB of RAM, and adding more tests created
problems for github CI.
* While it enabled parallel execution of tests within a single build
directory, --file-prefix argument could no longer be specified
externally (caused duplicate argument error). Specifying custom
--file-prefix was necessary when multiple builds ran in the same
environment, so the corresponding workflow became broken.
Move --file-prefix logic into a separate shell script, preserving
existing argument and cleaning the work directory after the test.
Apply it uniformly to all tests.
Signed-off-by: Marat Khalili <marat.khalili@huawei.com>
---
v2: addressed AI comments and CI failures
* Added missing SPDX header to the new shell script.
* Fixed typo in handling dump_test_names.
* Following AI suggestion changed EUID check to UID check.
* Abandoned attempts to cover telemetry test, it is now out of scope.
app/test/suites/meson.build | 43 +++++-----
app/test/suites/run_test_with_temp_prefix.sh | 84 ++++++++++++++++++++
2 files changed, 108 insertions(+), 19 deletions(-)
create mode 100755 app/test/suites/run_test_with_temp_prefix.sh
diff --git a/app/test/suites/meson.build b/app/test/suites/meson.build
index 786c459c24b3..de3c28a64df0 100644
--- a/app/test/suites/meson.build
+++ b/app/test/suites/meson.build
@@ -23,6 +23,15 @@ if not has_hugepage
endif
endif
+if is_linux
+ # use wrapper providing per-test work directories to allow parallel runs
+ test_runner = find_program('run_test_with_temp_prefix.sh')
+ test_args_prefix = [dpdk_test]
+else
+ test_runner = dpdk_test
+ test_args_prefix = []
+endif
+
# process source files to determine the different unit test suites
# - fast_tests
# - perf_tests
@@ -41,14 +50,16 @@ foreach suite:test_suites
if developer_mode
warning('Test "@0@" is not defined in any test suite'.format(t))
endif
- test(t, dpdk_test,
+ test(t, test_runner,
+ args: test_args_prefix,
env: ['DPDK_TEST=' + t],
timeout: timeout_seconds,
is_parallel: false)
endforeach
elif suite_name == 'stress-tests'
foreach t: suite_tests
- test(t, dpdk_test,
+ test(t, test_runner,
+ args: test_args_prefix,
env: ['DPDK_TEST=' + t],
timeout: timeout_seconds_stress,
is_parallel: false,
@@ -57,7 +68,8 @@ foreach suite:test_suites
elif suite_name != 'fast-tests'
# simple cases - tests without parameters or special handling
foreach t: suite_tests
- test(t, dpdk_test,
+ test(t, test_runner,
+ args: test_args_prefix,
env: ['DPDK_TEST=' + t],
timeout: timeout_seconds,
is_parallel: false,
@@ -81,7 +93,7 @@ foreach suite:test_suites
nohuge = params[1] == 'NOHUGE_OK'
asan = params[2] == 'ASAN_OK'
- test_args = []
+ test_args = test_args_prefix
if nohuge
test_args += test_no_huge_args
elif not has_hugepage
@@ -94,25 +106,17 @@ foreach suite:test_suites
test_args += ['-d', dpdk_drivers_build_dir]
endif
- # use unique file-prefix to allow parallel runs
- file_prefix = []
- trace_prefix = []
- if is_linux
- file_prefix = ['--file-prefix=' + test_name.underscorify()]
- trace_prefix = [file_prefix[0] + '_with_traces']
- endif
-
- test(test_name, dpdk_test,
- args : test_args + file_prefix,
+ test(test_name, test_runner,
+ args: test_args,
env: ['DPDK_TEST=' + test_name],
timeout : timeout_seconds_fast,
is_parallel : false,
suite : 'fast-tests')
if not is_windows and test_name == 'trace_autotest'
- trace_extra = ['--trace=.*',
- '--trace-dir=@0@'.format(meson.current_build_dir())]
- test(test_name + '_with_traces', dpdk_test,
- args : test_args + trace_extra + trace_prefix,
+ test_args += ['--trace=.*']
+ test_args += ['--trace-dir=@0@'.format(meson.current_build_dir())]
+ test(test_name + '_with_traces', test_runner,
+ args: test_args,
env: ['DPDK_TEST=' + test_name],
timeout : timeout_seconds_fast,
is_parallel : false,
@@ -165,7 +169,8 @@ dump_test_names = [
'dump_struct_sizes',
]
foreach arg : dump_test_names
- test(arg, dpdk_test,
+ test(arg, test_runner,
+ args: test_args_prefix,
env : ['DPDK_TEST=' + arg],
timeout : timeout_seconds_fast,
is_parallel : false,
diff --git a/app/test/suites/run_test_with_temp_prefix.sh b/app/test/suites/run_test_with_temp_prefix.sh
new file mode 100755
index 000000000000..e7137b29a68f
--- /dev/null
+++ b/app/test/suites/run_test_with_temp_prefix.sh
@@ -0,0 +1,84 @@
+#!/bin/bash
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2026 Huawei Technologies Co., Ltd
+# Run dpdk test with a temporary prefix and clean it up afterwards
+set -eEuo pipefail
+
+# Get value of the long option with name in the first argument, from the rest.
+get_arg_value() {
+ local arg_name="$1"
+ shift 1
+
+ local arg_value=''
+ local grab_next=false
+ local arg
+
+ for arg in "$@"; do
+ if $grab_next; then
+ arg_value="$arg"
+ grab_next=false
+ elif [[ "$arg" == "${arg_name}="* ]]; then
+ arg_value="${arg#*=}"
+ elif [[ "$arg" == "$arg_name" ]]; then
+ grab_next=true
+ fi
+ done
+
+ printf "%s\n" "$arg_value"
+}
+
+# Delete work directory passing through the return code
+delete_work_directory() {
+ local -r test_rc="$1"
+ [[ -z "${WORK_DIRECTORY:-}" ]] || rm -rf "$WORK_DIRECTORY"
+ return "$test_rc"
+}
+
+main() {
+ if [[ $# -eq 0 ]]; then
+ printf "Usage: %s <test_command> [arguments...]\n" "$0" >&2
+ printf "%s %s\n" \
+ "Runs a DPDK test with a temporary file prefix" \
+ "and cleans up the working directory." >&2
+ printf "Ensure the DPDK_TEST environment variable is set.\n" >&2
+ exit 1
+ fi
+ local test_command=("$@")
+
+ if [[ -z "${DPDK_TEST:-}" ]]; then
+ printf "Ensure the DPDK_TEST environment variable is set.\n" >&2
+ exit 1
+ fi
+ local -r dpdk_test="$DPDK_TEST"
+
+ # Make sure file prefix is determined and set in test args
+ local file_prefix="$(get_arg_value --file-prefix "${test_command[@]}")"
+ if [[ -z "$file_prefix" ]]; then
+ # If not yet specified, set --file-prefix to test name
+ file_prefix="$dpdk_test"
+ if [[ -n "$(get_arg_value --trace "${test_command[@]}")" ]]; then
+ # Some tests runs twice, with and without traces
+ file_prefix="${file_prefix}_with_traces"
+ fi
+ test_command+=("--file-prefix=$file_prefix")
+ fi
+
+ # Make sure runtime directory is determined and set in the environment
+ local runtime_directory="${RUNTIME_DIRECTORY:-}"
+ if [[ -z "$runtime_directory" ]]; then
+ # Follow the algorithm in eal_filesystem.c
+ if [[ "$UID" -eq 0 ]]; then
+ runtime_directory='/var/run'
+ else
+ runtime_directory="${XDG_RUNTIME_DIR:-/tmp}"
+ fi
+ export RUNTIME_DIRECTORY="$runtime_directory"
+ fi
+
+ WORK_DIRECTORY="$runtime_directory/dpdk/$file_prefix"
+ trap 'delete_work_directory "$?"' EXIT
+
+ "${test_command[@]}"
+}
+
+main "$@"
--
2.43.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-07-03 17:17 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-03 14:42 [PATCH] test/suites: clean up per-test directories Marat Khalili
2026-07-03 15:49 ` Stephen Hemminger
2026-07-03 17:17 ` [PATCH v2] " Marat Khalili
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox