Add a class that can create and delete child processes. Signed-off-by: Tom Hromatka <tom.hroma...@oracle.com> --- ftests/ftests.py | 4 +++ ftests/process.py | 78 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 ftests/process.py
diff --git a/ftests/ftests.py b/ftests/ftests.py index 7b39d6c9ec37..6ac5ba709667 100755 --- a/ftests/ftests.py +++ b/ftests/ftests.py @@ -29,6 +29,7 @@ import datetime import log from log import Log import os +from process import Process from run import Run import sys import time @@ -273,6 +274,9 @@ def run_tests(config): def teardown(config, record_time=False): global teardown_time start_time = time.time() + + Process.join_children() + try: config.container.stop() except Exception as e: diff --git a/ftests/process.py b/ftests/process.py new file mode 100644 index 000000000000..82a40d2c8013 --- /dev/null +++ b/ftests/process.py @@ -0,0 +1,78 @@ +# +# Cgroup class for the libcgroup functional tests +# +# Copyright (c) 2020 Oracle and/or its affiliates. +# Author: Tom Hromatka <tom.hroma...@oracle.com> +# + +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of version 2.1 of the GNU Lesser General Public License as +# published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License +# for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library; if not, see <http://www.gnu.org/licenses>. +# + +from cgroup import Cgroup +import multiprocessing as mp +from run import Run +import time + +children = list() + +class Process(object): + @staticmethod + def __infinite_loop(config, sleep_time=1, in_container=True): + cmd = ['nohup', 'perl', '-e', '\'while(1){{sleep({})}};\''.format(sleep_time), '&'] + + if in_container: + config.container.run(cmd, shell_bool=True) + else: + Run.run(cmd, shell_bool=True) + + @staticmethod + def create_process(config, in_container=True): + # To allow for multiple processes to be created, each new process + # sleeps for a different amount of time. This lets us uniquely find + # each process later in this function + sleep_time = len(children) + 1 + + p = mp.Process(target=Process.__infinite_loop, + args=(config, sleep_time, )) + p.start() + + # wait for the process to start. If we don't wait, then the getpid + # logic below may not find the process + time.sleep(2) + + # get the PID of the newly spawned infinite loop + cmd = 'ps x | grep perl | grep "sleep({})" | awk \'{{print $1}}\''.format(sleep_time) + if in_container: + pid = config.container.run(cmd, shell_bool=True) + else: + pid = Run.run(cmd, shell_bool=True) + + if pid == "" or int(pid) <= 0: + raise ValueException('Failed to get the pid of the child process: {}'.format(pid)) + + children.append(p) + return pid + + # Create a simple process in the requested cgroup + @staticmethod + def create_process_in_cgroup(config, controller, cgname, in_container=True): + child_pid = Process.create_process(config, in_container=in_container) + Cgroup.classify(config, controller, cgname, child_pid, + in_container=in_container) + + # The caller will block until all children are stopped. + @staticmethod + def join_children(): + for child in children: + child.join(1) -- 2.25.4 _______________________________________________ Libcg-devel mailing list Libcg-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/libcg-devel