myxce/src/scheduler/testsuite/test_alloc_cache.c
Rongsong Shen 89297dc825
feat(scheduler-sim-live-allocation): add unsatisfiable-cache callback seam (task 1.1)
Adds a NULL-by-default lookup/populate callback seam on xce_sched_core_t,
mirroring cache_clear_cb's proven shape, so the allocation dispatch
chokepoint can consult the unsatisfiable-resreq cache without a
normal-mode-only field access in shared code. Adapters live in
alloc_cache.c and are registered only during normal-mode startup;
simulation mode leaves both callbacks NULL and always computes fresh.

Adds the scheduler-sim-live-allocation spec (requirements/design/
research/tasks) as the planning artifact this and subsequent tasks
implement against.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RLSNJhNoULvVcUhXEFafQC
2026-09-18 10:14:04 +00:00

577 lines
23 KiB
C

/*
* test_alloc_cache.c - unit test for the session-level unsatisfiable-
* resreq cache (scheduler-allocation spec, task 2.2, Req 7.1, 7.3, 7.4,
* 7.5).
*
* White-box test TU: #includes ../src/alloc_cache.c directly (same
* convention test_host_iter.c/test_job_update.c/test_handlers.c already
* establish for this test suite), so it exercises the REAL
* cache_key_hash_/cache_key_cmp_/cache_key_assign_/cache_key_destroy_ and
* cache_lookup()/cache_insert()/cache_clear() implementations, not a stub.
*
* alloc_cache.c only depends on kv.h (libxce, already linked) and
* scheduler.h/sched/types.h (header-only struct definitions) -- it never
* touches xce_scheduler_t.core, so this fixture never calls
* xce_sched_core_init(); a bare memset()'d xce_scheduler_t with its own
* unsatisfiable_cache field constructed directly (mirroring sched_init()'s
* own construction call, scheduler.c) is sufficient.
*
* Covers, per this task's Observable line:
* - same-key-twice HIT (not just insert-then-miss-on-a-different-key,
* which the cache_key_cmp_() inverted-polarity bug already found and
* fixed during design review -- requirements.md's "New types (Req 7)"
* section -- would still have passed). This is deliberately the FIRST
* test below.
* - a lookup differing in any single field (each of the four resreq
* fingerprint fields, and each of the three identity fields) is a
* miss.
* - reason-category round-trip: insert with category X, hit later
* returns X -- tested with two distinct category values to rule out a
* trivial always-returns-0 implementation.
* - clear() empties all entries.
*/
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unity/unity.h>
#include "sched/alloc_cache.h"
#include "scheduler.h"
/* Pull in the real cache_key_ops/cache_lookup/cache_insert/cache_clear
* implementation under test. */
#include "../src/alloc_cache.c"
void setUp(void) { return; }
void tearDown(void) { return; }
/* ---------------------------------------------------------------------- */
/* Fixture helpers */
/* ---------------------------------------------------------------------- */
/*
* init_sched - a bare xce_scheduler_t with only unsatisfiable_cache
* constructed (this cache never touches sched->core). Mirrors sched_init()'s
* own construction call (scheduler.c) exactly, so the fixture and
* production code can never silently drift.
*/
static void init_sched(xce_scheduler_t* sched)
{
kv_params_t params = { .nslots = XCE_UNSAT_CACHE_NSLOTS,
.keyops = &cache_key_ops,
.datakiller = NULL };
memset(sched, 0, sizeof(*sched));
sched->unsatisfiable_cache = makeInstance(&kvtab_type, &params);
TEST_ASSERT_NOT_NULL(sched->unsatisfiable_cache);
}
static void fini_sched(xce_scheduler_t* sched)
{
if (sched->unsatisfiable_cache != NULL) {
destroy(sched->unsatisfiable_cache);
sched->unsatisfiable_cache = NULL;
}
}
/*
* init_primary_obj - a minimal, valid xce_sched_obj_t/xce_primary_schedobj_t
* pair: tag == XCE_RESREQ_PRIMARY, u.primary pointing at `primary`, with
* `primary`'s resreq_fp set to the given fingerprint fields and the
* object's own user/queue/project identity pointers set. Every other field
* (owner/resreq/reason on primary; glimits/hlimits/alloc/reason on obj) is
* left zeroed -- cache_lookup()/cache_insert() never touch them.
*/
static void init_primary_obj(xce_sched_obj_t* obj, xce_primary_schedobj_t* primary,
int min_tasks, int max_tasks,
uint32_t select_node_id, uint64_t rusage_hash,
const char* user, const char* queue,
const char* project)
{
memset(obj, 0, sizeof(*obj));
memset(primary, 0, sizeof(*primary));
primary->resreq_fp.min_tasks = min_tasks;
primary->resreq_fp.max_tasks = max_tasks;
primary->resreq_fp.select_node_id = select_node_id;
primary->resreq_fp.rusage_hash = rusage_hash;
obj->tag = XCE_RESREQ_PRIMARY;
obj->u.primary = primary;
obj->user = (char*)user;
obj->queue = (char*)queue;
obj->project = (char*)project;
}
/* Baseline fixture fingerprint + identity, reused (with one field varied
* at a time) across the miss tests below. Distinct string literals (not
* merely distinct content) are used for the identity fields so pointer
* inequality is unambiguous regardless of any compiler string-literal
* pooling -- this cache's cmp is pointer-based, exactly mirroring the real
* xstring-interned-pointer contract identity fields carry in production. */
#define BASE_MIN_TASKS 1
#define BASE_MAX_TASKS 4
#define BASE_SELECT_NODE_ID 100u
#define BASE_RUSAGE_HASH ((uint64_t)0xdeadbeefULL)
static const char BASE_USER[] = "alice";
static const char BASE_QUEUE[] = "normal";
static const char BASE_PROJECT[] = "proj1";
/* ---------------------------------------------------------------------- */
/* Tests */
/* ---------------------------------------------------------------------- */
/*
* THE critical test (design.md's own words: "a functionally dead cache
* from day one would not fail any test that doesn't specifically assert a
* hit"): insert once, then look up an INDEPENDENTLY constructed key with
* every field identical (including pointer-identical identity fields) --
* must be a hit, returning the exact category given at insert time. A
* cache_key_cmp_() with the earlier, inverted boolean polarity would fail
* this test (every lookup a false miss) while still passing a weaker
* insert-then-miss-on-a-different-key round-trip.
*/
static void test_same_key_twice_is_a_hit(void)
{
xce_scheduler_t sched;
xce_sched_obj_t obj1, obj2;
xce_primary_schedobj_t primary1, primary2;
int category = 42;
int out = -1;
int rc;
init_sched(&sched);
init_primary_obj(&obj1, &primary1, BASE_MIN_TASKS, BASE_MAX_TASKS,
BASE_SELECT_NODE_ID, BASE_RUSAGE_HASH, BASE_USER,
BASE_QUEUE, BASE_PROJECT);
init_primary_obj(&obj2, &primary2, BASE_MIN_TASKS, BASE_MAX_TASKS,
BASE_SELECT_NODE_ID, BASE_RUSAGE_HASH, BASE_USER,
BASE_QUEUE, BASE_PROJECT);
rc = cache_insert(&sched, &obj1, category);
TEST_ASSERT_EQUAL_INT(0, rc);
rc = cache_lookup(&sched, &obj2, &out);
TEST_ASSERT_EQUAL_INT(1, rc);
TEST_ASSERT_EQUAL_INT(category, out);
fini_sched(&sched);
}
/*
* A lookup before any insert is a plain miss.
*/
static void test_lookup_before_any_insert_is_a_miss(void)
{
xce_scheduler_t sched;
xce_sched_obj_t obj;
xce_primary_schedobj_t primary;
int out = -1;
int rc;
init_sched(&sched);
init_primary_obj(&obj, &primary, BASE_MIN_TASKS, BASE_MAX_TASKS,
BASE_SELECT_NODE_ID, BASE_RUSAGE_HASH, BASE_USER,
BASE_QUEUE, BASE_PROJECT);
rc = cache_lookup(&sched, &obj, &out);
TEST_ASSERT_EQUAL_INT(0, rc);
fini_sched(&sched);
}
/*
* differing_field_misses - shared body for "a lookup differing in exactly
* one field is a miss": insert the base key with `category`, then look up
* a second key built from the given (possibly-varied) fields -- must miss.
*/
static void assert_variant_misses(int min_tasks, int max_tasks,
uint32_t select_node_id,
uint64_t rusage_hash, const char* user,
const char* queue, const char* project)
{
xce_scheduler_t sched;
xce_sched_obj_t base_obj, variant_obj;
xce_primary_schedobj_t base_primary, variant_primary;
int out = -1;
int rc;
init_sched(&sched);
init_primary_obj(&base_obj, &base_primary, BASE_MIN_TASKS, BASE_MAX_TASKS,
BASE_SELECT_NODE_ID, BASE_RUSAGE_HASH, BASE_USER,
BASE_QUEUE, BASE_PROJECT);
init_primary_obj(&variant_obj, &variant_primary, min_tasks, max_tasks,
select_node_id, rusage_hash, user, queue, project);
rc = cache_insert(&sched, &base_obj, 7);
TEST_ASSERT_EQUAL_INT(0, rc);
rc = cache_lookup(&sched, &variant_obj, &out);
TEST_ASSERT_EQUAL_INT(0, rc);
fini_sched(&sched);
}
static void test_miss_on_differing_min_tasks(void)
{
assert_variant_misses(BASE_MIN_TASKS + 1, BASE_MAX_TASKS,
BASE_SELECT_NODE_ID, BASE_RUSAGE_HASH, BASE_USER,
BASE_QUEUE, BASE_PROJECT);
}
static void test_miss_on_differing_max_tasks(void)
{
assert_variant_misses(BASE_MIN_TASKS, BASE_MAX_TASKS + 1,
BASE_SELECT_NODE_ID, BASE_RUSAGE_HASH, BASE_USER,
BASE_QUEUE, BASE_PROJECT);
}
static void test_miss_on_differing_select_node_id(void)
{
assert_variant_misses(BASE_MIN_TASKS, BASE_MAX_TASKS,
BASE_SELECT_NODE_ID + 1, BASE_RUSAGE_HASH,
BASE_USER, BASE_QUEUE, BASE_PROJECT);
}
static void test_miss_on_differing_rusage_hash(void)
{
assert_variant_misses(BASE_MIN_TASKS, BASE_MAX_TASKS,
BASE_SELECT_NODE_ID, BASE_RUSAGE_HASH ^ 0x1ULL,
BASE_USER, BASE_QUEUE, BASE_PROJECT);
}
static void test_miss_on_differing_user(void)
{
static const char other_user[] = "bob";
assert_variant_misses(BASE_MIN_TASKS, BASE_MAX_TASKS,
BASE_SELECT_NODE_ID, BASE_RUSAGE_HASH, other_user,
BASE_QUEUE, BASE_PROJECT);
}
static void test_miss_on_differing_queue(void)
{
static const char other_queue[] = "priority";
assert_variant_misses(BASE_MIN_TASKS, BASE_MAX_TASKS,
BASE_SELECT_NODE_ID, BASE_RUSAGE_HASH, BASE_USER,
other_queue, BASE_PROJECT);
}
static void test_miss_on_differing_project(void)
{
static const char other_project[] = "proj2";
assert_variant_misses(BASE_MIN_TASKS, BASE_MAX_TASKS,
BASE_SELECT_NODE_ID, BASE_RUSAGE_HASH, BASE_USER,
BASE_QUEUE, other_project);
}
/*
* Req 7.5: a cache hit reports the SAME reason category the original
* miss's exhausted attempt stored -- tested with two distinct category
* values (on two distinct keys, since re-inserting the identical key
* would hit kvtab_add()'s own -EEXIST contract) to rule out a trivial
* always-returns-0 (or always-returns-the-first-inserted-value)
* implementation.
*/
static void test_reason_category_round_trip_two_distinct_categories(void)
{
xce_scheduler_t sched;
xce_sched_obj_t obj_a, obj_b;
xce_primary_schedobj_t primary_a, primary_b;
static const char user_b[] = "carol";
int out_a = -1, out_b = -1;
int rc;
init_sched(&sched);
init_primary_obj(&obj_a, &primary_a, BASE_MIN_TASKS, BASE_MAX_TASKS,
BASE_SELECT_NODE_ID, BASE_RUSAGE_HASH, BASE_USER,
BASE_QUEUE, BASE_PROJECT);
/* Distinct key (differs only in identity) so this doesn't collide with
* obj_a's own insert. */
init_primary_obj(&obj_b, &primary_b, BASE_MIN_TASKS, BASE_MAX_TASKS,
BASE_SELECT_NODE_ID, BASE_RUSAGE_HASH, user_b,
BASE_QUEUE, BASE_PROJECT);
rc = cache_insert(&sched, &obj_a, 11);
TEST_ASSERT_EQUAL_INT(0, rc);
rc = cache_insert(&sched, &obj_b, 99);
TEST_ASSERT_EQUAL_INT(0, rc);
rc = cache_lookup(&sched, &obj_a, &out_a);
TEST_ASSERT_EQUAL_INT(1, rc);
TEST_ASSERT_EQUAL_INT(11, out_a);
rc = cache_lookup(&sched, &obj_b, &out_b);
TEST_ASSERT_EQUAL_INT(1, rc);
TEST_ASSERT_EQUAL_INT(99, out_b);
fini_sched(&sched);
}
/*
* cache_clear() empties every entry: insert two distinct keys, clear, then
* confirm BOTH now miss (not just the one inserted last).
*/
static void test_clear_empties_all_entries(void)
{
xce_scheduler_t sched;
xce_sched_obj_t obj_a, obj_b;
xce_primary_schedobj_t primary_a, primary_b;
static const char user_b[] = "dave";
int out = -1;
int rc;
init_sched(&sched);
init_primary_obj(&obj_a, &primary_a, BASE_MIN_TASKS, BASE_MAX_TASKS,
BASE_SELECT_NODE_ID, BASE_RUSAGE_HASH, BASE_USER,
BASE_QUEUE, BASE_PROJECT);
init_primary_obj(&obj_b, &primary_b, BASE_MIN_TASKS, BASE_MAX_TASKS,
BASE_SELECT_NODE_ID, BASE_RUSAGE_HASH, user_b,
BASE_QUEUE, BASE_PROJECT);
TEST_ASSERT_EQUAL_INT(0, cache_insert(&sched, &obj_a, 1));
TEST_ASSERT_EQUAL_INT(0, cache_insert(&sched, &obj_b, 2));
/* Sanity: both are hits before clear. */
TEST_ASSERT_EQUAL_INT(1, cache_lookup(&sched, &obj_a, &out));
TEST_ASSERT_EQUAL_INT(1, cache_lookup(&sched, &obj_b, &out));
cache_clear(&sched);
TEST_ASSERT_NOT_NULL(sched.unsatisfiable_cache);
rc = cache_lookup(&sched, &obj_a, &out);
TEST_ASSERT_EQUAL_INT(0, rc);
rc = cache_lookup(&sched, &obj_b, &out);
TEST_ASSERT_EQUAL_INT(0, rc);
fini_sched(&sched);
}
/*
* Re-inserting the identical key without an intervening clear propagates
* kvtab_add()'s own -EEXIST contract -- exercising cache_insert()'s error
* path.
*/
static void test_insert_duplicate_key_returns_eexist(void)
{
xce_scheduler_t sched;
xce_sched_obj_t obj1, obj2;
xce_primary_schedobj_t primary1, primary2;
int rc;
init_sched(&sched);
init_primary_obj(&obj1, &primary1, BASE_MIN_TASKS, BASE_MAX_TASKS,
BASE_SELECT_NODE_ID, BASE_RUSAGE_HASH, BASE_USER,
BASE_QUEUE, BASE_PROJECT);
init_primary_obj(&obj2, &primary2, BASE_MIN_TASKS, BASE_MAX_TASKS,
BASE_SELECT_NODE_ID, BASE_RUSAGE_HASH, BASE_USER,
BASE_QUEUE, BASE_PROJECT);
TEST_ASSERT_EQUAL_INT(0, cache_insert(&sched, &obj1, 5));
rc = cache_insert(&sched, &obj2, 6);
TEST_ASSERT_EQUAL_INT(-EEXIST, rc);
fini_sched(&sched);
}
/*
* Defensive argument checking: NULL sched/obj/out_reason_category, and a
* non-primary tag object, are all rejected rather than crashing.
*/
static void test_argument_validation(void)
{
xce_scheduler_t sched;
xce_sched_obj_t obj;
xce_primary_schedobj_t primary;
xce_sched_obj_t non_primary_obj;
int out = -1;
init_sched(&sched);
init_primary_obj(&obj, &primary, BASE_MIN_TASKS, BASE_MAX_TASKS,
BASE_SELECT_NODE_ID, BASE_RUSAGE_HASH, BASE_USER,
BASE_QUEUE, BASE_PROJECT);
memset(&non_primary_obj, 0, sizeof(non_primary_obj));
non_primary_obj.tag = XCE_RESREQ_PRIMARY + 1; /* anything != PRIMARY */
TEST_ASSERT_EQUAL_INT(-EINVAL, cache_lookup(NULL, &obj, &out));
TEST_ASSERT_EQUAL_INT(-EINVAL, cache_lookup(&sched, NULL, &out));
TEST_ASSERT_EQUAL_INT(-EINVAL, cache_lookup(&sched, &obj, NULL));
TEST_ASSERT_EQUAL_INT(-EINVAL,
cache_lookup(&sched, &non_primary_obj, &out));
TEST_ASSERT_EQUAL_INT(-EINVAL, cache_insert(NULL, &obj, 1));
TEST_ASSERT_EQUAL_INT(-EINVAL, cache_insert(&sched, NULL, 1));
TEST_ASSERT_EQUAL_INT(-EINVAL, cache_insert(&sched, &non_primary_obj, 1));
/* cache_clear(NULL) must not crash. */
cache_clear(NULL);
fini_sched(&sched);
}
/* ---------------------------------------------------------------------- */
/* Task 1.1 (scheduler-sim-live-allocation spec, Req 5.2): the */
/* unsatisfiable-cache callback seam. */
/* ---------------------------------------------------------------------- */
/*
* A freshly-zeroed xce_sched_core_t (the same memset() default
* xce_sched_core_init() applies -- core.c is not linked into this
* white-box TU, so this test zeroes a bare instance directly rather than
* calling that function) leaves BOTH new callback fields NULL. This is
* the exact state every simulation-mode xce_sched_core_t is in forever --
* sim_loop.c never registers either callback (Req 5 AC 17 "Simulation
* isolation").
*/
static void test_seam_fields_default_null_on_zeroed_core(void)
{
xce_sched_core_t core;
memset(&core, 0, sizeof(core));
TEST_ASSERT_NULL(core.unsatisfiable_lookup_cb);
TEST_ASSERT_NULL(core.unsatisfiable_populate_cb);
}
/*
* THE Observable this task's own TDD note names: "with both callbacks
* left NULL, the allocation dispatch chokepoint always computes fresh
* with no crash and no incorrect skip." The real chokepoint
* (sched_make_primary_alloc_(), scheduler.c) is migrated to actually
* consult this seam by a LATER task (tasks.md 2.2, boundary "Core-Safe
* Allocation Chain, Unsatisfiable-Cache Callback Seam") -- this task adds
* only the seam itself, not that call site. This test proves the seam's
* own NULL-safety contract in isolation, using the identical NULL-check
* shape design.md's own invariant specifies for that future call site
* ("the allocation chain ... only ever NULL-checks and calls these"):
* with both fields NULL, a NULL-checked consult never dereferences either
* function pointer (no crash), is never mistaken for a cache HIT (no
* incorrect skip -- `hit` stays 0, meaning "compute fresh"), and a
* NULL-checked populate attempt is silently skipped, not a fatal error.
*/
static void test_null_callbacks_mean_always_compute_fresh(void)
{
xce_sched_core_t core;
xce_sched_obj_t obj;
xce_primary_schedobj_t primary;
int category = -1;
int hit = -1; /* poison: neither 0 nor 1 yet */
memset(&core, 0, sizeof(core));
init_primary_obj(&obj, &primary, BASE_MIN_TASKS, BASE_MAX_TASKS,
BASE_SELECT_NODE_ID, BASE_RUSAGE_HASH, BASE_USER,
BASE_QUEUE, BASE_PROJECT);
/* Prove the guard's PRECONDITION explicitly, immediately before relying
* on it below -- not just that the end result happens to be "compute
* fresh", but that the NULL-ness this test's two guarded calls depend
* on genuinely holds at the exact point each guard is evaluated. A
* design that accidentally called through a non-NULL stale/garbage
* pointer here (e.g. an uninitialized field instead of a true NULL)
* could still coincidentally return 0/not crash on some platforms;
* asserting NULL directly, right where each guard fires, rules that
* out. */
TEST_ASSERT_NULL(core.unsatisfiable_lookup_cb);
if (core.unsatisfiable_lookup_cb != NULL) {
hit = core.unsatisfiable_lookup_cb(&core, &obj, &category);
} else {
hit = 0; /* no cache registered => always a miss => compute fresh */
}
TEST_ASSERT_EQUAL_INT(0, hit);
/* A NULL-checked populate attempt must be a true no-op, not a crash --
* same "assert the guard's own precondition, right at the guard"
* discipline as the lookup check just above. */
TEST_ASSERT_NULL(core.unsatisfiable_populate_cb);
if (core.unsatisfiable_populate_cb != NULL) {
core.unsatisfiable_populate_cb(&core, &obj, 7);
}
}
/*
* Normal-mode observable (this task's own note): "a normal-mode test
* confirming the cache is still consulted/populated exactly as before
* this change." xce_alloc_cache_lookup_cb()/xce_alloc_cache_populate_cb()
* (alloc_cache.c) are the two adapters main.c registers on the real
* xce_scheduler_t's core (xce_sched_core_t core is xce_scheduler_t's
* first member, scheduler.h -- the same pointer-to-first-member idiom
* xce_alloc_cache_clear_cb() already uses). This test calls them through
* core.unsatisfiable_lookup_cb/unsatisfiable_populate_cb exactly as a
* normal-mode driver would, and confirms the result is identical to
* calling cache_lookup()/cache_insert() directly -- proving the adapters
* are a transparent passthrough, not a behavior change.
*/
static void test_lookup_and_populate_cb_adapters_match_direct_cache_calls(void)
{
xce_scheduler_t sched;
xce_sched_obj_t obj;
xce_primary_schedobj_t primary;
int out_direct = -1;
int out_via_cb = -1;
int rc;
init_sched(&sched);
sched.core.unsatisfiable_lookup_cb = xce_alloc_cache_lookup_cb;
sched.core.unsatisfiable_populate_cb = xce_alloc_cache_populate_cb;
init_primary_obj(&obj, &primary, BASE_MIN_TASKS, BASE_MAX_TASKS,
BASE_SELECT_NODE_ID, BASE_RUSAGE_HASH, BASE_USER,
BASE_QUEUE, BASE_PROJECT);
/* Miss before any insert, via the callback -- same as a direct
* cache_lookup() call (test_lookup_before_any_insert_is_a_miss
* above). */
TEST_ASSERT_NOT_NULL(sched.core.unsatisfiable_lookup_cb);
rc = sched.core.unsatisfiable_lookup_cb(&(sched.core), &obj, &out_via_cb);
TEST_ASSERT_EQUAL_INT(0, rc);
/* Populate via the callback... */
TEST_ASSERT_NOT_NULL(sched.core.unsatisfiable_populate_cb);
sched.core.unsatisfiable_populate_cb(&(sched.core), &obj, 55);
/* ...then confirm a DIRECT cache_lookup() call sees the SAME entry --
* the adapter genuinely populated the real cache, not a shadow copy. */
rc = cache_lookup(&sched, &obj, &out_direct);
TEST_ASSERT_EQUAL_INT(1, rc);
TEST_ASSERT_EQUAL_INT(55, out_direct);
/* And the callback-based lookup now also reports the same hit. */
rc = sched.core.unsatisfiable_lookup_cb(&(sched.core), &obj, &out_via_cb);
TEST_ASSERT_EQUAL_INT(1, rc);
TEST_ASSERT_EQUAL_INT(55, out_via_cb);
fini_sched(&sched);
}
int main(void)
{
UNITY_BEGIN();
RUN_TEST(test_same_key_twice_is_a_hit);
RUN_TEST(test_lookup_before_any_insert_is_a_miss);
RUN_TEST(test_miss_on_differing_min_tasks);
RUN_TEST(test_miss_on_differing_max_tasks);
RUN_TEST(test_miss_on_differing_select_node_id);
RUN_TEST(test_miss_on_differing_rusage_hash);
RUN_TEST(test_miss_on_differing_user);
RUN_TEST(test_miss_on_differing_queue);
RUN_TEST(test_miss_on_differing_project);
RUN_TEST(test_reason_category_round_trip_two_distinct_categories);
RUN_TEST(test_clear_empties_all_entries);
RUN_TEST(test_insert_duplicate_key_returns_eexist);
RUN_TEST(test_argument_validation);
RUN_TEST(test_seam_fields_default_null_on_zeroed_core);
RUN_TEST(test_null_callbacks_mean_always_compute_fresh);
RUN_TEST(test_lookup_and_populate_cb_adapters_match_direct_cache_calls);
return UNITY_END();
}