297 lines
9.5 KiB
Python
297 lines
9.5 KiB
Python
#!/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 copy
|
|
import os
|
|
import sys
|
|
|
|
# load modules from parent dir
|
|
sys.path.insert(1, os.path.dirname(sys.path[0]))
|
|
|
|
from mozharness.base.python import PreScriptAction
|
|
from mozharness.mozilla.structuredlog import StructuredOutputParser
|
|
from mozharness.mozilla.testing.codecoverage import (
|
|
CodeCoverageMixin,
|
|
code_coverage_config_options,
|
|
)
|
|
from mozharness.mozilla.testing.testbase import TestingMixin, testing_config_options
|
|
from mozharness.mozilla.vcstools import VCSToolsScript
|
|
|
|
# General command line arguments for Firefox ui tests
|
|
firefox_ui_tests_config_options = (
|
|
[
|
|
[
|
|
["--allow-software-gl-layers"],
|
|
{
|
|
"action": "store_true",
|
|
"dest": "allow_software_gl_layers",
|
|
"default": False,
|
|
"help": "Permits a software GL implementation (such as LLVMPipe) to use the GL "
|
|
"compositor.",
|
|
},
|
|
],
|
|
[
|
|
["--dry-run"],
|
|
{
|
|
"dest": "dry_run",
|
|
"default": False,
|
|
"help": "Only show what was going to be tested.",
|
|
},
|
|
],
|
|
[
|
|
["--disable-e10s"],
|
|
{
|
|
"dest": "e10s",
|
|
"action": "store_false",
|
|
"default": True,
|
|
"help": "Disable multi-process (e10s) mode when running tests.",
|
|
},
|
|
],
|
|
[
|
|
["--disable-fission"],
|
|
{
|
|
"dest": "disable_fission",
|
|
"action": "store_true",
|
|
"default": False,
|
|
"help": "Disable fission mode when running tests.",
|
|
},
|
|
],
|
|
[
|
|
["--setpref"],
|
|
{
|
|
"dest": "extra_prefs",
|
|
"action": "append",
|
|
"default": [],
|
|
"help": "Extra user prefs.",
|
|
},
|
|
],
|
|
[
|
|
["--symbols-path=SYMBOLS_PATH"],
|
|
{
|
|
"dest": "symbols_path",
|
|
"help": "absolute path to directory containing breakpad "
|
|
"symbols, or the url of a zip file containing symbols.",
|
|
},
|
|
],
|
|
]
|
|
+ copy.deepcopy(testing_config_options)
|
|
+ copy.deepcopy(code_coverage_config_options)
|
|
)
|
|
|
|
|
|
class FirefoxUIFunctionalTests(TestingMixin, VCSToolsScript, CodeCoverageMixin):
|
|
def __init__(
|
|
self,
|
|
config_options=None,
|
|
all_actions=None,
|
|
default_actions=None,
|
|
*args,
|
|
**kwargs,
|
|
):
|
|
config_options = config_options or firefox_ui_tests_config_options
|
|
actions = [
|
|
"clobber",
|
|
"download-and-extract",
|
|
"create-virtualenv",
|
|
"install",
|
|
"run-tests",
|
|
"uninstall",
|
|
]
|
|
|
|
super(FirefoxUIFunctionalTests, self).__init__(
|
|
config_options=config_options,
|
|
all_actions=all_actions or actions,
|
|
default_actions=default_actions or actions,
|
|
*args,
|
|
**kwargs,
|
|
)
|
|
|
|
# Code which runs in automation has to include the following properties
|
|
self.binary_path = self.config.get("binary_path")
|
|
self.installer_path = self.config.get("installer_path")
|
|
self.installer_url = self.config.get("installer_url")
|
|
self.test_packages_url = self.config.get("test_packages_url")
|
|
self.test_url = self.config.get("test_url")
|
|
|
|
if not self.test_url and not self.test_packages_url:
|
|
self.fatal("You must use --test-url, or --test-packages-url")
|
|
|
|
@PreScriptAction("create-virtualenv")
|
|
def _pre_create_virtualenv(self, action):
|
|
dirs = self.query_abs_dirs()
|
|
|
|
requirements = os.path.join(
|
|
dirs["abs_test_install_dir"], "config", "firefox_ui_requirements.txt"
|
|
)
|
|
self.register_virtualenv_module(requirements=[requirements])
|
|
|
|
def download_and_extract(self):
|
|
"""Override method from TestingMixin for more specific behavior."""
|
|
extract_dirs = [
|
|
"config/*",
|
|
"firefox-ui/*",
|
|
"marionette/*",
|
|
"mozbase/*",
|
|
"tools/mozterm/*",
|
|
"tools/wptserve/*",
|
|
"tools/wpt_third_party/*",
|
|
"mozpack/*",
|
|
"mozbuild/*",
|
|
]
|
|
super(FirefoxUIFunctionalTests, self).download_and_extract(
|
|
extract_dirs=extract_dirs
|
|
)
|
|
|
|
def query_abs_dirs(self):
|
|
if self.abs_dirs:
|
|
return self.abs_dirs
|
|
|
|
abs_dirs = super(FirefoxUIFunctionalTests, self).query_abs_dirs()
|
|
abs_tests_install_dir = os.path.join(abs_dirs["abs_work_dir"], "tests")
|
|
|
|
dirs = {
|
|
"abs_blob_upload_dir": os.path.join(
|
|
abs_dirs["abs_work_dir"], "blobber_upload_dir"
|
|
),
|
|
"abs_fxui_dir": os.path.join(abs_tests_install_dir, "firefox-ui"),
|
|
"abs_fxui_manifest_dir": os.path.join(
|
|
abs_tests_install_dir,
|
|
"firefox-ui",
|
|
"tests",
|
|
"testing",
|
|
"firefox-ui",
|
|
"tests",
|
|
),
|
|
"abs_test_install_dir": abs_tests_install_dir,
|
|
}
|
|
|
|
for key in dirs:
|
|
if key not in abs_dirs:
|
|
abs_dirs[key] = dirs[key]
|
|
self.abs_dirs = abs_dirs
|
|
|
|
return self.abs_dirs
|
|
|
|
def query_harness_args(self, extra_harness_config_options=None):
|
|
"""Collects specific test related command line arguments.
|
|
|
|
Sub classes should override this method for their own specific arguments.
|
|
"""
|
|
config_options = extra_harness_config_options or []
|
|
|
|
args = []
|
|
for option in config_options:
|
|
dest = option[1]["dest"]
|
|
name = self.config.get(dest)
|
|
|
|
if name:
|
|
if type(name) is bool:
|
|
args.append(option[0][0])
|
|
else:
|
|
args.extend([option[0][0], self.config[dest]])
|
|
|
|
return args
|
|
|
|
def run_test(self, binary_path, env=None, marionette_port=2828):
|
|
"""All required steps for running the tests against an installer."""
|
|
dirs = self.query_abs_dirs()
|
|
|
|
# Import the harness to retrieve the location of the cli scripts
|
|
import firefox_ui_harness
|
|
|
|
cmd = [
|
|
self.query_python_path(),
|
|
os.path.join(
|
|
os.path.dirname(firefox_ui_harness.__file__), "cli_functional.py"
|
|
),
|
|
"--binary",
|
|
binary_path,
|
|
"--address",
|
|
f"localhost:{marionette_port}",
|
|
# Resource files to serve via local webserver
|
|
"--server-root",
|
|
os.path.join(dirs["abs_fxui_dir"], "resources"),
|
|
# Use the work dir to get temporary data stored
|
|
"--workspace",
|
|
dirs["abs_work_dir"],
|
|
# logging options
|
|
"--gecko-log=-", # output from the gecko process redirected to stdout
|
|
"--log-raw=-", # structured log for output parser redirected to stdout
|
|
# Enable tracing output to log transmission protocol
|
|
"-vv",
|
|
]
|
|
|
|
# Collect all pass-through harness options to the script
|
|
cmd.extend(self.query_harness_args())
|
|
|
|
if not self.config.get("e10s"):
|
|
cmd.append("--disable-e10s")
|
|
|
|
if self.config.get("disable_fission"):
|
|
cmd.append("--disable-fission")
|
|
|
|
cmd.extend([f"--setpref={p}" for p in self.config.get("extra_prefs")])
|
|
|
|
if self.symbols_url:
|
|
cmd.extend(["--symbols-path", self.symbols_url])
|
|
|
|
parser = StructuredOutputParser(
|
|
config=self.config, log_obj=self.log_obj, strict=False
|
|
)
|
|
|
|
# Add the tests to run
|
|
cmd.append(
|
|
os.path.join(dirs["abs_fxui_manifest_dir"], "functional", "manifest.toml")
|
|
)
|
|
|
|
# Set further environment settings
|
|
env = env or self.query_env()
|
|
env.update({"MINIDUMP_SAVE_PATH": dirs["abs_blob_upload_dir"]})
|
|
if self.query_minidump_stackwalk():
|
|
env.update({"MINIDUMP_STACKWALK": self.minidump_stackwalk_path})
|
|
env["RUST_BACKTRACE"] = "full"
|
|
|
|
# If code coverage is enabled, set GCOV_PREFIX and JS_CODE_COVERAGE_OUTPUT_DIR
|
|
# env variables
|
|
if self.config.get("code_coverage"):
|
|
env["GCOV_PREFIX"] = self.gcov_dir
|
|
env["JS_CODE_COVERAGE_OUTPUT_DIR"] = self.jsvm_dir
|
|
|
|
if self.config["allow_software_gl_layers"]:
|
|
env["MOZ_LAYERS_ALLOW_SOFTWARE_GL"] = "1"
|
|
|
|
return_code = self.run_command(
|
|
cmd,
|
|
cwd=dirs["abs_fxui_dir"],
|
|
output_timeout=1000,
|
|
output_parser=parser,
|
|
env=env,
|
|
)
|
|
|
|
tbpl_status, log_level, summary = parser.evaluate_parser(return_code)
|
|
self.record_status(tbpl_status, level=log_level)
|
|
|
|
return return_code
|
|
|
|
@PreScriptAction("run-tests")
|
|
def _pre_run_tests(self, action):
|
|
if not self.installer_path and not self.installer_url:
|
|
self.critical(
|
|
"Please specify an installer via --installer-path or --installer-url."
|
|
)
|
|
sys.exit(1)
|
|
|
|
def run_tests(self):
|
|
"""Run all the tests"""
|
|
return self.run_test(
|
|
binary_path=self.binary_path,
|
|
env=self.query_env(),
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
myScript = FirefoxUIFunctionalTests()
|
|
myScript.run_and_exit()
|