diff options
-rw-r--r-- | 02-usart/test_harness/fake_env.c | 36 | ||||
-rw-r--r-- | 02-usart/test_harness/fake_env.h | 2 | ||||
-rw-r--r-- | 02-usart/test_harness/test_harness.c | 36 | ||||
-rw-r--r-- | 02-usart/test_harness/test_harness.h | 3 | ||||
-rw-r--r-- | 02-usart/tests/metatest.c | 22 |
5 files changed, 91 insertions, 8 deletions
diff --git a/02-usart/test_harness/fake_env.c b/02-usart/test_harness/fake_env.c index 3175317..6a32c99 100644 --- a/02-usart/test_harness/fake_env.c +++ b/02-usart/test_harness/fake_env.c @@ -3,17 +3,39 @@ #include <stdlib.h> #include <assert.h> -#define DEFINE_MEMORY_SEGMENT(name, start_addr, end_addr) \ - static void* fake_##name = NULL; \ - void* load_fake_##name##__ () \ +struct fakeenv_memseg { + const char* name; + void* segment; +}; + +#define DEFINE_MEMORY_SEGMENT(seg, start_addr, end_addr) \ + static __attribute((__section__("fakeenv"))) \ + struct fakeenv_memseg fake_##seg = { \ + .name = #seg, \ + .segment = NULL, \ + }; \ + void* load_fake_##seg##__ () \ { \ - if (fake_##name == NULL) { \ - fake_##name = malloc((end_addr) - (start_addr)); \ - assert(fake_##name != NULL); \ + if (fake_##seg .segment == NULL) { \ + fake_##seg .segment = malloc((end_addr) - (start_addr)); \ + assert(fake_##seg .segment != NULL); \ } \ - return fake_##name; \ + return fake_##seg.segment; \ } +extern struct fakeenv_memseg __start_fakeenv; +extern struct fakeenv_memseg __stop_fakeenv; + +void wipeout_fake_env() +{ + for (struct fakeenv_memseg* iter = &__start_fakeenv; + iter < &__stop_fakeenv; + ++ iter) { + free(iter->segment); + iter->segment = NULL; + } +} + /* Reset and clock control. */ DEFINE_MEMORY_SEGMENT(rcc, 0x40021000, 0x400210A0) diff --git a/02-usart/test_harness/fake_env.h b/02-usart/test_harness/fake_env.h index 73323cf..34056f4 100644 --- a/02-usart/test_harness/fake_env.h +++ b/02-usart/test_harness/fake_env.h @@ -15,4 +15,6 @@ void* load_fake_rcc__(); void* load_fake_spi1__(); void* load_fake_spi3__(); +void wipeout_fake_env(); + #endif /* FAKE_ENV_H_ */ diff --git a/02-usart/test_harness/test_harness.c b/02-usart/test_harness/test_harness.c index a0a2a33..bf9249c 100644 --- a/02-usart/test_harness/test_harness.c +++ b/02-usart/test_harness/test_harness.c @@ -1,4 +1,5 @@ #include "test_harness.h" +#include "fake_env.h" #include <assert.h> #include <stdio.h> @@ -19,6 +20,8 @@ volatile test_t dummy NULL }; +extern unsigned char __data_start; +extern unsigned char _end; extern test_t __start_tests; extern test_t __stop_tests; @@ -72,8 +75,17 @@ void test_printuc( fprintf(stderr, "%02x == %02x\n", (int) v1, (int) v2); } -int do_fork = 1; +static int do_fork = 1; +static size_t saved_data_size; +static unsigned char* saved_data = NULL; + int main(int argc, char** argv) { + /* Save all initialized data. */ + saved_data_size = &_end - &__data_start; + saved_data = malloc(saved_data_size); + memcpy(saved_data, &__data_start, saved_data_size); + + if (argc > 1 && strcmp(argv[1], "--nofork") == 0) { do_fork = 0; } @@ -91,6 +103,26 @@ void test_harness_abort(int ec) assert("Long jump failed.\n"); } +/* + * When nofork is true, this function will be called after each + * test to try and make each test hermetic. + * + * It does this by reseting the data segment to what it was when + * the program was first initialized. + * + * Of course, without forking, there's no way to guarantee hermetic + * testing in C. In fact a simple segementation fault will break + * the hermetic testing, but this does a pretty good job of at least + * reseting the environment so tests don't directly depend on eachother. + */ +static void nofork_reset() +{ + wipeout_fake_env(); + + /* Reset the data segment to what it was before. */ + memcpy(&__data_start, saved_data, saved_data_size); +} + static int execute_test(test_t* test) { char fullname[512]; @@ -105,9 +137,11 @@ static int execute_test(test_t* test) if ((ec = setjmp(jmpbuf)) == 0) { test->fn_ptr(); printf(GREEN "[PASS]" RESET " %s\n", fullname); + nofork_reset(); return 0; } else { printf(RED "[FAIL] (%d)" RESET " %s\n", ec, fullname); + nofork_reset(); return ec; } } diff --git a/02-usart/test_harness/test_harness.h b/02-usart/test_harness/test_harness.h index b236cba..698e2da 100644 --- a/02-usart/test_harness/test_harness.h +++ b/02-usart/test_harness/test_harness.h @@ -95,4 +95,7 @@ void test_printuc(size_t sz, unsigned char v1, unsigned char v2); void test_harness_abort(int ec); + +void wipeout_fake_env(); + #endif diff --git a/02-usart/tests/metatest.c b/02-usart/tests/metatest.c new file mode 100644 index 0000000..1024156 --- /dev/null +++ b/02-usart/tests/metatest.c @@ -0,0 +1,22 @@ +#include "test_harness.h" + +/* Tests the test harness itself. */ + +static int my_variable; +static int my_initialized_variable = 5; + +TEST(meta, clobbers_variables) +{ + my_variable = 6; + my_initialized_variable = 5; + + return 0; +} + +TEST(meta, variables_reset) +{ + ASSERT_EQ(my_variable, 0); + ASSERT_EQ(my_initialized_variable, 5); + + return 0; +} |