]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
selftests: harness: Add teardown callback to test metadata
authorThomas Weißschuh <thomas.weissschuh@linutronix.de>
Mon, 5 May 2025 15:15:28 +0000 (17:15 +0200)
committerThomas Weißschuh <linux@weissschuh.net>
Wed, 21 May 2025 13:32:35 +0000 (15:32 +0200)
To get rid of setjmp()/longjmp(), the teardown logic needs to be usable
from __bail(). Introduce a new callback for it.

Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Acked-by: Shuah Khan <skhan@linuxfoundation.org>
Link: https://lore.kernel.org/r/20250505-nolibc-kselftest-harness-v4-10-ee4dd5257135@linutronix.de
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
tools/testing/selftests/kselftest_harness.h

index 895821af3e5c5752065561d0a108210d79e9eeee..acb476093b74968ecb71180ade9e5852b22da170 100644 (file)
                        } \
                } \
                if (child == 0) { \
-                       if (!fixture_name##_teardown_parent && \
-                                       !__atomic_test_and_set(_metadata->no_teardown, __ATOMIC_RELAXED)) \
-                               fixture_name##_teardown(_metadata, self, variant->data); \
+                       _metadata->teardown_fn(false, _metadata, self, variant->data); \
                        _exit(0); \
                } \
-               if (fixture_name##_teardown_parent && \
-                               !__atomic_test_and_set(_metadata->no_teardown, __ATOMIC_RELAXED)) \
-                       fixture_name##_teardown(_metadata, self, variant->data); \
+               _metadata->teardown_fn(true, _metadata, self, variant->data); \
                munmap(_metadata->no_teardown, sizeof(*_metadata->no_teardown)); \
                _metadata->no_teardown = NULL; \
                if (self && fixture_name##_teardown_parent) \
                } \
                __test_check_assert(_metadata); \
        } \
+       static void wrapper_##fixture_name##_##test_name##_teardown( \
+               bool in_parent, struct __test_metadata *_metadata, \
+               void *self, const void *variant) \
+       { \
+               if (fixture_name##_teardown_parent == in_parent && \
+                               !__atomic_test_and_set(_metadata->no_teardown, __ATOMIC_RELAXED)) \
+                       fixture_name##_teardown(_metadata, self, variant); \
+       } \
        static struct __test_metadata *_##fixture_name##_##test_name##_object; \
        static void __attribute__((constructor)) \
                        _register_##fixture_name##_##test_name(void) \
                object->name = #test_name; \
                object->fn = &wrapper_##fixture_name##_##test_name; \
                object->fixture = &_##fixture_name##_fixture_object; \
+               object->teardown_fn = &wrapper_##fixture_name##_##test_name##_teardown; \
                object->termsig = signal; \
                object->timeout = tmout; \
                _##fixture_name##_##test_name##_object = object; \
@@ -912,6 +917,8 @@ struct __test_metadata {
                   struct __fixture_variant_metadata *);
        pid_t pid;      /* pid of test when being run */
        struct __fixture_metadata *fixture;
+       void (*teardown_fn)(bool in_parent, struct __test_metadata *_metadata,
+                           void *self, const void *variant);
        int termsig;
        int exit_code;
        int trigger; /* extra handler after the evaluation */