Wed, 31 Dec 2014 13:27:57 +0100
Ignore runtime configuration files generated during quality assurance.
michael@0 | 1 | # This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this file, |
michael@0 | 3 | # You can obtain one at http://mozilla.org/MPL/2.0/. |
michael@0 | 4 | from __future__ import print_function, unicode_literals |
michael@0 | 5 | |
michael@0 | 6 | import json |
michael@0 | 7 | import os |
michael@0 | 8 | import signal |
michael@0 | 9 | import sys |
michael@0 | 10 | import threading |
michael@0 | 11 | |
michael@0 | 12 | here = os.path.abspath(os.path.dirname(__file__)) |
michael@0 | 13 | |
michael@0 | 14 | from runreftest import RefTest, ReftestOptions |
michael@0 | 15 | |
michael@0 | 16 | from marionette import Marionette |
michael@0 | 17 | from mozprocess import ProcessHandler |
michael@0 | 18 | from mozrunner import FirefoxRunner |
michael@0 | 19 | import mozinfo |
michael@0 | 20 | import mozlog |
michael@0 | 21 | |
michael@0 | 22 | log = mozlog.getLogger('REFTEST') |
michael@0 | 23 | |
michael@0 | 24 | class B2GDesktopReftest(RefTest): |
michael@0 | 25 | def __init__(self, marionette): |
michael@0 | 26 | RefTest.__init__(self) |
michael@0 | 27 | self.last_test = os.path.basename(__file__) |
michael@0 | 28 | self.marionette = marionette |
michael@0 | 29 | self.profile = None |
michael@0 | 30 | self.runner = None |
michael@0 | 31 | self.test_script = os.path.join(here, 'b2g_start_script.js') |
michael@0 | 32 | self.timeout = None |
michael@0 | 33 | |
michael@0 | 34 | def run_marionette_script(self): |
michael@0 | 35 | assert(self.marionette.wait_for_port()) |
michael@0 | 36 | self.marionette.start_session() |
michael@0 | 37 | self.marionette.set_context(self.marionette.CONTEXT_CHROME) |
michael@0 | 38 | |
michael@0 | 39 | if os.path.isfile(self.test_script): |
michael@0 | 40 | f = open(self.test_script, 'r') |
michael@0 | 41 | self.test_script = f.read() |
michael@0 | 42 | f.close() |
michael@0 | 43 | self.marionette.execute_script(self.test_script) |
michael@0 | 44 | |
michael@0 | 45 | def run_tests(self, test_path, options): |
michael@0 | 46 | reftestlist = self.getManifestPath(test_path) |
michael@0 | 47 | if not reftestlist.startswith('file://'): |
michael@0 | 48 | reftestlist = 'file://%s' % reftestlist |
michael@0 | 49 | |
michael@0 | 50 | self.profile = self.create_profile(options, reftestlist, |
michael@0 | 51 | profile_to_clone=options.profile) |
michael@0 | 52 | env = self.buildBrowserEnv(options, self.profile.profile) |
michael@0 | 53 | kp_kwargs = { 'processOutputLine': [self._on_output], |
michael@0 | 54 | 'onTimeout': [self._on_timeout], |
michael@0 | 55 | 'kill_on_timeout': False } |
michael@0 | 56 | |
michael@0 | 57 | if not options.debugger: |
michael@0 | 58 | if not options.timeout: |
michael@0 | 59 | if mozinfo.info['debug']: |
michael@0 | 60 | options.timeout = 420 |
michael@0 | 61 | else: |
michael@0 | 62 | options.timeout = 300 |
michael@0 | 63 | self.timeout = options.timeout + 30.0 |
michael@0 | 64 | |
michael@0 | 65 | log.info("%s | Running tests: start.", os.path.basename(__file__)) |
michael@0 | 66 | cmd, args = self.build_command_line(options.app, |
michael@0 | 67 | ignore_window_size=options.ignoreWindowSize, |
michael@0 | 68 | browser_arg=options.browser_arg) |
michael@0 | 69 | self.runner = FirefoxRunner(profile=self.profile, |
michael@0 | 70 | binary=cmd, |
michael@0 | 71 | cmdargs=args, |
michael@0 | 72 | env=env, |
michael@0 | 73 | process_class=ProcessHandler, |
michael@0 | 74 | symbols_path=options.symbolsPath, |
michael@0 | 75 | kp_kwargs=kp_kwargs) |
michael@0 | 76 | |
michael@0 | 77 | status = 0 |
michael@0 | 78 | try: |
michael@0 | 79 | self.runner.start(outputTimeout=self.timeout) |
michael@0 | 80 | log.info("%s | Application pid: %d", |
michael@0 | 81 | os.path.basename(__file__), |
michael@0 | 82 | self.runner.process_handler.pid) |
michael@0 | 83 | |
michael@0 | 84 | # kick starts the reftest harness |
michael@0 | 85 | self.run_marionette_script() |
michael@0 | 86 | status = self.runner.wait() |
michael@0 | 87 | finally: |
michael@0 | 88 | self.runner.check_for_crashes(test_name=self.last_test) |
michael@0 | 89 | self.runner.cleanup() |
michael@0 | 90 | |
michael@0 | 91 | if status > 0: |
michael@0 | 92 | log.testFail("%s | application terminated with exit code %s", |
michael@0 | 93 | self.last_test, status) |
michael@0 | 94 | elif status < 0: |
michael@0 | 95 | log.info("%s | application killed with signal %s", |
michael@0 | 96 | self.last_test, -status) |
michael@0 | 97 | |
michael@0 | 98 | log.info("%s | Running tests: end.", os.path.basename(__file__)) |
michael@0 | 99 | return status |
michael@0 | 100 | |
michael@0 | 101 | def create_profile(self, options, reftestlist, profile_to_clone=None): |
michael@0 | 102 | profile = RefTest.createReftestProfile(self, options, reftestlist, |
michael@0 | 103 | profile_to_clone=profile_to_clone) |
michael@0 | 104 | |
michael@0 | 105 | prefs = {} |
michael@0 | 106 | # Turn off the locale picker screen |
michael@0 | 107 | prefs["browser.firstrun.show.localepicker"] = False |
michael@0 | 108 | prefs["browser.homescreenURL"] = "app://test-container.gaiamobile.org/index.html" |
michael@0 | 109 | prefs["browser.manifestURL"] = "app://test-container.gaiamobile.org/manifest.webapp" |
michael@0 | 110 | prefs["browser.tabs.remote"] = False |
michael@0 | 111 | prefs["dom.ipc.tabs.disabled"] = False |
michael@0 | 112 | prefs["dom.mozBrowserFramesEnabled"] = True |
michael@0 | 113 | prefs["font.size.inflation.emPerLine"] = 0 |
michael@0 | 114 | prefs["font.size.inflation.minTwips"] = 0 |
michael@0 | 115 | prefs["network.dns.localDomains"] = "app://test-container.gaiamobile.org" |
michael@0 | 116 | prefs["reftest.browser.iframe.enabled"] = False |
michael@0 | 117 | prefs["reftest.remote"] = False |
michael@0 | 118 | prefs["reftest.uri"] = "%s" % reftestlist |
michael@0 | 119 | # Set a future policy version to avoid the telemetry prompt. |
michael@0 | 120 | prefs["toolkit.telemetry.prompted"] = 999 |
michael@0 | 121 | prefs["toolkit.telemetry.notifiedOptOut"] = 999 |
michael@0 | 122 | |
michael@0 | 123 | # Set the extra prefs. |
michael@0 | 124 | profile.set_preferences(prefs) |
michael@0 | 125 | return profile |
michael@0 | 126 | |
michael@0 | 127 | def build_command_line(self, app, ignore_window_size=False, |
michael@0 | 128 | browser_arg=None): |
michael@0 | 129 | cmd = os.path.abspath(app) |
michael@0 | 130 | args = ['-marionette'] |
michael@0 | 131 | |
michael@0 | 132 | if browser_arg: |
michael@0 | 133 | args += [browser_arg] |
michael@0 | 134 | |
michael@0 | 135 | if not ignore_window_size: |
michael@0 | 136 | args.extend(['--screen', '800x1000']) |
michael@0 | 137 | return cmd, args |
michael@0 | 138 | |
michael@0 | 139 | def _on_output(self, line): |
michael@0 | 140 | print(line) |
michael@0 | 141 | # TODO use structured logging |
michael@0 | 142 | if "TEST-START" in line and "|" in line: |
michael@0 | 143 | self.last_test = line.split("|")[1].strip() |
michael@0 | 144 | |
michael@0 | 145 | def _on_timeout(self): |
michael@0 | 146 | msg = "%s | application timed out after %s seconds with no output" |
michael@0 | 147 | log.testFail(msg % (self.last_test, self.timeout)) |
michael@0 | 148 | |
michael@0 | 149 | # kill process to get a stack |
michael@0 | 150 | self.runner.stop(sig=signal.SIGABRT) |
michael@0 | 151 | |
michael@0 | 152 | |
michael@0 | 153 | def run_desktop_reftests(parser, options, args): |
michael@0 | 154 | kwargs = {} |
michael@0 | 155 | if options.marionette: |
michael@0 | 156 | host, port = options.marionette.split(':') |
michael@0 | 157 | kwargs['host'] = host |
michael@0 | 158 | kwargs['port'] = int(port) |
michael@0 | 159 | marionette = Marionette.getMarionetteOrExit(**kwargs) |
michael@0 | 160 | |
michael@0 | 161 | reftest = B2GDesktopReftest(marionette) |
michael@0 | 162 | |
michael@0 | 163 | options = ReftestOptions.verifyCommonOptions(parser, options, reftest) |
michael@0 | 164 | if options == None: |
michael@0 | 165 | sys.exit(1) |
michael@0 | 166 | |
michael@0 | 167 | # add a -bin suffix if b2g-bin exists, but just b2g was specified |
michael@0 | 168 | if options.app[-4:] != '-bin': |
michael@0 | 169 | if os.path.isfile("%s-bin" % options.app): |
michael@0 | 170 | options.app = "%s-bin" % options.app |
michael@0 | 171 | |
michael@0 | 172 | if options.desktop and not options.profile: |
michael@0 | 173 | raise Exception("must specify --profile when specifying --desktop") |
michael@0 | 174 | |
michael@0 | 175 | sys.exit(reftest.run_tests(args[0], options)) |