All checks were successful
Ubuntu Cross to Win64 / Cross Compile with ming64 (1.4.0, ubuntu-latest) (push) Successful in 1m30s
183 lines
5.8 KiB
C
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;
|
|
}
|