0

Rewrite and add to wpt/cookies/http-state/ordering-tests.html

Here's a mapping from the legacy http-state/ordering-tests.html to its
new location which will have a cookie with some variation of test=N in
it:

ordering0001 => test=1

There's also a couple of few new tests added here.

This CL also removes the remaining unused http-state resource files and
moves the domain tests up a directory.

Bug: 1171495
Change-Id: Ifc567ab42fbd13858975019a7f0e4b0e2571df76
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2676913
Reviewed-by: Lily Chen <chlily@chromium.org>
Commit-Queue: Mike Taylor <miketaylr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#851320}
This commit is contained in:
Mike Taylor
2021-02-05 22:48:04 +00:00
committed by Chromium LUCI CQ
parent 40e182a61e
commit 3c22093c9f
14 changed files with 98 additions and 377 deletions

@ -1,4 +0,0 @@
This is a testharness.js-based test.
FAIL ordering0001 - ordering0001 assert_equals: expected "key=val5; key=val1; key=val2; key=val4" but got "key=val0; key=val2"
Harness: the test ran to completion.

@ -1,30 +0,0 @@
<!doctype html>
<html>
<head>
<meta charset=utf-8>
<title>Tests basic cookie setting functionality</title>
<meta name=help href="https://tools.ietf.org/html/rfc6265#page-8">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/cookie-http-state-template.js"></script>
</head>
<body>
<div id="log"></div>
<div id="iframes"></div>
<script>
setup({ explicit_timeout: true });
const TEST_CASES = [
{file: "ordering0001", name: "ordering0001"},
];
for (const i in TEST_CASES) {
const t = TEST_CASES[i];
promise_test(createCookieTest(t.file),
t.file + " - " + t.name);
}
</script>
</body>
</html>

@ -1,71 +0,0 @@
<!doctype html>
<html>
<head>
<meta charset=utf-8>
<title>Tests basic cookie setting functionality</title>
<meta name=help href="https://tools.ietf.org/html/rfc6265#page-8">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="cookie-http-state-template.js"></script>
</head>
<body>
<h1>Cookie Tests</h1>
This page is a debug page for cookie tests. To run a test in isolation,
append "?debug=" and the test id to this URL. E.g. to debug "value0001", use
this url:<br>
<a href="cookie-setter.py?debug=value0001">
cookie-setter.py?debug=value0001
</a><br>
<br>
To request, append "?file=" and the file name (stripped of
"-tests.html"). For value0001, this would be:<br>
<a href="cookie-setter.py?file=value0001">
cookie-setter.py?file=value0001
</a><br>
<br>
Please note, the general tests are one level higher:<br>
<a href="../attribute-tests.html"> ../attribute-tests.html </a><br>
<a href="../charset-tests.html"> ../charset-tests.html </a><br>
<a href="../chromium-tests.html"> ../chromium-tests.html </a><br>
<a href="../comma-tests.html"> ../comma-tests.html </a><br>
<a href="../domain-tests.html"> ../domain-tests.html </a><br>
<a href="../general-tests.html"> ../general-tests.html </a><br>
<a href="../mozilla-tests.html"> ../mozilla-tests.html </a><br>
<a href="../name-tests.html"> ../name-tests.html </a><br>
<a href="../ordering-tests.html"> ../ordering-tests.html </a><br>
<a href="../path-tests.html"> ../path-tests.html </a><br>
<a href="../value-tests.html"> ../value-tests.html </a><br>
<h2>Current Cookies</h2>
These are all cookies, currently set by the browser for this domain: <br>
<span id="cookies">(None)</span>
<script type="text/javascript">
setInterval(() => {
document.getElementById("cookies").textContent =
document.cookie || "(None)";
}, 500);
</script>
<h2>All Tests</h2>
Below, all tests are running. The Log contains messages (e.g. when cookies
are left over) and the IFrames list preserves all requested files and shows
which cookies were expected to show. <br>
<div id="log"></div>
<div id="iframes"></div>
<script>
setup({ explicit_timeout: true });
const TEST_CASES = [%s];
for (const i in TEST_CASES) {
const t = TEST_CASES[i];
promise_test(createCookieTest(t.file),
t.file + " - " + t.name);
}
</script>
</body>
</html>

@ -1,131 +0,0 @@
const SERVER_LOCATION = "resources";
const SERVER_SCRIPT = SERVER_LOCATION + "/cookie-setter.py";
/* Adds a div with "<time> [<tag>] - <message>" to the "#log" container.*/
function log(message, tag) {
let log_str = document.createElement('div');
log_str.textContent = new Date().toTimeString().replace(/\s.+$/, '');
if (tag) {
log_str.textContent += " [" + tag + "] ";
}
log_str.textContent += " - " + message;
let log_container = document.getElementById("log");
log_container.appendChild(log_str);
log_container.scrollTo(0, log_container.scrollHeight);
}
/* Removes the "Cookie: " prefix and strip any leading or trailing whitespace.*/
function stripPrefixAndWhitespace(cookie_text) {
return cookie_text.replace(/^Cookie: /, '').replace(/^\s+|\s+$/g, '');
}
/* Returns the absolute path of the resource folder, ignoring any navigation. */
function getLocalResourcesPath() {
let replace = "(" + SERVER_LOCATION + "\/)*"; // Redundant location.
replace += "[^\/]*$"; // Everything after the last "/".
return location.pathname.replace(new RegExp(replace), "") + SERVER_LOCATION;
}
/* Returns the absolute server location ignoring any navgation.*/
function getAbsoluteServerLocation() {
// Replace the server location and everything coming after it ...
let replace = SERVER_LOCATION + ".*$";
// ... with the Server script (which includes the server location).
return getLocalResourcesPath().replace(new RegExp(replace),'')+ SERVER_SCRIPT;
}
/* Expires a cookie by name by setting it's expiry date into the past.*/
function expireCookie(name, expiry_date, path) {
name = name || "";
expiry_date = expiry_date || "Thu, 01 Jan 1970 00:00:00 UTC";
path = path || getLocalResourcesPath();
document.cookie = name + "=value; expires=" + expiry_date + "; path=" + path + ";";
}
/* Captures a snapshot of cookies with |parse| and allows to diff it with a
second snapshot with |diffWith|. This allows to run tests even if cookies were
previously set that would mess with the expected final set of Cookies.
With |resetCookies|, all cookies set between first and second snapshot are
expired. */
function CookieManager() {
this.initial_cookies = [];
}
/* Creates a snapshot of the current given document cookies.*/
CookieManager.prototype.parse = document_cookies => {
this.initial_cookies = [];
document_cookies = document_cookies.replace(/^Cookie: /, '');
if (document_cookies != "") {
this.initial_cookies = document_cookies.split(/\s*;\s*/);
}
}
/* Creates a diff of newly added cookies between the initial snapshot and the
newly given cookies. The diff is stored for cleaning purposes. A second call
will replace the the stored diff entirely.*/
CookieManager.prototype.diffWith = document_cookies => {
this.actual_cookies = document_cookies;
for (let i in initial_cookies) {
let no_spaces_cookie_regex =
new RegExp(/\s*[\;]*\s/.source + initial_cookies[i].replace(/\\/, "\\\\"));
this.actual_cookies = this.actual_cookies.replace(no_spaces_cookie_regex, '');
}
return this.actual_cookies;
}
/* Cleans cookies between the first and the second snapshot.
Some tests might set cookies to the root path or cookies without key. Both cases
are dropped here.*/
CookieManager.prototype.resetCookies = () => {
// If a cookie without keys was accepted, drop it additionally.
let cookies_to_delete = [""].concat(this.actual_cookies.split(/\s*;\s*/))
for (let i in cookies_to_delete){
expireCookie(cookies_to_delete[i].replace(/=.*$/, ""));
// Drop cookies with same name that were set to the root path which happens
// for example due to "0010" still failing.
expireCookie(cookies_to_delete[i].replace(/=.*$/, ""),
/*expiry_date=*/null,
/*path=*/'/');
// Some browsers incorrectly include the final "forward slash" character
// when calculating the default path. The expected behavior for default
// path calculation is verified elsewhere; this utility accommodates the
// non-standard behavior in order to improve the focus of the test suite.
expireCookie(cookies_to_delete[i].replace(/=.*$/, ""),
/*expiry_date=*/null,
/*path=*/getLocalResourcesPath() + "/");
}
}
/* Returns a new cookie test.
The test creates an iframe where a |file| from the cookie-setter.py is loaded.
This sets cookies which are diffed with an initial cookie snapshot and compared
to the expectation that the server returned.
Finally, it cleans up newly set cookies and all cookies in the root path or
without key. */
function createCookieTest(file) {
return t => {
let iframe_container = document.getElementById("iframes");
const iframe = document.createElement('iframe');
iframe_container.appendChild(iframe);
iframe_container.scrollTo(0, iframe_container.scrollHeight);
let diff_tool = new CookieManager();
t.add_cleanup(diff_tool.resetCookies);
return new Promise((resolve, reject) => {
diff_tool.parse(document.cookie);
if (diff_tool.initial_cookies.length > 0) {
// The cookies should ideally be empty. If that isn't the case, log it.
//Cookies with equal keys (e.g. foo=) may have unwanted side-effects.
log("Run with existing cookies: " + diff_tool.initial_cookies, file);
}
window.addEventListener("message", t.step_func(e => {
assert_true(!!e.data, "Message contains data")
resolve(e.data);
}));
iframe.src = getAbsoluteServerLocation() + "?file=" + file;
}).then((response) => {
let actual_cookies = diff_tool.diffWith(response.cookies);
let expected_cookies = stripPrefixAndWhitespace(response.expectation);
assert_equals(actual_cookies, expected_cookies);
});
}
};

@ -1,96 +0,0 @@
from os import path
from os import listdir
from wptserve.utils import isomorphic_decode
"""
The main purpose of this script is to set cookies based on files in this folder:
cookies/http-state/resources
If a wpt server is running, navigate to
http://<server>/cookies/http-state/resources/cookie-setter.py
which will run all cookie tests and explain the usage of this script in detail.
If you want to run a test in isolation, append "?debug=" and the test id to the
URL above.
"""
SETUP_FILE_TEMPLATE = u"{}-test"
EXPECTATION_FILE_TEMPLATE = u"{}-expected"
EXPECTATION_HTML_SCAFFOLD = u"iframe-expectation-doc.html.py-str"
DEBUGGING_HTML_SCAFFOLD = u"debugging-single-test.html.py-str"
DEFAULT_RESOURCE_DIR = path.join(u"cookies", u"http-state", u"resources")
DEFAULT_TEST_DIR = u"test-files"
ALL_TESTS = u"all-tests.html.py-str"
def dump_file(directory, filename):
"""Reads a file into a byte string."""
return open(path.join(directory, filename), "rb").read()
class CookieTestResponse(object):
"""Loads the Set-Cookie header from a given file name. Relies on the naming
convention that ever test file is called '<test_id>-test' and every
expectation is called '<test_id>-expected'."""
def __init__(self, file, root):
super(CookieTestResponse, self).__init__()
self.__test_file = SETUP_FILE_TEMPLATE.format(file)
self.__expectation_file = EXPECTATION_FILE_TEMPLATE.format(file)
self.__resources_dir = path.join(root, DEFAULT_RESOURCE_DIR)
self.__test_files_dir = path.join(self.__resources_dir, DEFAULT_TEST_DIR)
def cookie_setting_header(self):
"""Returns the loaded header."""
return dump_file(self.__test_files_dir, self.__test_file)
def body_with_expectation(self):
"""Returns a full HTML document which contains the expectation."""
html_frame = dump_file(self.__resources_dir, EXPECTATION_HTML_SCAFFOLD)
expected_data = dump_file(self.__test_files_dir, self.__expectation_file)
return html_frame.replace(b"{data}", expected_data)
def find_all_test_files(root):
"""Retrieves all files from the test-files/ folder and returns them as
string pair as used in the JavaScript object. Sorted by filename."""
all_files = []
line_template = u'{{file: "{filename}", name: "{filename}"}},'
for file in listdir(path.join(root, DEFAULT_RESOURCE_DIR, DEFAULT_TEST_DIR)):
if file.endswith(u'-test'):
name = file.replace(u'-test', u'')
all_files.append(line_template.format(filename=name).encode())
all_files.sort()
return all_files
def generate_for_all_tests(root):
"""Returns an HTML document which loads and executes all tests in the
test-files/ directory."""
html_frame = dump_file(path.join(root, DEFAULT_RESOURCE_DIR), ALL_TESTS)
return html_frame % b'\n'.join(find_all_test_files(root))
def main(request, response):
if b"debug" in request.GET:
"""If '?debug=' is set, return the document for a single test."""
response.writer.write_status(200)
response.writer.end_headers()
html_frame = dump_file(path.join(request.doc_root, DEFAULT_RESOURCE_DIR),
DEBUGGING_HTML_SCAFFOLD)
test_file = html_frame % (request.GET[b'debug'])
response.writer.write_content(test_file)
return
if b"file" in request.GET:
"""If '?file=' is set, send a cookie and a document which contains the
expectation of which cookies should be set by the browser in response."""
cookie_response = CookieTestResponse(isomorphic_decode(request.GET[b'file']), request.doc_root)
response.writer.write_status(200)
response.writer.write(cookie_response.cookie_setting_header())
response.writer.end_headers()
response.writer.write_content(cookie_response.body_with_expectation())
return
"""Without any arguments, return documentation and run all available tests."""
response.writer.write_status(200)
response.writer.end_headers()
response.writer.write_content(generate_for_all_tests(request.doc_root))

@ -1,21 +0,0 @@
<!doctype html>
<html>
<head>
<meta charset=utf-8>
<title>Debug single test</title>
<meta name=help href="https://tools.ietf.org/html/rfc6265#page-8">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="cookie-http-state-template.js"></script>
</head>
<body>
<div id="log"></div>
<div id="iframes"></div>
<script>
setup({ explicit_timeout: true });
promise_test(createCookieTest("%s"), "DEBUG");
</script>
</body>
</html>

@ -1,4 +0,0 @@
window.top.postMessage({
"cookies": document.cookie,
"expectation": document.querySelector('#data').innerText
}, "*");

@ -1,11 +0,0 @@
<!doctype html>
<html>
<head>
<meta charset=utf-8>
<title>Cookie Test Expectation Document</title>
</head>
<body>
<div id="data" style="white-space: pre">{data}</div>
<script src="iframe-content-pushing.js"></script>
</body>
</html>

@ -1 +0,0 @@
Cookie: key=val5; key=val1; key=val2; key=val4

@ -1,7 +0,0 @@
Set-Cookie: key=val0;
Set-Cookie: key=val1; path=/cookie-parser-result
Set-Cookie: key=val2; path=/
Set-Cookie: key=val3; path=/bar
Set-Cookie: key=val4; domain=.example.org
Set-Cookie: key=val5; domain=.example.org; path=/cookie-parser-result/foo
Location: /cookie-parser-result/foo/baz?ordering0001

@ -0,0 +1,24 @@
<!doctype html>
<html>
<head>
<meta charset=utf-8>
<title>Test cookie ordering</title>
<meta name=help href="https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-07#section-5.5">
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/cookies/resources/cookie-test.js"></script>
</head>
</head>
<body>
<script>
const port = "{{ports[http][0]}}";
const wwwHost = "{{domains[www]}}";
test(t => {
const win = window.open(`http://${wwwHost}:${port}/cookies/ordering/resources/ordering-child.sub.html`);
fetch_tests_from_window(win);
});
</script>
</body>
</html>

@ -0,0 +1,74 @@
<!doctype html>
<html>
<head>
<meta charset=utf-8>
<title>Test cookie ordering</title>
<meta name=help href="https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-07#section-5.5">
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/cookies/resources/cookie-test.js"></script>
</head>
<body>
<div id=log></div>
<script>
const host = "{{host}}";
const wwwHost = "{{domains[www]}}";
const orderingTests = [
{
cookie: [
"testA=1",
"testB=1; path=/cookies",
"testC=1; path=/",
"testD=1; path=/cooking",
`testE=1; domain=.${host}; path=/`,
`testF=1; domain=.${host}; path=/cookies/attributes`,
],
expected: "testF=1; testB=1; testC=1; testE=1",
name: "Cookies with longer path attribute values are ordered before shorter ones",
location: "/cookies/attributes/resources/path/one.html",
},
{
cookie: [
"testA=2",
"testB=2; path=/cookies/attributes/resources",
"testC=2; path=/",
"testD=2; path=/cooking",
`testE=2; domain=.${host}`,
`testF=2; domain=.${host}; path=/cookies/attributes`,
`testG=2; domain=.${host}; path=/cookies/attributes/resources/path`,
"testH=2; path=/cookies",
],
expected: "testG=2; testB=2; testF=2; testH=2; testC=2",
name: "Cookies with longer path attribute values are ordered before shorter ones (2)",
location: "/cookies/attributes/resources/path/one.html",
},
{
cookie: [
"testA=3; path=/cookies/attributes/resources/path",
"testB=3; path=/cookies/attributes/resources/path/one.html",
"testC=3; path=/cookies/attributes",
],
expected: "testB=3; testA=3; testC=3",
name: "Cookies with longer paths are listed before cookies with shorter paths",
location: "/cookies/attributes/resources/path/one.html",
},
{
cookie: [
"testZ=4; path=/cookies",
"testB=4; path=/cookies/attributes/resources/path",
"testA=4; path=/cookies",
],
expected: "testB=4; testZ=4; testA=4",
name: "For equal length paths, list the cookie with an earlier creation time first",
location: "/cookies/attributes/resources/path/one.html",
},
];
for (const test of orderingTests) {
httpRedirectCookieTest(test.cookie, test.expected, test.name,
test.location);
}
</script>
</body>
</html>

@ -95,7 +95,6 @@ TRAILING WHITESPACE: server-timing/resources/parsing/*
TRAILING WHITESPACE: webvtt/parsing/file-parsing/support/*.vtt
TRAILING WHITESPACE: webvtt/parsing/file-parsing/tests/support/*.vtt
TRAILING WHITESPACE: xhr/resources/headers-some-are-empty.asis
TRAILING WHITESPACE: cookies/http-state/resources/test-files/*
# Intentional use of print statements
PRINT STATEMENT: dom/nodes/Document-createElement-namespace-tests/generate.py