fix(scheduler): resolve limit host and project scopes against their own groups (bug-1933)
The limit plugin called build_limit() with the host-group and project-group managers swapped, so a limit's hosts: members were looked up among the project groups (a host-group name became a literal host name and the limit never applied) and its projects: members among the host groups. Pass them in the order build_limit() declares. New test test_limit_scopes_resolve_against_own_group_kind; the test's main() now initializes the interned-string table that group names need. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
25cdbc79b4
commit
6ecd418d21
4 changed files with 229 additions and 2 deletions
|
|
@ -74,8 +74,10 @@ static int limit_seed_config_impl(xce_sched_plugin_t* plugin,
|
|||
int rc;
|
||||
xce_limit_t* limit;
|
||||
|
||||
/* bug-1933: build_limit() takes the host groups before the
|
||||
* project groups */
|
||||
rc = build_limit(&limit, (core->ugmgr), (core->qgmgr),
|
||||
(core->pgmgr), (core->hgmgr), limits[i]);
|
||||
(core->hgmgr), (core->pgmgr), limits[i]);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@
|
|||
#include "scheduler.h"
|
||||
#include "xce/types.h"
|
||||
#include "xcelimit.h"
|
||||
#include "xstring.h"
|
||||
|
||||
void reset_sched_obj(xce_sched_obj_t* obj)
|
||||
{
|
||||
|
|
@ -420,13 +421,107 @@ static void test_get_configured_limits_registered_with_zero_limits(void)
|
|||
iter_destroy(&it);
|
||||
}
|
||||
|
||||
/* bug-1933: build_limit() takes (ugmgr, qgmgr, hgmgr, pgmgr) but the
|
||||
* plugin passed (ugmgr, qgmgr, pgmgr, hgmgr), so a limit's hosts: scope
|
||||
* resolved its members against the project groups (a host-group name
|
||||
* became a literal host name) and its projects: scope against the host
|
||||
* groups (a project named like a host group matched that group's hosts).
|
||||
* With host group "hg1" = {hostA}: a hosts: [hg1] limit must match hostA,
|
||||
* and a projects: [hg1] limit must not match project "hostA". */
|
||||
static void test_limit_scopes_resolve_against_own_group_kind(void)
|
||||
{
|
||||
xce_scheduler_t sched;
|
||||
xce_sched_plugin_t plugin;
|
||||
xce_limit_config_t* limits[2];
|
||||
xce_conf4sched_t config;
|
||||
xce_group_config_t hg1 = {
|
||||
.name = "hg1",
|
||||
.members = { .count = 1, .data = (char*[]) { "hostA" } }
|
||||
};
|
||||
xce_group_config_t* hgroups[1] = { &hg1 };
|
||||
xce_group_config_t scope = {
|
||||
.members = { .count = 1, .data = (char*[]) { "hg1" } }
|
||||
};
|
||||
xce_limit_t* by_host = NULL;
|
||||
xce_limit_t* by_project = NULL;
|
||||
int rc;
|
||||
|
||||
fixture_init(&sched, &plugin);
|
||||
fixture_register_plugin_in_core(&(sched.core), &plugin);
|
||||
|
||||
rc = groupmgr_load_configs(sched.core.hgmgr, 1, hgroups);
|
||||
TEST_ASSERT_TRUE(rc >= 0);
|
||||
|
||||
limits[0] = make_limit_config("host_scoped");
|
||||
limits[0]->hosts = &scope;
|
||||
limits[1] = make_limit_config("project_scoped");
|
||||
limits[1]->projects = &scope;
|
||||
|
||||
memset(&config, 0, sizeof(config));
|
||||
config.nlimits = 2;
|
||||
config.limits = limits;
|
||||
|
||||
rc = limit_update_config(&plugin, &config);
|
||||
TEST_ASSERT_EQUAL_INT(0, rc);
|
||||
|
||||
{
|
||||
var limits_handle = limit_get_configured_limits(&(sched.core));
|
||||
iterator_t it;
|
||||
xce_limit_t* l = NULL;
|
||||
|
||||
TEST_ASSERT_NOT_NULL(limits_handle);
|
||||
rc = iter_make(&it, limits_handle);
|
||||
TEST_ASSERT_TRUE(rc >= 0);
|
||||
while ((rc = iter_next(&it, (void**)&l)) >= 0) {
|
||||
if (rc == RTTI_ITER_NO_DATA) {
|
||||
break;
|
||||
}
|
||||
if (strcmp(l->name, "host_scoped") == 0) {
|
||||
by_host = l;
|
||||
} else if (strcmp(l->name, "project_scoped") == 0) {
|
||||
by_project = l;
|
||||
}
|
||||
}
|
||||
iter_destroy(&it);
|
||||
}
|
||||
TEST_ASSERT_NOT_NULL(by_host);
|
||||
TEST_ASSERT_NOT_NULL(by_project);
|
||||
|
||||
/* host scope: hg1 is a host group, so its host matches */
|
||||
TEST_ASSERT_EQUAL_INT(1, match_limit(by_host, 0, "u1", "normal",
|
||||
"default", "hostA"));
|
||||
TEST_ASSERT_EQUAL_INT(0, match_limit(by_host, 0, "u1", "normal",
|
||||
"default", "hostB"));
|
||||
|
||||
/* project scope: hg1 is a literal project name, never the host group */
|
||||
TEST_ASSERT_EQUAL_INT(0, match_limit(by_project, 1, "u1", "normal",
|
||||
"hostA"));
|
||||
TEST_ASSERT_EQUAL_INT(1, match_limit(by_project, 1, "u1", "normal",
|
||||
"hg1"));
|
||||
|
||||
limits[0]->hosts = NULL;
|
||||
limits[1]->projects = NULL;
|
||||
free_limit_config(limits[0]);
|
||||
free_limit_config(limits[1]);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* group names are interned strings (makeString(), group.c) */
|
||||
xstring_table_init(139);
|
||||
|
||||
UNITY_BEGIN();
|
||||
RUN_TEST(test_duplicate_limit_name_no_double_free);
|
||||
RUN_TEST(test_distinct_limit_names_both_succeed);
|
||||
RUN_TEST(test_accessors_null_when_plugin_not_registered);
|
||||
RUN_TEST(test_get_configured_limits_handle_iterates_registered_limit);
|
||||
RUN_TEST(test_get_configured_limits_registered_with_zero_limits);
|
||||
return UNITY_END();
|
||||
RUN_TEST(test_limit_scopes_resolve_against_own_group_kind);
|
||||
rc = UNITY_END();
|
||||
|
||||
xstring_table_fini();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue