feat(scheduler-sim-diagnostics): wire info limit into REPL dispatch
repl_cmd_info() now recognizes "limit" as an info subcommand, routing to the already-implemented and tested repl_info_limit() with the same ntok<3 usage guard shape as the queue/worker/resource branches. Usage string and help text updated to list it. repl_info_limit()'s own body is untouched -- this is a pure, additive dispatch-wiring change. Two new tests drive it through the real repl_dispatch() entry point (not a direct call) for both `info limit <name>` and `info limit all`. `info limit <name|all>` is now reachable from a live REPL session -- scheduler-sim-diagnostics' first capability is functionally complete. Remaining: task 5 (determinism/regression validation). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RLSNJhNoULvVcUhXEFafQC
This commit is contained in:
parent
4f60f148fb
commit
afe22d3122
4 changed files with 140 additions and 9 deletions
|
|
@ -305,6 +305,8 @@ static void repl_print_help(void)
|
|||
"Dump resource(s).");
|
||||
fprintf(stdout, FIELD_FMT, "info summary", "Quick overview.");
|
||||
fprintf(stdout, FIELD_FMT, "info config", "Show sim parameters.");
|
||||
fprintf(stdout, FIELD_FMT, "info limit <name>|all",
|
||||
"Show limit setting(s) and usage.");
|
||||
|
||||
fprintf(stdout, "\nSnapshot & Parameters:\n");
|
||||
fprintf(stdout, FIELD_FMT, "snapshot [FILE]",
|
||||
|
|
|
|||
|
|
@ -1483,9 +1483,12 @@ static void repl_print_limit_usage(xce_sched_sim_driver_t* sim,
|
|||
* 2.2, Req 1.1/1.2/1.5) -- scheduler-sim-diagnostics spec, Requirement Set
|
||||
* 1. Printing the Req 1.6 effective-host-scope note is task 2.3's job, and
|
||||
* printing live usage instances (Req 2.1-2.3, 3.1-3.4) is task 3's job.
|
||||
* Not yet wired into repl_cmd_info() (task 4 adds that branch) -- static
|
||||
* and currently uncalled from production code; exercised directly by
|
||||
* test_repl_limit_table.c per this task's own scope.
|
||||
* Wired into repl_cmd_info()'s own `else if (strcmp(tokens[1], "limit") ==
|
||||
* 0)` dispatch branch (task 4, Req 4.1/4.2) -- reachable both as real typed
|
||||
* REPL input (via repl_dispatch(), test_repl_limit_table.c's own dispatch-
|
||||
* round-trip tests) and directly (every other test in that file, per task
|
||||
* 2.1/2.3/3.1/3.2's own pre-task-4 scope). Stays `static`: only ever called
|
||||
* from within this file, same as every other `repl_info_*()` helper here.
|
||||
*
|
||||
* Requirement 1.7's "no limits configured" message is reserved for the
|
||||
* `all` path specifically -- its own acceptance criterion scopes it to
|
||||
|
|
@ -1792,10 +1795,11 @@ static void repl_info_break(xce_sched_sim_driver_t* sim)
|
|||
* repl_cmd_info - Req 5 AC 22's "info ..." family: dispatches on the second
|
||||
* token to repl_info_break()/repl_info_session()/repl_info_config()/
|
||||
* repl_info_job()/repl_info_queue()/repl_info_worker()/repl_info_resource()/
|
||||
* repl_info_summary() (all above). No `info` subcommand ever hands control
|
||||
* back to the driver loop -- inspecting state is never a reason to advance
|
||||
* the simulation. repl.c's repl_dispatch() calls this (repl_internal.h's
|
||||
* own extern declaration).
|
||||
* repl_info_summary()/repl_info_limit() (all above; repl_info_limit() wired
|
||||
* in by task 4, scheduler-sim-diagnostics spec Req 4.1/4.2). No `info`
|
||||
* subcommand ever hands control back to the driver loop -- inspecting state
|
||||
* is never a reason to advance the simulation. repl.c's repl_dispatch()
|
||||
* calls this (repl_internal.h's own extern declaration).
|
||||
*/
|
||||
bool repl_cmd_info(xce_sched_sim_driver_t* sim, const char* line)
|
||||
{
|
||||
|
|
@ -1804,7 +1808,7 @@ bool repl_cmd_info(xce_sched_sim_driver_t* sim, const char* line)
|
|||
|
||||
if (ntok < 2) {
|
||||
fprintf(stdout, "[sim] info: usage: info <break|session|config|job|jobs|queue|"
|
||||
"worker|resource|summary> [arg]\n");
|
||||
"worker|resource|summary|limit> [arg]\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -1842,6 +1846,12 @@ bool repl_cmd_info(xce_sched_sim_driver_t* sim, const char* line)
|
|||
} else {
|
||||
repl_info_resource(sim, tokens[2]);
|
||||
}
|
||||
} else if (strcmp(tokens[1], "limit") == 0) {
|
||||
if (ntok < 3) {
|
||||
fprintf(stdout, "[sim] info limit: usage: info limit <name>|all\n");
|
||||
} else {
|
||||
repl_info_limit(sim, tokens[2]);
|
||||
}
|
||||
} else {
|
||||
fprintf(stdout, "[sim] info: unrecognized subcommand '%s'\n", tokens[1]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -272,6 +272,33 @@ static char* capture_info_limit(xce_sched_sim_driver_t* sim, const char* arg)
|
|||
return capture_stdout_around(run_info_limit_for_capture);
|
||||
}
|
||||
|
||||
/*
|
||||
* Captures the output of dispatching one REPL command line THROUGH THE REAL
|
||||
* repl_dispatch() entry point -- task 4's own dispatch-round-trip
|
||||
* requirement (unlike capture_info_limit() above, which calls
|
||||
* repl_info_limit() directly, bypassing repl_cmd_info()'s tokenization and
|
||||
* dispatch entirely). Same g_sim/g_line/run_for_capture()/capture() shape
|
||||
* as capture_info_limit() above, and the same pattern
|
||||
* test_repl_resource_table.c's/test_repl_breakpoints_inspection.c's own
|
||||
* capture_dispatch() already establish for this file family. Never a
|
||||
* "step"/"continue"/"quit" line (this helper does not expect
|
||||
* repl_dispatch() to return true).
|
||||
*/
|
||||
static xce_sched_sim_driver_t* g_dispatch_sim;
|
||||
static const char* g_dispatch_line;
|
||||
|
||||
static void run_dispatch_for_capture(void)
|
||||
{
|
||||
(void)repl_dispatch(g_dispatch_sim, g_dispatch_line);
|
||||
}
|
||||
|
||||
static char* capture_dispatch(xce_sched_sim_driver_t* sim, const char* line)
|
||||
{
|
||||
g_dispatch_sim = sim;
|
||||
g_dispatch_line = line;
|
||||
return capture_stdout_around(run_dispatch_for_capture);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Limit configuration fixture helpers */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
|
@ -1492,6 +1519,94 @@ test_info_limit_named_shows_no_active_usage_instance_when_host_scoped_vres_exist
|
|||
"scoped_vres_exists_but_no_worker_populated: PASS\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Task 4 (Requirement Set 1, Req 4.1/4.2): the first tests in this file to
|
||||
* drive `info limit <name>`/`info limit all` through the REAL repl_dispatch()
|
||||
* entry point (capture_dispatch(), above) instead of calling
|
||||
* repl_info_limit() directly (capture_info_limit(), used by every test
|
||||
* above this point) -- proving the `else if (strcmp(tokens[1], "limit") ==
|
||||
* 0)` dispatch branch this task adds to repl_cmd_info() (repl_info.c)
|
||||
* actually routes real typed-in REPL input to repl_info_limit(), not just
|
||||
* that repl_info_limit() itself works in isolation (already proven by every
|
||||
* test above). Before this task's GREEN phase, repl_cmd_info() has no
|
||||
* "limit" branch at all, so `tokens[1] == "limit"` falls into its own
|
||||
* unrecognized-subcommand else branch ("[sim] info: unrecognized subcommand
|
||||
* 'limit'") -- both assertions below are expected to fail at RED.
|
||||
*/
|
||||
static void test_info_limit_dispatch_named_reaches_repl_info_limit_via_real_dispatch(
|
||||
void)
|
||||
{
|
||||
xce_sched_sim_driver_t sim;
|
||||
xce_sched_plugin_t plugin;
|
||||
xce_scheduler_t group_sched;
|
||||
char* captured;
|
||||
int rc;
|
||||
|
||||
memset(&sim, 0, sizeof(sim));
|
||||
rc = xce_sched_core_init(&(sim.core));
|
||||
TEST_ASSERT_EQUAL_INT(0, rc);
|
||||
|
||||
register_limit_plugin(&sim, &plugin, &group_sched);
|
||||
add_configured_limit(&plugin, "ug1_slots");
|
||||
|
||||
captured = capture_dispatch(&sim, "info limit ug1_slots");
|
||||
|
||||
TEST_ASSERT_NULL_MESSAGE(
|
||||
strstr(captured, "unrecognized subcommand"),
|
||||
"Req 4.1: 'info limit <name>' typed as real REPL input must be "
|
||||
"recognized -- repl_cmd_info() must route it to repl_info_limit(), "
|
||||
"not fall through to the unrecognized-subcommand branch");
|
||||
TEST_ASSERT_NOT_NULL_MESSAGE(
|
||||
strstr(captured, "limit: ug1_slots"),
|
||||
"Req 4.1: dispatching 'info limit ug1_slots' through repl_dispatch() "
|
||||
"must produce the same fmt_limit() dump a direct repl_info_limit() "
|
||||
"call already produces for this fixture");
|
||||
|
||||
free(captured);
|
||||
|
||||
printf("test_info_limit_dispatch_named_reaches_repl_info_limit_via_real_"
|
||||
"dispatch: PASS\n");
|
||||
}
|
||||
|
||||
static void
|
||||
test_info_limit_dispatch_all_reaches_repl_info_limit_via_real_dispatch(void)
|
||||
{
|
||||
xce_sched_sim_driver_t sim;
|
||||
xce_sched_plugin_t plugin;
|
||||
xce_scheduler_t group_sched;
|
||||
char* captured;
|
||||
int rc;
|
||||
|
||||
memset(&sim, 0, sizeof(sim));
|
||||
rc = xce_sched_core_init(&(sim.core));
|
||||
TEST_ASSERT_EQUAL_INT(0, rc);
|
||||
|
||||
register_limit_plugin(&sim, &plugin, &group_sched);
|
||||
add_configured_limit(&plugin, "limitA");
|
||||
add_configured_limit(&plugin, "limitB");
|
||||
|
||||
captured = capture_dispatch(&sim, "info limit all");
|
||||
|
||||
TEST_ASSERT_NULL_MESSAGE(
|
||||
strstr(captured, "unrecognized subcommand"),
|
||||
"Req 4.2: 'info limit all' typed as real REPL input must be "
|
||||
"recognized -- repl_cmd_info() must route it to repl_info_limit(), "
|
||||
"not fall through to the unrecognized-subcommand branch");
|
||||
TEST_ASSERT_NOT_NULL_MESSAGE(
|
||||
strstr(captured, "limit: limitA"),
|
||||
"Req 4.2: dispatching 'info limit all' through repl_dispatch() must "
|
||||
"display every configured limit's setting, starting with limitA");
|
||||
TEST_ASSERT_NOT_NULL_MESSAGE(
|
||||
strstr(captured, "limit: limitB"),
|
||||
"Req 4.2: ... and limitB too -- every configured limit, not just "
|
||||
"one");
|
||||
|
||||
free(captured);
|
||||
|
||||
printf("test_info_limit_dispatch_all_reaches_repl_info_limit_via_real_"
|
||||
"dispatch: PASS\n");
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
UNITY_BEGIN();
|
||||
|
|
@ -1528,5 +1643,9 @@ int main(void)
|
|||
test_info_limit_named_shows_accounted_zero_for_host_with_capacity_but_never_charged);
|
||||
RUN_TEST(
|
||||
test_info_limit_named_shows_no_active_usage_instance_when_host_scoped_vres_exists_but_no_worker_populated);
|
||||
RUN_TEST(
|
||||
test_info_limit_dispatch_named_reaches_repl_info_limit_via_real_dispatch);
|
||||
RUN_TEST(
|
||||
test_info_limit_dispatch_all_reaches_repl_info_limit_via_real_dispatch);
|
||||
return UNITY_END();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue