Skip to content

Commit

Permalink
tests: replace fake_criterion_tests section with `__attribute__((co…
Browse files Browse the repository at this point in the history
…nstructor))`s adding to a linked list, fixing the padding bug

* Fixes #473.

The previous way of appending `struct fake_criterion_test`s by putting them into a section
was buggy because extra padding was added between the elements in the section,
so iterating through them from `__{start,stop}_fake_criterion_tests` didn't work correctly.

This new way uses `__attribute__((constructor))` to add each `struct fake_criterion_test`
to a singly linked list. A singly linked list is used for simplicity,
though it does mean the tests are run in reverse order within a file,
but I don't really think the test order should matter, so this should be okay.
  • Loading branch information
kkysen committed Dec 4, 2024
1 parent 3a1cba5 commit 45c8133
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 16 deletions.
26 changes: 17 additions & 9 deletions misc/test_runner/include/ia2_test_runner.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@ typedef void (*ia2_test_fn)(void);
#endif

struct fake_criterion_test {
struct fake_criterion_test *next;
const char *suite;
const char *name;
ia2_test_fn test;
ia2_test_fn init;
int exit_code;
};

extern struct fake_criterion_test *fake_criterion_tests;

#define _STRINGIFY(a) #a
#define STRINGIFY(a) _STRINGIFY(a)

Expand All @@ -33,15 +36,20 @@ struct fake_criterion_test {
* that reference it like the RHS when initializing struct fake_criterion_test's test field. The
* last line of this macro is the start of the test function's definition and should be followed by { }
*/
#define Test(suite_, name_, ...) \
IA2_BEGIN_NO_WRAP \
void fake_criterion_##suite_##_##name_(void); \
IA2_END_NO_WRAP \
__attribute__((__section__("fake_criterion_tests"))) struct fake_criterion_test fake_criterion_##suite_##_##name_##_##test = { \
.suite = STRINGIFY(suite_), \
.name = STRINGIFY(name_), \
.test = fake_criterion_##suite_##_##name_, \
##__VA_ARGS__}; \
#define Test(suite_, name_, ...) \
IA2_BEGIN_NO_WRAP \
void fake_criterion_##suite_##_##name_(void); \
IA2_END_NO_WRAP \
struct fake_criterion_test fake_criterion_##suite_##_##name_##_##test IA2_SHARED_DATA = { \
.next = NULL, \
.suite = STRINGIFY(suite_), \
.name = STRINGIFY(name_), \
.test = fake_criterion_##suite_##_##name_, \
##__VA_ARGS__}; \
__attribute__((constructor)) void fake_criterion_add_##suite_##_##name_##_##test(void) { \
fake_criterion_##suite_##_##name_##_##test.next = fake_criterion_tests; \
fake_criterion_tests = &fake_criterion_##suite_##_##name_##_##test; \
} \
void fake_criterion_##suite_##_##name_(void)

#define cr_log_info(f, ...) printf(f "\n", ##__VA_ARGS__)
Expand Down
9 changes: 2 additions & 7 deletions misc/test_runner/test_runner.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@
#include <sys/wait.h>
#include <unistd.h>

extern struct fake_criterion_test __start_fake_criterion_tests;
extern struct fake_criterion_test __stop_fake_criterion_tests;
struct fake_criterion_test *fake_criterion_tests IA2_SHARED_DATA = NULL;

/* This is shared data to allow checking for violations from different compartments */
bool expect_fault IA2_SHARED_DATA = false;
Expand Down Expand Up @@ -83,12 +82,8 @@ int main() {
* invocation of the Test macro
*/
sigaction(SIGSEGV, &act, NULL);
struct fake_criterion_test *test_info = &__start_fake_criterion_tests;
for (; test_info < &__stop_fake_criterion_tests; test_info++) {
for (struct fake_criterion_test *test_info = fake_criterion_tests; test_info; test_info = test_info->next) {
fprintf(stderr, "running suite '%s' test '%s'...\n", test_info->suite, test_info->name);
if (!test_info->test) {
break;
}
pid_t pid = fork();
bool in_child = pid == 0;
if (in_child) {
Expand Down

0 comments on commit 45c8133

Please sign in to comment.