fix(scheduler): sim resource over-commit, byte-unit display, sync job-state-at-capture

- bug-1799/1801: fix resInUse over-commit in sim replay -- sched_account_jobs's
  per-round re-derive pass now skips RECONCILING/UNAVAIL workers the same way
  core_reset_workers already does (bug-1751), closing the gap that let a
  worker's used slots exceed its own capacity across a resync replay
- bug-1804: revise scheduler-sim-eager-reconciliation spec (user-directed) so
  a captured job's job->state is set to RUN synchronously at dispatch capture,
  mirroring sched_commit_decision's normal-mode semantics (bug-1624), instead
  of deferring until its separately-recorded JOB_STATE_CHANGE event replays
- bug-1800: render bytes-valued CONSUMABLE resources (mem/swp/tmp) with the
  same human-scaled unit formatting already used for maxmem/maxswap/maxtmp
- bug-1802/1803: add then revert a break-on-ANY-event breakpoint kind after
  live feedback that it over-fires inside busy sessions; replace it with a
  prescan-based "next non-dummy session" hint in info summary instead

Full scheduler suite: 77/77 tests pass (asan profile).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RLSNJhNoULvVcUhXEFafQC
This commit is contained in:
Rongsong Shen 2026-09-12 14:06:41 +00:00
parent ffca959ed9
commit 25fb5c115a
No known key found for this signature in database
GPG key ID: 5BCDAAE0123E9FE2
22 changed files with 1827 additions and 303 deletions

View file

@ -1902,6 +1902,99 @@ static void test_event_breakpoint_pauses_repl_at_matching_event(void)
printf("test_event_breakpoint_pauses_repl_at_matching_event: PASS\n");
}
/*
* test_info_summary_reports_next_nondummy_session_when_present -
* user-requested (2026-09-11, replacing a reverted `break ANY` breakpoint
* kind -- see repl_internal.h's own doc comment on xce_repl_bp_kind_t):
* `info summary`, called at the very start (before any `step`/`continue`,
* i.e. session_count==0), must report the next session that decodes at
* least one real event, skipping two fully-empty dummy sessions (rounds
* 1000 and 2000), plus the exact `step` count to reach it.
*/
static void
test_info_summary_reports_next_nondummy_session_when_present(void)
{
char replay_path[PATH_MAX];
char aux_dir[PATH_MAX];
char script_path[PATH_MAX];
char capture_path[PATH_MAX];
FILE* f;
char* captured;
f = write_header_and_snapshot(replay_path, sizeof(replay_path),
"_nextnd");
TEST_ASSERT_NOT_NULL(f);
append_replay_session(f, 1000ULL); /* session 1: dummy */
append_replay_session(f, 2000ULL); /* session 2: dummy */
append_jobstatechange_event(f, 2500ULL, 444ULL); /* session 3's event */
append_replay_session(f, 3000ULL); /* session 3: real */
append_end_of_stream_marker(f);
fclose(f);
make_tmp_dir(aux_dir, sizeof(aux_dir), "_nextndaux");
snprintf(script_path, sizeof(script_path), "%s/script.txt", aux_dir);
snprintf(capture_path, sizeof(capture_path), "%s/capture.out", aux_dir);
write_text_file(script_path, "info summary\nquit\n");
captured = run_group_d_and_capture(replay_path, script_path, capture_path);
TEST_ASSERT_NOT_NULL_MESSAGE(
strstr(captured, "next non-dummy session: 3 -- run 'step 3' to "
"reach it"),
"info summary must report session 3 (skipping the two dummy "
"sessions 1 and 2) and the exact step count (3) to reach it from "
"the very start (session_count==0)");
free(captured);
printf("test_info_summary_reports_next_nondummy_session_when_present: "
"PASS\n");
}
/*
* test_info_summary_reports_none_remaining_when_all_dummy - the file has
* exactly two sessions, BOTH dummy, and nothing after them -- `info
* summary` must say so plainly rather than reporting a bogus session
* number or silently omitting the line.
*/
static void
test_info_summary_reports_none_remaining_when_all_dummy(void)
{
char replay_path[PATH_MAX];
char aux_dir[PATH_MAX];
char script_path[PATH_MAX];
char capture_path[PATH_MAX];
FILE* f;
char* captured;
f = write_header_and_snapshot(replay_path, sizeof(replay_path),
"_nonend");
TEST_ASSERT_NOT_NULL(f);
append_replay_session(f, 1000ULL); /* session 1: dummy */
append_replay_session(f, 2000ULL); /* session 2: dummy */
append_end_of_stream_marker(f);
fclose(f);
make_tmp_dir(aux_dir, sizeof(aux_dir), "_nonendaux");
snprintf(script_path, sizeof(script_path), "%s/script.txt", aux_dir);
snprintf(capture_path, sizeof(capture_path), "%s/capture.out", aux_dir);
write_text_file(script_path, "info summary\nquit\n");
captured = run_group_d_and_capture(replay_path, script_path, capture_path);
TEST_ASSERT_NOT_NULL_MESSAGE(
strstr(captured, "next non-dummy session: none remaining"),
"info summary must plainly report that no non-dummy session "
"remains, not a bogus number or silence");
free(captured);
printf("test_info_summary_reports_none_remaining_when_all_dummy: "
"PASS\n");
}
static void test_decision_breakpoint_pauses_after_decision_output(void)
{
char replay_path[PATH_MAX];
@ -2149,6 +2242,8 @@ int main(void)
RUN_TEST(test_info_resource_all_reports_when_none_are_global_shared);
RUN_TEST(test_info_job_accepts_quoted_jobid_argument);
RUN_TEST(test_info_summary_reports_counts);
RUN_TEST(test_info_summary_reports_next_nondummy_session_when_present);
RUN_TEST(test_info_summary_reports_none_remaining_when_all_dummy);
RUN_TEST(test_info_session_reports_position_after_synthetic_events);
RUN_TEST(test_event_breakpoint_pauses_repl_at_matching_event);