feat(scheduler-sim-decision-trace): capture shortfall and limit rows from the satisfaction check

Task 2.2: each checked row carries name, flags, value type, total,
in-use, reserved, requested and met (same comparison as unsatisfy_());
limit rows resolve through the scope's matched limits and never count as
shortfalls; the cluster-wide check keeps every row, a host only unmet
rows, which set its shortfall/limit verdict.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Rongsong Shen 2026-10-08 09:35:00 +00:00
parent 90d417bb1b
commit 258267fa48
Signed by untrusted user: rshen
GPG key ID: 80533536B0EB651C
6 changed files with 977 additions and 38 deletions

View file

@ -1092,8 +1092,12 @@ static int emit_every_kind(xce_sched_trace_rec_t* rec)
xce_alloc_plan_t plan = make_plan(slots, 1);
xce_sched_worker_t w = make_worker(hname, 0);
sched_trace_reason_count_t rc = { 1, 1 };
sched_trace_row_t row;
make_primary(&fp, 1, 1);
memset(&row, 0, sizeof(row));
row.res = "mem";
row.total = 1;
sched_trace_path_push(rec, XCE_TRACE_PATH_ALT, 1, 2);
sched_trace_alt_skipped(rec, 1, 2); /* 1 */
sched_trace_path_pop(rec);
@ -1102,29 +1106,31 @@ static int emit_every_kind(xce_sched_trace_rec_t* rec)
sched_trace_path_push(rec, XCE_TRACE_PATH_MEMBER, 1, 1);
sched_trace_resreq_begin(rec, &fp.p, 0); /* 3 */
sched_trace_check_begin(rec, NULL);
sched_trace_check_end(rec, 1, true); /* 4 */
sched_trace_no_plan(rec, XCE_TRACE_NOPLAN_DECLINED); /* 5 */
sched_trace_plan_discarded(rec, &plan); /* 6 */
sched_trace_plan_not_tried(rec, &plan, -12); /* 7 */
sched_trace_plan_begin(rec, &plan); /* 8 */
sched_trace_pos_begin(rec, 1, 1); /* 9 */
sched_trace_row(rec, &row); /* 4 */
sched_trace_check_end(rec, 1, true); /* 5 */
sched_trace_no_plan(rec, XCE_TRACE_NOPLAN_DECLINED); /* 6 */
sched_trace_plan_discarded(rec, &plan); /* 7 */
sched_trace_plan_not_tried(rec, &plan, -12); /* 8 */
sched_trace_plan_begin(rec, &plan); /* 9 */
sched_trace_pos_begin(rec, 1, 1); /* 10 */
sched_trace_host_begin(rec, NULL, &w);
sched_trace_host_verdict(rec, XCE_TRACE_V_ACCEPTED, 0); /* 10 */
sched_trace_pos_end(rec, XCE_TRACE_POS_FILLED, hname); /* 11 */
sched_trace_plan_end(rec, 1, 0); /* 12 */
sched_trace_rollback_host(rec, hname); /* 13 */
sched_trace_row(rec, &row); /* 11, held */
sched_trace_host_verdict(rec, XCE_TRACE_V_ACCEPTED, 0); /* 12 */
sched_trace_pos_end(rec, XCE_TRACE_POS_FILLED, hname); /* 13 */
sched_trace_plan_end(rec, 1, 0); /* 14 */
sched_trace_rollback_host(rec, hname); /* 15 */
sched_trace_rollback_host(rec, hname); /* merged */
sched_trace_commit(rec); /* 14 */
sched_trace_finalize_failed(rec, -5); /* 15 */
sched_trace_search_end(rec, 1); /* 16 */
sched_trace_resreq_end(rec, 1, 0); /* 17 */
sched_trace_commit(rec); /* 16 */
sched_trace_finalize_failed(rec, -5); /* 17 */
sched_trace_search_end(rec, 1); /* 18 */
sched_trace_resreq_end(rec, 1, 0); /* 19 */
sched_trace_path_pop(rec);
sched_trace_member_failed(rec, 1, 1, -12); /* 18 */
sched_trace_attempt_reasons(rec, &rc, 1, NULL, 0, NULL, 0); /* 19 */
sched_trace_resreq_end(rec, 0, 0); /* 20 */
sched_trace_member_failed(rec, 1, 1, -12); /* 20 */
sched_trace_attempt_reasons(rec, &rc, 1, NULL, 0, NULL, 0); /* 21 */
sched_trace_resreq_end(rec, 0, 0); /* 22 */
sched_trace_path_pop(rec);
sched_trace_alt_result(rec, 0, 2); /* 21 */
return 21;
sched_trace_alt_result(rec, 0, 2); /* 23 */
return 23;
}
static void test_every_entry_kind_is_one_entry(void)
@ -1152,14 +1158,16 @@ static void test_every_entry_kind_is_one_entry(void)
TEST_ASSERT_EQUAL_INT(0, seen[SCHED_TRACE_E_POS_SUMMARY]);
sched_trace_rec_free(rec);
/* summary level: the position summary replaces the host lines and the
* position end, so the same calls make one entry fewer */
/* summary level: the position summary replaces the host lines (the
* host verdict and its row) and the position end, so the same calls
* make two entries fewer */
rec = new_rec_level(XCE_TRACE_LINE_BOUND_DEFAULT, XCE_TRACE_LEVEL_SUMMARY);
TEST_ASSERT_NOT_NULL(rec);
TEST_ASSERT_EQUAL_INT(n, emit_every_kind(rec));
TEST_ASSERT_EQUAL_INT(n - 1, rec->nentries);
TEST_ASSERT_EQUAL_INT(n - 2, rec->nentries);
for (e = rec->entries; e != NULL; e = e->next) {
TEST_ASSERT_TRUE(e->type != SCHED_TRACE_E_HOST);
TEST_ASSERT_TRUE(e->type != SCHED_TRACE_E_HOST_ROW);
TEST_ASSERT_TRUE(e->type != SCHED_TRACE_E_POS_END);
seen[e->type]++;
}