| 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()
|
|
|