Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions thorn/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,14 @@ SRC = src
KERNEL = kernel
COMMON = common
INCLUDE = include
TEST = test

# Assemble lists of corresponding source files for assembly, kernel and common
SRC_KERNEL = $(wildcard $(SRC)/$(KERNEL)/*.c)
ASM_KERNEL = $(wildcard $(SRC)/$(KERNEL)/*.S)
SRC_COMMON = $(wildcard $(SRC)/$(COMMON)/*.c)
ASM_COMMON = $(wildcard $(SRC)/$(COMMON)/*.S)
TESTS = $(wildcard $(TEST)/*.c)

# Assemble list of compiled objects, correspondingly
OBJECTS = $(patsubst $(SRC)/$(KERNEL)/%.c, $(BUILD)/$(SRC)/$(KERNEL)/%_c.o, $(SRC_KERNEL))
Expand Down Expand Up @@ -79,6 +81,11 @@ $(BUILD)/$(SRC)/$(COMMON)/%_S.o: $(SRC)/$(COMMON)/%.S
mkdir -p $(@D)
$(ARMGNU)-gcc $(ASMOPS) -MMD -c $< -o $@

# All test source targets
$(BUILD)/$(TEST)/%_c.o: $(TEST)/%.c
mkdir -p $(@D)
$(ARMGNU)-gcc $(ASMOPS) -MMD -c $< $(OBJECTS) -o $@

# Compile lists with the dependencies between objects
DEP_FILES = $(OBJECTS:%.o=%.d)
-include $(DEP_FILES)
Expand All @@ -105,6 +112,10 @@ flash-Darwin: $(IMAGE_NAME).img
sync
diskutil unmount $(MNT)

test: $(SRC) $(BUILD)/$(TEST)
# TODO: how to send and run the tests on the PI?
# for test in $(BUID)/$(TEST) ; do ./$$test ; done

resend: reboot send

send: $(IMAGE_NAME).img
Expand Down
122 changes: 122 additions & 0 deletions thorn/include/common/minunit.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/*
* Minimal Testing Framework based on
* https://github.com/siu/minunit
*/

#ifndef MINUNIT_MINUNIT_H
#define MINUNIT_MINUNIT_H

#include "common/printf.h"
#include "common/stddef.h"

/* Misc. counters */
static int minunit_run = 0;
static int minunit_assert = 0;
static int minunit_fail = 0;
static int minunit_status = 0;

/* Test setup and teardown function pointers */
static void (*minunit_setup) (void) = NULL;
static void (*minunit_teardown) (void) = NULL;

/* Definitions */
#define MU_TEST(method_name) static void method_name (void)
#define MU_TEST_SUITE(suite_name) static void suite_name (void)

#define MU__SAFE_BLOCK(block) \
do { \
block \
} while (0)

#define MU_RUN_SUITE(suite_name) MU__SAFE_BLOCK ( \
suite_name (); \
minunit_setup = NULL; \
minunit_teardown = NULL;)

/* Configure setup and teardown functions */
#define MU_SUITE_CONFIGURE(setup_fun, teardown_fun) MU__SAFE_BLOCK ( \
minunit_setup = setup_fun; \
minunit_teardown = teardown_fun;)

/* Test runner */
#define MU_RUN_TEST(test) MU__SAFE_BLOCK ( \
if (minunit_setup) (*minunit_setup) (); \
minunit_status = 0; \
test (); \
minunit_run++; \
if (minunit_status) { \
minunit_fail++; \
printf ("F"); \
} if (minunit_teardown) (*minunit_teardown) ();)

/* Report */
#define MU_REPORT() MU__SAFE_BLOCK ( \
printf ("\r\n\n%d tests, %d assertions, %d failures\r\n", \
minunit_run, minunit_assert, minunit_fail);)
#define MU_EXIT_CODE minunit_fail

/* Assertions */
#define mu_check(test) MU__SAFE_BLOCK ( \
minunit_assert++; \
if (!(test)) { \
printf ("%s failed:\n\t%s:%d: %s", \
__func__, __FILE__, __LINE__, test); \
minunit_status = 1; \
return; \
} else { \
printf (".\r\n"); \
})

#define mu_fail(message) MU__SAFE_BLOCK ( \
minunit_assert++; \
printf ("%s failed:\n\t%s:%d: %s", \
__func__, __FILE__, __LINE__, message); \
minunit_status = 1; \
return;)

#define mu_assert(test, message) MU__SAFE_BLOCK ( \
minunit_assert++; \
if (!(test)) { \
printf ("%s failed:\n\t%s:%d: %s", \
__func__, __FILE__, __LINE__, message); \
minunit_status = 1; \
return; \
} else { \
printf ("."); \
})

#define mu_assert_int_eq(expected, result) MU__SAFE_BLOCK ( \
int minunit_tmp_e; \
int minunit_tmp_r; \
minunit_assert++; \
minunit_tmp_e = (expected); \
minunit_tmp_r = (result); \
if (minunit_tmp_e != minunit_tmp_r) { \
printf ("%s failed:\n\t%s:%d: %d expected but was %d", \
__func__, __FILE__, __LINE__, minunit_tmp_e, minunit_tmp_r); \
minunit_status = 1; \
return; \
} else { \
printf ("."); \
})

// This one requires a strcmp() funktion
/* #define mu_assert_string_eq(expected, result) MU__SAFE_BLOCK ( \ */
/* const char * minunit_tmp_e = expected; \ */
/* const char * minunit_tmp_r = result; \ */
/* minunit_assert++; \ */
/* if (!minunit_tmp_e) { \ */
/* minunit_tmp_e = "<null pointer>"; \ */
/* } if (!minunit_tmp_r) { \ */
/* minunit_tmp_r = "<null pointer>"; \ */
/* } if (strcmp (minunit_tmp_e, minunit_tmp_r)) { \ */
/* printf ("%s failed:\n\t%s:%d: '%s' expected but was '%s'", \ */
/* __func__, __FILE__, __LINE__, minunit_tmp_e, minunit_tmp_r); \ */
/* minunit_status = 1; \ */
/* return; \ */
/* } else { \ */
/* printf ("."); \ */
/* }) */


#endif /* MINUNIT_MINUNIT_H */
75 changes: 75 additions & 0 deletions thorn/test/test_minunit.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#include "common/minunit.h"

static int foo = 0;
static int bar = 0;
/* static const char * foostring = "Thisstring"; */

void test_setup (void) {
foo = 7;
bar = 4;
}

void test_teardown (void) {
/* Nothing */
}

MU_TEST (test_check) {
mu_check (foo == 7);
}

MU_TEST (test_check_fail) {
mu_check (foo != 7);
}

MU_TEST (test_assert) {
mu_assert (foo == 7, "foo should be 7");
}

MU_TEST (test_assert_fail) {
mu_assert (foo != 7, "foo should be <> 7");
}

MU_TEST (test_assert_int_eq) {
mu_assert_int_eq (4, bar);
}

MU_TEST (test_assert_int_eq_fail) {
mu_assert_int_eq (5, bar);
}


MU_TEST (test_fail) {
mu_fail ("Fail now!");
}

/* MU_TEST (test_string_eq) { */
/* mu_assert_string_eq ("Thisstring", foostring); */
/* } */

/* MU_TEST (test_string_eq_fail) { */
/* mu_assert_string_eq ("Thatstring", foostring); */
/* } */


MU_TEST_SUITE (test_suite) {
MU_SUITE_CONFIGURE (&test_setup, &test_teardown);

MU_RUN_TEST (test_check);
MU_RUN_TEST (test_assert);
MU_RUN_TEST (test_assert_int_eq);

MU_RUN_TEST (test_check_fail);
MU_RUN_TEST (test_assert_fail);
MU_RUN_TEST (test_assert_int_eq_fail);

/* MU_RUN_TEST (test_string_eq); */
/* MU_RUN_TEST (test_string_eq_fail); */

MU_RUN_TEST (test_fail);
}

int run_tests (void) {
MU_RUN_SUITE (test_suite);
MU_REPORT ();
return MU_EXIT_CODE;
}