6464#include <sys/types.h>
6565#include <sys/wait.h>
6666#include <unistd.h>
67+ #include <setjmp.h>
6768
6869#include "kselftest.h"
6970
183184 struct __test_metadata *_metadata, \
184185 struct __fixture_variant_metadata *variant) \
185186 { \
186- test_name(_metadata); \
187+ _metadata->setup_completed = true; \
188+ if (setjmp(_metadata->env) == 0) \
189+ test_name(_metadata); \
190+ __test_check_assert(_metadata); \
187191 } \
188192 static struct __test_metadata _##test_name##_object = \
189193 { .name = #test_name, \
287291#define FIXTURE_TEARDOWN (fixture_name ) \
288292 void fixture_name##_teardown( \
289293 struct __test_metadata __attribute__((unused)) *_metadata, \
290- FIXTURE_DATA(fixture_name) __attribute__((unused)) *self)
294+ FIXTURE_DATA(fixture_name) __attribute__((unused)) *self, \
295+ const FIXTURE_VARIANT(fixture_name) \
296+ __attribute__((unused)) *variant)
291297
292298/**
293299 * FIXTURE_VARIANT() - Optionally called once per fixture
302308 * ...
303309 * };
304310 *
305- * Defines type of constant parameters provided to FIXTURE_SETUP() and TEST_F()
306- * as *variant*. Variants allow the same tests to be run with different
307- * arguments.
311+ * Defines type of constant parameters provided to FIXTURE_SETUP(), TEST_F() and
312+ * FIXTURE_TEARDOWN as *variant*. Variants allow the same tests to be run with
313+ * different arguments.
308314 */
309315#define FIXTURE_VARIANT (fixture_name ) struct _fixture_variant_##fixture_name
310316
356362 * Defines a test that depends on a fixture (e.g., is part of a test case).
357363 * Very similar to TEST() except that *self* is the setup instance of fixture's
358364 * datatype exposed for use by the implementation.
359- *
360- * Warning: use of ASSERT_* here will skip TEARDOWN.
361365 */
362- /* TODO(wad) register fixtures on dedicated test lists. */
363366#define TEST_F (fixture_name , test_name ) \
364367 __TEST_F_IMPL(fixture_name, test_name, -1, TEST_TIMEOUT_DEFAULT)
365368
381384 /* fixture data is alloced, setup, and torn down per call. */ \
382385 FIXTURE_DATA (fixture_name ) self ; \
383386 memset (& self , 0 , sizeof (FIXTURE_DATA (fixture_name ))); \
384- fixture_name ##_setup (_metadata , & self , variant -> data ); \
385- /* Let setup failure terminate early. */ \
386- if (!_metadata -> passed ) \
387- return ; \
388- fixture_name ##_ ##test_name (_metadata, &self, variant->data); \
389- fixture_name##_teardown(_metadata, &self); \
387+ if (setjmp (_metadata -> env ) == 0 ) { \
388+ fixture_name ##_setup (_metadata , & self , variant -> data ); \
389+ /* Let setup failure terminate early. */ \
390+ if (!_metadata -> passed ) \
391+ return ; \
392+ _metadata -> setup_completed = true; \
393+ fixture_name ##_ ##test_name (_metadata, &self, variant->data); \
394+ } \
395+ if (_metadata->setup_completed) \
396+ fixture_name##_teardown(_metadata, &self, variant->data); \
397+ __test_check_assert(_metadata); \
390398 } \
391399 static struct __test_metadata \
392400 _##fixture_name##_##test_name##_object = { \
683691 */
684692#define OPTIONAL_HANDLER (_assert ) \
685693 for (; _metadata->trigger; _metadata->trigger = \
686- __bail(_assert, _metadata->no_print, _metadata->step ))
694+ __bail(_assert, _metadata))
687695
688696#define __INC_STEP (_metadata ) \
689697 /* Keep "step" below 255 (which is used for "SKIP" reporting). */ \
@@ -830,6 +838,9 @@ struct __test_metadata {
830838 bool timed_out ; /* did this test timeout instead of exiting? */
831839 __u8 step ;
832840 bool no_print ; /* manual trigger when TH_LOG_STREAM is not available */
841+ bool aborted ; /* stopped test due to failed ASSERT */
842+ bool setup_completed ; /* did setup finish? */
843+ jmp_buf env ; /* for exiting out of test early */
833844 struct __test_results * results ;
834845 struct __test_metadata * prev , * next ;
835846};
@@ -848,16 +859,26 @@ static inline void __register_test(struct __test_metadata *t)
848859 __LIST_APPEND (t -> fixture -> tests , t );
849860}
850861
851- static inline int __bail (int for_realz , bool no_print , __u8 step )
862+ static inline int __bail (int for_realz , struct __test_metadata * t )
852863{
864+ /* if this is ASSERT, return immediately. */
853865 if (for_realz ) {
854- if (no_print )
855- _exit (step );
856- abort ();
866+ t -> aborted = true;
867+ longjmp (t -> env , 1 );
857868 }
869+ /* otherwise, end the for loop and continue. */
858870 return 0 ;
859871}
860872
873+ static inline void __test_check_assert (struct __test_metadata * t )
874+ {
875+ if (t -> aborted ) {
876+ if (t -> no_print )
877+ _exit (t -> step );
878+ abort ();
879+ }
880+ }
881+
861882struct __test_metadata * __active_test ;
862883static void __timeout_handler (int sig , siginfo_t * info , void * ucontext )
863884{
0 commit comments