1
0
mirror of https://github.com/systemd/systemd.git synced 2025-03-25 18:50:18 +03:00

oomd: add tests for oomd_fetch_cgroup_oom_preference

Add a new test function, test_oomd_fetch_cgroup_oom_preference, to test
the ManagedOOMPreference logic. For starters, cut the relevant tests out
of test_oomd_cgroup_context_acquire_and_insert, and add them to the new
function. Then, expand these tests to cover the new behavior.
This commit is contained in:
Nick Rosbrook 2022-07-19 12:48:04 -04:00
parent 652a4efb66
commit 39f9eee882

View File

@ -94,11 +94,8 @@ static void test_oomd_cgroup_context_acquire_and_insert(void) {
_cleanup_hashmap_free_ Hashmap *h1 = NULL, *h2 = NULL;
_cleanup_(oomd_cgroup_context_freep) OomdCGroupContext *ctx = NULL;
_cleanup_free_ char *cgroup = NULL;
ManagedOOMPreference root_pref;
OomdCGroupContext *c1, *c2;
CGroupMask mask;
bool test_xattrs;
int root_xattrs, r;
if (geteuid() != 0)
return (void) log_tests_skipped("not root");
@ -115,17 +112,6 @@ static void test_oomd_cgroup_context_acquire_and_insert(void) {
return (void) log_tests_skipped("cgroup memory controller is not available");
assert_se(cg_pid_get_path(NULL, 0, &cgroup) >= 0);
/* If we don't have permissions to set xattrs we're likely in a userns or missing capabilities
* so skip the xattr portions of the test. */
r = cg_set_xattr(SYSTEMD_CGROUP_CONTROLLER, cgroup, "user.oomd_test", "1", 1, 0);
test_xattrs = !ERRNO_IS_PRIVILEGE(r) && !ERRNO_IS_NOT_SUPPORTED(r);
if (test_xattrs) {
assert_se(cg_set_xattr(SYSTEMD_CGROUP_CONTROLLER, cgroup, "user.oomd_omit", "1", 1, 0) >= 0);
assert_se(cg_set_xattr(SYSTEMD_CGROUP_CONTROLLER, cgroup, "user.oomd_avoid", "1", 1, 0) >= 0);
}
assert_se(oomd_cgroup_context_acquire(cgroup, &ctx) == 0);
assert_se(streq(ctx->path, cgroup));
@ -135,34 +121,11 @@ static void test_oomd_cgroup_context_acquire_and_insert(void) {
assert_se(ctx->swap_usage == 0);
assert_se(ctx->last_pgscan == 0);
assert_se(ctx->pgscan == 0);
/* omit takes precedence over avoid when both are set to true */
if (test_xattrs)
assert_se(ctx->preference == MANAGED_OOM_PREFERENCE_OMIT);
else
assert_se(ctx->preference == MANAGED_OOM_PREFERENCE_NONE);
ctx = oomd_cgroup_context_free(ctx);
/* also check when only avoid is set to true */
if (test_xattrs) {
assert_se(cg_set_xattr(SYSTEMD_CGROUP_CONTROLLER, cgroup, "user.oomd_omit", "0", 1, 0) >= 0);
assert_se(cg_set_xattr(SYSTEMD_CGROUP_CONTROLLER, cgroup, "user.oomd_avoid", "1", 1, 0) >= 0);
}
assert_se(oomd_cgroup_context_acquire(cgroup, &ctx) == 0);
if (test_xattrs)
assert_se(ctx->preference == MANAGED_OOM_PREFERENCE_AVOID);
ctx = oomd_cgroup_context_free(ctx);
/* Test the root cgroup */
/* Root cgroup is live and not made on demand like the cgroup the test runs in. It can have varying
* xattrs set already so let's read in the booleans first to get the final preference value. */
root_xattrs = cg_get_xattr_bool(SYSTEMD_CGROUP_CONTROLLER, "", "user.oomd_omit");
root_pref = root_xattrs > 0 ? MANAGED_OOM_PREFERENCE_OMIT : MANAGED_OOM_PREFERENCE_NONE;
root_xattrs = cg_get_xattr_bool(SYSTEMD_CGROUP_CONTROLLER, "", "user.oomd_avoid");
root_pref = root_xattrs > 0 ? MANAGED_OOM_PREFERENCE_AVOID : MANAGED_OOM_PREFERENCE_NONE;
assert_se(oomd_cgroup_context_acquire("", &ctx) == 0);
assert_se(streq(ctx->path, "/"));
assert_se(ctx->current_memory_usage > 0);
assert_se(ctx->preference == root_pref);
/* Test hashmap inserts */
assert_se(h1 = hashmap_new(&oomd_cgroup_ctx_hash_ops));
@ -187,14 +150,6 @@ static void test_oomd_cgroup_context_acquire_and_insert(void) {
assert_se(c2->mem_pressure_limit == 6789);
assert_se(c2->mem_pressure_limit_hit_start == 42);
assert_se(c2->last_had_mem_reclaim == 888); /* assumes the live pgscan is less than UINT64_MAX */
/* Assert that avoid/omit are not set if the cgroup is not owned by root */
if (test_xattrs) {
ctx = oomd_cgroup_context_free(ctx);
assert_se(cg_set_access(SYSTEMD_CGROUP_CONTROLLER, cgroup, 65534, 0) >= 0);
assert_se(oomd_cgroup_context_acquire(cgroup, &ctx) == 0);
assert_se(ctx->preference == MANAGED_OOM_PREFERENCE_NONE);
}
}
static void test_oomd_update_cgroup_contexts_between_hashmaps(void) {
@ -451,6 +406,88 @@ static void test_oomd_sort_cgroups(void) {
sorted_cgroups = mfree(sorted_cgroups);
}
static void test_oomd_fetch_cgroup_oom_preference(void) {
_cleanup_(oomd_cgroup_context_freep) OomdCGroupContext *ctx = NULL;
_cleanup_free_ char *cgroup = NULL;
ManagedOOMPreference root_pref;
CGroupMask mask;
bool test_xattrs;
int root_xattrs, r;
if (geteuid() != 0)
return (void) log_tests_skipped("not root");
if (!is_pressure_supported())
return (void) log_tests_skipped("system does not support pressure");
if (cg_all_unified() <= 0)
return (void) log_tests_skipped("cgroups are not running in unified mode");
assert_se(cg_mask_supported(&mask) >= 0);
if (!FLAGS_SET(mask, CGROUP_MASK_MEMORY))
return (void) log_tests_skipped("cgroup memory controller is not available");
assert_se(cg_pid_get_path(NULL, 0, &cgroup) >= 0);
assert_se(oomd_cgroup_context_acquire(cgroup, &ctx) == 0);
/* If we don't have permissions to set xattrs we're likely in a userns or missing capabilities
* so skip the xattr portions of the test. */
r = cg_set_xattr(SYSTEMD_CGROUP_CONTROLLER, cgroup, "user.oomd_test", "1", 1, 0);
test_xattrs = !ERRNO_IS_PRIVILEGE(r) && !ERRNO_IS_NOT_SUPPORTED(r);
if (test_xattrs) {
assert_se(oomd_fetch_cgroup_oom_preference(ctx, NULL) == 0);
assert_se(cg_set_xattr(SYSTEMD_CGROUP_CONTROLLER, cgroup, "user.oomd_omit", "1", 1, 0) >= 0);
assert_se(cg_set_xattr(SYSTEMD_CGROUP_CONTROLLER, cgroup, "user.oomd_avoid", "1", 1, 0) >= 0);
/* omit takes precedence over avoid when both are set to true */
assert_se(oomd_fetch_cgroup_oom_preference(ctx, NULL) == 0);
assert_se(ctx->preference == MANAGED_OOM_PREFERENCE_OMIT);
} else {
assert_se(oomd_fetch_cgroup_oom_preference(ctx, NULL) < 0);
assert_se(ctx->preference == MANAGED_OOM_PREFERENCE_NONE);
}
ctx = oomd_cgroup_context_free(ctx);
/* also check when only avoid is set to true */
if (test_xattrs) {
assert_se(cg_set_xattr(SYSTEMD_CGROUP_CONTROLLER, cgroup, "user.oomd_omit", "0", 1, 0) >= 0);
assert_se(cg_set_xattr(SYSTEMD_CGROUP_CONTROLLER, cgroup, "user.oomd_avoid", "1", 1, 0) >= 0);
assert_se(oomd_cgroup_context_acquire(cgroup, &ctx) == 0);
assert_se(oomd_fetch_cgroup_oom_preference(ctx, NULL) == 0);
assert_se(ctx->preference == MANAGED_OOM_PREFERENCE_AVOID);
ctx = oomd_cgroup_context_free(ctx);
}
/* Test the root cgroup */
/* Root cgroup is live and not made on demand like the cgroup the test runs in. It can have varying
* xattrs set already so let's read in the booleans first to get the final preference value. */
assert_se(oomd_cgroup_context_acquire("", &ctx) == 0);
root_xattrs = cg_get_xattr_bool(SYSTEMD_CGROUP_CONTROLLER, "", "user.oomd_omit");
root_pref = root_xattrs > 0 ? MANAGED_OOM_PREFERENCE_OMIT : MANAGED_OOM_PREFERENCE_NONE;
root_xattrs = cg_get_xattr_bool(SYSTEMD_CGROUP_CONTROLLER, "", "user.oomd_avoid");
root_pref = root_xattrs > 0 ? MANAGED_OOM_PREFERENCE_AVOID : MANAGED_OOM_PREFERENCE_NONE;
assert_se(oomd_fetch_cgroup_oom_preference(ctx, NULL) == 0);
assert_se(ctx->preference == root_pref);
assert_se(oomd_fetch_cgroup_oom_preference(ctx, "/herp.slice/derp.scope") == -EINVAL);
/* Assert that avoid/omit are not set if the cgroup and prefix are not
* owned by the same user.*/
if (test_xattrs && !empty_or_root(ctx->path)) {
ctx = oomd_cgroup_context_free(ctx);
assert_se(cg_set_access(SYSTEMD_CGROUP_CONTROLLER, cgroup, 65534, 0) >= 0);
assert_se(oomd_cgroup_context_acquire(cgroup, &ctx) == 0);
assert_se(oomd_fetch_cgroup_oom_preference(ctx, NULL) == 0);
assert_se(ctx->preference == MANAGED_OOM_PREFERENCE_NONE);
assert_se(oomd_fetch_cgroup_oom_preference(ctx, ctx->path) == 0);
assert_se(ctx->preference == MANAGED_OOM_PREFERENCE_AVOID);
}
}
int main(void) {
int r;
@ -470,6 +507,7 @@ int main(void) {
test_oomd_cgroup_kill();
test_oomd_cgroup_context_acquire_and_insert();
test_oomd_fetch_cgroup_oom_preference();
return 0;
}