Source code

Revision control

Other Tools

1
#!/usr/bin/env python
2
3
# This Source Code Form is subject to the terms of the Mozilla Public
4
# License, v. 2.0. If a copy of the MPL was not distributed with this
5
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7
from __future__ import absolute_import
8
9
import os
10
import shutil
11
import sys
12
import tarfile
13
14
import mozinfo
15
16
# need this so raptor imports work both from /raptor and via mach
17
here = os.path.abspath(os.path.dirname(__file__))
18
19
try:
20
from mozbuild.base import MozbuildObject
21
22
build = MozbuildObject.from_environment(cwd=here)
23
except ImportError:
24
build = None
25
26
from mozlog import commandline
27
from mozprofile.cli import parse_preferences
28
29
from browsertime import BrowsertimeDesktop, BrowsertimeAndroid
30
from cmdline import parse_args, CHROMIUM_DISTROS
31
from logger.logger import RaptorLogger
32
from manifest import get_raptor_test_list
33
from signal_handler import SignalHandler
34
from utils import view_gecko_profile
35
from webextension import (
36
WebExtensionFirefox,
37
WebExtensionDesktopChrome,
38
WebExtensionAndroid,
39
)
40
41
LOG = RaptorLogger(component="raptor-main")
42
43
44
def main(args=sys.argv[1:]):
45
args = parse_args()
46
47
args.extra_prefs = parse_preferences(args.extra_prefs or [])
48
49
if args.enable_fission:
50
args.extra_prefs.update(
51
{
52
"fission.autostart": True,
53
"dom.serviceWorkers.parent_intercept": True,
54
"browser.tabs.documentchannel": True,
55
}
56
)
57
58
if args.extra_prefs and args.extra_prefs.get("fission.autostart", False):
59
args.enable_fission = True
60
61
commandline.setup_logging("raptor", args, {"tbpl": sys.stdout})
62
63
LOG.info("raptor-start")
64
65
if args.debug_mode:
66
LOG.info("debug-mode enabled")
67
68
LOG.info("received command line arguments: %s" % str(args))
69
70
# if a test name specified on command line, and it exists, just run that one
71
# otherwise run all available raptor tests that are found for this browser
72
raptor_test_list = get_raptor_test_list(args, mozinfo.os)
73
raptor_test_names = [raptor_test["name"] for raptor_test in raptor_test_list]
74
75
# ensure we have at least one valid test to run
76
if len(raptor_test_list) == 0:
77
LOG.critical("this test is not targeted for {}".format(args.app))
78
sys.exit(1)
79
80
LOG.info("raptor tests scheduled to run:")
81
for next_test in raptor_test_list:
82
LOG.info(next_test["name"])
83
84
if not args.browsertime:
85
if args.app == "firefox":
86
raptor_class = WebExtensionFirefox
87
elif args.app in CHROMIUM_DISTROS:
88
raptor_class = WebExtensionDesktopChrome
89
else:
90
raptor_class = WebExtensionAndroid
91
else:
92
93
def raptor_class(*inner_args, **inner_kwargs):
94
outer_kwargs = vars(args)
95
# peel off arguments that are specific to browsertime
96
for key in outer_kwargs.keys():
97
if key.startswith("browsertime_"):
98
value = outer_kwargs.pop(key)
99
inner_kwargs[key] = value
100
101
if args.app == "firefox" or args.app in CHROMIUM_DISTROS:
102
klass = BrowsertimeDesktop
103
else:
104
klass = BrowsertimeAndroid
105
106
return klass(*inner_args, **inner_kwargs)
107
108
raptor = raptor_class(
109
args.app,
110
args.binary,
111
run_local=args.run_local,
112
noinstall=args.noinstall,
113
installerpath=args.installerpath,
114
obj_path=args.obj_path,
115
gecko_profile=args.gecko_profile,
116
gecko_profile_interval=args.gecko_profile_interval,
117
gecko_profile_entries=args.gecko_profile_entries,
118
symbols_path=args.symbols_path,
119
host=args.host,
120
power_test=args.power_test,
121
cpu_test=args.cpu_test,
122
memory_test=args.memory_test,
123
is_release_build=args.is_release_build,
124
debug_mode=args.debug_mode,
125
post_startup_delay=args.post_startup_delay,
126
activity=args.activity,
127
intent=args.intent,
128
interrupt_handler=SignalHandler(),
129
enable_webrender=args.enable_webrender,
130
extra_prefs=args.extra_prefs or {},
131
device_name=args.device_name,
132
no_conditioned_profile=args.no_conditioned_profile,
133
)
134
135
success = raptor.run_tests(raptor_test_list, raptor_test_names)
136
137
if not success:
138
# didn't get test results; test timed out or crashed, etc. we want job to fail
139
LOG.critical(
140
"TEST-UNEXPECTED-FAIL: no raptor test results were found for %s"
141
% ", ".join(raptor_test_names)
142
)
143
os.sys.exit(1)
144
145
# if we have results but one test page timed out (i.e. one tp6 test page didn't load
146
# but others did) we still dumped PERFHERDER_DATA for the successfull pages but we
147
# want the overall test job to marked as a failure
148
pages_that_timed_out = raptor.get_page_timeout_list()
149
if len(pages_that_timed_out) > 0:
150
for _page in pages_that_timed_out:
151
message = [
152
("TEST-UNEXPECTED-FAIL", "test '%s'" % _page["test_name"]),
153
("timed out loading test page", _page["url"]),
154
]
155
if _page.get("pending_metrics") is not None:
156
message.append(("pending metrics", _page["pending_metrics"]))
157
158
LOG.critical(
159
" ".join("%s: %s" % (subject, msg) for subject, msg in message)
160
)
161
os.sys.exit(1)
162
163
# if we're running browsertime in the CI, we want to zip the result dir
164
if args.browsertime and not args.run_local:
165
result_dir = raptor.results_handler.result_dir()
166
if os.path.exists(result_dir):
167
LOG.info("Creating tarball at %s" % result_dir + ".tgz")
168
with tarfile.open(result_dir + ".tgz", "w:gz") as tar:
169
tar.add(result_dir, arcname=os.path.basename(result_dir))
170
LOG.info("Removing %s" % result_dir)
171
shutil.rmtree(result_dir)
172
173
# when running raptor locally with gecko profiling on, use the view-gecko-profile
174
# tool to automatically load the latest gecko profile in profiler.firefox.com
175
if args.gecko_profile and args.run_local:
176
if os.environ.get("DISABLE_PROFILE_LAUNCH", "0") == "1":
177
LOG.info(
178
"Not launching profiler.firefox.com because DISABLE_PROFILE_LAUNCH=1"
179
)
180
else:
181
view_gecko_profile(args.binary)
182
183
184
if __name__ == "__main__":
185
main()