From 12fe0ba6158c0d1adfca76f45911d6836e16b55c Mon Sep 17 00:00:00 2001 From: Sam Thursfield Date: Thu, 25 Dec 2014 00:14:17 +0000 Subject: functional-tests: Improve stopping of child processes Instead of using `tracker daemon --kill=miners` to stop the miners, use the Python 'subprocess' module. This ensures only the correct miner process gets killed if more than one is running. (I also found that `tracker daemon --kill-miners` was hanging my system, which was the real motivation for fixing this, but I have no idea why that happened). If a process fails to terminate after we sent it TERM, it now gets sent KILL. Previously the test would wait forever. --- tests/functional-tests/common/utils/helpers.py | 55 ++++++-------------------- 1 file changed, 12 insertions(+), 43 deletions(-) diff --git a/tests/functional-tests/common/utils/helpers.py b/tests/functional-tests/common/utils/helpers.py index d90196dda..b34c3d728 100644 --- a/tests/functional-tests/common/utils/helpers.py +++ b/tests/functional-tests/common/utils/helpers.py @@ -110,24 +110,6 @@ class Helper: log ("Starting %s" % ' '.join(command)) return subprocess.Popen ([path] + flags, **kws) - def _stop_process (self): - if options.is_manual_start (): - if self.available: - print ("Kill %s manually" % self.PROCESS_NAME) - self.loop.run () - else: - # FIXME: this can hang if the we try to terminate the - # process too early in its lifetime ... if you see: - # - # GLib-CRITICAL **: g_main_loop_quit: assertion 'loop != NULL' failed - # - # This means that the signal_handler() function was called - # before the main loop was started and the process failed to - # terminate. - self.process.terminate () - self.process.wait () - return False - def _name_owner_changed_cb (self, name, old_owner, new_owner): if name == self.BUS_NAME: if old_owner == '' and new_owner != '': @@ -187,17 +169,22 @@ class Helper: self.abort_if_process_exits_with_status_0 = False def stop (self): - if self.available: + start = time.time() + if self.process.poll() == None: # It should step out of this loop when the miner disappear from the bus GLib.source_remove(self.process_watch_timeout) - GLib.idle_add (self._stop_process) - self.timeout_id = GLib.timeout_add_seconds (REASONABLE_TIMEOUT, self._timeout_on_idle_cb) - self.loop.run () - if self.timeout_id is not None: - GLib.source_remove(self.timeout_id) + self.process.terminate() - log ("[%s] stop." % self.PROCESS_NAME) + while self.process.poll() == None: + time.sleep(0.1) + + if time.time() > (start + REASONABLE_TIMEOUT): + log ("[%s] Failed to terminate, sending kill!" % self.PROCESS_NAME) + self.process.kill() + self.process.wait() + + log ("[%s] stopped." % self.PROCESS_NAME) # Disconnect the signals of the next start we get duplicated messages self.bus._clean_up_signal_match (self.name_owner_match) @@ -601,24 +588,6 @@ class MinerFsHelper (Helper): if cfg.haveMaemo: FLAGS.append ('--disable-miner=userguides') - def _stop_process (self): - if options.is_manual_start (): - if self.available: - log ("Kill %s manually" % self.PROCESS_NAME) - self.loop.run () - else: - control_binary = os.path.join (cfg.BINDIR, "tracker") - - kws = {} - - if not options.is_verbose (): - FNULL = open ('/dev/null', 'w') - kws = { 'stdout': FNULL } - - subprocess.call ([control_binary, "daemon", "--kill=miners"], **kws) - - return False - def start (self): Helper.start (self) -- cgit v1.2.1