From: Kamalesh Babulal Date: Fri, 13 Oct 2023 12:02:24 +0000 (+0530) Subject: ftests: add test to exercise cgset recursive set option X-Git-Tag: v3.2.0~176 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ea9fb119273db76577f8b4b8834dfa46e18828fc;p=thirdparty%2Flibcgroup.git ftests: add test to exercise cgset recursive set option Add a test to recursive set settings of the controller(s) in a cgroup and its descendants using cgset '-R' flag. ----------------------------------------------------------------- Test Results: Run Date: Oct 28 15:25:57 Passed: 1 test(s) Skipped: 0 test(s) Failed: 0 test(s) ----------------------------------------------------------------- Timing Results: Test Time (sec) ------------------------------------------ setup 0.00 089-cgset-recursive_flag.py 0.13 teardown 0.00 ------------------------------------------ Total Run Time 0.13 Signed-off-by: Kamalesh Babulal Signed-off-by: Tom Hromatka --- diff --git a/tests/ftests/089-cgset-recursive_flag.py b/tests/ftests/089-cgset-recursive_flag.py new file mode 100755 index 00000000..e740ca58 --- /dev/null +++ b/tests/ftests/089-cgset-recursive_flag.py @@ -0,0 +1,177 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: LGPL-2.1-only +# +# Advanced cgset functionality test - set values via the '-r' flag +# +# Copyright (c) 2023 Oracle and/or its affiliates. +# Author: Kamalesh Babulal +# + +from cgroup import Cgroup, CgroupVersion as Version +from libcgroup import Mode +import consts +import ftests +import sys +import os + +CONTROLLERS = ['cpu', 'cpuset', 'pids'] + +PARENT = '089cgset' +CHILD = os.path.join(PARENT, 'childcg') +GRANDCHILD = os.path.join(CHILD, 'grandchildcg') + +SETTING_V1 = 'cpu.shares' +SETTING_V2 = 'cpu.weight' +SETTING_V1_V2 = 'cpuset.cpus' +SETTING_V2_SUBTREE = 'cgroup.subtree_control' + +VALUE_V1 = '512' +VALUE_V2 = '50' +VALUE_V1_V2 = '0' +VALUE_V2_SUBTREE = '+cpuset -pids' +VALUE_V1_V2_SUBTREE = '+cpuset' + +DEFAULT_VALUE_V1 = '1024' +DEFAULT_VALUE_V2 = '100' +DEFAULT_VALUE_V1_V2 = '0-1' + + +def prereqs(config): + pass + + +def is_hybrid_with_ctrl(config): + if Cgroup.get_cgroup_mode(config) == Mode.CGROUP_MODE_HYBRID: + if (Version.get_version(CONTROLLERS[1]) == Version.CGROUP_V2): + return True + + return False + + +def setup(config): + Cgroup.create(config, CONTROLLERS[0], GRANDCHILD) + + if (is_hybrid_with_ctrl(config)): + Cgroup.create(config, None, GRANDCHILD) + + +def cgroup_settings_helper(config, SETTING, VALUE, DEF_VAL): + + Cgroup.set(config, cgname=PARENT, setting=SETTING, value=VALUE, + recursive=True) + + Cgroup.get_and_validate(config, PARENT, SETTING, VALUE) + Cgroup.get_and_validate(config, CHILD, SETTING, VALUE) + Cgroup.get_and_validate(config, GRANDCHILD, SETTING, VALUE) + + Cgroup.set(config, cgname=PARENT, setting=SETTING, value=DEF_VAL, + recursive=False) + + Cgroup.get_and_validate(config, PARENT, SETTING, DEF_VAL) + Cgroup.get_and_validate(config, CHILD, SETTING, VALUE) + Cgroup.get_and_validate(config, GRANDCHILD, SETTING, VALUE) + + +def cgroup_subtree_helper(config, SUBTREE, SUBTREE_VAL): + result = consts.TEST_PASSED + cause = None + + Cgroup.set(config, cgname=PARENT, setting=SUBTREE, value=SUBTREE_VAL, + recursive=True) + + # checking if the controller is enabled in granchildcg, in turn will + # check its parent cgroup childcg's subtree_control file, if it's enabled + # in parent cgroup, it's also enabled in the grandparent too. + if not Cgroup.is_controller_enabled(config, GRANDCHILD, CONTROLLERS[1]): + result = consts.TEST_FAILED + cause = 'Controller {} is not enabled in the child cgroup'.format(CONTROLLERS[1]) + + # check if 'cpuset' controller is enabled + if not Cgroup.is_controller_enabled(config, GRANDCHILD, CONTROLLERS[1]): + result = consts.TEST_FAILED + tmp_cause = ('Controller {} is not enabled in the child cgroup' + ''.format('cpuset')) + cause = '\n'.join(filter(None, [cause, tmp_cause])) + + # check if 'pids' controller is enabled + if Cgroup.get_cgroup_mode(config) == Mode.CGROUP_MODE_UNIFIED: + if Cgroup.is_controller_enabled(config, GRANDCHILD, CONTROLLERS[2]): + result = consts.TEST_FAILED + tmp_cause = ('Controller {} is enabled in the child cgroup' + ''.format('pids')) + cause = '\n'.join(filter(None, [cause, tmp_cause])) + + # for the grandchildcg read it's cgroup.subtree_control, is_controller_enabled + # will check its parent cgroup childcg's subtree_control + if Cgroup.get(config, None, GRANDCHILD, setting='cgroup.subtree_control', + print_headers=False, values_only=True): + result = consts.TEST_FAILED + tmp_cause = 'Controller {} enabled in grandchild cgroup'.format(CONTROLLERS[1]) + cause = '\n'.join(filter(None, [cause, tmp_cause])) + + return result, cause + + +def test_cgroup_legacy(config): + cgroup_settings_helper(config, SETTING_V1, VALUE_V1, DEFAULT_VALUE_V1) + + return consts.TEST_PASSED, None + + +def test_cgroup_hybrid(config): + result = consts.TEST_PASSED + cause = None + + cgroup_settings_helper(config, SETTING_V1, VALUE_V1, DEFAULT_VALUE_V1) + + if (is_hybrid_with_ctrl(config)): + result, cause = cgroup_subtree_helper(config, SETTING_V2_SUBTREE, + VALUE_V1_V2_SUBTREE) + + cgroup_settings_helper(config, SETTING_V1_V2, VALUE_V1_V2, DEFAULT_VALUE_V1_V2) + + return result, cause + + +def test_cgroup_unified(config): + cgroup_settings_helper(config, SETTING_V2, VALUE_V2, DEFAULT_VALUE_V2) + result, cause = cgroup_subtree_helper(config, SETTING_V2_SUBTREE, VALUE_V2_SUBTREE) + + return result, cause + + +def test(config): + + if Cgroup.get_cgroup_mode(config) == Mode.CGROUP_MODE_UNIFIED: + result, cause = test_cgroup_unified(config) + elif Cgroup.get_cgroup_mode(config) == Mode.CGROUP_MODE_HYBRID: + result, cause = test_cgroup_hybrid(config) + else: + result, cause = test_cgroup_legacy(config) + + return result, cause + + +def teardown(config): + Cgroup.delete(config, CONTROLLERS[0], PARENT, recursive=True) + if (is_hybrid_with_ctrl(config)): + Cgroup.delete(config, None, PARENT, recursive=True) + + +def main(config): + prereqs(config) + + setup(config) + [result, cause] = test(config) + teardown(config) + + return [result, cause] + + +if __name__ == '__main__': + config = ftests.parse_args() + # this test was invoked directly. run only it + config.args.num = int(os.path.basename(__file__).split('-')[0]) + sys.exit(ftests.main(config)) + +# vim: set et ts=4 sw=4: