rtengine/tests/rttest.c
Kevin Trogant 9f94ac40ee
All checks were successful
Ubuntu Cross to Win64 / Cross Compile with ming64 (1.4.0, ubuntu-latest) (push) Successful in 1m30s
fix(tests): Prevent compile error when no fixtures are defined.
2024-07-19 15:06:41 +02:00

183 lines
5.8 KiB
C

#include <stdbool.h>
#include <stdio.h>
#include "runtime/config.h"
#include "runtime/ds.h"
#include "runtime/mem_arena.h"
#include "runtime/runtime.h"
/* Check basic relative pointer behaviour */
static rt_result RelPtrTest(void) {
char buf[sizeof(rt_relptr) + sizeof(unsigned int)];
rt_relptr *ptr = (rt_relptr *)buf;
unsigned int *target = (unsigned int *)&buf[sizeof(rt_relptr)];
*target = 42;
rtSetRelptr(ptr, target);
void *resolved = rtResolveRelptr(ptr);
if ((uintptr_t)resolved != (uintptr_t)target)
return 1;
if (*(unsigned int *)resolved != *target)
return 2;
return RT_SUCCESS;
}
static rt_result NegRelPtrTest(void) {
char buf[sizeof(unsigned int) + sizeof(rt_relptr)];
unsigned int *target = (unsigned int *)buf;
rt_relptr *ptr = (rt_relptr *)&buf[sizeof(unsigned int)];
*target = 42;
rtSetRelptr(ptr, target);
void *resolved = rtResolveRelptr(ptr);
if ((uintptr_t)resolved != (uintptr_t)target)
return 1;
if (*(unsigned int *)resolved != *target)
return 2;
return RT_SUCCESS;
}
static rt_result HashTableBasics(void) {
{
uint64_t mem[128];
rt_hashtable ht = rtCreateHashtable(64, mem, NULL, NULL);
for (uint64_t i = 0; i < 64; ++i) {
if (rtHashtableInsert(&ht, i, i) != RT_SUCCESS)
return RT_UNKNOWN_ERROR;
uint64_t found = rtHashtableLookup(&ht, i, UINT64_MAX);
if (found != i)
return RT_INVALID_VALUE;
}
}
{
rt_create_arena_result arena_res = rtCreateArena(NULL, RT_KB(4));
if (!arena_res.ok)
return RT_OUT_OF_MEMORY;
rt_arena arena = arena_res.arena;
void *mem = rtArenaPush(&arena, RT_HASH_TABLE_MEMORY_REQUIRED(64));
if (!mem)
return RT_OUT_OF_MEMORY;
rt_hashtable ht = rtCreateHashtable(64, mem, rtHashtableGrowMemoryFromArena, &arena);
for (uint64_t i = 0; i < 64; ++i) {
if (rtHashtableInsert(&ht, 256 + i, i) != RT_SUCCESS)
return RT_UNKNOWN_ERROR;
uint64_t found = rtHashtableLookup(&ht, 256 + i, UINT64_MAX);
if (found != i)
return RT_INVALID_VALUE;
}
rtReleaseArena(&arena);
}
return RT_SUCCESS;
}
/* Scaffolding
*
* Run all the test cases, output if they passed or failed.
*/
/* A null fixture to prevent an empty array. */
static rt_result NullFixtureSetup(void) {
return RT_SUCCESS;
}
static void NullFixtureTeardown(void) {
}
typedef rt_result rt_fixture_setup_fn(void);
typedef void rt_fixture_teardown_fn(void);
typedef struct {
const char *name;
bool is_initialized;
rt_fixture_setup_fn *setup;
rt_fixture_teardown_fn *teardown;
} rt_test_fixture;
typedef rt_result rt_test_fnc(void);
typedef struct {
const char *name;
rt_test_fnc *fnc;
rt_test_fixture *fixture;
} rt_test_case;
#define TEST_CASE(fn) \
{ .name = #fn, .fnc = fn, .fixture = NULL, }
#define TEST_CASE_FIXTURE(fn, _fixture) \
{ .name = #fn, .fnc = fn, .fixture = &_fixture }
/* X-Macro to create named fixtures */
/* Add more fixtures here*/
#define TEST_FIXTURE_LIST TEST_FIXTURE(NullFixture, NullFixtureSetup, NullFixtureTeardown)
#define TEST_FIXTURE(n, setup_fn, teardown_fn) \
rt_test_fixture n = {.name = #n, \
.is_initialized = false, \
.setup = setup_fn, \
.teardown = teardown_fn};
TEST_FIXTURE_LIST
#undef TEST_FIXTURE
#define TEST_FIXTURE(n, _s, _t) &n
static rt_test_fixture *_test_fixtures[] = {TEST_FIXTURE_LIST};
static rt_test_case _test_cases[] = {TEST_CASE(RelPtrTest),
TEST_CASE(NegRelPtrTest),
/*TEST_CASE_FIXTURE(PushRenderList, render_list_fixture),
TEST_CASE_FIXTURE(PushLongRenderList, render_list_fixture),*/
TEST_CASE(HashTableBasics)};
int main() {
int out = 0;
for (size_t i = 0; i < RT_ARRAY_COUNT(_test_cases); ++i) {
if (_test_cases[i].fixture) {
rt_test_fixture *fixture = _test_cases[i].fixture;
if (!fixture->is_initialized) {
printf("[SETUP %s] ... ", fixture->name);
rt_result res = fixture->setup();
if (res == RT_SUCCESS) {
printf("OK\n");
fixture->is_initialized = true;
} else {
printf("FAILED (%u)\n", res);
++out;
printf("Cannot run test case %s because the setup of fixture %s failed!\n",
_test_cases[i].name,
fixture->name);
continue;
}
}
}
printf("[%s] ... ", _test_cases[i].name);
rt_result res = _test_cases[i].fnc();
if (res == RT_SUCCESS) {
printf("OK\n");
} else {
printf("FAILED (%u)\n", res);
++out;
}
}
/* Teardown fixtures.
* The +1 is necessary to avoid comparing i=0 < 0, which causes a compile
* error */
for (size_t i = 0; (i + 1) < (RT_ARRAY_COUNT(_test_fixtures) + 1); ++i) {
if (_test_fixtures[i]->is_initialized) {
printf("[TEARDOWN %s] ... ", _test_fixtures[i]->name);
_test_fixtures[i]->teardown();
printf("DONE\n");
}
}
return out;
}