author | Geoffrey Sneddon <me@gsnedders.com> |
Mon, 26 Mar 2018 11:17:50 +0000 | |
changeset 410916 | b0838962d2d707c00708f81ae4f80ddc161955a7 |
parent 410915 | cc3255a9f8f4b107c6fd2e8a25c1bc357435281f |
child 410917 | 8e8079c376b436cad4aa4c04efa003bc1e10ef04 |
push id | 33749 |
push user | csabou@mozilla.com |
push date | Mon, 02 Apr 2018 10:18:51 +0000 |
treeherder | mozilla-central@c44f60c43432 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | testonly |
bugs | 1436459 |
milestone | 61.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -386168,17 +386168,17 @@ "cfedb92777a36954d6e285461bf224cb6d2b5407", "support" ], "./LICENSE.md": [ "722729a1062b97ad2fdd43896b2c6a45b1fff144", "support" ], "./README.md": [ - "c58b661f8a9377baf6d71b9e2b704441b127ef5d", + "8a00f4e0dea3810e28a32421ded06b8e78e94129", "support" ], "./check_stability.ini": [ "f8af4287f3b0f6925a2a6c5c75b3788e24de1680", "support" ], "./config.default.json": [ "403d365196f6fe2c631d27fe6042e3114d204016", @@ -538308,17 +538308,17 @@ "8a28f329253f3293cd8798d53672bd5a85c260ce", "support" ], "docs/index.html": [ "12c7175a4d6c486ca9ebea4c6a43d2aec9845d8b", "support" ], "docs/introduction.md": [ - "98606eeeb43d80624d6ad6fa51c741afedff1598", + "e7d0165e5c6a8604d25f32032b2374bff6e59e02", "support" ], "dom/OWNERS": [ "2bfae729fb0eab4081f06e51ae5640b49e012b8e", "support" ], "dom/abort/event.any.js": [ "d41904ddfc56e5ef3e89d965a4e5fa392e996ef9",
--- a/testing/web-platform/tests/README.md +++ b/testing/web-platform/tests/README.md @@ -27,27 +27,32 @@ Running the Tests The tests are designed to be run from your local computer. The test environment requires [Python 2.7+](http://www.python.org/downloads) (but not Python 3.x). On Windows, be sure to add the Python directory (`c:\python2x`, by default) to your `%Path%` [Environment Variable](http://www.computerhope.com/issues/ch000549.htm), and read the [Windows Notes](#windows-notes) section below. To get the tests running, you need to set up the test domains in your -[`hosts` file](http://en.wikipedia.org/wiki/Hosts_%28file%29%23Location_in_the_file_system). The -following entries are required: +[`hosts` file](http://en.wikipedia.org/wiki/Hosts_%28file%29%23Location_in_the_file_system). +The necessary content can be generated with `./wpt make-hosts-file`; on +Windows, you will need to preceed the prior command with `python` or +the path to the Python binary (`python wpt make-hosts-file`). + +For example, on most UNIX-like systems, you can setup the hosts file with: + +```bash +./wpt make-hosts-file | sudo tee -a /etc/hosts ``` -127.0.0.1 web-platform.test -127.0.0.1 www.web-platform.test -127.0.0.1 www1.web-platform.test -127.0.0.1 www2.web-platform.test -127.0.0.1 xn--n8j6ds53lwwkrqhv28a.web-platform.test -127.0.0.1 xn--lve-6lad.web-platform.test -0.0.0.0 nonexistent-origin.web-platform.test + +And on Windows (note this requires an Administrator privileged shell): + +```bash +python wpt make-hosts-file >> %SystemRoot%\System32\drivers\etc\hosts ``` If you are behind a proxy, you also need to make sure the domains above are excluded from your proxy lookups. Running Tests Manually ======================
--- a/testing/web-platform/tests/docs/introduction.md +++ b/testing/web-platform/tests/docs/introduction.md @@ -97,27 +97,32 @@ anything as a result! The tests are designed to be run from your local computer. The test environment requires [Python 2.7+](http://www.python.org/downloads) (but not Python 3.x). On Windows, be sure to add the Python directory (`c:\python2x`, by default) to your `%Path%` [Environment Variable](http://www.computerhope.com/issues/ch000549.htm), and read the [Windows Notes](#windows-notes) section below. To get the tests running, you need to set up the test domains in your -[`hosts` file](http://en.wikipedia.org/wiki/Hosts_%28file%29%23Location_in_the_file_system). The -following entries are required: +[`hosts` file](http://en.wikipedia.org/wiki/Hosts_%28file%29%23Location_in_the_file_system). +The necessary content can be generated with `./wpt make-hosts-file`; on +Windows, you will need to preceed the prior command with `python` or +the path to the Python binary (`python wpt make-hosts-file`). + +For example, on most UNIX-like systems, you can setup the hosts file with: + +```bash +./wpt make-hosts-file | sudo tee -a /etc/hosts ``` -127.0.0.1 web-platform.test -127.0.0.1 www.web-platform.test -127.0.0.1 www1.web-platform.test -127.0.0.1 www2.web-platform.test -127.0.0.1 xn--n8j6ds53lwwkrqhv28a.web-platform.test -127.0.0.1 xn--lve-6lad.web-platform.test -0.0.0.0 nonexistent-origin.web-platform.test + +And on Windows (note this requires an Administrator privileged shell): + +```bash +python wpt make-hosts-file >> %SystemRoot%\System32\drivers\etc\hosts ``` If you are behind a proxy, you also need to make sure the domains above are excluded from your proxy lookups. The test environment can then be started using ./wpt serve
--- a/testing/web-platform/tests/tools/ci/commands.json +++ b/testing/web-platform/tests/tools/ci/commands.json @@ -1,6 +1,7 @@ { "test-jobs": {"path": "jobs.py", "script": "run", "parser": "create_parser", "help": "List test jobs that should run for a set of commits", "virtualenv": false}, "check-stability": {"path": "check_stability.py", "script": "run", "parser": "get_parser", "parse_known": true, "help": "Check test stability", - "virtualenv": true, "install": ["requests"], "requirements": ["../wptrunner/requirements.txt"]} + "virtualenv": true, "install": ["requests"], "requirements": ["../wptrunner/requirements.txt"]}, + "make-hosts-file": {"path": "make_hosts_file.py", "script": "run", "parser": "create_parser", "help": "Output a hosts file to stdout", "virtualenv": false} }
--- a/testing/web-platform/tests/tools/ci/lib.sh +++ b/testing/web-platform/tests/tools/ci/lib.sh @@ -1,25 +1,17 @@ #!/bin/bash hosts_fixup() { echo "travis_fold:start:hosts_fixup" echo "Rewriting hosts file" echo "## /etc/hosts ##" cat /etc/hosts sudo sed -i 's/^::1\s*localhost/::1/' /etc/hosts - sudo sh -c 'echo " -127.0.0.1 web-platform.test -127.0.0.1 www.web-platform.test -127.0.0.1 www1.web-platform.test -127.0.0.1 www2.web-platform.test -127.0.0.1 xn--n8j6ds53lwwkrqhv28a.web-platform.test -127.0.0.1 xn--lve-6lad.web-platform.test -0.0.0.0 nonexistent-origin.web-platform.test -" >> /etc/hosts' + ./wpt make-hosts-file | sudo tee -a /etc/hosts echo "== /etc/hosts ==" cat /etc/hosts echo "----------------" echo "travis_fold:end:hosts_fixup" } install_chrome() { channel=$1
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/tools/ci/make_hosts_file.py @@ -0,0 +1,19 @@ +import argparse +import os + +from ..localpaths import repo_root + +from ..serve.serve import load_config, normalise_config, make_hosts_file + +def create_parser(): + parser = argparse.ArgumentParser() + parser.add_argument("address", default="127.0.0.1", nargs="?", help="Address that hosts should point at") + return parser + +def run(**kwargs): + config = load_config(os.path.join(repo_root, "config.default.json"), + os.path.join(repo_root, "config.json")) + + config = normalise_config(config, {}) + + print(make_hosts_file(config, kwargs["address"]))
--- a/testing/web-platform/tests/tools/conftest.py +++ b/testing/web-platform/tests/tools/conftest.py @@ -1,13 +1,22 @@ import platform import os +import sys from hypothesis import settings, HealthCheck impl = platform.python_implementation() settings.register_profile("ci", settings(max_examples=1000, suppress_health_check=[HealthCheck.too_slow])) settings.register_profile("pypy", settings(suppress_health_check=[HealthCheck.too_slow])) settings.load_profile(os.getenv("HYPOTHESIS_PROFILE", "default" if impl != "PyPy" else "pypy")) + +# serve can't even be imported on Py3, so totally ignore it even from collection +collect_ignore = [] +if sys.version_info[0] >= 3: + serve = os.path.join(os.path.dirname(__file__), "serve") + collect_ignore.extend([os.path.join(root, f) + for root, _, files in os.walk(serve) + for f in files])
--- a/testing/web-platform/tests/tools/serve/serve.py +++ b/testing/web-platform/tests/tools/serve/serve.py @@ -198,16 +198,18 @@ done(); rewrites = [("GET", "/resources/WebIDLParser.js", "/resources/webidl2/lib/webidl2.js")] subdomains = [u"www", u"www1", u"www2", u"天気の良い日", u"élève"] +not_subdomains = [u"nonexistent-origin"] + class RoutesBuilder(object): def __init__(self): self.forbidden_override = [("GET", "/tools/runner/*", handlers.file_handler), ("POST", "/tools/runner/update_manifest.py", handlers.python_script_handler)] self.forbidden = [("*", "/_certs/*", handlers.ErrorHandler(404)), ("*", "/tools/*", handlers.ErrorHandler(404)), @@ -463,16 +465,34 @@ def check_subdomains(host, paths, bind_h def get_subdomains(host): #This assumes that the tld is ascii-only or already in punycode return {subdomain: (subdomain.encode("idna"), host) for subdomain in subdomains} +def get_not_subdomains(host): + #This assumes that the tld is ascii-only or already in punycode + return {subdomain: (subdomain.encode("idna"), host) + for subdomain in not_subdomains} + + +def make_hosts_file(config, host): + rv = [] + + for domain in config["domains"].values(): + rv.append("%s\t%s\n" % (host, domain)) + + for not_domain in config.get("not_domains", {}).values(): + rv.append("0.0.0.0\t%s\n" % not_domain) + + return "".join(rv) + + def start_servers(host, ports, paths, routes, bind_hostname, config, ssl_config, **kwargs): servers = defaultdict(list) for scheme, ports in ports.iteritems(): assert len(ports) == {"http":2}.get(scheme, 1) for port in ports: if port is None: @@ -621,34 +641,39 @@ def get_ports(config, ssl_environment): rv[scheme].append(port) return rv def normalise_config(config, ports): host = config["external_host"] if config["external_host"] else config["host"] domains = get_subdomains(host) + not_domains = get_not_subdomains(host) ports_ = {} for scheme, ports_used in ports.iteritems(): ports_[scheme] = ports_used for key, value in domains.iteritems(): domains[key] = ".".join(value) + for key, value in not_domains.iteritems(): + not_domains[key] = ".".join(value) + domains[""] = host ports_ = {} for scheme, ports_used in ports.iteritems(): ports_[scheme] = ports_used # make a (shallow) copy of the config and update that, so that the # normalized config can be used in place of the original one. config_ = config.copy() config_["host"] = host config_["domains"] = domains + config_["not_domains"] = not_domains config_["ports"] = ports_ return config_ def get_paths(config): return {"doc_root": config["doc_root"], "ws_doc_root": config["ws_doc_root"]}
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/tools/serve/test_serve.py @@ -0,0 +1,12 @@ +from . import serve + +def test_make_hosts_file(): + hosts = serve.make_hosts_file({ + "domains": {"www": "www.foo.bar.test", "www1": "www1.foo.bar.test"}, + "not_domains": {"aaa": "aaa.foo.bar.test", "bbb": "bbb.foo.bar.test"} + }, "127.1.1.1") + lines = hosts.split("\n") + assert "127.1.1.1\twww.foo.bar.test" in lines + assert "127.1.1.1\twww1.foo.bar.test" in lines + assert "0.0.0.0\taaa.foo.bar.test" in lines + assert "0.0.0.0\tbbb.foo.bar.test" in lines
--- a/testing/web-platform/tests/tools/wpt/run.py +++ b/testing/web-platform/tests/tools/wpt/run.py @@ -6,16 +6,18 @@ import subprocess import sys import tarfile from distutils.spawn import find_executable wpt_root = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir)) sys.path.insert(0, os.path.abspath(os.path.join(wpt_root, "tools"))) from . import browser, utils, virtualenv +from ..serve import serve + logger = None class WptrunError(Exception): pass class WptrunnerHelpAction(argparse.Action): @@ -89,43 +91,44 @@ your PATH. Otherwise run with --ssl-type=none""") else: raise WptrunError("""OpenSSL not found. If you don't need HTTPS support run with --ssl-type=none, otherwise install OpenSSL and ensure that it's on your $PATH.""") def check_environ(product): if product not in ("firefox", "servo"): - expected_hosts = ["web-platform.test", - "www.web-platform.test", - "www1.web-platform.test", - "www2.web-platform.test", - "xn--n8j6ds53lwwkrqhv28a.web-platform.test", - "xn--lve-6lad.web-platform.test", - "nonexistent-origin.web-platform.test"] + expected_hosts = {".".join(x) + for x in serve.get_subdomains("web-platform.test").values()} + expected_hosts |= {".".join(x) + for x in serve.get_not_subdomains("web-platform.test").values()} missing_hosts = set(expected_hosts) if platform.uname()[0] != "Windows": hosts_path = "/etc/hosts" else: hosts_path = "C:\Windows\System32\drivers\etc\hosts" with open(hosts_path, "r") as f: for line in f: line = line.split("#", 1)[0].strip() parts = line.split() hosts = parts[1:] for host in hosts: missing_hosts.discard(host) if missing_hosts: - raise WptrunError("""Missing hosts file configuration. Expected entries like: + if platform.uname()[0] != "Windows": + message = """Missing hosts file configuration. Run -%s +python wpt make-hosts-file >> %s -See README.md for more details.""" % "\n".join("%s\t%s" % - ("127.0.0.1" if "nonexistent" not in host else "0.0.0.0", host) - for host in expected_hosts)) +from a shell with Administrator privileges.""" % hosts_path + else: + message = """Missing hosts file configuration. Run + +./wpt make-hosts-file | sudo tee -a %s""" % hosts_path + raise WptrunError(message) class BrowserSetup(object): name = None browser_cls = None def __init__(self, venv, prompt=True, sub_product=None): self.browser = self.browser_cls()
--- a/testing/web-platform/tests/tools/wptrunner/MANIFEST.in +++ b/testing/web-platform/tests/tools/wptrunner/MANIFEST.in @@ -1,8 +1,7 @@ exclude MANIFEST.in include requirements.txt include wptrunner.default.ini include wptrunner/testharness_runner.html include wptrunner/*.js include wptrunner/executors/*.js include wptrunner/config.json -include wptrunner/browsers/server-locations.txt \ No newline at end of file
--- a/testing/web-platform/tests/tools/wptrunner/setup.py +++ b/testing/web-platform/tests/tools/wptrunner/setup.py @@ -47,17 +47,16 @@ setup(name=PACKAGE_NAME, package_data={"wptrunner": ["executors/testharness_marionette.js", "executors/testharness_webdriver.js", "executors/reftest.js", "executors/reftest-wait.js", "testharnessreport.js", "testharness_runner.html", "config.json", "wptrunner.default.ini", - "browsers/server-locations.txt", "browsers/sauce_setup/*", "prefs/*"]}, include_package_data=True, data_files=[("requirements", requirements_files)], install_requires=deps ) if "install" in sys.argv:
--- a/testing/web-platform/tests/tools/wptrunner/wptrunner/browsers/chrome.py +++ b/testing/web-platform/tests/tools/wptrunner/wptrunner/browsers/chrome.py @@ -55,18 +55,17 @@ def executor_kwargs(test_type, server_co return executor_kwargs def env_extras(**kwargs): return [] def env_options(): - return {"host": "web-platform.test", - "bind_hostname": "true"} + return {"bind_hostname": "true"} class ChromeBrowser(Browser): """Chrome is backed by chromedriver, which is supplied through ``wptrunner.webdriver.ChromeDriverServer``. """ def __init__(self, logger, binary, webdriver_binary="chromedriver",
--- a/testing/web-platform/tests/tools/wptrunner/wptrunner/browsers/chrome_android.py +++ b/testing/web-platform/tests/tools/wptrunner/wptrunner/browsers/chrome_android.py @@ -63,18 +63,17 @@ def executor_kwargs(test_type, server_co return executor_kwargs def env_extras(**kwargs): return [] def env_options(): - return {"host": "web-platform.test", - "bind_hostname": "true"} + return {"bind_hostname": "true"} class ChromeAndroidBrowser(Browser): """Chrome is backed by chromedriver, which is supplied through ``wptrunner.webdriver.ChromeDriverServer``. """ def __init__(self, logger, binary, webdriver_binary="chromedriver",
--- a/testing/web-platform/tests/tools/wptrunner/wptrunner/browsers/edge.py +++ b/testing/web-platform/tests/tools/wptrunner/wptrunner/browsers/edge.py @@ -33,18 +33,17 @@ def executor_kwargs(test_type, server_co executor_kwargs["close_after_done"] = True executor_kwargs["capabilities"] = dict(DesiredCapabilities.EDGE.items()) return executor_kwargs def env_extras(**kwargs): return [] def env_options(): - return {"host": "web-platform.test", - "bind_hostname": "true", + return {"bind_hostname": "true", "supports_debugger": False} class EdgeBrowser(Browser): used_ports = set() def __init__(self, logger, webdriver_binary, webdriver_args=None): Browser.__init__(self, logger) self.server = EdgeDriverServer(self.logger,
--- a/testing/web-platform/tests/tools/wptrunner/wptrunner/browsers/firefox.py +++ b/testing/web-platform/tests/tools/wptrunner/wptrunner/browsers/firefox.py @@ -1,34 +1,33 @@ import os import platform import signal import subprocess import sys +import tempfile import mozinfo import mozleak from mozprocess import ProcessHandler from mozprofile import FirefoxProfile, Preferences -from mozprofile.permissions import ServerLocations from mozrunner import FirefoxRunner from mozrunner.utils import get_stack_fixer_function from mozcrash import mozcrash from .base import (get_free_port, Browser, ExecutorBrowser, require_arg, cmd_arg, browser_command) from ..executors import executor_kwargs as base_executor_kwargs from ..executors.executormarionette import (MarionetteTestharnessExecutor, MarionetteRefTestExecutor, MarionetteWdspecExecutor) -from ..environment import hostnames here = os.path.join(os.path.split(__file__)[0]) __wptrunner__ = {"product": "firefox", "check_args": "check_args", "browser": "FirefoxBrowser", "executor": {"testharness": "MarionetteTestharnessExecutor", @@ -75,17 +74,18 @@ def browser_kwargs(test_type, run_info_d "e10s": kwargs["gecko_e10s"], "stackfix_dir": kwargs["stackfix_dir"], "binary_args": kwargs["binary_args"], "timeout_multiplier": get_timeout_multiplier(test_type, run_info_data, **kwargs), "leak_check": kwargs["leak_check"], "stylo_threads": kwargs["stylo_threads"], - "chaos_mode_flags": kwargs["chaos_mode_flags"]} + "chaos_mode_flags": kwargs["chaos_mode_flags"], + "config": kwargs["config"]} def executor_kwargs(test_type, server_config, cache_manager, run_info_data, **kwargs): executor_kwargs = base_executor_kwargs(test_type, server_config, cache_manager, **kwargs) executor_kwargs["close_after_done"] = test_type != "reftest" executor_kwargs["timeout_multiplier"] = get_timeout_multiplier(test_type, @@ -97,17 +97,17 @@ def executor_kwargs(test_type, server_co executor_kwargs["reftest_screenshot"] = kwargs["reftest_screenshot"] if test_type == "wdspec": options = {} if kwargs["binary"]: options["binary"] = kwargs["binary"] if kwargs["binary_args"]: options["args"] = kwargs["binary_args"] options["prefs"] = { - "network.dns.localDomains": ",".join(hostnames) + "network.dns.localDomains": ",".join(server_config['domains'].values()) } capabilities["moz:firefoxOptions"] = options if kwargs["certutil_binary"] is None: capabilities["acceptInsecureCerts"] = True if capabilities: executor_kwargs["capabilities"] = capabilities return executor_kwargs @@ -138,32 +138,33 @@ class FirefoxBrowser(Browser): used_ports = set() init_timeout = 60 shutdown_timeout = 60 def __init__(self, logger, binary, prefs_root, test_type, extra_prefs=None, debug_info=None, symbols_path=None, stackwalk_binary=None, certutil_binary=None, ca_certificate_path=None, e10s=False, stackfix_dir=None, binary_args=None, timeout_multiplier=None, leak_check=False, stylo_threads=1, - chaos_mode_flags=None): + chaos_mode_flags=None, config=None): Browser.__init__(self, logger) self.binary = binary self.prefs_root = prefs_root self.test_type = test_type self.extra_prefs = extra_prefs self.marionette_port = None self.runner = None self.debug_info = debug_info self.profile = None self.symbols_path = symbols_path self.stackwalk_binary = stackwalk_binary self.ca_certificate_path = ca_certificate_path self.certutil_binary = certutil_binary self.e10s = e10s self.binary_args = binary_args + self.config = config if stackfix_dir: self.stack_fixer = get_stack_fixer_function(stackfix_dir, self.symbols_path) else: self.stack_fixer = None if timeout_multiplier: self.init_timeout = self.init_timeout * timeout_multiplier @@ -184,25 +185,22 @@ class FirefoxBrowser(Browser): env = os.environ.copy() 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) - locations = ServerLocations(filename=os.path.join(here, "server-locations.txt")) - preferences = self.load_prefs() - self.profile = FirefoxProfile(locations=locations, - preferences=preferences) + self.profile = FirefoxProfile(preferences=preferences) self.profile.set_preferences({"marionette.port": self.marionette_port, "dom.disable_open_during_load": False, - "network.dns.localDomains": ",".join(hostnames), + "network.dns.localDomains": ",".join(self.config['domains'].values()), "network.proxy.type": 0, "places.history.enabled": False, "dom.send_after_paint_to_content": True, "network.preload": True}) if self.e10s: self.profile.set_preferences({"browser.tabs.remote.autostart": True}) if self.test_type == "reftest":
--- a/testing/web-platform/tests/tools/wptrunner/wptrunner/browsers/ie.py +++ b/testing/web-platform/tests/tools/wptrunner/wptrunner/browsers/ie.py @@ -37,18 +37,17 @@ def executor_kwargs(test_type, server_co executor_kwargs["close_after_done"] = True executor_kwargs["capabilities"] = capabilities return executor_kwargs def env_extras(**kwargs): return [] def env_options(): - return {"host": "web-platform.test", - "bind_hostname": "true", + return {"bind_hostname": "true", "supports_debugger": False} class InternetExplorerBrowser(Browser): used_ports = set() def __init__(self, logger, webdriver_binary, webdriver_args=None): Browser.__init__(self, logger) self.server = InternetExplorerDriverServer(self.logger,
--- a/testing/web-platform/tests/tools/wptrunner/wptrunner/browsers/opera.py +++ b/testing/web-platform/tests/tools/wptrunner/wptrunner/browsers/opera.py @@ -55,18 +55,17 @@ def executor_kwargs(test_type, server_co return executor_kwargs def env_extras(**kwargs): return [] def env_options(): - return {"host": "web-platform.test", - "bind_hostname": "true"} + return {"bind_hostname": "true"} class OperaBrowser(Browser): """Opera is backed by operadriver, which is supplied through ``wptrunner.webdriver.OperaDriverServer``. """ def __init__(self, logger, binary, webdriver_binary="operadriver",
--- a/testing/web-platform/tests/tools/wptrunner/wptrunner/browsers/sauce.py +++ b/testing/web-platform/tests/tools/wptrunner/wptrunner/browsers/sauce.py @@ -108,31 +108,31 @@ def executor_kwargs(test_type, server_co return executor_kwargs def env_extras(**kwargs): return [SauceConnect(**kwargs)] def env_options(): - return {"host": "web-platform.test", - "bind_hostname": "true", + return {"bind_hostname": "true", "supports_debugger": False} def get_tar(url, dest): resp = requests.get(url, stream=True) resp.raise_for_status() with tarfile.open(fileobj=CStringIO(resp.raw.read())) as f: f.extractall(path=dest) class SauceConnect(): def __init__(self, **kwargs): + self.config = kwargs["config"] self.sauce_user = kwargs["sauce_user"] self.sauce_key = kwargs["sauce_key"] self.sauce_tunnel_id = kwargs["sauce_tunnel_id"] self.sauce_connect_binary = kwargs.get("sauce_connect_binary") self.sc_process = None self.temp_dir = None def __enter__(self, options): @@ -148,18 +148,17 @@ class SauceConnect(): self.sauce_connect_binary, "--user=%s" % self.sauce_user, "--api-key=%s" % self.sauce_key, "--no-remove-colliding-tunnels", "--tunnel-identifier=%s" % self.sauce_tunnel_id, "--metrics-address=0.0.0.0:9876", "--readyfile=./sauce_is_ready", "--tunnel-domains", - "web-platform.test", - "*.web-platform.test" + ",".join(self.config['domains'].values()) ]) # Timeout config vars each_sleep_secs = 1 max_wait = 30 kill_wait = 5 tot_wait = 0
deleted file mode 100644 --- a/testing/web-platform/tests/tools/wptrunner/wptrunner/browsers/server-locations.txt +++ /dev/null @@ -1,31 +0,0 @@ -http://localhost:8000 primary - -http://web-platform.test:8000 -http://www.web-platform.test:8000 -http://www1.web-platform.test:8000 -http://www2.web-platform.test:8000 -http://xn--n8j6ds53lwwkrqhv28a.web-platform.test:8000 -http://xn--lve-6lad.web-platform.test:8000 - -http://web-platform.test:8001 -http://www.web-platform.test:8001 -http://www1.web-platform.test:8001 -http://www2.web-platform.test:8001 -http://xn--n8j6ds53lwwkrqhv28a.web-platform.test:8001 -http://xn--lve-6lad.web-platform.test:8001 - -https://web-platform.test:8443 -https://www.web-platform.test:8443 -https://www1.web-platform.test:8443 -https://www2.web-platform.test:8443 -https://xn--n8j6ds53lwwkrqhv28a.web-platform.test:8443 -https://xn--lve-6lad.web-platform.test:8443 - -# These are actually ws servers, but until mozprofile is -# fixed we have to pretend that they are http servers -http://web-platform.test:8888 -http://www.web-platform.test:8888 -http://www1.web-platform.test:8888 -http://www2.web-platform.test:8888 -http://xn--n8j6ds53lwwkrqhv28a.web-platform.test:8888 -http://xn--lve-6lad.web-platform.test:8888
--- a/testing/web-platform/tests/tools/wptrunner/wptrunner/browsers/servodriver.py +++ b/testing/web-platform/tests/tools/wptrunner/wptrunner/browsers/servodriver.py @@ -1,14 +1,17 @@ import os +import shutil import subprocess import tempfile from mozprocess import ProcessHandler +from serve.serve import make_hosts_file + from .base import Browser, require_arg, get_free_port, browser_command, ExecutorBrowser from ..executors import executor_kwargs as base_executor_kwargs from ..executors.executorservodriver import (ServoWebDriverTestharnessExecutor, ServoWebDriverRefTestExecutor) here = os.path.join(os.path.split(__file__)[0]) __wptrunner__ = { @@ -21,24 +24,16 @@ here = os.path.join(os.path.split(__file }, "browser_kwargs": "browser_kwargs", "executor_kwargs": "executor_kwargs", "env_extras": "env_extras", "env_options": "env_options", "update_properties": "update_properties", } -hosts_text = """127.0.0.1 web-platform.test -127.0.0.1 www.web-platform.test -127.0.0.1 www1.web-platform.test -127.0.0.1 www2.web-platform.test -127.0.0.1 xn--n8j6ds53lwwkrqhv28a.web-platform.test -127.0.0.1 xn--lve-6lad.web-platform.test -""" - def check_args(**kwargs): require_arg(kwargs, "binary") def browser_kwargs(test_type, run_info_data, **kwargs): return { "binary": kwargs["binary"], @@ -64,35 +59,35 @@ def env_options(): "testharnessreport": "testharnessreport-servodriver.js", "supports_debugger": True} def update_properties(): return ["debug", "os", "version", "processor", "bits"], None -def make_hosts_file(): +def write_hosts_file(config): hosts_fd, hosts_path = tempfile.mkstemp() with os.fdopen(hosts_fd, "w") as f: - f.write(hosts_text) + f.write(make_hosts_file(config, "127.0.0.1")) return hosts_path class ServoWebDriverBrowser(Browser): used_ports = set() def __init__(self, logger, binary, debug_info=None, webdriver_host="127.0.0.1", user_stylesheets=None): Browser.__init__(self, logger) self.binary = binary self.webdriver_host = webdriver_host self.webdriver_port = None self.proc = None self.debug_info = debug_info - self.hosts_path = make_hosts_file() + self.hosts_path = write_hosts_file() self.command = None self.user_stylesheets = user_stylesheets if user_stylesheets else [] def start(self, **kwargs): self.webdriver_port = get_free_port(4444, exclude=self.used_ports) self.used_ports.add(self.webdriver_port) env = os.environ.copy() @@ -153,13 +148,14 @@ class ServoWebDriverBrowser(Browser): def is_alive(self): if self.runner: return self.runner.is_running() return False def cleanup(self): self.stop() + shutil.rmtree(os.path.dirname(self.hosts_file)) def executor_browser(self): assert self.webdriver_port is not None return ExecutorBrowser, {"webdriver_host": self.webdriver_host, "webdriver_port": self.webdriver_port}
--- a/testing/web-platform/tests/tools/wptrunner/wptrunner/environment.py +++ b/testing/web-platform/tests/tools/wptrunner/wptrunner/environment.py @@ -13,24 +13,16 @@ from wptserve.handlers import StringHand here = os.path.split(__file__)[0] repo_root = os.path.abspath(os.path.join(here, os.pardir, os.pardir, os.pardir)) serve = None sslutils = None -hostnames = ["web-platform.test", - "www.web-platform.test", - "www1.web-platform.test", - "www2.web-platform.test", - "xn--n8j6ds53lwwkrqhv28a.web-platform.test", - "xn--lve-6lad.web-platform.test"] - - def do_delayed_imports(logger, test_paths): global serve, sslutils serve_root = serve_path(test_paths) sys.path.insert(0, serve_root) failed = []
--- a/testing/web-platform/tests/tools/wptrunner/wptrunner/executors/executorservo.py +++ b/testing/web-platform/tests/tools/wptrunner/wptrunner/executors/executorservo.py @@ -8,16 +8,18 @@ import tempfile import threading import traceback import urlparse import uuid from collections import defaultdict from mozprocess import ProcessHandler +from serve.serve import make_hosts_file + from .base import (ExecutorException, Protocol, RefTestImplementation, testharness_result_converter, reftest_result_converter, WdspecExecutor, WebDriverProtocol) from .process import ProcessTestExecutor from ..browsers.base import browser_command @@ -25,44 +27,36 @@ from ..wpttest import WdspecResult, Wdsp from ..webdriver_server import ServoDriverServer from .executormarionette import WdspecRun pytestrunner = None webdriver = None extra_timeout = 5 # seconds -hosts_text = """127.0.0.1 web-platform.test -127.0.0.1 www.web-platform.test -127.0.0.1 www1.web-platform.test -127.0.0.1 www2.web-platform.test -127.0.0.1 xn--n8j6ds53lwwkrqhv28a.web-platform.test -127.0.0.1 xn--lve-6lad.web-platform.test -""" - -def make_hosts_file(): +def write_hosts_file(config): hosts_fd, hosts_path = tempfile.mkstemp() with os.fdopen(hosts_fd, "w") as f: - f.write(hosts_text) + f.write(make_hosts_file(config, "127.0.0.1")) return hosts_path class ServoTestharnessExecutor(ProcessTestExecutor): convert_result = testharness_result_converter def __init__(self, browser, server_config, timeout_multiplier=1, debug_info=None, pause_after_test=False, **kwargs): ProcessTestExecutor.__init__(self, browser, server_config, timeout_multiplier=timeout_multiplier, debug_info=debug_info) self.pause_after_test = pause_after_test self.result_data = None self.result_flag = None self.protocol = Protocol(self, browser) - self.hosts_path = make_hosts_file() + self.hosts_path = write_hosts_file(server_config) def teardown(self): try: os.unlink(self.hosts_path) except OSError: pass ProcessTestExecutor.teardown(self)
deleted file mode 100644 --- a/testing/web-platform/tests/tools/wptrunner/wptrunner/hosts.py +++ /dev/null @@ -1,100 +0,0 @@ -from __future__ import unicode_literals - - -class HostsLine(object): - def __init__(self, ip_address, canonical_hostname, aliases=None, comment=None): - self.ip_address = ip_address - self.canonical_hostname = canonical_hostname - self.aliases = aliases if aliases is not None else [] - self.comment = comment - if self.ip_address is None: - assert self.canonical_hostname is None - assert not self.aliases - assert self.comment is not None - - @classmethod - def from_string(cls, line): - if not line.strip(): - return - - line = line.strip() - - ip_address = None - canonical_hostname = None - aliases = [] - comment = None - - comment_parts = line.split("#", 1) - if len(comment_parts) > 1: - comment = comment_parts[1] - - data = comment_parts[0].strip() - - if data: - fields = data.split() - if len(fields) < 2: - raise ValueError("Invalid hosts line") - - ip_address = fields[0] - canonical_hostname = fields[1] - aliases = fields[2:] - - return cls(ip_address, canonical_hostname, aliases, comment) - - -class HostsFile(object): - def __init__(self): - self.data = [] - self.by_hostname = {} - - def set_host(self, host): - if host.canonical_hostname is None: - self.data.append(host) - elif host.canonical_hostname in self.by_hostname: - old_host = self.by_hostname[host.canonical_hostname] - old_host.ip_address = host.ip_address - old_host.aliases = host.aliases - old_host.comment = host.comment - else: - self.data.append(host) - self.by_hostname[host.canonical_hostname] = host - - @classmethod - def from_file(cls, f): - rv = cls() - for line in f: - host = HostsLine.from_string(line) - if host is not None: - rv.set_host(host) - return rv - - def to_string(self): - field_widths = [0, 0] - for line in self.data: - if line.ip_address is not None: - field_widths[0] = max(field_widths[0], len(line.ip_address)) - field_widths[1] = max(field_widths[1], len(line.canonical_hostname)) - - lines = [] - - for host in self.data: - line = "" - if host.ip_address is not None: - ip_string = host.ip_address.ljust(field_widths[0]) - hostname_str = host.canonical_hostname - if host.aliases: - hostname_str = "%s %s" % (hostname_str.ljust(field_widths[1]), - " ".join(host.aliases)) - line = "%s %s" % (ip_string, hostname_str) - if host.comment: - if line: - line += " " - line += "#%s" % host.comment - lines.append(line) - - lines.append("") - - return "\n".join(lines) - - def to_file(self, f): - f.write(self.to_string().encode("utf8"))
--- a/testing/web-platform/tests/tools/wptrunner/wptrunner/tests/browsers/test_sauce.py +++ b/testing/web-platform/tests/tools/wptrunner/wptrunner/tests/browsers/test_sauce.py @@ -15,16 +15,19 @@ def test_sauceconnect_success(): mock.patch.object(sauce.os.path, "exists") as exists: # Act as if it's still running Popen.return_value.poll.return_value = None Popen.return_value.returncode = None # Act as if file created exists.return_value = True sauce_connect = sauce.SauceConnect( + config={ + "domains": {"": "example.net"} + }, sauce_user="aaa", sauce_key="bbb", sauce_tunnel_id="ccc", sauce_connect_binary="ddd") sauce_connect.__enter__(None) @@ -41,16 +44,19 @@ def test_sauceconnect_failure_exit(ready mock.patch.object(sauce.subprocess, "Popen") as Popen,\ mock.patch.object(sauce.os.path, "exists") as exists,\ mock.patch.object(sauce.time, "sleep") as sleep: Popen.return_value.poll.return_value = returncode Popen.return_value.returncode = returncode exists.return_value = readyfile sauce_connect = sauce.SauceConnect( + config={ + "domains": {"": "example.net"} + }, sauce_user="aaa", sauce_key="bbb", sauce_tunnel_id="ccc", sauce_connect_binary="ddd") with pytest.raises(sauce.SauceException): sauce_connect.__enter__(None) @@ -63,22 +69,56 @@ def test_sauceconnect_failure_never_read mock.patch.object(sauce.subprocess, "Popen") as Popen,\ mock.patch.object(sauce.os.path, "exists") as exists,\ mock.patch.object(sauce.time, "sleep") as sleep: Popen.return_value.poll.return_value = None Popen.return_value.returncode = None exists.return_value = False sauce_connect = sauce.SauceConnect( + config={ + "domains": {"": "example.net"} + }, sauce_user="aaa", sauce_key="bbb", sauce_tunnel_id="ccc", sauce_connect_binary="ddd") with pytest.raises(sauce.SauceException): sauce_connect.__enter__(None) # We should sleep while waiting for it to create the readyfile sleep.assert_called() # Check we actually kill it after termination fails Popen.return_value.terminate.assert_called() Popen.return_value.kill.assert_called() + + +def test_sauceconnect_tunnel_domains(): + with mock.patch.object(sauce.SauceConnect, "upload_prerun_exec"),\ + mock.patch.object(sauce.subprocess, "Popen") as Popen,\ + mock.patch.object(sauce.os.path, "exists") as exists: + Popen.return_value.poll.return_value = None + Popen.return_value.returncode = None + exists.return_value = True + + sauce_connect = sauce.SauceConnect( + config={ + "domains": {"foo": "foo.bar.example.com", "": "example.net"} + }, + sauce_user="aaa", + sauce_key="bbb", + sauce_tunnel_id="ccc", + sauce_connect_binary="ddd") + + sauce_connect.__enter__(None) + + Popen.assert_called_once() + args, kwargs = Popen.call_args + cmd = args[0] + assert "--tunnel-domains" in cmd + i = cmd.index("--tunnel-domains") + rest = cmd[i+1:] + assert len(rest) >= 1 + if len(rest) > 1: + assert rest[1].startswith("-"), "--tunnel-domains takes a comma separated list (not a space separated list)" + assert set(rest[0].split(",")) == {"foo.bar.example.com", "example.net"}
deleted file mode 100644 --- a/testing/web-platform/tests/tools/wptrunner/wptrunner/tests/test_hosts.py +++ /dev/null @@ -1,54 +0,0 @@ -import unittest -import sys -from os.path import join, dirname -from cStringIO import StringIO - -sys.path.insert(0, join(dirname(__file__), "..", "..")) - -from wptrunner import hosts - - -class HostsTest(unittest.TestCase): - def do_test(self, input, expected): - host_file = hosts.HostsFile.from_file(StringIO(input)) - self.assertEquals(host_file.to_string(), expected) - - def test_simple(self): - self.do_test("""127.0.0.1 \tlocalhost alias # comment -# Another comment""", - """127.0.0.1 localhost alias # comment -# Another comment -""") - - def test_blank_lines(self): - self.do_test("""127.0.0.1 \tlocalhost alias # comment - -\r - \t -# Another comment""", - """127.0.0.1 localhost alias # comment -# Another comment -""") - - def test_whitespace(self): - self.do_test(""" \t127.0.0.1 \tlocalhost alias # comment \r - \t# Another comment""", - """127.0.0.1 localhost alias # comment -# Another comment -""") - - def test_alignment(self): - self.do_test("""127.0.0.1 \tlocalhost alias -192.168.1.1 another_host another_alias -""","""127.0.0.1 localhost alias -192.168.1.1 another_host another_alias -""") - - def test_multiple_same_name(self): - # The semantics are that we overwrite earlier entries with the same name - self.do_test("""127.0.0.1 \tlocalhost alias -192.168.1.1 localhost another_alias""","""192.168.1.1 localhost another_alias -""") - -if __name__ == "__main__": - unittest.main()
--- a/testing/web-platform/tests/tools/wptrunner/wptrunner/wptrunner.py +++ b/testing/web-platform/tests/tools/wptrunner/wptrunner/wptrunner.py @@ -213,16 +213,17 @@ def run_tests(config, test_paths, produc if test_type == "wdspec": browser_cls = NullBrowser else: browser_cls = target_browser_cls browser_kwargs = get_browser_kwargs(test_type, run_info, ssl_env=ssl_env, + config=test_environment.config, **kwargs) executor_cls = executor_classes.get(test_type) executor_kwargs = get_executor_kwargs(test_type, test_environment.config, test_environment.cache_manager, run_info, **kwargs)
--- a/testing/web-platform/tests/tools/wptserve/wptserve/pipes.py +++ b/testing/web-platform/tests/tools/wptserve/wptserve/pipes.py @@ -387,16 +387,22 @@ def template(request, content, escape_ty field = tokens[0][1] if field in variables: value = variables[field] elif field == "headers": value = request.headers elif field == "GET": value = FirstWrapper(request.GET) + elif field == "domains": + if ('not_domains' in request.server.config and + tokens[1][1] in request.server.config['not_domains']): + value = request.server.config['not_domains'] + else: + value = request.server.config['domains'] elif field in request.server.config: value = request.server.config[tokens[0][1]] elif field == "location": value = {"server": "%s://%s:%s" % (request.url_parts.scheme, request.url_parts.hostname, request.url_parts.port), "scheme": request.url_parts.scheme, "host": "%s:%s" % (request.url_parts.hostname,