Reimplement support for wdspec tests running in Firefox for android
diff --git a/tools/wptrunner/requirements_firefox.txt b/tools/wptrunner/requirements_firefox.txt
index 74d16ad..c8ac33a 100644
--- a/tools/wptrunner/requirements_firefox.txt
+++ b/tools/wptrunner/requirements_firefox.txt
@@ -1,5 +1,6 @@
marionette_driver==3.1.0
mozcrash==2.1.0
+mozdevice==4.0.3
mozinstall==2.0.1
mozleak==0.2
moznetwork==1.1.0
diff --git a/tools/wptrunner/wptrunner/browsers/firefox.py b/tools/wptrunner/wptrunner/browsers/firefox.py
index d95ee4a..e533bf0 100644
--- a/tools/wptrunner/wptrunner/browsers/firefox.py
+++ b/tools/wptrunner/wptrunner/browsers/firefox.py
@@ -815,8 +815,8 @@
def __init__(self, logger, binary, prefs_root, webdriver_binary, webdriver_args,
extra_prefs=None, debug_info=None, symbols_path=None, stackwalk_binary=None,
certutil_binary=None, ca_certificate_path=None, e10s=False,
- enable_webrender=False, enable_fission=False, stackfix_dir=None, leak_check=False,
- asan=False, stylo_threads=1,chaos_mode_flags=None, config=None,
+ enable_fission=False, stackfix_dir=None, leak_check=False,
+ asan=False, stylo_threads=1, chaos_mode_flags=None, config=None,
browser_channel="nightly", headless=None, **kwargs):
super().__init__(logger, binary, webdriver_binary, webdriver_args)
@@ -831,19 +831,7 @@
self.leak_check = leak_check
self.leak_report_file = None
- self.env = get_environ(self.logger,
- binary,
- debug_info,
- stylo_threads,
- headless,
- enable_webrender,
- chaos_mode_flags)
- self.env["RUST_BACKTRACE"] = "1"
- # This doesn't work with wdspec tests
- # In particular tests can create a session without passing in the capabilites
- # and in those cases we get the default geckodriver profile which doesn't
- # guarantee zero network access
- del self.env["MOZ_DISABLE_NONLOCAL_CONNECTIONS"]
+ self.env = self.get_env(binary, debug_info, stylo_threads, headless, chaos_mode_flags)
profile_creator = ProfileCreator(logger,
prefs_root,
@@ -860,6 +848,21 @@
self.profile = profile_creator.create()
self.marionette_port = None
+ def get_env(self, binary, debug_info, stylo_threads, headless, chaos_mode_flags):
+ env = get_environ(self.logger,
+ binary,
+ debug_info,
+ stylo_threads,
+ headless,
+ chaos_mode_flags)
+ env["RUST_BACKTRACE"] = "1"
+ # This doesn't work with wdspec tests
+ # In particular tests can create a session without passing in the capabilites
+ # and in those cases we get the default geckodriver profile which doesn't
+ # guarantee zero network access
+ del env["MOZ_DISABLE_NONLOCAL_CONNECTIONS"]
+ return env
+
def create_output_handler(self, cmd):
return FirefoxOutputHandler(self.logger,
cmd,
@@ -883,9 +886,11 @@
while time.time() < end_time:
self.logger.debug("Waiting for WebDriver session to end")
try:
+ self.logger.debug(f"Connecting to http://{self.host}:{self.port}/status")
conn = HTTPConnection(self.host, self.port)
conn.request("GET", "/status")
res = conn.getresponse()
+ self.logger.debug(f"Got response from http://{self.host}:{self.port}/status")
except Exception:
self.logger.debug(
f"Connecting to http://{self.host}:{self.port}/status failed")
@@ -903,6 +908,7 @@
if msg.get("value", {}).get("ready") is True:
self.logger.debug("Got ready status")
break
+ self.logger.debug(f"Got status response {data}")
time.sleep(1)
else:
self.logger.debug("WebDriver session didn't end")
diff --git a/tools/wptrunner/wptrunner/browsers/firefox_android.py b/tools/wptrunner/wptrunner/browsers/firefox_android.py
index 9b57db0..66821b8 100644
--- a/tools/wptrunner/wptrunner/browsers/firefox_android.py
+++ b/tools/wptrunner/wptrunner/browsers/firefox_android.py
@@ -1,7 +1,7 @@
import os
import moznetwork
-from mozrunner import FennecEmulatorRunner
+from mozrunner import FennecEmulatorRunner, get_app_context
from .base import (get_free_port,
cmd_arg,
@@ -16,12 +16,14 @@
run_info_extras as fx_run_info_extras,
update_properties, # noqa: F401
executor_kwargs as fx_executor_kwargs, # noqa: F401
+ FirefoxWdSpecBrowser,
ProfileCreator as FirefoxProfileCreator)
__wptrunner__ = {"product": "firefox_android",
"check_args": "check_args",
- "browser": "FirefoxAndroidBrowser",
+ "browser": {None: "FirefoxAndroidBrowser",
+ "wdspec": "FirefoxAndroidWdSpecBrowser"},
"executor": {"testharness": "MarionetteTestharnessExecutor",
"reftest": "MarionetteRefTestExecutor",
"crashtest": "MarionetteCrashtestExecutor",
@@ -41,6 +43,8 @@
def browser_kwargs(logger, test_type, run_info_data, config, **kwargs):
return {"adb_binary": kwargs["adb_binary"],
+ "webdriver_binary": kwargs["webdriver_binary"],
+ "webdriver_args": kwargs["webdriver_args"],
"package_name": kwargs["package_name"],
"device_serial": kwargs["device_serial"],
"prefs_root": kwargs["prefs_root"],
@@ -97,6 +101,17 @@
"supports_debugger": True}
+def get_environ(stylo_threads, chaos_mode_flags):
+ env = {}
+ env["MOZ_CRASHREPORTER"] = "1"
+ env["MOZ_CRASHREPORTER_SHUTDOWN"] = "1"
+ env["MOZ_DISABLE_NONLOCAL_CONNECTIONS"] = "1"
+ env["STYLO_THREADS"] = str(stylo_threads)
+ if chaos_mode_flags is not None:
+ env["MOZ_CHAOSMODE"] = str(chaos_mode_flags)
+ return env
+
+
class ProfileCreator(FirefoxProfileCreator):
def __init__(self, logger, prefs_root, config, test_type, extra_prefs,
enable_fission, browser_channel, certutil_binary, ca_certificate_path):
@@ -216,17 +231,7 @@
[cmd_arg("marionette"), "about:blank"],
self.debug_info)
- env = {}
- env["MOZ_CRASHREPORTER"] = "1"
- env["MOZ_CRASHREPORTER_SHUTDOWN"] = "1"
- env["MOZ_DISABLE_NONLOCAL_CONNECTIONS"] = "1"
- env["STYLO_THREADS"] = str(self.stylo_threads)
- if self.chaos_mode_flags is not None:
- env["MOZ_CHAOSMODE"] = str(self.chaos_mode_flags)
- if self.enable_webrender:
- env["MOZ_WEBRENDER"] = "1"
- else:
- env["MOZ_WEBRENDER"] = "0"
+ env = get_environ(self.stylo_threads, self.chaos_mode_flags)
self.runner = FennecEmulatorRunner(app=self.package_name,
profile=self.profile,
@@ -299,3 +304,58 @@
if not os.environ.get("MINIDUMP_STACKWALK", "") and self.stackwalk_binary:
os.environ["MINIDUMP_STACKWALK"] = self.stackwalk_binary
return bool(self.runner.check_for_crashes(test_name=test))
+
+
+class FirefoxAndroidWdSpecBrowser(FirefoxWdSpecBrowser):
+ def __init__(self, logger, prefs_root, webdriver_binary, webdriver_args,
+ extra_prefs=None, debug_info=None, symbols_path=None, stackwalk_binary=None,
+ certutil_binary=None, ca_certificate_path=None, e10s=False,
+ enable_fission=False, stackfix_dir=None, leak_check=False,
+ asan=False, stylo_threads=1, chaos_mode_flags=None, config=None,
+ browser_channel="nightly", headless=None,
+ package_name="org.mozilla.geckoview.test_runner", device_serial=None,
+ adb_binary=None, **kwargs):
+
+ super().__init__(logger, None, prefs_root, webdriver_binary, webdriver_args,
+ extra_prefs=extra_prefs, debug_info=debug_info, symbols_path=symbols_path,
+ stackwalk_binary=stackwalk_binary, certutil_binary=certutil_binary,
+ ca_certificate_path=ca_certificate_path, e10s=e10s,
+ enable_fission=enable_fission, stackfix_dir=stackfix_dir,
+ leak_check=leak_check, asan=asan, stylo_threads=stylo_threads,
+ chaos_mode_flags=chaos_mode_flags, config=config,
+ browser_channel=browser_channel, headless=headless, **kwargs)
+
+ self.config = config
+ self.package_name = package_name
+ self.device_serial = device_serial
+ # This is just to support the same adb lookup as for other test types
+ context = get_app_context("fennec")(adb_path=adb_binary, device_serial=device_serial)
+ self.device = context.get_device(context.adb, self.device_serial)
+
+ def start(self, group_metadata, **kwargs):
+ for ports in self.config.ports.values():
+ for port in ports:
+ self.device.reverse(
+ local="tcp:{}".format(port),
+ remote="tcp:{}".format(port))
+ super().start(group_metadata, **kwargs)
+
+ def stop(self, force=False):
+ try:
+ self.device.remove_reverses()
+ except Exception as e:
+ self.logger.warning("Failed to remove forwarded or reversed ports: %s" % e)
+ super().stop(force=force)
+
+ def get_env(self, binary, debug_info, stylo_threads, headless, chaos_mode_flags):
+ env = get_environ(stylo_threads, chaos_mode_flags)
+ env["RUST_BACKTRACE"] = "1"
+ del env["MOZ_DISABLE_NONLOCAL_CONNECTIONS"]
+ return env
+
+ def executor_browser(self):
+ cls, args = super().executor_browser()
+ args["androidPackage"] = self.package_name
+ args["androidDeviceSerial"] = self.device_serial
+ args["env"] = self.env
+ return cls, args
diff --git a/tools/wptrunner/wptrunner/executors/executormarionette.py b/tools/wptrunner/wptrunner/executors/executormarionette.py
index 447474b..b1ee026 100644
--- a/tools/wptrunner/wptrunner/executors/executormarionette.py
+++ b/tools/wptrunner/wptrunner/executors/executormarionette.py
@@ -1273,6 +1273,6 @@
args = self.capabilities["moz:firefoxOptions"].setdefault("args", [])
args.extend(["--profile", self.browser.profile])
- for option in ["env"]:
+ for option in ["androidPackage", "androidDeviceSerial", "env"]:
if hasattr(browser, option):
self.capabilities["moz:firefoxOptions"][option] = getattr(browser, option)