From: Kamalesh Babulal Date: Fri, 28 Apr 2023 04:57:57 +0000 (+0530) Subject: ftests: add test to pass pid to systemd scope create via cgcreate X-Git-Tag: v3.1.0~80 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=30ec5bc8d9c8c73ed9a170dab716237ad6ea9b21;p=thirdparty%2Flibcgroup.git ftests: add test to pass pid to systemd scope create via cgcreate Add a test to pass task pid to systemd scope during creation using the cgcreate tool. ----------------------------------------------------------------- Test Results: Run Date: Apr 27 12:54:10 Passed: 1 test(s) Skipped: 0 test(s) Failed: 0 test(s) ----------------------------------------------------------------- Timing Results: Test Time (sec) ----------------------------------------------------- setup 0.00 084-sudo-cgcreate_systemd_scope_pid.py 2.16 teardown 0.00 ----------------------------------------------------- Total Run Time 2.16 Signed-off-by: Kamalesh Babulal Signed-off-by: Tom Hromatka TJH: Added one more call to Cgroup.get_pids_in_cgroup() --- diff --git a/tests/ftests/084-sudo-cgcreate_systemd_scope_pid.py b/tests/ftests/084-sudo-cgcreate_systemd_scope_pid.py new file mode 100755 index 00000000..a418928b --- /dev/null +++ b/tests/ftests/084-sudo-cgcreate_systemd_scope_pid.py @@ -0,0 +1,141 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: LGPL-2.1-only +# +# Test to create a systemd scope with pid using cgcreate +# +# Copyright (c) 2023 Oracle and/or its affiliates. +# Author: Kamalesh Babulal +# + +from cgroup import Cgroup +from process import Process +from libcgroup import Mode +from run import RunError +import consts +import ftests +import sys +import os + +CONTROLLERS = ['cpu', 'pids'] +SLICE = 'libcgroup.slice' +CGNAME1 = os.path.join(SLICE, '084cgcreate1.scope') +CGNAME2 = os.path.join(SLICE, '084cgcreate2.scope') + + +def prereqs(config): + result = consts.TEST_PASSED + cause = None + + if config.args.container: + result = consts.TEST_SKIPPED + cause = 'This test cannot be run within a container' + return result, cause + + if Cgroup.get_cgroup_mode(config) != Mode.CGROUP_MODE_UNIFIED: + result = consts.TEST_SKIPPED + cause = 'This test requires the unified cgroup hierarchy' + + return result, cause + + +def setup(config): + pass + + +def test(config): + result = consts.TEST_PASSED + cause = None + + # + # Test 1: Pass invalid task pid as scope_pid and systemd scope creation + # should fail + # + try: + Cgroup.create_and_validate(config, CONTROLLERS, CGNAME1, create_scope=True, + scope_pid=1000000) + except RunError as re: + if 'Process with ID 1000000 does not exist' not in str(re): + raise re + + # + # Test 2: Pass a valid task pid as scope_pid and systemd scope creation + # will succeed. Read the scope cgroup.procs to find if the task + # passed by us was used as scope task. + # + scope_pid = config.process.create_process(config) + Cgroup.create_and_validate(config, CONTROLLERS, CGNAME1, create_scope=True, scope_pid=scope_pid) + + try: + pid = Cgroup.get_pids_in_cgroup(config, CGNAME1, CONTROLLERS[0])[0] + if scope_pid != pid: + result = consts.TEST_FAILED + cause = 'scope created with other pid {}, expected pid {}'.format(pid, scope_pid) + return result, cause + except RunError: + result = consts.TEST_FAILED + cause = 'Failed to read pid in {}\'s cgroup.procs'.format(CGNAME1) + return result, cause + + # + # Test 3: Pass the already created task pid as scope_pid for a new systemd + # scope. This would mean the CGNAME1 should be killed and the pid + # should be the default scope task of CGNAME2 + Cgroup.create_and_validate(config, CONTROLLERS, CGNAME2, create_scope=True, scope_pid=scope_pid) + + # CGNAME1 should be deleted by the systemd. + try: + pid = Cgroup.get_pids_in_cgroup(config, CGNAME1, CONTROLLERS[0])[0] + except RunError as re: + if 'No such file or directory' not in re.stderr: + raise re + else: + result = consts.TEST_FAILED + cause = 'Erroneously succeeded reading cgroup.procs in {}'.format(CGNAME1) + return result, cause + + try: + pid = Cgroup.get_pids_in_cgroup(config, CGNAME2, CONTROLLERS[0])[0] + if scope_pid != pid: + result = consts.TEST_FAILED + cause = 'scope created with other pid {}, expected pid {}'.format(pid, scope_pid) + return result, cause + except RunError: + result = consts.TEST_FAILED + cause = 'Failed to read pid in {}\'s cgroup.procs'.format(CGNAME2) + + return result, cause + + +def teardown(config): + pid = Cgroup.get_pids_in_cgroup(config, CGNAME2, CONTROLLERS[0])[0] + Process.kill(config, pid) + + # systemd will automatically remove the cgroup once there are no more pids in + # the cgroup, so we don't need to delete CGNAME2. But let's try to remove the + # slice + try: + Cgroup.delete(config, CONTROLLERS, SLICE) + except RunError: + pass + + +def main(config): + [result, cause] = prereqs(config) + if result != consts.TEST_PASSED: + return [result, cause] + + 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: diff --git a/tests/ftests/Makefile.am b/tests/ftests/Makefile.am index 452d3142..5599c519 100644 --- a/tests/ftests/Makefile.am +++ b/tests/ftests/Makefile.am @@ -104,6 +104,7 @@ EXTRA_DIST_PYTHON_TESTS = \ 081-pybindings-cgrp_get_curr_ctrl_path-v1.py \ 082-pybindings-cgrp_get_curr_ctrl_path-v2.py \ 083-pybindings-helpers_cgroup_mode.py \ + 084-sudo-cgcreate_systemd_scope_pid.py \ 998-cgdelete-non-existing-shared-mnt-cgroup-v1.py # Intentionally omit the stress test from the extra dist # 999-stress-cgroup_init.py