summaryrefslogtreecommitdiffstats
path: root/testing/raptor/raptor/raptor.py
diff options
context:
space:
mode:
Diffstat (limited to 'testing/raptor/raptor/raptor.py')
-rw-r--r--testing/raptor/raptor/raptor.py207
1 files changed, 207 insertions, 0 deletions
diff --git a/testing/raptor/raptor/raptor.py b/testing/raptor/raptor/raptor.py
new file mode 100644
index 0000000000..174155d8ed
--- /dev/null
+++ b/testing/raptor/raptor/raptor.py
@@ -0,0 +1,207 @@
+#!/usr/bin/env python
+
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import os
+import shutil
+import sys
+import tarfile
+import traceback
+
+import mozinfo
+
+# need this so raptor imports work both from /raptor and via mach
+here = os.path.abspath(os.path.dirname(__file__))
+
+try:
+ from mozbuild.base import MozbuildObject
+
+ build = MozbuildObject.from_environment(cwd=here)
+except ImportError:
+ build = None
+
+from browsertime import BrowsertimeAndroid, BrowsertimeDesktop
+from cmdline import CHROMIUM_DISTROS, DESKTOP_APPS, parse_args
+from logger.logger import RaptorLogger
+from manifest import get_raptor_test_list
+from mozlog import commandline
+from mozprofile.cli import parse_key_value, parse_preferences
+from signal_handler import SignalHandler
+from utils import view_gecko_profile_from_raptor
+from webextension import (
+ WebExtensionAndroid,
+ WebExtensionDesktopChrome,
+ WebExtensionFirefox,
+)
+
+LOG = RaptorLogger(component="raptor-main")
+
+
+def main(args=sys.argv[1:]):
+ args = parse_args()
+
+ args.extra_prefs = parse_preferences(args.extra_prefs or [])
+
+ if args.enable_marionette_trace:
+ args.extra_prefs.update(
+ {
+ "remote.log.level": "Trace",
+ }
+ )
+
+ args.environment = dict(parse_key_value(args.environment or [], context="--setenv"))
+
+ commandline.setup_logging("raptor", args, {"tbpl": sys.stdout})
+ LOG.info("Python version: %s" % sys.version)
+ LOG.info("raptor-start")
+
+ if args.debug_mode:
+ LOG.info("debug-mode enabled")
+
+ LOG.info("received command line arguments: %s" % str(args))
+
+ # if a test name specified on command line, and it exists, just run that one
+ # otherwise run all available raptor tests that are found for this browser
+ raptor_test_list = get_raptor_test_list(args, mozinfo.os)
+ raptor_test_names = [raptor_test["name"] for raptor_test in raptor_test_list]
+
+ # ensure we have at least one valid test to run
+ if len(raptor_test_list) == 0:
+ LOG.critical("test '{}' could not be found for {}".format(args.test, args.app))
+ sys.exit(1)
+
+ LOG.info("raptor tests scheduled to run:")
+ for next_test in raptor_test_list:
+ LOG.info(next_test["name"])
+
+ if not args.browsertime:
+ if args.app == "firefox":
+ raptor_class = WebExtensionFirefox
+ elif args.app in CHROMIUM_DISTROS:
+ raptor_class = WebExtensionDesktopChrome
+ else:
+ raptor_class = WebExtensionAndroid
+ else:
+
+ def raptor_class(*inner_args, **inner_kwargs):
+ outer_kwargs = vars(args)
+ # peel off arguments that are specific to browsertime
+ for key in outer_kwargs.keys():
+ if key.startswith("browsertime_"):
+ inner_kwargs[key] = outer_kwargs.get(key)
+
+ if args.app in DESKTOP_APPS:
+ klass = BrowsertimeDesktop
+ else:
+ klass = BrowsertimeAndroid
+
+ return klass(*inner_args, **inner_kwargs)
+
+ try:
+ raptor = raptor_class(
+ args.app,
+ args.binary,
+ run_local=args.run_local,
+ noinstall=args.noinstall,
+ installerpath=args.installerpath,
+ obj_path=args.obj_path,
+ gecko_profile=args.gecko_profile,
+ gecko_profile_interval=args.gecko_profile_interval,
+ gecko_profile_entries=args.gecko_profile_entries,
+ gecko_profile_extra_threads=args.gecko_profile_extra_threads,
+ gecko_profile_threads=args.gecko_profile_threads,
+ gecko_profile_features=args.gecko_profile_features,
+ extra_profiler_run=args.extra_profiler_run,
+ symbols_path=args.symbols_path,
+ host=args.host,
+ power_test=args.power_test,
+ cpu_test=args.cpu_test,
+ memory_test=args.memory_test,
+ live_sites=args.live_sites,
+ cold=args.cold,
+ is_release_build=args.is_release_build,
+ debug_mode=args.debug_mode,
+ post_startup_delay=args.post_startup_delay,
+ activity=args.activity,
+ intent=args.intent,
+ interrupt_handler=SignalHandler(),
+ extra_prefs=args.extra_prefs or {},
+ environment=args.environment or {},
+ device_name=args.device_name,
+ disable_perf_tuning=args.disable_perf_tuning,
+ conditioned_profile=args.conditioned_profile,
+ test_bytecode_cache=args.test_bytecode_cache,
+ chimera=args.chimera,
+ project=args.project,
+ verbose=args.verbose,
+ fission=args.fission,
+ extra_summary_methods=args.extra_summary_methods,
+ benchmark_repository=args.benchmark_repository,
+ benchmark_revision=args.benchmark_revision,
+ benchmark_branch=args.benchmark_branch,
+ )
+ except Exception:
+ traceback.print_exc()
+ LOG.critical(
+ "TEST-UNEXPECTED-FAIL: could not initialize the raptor test runner"
+ )
+ os.sys.exit(1)
+
+ raptor.results_handler.use_existing_results(args.browsertime_existing_results)
+ success = raptor.run_tests(raptor_test_list, raptor_test_names)
+
+ if not success:
+ # if we have results but one test page timed out (i.e. one tp6 test page didn't load
+ # but others did) we still dumped PERFHERDER_DATA for the successfull pages but we
+ # want the overall test job to marked as a failure
+ pages_that_timed_out = raptor.get_page_timeout_list()
+ if pages_that_timed_out:
+ for _page in pages_that_timed_out:
+ message = [
+ ("TEST-UNEXPECTED-FAIL", "test '%s'" % _page["test_name"]),
+ ("timed out loading test page", "waiting for pending metrics"),
+ ]
+ if _page.get("pending_metrics") is not None:
+ LOG.warning(
+ "page cycle {} has pending metrics: {}".format(
+ _page["page_cycle"], _page["pending_metrics"]
+ )
+ )
+
+ LOG.critical(
+ " ".join("%s: %s" % (subject, msg) for subject, msg in message)
+ )
+ else:
+ # we want the job to fail when we didn't get any test results
+ # (due to test timeout/crash/etc.)
+ LOG.critical(
+ "TEST-UNEXPECTED-FAIL: no raptor test results were found for %s"
+ % ", ".join(raptor_test_names)
+ )
+ os.sys.exit(1)
+
+ # if we're running browsertime in the CI, we want to zip the result dir
+ if args.browsertime and not args.run_local:
+ result_dir = raptor.results_handler.result_dir()
+ if os.path.exists(result_dir):
+ LOG.info("Creating tarball at %s" % result_dir + ".tgz")
+ with tarfile.open(result_dir + ".tgz", "w:gz") as tar:
+ tar.add(result_dir, arcname=os.path.basename(result_dir))
+ LOG.info("Removing %s" % result_dir)
+ shutil.rmtree(result_dir)
+
+ # when running raptor locally with gecko profiling on, use the view-gecko-profile
+ # tool to automatically load the latest gecko profile in profiler.firefox.com
+ if args.gecko_profile and args.run_local:
+ if os.environ.get("DISABLE_PROFILE_LAUNCH", "0") == "1":
+ LOG.info(
+ "Not launching profiler.firefox.com because DISABLE_PROFILE_LAUNCH=1"
+ )
+ else:
+ view_gecko_profile_from_raptor()
+
+
+if __name__ == "__main__":
+ main()