import consts
from container import Container
import os
+from process import Process
+import utils
class Config(object):
def __init__(self, args, container=None):
stop_timeout=args.timeout, arch=None,
distro=args.distro, release=args.release)
+ self.process = Process()
+
self.ftest_dir = os.path.dirname(os.path.abspath(__file__))
self.libcg_dir = os.path.dirname(self.ftest_dir)
self.verbose = False
def __str__(self):
- out_str = "Configuration"
+ out_str = "Configuration\n"
if self.args.container:
- out_str += "\n\tcontainer = {}".format(self.container)
+ out_str += utils.indent(str(self.container), 4)
+ out_str += utils.indent(str(self.process), 4)
return out_str
-
class ConfigError(Exception):
def __init__(self, message):
super(ConfigError, self).__init__(message)
from cgroup import Cgroup
import multiprocessing as mp
from run import Run
+from run import RunError
import time
-children = list()
-
class Process(object):
+ def __init__(self):
+ self.children = list()
+ self.children_pids = list()
+
+ def __str__(self):
+ out_str = "Process Class\n"
+ out_str += "\tchildren = {}\n".format(self.children)
+ out_str += "\tchildren_pids = {}\n".format(self.children_pids)
+
+ return out_str
+
@staticmethod
def __infinite_loop(config, sleep_time=1):
- cmd = ['nohup', 'perl', '-e', '\'while(1){{sleep({})}};\''.format(sleep_time), '&']
+ cmd = ['/usr/bin/perl', '-e', '\'while(1){{sleep({})}};\''.format(sleep_time)]
- if config.args.container:
- config.container.run(cmd, shell_bool=True)
- else:
- Run.run(cmd, shell_bool=True)
+ try:
+ if config.args.container:
+ config.container.run(cmd, shell_bool=True)
+ else:
+ Run.run(cmd, shell_bool=True)
+ except RunError as re:
+ # when the process is killed, a RunError will be thrown. let's
+ # catch and suppress it
+ pass
- @staticmethod
- def create_process(config):
+ def create_process(self, config):
# 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
+ sleep_time = len(self.children) + 1
p = mp.Process(target=Process.__infinite_loop,
args=(config, sleep_time, ))
if config.args.container:
pid = config.container.run(cmd, shell_bool=True)
else:
- pid = Run.run(cmd, shell_bool=True)
+ pid = Run.run(cmd, shell_bool=True).decode('ascii')
+
+ for _pid in pid.splitlines():
+ self.children_pids.append(_pid)
+
+ if pid.find('\n') >= 0:
+ # The second pid in the list contains the actual perl process
+ pid = pid.splitlines()[1]
if pid == "" or int(pid) <= 0:
raise ValueException('Failed to get the pid of the child process: {}'.format(pid))
- children.append(p)
+ self.children.append(p)
return pid
# Create a simple process in the requested cgroup
- @staticmethod
- def create_process_in_cgroup(config, controller, cgname):
- child_pid = Process.create_process(config)
+ def create_process_in_cgroup(self, config, controller, cgname):
+ child_pid = self.create_process(config)
Cgroup.classify(config, controller, cgname, child_pid)
# The caller will block until all children are stopped.
- @staticmethod
- def join_children():
- for child in children:
+ def join_children(self, config):
+ for child in self.children:
child.join(1)
+
+ for child in self.children_pids:
+ try:
+ if config.args.container:
+ config.container.run(['kill', child])
+ else:
+ Run.run(['kill', child])
+ except:
+ # ignore any errors during the kill command. this is belt
+ # and suspenders code
+ pass