fix(scheduler): --sim-verify false-flagged every DISPATCH decision on wall-clock drift (bug-1842)

sim_verify_alloc_eq() compared xce_alloc_t.from, which make_alloc()
(xcealloc.c) stamps with the real OS wall clock (time(NULL)), not
core.c's virtualized sim clock. The recorded (expected) value is
whatever real second the original run happened to execute in; the
freshly-rebuilt (actual) value is whatever real second the replay
executes in -- two unrelated real-world timestamps, so every
otherwise-correct DISPATCH decision failed verification whenever a
replay ran even one wall-clock second away from its own recording.

Drop `from` from the comparison -- it's reservation bookkeeping, not
part of a decision's semantic identity. Verified against a real
captured .replay file: 120/120 false DISPATCH mismatches -> 0.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Rongsong Shen 2026-09-23 03:07:47 +00:00
parent e592e92178
commit 7901db57d4
No known key found for this signature in database
GPG key ID: 5BCDAAE0123E9FE2
4 changed files with 126 additions and 8 deletions

View file

@ -624,6 +624,41 @@ static void test_dispatch_decisions_differing_resource_value_mismatch(void)
"PASS\n");
}
/*
* test_dispatch_decisions_differing_from_timestamp_still_match -
* bug-1838-followup regression: `from` (xce_alloc_t's wall-clock reservation-
* start stamp, set unconditionally by make_alloc() via time(NULL) --
* xcealloc.c) is real-OS-clock-derived, not part of a decision's semantic
* identity. `expected`'s `from` is whatever second the ORIGINAL recording
* ran in; `actual`'s is whatever second THIS run rebuilds the allocation in
* -- two independent real-world timestamps that will essentially never
* agree for any replay of a real recording, even when the decision itself
* (job/host/resource/value/duration) is byte-for-byte the one that was
* recorded. Uses two `from` values far enough apart (a Unix-epoch-plausible
* value vs. 1) that they could never coincidentally collide, proving this
* is deliberate exclusion, not a fluke of nearby clock reads.
*/
static void test_dispatch_decisions_differing_from_timestamp_still_match(void)
{
xce_alloc_t* res_a[1]
= { make_test_alloc("gpu", "resv1", 1, 2.0, 1790000000ULL, 1800) };
xce_host_alloc_t* host_a[1] = { make_test_host_alloc("hostA", res_a, 1) };
xce_job_alloc_t* expected_alloc = make_test_job_alloc(42, host_a, 1);
xce_alloc_t* res_b[1] = { make_test_alloc("gpu", "resv1", 1, 2.0, 1ULL,
1800) };
xce_host_alloc_t* host_b[1] = { make_test_host_alloc("hostA", res_b, 1) };
xce_job_alloc_t* actual_alloc = make_test_job_alloc(42, host_b, 1);
replay_decision_t expected = make_replay_dispatch_decision(expected_alloc);
xce_decision_t* actual = make_dispatch_decision(actual_alloc);
TEST_ASSERT_TRUE(sim_decision_eq(&expected, actual));
printf("test_dispatch_decisions_differing_from_timestamp_still_match: "
"PASS\n");
}
static void test_pend_decisions_with_identical_content_match(void)
{
replay_decision_t expected = make_replay_pend_decision(9001ULL, 3);
@ -1748,6 +1783,7 @@ int main(void)
RUN_TEST(test_dispatch_decisions_differing_jobid_mismatch);
RUN_TEST(test_dispatch_decisions_differing_host_mismatch);
RUN_TEST(test_dispatch_decisions_differing_resource_value_mismatch);
RUN_TEST(test_dispatch_decisions_differing_from_timestamp_still_match);
RUN_TEST(test_pend_decisions_with_identical_content_match);
RUN_TEST(test_pend_decisions_differing_jobid_mismatch);
RUN_TEST(test_pend_decisions_differing_main_reason_mismatch);