#include #include #include #include #include #include /* 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(); }