Index: chrome/test/functional/test_clean_exit_with_children.py |
diff --git a/chrome/test/functional/test_clean_exit_with_children.py b/chrome/test/functional/test_clean_exit_with_children.py |
new file mode 100755 |
index 0000000000000000000000000000000000000000..421d84cf1acde560eb76e7f72a1c73df631b7d5e |
--- /dev/null |
+++ b/chrome/test/functional/test_clean_exit_with_children.py |
@@ -0,0 +1,76 @@ |
+#!/usr/bin/env python |
+# Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+ |
+import os |
+import psutil |
+import signal |
+import time |
+import unittest |
+ |
+import pyauto_functional |
+import pyauto |
+ |
+ |
+class WaitForChildrenBeforeExitingTest(pyauto.PyUITest): |
+ |
+ def ExtraChromeFlags(self): |
+ """Ensures Chrome is launched with custom flags. |
+ |
+ Returns: |
+ A list of extra flags to pass to Chrome when it is launched. |
+ """ |
+ extra_flags = ['--no-sandbox', '--child-clean-exit', |
+ '--wait-for-children-before-exiting'] |
+ return pyauto.PyUITest.ExtraChromeFlags(self) + extra_flags |
+ |
+ |
+ def _IsProcessAlive(self, pid): |
+ """Checks whether a process is alive or not. |
+ |
+ Args: |
+ pid: The process id on which to perform this check. |
+ |
+ Returns: |
+ True if a process is alive and not a zombie. |
+ """ |
+ try: |
+ process = psutil.Process(pid) |
+ except psutil.error.NoSuchProcess: |
+ return False |
+ |
+ if process.status == psutil.STATUS_ZOMBIE: |
+ return False |
+ |
+ return True |
+ |
+ def testWaitForChildrenBeforeExiting(self): |
+ """Ensures the browser process waits for all children before exiting.""" |
+ url = self.GetHttpURLForDataPath('title2.html') |
+ self.NavigateToURL(url) |
+ |
+ browser_pid = self.GetBrowserInfo()['browser_pid'] |
+ renderer_pid = ( |
+ self.GetBrowserInfo()['windows'][0]['tabs'][0]['renderer_pid']) |
+ |
+ os.kill(renderer_pid, signal.SIGSTOP) |
+ os.kill(browser_pid, signal.SIGINT) |
+ |
+ time.sleep(20) |
+ |
+ # The browser should still be alive, waiting for the renderer to die. |
+ self.assertTrue(self._IsProcessAlive(browser_pid)) |
+ self.assertTrue(self._IsProcessAlive(renderer_pid)) |
+ |
+ # Resume the renderer. |
+ os.kill(renderer_pid, signal.SIGCONT) |
+ |
+ time.sleep(20) |
+ |
+ self.assertFalse(self._IsProcessAlive(renderer_pid)) |
+ self.assertFalse(self._IsProcessAlive(browser_pid)) |
+ |
+ |
+if __name__ == '__main__': |
+ pyauto_functional.Main() |