All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next v3 00/11] selftests: kselftest_harness: support using xfail
@ 2024-02-20 19:22 Jakub Kicinski
  2024-02-20 19:22 ` [PATCH net-next v3 01/11] selftests: kselftest_harness: pass step via shared memory Jakub Kicinski
                   ` (12 more replies)
  0 siblings, 13 replies; 28+ messages in thread
From: Jakub Kicinski @ 2024-02-20 19:22 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, shuah, linux-kselftest, mic,
	linux-security-module, keescook, jakub, Jakub Kicinski

Hi!

When running selftests for our subsystem in our CI we'd like all
tests to pass. Currently some tests use SKIP for cases they
expect to fail, because the kselftest_harness limits the return
codes to pass/fail/skip.

Clean up and support the use of the full range of ksft exit codes
under kselftest_harness.

Merge plan is to put it on top of -rc4 and merge into net-next.
That way others should be able to pull the patches without
any networking changes.

v2: https://lore.kernel.org/all/20240216002619.1999225-1-kuba@kernel.org/
 - fix alignment
follow up RFC: https://lore.kernel.org/all/20240216004122.2004689-1-kuba@kernel.org/
v1: https://lore.kernel.org/all/20240213154416.422739-1-kuba@kernel.org/

Jakub Kicinski (11):
  selftests: kselftest_harness: pass step via shared memory
  selftests: kselftest_harness: use KSFT_* exit codes
  selftests: kselftest_harness: generate test name once
  selftests: kselftest_harness: save full exit code in metadata
  selftests: kselftest_harness: use exit code to store skip
  selftests: kselftest: add ksft_test_result_code(), handling all exit
    codes
  selftests: kselftest_harness: print test name for SKIP
  selftests: kselftest_harness: separate diagnostic message with # in
    ksft_test_result_code()
  selftests: kselftest_harness: let PASS / FAIL provide diagnostic
  selftests: kselftest_harness: support using xfail
  selftests: ip_local_port_range: use XFAIL instead of SKIP

 tools/testing/selftests/kselftest.h           |  45 ++++++
 tools/testing/selftests/kselftest_harness.h   | 148 ++++++++++++------
 tools/testing/selftests/landlock/base_test.c  |   2 +-
 tools/testing/selftests/landlock/common.h     |  22 +--
 tools/testing/selftests/landlock/fs_test.c    |   4 +-
 tools/testing/selftests/landlock/net_test.c   |   4 +-
 .../testing/selftests/landlock/ptrace_test.c  |   7 +-
 .../selftests/net/ip_local_port_range.c       |   6 +-
 tools/testing/selftests/net/tls.c             |   2 +-
 tools/testing/selftests/seccomp/seccomp_bpf.c |   9 +-
 10 files changed, 168 insertions(+), 81 deletions(-)

-- 
2.43.0


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH net-next v3 01/11] selftests: kselftest_harness: pass step via shared memory
  2024-02-20 19:22 [PATCH net-next v3 00/11] selftests: kselftest_harness: support using xfail Jakub Kicinski
@ 2024-02-20 19:22 ` Jakub Kicinski
  2024-02-20 19:22 ` [PATCH net-next v3 02/11] selftests: kselftest_harness: use KSFT_* exit codes Jakub Kicinski
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 28+ messages in thread
From: Jakub Kicinski @ 2024-02-20 19:22 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, shuah, linux-kselftest, mic,
	linux-security-module, keescook, jakub, Jakub Kicinski, luto,
	wad

Commit 0ef67a888375 ("selftests/harness: Report skip reason")
added shared memory to communicate between harness and test.
Use that instead of exit codes to send the failing step back
to the harness. The exit codes are limited and because of
the step passing we can't use the full range of KSFT_* exit
codes.

Acked-by: Kees Cook <keescook@chromium.org>
Tested-by: Jakub Sitnicki <jakub@cloudflare.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
CC: mic@digikod.net
CC: luto@amacapital.net
CC: wad@chromium.org
CC: shuah@kernel.org
CC: linux-kselftest@vger.kernel.org
CC: linux-security-module@vger.kernel.org
---
 tools/testing/selftests/kselftest_harness.h | 21 ++++++++++-----------
 tools/testing/selftests/landlock/common.h   |  5 ++---
 2 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h
index e05ac8261046..98bdedf9a53a 100644
--- a/tools/testing/selftests/kselftest_harness.h
+++ b/tools/testing/selftests/kselftest_harness.h
@@ -101,8 +101,8 @@
  * ASSERT_* number for which the test failed.  This behavior can be enabled by
  * writing `_metadata->no_print = true;` before the check sequence that is
  * unable to print.  When an error occur, instead of printing an error message
- * and calling `abort(3)`, the test process call `_exit(2)` with the assert
- * number as argument, which is then printed by the parent process.
+ * and calling `abort(3)`, the test process call `_exit(2)` and pass the error
+ * to be printed to the parent process via shared memory.
  */
 #define TH_LOG(fmt, ...) do { \
 	if (TH_LOG_ENABLED) \
@@ -695,9 +695,8 @@
 			__bail(_assert, _metadata))
 
 #define __INC_STEP(_metadata) \
-	/* Keep "step" below 255 (which is used for "SKIP" reporting). */	\
-	if (_metadata->passed && _metadata->step < 253) \
-		_metadata->step++;
+	if (_metadata->passed) \
+		_metadata->results->step++;
 
 #define is_signed_type(var)       (!!(((__typeof__(var))(-1)) < (__typeof__(var))1))
 
@@ -784,6 +783,7 @@
 
 struct __test_results {
 	char reason[1024];	/* Reason for test result */
+	unsigned int step;	/* Test step reached without failure */
 };
 
 struct __test_metadata;
@@ -837,7 +837,6 @@ struct __test_metadata {
 	int trigger; /* extra handler after the evaluation */
 	int timeout;	/* seconds to wait for test timeout */
 	bool timed_out;	/* did this test timeout instead of exiting? */
-	__u8 step;
 	bool no_print; /* manual trigger when TH_LOG_STREAM is not available */
 	bool aborted;	/* stopped test due to failed ASSERT */
 	bool setup_completed; /* did setup finish? */
@@ -875,7 +874,7 @@ static inline void __test_check_assert(struct __test_metadata *t)
 {
 	if (t->aborted) {
 		if (t->no_print)
-			_exit(t->step);
+			_exit(1);
 		abort();
 	}
 }
@@ -960,7 +959,7 @@ void __wait_for_test(struct __test_metadata *t)
 				fprintf(TH_LOG_STREAM,
 					"# %s: Test failed at step #%d\n",
 					t->name,
-					WEXITSTATUS(status));
+					t->results->step);
 			}
 		}
 	} else if (WIFSIGNALED(status)) {
@@ -1114,9 +1113,9 @@ void __run_test(struct __fixture_metadata *f,
 	t->passed = 1;
 	t->skip = 0;
 	t->trigger = 0;
-	t->step = 1;
 	t->no_print = 0;
 	memset(t->results->reason, 0, sizeof(t->results->reason));
+	t->results->step = 1;
 
 	ksft_print_msg(" RUN           %s%s%s.%s ...\n",
 	       f->name, variant->name[0] ? "." : "", variant->name, t->name);
@@ -1137,8 +1136,8 @@ void __run_test(struct __fixture_metadata *f,
 		/* Pass is exit 0 */
 		if (t->passed)
 			_exit(0);
-		/* Something else happened, report the step. */
-		_exit(t->step);
+		/* Something else happened. */
+		_exit(1);
 	} else {
 		__wait_for_test(t);
 	}
diff --git a/tools/testing/selftests/landlock/common.h b/tools/testing/selftests/landlock/common.h
index e64bbdf0e86e..c15e22abdca6 100644
--- a/tools/testing/selftests/landlock/common.h
+++ b/tools/testing/selftests/landlock/common.h
@@ -50,13 +50,13 @@
 				_exit(255); \
 			if (_metadata->passed) \
 				_exit(0); \
-			_exit(_metadata->step); \
+			_exit(1); \
 		} \
 		if (child != waitpid(child, &status, 0)) \
 			abort(); \
 		if (WIFSIGNALED(status) || !WIFEXITED(status)) { \
 			_metadata->passed = 0; \
-			_metadata->step = 1; \
+			_metadata->results->step = 1; \
 			return; \
 		} \
 		switch (WEXITSTATUS(status)) { \
@@ -69,7 +69,6 @@
 			break; \
 		default: \
 			_metadata->passed = 0; \
-			_metadata->step = WEXITSTATUS(status); \
 			break; \
 		} \
 	} \
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH net-next v3 02/11] selftests: kselftest_harness: use KSFT_* exit codes
  2024-02-20 19:22 [PATCH net-next v3 00/11] selftests: kselftest_harness: support using xfail Jakub Kicinski
  2024-02-20 19:22 ` [PATCH net-next v3 01/11] selftests: kselftest_harness: pass step via shared memory Jakub Kicinski
@ 2024-02-20 19:22 ` Jakub Kicinski
  2024-02-20 19:22 ` [PATCH net-next v3 03/11] selftests: kselftest_harness: generate test name once Jakub Kicinski
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 28+ messages in thread
From: Jakub Kicinski @ 2024-02-20 19:22 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, shuah, linux-kselftest, mic,
	linux-security-module, keescook, jakub, Jakub Kicinski, luto,
	wad

Now that we no longer need low exit codes to communicate
assertion steps - use normal KSFT exit codes.

Acked-by: Kees Cook <keescook@chromium.org>
Tested-by: Jakub Sitnicki <jakub@cloudflare.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
CC: keescook@chromium.org
CC: luto@amacapital.net
CC: wad@chromium.org
CC: shuah@kernel.org
CC: mic@digikod.net
CC: linux-kselftest@vger.kernel.org
CC: linux-security-module@vger.kernel.org
---
 tools/testing/selftests/kselftest_harness.h | 13 ++++++-------
 tools/testing/selftests/landlock/common.h   | 10 +++++-----
 2 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h
index 98bdedf9a53a..618b41eac749 100644
--- a/tools/testing/selftests/kselftest_harness.h
+++ b/tools/testing/selftests/kselftest_harness.h
@@ -874,7 +874,7 @@ static inline void __test_check_assert(struct __test_metadata *t)
 {
 	if (t->aborted) {
 		if (t->no_print)
-			_exit(1);
+			_exit(KSFT_FAIL);
 		abort();
 	}
 }
@@ -937,7 +937,7 @@ void __wait_for_test(struct __test_metadata *t)
 		fprintf(TH_LOG_STREAM,
 			"# %s: Test terminated by timeout\n", t->name);
 	} else if (WIFEXITED(status)) {
-		if (WEXITSTATUS(status) == 255) {
+		if (WEXITSTATUS(status) == KSFT_SKIP) {
 			/* SKIP */
 			t->passed = 1;
 			t->skip = 1;
@@ -950,7 +950,7 @@ void __wait_for_test(struct __test_metadata *t)
 		} else {
 			switch (WEXITSTATUS(status)) {
 			/* Success */
-			case 0:
+			case KSFT_PASS:
 				t->passed = 1;
 				break;
 			/* Other failure, assume step report. */
@@ -1132,12 +1132,11 @@ void __run_test(struct __fixture_metadata *f,
 		setpgrp();
 		t->fn(t, variant);
 		if (t->skip)
-			_exit(255);
-		/* Pass is exit 0 */
+			_exit(KSFT_SKIP);
 		if (t->passed)
-			_exit(0);
+			_exit(KSFT_PASS);
 		/* Something else happened. */
-		_exit(1);
+		_exit(KSFT_FAIL);
 	} else {
 		__wait_for_test(t);
 	}
diff --git a/tools/testing/selftests/landlock/common.h b/tools/testing/selftests/landlock/common.h
index c15e22abdca6..f5b40399a538 100644
--- a/tools/testing/selftests/landlock/common.h
+++ b/tools/testing/selftests/landlock/common.h
@@ -47,10 +47,10 @@
 			_metadata->no_print = 1; \
 			fixture_name##_##test_name##_child(_metadata, self, variant); \
 			if (_metadata->skip) \
-				_exit(255); \
+				_exit(KSFT_SKIP); \
 			if (_metadata->passed) \
-				_exit(0); \
-			_exit(1); \
+				_exit(KSFT_PASS); \
+			_exit(KSFT_FAIL); \
 		} \
 		if (child != waitpid(child, &status, 0)) \
 			abort(); \
@@ -60,10 +60,10 @@
 			return; \
 		} \
 		switch (WEXITSTATUS(status)) { \
-		case 0: \
+		case KSFT_PASS: \
 			_metadata->passed = 1; \
 			break; \
-		case 255: \
+		case KSFT_SKIP: \
 			_metadata->passed = 1; \
 			_metadata->skip = 1; \
 			break; \
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH net-next v3 03/11] selftests: kselftest_harness: generate test name once
  2024-02-20 19:22 [PATCH net-next v3 00/11] selftests: kselftest_harness: support using xfail Jakub Kicinski
  2024-02-20 19:22 ` [PATCH net-next v3 01/11] selftests: kselftest_harness: pass step via shared memory Jakub Kicinski
  2024-02-20 19:22 ` [PATCH net-next v3 02/11] selftests: kselftest_harness: use KSFT_* exit codes Jakub Kicinski
@ 2024-02-20 19:22 ` Jakub Kicinski
  2024-02-20 19:22 ` [PATCH net-next v3 04/11] selftests: kselftest_harness: save full exit code in metadata Jakub Kicinski
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 28+ messages in thread
From: Jakub Kicinski @ 2024-02-20 19:22 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, shuah, linux-kselftest, mic,
	linux-security-module, keescook, jakub, Jakub Kicinski

Since we added variant support generating full test case
name takes 4 string arguments. We're about to need it
in another two places. Stop the duplication and print
once into a temporary buffer.

Suggested-by: Jakub Sitnicki <jakub@cloudflare.com>
Acked-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 tools/testing/selftests/kselftest_harness.h | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h
index 618b41eac749..8fc24a728240 100644
--- a/tools/testing/selftests/kselftest_harness.h
+++ b/tools/testing/selftests/kselftest_harness.h
@@ -56,6 +56,7 @@
 #include <asm/types.h>
 #include <ctype.h>
 #include <errno.h>
+#include <limits.h>
 #include <stdbool.h>
 #include <stdint.h>
 #include <stdio.h>
@@ -1109,6 +1110,8 @@ void __run_test(struct __fixture_metadata *f,
 		struct __fixture_variant_metadata *variant,
 		struct __test_metadata *t)
 {
+	char test_name[LINE_MAX];
+
 	/* reset test struct */
 	t->passed = 1;
 	t->skip = 0;
@@ -1117,8 +1120,10 @@ void __run_test(struct __fixture_metadata *f,
 	memset(t->results->reason, 0, sizeof(t->results->reason));
 	t->results->step = 1;
 
-	ksft_print_msg(" RUN           %s%s%s.%s ...\n",
-	       f->name, variant->name[0] ? "." : "", variant->name, t->name);
+	snprintf(test_name, sizeof(test_name), "%s%s%s.%s",
+		 f->name, variant->name[0] ? "." : "", variant->name, t->name);
+
+	ksft_print_msg(" RUN           %s ...\n", test_name);
 
 	/* Make sure output buffers are flushed before fork */
 	fflush(stdout);
@@ -1140,15 +1145,14 @@ void __run_test(struct __fixture_metadata *f,
 	} else {
 		__wait_for_test(t);
 	}
-	ksft_print_msg("         %4s  %s%s%s.%s\n", t->passed ? "OK" : "FAIL",
-	       f->name, variant->name[0] ? "." : "", variant->name, t->name);
+	ksft_print_msg("         %4s  %s\n",
+		       t->passed ? "OK" : "FAIL", test_name);
 
 	if (t->skip)
 		ksft_test_result_skip("%s\n", t->results->reason[0] ?
 					t->results->reason : "unknown");
 	else
-		ksft_test_result(t->passed, "%s%s%s.%s\n",
-			f->name, variant->name[0] ? "." : "", variant->name, t->name);
+		ksft_test_result(t->passed, "%s\n", test_name);
 }
 
 static int test_harness_run(int argc, char **argv)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH net-next v3 04/11] selftests: kselftest_harness: save full exit code in metadata
  2024-02-20 19:22 [PATCH net-next v3 00/11] selftests: kselftest_harness: support using xfail Jakub Kicinski
                   ` (2 preceding siblings ...)
  2024-02-20 19:22 ` [PATCH net-next v3 03/11] selftests: kselftest_harness: generate test name once Jakub Kicinski
@ 2024-02-20 19:22 ` Jakub Kicinski
  2024-02-20 19:22 ` [PATCH net-next v3 05/11] selftests: kselftest_harness: use exit code to store skip Jakub Kicinski
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 28+ messages in thread
From: Jakub Kicinski @ 2024-02-20 19:22 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, shuah, linux-kselftest, mic,
	linux-security-module, keescook, jakub, Jakub Kicinski

Instead of tracking passed = 0/1 rename the field to exit_code
and invert the values so that they match the KSFT_* exit codes.
This will allow us to fold SKIP / XFAIL into the same value.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 tools/testing/selftests/kselftest_harness.h   | 48 +++++++++++--------
 tools/testing/selftests/landlock/base_test.c  |  2 +-
 tools/testing/selftests/landlock/common.h     | 14 ++----
 tools/testing/selftests/landlock/fs_test.c    |  4 +-
 tools/testing/selftests/landlock/net_test.c   |  4 +-
 .../testing/selftests/landlock/ptrace_test.c  |  7 +--
 tools/testing/selftests/net/tls.c             |  2 +-
 tools/testing/selftests/seccomp/seccomp_bpf.c |  9 ++--
 8 files changed, 46 insertions(+), 44 deletions(-)

diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h
index 8fc24a728240..bbb339642a72 100644
--- a/tools/testing/selftests/kselftest_harness.h
+++ b/tools/testing/selftests/kselftest_harness.h
@@ -136,7 +136,7 @@
 		fprintf(TH_LOG_STREAM, "#      SKIP      %s\n", \
 			_metadata->results->reason); \
 	} \
-	_metadata->passed = 1; \
+	_metadata->exit_code = KSFT_PASS; \
 	_metadata->skip = 1; \
 	_metadata->trigger = 0; \
 	statement; \
@@ -389,7 +389,7 @@
 		if (setjmp(_metadata->env) == 0) { \
 			fixture_name##_setup(_metadata, &self, variant->data); \
 			/* Let setup failure terminate early. */ \
-                       if (!_metadata->passed || _metadata->skip) \
+			if (!__test_passed(_metadata) || _metadata->skip) \
 				return; \
 			_metadata->setup_completed = true; \
 			fixture_name##_##test_name(_metadata, &self, variant->data); \
@@ -696,7 +696,7 @@
 			__bail(_assert, _metadata))
 
 #define __INC_STEP(_metadata) \
-	if (_metadata->passed) \
+	if (__test_passed(_metadata))	\
 		_metadata->results->step++;
 
 #define is_signed_type(var)       (!!(((__typeof__(var))(-1)) < (__typeof__(var))1))
@@ -742,7 +742,7 @@
 			break; \
 			} \
 		} \
-		_metadata->passed = 0; \
+		_metadata->exit_code = KSFT_FAIL; \
 		/* Ensure the optional handler is triggered */ \
 		_metadata->trigger = 1; \
 	} \
@@ -754,7 +754,7 @@
 	if (_assert) __INC_STEP(_metadata); \
 	if (!(strcmp(__exp, __seen) _t 0))  { \
 		__TH_LOG("Expected '%s' %s '%s'.", __exp, #_t, __seen); \
-		_metadata->passed = 0; \
+		_metadata->exit_code = KSFT_FAIL; \
 		_metadata->trigger = 1; \
 	} \
 } while (0); OPTIONAL_HANDLER(_assert)
@@ -833,7 +833,7 @@ struct __test_metadata {
 	pid_t pid;	/* pid of test when being run */
 	struct __fixture_metadata *fixture;
 	int termsig;
-	int passed;
+	int exit_code;
 	int skip;	/* did SKIP get used? */
 	int trigger; /* extra handler after the evaluation */
 	int timeout;	/* seconds to wait for test timeout */
@@ -846,6 +846,12 @@ struct __test_metadata {
 	struct __test_metadata *prev, *next;
 };
 
+static inline bool __test_passed(struct __test_metadata *metadata)
+{
+	return metadata->exit_code != KSFT_FAIL &&
+	       metadata->exit_code <= KSFT_SKIP;
+}
+
 /*
  * Since constructors are called in reverse order, reverse the test
  * list so tests are run in source declaration order.
@@ -913,7 +919,7 @@ void __wait_for_test(struct __test_metadata *t)
 	int status;
 
 	if (sigaction(SIGALRM, &action, &saved_action)) {
-		t->passed = 0;
+		t->exit_code = KSFT_FAIL;
 		fprintf(TH_LOG_STREAM,
 			"# %s: unable to install SIGALRM handler\n",
 			t->name);
@@ -925,7 +931,7 @@ void __wait_for_test(struct __test_metadata *t)
 	waitpid(t->pid, &status, 0);
 	alarm(0);
 	if (sigaction(SIGALRM, &saved_action, NULL)) {
-		t->passed = 0;
+		t->exit_code = KSFT_FAIL;
 		fprintf(TH_LOG_STREAM,
 			"# %s: unable to uninstall SIGALRM handler\n",
 			t->name);
@@ -934,16 +940,16 @@ void __wait_for_test(struct __test_metadata *t)
 	__active_test = NULL;
 
 	if (t->timed_out) {
-		t->passed = 0;
+		t->exit_code = KSFT_FAIL;
 		fprintf(TH_LOG_STREAM,
 			"# %s: Test terminated by timeout\n", t->name);
 	} else if (WIFEXITED(status)) {
 		if (WEXITSTATUS(status) == KSFT_SKIP) {
 			/* SKIP */
-			t->passed = 1;
+			t->exit_code = KSFT_PASS;
 			t->skip = 1;
 		} else if (t->termsig != -1) {
-			t->passed = 0;
+			t->exit_code = KSFT_FAIL;
 			fprintf(TH_LOG_STREAM,
 				"# %s: Test exited normally instead of by signal (code: %d)\n",
 				t->name,
@@ -952,11 +958,11 @@ void __wait_for_test(struct __test_metadata *t)
 			switch (WEXITSTATUS(status)) {
 			/* Success */
 			case KSFT_PASS:
-				t->passed = 1;
+				t->exit_code = KSFT_PASS;
 				break;
 			/* Other failure, assume step report. */
 			default:
-				t->passed = 0;
+				t->exit_code = KSFT_FAIL;
 				fprintf(TH_LOG_STREAM,
 					"# %s: Test failed at step #%d\n",
 					t->name,
@@ -964,13 +970,13 @@ void __wait_for_test(struct __test_metadata *t)
 			}
 		}
 	} else if (WIFSIGNALED(status)) {
-		t->passed = 0;
+		t->exit_code = KSFT_FAIL;
 		if (WTERMSIG(status) == SIGABRT) {
 			fprintf(TH_LOG_STREAM,
 				"# %s: Test terminated by assertion\n",
 				t->name);
 		} else if (WTERMSIG(status) == t->termsig) {
-			t->passed = 1;
+			t->exit_code = KSFT_PASS;
 		} else {
 			fprintf(TH_LOG_STREAM,
 				"# %s: Test terminated unexpectedly by signal %d\n",
@@ -1113,7 +1119,7 @@ void __run_test(struct __fixture_metadata *f,
 	char test_name[LINE_MAX];
 
 	/* reset test struct */
-	t->passed = 1;
+	t->exit_code = KSFT_PASS;
 	t->skip = 0;
 	t->trigger = 0;
 	t->no_print = 0;
@@ -1132,13 +1138,13 @@ void __run_test(struct __fixture_metadata *f,
 	t->pid = fork();
 	if (t->pid < 0) {
 		ksft_print_msg("ERROR SPAWNING TEST CHILD\n");
-		t->passed = 0;
+		t->exit_code = KSFT_FAIL;
 	} else if (t->pid == 0) {
 		setpgrp();
 		t->fn(t, variant);
 		if (t->skip)
 			_exit(KSFT_SKIP);
-		if (t->passed)
+		if (__test_passed(t))
 			_exit(KSFT_PASS);
 		/* Something else happened. */
 		_exit(KSFT_FAIL);
@@ -1146,13 +1152,13 @@ void __run_test(struct __fixture_metadata *f,
 		__wait_for_test(t);
 	}
 	ksft_print_msg("         %4s  %s\n",
-		       t->passed ? "OK" : "FAIL", test_name);
+		       __test_passed(t) ? "OK" : "FAIL", test_name);
 
 	if (t->skip)
 		ksft_test_result_skip("%s\n", t->results->reason[0] ?
 					t->results->reason : "unknown");
 	else
-		ksft_test_result(t->passed, "%s\n", test_name);
+		ksft_test_result(__test_passed(t), "%s\n", test_name);
 }
 
 static int test_harness_run(int argc, char **argv)
@@ -1200,7 +1206,7 @@ static int test_harness_run(int argc, char **argv)
 				t->results = results;
 				__run_test(f, v, t);
 				t->results = NULL;
-				if (t->passed)
+				if (__test_passed(t))
 					pass_count++;
 				else
 					ret = 1;
diff --git a/tools/testing/selftests/landlock/base_test.c b/tools/testing/selftests/landlock/base_test.c
index 646f778dfb1e..a6f89aaea77d 100644
--- a/tools/testing/selftests/landlock/base_test.c
+++ b/tools/testing/selftests/landlock/base_test.c
@@ -307,7 +307,7 @@ TEST(ruleset_fd_transfer)
 		dir_fd = open("/tmp", O_RDONLY | O_DIRECTORY | O_CLOEXEC);
 		ASSERT_LE(0, dir_fd);
 		ASSERT_EQ(0, close(dir_fd));
-		_exit(_metadata->passed ? EXIT_SUCCESS : EXIT_FAILURE);
+		_exit(_metadata->exit_code);
 		return;
 	}
 
diff --git a/tools/testing/selftests/landlock/common.h b/tools/testing/selftests/landlock/common.h
index f5b40399a538..89f8183bd8f5 100644
--- a/tools/testing/selftests/landlock/common.h
+++ b/tools/testing/selftests/landlock/common.h
@@ -46,29 +46,25 @@
 		if (child == 0) { \
 			_metadata->no_print = 1; \
 			fixture_name##_##test_name##_child(_metadata, self, variant); \
-			if (_metadata->skip) \
-				_exit(KSFT_SKIP); \
-			if (_metadata->passed) \
-				_exit(KSFT_PASS); \
-			_exit(KSFT_FAIL); \
+			_exit(_metadata->exit_code); \
 		} \
 		if (child != waitpid(child, &status, 0)) \
 			abort(); \
 		if (WIFSIGNALED(status) || !WIFEXITED(status)) { \
-			_metadata->passed = 0; \
+			_metadata->exit_code = KSFT_FAIL; \
 			_metadata->results->step = 1; \
 			return; \
 		} \
 		switch (WEXITSTATUS(status)) { \
 		case KSFT_PASS: \
-			_metadata->passed = 1; \
+			_metadata->exit_code = KSFT_PASS; \
 			break; \
 		case KSFT_SKIP: \
-			_metadata->passed = 1; \
+			_metadata->exit_code = KSFT_PASS; \
 			_metadata->skip = 1; \
 			break; \
 		default: \
-			_metadata->passed = 0; \
+			_metadata->exit_code = KSFT_FAIL; \
 			break; \
 		} \
 	} \
diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c
index 2d6d9b43d958..98817a14c91b 100644
--- a/tools/testing/selftests/landlock/fs_test.c
+++ b/tools/testing/selftests/landlock/fs_test.c
@@ -1964,7 +1964,7 @@ static void test_execute(struct __test_metadata *const _metadata, const int err,
 			       strerror(errno));
 		};
 		ASSERT_EQ(err, errno);
-		_exit(_metadata->passed ? 2 : 1);
+		_exit(__test_passed(_metadata) ? 2 : 1);
 		return;
 	}
 	ASSERT_EQ(child, waitpid(child, &status, 0));
@@ -3807,7 +3807,7 @@ TEST_F_FORK(ftruncate, open_and_ftruncate_in_different_processes)
 
 		ASSERT_EQ(0, close(socket_fds[0]));
 
-		_exit(_metadata->passed ? EXIT_SUCCESS : EXIT_FAILURE);
+		_exit(_metadata->exit_code);
 		return;
 	}
 
diff --git a/tools/testing/selftests/landlock/net_test.c b/tools/testing/selftests/landlock/net_test.c
index 936cfc879f1d..f21cfbbc3638 100644
--- a/tools/testing/selftests/landlock/net_test.c
+++ b/tools/testing/selftests/landlock/net_test.c
@@ -539,7 +539,7 @@ static void test_bind_and_connect(struct __test_metadata *const _metadata,
 		}
 
 		EXPECT_EQ(0, close(connect_fd));
-		_exit(_metadata->passed ? EXIT_SUCCESS : EXIT_FAILURE);
+		_exit(_metadata->exit_code);
 		return;
 	}
 
@@ -834,7 +834,7 @@ TEST_F(protocol, connect_unspec)
 		}
 
 		EXPECT_EQ(0, close(connect_fd));
-		_exit(_metadata->passed ? EXIT_SUCCESS : EXIT_FAILURE);
+		_exit(_metadata->exit_code);
 		return;
 	}
 
diff --git a/tools/testing/selftests/landlock/ptrace_test.c b/tools/testing/selftests/landlock/ptrace_test.c
index 55e7871631a1..a19db4d0b3bd 100644
--- a/tools/testing/selftests/landlock/ptrace_test.c
+++ b/tools/testing/selftests/landlock/ptrace_test.c
@@ -314,7 +314,7 @@ TEST_F(hierarchy, trace)
 	ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC));
 	if (variant->domain_both) {
 		create_domain(_metadata);
-		if (!_metadata->passed)
+		if (!__test_passed(_metadata))
 			/* Aborts before forking. */
 			return;
 	}
@@ -375,7 +375,7 @@ TEST_F(hierarchy, trace)
 
 		/* Waits for the parent PTRACE_ATTACH test. */
 		ASSERT_EQ(1, read(pipe_parent[0], &buf_child, 1));
-		_exit(_metadata->passed ? EXIT_SUCCESS : EXIT_FAILURE);
+		_exit(_metadata->exit_code);
 		return;
 	}
 
@@ -430,9 +430,10 @@ TEST_F(hierarchy, trace)
 	/* Signals that the parent PTRACE_ATTACH test is done. */
 	ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
 	ASSERT_EQ(child, waitpid(child, &status, 0));
+
 	if (WIFSIGNALED(status) || !WIFEXITED(status) ||
 	    WEXITSTATUS(status) != EXIT_SUCCESS)
-		_metadata->passed = 0;
+		_metadata->exit_code = KSFT_FAIL;
 }
 
 TEST_HARNESS_MAIN
diff --git a/tools/testing/selftests/net/tls.c b/tools/testing/selftests/net/tls.c
index 49c84602707f..046d1ccedcf3 100644
--- a/tools/testing/selftests/net/tls.c
+++ b/tools/testing/selftests/net/tls.c
@@ -1882,7 +1882,7 @@ TEST_F(tls_err, poll_partial_rec_async)
 		pfd.events = POLLIN;
 		EXPECT_EQ(poll(&pfd, 1, 20), 1);
 
-		exit(!_metadata->passed);
+		exit(!__test_passed(_metadata));
 	}
 }
 
diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c
index 38f651469968..1027e6170186 100644
--- a/tools/testing/selftests/seccomp/seccomp_bpf.c
+++ b/tools/testing/selftests/seccomp/seccomp_bpf.c
@@ -1576,7 +1576,7 @@ void start_tracer(struct __test_metadata *_metadata, int fd, pid_t tracee,
 		ASSERT_EQ(0, ret);
 	}
 	/* Directly report the status of our test harness results. */
-	syscall(__NR_exit, _metadata->passed ? EXIT_SUCCESS : EXIT_FAILURE);
+	syscall(__NR_exit, _metadata->exit_code);
 }
 
 /* Common tracer setup/teardown functions. */
@@ -1623,7 +1623,7 @@ void teardown_trace_fixture(struct __test_metadata *_metadata,
 		ASSERT_EQ(0, kill(tracer, SIGUSR1));
 		ASSERT_EQ(tracer, waitpid(tracer, &status, 0));
 		if (WEXITSTATUS(status))
-			_metadata->passed = 0;
+			_metadata->exit_code = KSFT_FAIL;
 	}
 }
 
@@ -3088,8 +3088,7 @@ TEST(syscall_restart)
 		}
 
 		/* Directly report the status of our test harness results. */
-		syscall(__NR_exit, _metadata->passed ? EXIT_SUCCESS
-						     : EXIT_FAILURE);
+		syscall(__NR_exit, _metadata->exit_code);
 	}
 	EXPECT_EQ(0, close(pipefd[0]));
 
@@ -3174,7 +3173,7 @@ TEST(syscall_restart)
 
 	ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));
 	if (WIFSIGNALED(status) || WEXITSTATUS(status))
-		_metadata->passed = 0;
+		_metadata->exit_code = KSFT_FAIL;
 }
 
 TEST_SIGNAL(filter_flag_log, SIGSYS)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH net-next v3 05/11] selftests: kselftest_harness: use exit code to store skip
  2024-02-20 19:22 [PATCH net-next v3 00/11] selftests: kselftest_harness: support using xfail Jakub Kicinski
                   ` (3 preceding siblings ...)
  2024-02-20 19:22 ` [PATCH net-next v3 04/11] selftests: kselftest_harness: save full exit code in metadata Jakub Kicinski
@ 2024-02-20 19:22 ` Jakub Kicinski
  2024-02-21  0:49   ` Kees Cook
  2024-02-20 19:22 ` [PATCH net-next v3 06/11] selftests: kselftest: add ksft_test_result_code(), handling all exit codes Jakub Kicinski
                   ` (7 subsequent siblings)
  12 siblings, 1 reply; 28+ messages in thread
From: Jakub Kicinski @ 2024-02-20 19:22 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, shuah, linux-kselftest, mic,
	linux-security-module, keescook, jakub, Jakub Kicinski

We always use skip in combination with exit_code being 0
(KSFT_PASS). This are basic KSFT / KTAP semantics.
Store the right KSFT_* code in exit_code directly.

This makes it easier to support tests reporting other
extended KSFT_* codes like XFAIL / XPASS.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 tools/testing/selftests/kselftest_harness.h | 20 +++++---------------
 tools/testing/selftests/landlock/common.h   |  5 +----
 2 files changed, 6 insertions(+), 19 deletions(-)

diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h
index bbb339642a72..42ec3ca29c4b 100644
--- a/tools/testing/selftests/kselftest_harness.h
+++ b/tools/testing/selftests/kselftest_harness.h
@@ -136,8 +136,7 @@
 		fprintf(TH_LOG_STREAM, "#      SKIP      %s\n", \
 			_metadata->results->reason); \
 	} \
-	_metadata->exit_code = KSFT_PASS; \
-	_metadata->skip = 1; \
+	_metadata->exit_code = KSFT_SKIP; \
 	_metadata->trigger = 0; \
 	statement; \
 } while (0)
@@ -389,7 +388,7 @@
 		if (setjmp(_metadata->env) == 0) { \
 			fixture_name##_setup(_metadata, &self, variant->data); \
 			/* Let setup failure terminate early. */ \
-			if (!__test_passed(_metadata) || _metadata->skip) \
+			if (_metadata->exit_code) \
 				return; \
 			_metadata->setup_completed = true; \
 			fixture_name##_##test_name(_metadata, &self, variant->data); \
@@ -834,7 +833,6 @@ struct __test_metadata {
 	struct __fixture_metadata *fixture;
 	int termsig;
 	int exit_code;
-	int skip;	/* did SKIP get used? */
 	int trigger; /* extra handler after the evaluation */
 	int timeout;	/* seconds to wait for test timeout */
 	bool timed_out;	/* did this test timeout instead of exiting? */
@@ -945,9 +943,7 @@ void __wait_for_test(struct __test_metadata *t)
 			"# %s: Test terminated by timeout\n", t->name);
 	} else if (WIFEXITED(status)) {
 		if (WEXITSTATUS(status) == KSFT_SKIP) {
-			/* SKIP */
-			t->exit_code = KSFT_PASS;
-			t->skip = 1;
+			t->exit_code = WEXITSTATUS(status);
 		} else if (t->termsig != -1) {
 			t->exit_code = KSFT_FAIL;
 			fprintf(TH_LOG_STREAM,
@@ -1120,7 +1116,6 @@ void __run_test(struct __fixture_metadata *f,
 
 	/* reset test struct */
 	t->exit_code = KSFT_PASS;
-	t->skip = 0;
 	t->trigger = 0;
 	t->no_print = 0;
 	memset(t->results->reason, 0, sizeof(t->results->reason));
@@ -1142,19 +1137,14 @@ void __run_test(struct __fixture_metadata *f,
 	} else if (t->pid == 0) {
 		setpgrp();
 		t->fn(t, variant);
-		if (t->skip)
-			_exit(KSFT_SKIP);
-		if (__test_passed(t))
-			_exit(KSFT_PASS);
-		/* Something else happened. */
-		_exit(KSFT_FAIL);
+		_exit(t->exit_code);
 	} else {
 		__wait_for_test(t);
 	}
 	ksft_print_msg("         %4s  %s\n",
 		       __test_passed(t) ? "OK" : "FAIL", test_name);
 
-	if (t->skip)
+	if (t->exit_code == KSFT_SKIP)
 		ksft_test_result_skip("%s\n", t->results->reason[0] ?
 					t->results->reason : "unknown");
 	else
diff --git a/tools/testing/selftests/landlock/common.h b/tools/testing/selftests/landlock/common.h
index 89f8183bd8f5..56c5b5c5676a 100644
--- a/tools/testing/selftests/landlock/common.h
+++ b/tools/testing/selftests/landlock/common.h
@@ -57,11 +57,8 @@
 		} \
 		switch (WEXITSTATUS(status)) { \
 		case KSFT_PASS: \
-			_metadata->exit_code = KSFT_PASS; \
-			break; \
 		case KSFT_SKIP: \
-			_metadata->exit_code = KSFT_PASS; \
-			_metadata->skip = 1; \
+			_metadata->exit_code = WEXITSTATUS(status); \
 			break; \
 		default: \
 			_metadata->exit_code = KSFT_FAIL; \
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH net-next v3 06/11] selftests: kselftest: add ksft_test_result_code(), handling all exit codes
  2024-02-20 19:22 [PATCH net-next v3 00/11] selftests: kselftest_harness: support using xfail Jakub Kicinski
                   ` (4 preceding siblings ...)
  2024-02-20 19:22 ` [PATCH net-next v3 05/11] selftests: kselftest_harness: use exit code to store skip Jakub Kicinski
@ 2024-02-20 19:22 ` Jakub Kicinski
  2024-02-21  0:49   ` Kees Cook
  2024-02-20 19:22 ` [PATCH net-next v3 07/11] selftests: kselftest_harness: print test name for SKIP Jakub Kicinski
                   ` (6 subsequent siblings)
  12 siblings, 1 reply; 28+ messages in thread
From: Jakub Kicinski @ 2024-02-20 19:22 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, shuah, linux-kselftest, mic,
	linux-security-module, keescook, jakub, Jakub Kicinski

For generic test harness code it's more useful to deal with exit
codes directly, rather than having to switch on them and call
the right ksft_test_result_*() helper. Add such function to kselftest.h.

Note that "directive" and "diagnostic" are what ktap docs call
those parts of the message.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 tools/testing/selftests/kselftest.h         | 39 +++++++++++++++++++++
 tools/testing/selftests/kselftest_harness.h |  9 +++--
 2 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/kselftest.h b/tools/testing/selftests/kselftest.h
index a781e6311810..12ad7f8dfe3a 100644
--- a/tools/testing/selftests/kselftest.h
+++ b/tools/testing/selftests/kselftest.h
@@ -25,6 +25,7 @@
  *     ksft_test_result_skip(fmt, ...);
  *     ksft_test_result_xfail(fmt, ...);
  *     ksft_test_result_error(fmt, ...);
+ *     ksft_test_result_code(exit_code, test_name, fmt, ...);
  *
  * When all tests are finished, clean up and exit the program with one of:
  *
@@ -254,6 +255,44 @@ static inline __printf(1, 2) void ksft_test_result_error(const char *msg, ...)
 	va_end(args);
 }
 
+static inline __printf(2, 3)
+void ksft_test_result_code(int exit_code, const char *msg, ...)
+{
+	const char *tap_code = "ok";
+	const char *directive = "";
+	int saved_errno = errno;
+	va_list args;
+
+	switch (exit_code) {
+	case KSFT_PASS:
+		ksft_cnt.ksft_pass++;
+		break;
+	case KSFT_XFAIL:
+		directive = " # XFAIL ";
+		ksft_cnt.ksft_xfail++;
+		break;
+	case KSFT_XPASS:
+		directive = " # XPASS ";
+		ksft_cnt.ksft_xpass++;
+		break;
+	case KSFT_SKIP:
+		directive = " # SKIP ";
+		ksft_cnt.ksft_xskip++;
+		break;
+	case KSFT_FAIL:
+	default:
+		tap_code = "not ok";
+		ksft_cnt.ksft_fail++;
+		break;
+	}
+
+	va_start(args, msg);
+	printf("%s %u%s", tap_code, ksft_test_num(), directive);
+	errno = saved_errno;
+	vprintf(msg, args);
+	va_end(args);
+}
+
 static inline int ksft_exit_pass(void)
 {
 	ksft_print_cnts();
diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h
index 42ec3ca29c4b..684c5676dfcb 100644
--- a/tools/testing/selftests/kselftest_harness.h
+++ b/tools/testing/selftests/kselftest_harness.h
@@ -1113,6 +1113,7 @@ void __run_test(struct __fixture_metadata *f,
 		struct __test_metadata *t)
 {
 	char test_name[LINE_MAX];
+	const char *diagnostic;
 
 	/* reset test struct */
 	t->exit_code = KSFT_PASS;
@@ -1144,9 +1145,13 @@ void __run_test(struct __fixture_metadata *f,
 	ksft_print_msg("         %4s  %s\n",
 		       __test_passed(t) ? "OK" : "FAIL", test_name);
 
+	if (t->results->reason[0])
+		diagnostic = t->results->reason;
+	else
+		diagnostic = "unknown";
+
 	if (t->exit_code == KSFT_SKIP)
-		ksft_test_result_skip("%s\n", t->results->reason[0] ?
-					t->results->reason : "unknown");
+		ksft_test_result_code(t->exit_code, "%s\n", diagnostic);
 	else
 		ksft_test_result(__test_passed(t), "%s\n", test_name);
 }
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH net-next v3 07/11] selftests: kselftest_harness: print test name for SKIP
  2024-02-20 19:22 [PATCH net-next v3 00/11] selftests: kselftest_harness: support using xfail Jakub Kicinski
                   ` (5 preceding siblings ...)
  2024-02-20 19:22 ` [PATCH net-next v3 06/11] selftests: kselftest: add ksft_test_result_code(), handling all exit codes Jakub Kicinski
@ 2024-02-20 19:22 ` Jakub Kicinski
  2024-02-21  0:50   ` Kees Cook
  2024-02-20 19:22 ` [PATCH net-next v3 08/11] selftests: kselftest_harness: separate diagnostic message with # in ksft_test_result_code() Jakub Kicinski
                   ` (5 subsequent siblings)
  12 siblings, 1 reply; 28+ messages in thread
From: Jakub Kicinski @ 2024-02-20 19:22 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, shuah, linux-kselftest, mic,
	linux-security-module, keescook, jakub, Jakub Kicinski

Jakub points out that for parsers it's rather useful to always
have the test name on the result line. Currently if we SKIP
(or soon XFAIL or XPASS), we will print:

ok 17 # SKIP SCTP doesn't support IP_BIND_ADDRESS_NO_PORT

     ^
     no test name

Always print the test name.
KTAP format seems to allow or even call for it, per:
https://docs.kernel.org/dev-tools/ktap.html

Suggested-by: Jakub Sitnicki <jakub@cloudflare.com>
Link: https://lore.kernel.org/all/87jzn6lnou.fsf@cloudflare.com/
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 tools/testing/selftests/kselftest.h         | 7 ++++---
 tools/testing/selftests/kselftest_harness.h | 3 ++-
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/tools/testing/selftests/kselftest.h b/tools/testing/selftests/kselftest.h
index 12ad7f8dfe3a..25e29626566e 100644
--- a/tools/testing/selftests/kselftest.h
+++ b/tools/testing/selftests/kselftest.h
@@ -255,8 +255,9 @@ static inline __printf(1, 2) void ksft_test_result_error(const char *msg, ...)
 	va_end(args);
 }
 
-static inline __printf(2, 3)
-void ksft_test_result_code(int exit_code, const char *msg, ...)
+static inline __printf(3, 4)
+void ksft_test_result_code(int exit_code, const char *test_name,
+			   const char *msg, ...)
 {
 	const char *tap_code = "ok";
 	const char *directive = "";
@@ -287,7 +288,7 @@ void ksft_test_result_code(int exit_code, const char *msg, ...)
 	}
 
 	va_start(args, msg);
-	printf("%s %u%s", tap_code, ksft_test_num(), directive);
+	printf("%s %u %s%s", tap_code, ksft_test_num(), test_name, directive);
 	errno = saved_errno;
 	vprintf(msg, args);
 	va_end(args);
diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h
index 684c5676dfcb..a1a794e4b8f6 100644
--- a/tools/testing/selftests/kselftest_harness.h
+++ b/tools/testing/selftests/kselftest_harness.h
@@ -1151,7 +1151,8 @@ void __run_test(struct __fixture_metadata *f,
 		diagnostic = "unknown";
 
 	if (t->exit_code == KSFT_SKIP)
-		ksft_test_result_code(t->exit_code, "%s\n", diagnostic);
+		ksft_test_result_code(t->exit_code, test_name,
+				      "%s\n", diagnostic);
 	else
 		ksft_test_result(__test_passed(t), "%s\n", test_name);
 }
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH net-next v3 08/11] selftests: kselftest_harness: separate diagnostic message with # in ksft_test_result_code()
  2024-02-20 19:22 [PATCH net-next v3 00/11] selftests: kselftest_harness: support using xfail Jakub Kicinski
                   ` (6 preceding siblings ...)
  2024-02-20 19:22 ` [PATCH net-next v3 07/11] selftests: kselftest_harness: print test name for SKIP Jakub Kicinski
@ 2024-02-20 19:22 ` Jakub Kicinski
  2024-02-21  0:50   ` Kees Cook
  2024-02-20 19:22 ` [PATCH net-next v3 09/11] selftests: kselftest_harness: let PASS / FAIL provide diagnostic Jakub Kicinski
                   ` (4 subsequent siblings)
  12 siblings, 1 reply; 28+ messages in thread
From: Jakub Kicinski @ 2024-02-20 19:22 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, shuah, linux-kselftest, mic,
	linux-security-module, keescook, jakub, Jakub Kicinski

According to the spec we should always print a # if we add
a diagnostic message. Having the caller pass in the new line
as part of diagnostic message makes handling this a bit
counter-intuitive, so append the new line in the helper.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 tools/testing/selftests/kselftest.h         | 5 +++++
 tools/testing/selftests/kselftest_harness.h | 2 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/kselftest.h b/tools/testing/selftests/kselftest.h
index 25e29626566e..541bf192e30e 100644
--- a/tools/testing/selftests/kselftest.h
+++ b/tools/testing/selftests/kselftest.h
@@ -287,10 +287,15 @@ void ksft_test_result_code(int exit_code, const char *test_name,
 		break;
 	}
 
+	/* Docs seem to call for double space if directive is absent */
+	if (!directive[0] && msg[0])
+		directive = " #  ";
+
 	va_start(args, msg);
 	printf("%s %u %s%s", tap_code, ksft_test_num(), test_name, directive);
 	errno = saved_errno;
 	vprintf(msg, args);
+	printf("\n");
 	va_end(args);
 }
 
diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h
index a1a794e4b8f6..6157a7b059c6 100644
--- a/tools/testing/selftests/kselftest_harness.h
+++ b/tools/testing/selftests/kselftest_harness.h
@@ -1152,7 +1152,7 @@ void __run_test(struct __fixture_metadata *f,
 
 	if (t->exit_code == KSFT_SKIP)
 		ksft_test_result_code(t->exit_code, test_name,
-				      "%s\n", diagnostic);
+				      "%s", diagnostic);
 	else
 		ksft_test_result(__test_passed(t), "%s\n", test_name);
 }
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH net-next v3 09/11] selftests: kselftest_harness: let PASS / FAIL provide diagnostic
  2024-02-20 19:22 [PATCH net-next v3 00/11] selftests: kselftest_harness: support using xfail Jakub Kicinski
                   ` (7 preceding siblings ...)
  2024-02-20 19:22 ` [PATCH net-next v3 08/11] selftests: kselftest_harness: separate diagnostic message with # in ksft_test_result_code() Jakub Kicinski
@ 2024-02-20 19:22 ` Jakub Kicinski
  2024-02-21  0:52   ` Kees Cook
  2024-02-20 19:22 ` [PATCH net-next v3 10/11] selftests: kselftest_harness: support using xfail Jakub Kicinski
                   ` (3 subsequent siblings)
  12 siblings, 1 reply; 28+ messages in thread
From: Jakub Kicinski @ 2024-02-20 19:22 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, shuah, linux-kselftest, mic,
	linux-security-module, keescook, jakub, Jakub Kicinski

Switch to printing KTAP line for PASS / FAIL with ksft_test_result_code(),
this gives us the ability to report diagnostic messages.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 tools/testing/selftests/kselftest_harness.h | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h
index 6157a7b059c6..7c3d19bf4220 100644
--- a/tools/testing/selftests/kselftest_harness.h
+++ b/tools/testing/selftests/kselftest_harness.h
@@ -1147,14 +1147,13 @@ void __run_test(struct __fixture_metadata *f,
 
 	if (t->results->reason[0])
 		diagnostic = t->results->reason;
+	else if (t->exit_code == KSFT_PASS || t->exit_code == KSFT_FAIL)
+		diagnostic = NULL;
 	else
 		diagnostic = "unknown";
 
-	if (t->exit_code == KSFT_SKIP)
-		ksft_test_result_code(t->exit_code, test_name,
-				      "%s", diagnostic);
-	else
-		ksft_test_result(__test_passed(t), "%s\n", test_name);
+	ksft_test_result_code(t->exit_code, test_name,
+			      diagnostic ? "%s" : "", diagnostic);
 }
 
 static int test_harness_run(int argc, char **argv)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH net-next v3 10/11] selftests: kselftest_harness: support using xfail
  2024-02-20 19:22 [PATCH net-next v3 00/11] selftests: kselftest_harness: support using xfail Jakub Kicinski
                   ` (8 preceding siblings ...)
  2024-02-20 19:22 ` [PATCH net-next v3 09/11] selftests: kselftest_harness: let PASS / FAIL provide diagnostic Jakub Kicinski
@ 2024-02-20 19:22 ` Jakub Kicinski
  2024-02-21  0:52   ` Kees Cook
  2024-02-20 19:22 ` [PATCH net-next v3 11/11] selftests: ip_local_port_range: use XFAIL instead of SKIP Jakub Kicinski
                   ` (2 subsequent siblings)
  12 siblings, 1 reply; 28+ messages in thread
From: Jakub Kicinski @ 2024-02-20 19:22 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, shuah, linux-kselftest, mic,
	linux-security-module, keescook, jakub, Jakub Kicinski

Currently some tests report skip for things they expect to fail
e.g. when given combination of parameters is known to be unsupported.
This is confusing because in an ideal test environment and fully
featured kernel no tests should be skipped.

Selftest summary line already includes xfail and xpass counters,
e.g.:

but there's no way to use it from within the harness.

Add a new per-fixture+variant combination list of test cases
we expect to fail.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
v3: change the paradigm to declarative
---
 tools/testing/selftests/kselftest_harness.h | 49 ++++++++++++++++++++-
 1 file changed, 48 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h
index 7c3d19bf4220..1ade9fac0b5f 100644
--- a/tools/testing/selftests/kselftest_harness.h
+++ b/tools/testing/selftests/kselftest_harness.h
@@ -800,6 +800,37 @@ struct __fixture_metadata {
 	.prev = &_fixture_global,
 };
 
+struct __test_xfail {
+	struct __fixture_metadata *fixture;
+	struct __fixture_variant_metadata *variant;
+	struct __test_metadata *test;
+	struct __test_xfail *prev, *next;
+};
+
+/**
+ * XFAIL_ADD() - mark variant + test case combination as expected to fail
+ * @fixture_name: name of the fixture
+ * @variant_name: name of the variant
+ * @test_name: name of the test case
+ *
+ * Mark a combination of variant + test case for a given fixture as expected
+ * to fail. Tests marked this way will report XPASS / XFAIL return codes,
+ * instead of PASS / FAIL,and use respective counters.
+ */
+#define XFAIL_ADD(fixture_name, variant_name, test_name) \
+	static struct __test_xfail \
+		_##fixture_name##_##variant_name##_##test_name##_xfail = \
+	{ \
+		.fixture = &_##fixture_name##_fixture_object, \
+		.variant = &_##fixture_name##_##variant_name##_object, \
+		.test = &_##fixture_name##_##test_name##_object, \
+	}; \
+	static void __attribute__((constructor)) \
+		_register_##fixture_name##_##variant_name##_##test_name##_xfail(void) \
+	{ \
+		__register_xfail(&_##fixture_name##_##variant_name##_##test_name##_xfail); \
+	}
+
 static struct __fixture_metadata *__fixture_list = &_fixture_global;
 static int __constructor_order;
 
@@ -814,6 +845,7 @@ static inline void __register_fixture(struct __fixture_metadata *f)
 struct __fixture_variant_metadata {
 	const char *name;
 	const void *data;
+	struct __test_xfail *xfails;
 	struct __fixture_variant_metadata *prev, *next;
 };
 
@@ -864,6 +896,11 @@ static inline void __register_test(struct __test_metadata *t)
 	__LIST_APPEND(t->fixture->tests, t);
 }
 
+static inline void __register_xfail(struct __test_xfail *xf)
+{
+	__LIST_APPEND(xf->variant->xfails, xf);
+}
+
 static inline int __bail(int for_realz, struct __test_metadata *t)
 {
 	/* if this is ASSERT, return immediately. */
@@ -942,7 +979,9 @@ void __wait_for_test(struct __test_metadata *t)
 		fprintf(TH_LOG_STREAM,
 			"# %s: Test terminated by timeout\n", t->name);
 	} else if (WIFEXITED(status)) {
-		if (WEXITSTATUS(status) == KSFT_SKIP) {
+		if (WEXITSTATUS(status) == KSFT_SKIP ||
+		    WEXITSTATUS(status) == KSFT_XPASS ||
+		    WEXITSTATUS(status) == KSFT_XFAIL) {
 			t->exit_code = WEXITSTATUS(status);
 		} else if (t->termsig != -1) {
 			t->exit_code = KSFT_FAIL;
@@ -1112,6 +1151,7 @@ void __run_test(struct __fixture_metadata *f,
 		struct __fixture_variant_metadata *variant,
 		struct __test_metadata *t)
 {
+	struct __test_xfail *xfail;
 	char test_name[LINE_MAX];
 	const char *diagnostic;
 
@@ -1145,6 +1185,13 @@ void __run_test(struct __fixture_metadata *f,
 	ksft_print_msg("         %4s  %s\n",
 		       __test_passed(t) ? "OK" : "FAIL", test_name);
 
+	/* Check if we're expecting this test to fail */
+	for (xfail = variant->xfails; xfail; xfail = xfail->next)
+		if (xfail->test == t)
+			break;
+	if (xfail)
+		t->exit_code = __test_passed(t) ? KSFT_XPASS : KSFT_XFAIL;
+
 	if (t->results->reason[0])
 		diagnostic = t->results->reason;
 	else if (t->exit_code == KSFT_PASS || t->exit_code == KSFT_FAIL)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH net-next v3 11/11] selftests: ip_local_port_range: use XFAIL instead of SKIP
  2024-02-20 19:22 [PATCH net-next v3 00/11] selftests: kselftest_harness: support using xfail Jakub Kicinski
                   ` (9 preceding siblings ...)
  2024-02-20 19:22 ` [PATCH net-next v3 10/11] selftests: kselftest_harness: support using xfail Jakub Kicinski
@ 2024-02-20 19:22 ` Jakub Kicinski
  2024-02-21 12:03 ` [PATCH net-next v3 00/11] selftests: kselftest_harness: support using xfail Paolo Abeni
  2024-02-24  0:02 ` Jakub Kicinski
  12 siblings, 0 replies; 28+ messages in thread
From: Jakub Kicinski @ 2024-02-20 19:22 UTC (permalink / raw)
  To: davem
  Cc: netdev, edumazet, pabeni, shuah, linux-kselftest, mic,
	linux-security-module, keescook, jakub, Jakub Kicinski

SCTP does not support IP_LOCAL_PORT_RANGE and we know it,
so use XFAIL instead of SKIP.

Reviewed-by: Kees Cook <keescook@chromium.org>
Tested-by: Jakub Sitnicki <jakub@cloudflare.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 tools/testing/selftests/net/ip_local_port_range.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/net/ip_local_port_range.c b/tools/testing/selftests/net/ip_local_port_range.c
index 6ebd58869a63..193b82745fd8 100644
--- a/tools/testing/selftests/net/ip_local_port_range.c
+++ b/tools/testing/selftests/net/ip_local_port_range.c
@@ -365,9 +365,6 @@ TEST_F(ip_local_port_range, late_bind)
 	__u32 range;
 	__u16 port;
 
-	if (variant->so_protocol == IPPROTO_SCTP)
-		SKIP(return, "SCTP doesn't support IP_BIND_ADDRESS_NO_PORT");
-
 	fd = socket(variant->so_domain, variant->so_type, 0);
 	ASSERT_GE(fd, 0) TH_LOG("socket failed");
 
@@ -414,6 +411,9 @@ TEST_F(ip_local_port_range, late_bind)
 	ASSERT_TRUE(!err) TH_LOG("close failed");
 }
 
+XFAIL_ADD(ip_local_port_range, ip4_stcp, late_bind);
+XFAIL_ADD(ip_local_port_range, ip6_stcp, late_bind);
+
 TEST_F(ip_local_port_range, get_port_range)
 {
 	__u16 lo, hi;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [PATCH net-next v3 05/11] selftests: kselftest_harness: use exit code to store skip
  2024-02-20 19:22 ` [PATCH net-next v3 05/11] selftests: kselftest_harness: use exit code to store skip Jakub Kicinski
@ 2024-02-21  0:49   ` Kees Cook
  0 siblings, 0 replies; 28+ messages in thread
From: Kees Cook @ 2024-02-21  0:49 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: davem, netdev, edumazet, pabeni, shuah, linux-kselftest, mic,
	linux-security-module, jakub

On Tue, Feb 20, 2024 at 11:22:29AM -0800, Jakub Kicinski wrote:
> We always use skip in combination with exit_code being 0
> (KSFT_PASS). This are basic KSFT / KTAP semantics.
> Store the right KSFT_* code in exit_code directly.
> 
> This makes it easier to support tests reporting other
> extended KSFT_* codes like XFAIL / XPASS.
> 
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>

Reviewed-by: Kees Cook <keescook@chromium.org>

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH net-next v3 06/11] selftests: kselftest: add ksft_test_result_code(), handling all exit codes
  2024-02-20 19:22 ` [PATCH net-next v3 06/11] selftests: kselftest: add ksft_test_result_code(), handling all exit codes Jakub Kicinski
@ 2024-02-21  0:49   ` Kees Cook
  0 siblings, 0 replies; 28+ messages in thread
From: Kees Cook @ 2024-02-21  0:49 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: davem, netdev, edumazet, pabeni, shuah, linux-kselftest, mic,
	linux-security-module, jakub

On Tue, Feb 20, 2024 at 11:22:30AM -0800, Jakub Kicinski wrote:
> For generic test harness code it's more useful to deal with exit
> codes directly, rather than having to switch on them and call
> the right ksft_test_result_*() helper. Add such function to kselftest.h.
> 
> Note that "directive" and "diagnostic" are what ktap docs call
> those parts of the message.
> 
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>

Reviewed-by: Kees Cook <keescook@chromium.org>

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH net-next v3 07/11] selftests: kselftest_harness: print test name for SKIP
  2024-02-20 19:22 ` [PATCH net-next v3 07/11] selftests: kselftest_harness: print test name for SKIP Jakub Kicinski
@ 2024-02-21  0:50   ` Kees Cook
  0 siblings, 0 replies; 28+ messages in thread
From: Kees Cook @ 2024-02-21  0:50 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: davem, netdev, edumazet, pabeni, shuah, linux-kselftest, mic,
	linux-security-module, jakub

On Tue, Feb 20, 2024 at 11:22:31AM -0800, Jakub Kicinski wrote:
> Jakub points out that for parsers it's rather useful to always
> have the test name on the result line. Currently if we SKIP
> (or soon XFAIL or XPASS), we will print:
> 
> ok 17 # SKIP SCTP doesn't support IP_BIND_ADDRESS_NO_PORT
> 
>      ^
>      no test name
> 
> Always print the test name.
> KTAP format seems to allow or even call for it, per:
> https://docs.kernel.org/dev-tools/ktap.html
> 
> Suggested-by: Jakub Sitnicki <jakub@cloudflare.com>
> Link: https://lore.kernel.org/all/87jzn6lnou.fsf@cloudflare.com/
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>

Reviewed-by: Kees Cook <keescook@chromium.org>

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH net-next v3 08/11] selftests: kselftest_harness: separate diagnostic message with # in ksft_test_result_code()
  2024-02-20 19:22 ` [PATCH net-next v3 08/11] selftests: kselftest_harness: separate diagnostic message with # in ksft_test_result_code() Jakub Kicinski
@ 2024-02-21  0:50   ` Kees Cook
  0 siblings, 0 replies; 28+ messages in thread
From: Kees Cook @ 2024-02-21  0:50 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: davem, netdev, edumazet, pabeni, shuah, linux-kselftest, mic,
	linux-security-module, jakub

On Tue, Feb 20, 2024 at 11:22:32AM -0800, Jakub Kicinski wrote:
> According to the spec we should always print a # if we add
> a diagnostic message. Having the caller pass in the new line
> as part of diagnostic message makes handling this a bit
> counter-intuitive, so append the new line in the helper.
> 
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>

Reviewed-by: Kees Cook <keescook@chromium.org>

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH net-next v3 10/11] selftests: kselftest_harness: support using xfail
  2024-02-20 19:22 ` [PATCH net-next v3 10/11] selftests: kselftest_harness: support using xfail Jakub Kicinski
@ 2024-02-21  0:52   ` Kees Cook
  0 siblings, 0 replies; 28+ messages in thread
From: Kees Cook @ 2024-02-21  0:52 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: davem, netdev, edumazet, pabeni, shuah, linux-kselftest, mic,
	linux-security-module, jakub

On Tue, Feb 20, 2024 at 11:22:34AM -0800, Jakub Kicinski wrote:
> Currently some tests report skip for things they expect to fail
> e.g. when given combination of parameters is known to be unsupported.
> This is confusing because in an ideal test environment and fully
> featured kernel no tests should be skipped.
> 
> Selftest summary line already includes xfail and xpass counters,
> e.g.:
> 
> but there's no way to use it from within the harness.
> 
> Add a new per-fixture+variant combination list of test cases
> we expect to fail.
> 
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>

Thanks for this implementation; this will work nicely. :)

Reviewed-by: Kees Cook <keescook@chromium.org>

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH net-next v3 09/11] selftests: kselftest_harness: let PASS / FAIL provide diagnostic
  2024-02-20 19:22 ` [PATCH net-next v3 09/11] selftests: kselftest_harness: let PASS / FAIL provide diagnostic Jakub Kicinski
@ 2024-02-21  0:52   ` Kees Cook
  0 siblings, 0 replies; 28+ messages in thread
From: Kees Cook @ 2024-02-21  0:52 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: davem, netdev, edumazet, pabeni, shuah, linux-kselftest, mic,
	linux-security-module, jakub

On Tue, Feb 20, 2024 at 11:22:33AM -0800, Jakub Kicinski wrote:
> Switch to printing KTAP line for PASS / FAIL with ksft_test_result_code(),
> this gives us the ability to report diagnostic messages.
> 
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>

Reviewed-by: Kees Cook <keescook@chromium.org>

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH net-next v3 00/11] selftests: kselftest_harness: support using xfail
  2024-02-20 19:22 [PATCH net-next v3 00/11] selftests: kselftest_harness: support using xfail Jakub Kicinski
                   ` (10 preceding siblings ...)
  2024-02-20 19:22 ` [PATCH net-next v3 11/11] selftests: ip_local_port_range: use XFAIL instead of SKIP Jakub Kicinski
@ 2024-02-21 12:03 ` Paolo Abeni
  2024-02-23 17:48   ` Kees Cook
  2024-02-24  0:02 ` Jakub Kicinski
  12 siblings, 1 reply; 28+ messages in thread
From: Paolo Abeni @ 2024-02-21 12:03 UTC (permalink / raw)
  To: shuah
  Cc: netdev, edumazet, linux-kselftest, mic, linux-security-module,
	keescook, jakub, Jakub Kicinski, davem

On Tue, 2024-02-20 at 11:22 -0800, Jakub Kicinski wrote:
> When running selftests for our subsystem in our CI we'd like all
> tests to pass. Currently some tests use SKIP for cases they
> expect to fail, because the kselftest_harness limits the return
> codes to pass/fail/skip.
> 
> Clean up and support the use of the full range of ksft exit codes
> under kselftest_harness.
> 
> Merge plan is to put it on top of -rc4 and merge into net-next.
> That way others should be able to pull the patches without
> any networking changes.
> 
> v2: https://lore.kernel.org/all/20240216002619.1999225-1-kuba@kernel.org/
>  - fix alignment
> follow up RFC: https://lore.kernel.org/all/20240216004122.2004689-1-kuba@kernel.org/
> v1: https://lore.kernel.org/all/20240213154416.422739-1-kuba@kernel.org/

@Shuah: it's not clear to me if you prefer to take this series via the
kselftests tree or we can take it via the net-next tree. Could you
please advise?

thanks!

Paolo

p.s. if this was already clarified in the past, I'm sorry: I lost track
of it.


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH net-next v3 00/11] selftests: kselftest_harness: support using xfail
  2024-02-21 12:03 ` [PATCH net-next v3 00/11] selftests: kselftest_harness: support using xfail Paolo Abeni
@ 2024-02-23 17:48   ` Kees Cook
  0 siblings, 0 replies; 28+ messages in thread
From: Kees Cook @ 2024-02-23 17:48 UTC (permalink / raw)
  To: shuah, Paolo Abeni
  Cc: netdev, edumazet, linux-kselftest, mic, linux-security-module,
	jakub, Jakub Kicinski, davem

On Wed, Feb 21, 2024 at 01:03:26PM +0100, Paolo Abeni wrote:
> On Tue, 2024-02-20 at 11:22 -0800, Jakub Kicinski wrote:
> > When running selftests for our subsystem in our CI we'd like all
> > tests to pass. Currently some tests use SKIP for cases they
> > expect to fail, because the kselftest_harness limits the return
> > codes to pass/fail/skip.
> > 
> > Clean up and support the use of the full range of ksft exit codes
> > under kselftest_harness.
> > 
> > Merge plan is to put it on top of -rc4 and merge into net-next.
> > That way others should be able to pull the patches without
> > any networking changes.
> > 
> > v2: https://lore.kernel.org/all/20240216002619.1999225-1-kuba@kernel.org/
> >  - fix alignment
> > follow up RFC: https://lore.kernel.org/all/20240216004122.2004689-1-kuba@kernel.org/
> > v1: https://lore.kernel.org/all/20240213154416.422739-1-kuba@kernel.org/
> 
> @Shuah: it's not clear to me if you prefer to take this series via the
> kselftests tree or we can take it via the net-next tree. Could you
> please advise?
> 
> thanks!
> 
> Paolo
> 
> p.s. if this was already clarified in the past, I'm sorry: I lost track
> of it.

Given the urgency for net-dev and the lack of conflicts with other
kselftest changes (AFAICT), I would assume it would be fine to carry
this in net-dev (especially since the merge window fast approaches).

Shuah, any objection?

-Kees

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH net-next v3 00/11] selftests: kselftest_harness: support using xfail
  2024-02-20 19:22 [PATCH net-next v3 00/11] selftests: kselftest_harness: support using xfail Jakub Kicinski
                   ` (11 preceding siblings ...)
  2024-02-21 12:03 ` [PATCH net-next v3 00/11] selftests: kselftest_harness: support using xfail Paolo Abeni
@ 2024-02-24  0:02 ` Jakub Kicinski
  2024-02-26 16:23   ` [PATCH 0/2] Merge TEST_F_FORK() into TEST_F() Mickaël Salaün
  2024-02-26 16:27   ` [PATCH net-next v3 00/11] selftests: kselftest_harness: support using xfail Mickaël Salaün
  12 siblings, 2 replies; 28+ messages in thread
From: Jakub Kicinski @ 2024-02-24  0:02 UTC (permalink / raw)
  To: mic
  Cc: davem, netdev, edumazet, pabeni, shuah, linux-kselftest,
	linux-security-module, keescook, jakub

On Tue, 20 Feb 2024 11:22:24 -0800 Jakub Kicinski wrote:
> When running selftests for our subsystem in our CI we'd like all
> tests to pass. Currently some tests use SKIP for cases they
> expect to fail, because the kselftest_harness limits the return
> codes to pass/fail/skip.
> 
> Clean up and support the use of the full range of ksft exit codes
> under kselftest_harness.
> 
> Merge plan is to put it on top of -rc4 and merge into net-next.
> That way others should be able to pull the patches without
> any networking changes.

Hi Mickaël,

would you be able to take a look at those changes? landlock seems to be
the sole user of the "no_print" functionality in the selftest harness.
If the patches look good I'll create a branch based on Linus's tree
so that anyone interested can pull the changes in..

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 0/2] Merge TEST_F_FORK() into TEST_F()
  2024-02-24  0:02 ` Jakub Kicinski
@ 2024-02-26 16:23   ` Mickaël Salaün
  2024-02-26 16:23     ` [PATCH 1/2] selftests/landlock: Redefine TEST_F() as TEST_F_FORK() Mickaël Salaün
  2024-02-26 16:23     ` [PATCH 2/2] selftests/harness: Merge TEST_F_FORK() into TEST_F() Mickaël Salaün
  2024-02-26 16:27   ` [PATCH net-next v3 00/11] selftests: kselftest_harness: support using xfail Mickaël Salaün
  1 sibling, 2 replies; 28+ messages in thread
From: Mickaël Salaün @ 2024-02-26 16:23 UTC (permalink / raw)
  To: Jakub Kicinski, Kees Cook, Shuah Khan, davem
  Cc: Mickaël Salaün, Günther Noack, Will Drewry,
	edumazet, jakub, pabeni, linux-kernel, linux-kselftest,
	linux-security-module, netdev

Hi,

This is a long due cleanup to merge TEST_F_FORK() into TEST_F().

This should simplify Jakub's patches by removing the step counter:
https://lore.kernel.org/r/20240220192235.2953484-1-kuba@kernel.org

Regards,

Mickaël Salaün (2):
  selftests/landlock: Redefine TEST_F() as TEST_F_FORK()
  selftests/harness: Merge TEST_F_FORK() into TEST_F()

 tools/testing/selftests/kselftest_harness.h | 56 +++++++++-----------
 tools/testing/selftests/landlock/common.h   | 58 +--------------------
 2 files changed, 27 insertions(+), 87 deletions(-)

-- 
2.44.0


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 1/2] selftests/landlock: Redefine TEST_F() as TEST_F_FORK()
  2024-02-26 16:23   ` [PATCH 0/2] Merge TEST_F_FORK() into TEST_F() Mickaël Salaün
@ 2024-02-26 16:23     ` Mickaël Salaün
  2024-02-26 16:23     ` [PATCH 2/2] selftests/harness: Merge TEST_F_FORK() into TEST_F() Mickaël Salaün
  1 sibling, 0 replies; 28+ messages in thread
From: Mickaël Salaün @ 2024-02-26 16:23 UTC (permalink / raw)
  To: Jakub Kicinski, Kees Cook, Shuah Khan, davem
  Cc: Mickaël Salaün, Günther Noack, Will Drewry,
	edumazet, jakub, pabeni, linux-kernel, linux-kselftest,
	linux-security-module, netdev

This has the effect of creating a new test process for either TEST_F()
or TEST_F_FORK(), which doesn't change tests but will ease potential
backports.  See next commit for the TEST_F_FORK() merge into TEST_F().

Cc: Günther Noack <gnoack@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Kees Cook <keescook@chromium.org>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Will Drewry <wad@chromium.org>
Signed-off-by: Mickaël Salaün <mic@digikod.net>
---
 tools/testing/selftests/landlock/common.h | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/landlock/common.h b/tools/testing/selftests/landlock/common.h
index 425c5698aea2..0bc15d36971a 100644
--- a/tools/testing/selftests/landlock/common.h
+++ b/tools/testing/selftests/landlock/common.h
@@ -37,7 +37,7 @@
 		struct __test_metadata *_metadata, \
 		FIXTURE_DATA(fixture_name) *self, \
 		const FIXTURE_VARIANT(fixture_name) *variant); \
-	TEST_F(fixture_name, test_name) \
+	__TEST_F_IMPL(fixture_name, test_name, -1, TEST_TIMEOUT_DEFAULT) \
 	{ \
 		int status; \
 		const pid_t child = fork(); \
@@ -80,6 +80,10 @@
 			__attribute__((unused)) *variant)
 /* clang-format on */
 
+/* Makes backporting easier. */
+#undef TEST_F
+#define TEST_F(fixture_name, test_name) TEST_F_FORK(fixture_name, test_name)
+
 #ifndef landlock_create_ruleset
 static inline int
 landlock_create_ruleset(const struct landlock_ruleset_attr *const attr,
-- 
2.44.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* [PATCH 2/2] selftests/harness: Merge TEST_F_FORK() into TEST_F()
  2024-02-26 16:23   ` [PATCH 0/2] Merge TEST_F_FORK() into TEST_F() Mickaël Salaün
  2024-02-26 16:23     ` [PATCH 1/2] selftests/landlock: Redefine TEST_F() as TEST_F_FORK() Mickaël Salaün
@ 2024-02-26 16:23     ` Mickaël Salaün
  2024-02-26 19:04       ` Kees Cook
  1 sibling, 1 reply; 28+ messages in thread
From: Mickaël Salaün @ 2024-02-26 16:23 UTC (permalink / raw)
  To: Jakub Kicinski, Kees Cook, Shuah Khan, davem
  Cc: Mickaël Salaün, Günther Noack, Will Drewry,
	edumazet, jakub, pabeni, linux-kernel, linux-kselftest,
	linux-security-module, netdev

Remplace Landlock-specific TEST_F_FORK() with an improved TEST_F() which
brings four related changes:

Run TEST_F()'s tests in a grandchild process to make it possible to
drop privileges and delegate teardown to the parent.

Compared to TEST_F_FORK(), simplify handling of the test grandchild
process thanks to vfork(2), and makes it generic (e.g. no explicit
conversion between exit code and _metadata).

Compared to TEST_F_FORK(), run teardown even when tests failed with an
assert thanks to commit 63e6b2a42342 ("selftests/harness: Run TEARDOWN
for ASSERT failures").

Simplify the test harness code by removing the no_print and step fields
which are not used.  I added this feature just after I made
kselftest_harness.h more broadly available but this step counter
remained even though it wasn't needed after all. See commit 369130b63178
("selftests: Enhance kselftest_harness.h to print which assert failed").

Replace spaces with tabs in one line of __TEST_F_IMPL().

Cc: Günther Noack <gnoack@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Kees Cook <keescook@chromium.org>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Will Drewry <wad@chromium.org>
Signed-off-by: Mickaël Salaün <mic@digikod.net>
---
 tools/testing/selftests/kselftest_harness.h | 56 +++++++++----------
 tools/testing/selftests/landlock/common.h   | 62 +--------------------
 2 files changed, 27 insertions(+), 91 deletions(-)

diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h
index e05ac8261046..841d34deb1a6 100644
--- a/tools/testing/selftests/kselftest_harness.h
+++ b/tools/testing/selftests/kselftest_harness.h
@@ -95,14 +95,6 @@
  * E.g., #define TH_LOG_ENABLED 1
  *
  * If no definition is provided, logging is enabled by default.
- *
- * If there is no way to print an error message for the process running the
- * test (e.g. not allowed to write to stderr), it is still possible to get the
- * ASSERT_* number for which the test failed.  This behavior can be enabled by
- * writing `_metadata->no_print = true;` before the check sequence that is
- * unable to print.  When an error occur, instead of printing an error message
- * and calling `abort(3)`, the test process call `_exit(2)` with the assert
- * number as argument, which is then printed by the parent process.
  */
 #define TH_LOG(fmt, ...) do { \
 	if (TH_LOG_ENABLED) \
@@ -363,6 +355,11 @@
  * Defines a test that depends on a fixture (e.g., is part of a test case).
  * Very similar to TEST() except that *self* is the setup instance of fixture's
  * datatype exposed for use by the implementation.
+ *
+ * The @test_name code is run in a separate process sharing the same memory
+ * (i.e. vfork), which means that the test process can update its privileges
+ * without impacting the related FIXTURE_TEARDOWN() (e.g. to remove files from
+ * a directory where write access was dropped).
  */
 #define TEST_F(fixture_name, test_name) \
 	__TEST_F_IMPL(fixture_name, test_name, -1, TEST_TIMEOUT_DEFAULT)
@@ -384,15 +381,28 @@
 	{ \
 		/* fixture data is alloced, setup, and torn down per call. */ \
 		FIXTURE_DATA(fixture_name) self; \
+		pid_t child; \
 		memset(&self, 0, sizeof(FIXTURE_DATA(fixture_name))); \
 		if (setjmp(_metadata->env) == 0) { \
 			fixture_name##_setup(_metadata, &self, variant->data); \
 			/* Let setup failure terminate early. */ \
-                       if (!_metadata->passed || _metadata->skip) \
+			if (!_metadata->passed || _metadata->skip) \
 				return; \
 			_metadata->setup_completed = true; \
-			fixture_name##_##test_name(_metadata, &self, variant->data); \
+			/* Use the same _metadata. */ \
+			child = vfork(); \
+			if (child == 0) { \
+				fixture_name##_##test_name(_metadata, &self, variant->data); \
+				_exit(0); \
+			} \
+			if (child < 0) { \
+				ksft_print_msg("ERROR SPAWNING TEST GANDCHILD\n"); \
+				_metadata->passed = 0; \
+			} \
 		} \
+		if (child == 0) \
+			/* Child failed and updated the shared _metadata. */ \
+			_exit(0); \
 		if (_metadata->setup_completed) \
 			fixture_name##_teardown(_metadata, &self, variant->data); \
 		__test_check_assert(_metadata); \
@@ -694,18 +704,12 @@
 	for (; _metadata->trigger; _metadata->trigger = \
 			__bail(_assert, _metadata))
 
-#define __INC_STEP(_metadata) \
-	/* Keep "step" below 255 (which is used for "SKIP" reporting). */	\
-	if (_metadata->passed && _metadata->step < 253) \
-		_metadata->step++;
-
 #define is_signed_type(var)       (!!(((__typeof__(var))(-1)) < (__typeof__(var))1))
 
 #define __EXPECT(_expected, _expected_str, _seen, _seen_str, _t, _assert) do { \
 	/* Avoid multiple evaluation of the cases */ \
 	__typeof__(_expected) __exp = (_expected); \
 	__typeof__(_seen) __seen = (_seen); \
-	if (_assert) __INC_STEP(_metadata); \
 	if (!(__exp _t __seen)) { \
 		/* Report with actual signedness to avoid weird output. */ \
 		switch (is_signed_type(__exp) * 2 + is_signed_type(__seen)) { \
@@ -751,7 +755,6 @@
 #define __EXPECT_STR(_expected, _seen, _t, _assert) do { \
 	const char *__exp = (_expected); \
 	const char *__seen = (_seen); \
-	if (_assert) __INC_STEP(_metadata); \
 	if (!(strcmp(__exp, __seen) _t 0))  { \
 		__TH_LOG("Expected '%s' %s '%s'.", __exp, #_t, __seen); \
 		_metadata->passed = 0; \
@@ -837,8 +840,6 @@ struct __test_metadata {
 	int trigger; /* extra handler after the evaluation */
 	int timeout;	/* seconds to wait for test timeout */
 	bool timed_out;	/* did this test timeout instead of exiting? */
-	__u8 step;
-	bool no_print; /* manual trigger when TH_LOG_STREAM is not available */
 	bool aborted;	/* stopped test due to failed ASSERT */
 	bool setup_completed; /* did setup finish? */
 	jmp_buf env;	/* for exiting out of test early */
@@ -873,11 +874,8 @@ static inline int __bail(int for_realz, struct __test_metadata *t)
 
 static inline void __test_check_assert(struct __test_metadata *t)
 {
-	if (t->aborted) {
-		if (t->no_print)
-			_exit(t->step);
+	if (t->aborted)
 		abort();
-	}
 }
 
 struct __test_metadata *__active_test;
@@ -954,13 +952,12 @@ void __wait_for_test(struct __test_metadata *t)
 			case 0:
 				t->passed = 1;
 				break;
-			/* Other failure, assume step report. */
+			/* Failure */
 			default:
 				t->passed = 0;
 				fprintf(TH_LOG_STREAM,
-					"# %s: Test failed at step #%d\n",
-					t->name,
-					WEXITSTATUS(status));
+					"# %s: Test failed\n",
+					t->name);
 			}
 		}
 	} else if (WIFSIGNALED(status)) {
@@ -1114,8 +1111,6 @@ void __run_test(struct __fixture_metadata *f,
 	t->passed = 1;
 	t->skip = 0;
 	t->trigger = 0;
-	t->step = 1;
-	t->no_print = 0;
 	memset(t->results->reason, 0, sizeof(t->results->reason));
 
 	ksft_print_msg(" RUN           %s%s%s.%s ...\n",
@@ -1137,8 +1132,7 @@ void __run_test(struct __fixture_metadata *f,
 		/* Pass is exit 0 */
 		if (t->passed)
 			_exit(0);
-		/* Something else happened, report the step. */
-		_exit(t->step);
+		_exit(1);
 	} else {
 		__wait_for_test(t);
 	}
diff --git a/tools/testing/selftests/landlock/common.h b/tools/testing/selftests/landlock/common.h
index 0bc15d36971a..7e2b431b9f90 100644
--- a/tools/testing/selftests/landlock/common.h
+++ b/tools/testing/selftests/landlock/common.h
@@ -23,66 +23,8 @@
 #define __maybe_unused __attribute__((__unused__))
 #endif
 
-/*
- * TEST_F_FORK() is useful when a test drop privileges but the corresponding
- * FIXTURE_TEARDOWN() requires them (e.g. to remove files from a directory
- * where write actions are denied).  For convenience, FIXTURE_TEARDOWN() is
- * also called when the test failed, but not when FIXTURE_SETUP() failed.  For
- * this to be possible, we must not call abort() but instead exit smoothly
- * (hence the step print).
- */
-/* clang-format off */
-#define TEST_F_FORK(fixture_name, test_name) \
-	static void fixture_name##_##test_name##_child( \
-		struct __test_metadata *_metadata, \
-		FIXTURE_DATA(fixture_name) *self, \
-		const FIXTURE_VARIANT(fixture_name) *variant); \
-	__TEST_F_IMPL(fixture_name, test_name, -1, TEST_TIMEOUT_DEFAULT) \
-	{ \
-		int status; \
-		const pid_t child = fork(); \
-		if (child < 0) \
-			abort(); \
-		if (child == 0) { \
-			_metadata->no_print = 1; \
-			fixture_name##_##test_name##_child(_metadata, self, variant); \
-			if (_metadata->skip) \
-				_exit(255); \
-			if (_metadata->passed) \
-				_exit(0); \
-			_exit(_metadata->step); \
-		} \
-		if (child != waitpid(child, &status, 0)) \
-			abort(); \
-		if (WIFSIGNALED(status) || !WIFEXITED(status)) { \
-			_metadata->passed = 0; \
-			_metadata->step = 1; \
-			return; \
-		} \
-		switch (WEXITSTATUS(status)) { \
-		case 0: \
-			_metadata->passed = 1; \
-			break; \
-		case 255: \
-			_metadata->passed = 1; \
-			_metadata->skip = 1; \
-			break; \
-		default: \
-			_metadata->passed = 0; \
-			_metadata->step = WEXITSTATUS(status); \
-			break; \
-		} \
-	} \
-	static void fixture_name##_##test_name##_child( \
-		struct __test_metadata __attribute__((unused)) *_metadata, \
-		FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \
-		const FIXTURE_VARIANT(fixture_name) \
-			__attribute__((unused)) *variant)
-/* clang-format on */
-
-/* Makes backporting easier. */
-#undef TEST_F
-#define TEST_F(fixture_name, test_name) TEST_F_FORK(fixture_name, test_name)
+/* TEST_F_FORK() should not be used for new tests. */
+#define TEST_F_FORK(fixture_name, test_name) TEST_F(fixture_name, test_name)
 
 #ifndef landlock_create_ruleset
 static inline int
-- 
2.44.0


^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [PATCH net-next v3 00/11] selftests: kselftest_harness: support using xfail
  2024-02-24  0:02 ` Jakub Kicinski
  2024-02-26 16:23   ` [PATCH 0/2] Merge TEST_F_FORK() into TEST_F() Mickaël Salaün
@ 2024-02-26 16:27   ` Mickaël Salaün
  2024-02-26 16:53     ` Jakub Kicinski
  1 sibling, 1 reply; 28+ messages in thread
From: Mickaël Salaün @ 2024-02-26 16:27 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: davem, netdev, edumazet, pabeni, shuah, linux-kselftest,
	linux-security-module, keescook, jakub

On Fri, Feb 23, 2024 at 04:02:59PM -0800, Jakub Kicinski wrote:
> On Tue, 20 Feb 2024 11:22:24 -0800 Jakub Kicinski wrote:
> > When running selftests for our subsystem in our CI we'd like all
> > tests to pass. Currently some tests use SKIP for cases they
> > expect to fail, because the kselftest_harness limits the return
> > codes to pass/fail/skip.
> > 
> > Clean up and support the use of the full range of ksft exit codes
> > under kselftest_harness.
> > 
> > Merge plan is to put it on top of -rc4 and merge into net-next.
> > That way others should be able to pull the patches without
> > any networking changes.
> 
> Hi Mickaël,
> 
> would you be able to take a look at those changes? landlock seems to be
> the sole user of the "no_print" functionality in the selftest harness.
> If the patches look good I'll create a branch based on Linus's tree
> so that anyone interested can pull the changes in..

Hi Jakub,

I missed your patches before this series.  I just sent two patches to
clean things up before you change them.  This should simplify your
patches and improve the overall maintenance.  I'd appreciate if you
rebase on top of them.

Regards,
 Mickaël

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH net-next v3 00/11] selftests: kselftest_harness: support using xfail
  2024-02-26 16:27   ` [PATCH net-next v3 00/11] selftests: kselftest_harness: support using xfail Mickaël Salaün
@ 2024-02-26 16:53     ` Jakub Kicinski
  0 siblings, 0 replies; 28+ messages in thread
From: Jakub Kicinski @ 2024-02-26 16:53 UTC (permalink / raw)
  To: Mickaël Salaün
  Cc: davem, netdev, edumazet, pabeni, shuah, linux-kselftest,
	linux-security-module, keescook, jakub

On Mon, 26 Feb 2024 17:27:34 +0100 Mickaël Salaün wrote:
> > would you be able to take a look at those changes? landlock seems to be
> > the sole user of the "no_print" functionality in the selftest harness.
> > If the patches look good I'll create a branch based on Linus's tree
> > so that anyone interested can pull the changes in..  
> 
> Hi Jakub,
> 
> I missed your patches before this series.  I just sent two patches to
> clean things up before you change them.  This should simplify your
> patches and improve the overall maintenance.  I'd appreciate if you
> rebase on top of them.

Nice! vfork() is a bit scary so I'll give people a couple of days to
review and then post a combined+rebased series.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 2/2] selftests/harness: Merge TEST_F_FORK() into TEST_F()
  2024-02-26 16:23     ` [PATCH 2/2] selftests/harness: Merge TEST_F_FORK() into TEST_F() Mickaël Salaün
@ 2024-02-26 19:04       ` Kees Cook
  2024-02-26 20:21         ` Mickaël Salaün
  0 siblings, 1 reply; 28+ messages in thread
From: Kees Cook @ 2024-02-26 19:04 UTC (permalink / raw)
  To: Mickaël Salaün
  Cc: Jakub Kicinski, Shuah Khan, davem, Günther Noack,
	Will Drewry, edumazet, jakub, pabeni, linux-kernel,
	linux-kselftest, linux-security-module, netdev

On Mon, Feb 26, 2024 at 05:23:35PM +0100, Mickaël Salaün wrote:
> Remplace Landlock-specific TEST_F_FORK() with an improved TEST_F() which
> brings four related changes:
> 
> Run TEST_F()'s tests in a grandchild process to make it possible to
> drop privileges and delegate teardown to the parent.
> 
> Compared to TEST_F_FORK(), simplify handling of the test grandchild
> process thanks to vfork(2), and makes it generic (e.g. no explicit
> conversion between exit code and _metadata).
> 
> Compared to TEST_F_FORK(), run teardown even when tests failed with an
> assert thanks to commit 63e6b2a42342 ("selftests/harness: Run TEARDOWN
> for ASSERT failures").
> 
> Simplify the test harness code by removing the no_print and step fields
> which are not used.  I added this feature just after I made
> kselftest_harness.h more broadly available but this step counter
> remained even though it wasn't needed after all. See commit 369130b63178
> ("selftests: Enhance kselftest_harness.h to print which assert failed").

I'm personally fine dropping the step counter. (I do wonder if that
removal should be split from the grandchild launching.)

> Replace spaces with tabs in one line of __TEST_F_IMPL().
> 
> Cc: Günther Noack <gnoack@google.com>
> Cc: Jakub Kicinski <kuba@kernel.org>
> Cc: Kees Cook <keescook@chromium.org>
> Cc: Shuah Khan <shuah@kernel.org>
> Cc: Will Drewry <wad@chromium.org>
> Signed-off-by: Mickaël Salaün <mic@digikod.net>

One typo below, but otherwise seems good to me:

Reviewed-by: Kees Cook <keescook@chromium.org>


> [...]
>  			_metadata->setup_completed = true; \
> -			fixture_name##_##test_name(_metadata, &self, variant->data); \
> +			/* Use the same _metadata. */ \
> +			child = vfork(); \
> +			if (child == 0) { \
> +				fixture_name##_##test_name(_metadata, &self, variant->data); \
> +				_exit(0); \
> +			} \
> +			if (child < 0) { \
> +				ksft_print_msg("ERROR SPAWNING TEST GANDCHILD\n"); \

typo: GAND -> GRAND

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 2/2] selftests/harness: Merge TEST_F_FORK() into TEST_F()
  2024-02-26 19:04       ` Kees Cook
@ 2024-02-26 20:21         ` Mickaël Salaün
  0 siblings, 0 replies; 28+ messages in thread
From: Mickaël Salaün @ 2024-02-26 20:21 UTC (permalink / raw)
  To: Kees Cook
  Cc: Jakub Kicinski, Shuah Khan, davem, Günther Noack,
	Will Drewry, edumazet, jakub, pabeni, linux-kernel,
	linux-kselftest, linux-security-module, netdev

On Mon, Feb 26, 2024 at 11:04:12AM -0800, Kees Cook wrote:
> On Mon, Feb 26, 2024 at 05:23:35PM +0100, Mickaël Salaün wrote:
> > Remplace Landlock-specific TEST_F_FORK() with an improved TEST_F() which
> > brings four related changes:
> > 
> > Run TEST_F()'s tests in a grandchild process to make it possible to
> > drop privileges and delegate teardown to the parent.
> > 
> > Compared to TEST_F_FORK(), simplify handling of the test grandchild
> > process thanks to vfork(2), and makes it generic (e.g. no explicit
> > conversion between exit code and _metadata).
> > 
> > Compared to TEST_F_FORK(), run teardown even when tests failed with an
> > assert thanks to commit 63e6b2a42342 ("selftests/harness: Run TEARDOWN
> > for ASSERT failures").
> > 
> > Simplify the test harness code by removing the no_print and step fields
> > which are not used.  I added this feature just after I made
> > kselftest_harness.h more broadly available but this step counter
> > remained even though it wasn't needed after all. See commit 369130b63178
> > ("selftests: Enhance kselftest_harness.h to print which assert failed").
> 
> I'm personally fine dropping the step counter. (I do wonder if that
> removal should be split from the grandchild launching.)

I thought about that but it was not worth it to add more lines to
review.

> 
> > Replace spaces with tabs in one line of __TEST_F_IMPL().
> > 
> > Cc: Günther Noack <gnoack@google.com>
> > Cc: Jakub Kicinski <kuba@kernel.org>
> > Cc: Kees Cook <keescook@chromium.org>
> > Cc: Shuah Khan <shuah@kernel.org>
> > Cc: Will Drewry <wad@chromium.org>
> > Signed-off-by: Mickaël Salaün <mic@digikod.net>
> 
> One typo below, but otherwise seems good to me:
> 
> Reviewed-by: Kees Cook <keescook@chromium.org>
> 
> 
> > [...]
> >  			_metadata->setup_completed = true; \
> > -			fixture_name##_##test_name(_metadata, &self, variant->data); \
> > +			/* Use the same _metadata. */ \
> > +			child = vfork(); \
> > +			if (child == 0) { \
> > +				fixture_name##_##test_name(_metadata, &self, variant->data); \
> > +				_exit(0); \
> > +			} \
> > +			if (child < 0) { \
> > +				ksft_print_msg("ERROR SPAWNING TEST GANDCHILD\n"); \
> 
> typo: GAND -> GRAND

Good catch!

Jakub, please fix this with the next combined+rebased series. Thanks!

> 
> -- 
> Kees Cook
> 

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2024-02-26 20:21 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-20 19:22 [PATCH net-next v3 00/11] selftests: kselftest_harness: support using xfail Jakub Kicinski
2024-02-20 19:22 ` [PATCH net-next v3 01/11] selftests: kselftest_harness: pass step via shared memory Jakub Kicinski
2024-02-20 19:22 ` [PATCH net-next v3 02/11] selftests: kselftest_harness: use KSFT_* exit codes Jakub Kicinski
2024-02-20 19:22 ` [PATCH net-next v3 03/11] selftests: kselftest_harness: generate test name once Jakub Kicinski
2024-02-20 19:22 ` [PATCH net-next v3 04/11] selftests: kselftest_harness: save full exit code in metadata Jakub Kicinski
2024-02-20 19:22 ` [PATCH net-next v3 05/11] selftests: kselftest_harness: use exit code to store skip Jakub Kicinski
2024-02-21  0:49   ` Kees Cook
2024-02-20 19:22 ` [PATCH net-next v3 06/11] selftests: kselftest: add ksft_test_result_code(), handling all exit codes Jakub Kicinski
2024-02-21  0:49   ` Kees Cook
2024-02-20 19:22 ` [PATCH net-next v3 07/11] selftests: kselftest_harness: print test name for SKIP Jakub Kicinski
2024-02-21  0:50   ` Kees Cook
2024-02-20 19:22 ` [PATCH net-next v3 08/11] selftests: kselftest_harness: separate diagnostic message with # in ksft_test_result_code() Jakub Kicinski
2024-02-21  0:50   ` Kees Cook
2024-02-20 19:22 ` [PATCH net-next v3 09/11] selftests: kselftest_harness: let PASS / FAIL provide diagnostic Jakub Kicinski
2024-02-21  0:52   ` Kees Cook
2024-02-20 19:22 ` [PATCH net-next v3 10/11] selftests: kselftest_harness: support using xfail Jakub Kicinski
2024-02-21  0:52   ` Kees Cook
2024-02-20 19:22 ` [PATCH net-next v3 11/11] selftests: ip_local_port_range: use XFAIL instead of SKIP Jakub Kicinski
2024-02-21 12:03 ` [PATCH net-next v3 00/11] selftests: kselftest_harness: support using xfail Paolo Abeni
2024-02-23 17:48   ` Kees Cook
2024-02-24  0:02 ` Jakub Kicinski
2024-02-26 16:23   ` [PATCH 0/2] Merge TEST_F_FORK() into TEST_F() Mickaël Salaün
2024-02-26 16:23     ` [PATCH 1/2] selftests/landlock: Redefine TEST_F() as TEST_F_FORK() Mickaël Salaün
2024-02-26 16:23     ` [PATCH 2/2] selftests/harness: Merge TEST_F_FORK() into TEST_F() Mickaël Salaün
2024-02-26 19:04       ` Kees Cook
2024-02-26 20:21         ` Mickaël Salaün
2024-02-26 16:27   ` [PATCH net-next v3 00/11] selftests: kselftest_harness: support using xfail Mickaël Salaün
2024-02-26 16:53     ` Jakub Kicinski

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.