From f24ec48b27d4cb8dd0555840206dedbb45f1423c Mon Sep 17 00:00:00 2001 From: Dirk Engling Date: Sat, 24 Oct 2026 01:17:50 +0200 Subject: Add a unit test harness and a first set of tests make check builds tests/runner from the modules that link without the io subsystem and runs it. --- tests/test.h | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 tests/test.h (limited to 'tests/test.h') diff --git a/tests/test.h b/tests/test.h new file mode 100644 index 0000000..941e058 --- /dev/null +++ b/tests/test.h @@ -0,0 +1,83 @@ +/* This software was written by Dirk Engling + It is considered beerware. Prost. Skol. Cheers or whatever. + + $id$ */ + +#ifndef OT_TEST_H__ +#define OT_TEST_H__ + +#include +#include + +/* Minimal scaffolding for opentracker's unit tests. No external dependencies. + + Tests are grouped into modules, one per source file under test. A module is + a list of small case functions, each pinning one behaviour. A failing CHECK + reports file, line and the offending values, then returns from the case it + is in, so a single run reports as many independent problems as it can. + Because the macros return, they may only be used in functions returning + void. */ + +void test_module(const char *name); +void test_case(const char *name); +void test_failf(const char *file, int line, const char *fmt, ...); +void test_failmem(const char *file, int line, const char *what, const void *got, const void *want, size_t len); +int test_summary(void); + +extern unsigned long test_checks; +extern unsigned long test_failures; + +#define CHECK(cond) \ + do { \ + ++test_checks; \ + if (!(cond)) { \ + test_failf(__FILE__, __LINE__, "expected %s", #cond); \ + return; \ + } \ + } while (0) + +#define CHECK_INT(got, want) \ + do { \ + long long got_ = (long long)(got), want_ = (long long)(want); \ + ++test_checks; \ + if (got_ != want_) { \ + test_failf(__FILE__, __LINE__, "%s: got %lld, want %lld", #got, got_, want_); \ + return; \ + } \ + } while (0) + +#define CHECK_PTR(got, want) \ + do { \ + const void *got_ = (const void *)(got), *want_ = (const void *)(want); \ + ++test_checks; \ + if (got_ != want_) { \ + test_failf(__FILE__, __LINE__, "%s: got %p, want %p", #got, got_, want_); \ + return; \ + } \ + } while (0) + +#define CHECK_MEM(got, want, len) \ + do { \ + ++test_checks; \ + if (memcmp((got), (want), (len))) { \ + test_failmem(__FILE__, __LINE__, #got, (got), (want), (len)); \ + return; \ + } \ + } while (0) + +#define CHECK_STR(got, want) \ + do { \ + const char *got_ = (got), *want_ = (want); \ + ++test_checks; \ + if (strcmp(got_, want_)) { \ + test_failf(__FILE__, __LINE__, "%s: got \"%s\", want \"%s\"", #got, got_, want_); \ + return; \ + } \ + } while (0) + +/* One entry point per module under test */ +void test_scan_urlencoded_query(void); +void test_iovec(void); +void test_vector(void); + +#endif -- cgit v1.3