selftests: harness: Add kselftest harness selftest

Add a selftest for the kselftest harness itself so any changes can be
validated.

Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Reviewed-by: Muhammad Usama Anjum <usama.anjum@collabora.com>
Acked-by: Shuah Khan <skhan@linuxfoundation.org>
Link: https://lore.kernel.org/r/20250505-nolibc-kselftest-harness-v4-1-ee4dd5257135@linutronix.de
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
This commit is contained in:
Thomas Weißschuh 2025-05-05 17:15:19 +02:00 committed by Thomas Weißschuh
parent 2011097c17
commit df82ffc5a3
7 changed files with 224 additions and 0 deletions

View file

@ -21742,6 +21742,7 @@ F: include/linux/seccomp.h
F: include/uapi/linux/seccomp.h
F: kernel/seccomp.c
F: tools/testing/selftests/kselftest_harness.h
F: tools/testing/selftests/kselftest_harness/
F: tools/testing/selftests/seccomp/*
K: \bsecure_computing
K: \bTIF_SECCOMP\b

View file

@ -48,6 +48,7 @@ TARGETS += ipc
TARGETS += ir
TARGETS += kcmp
TARGETS += kexec
TARGETS += kselftest_harness
TARGETS += kvm
TARGETS += landlock
TARGETS += lib

View file

@ -0,0 +1,2 @@
/harness-selftest
/harness-selftest.seen

View file

@ -0,0 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
TEST_GEN_PROGS_EXTENDED := harness-selftest
TEST_PROGS := harness-selftest.sh
EXTRA_CLEAN := harness-selftest.seen
include ../lib.mk

View file

@ -0,0 +1,136 @@
// SPDX-License-Identifier: GPL-2.0
#include <stdio.h>
#include <sys/resource.h>
#include <sys/prctl.h>
/* Avoid any inconsistencies */
#define TH_LOG_STREAM stdout
#include "../kselftest_harness.h"
static void test_helper(struct __test_metadata *_metadata)
{
ASSERT_EQ(0, 0);
}
TEST(standalone_pass) {
TH_LOG("before");
ASSERT_EQ(0, 0);
EXPECT_EQ(0, 0);
test_helper(_metadata);
TH_LOG("after");
}
TEST(standalone_fail) {
TH_LOG("before");
EXPECT_EQ(0, 0);
EXPECT_EQ(0, 1);
ASSERT_EQ(0, 1);
TH_LOG("after");
}
TEST_SIGNAL(signal_pass, SIGUSR1) {
TH_LOG("before");
ASSERT_EQ(0, 0);
TH_LOG("after");
kill(getpid(), SIGUSR1);
}
TEST_SIGNAL(signal_fail, SIGUSR1) {
TH_LOG("before");
ASSERT_EQ(0, 1);
TH_LOG("after");
kill(getpid(), SIGUSR1);
}
FIXTURE(fixture) {
pid_t testpid;
};
FIXTURE_SETUP(fixture) {
TH_LOG("setup");
self->testpid = getpid();
}
FIXTURE_TEARDOWN(fixture) {
TH_LOG("teardown same-process=%d", self->testpid == getpid());
}
TEST_F(fixture, pass) {
TH_LOG("before");
ASSERT_EQ(0, 0);
test_helper(_metadata);
standalone_pass(_metadata);
TH_LOG("after");
}
TEST_F(fixture, fail) {
TH_LOG("before");
ASSERT_EQ(0, 1);
fixture_pass(_metadata, self, variant);
TH_LOG("after");
}
TEST_F_TIMEOUT(fixture, timeout, 1) {
TH_LOG("before");
sleep(2);
TH_LOG("after");
}
FIXTURE(fixture_parent) {
pid_t testpid;
};
FIXTURE_SETUP(fixture_parent) {
TH_LOG("setup");
self->testpid = getpid();
}
FIXTURE_TEARDOWN_PARENT(fixture_parent) {
TH_LOG("teardown same-process=%d", self->testpid == getpid());
}
TEST_F(fixture_parent, pass) {
TH_LOG("before");
ASSERT_EQ(0, 0);
TH_LOG("after");
}
FIXTURE(fixture_setup_failure) {
pid_t testpid;
};
FIXTURE_SETUP(fixture_setup_failure) {
TH_LOG("setup");
self->testpid = getpid();
ASSERT_EQ(0, 1);
}
FIXTURE_TEARDOWN(fixture_setup_failure) {
TH_LOG("teardown same-process=%d", self->testpid == getpid());
}
TEST_F(fixture_setup_failure, pass) {
TH_LOG("before");
ASSERT_EQ(0, 0);
TH_LOG("after");
}
int main(int argc, char **argv)
{
/*
* The harness uses abort() to signal assertion failures, which triggers coredumps.
* This may be useful to debug real failures but not for this selftest, disable them.
*/
struct rlimit rlimit = {
.rlim_cur = 0,
.rlim_max = 0,
};
prctl(PR_SET_DUMPABLE, 0, 0, 0, 0);
setrlimit(RLIMIT_CORE, &rlimit);
return test_harness_run(argc, argv);
}

View file

@ -0,0 +1,64 @@
TAP version 13
1..9
# Starting 9 tests from 4 test cases.
# RUN global.standalone_pass ...
# harness-selftest.c:19:standalone_pass:before
# harness-selftest.c:23:standalone_pass:after
# OK global.standalone_pass
ok 1 global.standalone_pass
# RUN global.standalone_fail ...
# harness-selftest.c:27:standalone_fail:before
# harness-selftest.c:29:standalone_fail:Expected 0 (0) == 1 (1)
# harness-selftest.c:30:standalone_fail:Expected 0 (0) == 1 (1)
# standalone_fail: Test terminated by assertion
# FAIL global.standalone_fail
not ok 2 global.standalone_fail
# RUN global.signal_pass ...
# harness-selftest.c:35:signal_pass:before
# harness-selftest.c:37:signal_pass:after
# OK global.signal_pass
ok 3 global.signal_pass
# RUN global.signal_fail ...
# harness-selftest.c:42:signal_fail:before
# harness-selftest.c:43:signal_fail:Expected 0 (0) == 1 (1)
# signal_fail: Test terminated by assertion
# FAIL global.signal_fail
not ok 4 global.signal_fail
# RUN fixture.pass ...
# harness-selftest.c:53:pass:setup
# harness-selftest.c:62:pass:before
# harness-selftest.c:19:pass:before
# harness-selftest.c:23:pass:after
# harness-selftest.c:66:pass:after
# harness-selftest.c:58:pass:teardown same-process=1
# OK fixture.pass
ok 5 fixture.pass
# RUN fixture.fail ...
# harness-selftest.c:53:fail:setup
# harness-selftest.c:70:fail:before
# harness-selftest.c:71:fail:Expected 0 (0) == 1 (1)
# harness-selftest.c:58:fail:teardown same-process=1
# fail: Test terminated by assertion
# FAIL fixture.fail
not ok 6 fixture.fail
# RUN fixture.timeout ...
# harness-selftest.c:53:timeout:setup
# harness-selftest.c:77:timeout:before
# timeout: Test terminated by timeout
# FAIL fixture.timeout
not ok 7 fixture.timeout
# RUN fixture_parent.pass ...
# harness-selftest.c:87:pass:setup
# harness-selftest.c:96:pass:before
# harness-selftest.c:98:pass:after
# harness-selftest.c:92:pass:teardown same-process=0
# OK fixture_parent.pass
ok 8 fixture_parent.pass
# RUN fixture_setup_failure.pass ...
# harness-selftest.c:106:pass:setup
# harness-selftest.c:108:pass:Expected 0 (0) == 1 (1)
# pass: Test terminated by assertion
# FAIL fixture_setup_failure.pass
not ok 9 fixture_setup_failure.pass
# FAILED: 4 / 9 tests passed.
# Totals: pass:4 fail:5 xfail:0 xpass:0 skip:0 error:0

View file

@ -0,0 +1,13 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
#
# Selftest for kselftest_harness.h
#
set -e
DIR="$(dirname $(readlink -f "$0"))"
"$DIR"/harness-selftest > harness-selftest.seen || true
diff -u "$DIR"/harness-selftest.expected harness-selftest.seen