]> git.ipfire.org Git - thirdparty/libcgroup.git/commitdiff
ftests: add test to exercise cgset recursive set option
authorKamalesh Babulal <kamalesh.babulal@oracle.com>
Fri, 13 Oct 2023 12:02:24 +0000 (17:32 +0530)
committerTom Hromatka <tom.hromatka@oracle.com>
Wed, 1 Nov 2023 14:59:13 +0000 (08:59 -0600)
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 <kamalesh.babulal@oracle.com>
Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com>
tests/ftests/089-cgset-recursive_flag.py [new file with mode: 0755]

diff --git a/tests/ftests/089-cgset-recursive_flag.py b/tests/ftests/089-cgset-recursive_flag.py
new file mode 100755 (executable)
index 0000000..e740ca5
--- /dev/null
@@ -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 <kamalesh.babulal@oracle.com>
+#
+
+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: