Since Process.processes is a weak reference dictionary any process
put in this dict will disappear if all references are lost. This
is much better than keeping a list in the Namespace which will hold
the references forever until test-runner manually kills them all at
the end of the test. This does still need to be done for daemon
processes but everything else can just go away when it is no longer
needed.
---
tools/test-runner | 40 +++++++++++++++++-----------------------
1 file changed, 17 insertions(+), 23 deletions(-)
diff --git a/tools/test-runner b/tools/test-runner
index bd0034c2..b0d6554d 100755
--- a/tools/test-runner
+++ b/tools/test-runner
@@ -57,12 +57,9 @@ def dbg(*s, **kwargs):
def exit_vm():
if config:
- for p in config.ctx.processes:
+ for p in Process.get_all():
print("Process %s still running!" % p.args[0])
p.kill()
- p = None
-
- config.ctx.processes = []
if config.ctx and config.ctx.results:
print_results(config.ctx.results)
@@ -178,6 +175,7 @@ class Process(subprocess.Popen):
self.out = ''
self.hup = False
self.killed = False
+ self.namespace = namespace
if not self.ctx:
global config
@@ -219,6 +217,15 @@ class Process(subprocess.Popen):
raise subprocess.CalledProcessError(returncode=self.returncode,
cmd=args)
+ @classmethod
+ def get_all(cls):
+ return cls.processes.values()
+
+ @classmethod
+ def kill_all(cls):
+ for p in cls.processes.values():
+ p.kill()
+
@staticmethod
def _write_io(instance, data, stdout=True):
for f in instance.write_fds:
@@ -321,8 +328,6 @@ class Process(subprocess.Popen):
self.cleanup = None
self.killed = True
- if self in self.ctx.processes:
- self.ctx.processes.remove(self)
# Override kill()
def kill(self, force=False):
if self.killed:
@@ -588,7 +593,6 @@ dbus_count = 0
class Namespace:
def __init__(self, args, name, radios):
self.dbus_address = None
- self.processes = []
self.name = name
self.radios = radios
self.args = args
@@ -607,10 +611,7 @@ class Namespace:
self.radios = []
- for p in list(self.processes):
- p.kill()
-
- self.processes = []
+ Process.kill_all()
def __del__(self):
print("Removing namespace %s" % self.name)
@@ -628,19 +629,14 @@ class Namespace:
# In case this process needs DBus...
env['DBUS_SYSTEM_BUS_ADDRESS'] = self.dbus_address
- p = Process(args, namespace=self.name, env=env, **kwargs)
-
- if not kwargs.get('wait', False):
- self.processes.append(p)
-
- return p
+ return Process(args, namespace=self.name, env=env, **kwargs)
def stop_process(self, p, force=False):
p.kill(force)
def is_process_running(self, process):
- for p in self.processes:
- if p.args[0] == process:
+ for p in Process.get_all():
+ if p.namespace == self.name and p.args[0] == process:
return True
return False
@@ -698,8 +694,7 @@ class Namespace:
if self.is_verbose('iwd-acd'):
env['IWD_ACD_DEBUG'] = '1'
- pid = self.start_process(args, env=env)
- return pid
+ return self.start_process(args, env=env)
def is_verbose(self, process, log=True):
process = os.path.basename(process)
@@ -786,7 +781,7 @@ class Namespace:
def __str__(self):
ret = 'Namespace: %s\n' % self.name
ret += 'Processes:\n'
- for p in self.processes:
+ for p in Process.get_all():
ret += '\t%s' % str(p)
ret += 'Radios:\n'
@@ -808,7 +803,6 @@ class TestContext(Namespace):
'''
def __init__(self, args):
self.name = None
- self.processes = []
self.args = args
self.hw_config = None
self.hostapd = None
--
2.31.1