Bug 1316309 - Add ability to set xpcshell timeout via commandline and double the timeout on Windows, r?RyanVM
authorAndrew Halberstadt <ahalberstadt@mozilla.com>
Wed, 09 Nov 2016 11:03:16 -0500
changeset 888914 3cc42a41f37e32829eced6bcdf434304c1585790
parent 888897 234ad1e9d57883b7f10921cb61b3bba7f9fd2012
child 888915 1305681fbe269619f13753d29ee3e7850c54b0df
push id153873
push userahalberstadt@mozilla.com
push dateWed, 09 Nov 2016 16:03:50 +0000
treeherdertry@1305681fbe26 [default view] [failures only]
reviewersRyanVM
bugs1316309
milestone52.0a1
Bug 1316309 - Add ability to set xpcshell timeout via commandline and double the timeout on Windows, r?RyanVM MozReview-Commit-ID: LnraDl5YTPX
testing/mozharness/configs/unittests/win_unittest.py
testing/xpcshell/runxpcshelltests.py
testing/xpcshell/xpcshellcommandline.py
--- a/testing/mozharness/configs/unittests/win_unittest.py
+++ b/testing/mozharness/configs/unittests/win_unittest.py
@@ -135,16 +135,17 @@ config = {
         },
         "xpcshell": {
             "options": [
                 "--symbols-path=%(symbols_path)s",
                 "--test-plugin-path=%(test_plugin_path)s",
                 "--log-raw=%(raw_log_file)s",
                 "--log-errorsummary=%(error_summary_file)s",
                 "--utility-path=tests/bin",
+                "--test-timeout=600",
             ],
             "run_filename": "runxpcshelltests.py",
             "testsdir": "xpcshell"
         },
         "gtest": {
             "options": [
                 "--xre-path=%(abs_res_dir)s",
                 "--cwd=%(gtest_dir)s",
--- a/testing/xpcshell/runxpcshelltests.py
+++ b/testing/xpcshell/runxpcshelltests.py
@@ -41,18 +41,16 @@ try:
     HAVE_PSUTIL = True
 except Exception:
     HAVE_PSUTIL = False
 
 from xpcshellcommandline import parser_desktop
 
 SCRIPT_DIR = os.path.abspath(os.path.realpath(os.path.dirname(__file__)))
 
-HARNESS_TIMEOUT = 5 * 60
-
 # benchmarking on tbpl revealed that this works best for now
 NUM_THREADS = int(cpu_count() * 4)
 
 EXPECTED_LOG_ACTIONS = set([
     "test_status",
     "log",
 ])
 
@@ -154,17 +152,17 @@ class XPCShellTestThread(Thread):
         self.failCount = 0
 
         # Context for output processing
         self.output_lines = []
         self.has_failure_output = False
         self.saw_proc_start = False
         self.saw_proc_end = False
         self.complete_command = None
-        self.harness_timeout = kwargs.get('harness_timeout')
+        self.test_timeout = kwargs.get('test_timeout')
         self.timedout = False
 
         # event from main thread to signal work done
         self.event = event
         self.done = False # explicitly set flag so we don't rely on thread.isAlive
 
     def run(self):
         try:
@@ -656,17 +654,17 @@ class XPCShellTestThread(Thread):
             self.env['PYTHON'] = sys.executable
             self.env['BREAKPAD_SYMBOLS_PATH'] = self.symbolsPath
             self.env['DMD_PRELOAD_VAR'] = preloadEnvVar
             self.env['DMD_PRELOAD_VALUE'] = libdmd
 
         if self.test_object.get('subprocess') == 'true':
             self.env['PYTHON'] = sys.executable
 
-        testTimeoutInterval = self.harness_timeout
+        testTimeoutInterval = self.test_timeout
         # Allow a test to request a multiple of the timeout if it is expected to take long
         if 'requesttimeoutfactor' in self.test_object:
             testTimeoutInterval *= int(self.test_object['requesttimeoutfactor'])
 
         testTimer = None
         if not self.interactive and not self.debuggerInfo and not self.jsDebuggerInfo:
             testTimer = Timer(testTimeoutInterval, lambda: self.testTimeout(proc))
             testTimer.start()
@@ -797,17 +795,16 @@ class XPCShellTestThread(Thread):
 
         self.keep_going = True
 
 class XPCShellTests(object):
 
     def __init__(self, log=None):
         """ Initializes node status and logger. """
         self.log = log
-        self.harness_timeout = HARNESS_TIMEOUT
         self.nodeProc = {}
 
     def getTestManifest(self, manifest):
         if isinstance(manifest, TestManifest):
             return manifest
         elif manifest is not None:
             manifest = os.path.normpath(os.path.abspath(manifest))
             if os.path.isfile(manifest):
@@ -1090,17 +1087,17 @@ class XPCShellTests(object):
                  manifest=None, testPaths=None, mobileArgs=None, tempDir=None,
                  interactive=False, verbose=False, keepGoing=False, logfiles=True,
                  thisChunk=1, totalChunks=1, debugger=None,
                  debuggerArgs=None, debuggerInteractive=False,
                  profileName=None, mozInfo=None, sequential=False, shuffle=False,
                  testingModulesDir=None, pluginsPath=None,
                  testClass=XPCShellTestThread, failureManifest=None,
                  log=None, stream=None, jsDebugger=False, jsDebuggerPort=0,
-                 test_tags=None, dump_tests=None, utility_path=None,
+                 test_tags=None, dump_tests=None, utility_path=None, test_timeout=300,
                  rerun_failures=False, failure_manifest=None, jscovdir=None, **otherOptions):
         """Run xpcshell tests.
 
         |xpcshell|, is the xpcshell executable to use to run the tests.
         |xrePath|, if provided, is the path to the XRE to use.
         |appPath|, if provided, is the path to an application directory.
         |symbolsPath|, if provided is the path to a directory containing
           breakpad symbols for processing crashes in tests.
@@ -1277,17 +1274,17 @@ class XPCShellTests(object):
             'singleFile': self.singleFile,
             'env': self.env, # making a copy of this in the testthreads
             'symbolsPath': self.symbolsPath,
             'logfiles': self.logfiles,
             'xpcshell': self.xpcshell,
             'xpcsRunArgs': self.xpcsRunArgs,
             'failureManifest': self.failure_manifest,
             'jscovdir': self.jscovdir,
-            'harness_timeout': self.harness_timeout,
+            'test_timeout': test_timeout,
             'stack_fixer_function': self.stack_fixer_function,
         }
 
         if self.sequential:
             # Allow user to kill hung xpcshell subprocess with SIGINT
             # when we are only running tests sequentially.
             signal.signal(signal.SIGINT, markGotSIGINT)
 
--- a/testing/xpcshell/xpcshellcommandline.py
+++ b/testing/xpcshell/xpcshellcommandline.py
@@ -106,16 +106,20 @@ def add_common_arguments(parser):
     # path to the failure file from the previous run
     parser.add_argument("--rerun-failures",
                         action="store_true",
                         help="Rerun failures from the previous run, if any")
     parser.add_argument("--failure-manifest",
                         action="store",
                         help="Path to a manifest file from which to rerun failures "
                         "(with --rerun-failure) or in which to record failed tests")
+    parser.add_argument("--test-timeout",
+                        default=300, type=int,
+                        help="Maximum time in seconds a test is allowed to take before "
+                        "it is killed. Default 300s")
     parser.add_argument("testPaths", nargs="*", default=None,
                         help="Paths of tests to run.")
 
 def add_remote_arguments(parser):
     parser.add_argument("--deviceIP", action="store", type=str, dest="deviceIP",
                         help="ip address of remote device to test")
 
     parser.add_argument("--devicePort", action="store", type=str, dest="devicePort",