Skip to content

Commit

Permalink
Fix #2669: Add alternate_hosts (#10166)
Browse files Browse the repository at this point in the history
  • Loading branch information
gsnedders authored May 1, 2018
1 parent a0b8550 commit dfeea56
Show file tree
Hide file tree
Showing 12 changed files with 226 additions and 86 deletions.
3 changes: 3 additions & 0 deletions config.default.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{"browser_host": "web-platform.test",
"alternate_hosts": {
"alt": "not-web-platform.test"
},
"doc_root": null,
"ws_doc_root": null,
"server_host": null,
Expand Down
43 changes: 25 additions & 18 deletions docs/_writing-tests/server-features.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,18 @@ generation. This is supported through the

### Tests Involving Multiple Origins

In the test environment, five subdomains are available: `www`, `www1`,
`www2`, `天気の良い日`, and `élève`; there is also
`nonexistent-origin` which is guaranteed not to resolve. In addition,
the HTTP server listens on two ports, and the WebSockets server on
one. These subdomains and ports must be used for cross-origin
tests. Tests must not hardcode the hostname of the server that they
expect to be running on or the port numbers, as these are not
guaranteed by the test environment. Instead they can get this
information in one of two ways:
Our test servers are guaranteed to be accessible through two domains
and five subdomains under each. The 'main' domain is unnamed; the
other is called 'alt'. These subdomains are: `www`, `www1`, `www2`,
`天気の良い日`, and `élève`; there is also `nonexistent-origin` which
is guaranteed not to resolve. In addition, the HTTP server listens on
two ports, and the WebSockets server on one. These subdomains and
ports must be used for cross-origin tests.

Tests must not hardcode the hostname of the server that they expect to
be running on or the port numbers, as these are not guaranteed by the
test environment. Instead they can get this information in one of two
ways:

* From script, using the `location` API.

Expand All @@ -33,15 +36,19 @@ form `{name}.sub.{ext}` e.g. `example-test.sub.html` or be referenced
through a URL containing `pipe=sub` in the query string
e.g. `example-test.html?pipe=sub`. The substitution syntax uses `{%
raw %}{{ }}{% endraw %}` to delimit items for substitution. For
example to substitute in the host name on which the tests are running,
one would write: `{% raw %}{{host}}{% endraw %}`.


As well as the host, one can get full domains, including subdomains
using the `domains` dictionary. For example, `{% raw
%}{{domains[www]}}{% endraw %}` or `{% raw %}{{domains[élève]}}{%
endraw %}` would be replaced by the full qualified domain name of the
respective subdomains.
example to substitute in the main host name, one would write:
`{% raw %}{{host}}{% endraw %}`.

To get full domains, including subdomains, there is the `hosts`
dictionary, where the first dimension is the name of the domain, and
the second the subdomain. For example, `{% raw %}{{hosts[][www]}}{%
endraw %}` would give the `www` subdomain under the main (unnamed)
domain, and `{% raw %}{{hosts[alt][élève]}}{% endraw %}` would give
the `élève` subdomain under the alt domain.

For mostly historic reasons, the subdomains of the main domain are
also available under the `domains` dictionary; this is identical to
`hosts[]`.

Ports are also available on a per-protocol basis. For example, `{% raw
%}{{ports[ws][0]}}{% endraw %}` is replaced with the first (and only)
Expand Down
23 changes: 14 additions & 9 deletions tools/serve/serve.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,9 +399,13 @@ def is_alive(self):
return self.proc.is_alive()


def check_subdomains(domains, paths, bind_address, ssl_config, aliases):
domains = domains.copy()
host = domains.pop("")
def check_subdomains(config):
paths = config.paths
bind_address = config.bind_address
ssl_config = config.ssl_config
aliases = config.aliases

host = config.server_host
port = get_port(host)
logger.debug("Going to use port %d to check subdomains" % port)

Expand All @@ -423,7 +427,10 @@ def check_subdomains(domains, paths, bind_address, ssl_config, aliases):
"You may need to edit /etc/hosts or similar, see README.md." % (host, port))
sys.exit(1)

for domain in domains.itervalues():
for domain in config.domains_set:
if domain == host:
continue

try:
urllib2.urlopen("http://%s:%d/" % (domain, port))
except Exception as e:
Expand All @@ -437,10 +444,10 @@ def check_subdomains(domains, paths, bind_address, ssl_config, aliases):
def make_hosts_file(config, host):
rv = []

for domain in config["domains"].values():
for domain in config.domains_set:
rv.append("%s\t%s\n" % (host, domain))

for not_domain in config.get("not_domains", {}).values():
for not_domain in config.not_domains_set:
rv.append("0.0.0.0\t%s\n" % not_domain)

return "".join(rv)
Expand Down Expand Up @@ -695,9 +702,7 @@ def run(**kwargs):
bind_address = config["bind_address"]

if config["check_subdomains"]:
paths = config.paths
ssl_config = config.ssl_config
check_subdomains(config.domains, paths, bind_address, ssl_config, config["aliases"])
check_subdomains(config)

stash_address = None
if bind_address:
Expand Down
26 changes: 18 additions & 8 deletions tools/serve/test_serve.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
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")
c = serve.Config(browser_host="foo.bar", alternate_hosts={"alt": "foo2.bar"})
hosts = serve.make_hosts_file(c, "192.168.42.42")
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
assert set(lines) == {"",
"0.0.0.0\tnonexistent-origin.foo.bar",
"0.0.0.0\tnonexistent-origin.foo2.bar",
"192.168.42.42\tfoo.bar",
"192.168.42.42\tfoo2.bar",
"192.168.42.42\twww.foo.bar",
"192.168.42.42\twww.foo2.bar",
"192.168.42.42\twww1.foo.bar",
"192.168.42.42\twww1.foo2.bar",
"192.168.42.42\twww2.foo.bar",
"192.168.42.42\twww2.foo2.bar",
"192.168.42.42\txn--lve-6lad.foo.bar",
"192.168.42.42\txn--lve-6lad.foo2.bar",
"192.168.42.42\txn--n8j6ds53lwwkrqhv28a.foo.bar",
"192.168.42.42\txn--n8j6ds53lwwkrqhv28a.foo2.bar"}
assert lines[-1] == ""
3 changes: 1 addition & 2 deletions tools/wpt/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,7 @@ def check_environ(product):
if product not in ("firefox", "servo"):
config = serve.load_config(os.path.join(wpt_root, "config.default.json"),
os.path.join(wpt_root, "config.json"))
expected_hosts = (set(config["domains"].itervalues()) ^
set(config["not_domains"].itervalues()))
expected_hosts = set(config.all_domains_set)
missing_hosts = set(expected_hosts)
if platform.uname()[0] != "Windows":
hosts_path = "/etc/hosts"
Expand Down
4 changes: 2 additions & 2 deletions tools/wptrunner/wptrunner/browsers/firefox.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def executor_kwargs(test_type, server_config, cache_manager, run_info_data,
if kwargs["binary_args"]:
options["args"] = kwargs["binary_args"]
options["prefs"] = {
"network.dns.localDomains": ",".join(server_config.domains.itervalues())
"network.dns.localDomains": ",".join(server_config.domains_set)
}
capabilities["moz:firefoxOptions"] = options
if kwargs["certutil_binary"] is None:
Expand Down Expand Up @@ -198,7 +198,7 @@ def start(self, **kwargs):
self.profile = FirefoxProfile(preferences=preferences)
self.profile.set_preferences({"marionette.port": self.marionette_port,
"dom.disable_open_during_load": False,
"network.dns.localDomains": ",".join(self.config.domains.itervalues()),
"network.dns.localDomains": ",".join(self.config.domains_set),
"network.proxy.type": 0,
"places.history.enabled": False,
"dom.send_after_paint_to_content": True,
Expand Down
2 changes: 1 addition & 1 deletion tools/wptrunner/wptrunner/browsers/sauce.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ def __enter__(self):
"--metrics-address=0.0.0.0:9876",
"--readyfile=./sauce_is_ready",
"--tunnel-domains",
",".join(self.env_config['domains'].values())
",".join(self.env_config.domains_set)
])

# Timeout config vars
Expand Down
6 changes: 5 additions & 1 deletion tools/wptrunner/wptrunner/tests/browsers/test_sauce.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ def test_sauceconnect_tunnel_domains():
sauce_connect_binary="ddd")

env_config = Config(browser_host="example.net",
alternate_hosts={"alt": "example.org"},
subdomains={"a", "b"},
not_subdomains={"x", "y"})
sauce_connect(None, env_config)
Expand All @@ -125,4 +126,7 @@ def test_sauceconnect_tunnel_domains():
assert rest[1].startswith("-"), "--tunnel-domains takes a comma separated list (not a space separated list)"
assert set(rest[0].split(",")) == {'example.net',
'a.example.net',
'b.example.net'}
'b.example.net',
'example.org',
'a.example.org',
'b.example.org'}
104 changes: 92 additions & 12 deletions tools/wptserve/tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,48 +272,128 @@ def test_set_server_host():

def test_domains():
c = config.Config(browser_host="foo.bar",
alternate_hosts={"alt": "foo2.bar"},
subdomains={"a", "b"},
not_subdomains={"x", "y"})
domains = c.domains
assert domains == {
"": "foo.bar",
"a": "a.foo.bar",
"b": "b.foo.bar",
"": {
"": "foo.bar",
"a": "a.foo.bar",
"b": "b.foo.bar",
},
"alt": {
"": "foo2.bar",
"a": "a.foo2.bar",
"b": "b.foo2.bar",
},
}


def test_not_domains():
c = config.Config(browser_host="foo.bar",
alternate_hosts={"alt": "foo2.bar"},
subdomains={"a", "b"},
not_subdomains={"x", "y"})
not_domains = c.not_domains
assert not_domains == {
"x": "x.foo.bar",
"y": "y.foo.bar",
"": {
"x": "x.foo.bar",
"y": "y.foo.bar",
},
"alt": {
"x": "x.foo2.bar",
"y": "y.foo2.bar",
},
}


def test_domains_not_domains_intersection():
c = config.Config(browser_host="foo.bar",
alternate_hosts={"alt": "foo2.bar"},
subdomains={"a", "b"},
not_subdomains={"x", "y"})
domains = c.domains
not_domains = c.not_domains
assert len(set(domains.iterkeys()) & set(not_domains.iterkeys())) == 0
assert len(set(domains.itervalues()) & set(not_domains.itervalues())) == 0
assert len(set(domains.iterkeys()) ^ set(not_domains.iterkeys())) == 0
for host in domains.iterkeys():
host_domains = domains[host]
host_not_domains = not_domains[host]
assert len(set(host_domains.iterkeys()) & set(host_not_domains.iterkeys())) == 0
assert len(set(host_domains.itervalues()) & set(host_not_domains.itervalues())) == 0


def test_all_domains():
c = config.Config(browser_host="foo.bar",
alternate_hosts={"alt": "foo2.bar"},
subdomains={"a", "b"},
not_subdomains={"x", "y"})
all_domains = c.all_domains
assert all_domains == {
"": "foo.bar",
"a": "a.foo.bar",
"b": "b.foo.bar",
"x": "x.foo.bar",
"y": "y.foo.bar",
"": {
"": "foo.bar",
"a": "a.foo.bar",
"b": "b.foo.bar",
"x": "x.foo.bar",
"y": "y.foo.bar",
},
"alt": {
"": "foo2.bar",
"a": "a.foo2.bar",
"b": "b.foo2.bar",
"x": "x.foo2.bar",
"y": "y.foo2.bar",
},
}


def test_domains_set():
c = config.Config(browser_host="foo.bar",
alternate_hosts={"alt": "foo2.bar"},
subdomains={"a", "b"},
not_subdomains={"x", "y"})
domains_set = c.domains_set
assert domains_set == {
"foo.bar",
"a.foo.bar",
"b.foo.bar",
"foo2.bar",
"a.foo2.bar",
"b.foo2.bar",
}


def test_not_domains_set():
c = config.Config(browser_host="foo.bar",
alternate_hosts={"alt": "foo2.bar"},
subdomains={"a", "b"},
not_subdomains={"x", "y"})
not_domains_set = c.not_domains_set
assert not_domains_set == {
"x.foo.bar",
"y.foo.bar",
"x.foo2.bar",
"y.foo2.bar",
}


def test_all_domains_set():
c = config.Config(browser_host="foo.bar",
alternate_hosts={"alt": "foo2.bar"},
subdomains={"a", "b"},
not_subdomains={"x", "y"})
all_domains_set = c.all_domains_set
assert all_domains_set == {
"foo.bar",
"a.foo.bar",
"b.foo.bar",
"x.foo.bar",
"y.foo.bar",
"foo2.bar",
"a.foo2.bar",
"b.foo2.bar",
"x.foo2.bar",
"y.foo2.bar",
}


Expand Down
Loading

0 comments on commit dfeea56

Please sign in to comment.