As TDD proponent and as osdever, I wanted to see if I could combine the two to a method of making a kernel, TDD style. I've tried (for about 30 minutes during my lunch break today) and came up with this. The difference between this and basic typical TDD frameworks is that this one assumes that you have only run the .ctors section, and that you have a non-crashing kerror function (that you can change in the header if you'd like). It does not use malloc, it does not use anything that a simple ELF loader wouldn't have put there already. You should be able to use this to unit-test your paging code.
Of course, if stuff crashes or triple-faults all bets are off.
Header:
Code: Select all
#ifndef TEST_H
#define TEST_H
#include <cstddef>
#include <kerror.h>
struct test_entry;
void register_test(test_entry *entry);
struct test_entry {
test_entry(const char *testname, const char *filename, size_t lineno, bool (*test)())
: testname(testname)
, filename(filename)
, lineno(lineno)
, test(test)
{
register_test(this);
}
test_entry *next;
const char *testname;
const char *filename;
size_t lineno;
bool (*test)();
};
#define TEST(x) bool testf_##x(); static struct test_entry test##x(#x, __FILE__, __LINE__, &testf_##x); bool testf_##x()
#define ASSERT(x, y) if ((x) != (y)) { kerror(0, "%s:%d: ASSERT: %d was not equal to %d\n", __FILE__, __LINE__, x, y); return false; } (void)0
#define ASSERT_THAT(x) if (!(x)) { kerror(0, "%s:%d: ASSERT: %s was not true\n", __FILE__, __LINE__, #x); return false; } (void)0
void test_run();
#endif
Code: Select all
#include "test.h"
struct test_entry *tests = 0;
void register_test(test_entry *entry) {
entry->next = tests;
tests = entry;
}
void test_run() {
test_entry *entry = tests;
size_t testcount = 0, failures = 0;
while (entry) {
testcount++;
kerror(0, ".");
if (!entry->test()) {
kerror(0, "\n%s:%d: Failed test %s\n", entry->filename, entry->lineno, entry->testname);
failures++;
}
entry = entry->next;
}
kerror(0, "\n%d / %d tests failed\n", failures, testcount);
}
Code: Select all
TEST(vector_simple_use) {
std::vector<int> numbers;
ASSERT(numbers.size(), 0);
ASSERT(numbers.capacity(), 0);
}
Hope you enjoy it!