Skip to content

Commit b8451e9

Browse files
committed
Test and document resources/server endpoints
1 parent f9a7e19 commit b8451e9

File tree

7 files changed

+660
-494
lines changed

7 files changed

+660
-494
lines changed

_hp/hp/test_internals.py

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,110 @@
11
import pytest
2+
import json
3+
import httpx
24

35
from hp.tools.crawler.selenium_run_specific import config, run_specific
46
from hp.tools.crawler.utils import generate_short_uuid
57

8+
with open("_hp/wpt-config.json", "r") as f:
9+
wpt_config = json.load(f)
10+
611

712
def test_generate_short_uuid():
13+
"""Assert length of generate_shot_uuid is correct."""
814
assert len(generate_short_uuid(3)) == 3
915

1016

1117
def test_selenium_test_specific():
12-
url = "http://sub.headers.websec.saarland/_hp/tests/referrer-access-rp.sub.html?resp_type=basic&browser_id=1&label=RP&first_id=199&last_id=199&scheme=http&t_resp_id=199&t_element_relation=iframe_window.open&t_resp_origin=http://sub.headers.websec.saarland"
18+
"""Smoke test for run_specific: function runs without crashing, browser can visit one of our test pages."""
19+
url = f"http://sub.{wpt_config['browser_host']}/_hp/tests/referrer-access-rp.sub.html?resp_type=basic&browser_id=1&label=RP&first_id=199&last_id=199&scheme=http&t_resp_id=199&t_element_relation=iframe_window.open&t_resp_origin=http://sub.{wpt_config['browser_host']}"
1320
for browser_name, browser_version, binary_location, arguments, _ in config:
1421
run_specific(url, browser_name, browser_version, binary_location, arguments)
1522

1623
assert True
24+
25+
26+
def test_get_resp_ids():
27+
"""Check that server returns resp_ids: 2 entries for label=XFO&resp_type=debug"""
28+
assert wpt_config["browser_host"]
29+
assert wpt_config["alternate_hosts"]["alt"]
30+
base_host = f"sub.{wpt_config['browser_host']}"
31+
label = "XFO"
32+
resp_type = "debug"
33+
34+
resp_ids = httpx.get(
35+
f"https://{base_host}/_hp/server/get_resp_ids.py?label={label}&resp_type={resp_type}",
36+
verify=False,
37+
).json()
38+
39+
assert len(resp_ids) == 2
40+
41+
42+
def test_notify_runner_clients():
43+
"""Check that notify_runner_clients.py works"""
44+
base_host = f"sub.{wpt_config['browser_host']}"
45+
run_id = "does_not_exist"
46+
47+
resp = httpx.get(
48+
f"https://{base_host}/_hp/server/notify_runner_clients.py?run_id={run_id}",
49+
verify=False,
50+
).json()
51+
52+
assert resp == {"result": "done"}
53+
54+
55+
def test_responses():
56+
"""Check that responses.py returns valid responses"""
57+
base_host = f"sub.{wpt_config['browser_host']}"
58+
resp_id = 1
59+
resp = 1
60+
feature_group = "framing"
61+
62+
resp = httpx.get(
63+
f"https://{base_host}/_hp/server/responses.py?resp={resp}&resp_id={resp_id}&feature_group={feature_group}",
64+
verify=False,
65+
)
66+
67+
assert resp.status_code == 200
68+
69+
70+
def test_store_results():
71+
"""Check that store_results.py works"""
72+
base_host = f"sub.{wpt_config['browser_host']}"
73+
74+
resp = httpx.post(
75+
f"https://{base_host}/_hp/server/store_results.py", verify=False
76+
).json()
77+
78+
# Empty body/non-json body should be rejected
79+
assert resp == {"Error": "Expecting value: line 1 column 1 (char 0)"}
80+
81+
# Correct entry should be saved
82+
body = {
83+
"tests": [
84+
{
85+
"name": "referrer_iframe|false|window.open|http://sub.headers.websec.saarland|199",
86+
"outcome": "document.referrer: http://sub.headers.websec.saarland/_hp/server/responses.py?feature_group=rp&resp_id=199&count=1&nest=1&origin=http://sub.headers.websec.saarland&element=window.open&resp=1",
87+
"status": 0,
88+
"message": None,
89+
"stack": None,
90+
"resp_scheme": "http",
91+
"resp_host": "sub.headers.websec.saarland",
92+
"relation": "window.open",
93+
}
94+
],
95+
"browser_id": "1",
96+
"test": "http://sub.headers.websec.saarland/_hp/tests/referrer-access-rp.sub.html?resp_type=basic&browser_id=1&label=RP&first_id=199&last_id=199&scheme=http&t_resp_id=199&t_element_relation=iframe_window.open&t_resp_origin=http://sub.headers.websec.saarland",
97+
"status": 0,
98+
"message": None,
99+
"stack": None,
100+
"org_scheme": "http",
101+
"org_host": "sub.headers.websec.saarland",
102+
"full_url": "http://sub.headers.websec.saarland/_hp/tests/referrer-access-rp.sub.html?resp_type=basic&browser_id=1&label=RP&first_id=199&last_id=199&scheme=http&t_resp_id=199&t_element_relation=iframe_window.open&t_resp_origin=http://sub.headers.websec.saarland",
103+
}
104+
105+
resp = httpx.post(
106+
f"https://{base_host}/_hp/server/store_results.py", verify=False, json=body
107+
).json()
108+
109+
# Correct body should be saved
110+
assert resp == {'Status': 'Success'}

_hp/resources/store_results.sub.js

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1-
// More helper functions here!
1+
/*
2+
Functions and helpers to run the "Head(er)s Up!" browser tests and store the final results in the database
3+
*/
4+
// Scheme and host of the top-level file (original scheme/host)
25
var org_scheme = location.port == 9000 ? "http2" : location.protocol == "http:" ? "http" : "https";
36
var org_host = location.hostname;
47

8+
// String to search for on the page; Only necessary for manual debugging of the COEP bug
59
let search = urlParams.get('search') || undefined;
610

711
// We always visit the testpages at http://sub.headers.websec.saarland or https://sub.headers.websec.saarland
8-
// We then create tests for http, https, ~~and http2~~ for the following cases:
9-
// same-org, 2x same-site (parent-domain + sub-domain), cross-site
12+
// We then create tests for the following origins:
13+
// (https and https) X same-org, 2x same-site (parent-domain + sub-domain), cross-site
1014
function get_test_origins(resp_type) {
1115
const same_host = 'sub.{{host}}';
1216
const parent = '{{host}}';
@@ -24,13 +28,16 @@ function get_test_origins(resp_type) {
2428
origins.push(`http://${host}`);
2529
}
2630
origins.push(`https://${host}`);
27-
// H2 has a process leak? after a while 7k+ processes are open and everything crashes
31+
32+
// The WPT HTTP/2 server has a process leak: after a while 7k+ processes are open and everything crashes
2833
// Occurs for both with/without settings to allow for invalid responses
34+
// For now do not test HTTP/2
2935
//origins.push(`https://${host}:{{ports[h2][0]}}`);
3036
}
3137
return origins;
3238
};
3339

40+
// Helper to wait for a postMessage from a specific frame
3441
function waitForMessageFrom(frame, test) {
3542
return new Promise(resolve => {
3643
window.addEventListener("message", test.step_func(e => {
@@ -41,32 +48,38 @@ function waitForMessageFrom(frame, test) {
4148
});
4249
}
4350

44-
// Run all tests for origin relations and similar!
51+
// Run all declared tests for the specified origins
4552
function run_tests(test_declarations, path, label, origins) {
46-
const resp_type = urlParams.get("resp_type") || "debug"; // Default resp_type is debug
53+
// Which tests to run: debug (default), basic, parsing
54+
const resp_type = urlParams.get("resp_type") || "debug";
55+
// Which tests to run (from first_id to last_id)
4756
const first_id = parseInt(urlParams.get("first_id"), 10) || null;
4857
const last_id = parseInt(urlParams.get("last_id"), 10) || null;
58+
// If tests open popups, which to run (from first_popup to last_popup)
4959
const first_popup = parseInt(urlParams.get("first_popup"), 10) || 0;
5060
const last_popup = parseInt(urlParams.get("last_popup"), 10) || Infinity;
61+
// Do not run any popup tests
5162
const run_no_popup = urlParams.get("run_no_popup") || 'yes';
5263

53-
// Manual confirmation mode
64+
// Settings for the manual confirmation mode
65+
// Only run this exact test instance
5466
const t_resp_id = parseInt(urlParams.get("t_resp_id"), 10) || null;
5567
const t_resp_origin = urlParams.get("t_resp_origin") || null;
5668
const element_relation = urlParams.get("t_element_relation") || null;
5769

58-
// Fetch origin relations if not specified
70+
// If no origin relations are specified, run for the default origins of the `resp_type`
5971
if (!origins) {
6072
origins = get_test_origins(resp_type);
6173
}
6274

63-
// If &first_id=<first_id>&last_id=<last_id>; run on the specified ids
75+
// For automated testing run on the specified ids (&first_id=<first_id>&last_id=<last_id>;)
6476
let popup_count = 0;
6577
if (first_id && last_id) {
6678
for (var response_id = first_id; response_id < last_id + 1; response_id++) {
6779
for (var origin of origins) {
6880
for (let test of test_declarations) {
69-
// Only run exactly one test in the manual confirmation mode (the manual confirmation mode has to use clean_urls without popup_settings!)
81+
// Only run exactly one test in the manual confirmation mode
82+
// (the manual confirmation mode has to use clean_urls without popup_settings!)
7083
if (t_resp_id) {
7184
if (t_resp_id != response_id) {
7285
continue
@@ -108,6 +121,7 @@ function run_tests(test_declarations, path, label, origins) {
108121
console.log(`All popups: ${popup_count}`);
109122
}
110123

124+
// Helper to create nested tests
111125
function nested_test(frame_element, sandbox, url, response_id, element, test_info, test_name) {
112126
async_test(t => {
113127
t.set_test_info(url, test_info);
@@ -145,19 +159,20 @@ function nested_test(frame_element, sandbox, url, response_id, element, test_inf
145159
}, test_name);
146160
}
147161

148-
// Store result helpers!
162+
// Store all the results on our database
149163
async function save_result(tests, status) {
150164
console.log(tests);
165+
// Convert the WPT test results to our format
151166
var test_results = tests.map(function (x) {
152167
return {
153168
name: x.name, outcome: x.outcome, status: x.status, message: x.message, stack: x.stack,
154169
resp_scheme: x.resp_scheme, resp_host: x.resp_host, relation: x.relation
155170
}
156171
});
157172
var data = {
158-
// Results for the individual tests + metainfo (which browser)
173+
// Results for the individual tests + metainfo (e.g., which browser)
159174
tests: test_results,
160-
browser_id: urlParams.get('browser_id') || 1, // One is the unknown browser!
175+
browser_id: urlParams.get('browser_id') || 1, // "1" is the unknown browser!
161176
// Other metadata (status etc. of the complete test file run)
162177
test: window.location.href,
163178
status: status.status,
@@ -167,6 +182,7 @@ async function save_result(tests, status) {
167182
org_host: org_host,
168183
full_url: document.location.href
169184
};
185+
// Store the results at the database
170186
await fetch('https://{{host}}:{{ports[https][0]}}/_hp/server/store_results.py', {
171187
method: 'POST',
172188
body: JSON.stringify(data),
@@ -181,12 +197,13 @@ async function save_result(tests, status) {
181197
d.id = "finished";
182198
document.body.appendChild(d);
183199

184-
// Try to stop the page runner
200+
// Stop the run_id page runner by notifying the runner via postgres
185201
let run_id = urlParams.get('run_id') || undefined;
186202
if (run_id) {
187203
await fetch(`${location.origin}/_hp/server/notify_runner_clients.py?run_id=${run_id}`);
188204
}
189205

206+
// For manual debugging of the COEP test only
190207
if (search) {
191208
// Get the content of the webpage
192209
const webpageContent = document.body.innerText;
@@ -209,10 +226,11 @@ async function save_result(tests, status) {
209226
try {
210227
window.opener.postMessage("finished", "*");
211228
} catch (e) {
212-
// Openere page does not exist; test opened directly
229+
// Opener page does not exist; test opened directly
213230
console.log(e);
214231
}
215232

216233

217234
};
218-
add_completion_callback(save_result);
235+
// Save the results if the tests are finished
236+
add_completion_callback(save_result);

0 commit comments

Comments
 (0)