myxce/src/scheduler/testsuite/test.c

148 lines
4.1 KiB
C

#include <argp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdatomic.h>
#include <unity/unity.h>
/* Pull resource.c into this TU so static helpers are visible for white-box testing.
* This also brings in scheduler.h (with the real xce_scheduler_t) and all deps. */
#include "../src/resource.c"
/* Stubs for symbols used by resource.c functions not under test */
xce_sched_worker_t* sched_get_worker(xce_scheduler_t* s, char* n) { (void)s; (void)n; return NULL; }
int plugin_prepare_allocation(void* s, xce_sched_ctx_t* c) { (void)s; (void)c; return 0; }
int sched_ctx_get_uncomit_host(xvec_t** v, xce_sched_ctx_t* c, int i) { (void)v; (void)c; (void)i; return 0; }
void setUp() { return; }
void tearDown(void)
{
printf("\n-----------------------------------------------------\n");
return;
}
static char doc[] = "sched_test";
static char args_doc[] = "";
#define MAX_TESTS (256)
struct arguments {
int ntests;
char* tests[MAX_TESTS];
};
static struct argp_option options[] = {
{ "run", 't', "STR", 0, "run test" },
{ 0 }
};
static error_t parse_opt(int key, char* arg, struct argp_state* state)
{
struct arguments* arguments = state->input;
switch (key) {
case 't':
if (arguments->ntests >= MAX_TESTS) {
fprintf(stderr, "Too many tests\n");
exit(-1);
}
arguments->tests[arguments->ntests] = arg;
arguments->ntests++;
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
static struct argp argp = { options, parse_opt, args_doc, doc };
struct arguments arguments;
static int check_test(struct arguments* args, char* x)
{
int i;
if (args->ntests == 0) {
return 1;
}
for (i = 0; i < args->ntests; i++) {
if (strcmp(x, args->tests[i]) == 0) {
return 1;
}
}
return 0;
}
static void
test_build_host_eval_ctx_float(void)
{
/* Worker with one float resource at res_idx=2 (value=4.0) */
xce_sched_worker_t w;
memset(&w, 0, sizeof(w));
zarray_init(&w.resvals, sizeof(xce_val_t*), NULL);
xce_val_t v;
memset(&v, 0, sizeof(v));
v.which = Value_u_fvalue;
v.u.fvalue = 4.0;
/* store xce_val_t* directly, matching production put_resvals behavior */
zarray_put(&w.resvals, 2, &v);
host_eval_ctx_t* ctx = build_host_eval_ctx(&w, 3);
TEST_ASSERT_NOT_NULL(ctx);
/* Unity is built without UNITY_INCLUDE_DOUBLE; compare via float cast */
TEST_ASSERT_EQUAL_FLOAT(4.0f, (float)ctx->numvals[2]);
TEST_ASSERT_NULL(ctx->strvals[2]);
TEST_ASSERT_EQUAL_INT(3, ctx->num_res);
free_host_eval_ctx(ctx);
zarray_fini(&w.resvals);
}
static void
test_scheduler_t_has_atomic_gc_fields(void)
{
xce_scheduler_t sched;
memset(&sched, 0, sizeof(sched));
TEST_ASSERT_EQUAL_INT(0, atomic_load(&sched.session_active));
TEST_ASSERT_EQUAL_INT(0, atomic_load(&sched.eval_in_progress));
TEST_ASSERT_EQUAL_INT(0, atomic_load(&sched.staging_merge_complete));
}
static void
test_sel_optimize_set_at_scheduler_startup(void)
{
/* sel_optimize_set(1) is called in sched_init.
* Since we can't call sched_init (it starts threads/network),
* verify the setter/getter contract directly. */
sel_optimize_set(1);
TEST_ASSERT_EQUAL_INT(1, sel_get_optimize_level());
/* reset for clean test isolation */
#ifdef UNIT_TEST
sel_optimize_test_reset();
#endif
}
#define TEST(x) \
do { \
if (check_test(&arguments, #x)) { \
RUN_TEST(x, 0); \
} \
} while (0)
int main(int argc, char* argv[])
{
argp_parse(&argp, argc, argv, 0, 0, &arguments);
UNITY_BEGIN();
TEST(test_build_host_eval_ctx_float);
TEST(test_scheduler_t_has_atomic_gc_fields);
TEST(test_sel_optimize_set_at_scheduler_startup);
return UNITY_END();
}