Collapse the 28 zero-#include white-box scheduler tests (whose meson
executable blocks each duplicated the full scheduler_srcs list) into a
single sched_unit_test aggregate, following the controller
controller_test.c precedent: one executable, one process, one runner.
- sched_unit_runner.c: SUITES registry (28 entries) with per-suite
setUp/tearDown dispatch, -t <suite> filter, UnitySetTestFile per entry
- testsuite/meson.build: runner + 28 test TUs + every scheduler_srcs
entry except src/main.c as separate TUs; foreach over scheduler_srcs
so the aggregate can never drift from the production source list;
all baked-path defines (XCE_SCHED_*_PATH, XCE_SIM_*) move to the
aggregate's c_args; -Werror=incompatible-pointer-types carried
suite-wide (verified clean across all 28 tests + 50 src TUs)
- transformed tests drop main()/setUp()/tearDown() and local stubs that
now resolve against the aggregate's real src TUs
- test() registrations 126 -> 99 (126 - 28 + 1 aggregate); the three
--wrap= interposition tests (decision publish retry, backpressure,
decision redelivery) keep their standalone executables unchanged
- isolation libs (sched_core_isolation_lib, sched_sim_isolation_lib)
stay build-only and are wired as test()-level depends; the nm(1)
text-scan tests find them via XCE_CORE_LIB_PATH/XCE_SIM_LIB_PATH
Verified: meson test --suite scheduler 100/100 green x3 consecutive
runs (43s total, aggregate 3.3s); /tmp/xce_* sweep clean (the one
leftover is test_worker_launch_type_dispatch.c's by-design fixed-path
fake xrun launcher).
Co-Authored-By: Claude Code <noreply@anthropic.com>
Retypes sched_make_allocation()/sched_make_primary_allocation()/
sched_make_compound_allocation()/sched_make_alter_allocation()/
sched_commit_decision(), plus 3 private helpers found necessary
during migration (sched_make_primary_alloc_(), sched_make_seqjob_
allocation(), sched_make_parjob_allocation()) from xce_scheduler_t*
to xce_sched_core_t* in scheduler.c.
Wires the one genuine normal-mode-only touch point -- the
unsatisfiable-resreq cache, inside sched_make_primary_alloc_() --
through the task-1.1 NULL-safe callback seam (core->unsatisfiable_
lookup_cb/populate_cb) instead of a direct field read. No other
normal-mode-only state was found in any of the 8 migrated functions,
independently confirmed by both the implementer and reviewer against
xce_scheduler_t's own field list -- no escalation needed.
Minimal &(sched->core) call-site wraps applied inside sched_allocator()/
commit_decision() (task 3.1's home, not yet migrated), matching the
pattern established in tasks 1.2/1.3/2.1.
TDD: two-part RED -- a compile-error RED from the sched_commit_decision
retype, and a behavioral RED using spy callbacks proving the cache
seam was genuinely unconsulted before this fix.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RLSNJhNoULvVcUhXEFafQC
Extends task 2.1's test_scheduler_dispatch_commit.c with two tests
proving resource-in-use accounting survives more than a single round
boundary between dispatch and worker confirmation, per task 5.1's
"several rounds" / "matching a same-round confirmation" language:
- test_dispatch_commit_survives_several_rounds_before_confirmation:
loops 5 round-boundary cycles, asserting resInUse after EVERY round,
not just once.
- test_dispatch_commit_multi_round_gap_matches_same_round_confirmation:
compares resInUse after 1 round vs after 5 rounds and asserts
equality -- a same-round confirmation is modeled as nrounds==1 since
design.md documents re-applying JOB_STAT_RUN to an already-RUN job as
a confirmed no-op, so resInUse depends only on job->state, never on
confirmation timing.
Test-only; scheduler.c is untouched. RED phase independently verified
by both implementer and reviewer via an actual revert-rebuild-rerun
cycle (4/5 tests fail without the task 2.1 fix). Independently reviewed
and approved.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Cxa1PmqAB5PyXfJaNvj8TN
sched_commit_decision()'s DISPATCH branch now sets job->state = JOB_STAT_RUN
in the same operation that already commits job->allocs/job->accounts, per
Requirement 1.1/1.2/1.3. sched_account_jobs()'s existing JOB_IS_RUN gate is
unmodified -- this closes bug-1624 by giving it the input it was missing: a
dispatched job now survives a round boundary in resource-in-use totals
regardless of how many rounds pass before worker confirmation arrives.
Regression test drives the real, unmodified sched_account_jobs() across a
simulated round boundary (resInUse reset, no confirmation event) and
independently reverting the one-line change reproduces bug-1624 exactly.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>