[tracker: 3/6] functional-tests: Improve stopping of child processes



commit 12fe0ba6158c0d1adfca76f45911d6836e16b55c
Author: Sam Thursfield <sam afuera me uk>
Date:   Thu Dec 25 00:14:17 2014 +0000

    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 files changed, 12 insertions(+), 43 deletions(-)
---
diff --git a/tests/functional-tests/common/utils/helpers.py b/tests/functional-tests/common/utils/helpers.py
index d90196d..b34c3d7 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)
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]