diff --git a/src/scheduler/testsuite/test.c b/src/scheduler/testsuite/test.c index 817c13a..602163c 100644 --- a/src/scheduler/testsuite/test.c +++ b/src/scheduler/testsuite/test.c @@ -5,6 +5,7 @@ #include #include #include +#include "xstring.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. */ @@ -220,6 +221,124 @@ test_gc_predicates_idle_invariant(void) sel_optimize_test_reset(); } +static void +test_meet_host_selection_numeric_match(void) +{ + /* Job requires: res[0] >= 4. + * Worker with res[0]=8.0 must match (rc=1). + * Worker with res[0]=2.0 must not match (rc=0). */ + sel_optimize_set(1); + sel_node_table_init(); + + /* Build resreq AST: SEL_GE(SEL_RESNAME(idx=0, NUMERIC), SEL_NUM(4.0)) */ + xce_select_node_t* resname = makeSelectNode(SEL_RESNAME, 0, RES_TYPE_NUMERIC); + + double dval = 4.0; + uintptr_t bits; + memcpy(&bits, &dval, sizeof(bits)); + xce_select_node_t* num4 = makeSelectNode(SEL_NUM, bits, 0); + + xce_select_node_t* ge = makeSelectNode(SEL_GE, + (uintptr_t)resname, + (uintptr_t)num4); + TEST_ASSERT_NOT_NULL(ge); + + xce_select_t sel = { .root = ge }; + xce_scheduler_t sched; + memset(&sched, 0, sizeof(sched)); + + /* Worker with 8.0 at res_idx=0 — must pass */ + xce_sched_worker_t w8; + memset(&w8, 0, sizeof(w8)); + zarray_init(&w8.resvals, sizeof(xce_val_t*), NULL); + + xce_val_t v8; + memset(&v8, 0, sizeof(v8)); + v8.which = Value_u_fvalue; + v8.u.fvalue = 8.0f; + zarray_put(&w8.resvals, 0, &v8); + + TEST_ASSERT_EQUAL_INT(1, sched_meet_host_selection(&sched, &w8, &sel)); + + /* Worker with 2.0 at res_idx=0 — must fail */ + xce_sched_worker_t w2; + memset(&w2, 0, sizeof(w2)); + zarray_init(&w2.resvals, sizeof(xce_val_t*), NULL); + + xce_val_t v2; + memset(&v2, 0, sizeof(v2)); + v2.which = Value_u_fvalue; + v2.u.fvalue = 2.0f; + zarray_put(&w2.resvals, 0, &v2); + + TEST_ASSERT_EQUAL_INT(0, sched_meet_host_selection(&sched, &w2, &sel)); + + zarray_fini(&w8.resvals); + zarray_fini(&w2.resvals); + gc_clear_marks(); + gc_sweep_select_nodes(NULL, 0); + sel_node_table_fini(); + sel_optimize_test_reset(); +} + +static void +test_meet_host_selection_string_match(void) +{ + /* Job requires: res[1] == "gpu". + * Worker with strval[1]="gpu" must match (rc=1). + * Worker with strval[1]="cpu" must not match (rc=0). */ + sel_optimize_set(1); + xstring_table_init(139); + sel_node_table_init(); + + /* Build resreq AST: SEL_EQ(SEL_RESNAME(idx=1, STRING), SEL_STR("gpu")) */ + xce_select_node_t* resname = makeSelectNode(SEL_RESNAME, 1, RES_TYPE_STRING); + char* gpu_str = makeString("gpu"); + xce_select_node_t* str_node = makeSelectNode(SEL_STR, (uintptr_t)gpu_str, 0); + xce_select_node_t* eq = makeSelectNode(SEL_EQ, + (uintptr_t)resname, + (uintptr_t)str_node); + TEST_ASSERT_NOT_NULL(eq); + + xce_select_t sel = { .root = eq }; + xce_scheduler_t sched; + memset(&sched, 0, sizeof(sched)); + + /* Worker with "gpu" at res_idx=1 — must pass */ + xce_sched_worker_t wgpu; + memset(&wgpu, 0, sizeof(wgpu)); + zarray_init(&wgpu.resvals, sizeof(xce_val_t*), NULL); + + xce_val_t vgpu; + memset(&vgpu, 0, sizeof(vgpu)); + vgpu.which = Value_u_svalue; + vgpu.u.svalue = "gpu"; + zarray_put(&wgpu.resvals, 1, &vgpu); + + TEST_ASSERT_EQUAL_INT(1, sched_meet_host_selection(&sched, &wgpu, &sel)); + + /* Worker with "cpu" at res_idx=1 — must fail */ + xce_sched_worker_t wcpu; + memset(&wcpu, 0, sizeof(wcpu)); + zarray_init(&wcpu.resvals, sizeof(xce_val_t*), NULL); + + xce_val_t vcpu; + memset(&vcpu, 0, sizeof(vcpu)); + vcpu.which = Value_u_svalue; + vcpu.u.svalue = "cpu"; + zarray_put(&wcpu.resvals, 1, &vcpu); + + TEST_ASSERT_EQUAL_INT(0, sched_meet_host_selection(&sched, &wcpu, &sel)); + + zarray_fini(&wgpu.resvals); + zarray_fini(&wcpu.resvals); + gc_clear_marks(); + gc_sweep_select_nodes(NULL, 0); + sel_node_table_fini(); + xstring_table_fini(); + sel_optimize_test_reset(); +} + #define TEST(x) \ do { \ if (check_test(&arguments, #x)) { \ @@ -240,6 +359,8 @@ int main(int argc, char* argv[]) TEST(test_meet_host_selection_always_true_passes); TEST(test_meet_host_selection_always_false_fails); TEST(test_gc_predicates_idle_invariant); + TEST(test_meet_host_selection_numeric_match); + TEST(test_meet_host_selection_string_match); return UNITY_END(); }