aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--02-usart/test_harness/fake_env.c36
-rw-r--r--02-usart/test_harness/fake_env.h2
-rw-r--r--02-usart/test_harness/test_harness.c36
-rw-r--r--02-usart/test_harness/test_harness.h3
-rw-r--r--02-usart/tests/metatest.c22
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;
+}