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