feat(scheduler-sim-diagnostics): display configured limit setting via fmt_limit()
repl_info_limit() now prints a matched limit's configured setting on both the all and named-lookup success paths: fmt_limit() (existing libxce formatter, unmodified) into a stack buffer, re-split and printed through a new repl_print_limit_dump() helper matching this file's existing [sim]-prefix- per-line convention. Inclusion and exclusion group membership both render since fmt_group() already handles both, adopted as-is per design.md's explicit reuse decision. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RLSNJhNoULvVcUhXEFafQC
This commit is contained in:
parent
d3df8fb29f
commit
117d01c77e
3 changed files with 199 additions and 15 deletions
|
|
@ -378,6 +378,51 @@ static void add_configured_limit(xce_sched_plugin_t* plugin, const char* name)
|
|||
free_limit_config(limits[0]);
|
||||
}
|
||||
|
||||
/*
|
||||
* add_configured_limit_with_host_exclusion - task 2.2's own Requirement 1.5
|
||||
* fixture: an "all except X" exclusion group on the HOST dimension, the
|
||||
* same shape test_limit.c's own test_build_consumer2() already establishes
|
||||
* for the USER dimension (.members=["all"], .ex_members=[<excluded>]).
|
||||
* Unlike add_configured_limit()/make_limit_config() (which leaves every
|
||||
* consumer's xce_group_config_t* NULL, so build_consumer() falls back to
|
||||
* the builtin "all" group for all four dimensions), this drives the real
|
||||
* limit_update_config() with an explicit `.hosts` group config.
|
||||
*
|
||||
* All storage here (val, hosts_cfg, limit_cfg, the `limits` array) lives on
|
||||
* this function's own stack frame; limit_update_config() -> build_limit()
|
||||
* -> build_consumer() -> makeGroup() synchronously copies every member
|
||||
* name into the real, persisted xce_group_t (and build_limit() itself
|
||||
* strdup()s the limit/resource names) before this function returns, so
|
||||
* nothing here needs to outlive the call -- the identical lifetime
|
||||
* assumption test_limit.c's own test_build_limit_ok1()-style compound
|
||||
* literals already rely on.
|
||||
*/
|
||||
static void add_configured_limit_with_host_exclusion(
|
||||
xce_sched_plugin_t* plugin, const char* name, const char* included,
|
||||
const char* excluded)
|
||||
{
|
||||
xce_limit_val_t val = { .resname = "mem",
|
||||
.percent = 0,
|
||||
.val = 10.0 };
|
||||
xce_group_config_t hosts_cfg
|
||||
= { .members = { .count = 1, .data = (char*[]) { (char*)included } },
|
||||
.ex_members = { .count = 1,
|
||||
.data = (char*[]) { (char*)excluded } } };
|
||||
xce_limit_config_t limit_cfg = { .name = (char*)name,
|
||||
.hosts = &hosts_cfg,
|
||||
.val = &val };
|
||||
xce_limit_config_t* limits[1] = { &limit_cfg };
|
||||
xce_conf4sched_t config;
|
||||
int rc;
|
||||
|
||||
memset(&config, 0, sizeof(config));
|
||||
config.nlimits = 1;
|
||||
config.limits = limits;
|
||||
|
||||
rc = limit_update_config(plugin, &config);
|
||||
TEST_ASSERT_EQUAL_INT(0, rc);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* Tests */
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
|
@ -602,6 +647,89 @@ test_info_limit_named_does_not_report_no_such_limit_for_configured_name(void)
|
|||
"configured_name: PASS\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Task 2.2's own Observable #1 (Requirement 1.1, 1.5): a matched limit's
|
||||
* configured setting is actually printed -- for the first time,
|
||||
* repl_info_limit() finding a real match must emit something beyond
|
||||
* silence. A limit configured with an exclusion group ("all except X" on
|
||||
* the HOST dimension) must show BOTH the inclusion member and the
|
||||
* exclusion member (fmt_group()'s "~" prefix) in the same displayed scope
|
||||
* line, not just the presence of some output.
|
||||
*/
|
||||
static void
|
||||
test_info_limit_named_shows_both_inclusion_and_exclusion_membership(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_with_host_exclusion(&plugin, "host_limit1", "all",
|
||||
"excluded_host");
|
||||
|
||||
captured = capture_info_limit(&sim, "host_limit1");
|
||||
|
||||
TEST_ASSERT_NOT_NULL_MESSAGE(
|
||||
strstr(captured, "limit: host_limit1"),
|
||||
"the matched limit's fmt_limit() dump must include its name line "
|
||||
"(proves real fmt_limit() output, not a stub)");
|
||||
TEST_ASSERT_NOT_NULL_MESSAGE(
|
||||
strstr(captured, "HOST = [all ~excluded_host]"),
|
||||
"Requirement 1.5: the HOST scope line must show BOTH the inclusion "
|
||||
"member ('all') and the exclusion member ('~excluded_host', "
|
||||
"fmt_group()'s own exclusion prefix) together, distinguishing "
|
||||
"included members from explicitly excluded ones");
|
||||
|
||||
free(captured);
|
||||
|
||||
printf("test_info_limit_named_shows_both_inclusion_and_exclusion_"
|
||||
"membership: PASS\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Task 2.2's own Observable #2 (Requirement 1.2): `info limit all` against
|
||||
* a fixture with MULTIPLE configured limits must display every one's
|
||||
* configured setting, not just the first match or a truncated listing.
|
||||
*/
|
||||
static void test_info_limit_all_displays_every_configured_limits_setting(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_info_limit(&sim, "all");
|
||||
|
||||
TEST_ASSERT_NOT_NULL_MESSAGE(
|
||||
strstr(captured, "limit: limitA"),
|
||||
"Requirement 1.2: 'info limit all' must display limitA's "
|
||||
"configured setting");
|
||||
TEST_ASSERT_NOT_NULL_MESSAGE(
|
||||
strstr(captured, "limit: limitB"),
|
||||
"Requirement 1.2: 'info limit all' must display limitB's "
|
||||
"configured setting too -- every configured limit, not just one");
|
||||
|
||||
free(captured);
|
||||
|
||||
printf("test_info_limit_all_displays_every_configured_limits_setting: "
|
||||
"PASS\n");
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
UNITY_BEGIN();
|
||||
|
|
@ -617,5 +745,8 @@ int main(void)
|
|||
test_info_limit_named_reports_no_such_limit_when_plugin_never_registered_not_no_limits_configured);
|
||||
RUN_TEST(
|
||||
test_info_limit_named_does_not_report_no_such_limit_for_configured_name);
|
||||
RUN_TEST(
|
||||
test_info_limit_named_shows_both_inclusion_and_exclusion_membership);
|
||||
RUN_TEST(test_info_limit_all_displays_every_configured_limits_setting);
|
||||
return UNITY_END();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue