summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <holger@moiji-mobile.com>2019-02-27 02:31:50 +0000
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2019-03-04 06:53:51 +0000
commit20b52c1ee36f892daa1467c2cec18d894e024560 (patch)
treef17909c2488ec15b4085ebb81c57f1f5142d87bc
parentf922a998cb3636b0b62b99fcef9212000103e19c (diff)
process: Speed-up terminating lots of processes by batching it
Introduce a strategy to terminate processes and begin with an implementation for parallel (that has no degree of parallelism right now). Change-Id: I7dd4a7e26aca758198aa08a434eaf5f3f5af632d
-rw-r--r--src/osmo_gsm_tester/process.py26
-rw-r--r--src/osmo_gsm_tester/suite.py22
2 files changed, 38 insertions, 10 deletions
diff --git a/src/osmo_gsm_tester/process.py b/src/osmo_gsm_tester/process.py
index b1769f8..1e53aba 100644
--- a/src/osmo_gsm_tester/process.py
+++ b/src/osmo_gsm_tester/process.py
@@ -21,12 +21,38 @@ import os
import time
import subprocess
import signal
+from abc import ABCMeta, abstractmethod
from datetime import datetime
from . import log
from .event_loop import MainLoop
from .util import Dir
+class TerminationStrategy(log.Origin, metaclass=ABCMeta):
+ """A baseclass for terminating a collection of processes."""
+
+ def __init__(self):
+ self._processes = []
+
+ def add_process(self, process):
+ """Remembers a process that needs to be terminated."""
+ self._processes.append(process)
+
+ @abstractmethod
+ def terminate_all(self):
+ "Terminates all scheduled processes and waits for the termination."""
+ pass
+
+
+class ParallelTerminationStrategy(TerminationStrategy):
+ """Processes will be terminated in parallel."""
+
+ def terminate_all(self):
+ # TODO(zecke): Actually make this non-sequential.
+ for process in self._processes:
+ process.terminate()
+
+
class Process(log.Origin):
def __init__(self, name, run_dir, popen_args, **popen_kwargs):
diff --git a/src/osmo_gsm_tester/suite.py b/src/osmo_gsm_tester/suite.py
index e5ac9a8..39da917 100644
--- a/src/osmo_gsm_tester/suite.py
+++ b/src/osmo_gsm_tester/suite.py
@@ -23,7 +23,7 @@ import time
import pprint
from . import config, log, util, resource, test
from .event_loop import MainLoop
-from . import osmo_nitb, osmo_hlr, osmo_mgcpgw, osmo_mgw, osmo_msc, osmo_bsc, osmo_stp, osmo_ggsn, osmo_sgsn, modem, esme, osmocon, ms_driver, iperf3
+from . import osmo_nitb, osmo_hlr, osmo_mgcpgw, osmo_mgw, osmo_msc, osmo_bsc, osmo_stp, osmo_ggsn, osmo_sgsn, modem, esme, osmocon, ms_driver, iperf3, process
class Timeout(Exception):
pass
@@ -246,9 +246,11 @@ class SuiteRun(log.Origin):
self._processes.insert(0, (process, respawn))
def stop_processes(self):
+ strategy = process.ParallelTerminationStrategy()
while self._processes:
- process, respawn = self._processes.pop()
- process.terminate()
+ proc, _ = self._processes.pop()
+ strategy.add_process(proc)
+ strategy.terminate_all()
def stop_process(self, process):
'Remove process from monitored list and stop it'
@@ -382,15 +384,15 @@ class SuiteRun(log.Origin):
def poll(self):
if self._processes:
- for process, respawn in self._processes:
- if process.terminated():
+ for proc, respawn in self._processes:
+ if proc.terminated():
if respawn == True:
- process.respawn()
+ proc.respawn()
else:
- process.log_stdout_tail()
- process.log_stderr_tail()
- log.ctx(process)
- raise log.Error('Process ended prematurely: %s' % process.name())
+ proc.log_stdout_tail()
+ proc.log_stderr_tail()
+ log.ctx(proc)
+ raise log.Error('Process ended prematurely: %s' % proc.name())
def prompt(self, *msgs, **msg_details):
'ask for user interaction. Do not use in tests that should run automatically!'