mirror of
https://github.com/servo/servo.git
synced 2025-06-28 19:13:41 +01:00
Update web-platform-tests to revision 7ed322c3132993bcb5734702b40621448670fc76
This commit is contained in:
parent
10fa5fa68a
commit
110ca49f65
52 changed files with 1682 additions and 485 deletions
|
@ -7,7 +7,7 @@
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[Opening a blob URL in a new window immediately before revoking it works.]
|
[Opening a blob URL in a new window immediately before revoking it works.]
|
||||||
expected: TIMEOUT
|
expected: FAIL
|
||||||
|
|
||||||
[Opening a blob URL in a noopener about:blank window immediately before revoking it works.]
|
[Opening a blob URL in a noopener about:blank window immediately before revoking it works.]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
|
@ -280382,6 +280382,15 @@
|
||||||
"native-file-system/script-tests/FileSystemFileHandle-getFile.js": [
|
"native-file-system/script-tests/FileSystemFileHandle-getFile.js": [
|
||||||
[]
|
[]
|
||||||
],
|
],
|
||||||
|
"native-file-system/script-tests/FileSystemWritableFileStream-piped.js": [
|
||||||
|
[]
|
||||||
|
],
|
||||||
|
"native-file-system/script-tests/FileSystemWritableFileStream-write.js": [
|
||||||
|
[]
|
||||||
|
],
|
||||||
|
"native-file-system/script-tests/FileSystemWritableFileStream.js": [
|
||||||
|
[]
|
||||||
|
],
|
||||||
"native-file-system/script-tests/FileSystemWriter.js": [
|
"native-file-system/script-tests/FileSystemWriter.js": [
|
||||||
[]
|
[]
|
||||||
],
|
],
|
||||||
|
@ -374719,6 +374728,12 @@
|
||||||
{}
|
{}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"loading/lazyload/move-element-and-scroll.tentative.html": [
|
||||||
|
[
|
||||||
|
"loading/lazyload/move-element-and-scroll.tentative.html",
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
"loading/lazyload/not-rendered-below-viewport-image-loading-lazy.tentative.html": [
|
"loading/lazyload/not-rendered-below-viewport-image-loading-lazy.tentative.html": [
|
||||||
[
|
[
|
||||||
"loading/lazyload/not-rendered-below-viewport-image-loading-lazy.tentative.html",
|
"loading/lazyload/not-rendered-below-viewport-image-loading-lazy.tentative.html",
|
||||||
|
@ -374767,6 +374782,12 @@
|
||||||
{}
|
{}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"loading/lazyload/remove-element-and-scroll.tentative.html": [
|
||||||
|
[
|
||||||
|
"loading/lazyload/remove-element-and-scroll.tentative.html",
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
"loading/preloader-css-import-no-quote.tentative.html": [
|
"loading/preloader-css-import-no-quote.tentative.html": [
|
||||||
[
|
[
|
||||||
"loading/preloader-css-import-no-quote.tentative.html",
|
"loading/preloader-css-import-no-quote.tentative.html",
|
||||||
|
@ -379592,6 +379613,81 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"native-file-system/native_FileSystemWritableFileStream-piped.tentative.https.manual.window.js": [
|
||||||
|
[
|
||||||
|
"native-file-system/native_FileSystemWritableFileStream-piped.tentative.https.manual.window.html",
|
||||||
|
{
|
||||||
|
"script_metadata": [
|
||||||
|
[
|
||||||
|
"script",
|
||||||
|
"/resources/testdriver.js"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"script",
|
||||||
|
"resources/test-helpers.js"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"script",
|
||||||
|
"resources/native-fs-test-helpers.js"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"script",
|
||||||
|
"script-tests/FileSystemWritableFileStream-piped.js"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"native-file-system/native_FileSystemWritableFileStream-write.tentative.https.manual.window.js": [
|
||||||
|
[
|
||||||
|
"native-file-system/native_FileSystemWritableFileStream-write.tentative.https.manual.window.html",
|
||||||
|
{
|
||||||
|
"script_metadata": [
|
||||||
|
[
|
||||||
|
"script",
|
||||||
|
"/resources/testdriver.js"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"script",
|
||||||
|
"resources/test-helpers.js"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"script",
|
||||||
|
"resources/native-fs-test-helpers.js"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"script",
|
||||||
|
"script-tests/FileSystemWritableFileStream-write.js"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"native-file-system/native_FileSystemWritableFileStream.tentative.https.manual.window.js": [
|
||||||
|
[
|
||||||
|
"native-file-system/native_FileSystemWritableFileStream.tentative.https.manual.window.html",
|
||||||
|
{
|
||||||
|
"script_metadata": [
|
||||||
|
[
|
||||||
|
"script",
|
||||||
|
"/resources/testdriver.js"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"script",
|
||||||
|
"resources/test-helpers.js"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"script",
|
||||||
|
"resources/native-fs-test-helpers.js"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"script",
|
||||||
|
"script-tests/FileSystemWritableFileStream.js"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
"native-file-system/native_FileSystemWriter.tentative.https.manual.window.js": [
|
"native-file-system/native_FileSystemWriter.tentative.https.manual.window.js": [
|
||||||
[
|
[
|
||||||
"native-file-system/native_FileSystemWriter.tentative.https.manual.window.html",
|
"native-file-system/native_FileSystemWriter.tentative.https.manual.window.html",
|
||||||
|
@ -379971,6 +380067,134 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"native-file-system/sandboxed_FileSystemWritableFileStream-piped.tentative.https.any.js": [
|
||||||
|
[
|
||||||
|
"native-file-system/sandboxed_FileSystemWritableFileStream-piped.tentative.https.any.html",
|
||||||
|
{
|
||||||
|
"script_metadata": [
|
||||||
|
[
|
||||||
|
"script",
|
||||||
|
"resources/test-helpers.js"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"script",
|
||||||
|
"resources/sandboxed-fs-test-helpers.js"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"script",
|
||||||
|
"../streams/resources/recording-streams.js"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"script",
|
||||||
|
"script-tests/FileSystemWritableFileStream-piped.js"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"native-file-system/sandboxed_FileSystemWritableFileStream-piped.tentative.https.any.worker.html",
|
||||||
|
{
|
||||||
|
"script_metadata": [
|
||||||
|
[
|
||||||
|
"script",
|
||||||
|
"resources/test-helpers.js"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"script",
|
||||||
|
"resources/sandboxed-fs-test-helpers.js"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"script",
|
||||||
|
"../streams/resources/recording-streams.js"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"script",
|
||||||
|
"script-tests/FileSystemWritableFileStream-piped.js"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"native-file-system/sandboxed_FileSystemWritableFileStream-write.tentative.https.any.js": [
|
||||||
|
[
|
||||||
|
"native-file-system/sandboxed_FileSystemWritableFileStream-write.tentative.https.any.html",
|
||||||
|
{
|
||||||
|
"script_metadata": [
|
||||||
|
[
|
||||||
|
"script",
|
||||||
|
"resources/test-helpers.js"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"script",
|
||||||
|
"resources/sandboxed-fs-test-helpers.js"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"script",
|
||||||
|
"script-tests/FileSystemWritableFileStream-write.js"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"native-file-system/sandboxed_FileSystemWritableFileStream-write.tentative.https.any.worker.html",
|
||||||
|
{
|
||||||
|
"script_metadata": [
|
||||||
|
[
|
||||||
|
"script",
|
||||||
|
"resources/test-helpers.js"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"script",
|
||||||
|
"resources/sandboxed-fs-test-helpers.js"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"script",
|
||||||
|
"script-tests/FileSystemWritableFileStream-write.js"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"native-file-system/sandboxed_FileSystemWritableFileStream.tentative.https.any.js": [
|
||||||
|
[
|
||||||
|
"native-file-system/sandboxed_FileSystemWritableFileStream.tentative.https.any.html",
|
||||||
|
{
|
||||||
|
"script_metadata": [
|
||||||
|
[
|
||||||
|
"script",
|
||||||
|
"resources/test-helpers.js"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"script",
|
||||||
|
"resources/sandboxed-fs-test-helpers.js"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"script",
|
||||||
|
"script-tests/FileSystemWritableFileStream.js"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"native-file-system/sandboxed_FileSystemWritableFileStream.tentative.https.any.worker.html",
|
||||||
|
{
|
||||||
|
"script_metadata": [
|
||||||
|
[
|
||||||
|
"script",
|
||||||
|
"resources/test-helpers.js"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"script",
|
||||||
|
"resources/sandboxed-fs-test-helpers.js"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"script",
|
||||||
|
"script-tests/FileSystemWritableFileStream.js"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
"native-file-system/sandboxed_FileSystemWriter.tentative.https.any.js": [
|
"native-file-system/sandboxed_FileSystemWriter.tentative.https.any.js": [
|
||||||
[
|
[
|
||||||
"native-file-system/sandboxed_FileSystemWriter.tentative.https.any.html",
|
"native-file-system/sandboxed_FileSystemWriter.tentative.https.any.html",
|
||||||
|
@ -671141,6 +671365,10 @@
|
||||||
"f7d887b18a228e648a5de45b890bfce371963cec",
|
"f7d887b18a228e648a5de45b890bfce371963cec",
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
|
"loading/lazyload/move-element-and-scroll.tentative.html": [
|
||||||
|
"f9d89807b8c5575982e4d28f156cb604ae0bbd8b",
|
||||||
|
"testharness"
|
||||||
|
],
|
||||||
"loading/lazyload/not-rendered-below-viewport-image-loading-lazy.tentative.html": [
|
"loading/lazyload/not-rendered-below-viewport-image-loading-lazy.tentative.html": [
|
||||||
"0c40d7dbcd832b379a3d8427f9390fca842439cd",
|
"0c40d7dbcd832b379a3d8427f9390fca842439cd",
|
||||||
"testharness"
|
"testharness"
|
||||||
|
@ -671173,6 +671401,10 @@
|
||||||
"58f8c3a4d5a1e21ce2afd9def3ab9b5870cc272f",
|
"58f8c3a4d5a1e21ce2afd9def3ab9b5870cc272f",
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
|
"loading/lazyload/remove-element-and-scroll.tentative.html": [
|
||||||
|
"53708ceac75fa3421c4ecc1a8b91034c5a91c396",
|
||||||
|
"testharness"
|
||||||
|
],
|
||||||
"loading/lazyload/resources/image.png": [
|
"loading/lazyload/resources/image.png": [
|
||||||
"b712825093805d1052b01047b1dbb102f0af8f0f",
|
"b712825093805d1052b01047b1dbb102f0af8f0f",
|
||||||
"support"
|
"support"
|
||||||
|
@ -676393,6 +676625,18 @@
|
||||||
"16c68c59b273663fb16847f121f38e03bb94cf19",
|
"16c68c59b273663fb16847f121f38e03bb94cf19",
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
|
"native-file-system/native_FileSystemWritableFileStream-piped.tentative.https.manual.window.js": [
|
||||||
|
"2c0299df12e9577261cce2f68d12a1bf744158c2",
|
||||||
|
"testharness"
|
||||||
|
],
|
||||||
|
"native-file-system/native_FileSystemWritableFileStream-write.tentative.https.manual.window.js": [
|
||||||
|
"0efacf9e607d990bccf185b7d84d5f45220338d8",
|
||||||
|
"testharness"
|
||||||
|
],
|
||||||
|
"native-file-system/native_FileSystemWritableFileStream.tentative.https.manual.window.js": [
|
||||||
|
"caf6fbd1c52a3cef603896f8ee98d9618e4dc92e",
|
||||||
|
"testharness"
|
||||||
|
],
|
||||||
"native-file-system/native_FileSystemWriter.tentative.https.manual.window.js": [
|
"native-file-system/native_FileSystemWriter.tentative.https.manual.window.js": [
|
||||||
"25d8ee995857fa67be2c41f048e882ec473f739d",
|
"25d8ee995857fa67be2c41f048e882ec473f739d",
|
||||||
"testharness"
|
"testharness"
|
||||||
|
@ -676485,6 +676729,18 @@
|
||||||
"fb93858fe7934b27244fa0ff828eac75c34b6629",
|
"fb93858fe7934b27244fa0ff828eac75c34b6629",
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
|
"native-file-system/sandboxed_FileSystemWritableFileStream-piped.tentative.https.any.js": [
|
||||||
|
"eed6a561dc40e658b6b6c8d51766cdacc42a024c",
|
||||||
|
"testharness"
|
||||||
|
],
|
||||||
|
"native-file-system/sandboxed_FileSystemWritableFileStream-write.tentative.https.any.js": [
|
||||||
|
"7ef0ea0ef82626eae74f152b94f898859aca6832",
|
||||||
|
"testharness"
|
||||||
|
],
|
||||||
|
"native-file-system/sandboxed_FileSystemWritableFileStream.tentative.https.any.js": [
|
||||||
|
"16dbbe6a808a603c9b81482f733dcf09e84670ff",
|
||||||
|
"testharness"
|
||||||
|
],
|
||||||
"native-file-system/sandboxed_FileSystemWriter.tentative.https.any.js": [
|
"native-file-system/sandboxed_FileSystemWriter.tentative.https.any.js": [
|
||||||
"8352e2487fe0823a2d353372757d833d85e98c4b",
|
"8352e2487fe0823a2d353372757d833d85e98c4b",
|
||||||
"testharness"
|
"testharness"
|
||||||
|
@ -676525,6 +676781,18 @@
|
||||||
"6b7d9f9a3171c96aaa2e1312451b3a9cac6c2e9b",
|
"6b7d9f9a3171c96aaa2e1312451b3a9cac6c2e9b",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
|
"native-file-system/script-tests/FileSystemWritableFileStream-piped.js": [
|
||||||
|
"59fc1e3d1362b3ec90e3ef7a4f0981bdd4a21340",
|
||||||
|
"support"
|
||||||
|
],
|
||||||
|
"native-file-system/script-tests/FileSystemWritableFileStream-write.js": [
|
||||||
|
"f14d79fd040a0e7fc7f19216fec1aec0ca23dec8",
|
||||||
|
"support"
|
||||||
|
],
|
||||||
|
"native-file-system/script-tests/FileSystemWritableFileStream.js": [
|
||||||
|
"5acf93aec8cee8ef3a8389979e2a402acf5cbc7f",
|
||||||
|
"support"
|
||||||
|
],
|
||||||
"native-file-system/script-tests/FileSystemWriter.js": [
|
"native-file-system/script-tests/FileSystemWriter.js": [
|
||||||
"1c51d0b4eb771eec5a606263e72719be589aa317",
|
"1c51d0b4eb771eec5a606263e72719be589aa317",
|
||||||
"support"
|
"support"
|
||||||
|
@ -710978,7 +711246,7 @@
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/requirements_mypy.txt": [
|
"tools/requirements_mypy.txt": [
|
||||||
"50afed2bb2dec184caee69a1074e428d115c5b40",
|
"f3a56a6dd715ac6d6b01057a609a3e470ba8e303",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/runner/css/bootstrap-theme.min.css": [
|
"tools/runner/css/bootstrap-theme.min.css": [
|
||||||
|
@ -715338,7 +715606,7 @@
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/browsers/base.py": [
|
"tools/wptrunner/wptrunner/browsers/base.py": [
|
||||||
"655344581973c15b657729feb736dd2073d79a30",
|
"fef052dd5ab495dad4342e086491723c761edcfd",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/browsers/chrome.py": [
|
"tools/wptrunner/wptrunner/browsers/chrome.py": [
|
||||||
|
@ -715366,7 +715634,7 @@
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/browsers/epiphany.py": [
|
"tools/wptrunner/wptrunner/browsers/epiphany.py": [
|
||||||
"8a0e5f578b2feb871ddd50ab08168c6b9d45e4b0",
|
"f6c4c602a38c043637cf9dbc8bbb5350ec94527e",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/browsers/firefox.py": [
|
"tools/wptrunner/wptrunner/browsers/firefox.py": [
|
||||||
|
@ -715410,11 +715678,11 @@
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/browsers/webkit.py": [
|
"tools/wptrunner/wptrunner/browsers/webkit.py": [
|
||||||
"aa2862139450f682e6051c5f617ab8caf1960784",
|
"1be683ed26e43a9e10a1f82520811c33e90dad05",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/browsers/webkitgtk_minibrowser.py": [
|
"tools/wptrunner/wptrunner/browsers/webkitgtk_minibrowser.py": [
|
||||||
"d735f3c0792a6356c6270143205c55b7c02eef47",
|
"d8b9744bd743e39ce19f008e7f40cbc80e80107c",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/config.py": [
|
"tools/wptrunner/wptrunner/config.py": [
|
||||||
|
@ -715422,7 +715690,7 @@
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/environment.py": [
|
"tools/wptrunner/wptrunner/environment.py": [
|
||||||
"e79ae3750647f88bba44703181c208229800f658",
|
"7dcea4aeafabb9c481dccdc1aaf9bd153572bb7d",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/executors/__init__.py": [
|
"tools/wptrunner/wptrunner/executors/__init__.py": [
|
||||||
|
@ -715466,7 +715734,7 @@
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/executors/executorservo.py": [
|
"tools/wptrunner/wptrunner/executors/executorservo.py": [
|
||||||
"9cef1fb2d7f78e8729e51ff400b3df2402a2e94e",
|
"9eebfa59febf991bd41db25f2b02ea4c8c00195e",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/executors/executorservodriver.py": [
|
"tools/wptrunner/wptrunner/executors/executorservodriver.py": [
|
||||||
|
@ -715522,7 +715790,7 @@
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/expectedtree.py": [
|
"tools/wptrunner/wptrunner/expectedtree.py": [
|
||||||
"4d505086bd8d991c953c34d38d8e1fa0cb920f99",
|
"7521f25b1344f5c50b8182a2b7a68278858f9b47",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/font.py": [
|
"tools/wptrunner/wptrunner/font.py": [
|
||||||
|
@ -715550,23 +715818,23 @@
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/manifestexpected.py": [
|
"tools/wptrunner/wptrunner/manifestexpected.py": [
|
||||||
"eae85b1f6661a67dff59ef78a9ed627e3e3603d8",
|
"65b53f0ab97b581b2b71277bd8f260f79a1afb12",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/manifestinclude.py": [
|
"tools/wptrunner/wptrunner/manifestinclude.py": [
|
||||||
"d302831a57abbaadd75fe49e094482dc14223ea3",
|
"b3ab2c0776571ffe4ca49e599e0a898c4a7c79a3",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/manifestupdate.py": [
|
"tools/wptrunner/wptrunner/manifestupdate.py": [
|
||||||
"2f2a8d543352d4c2128afd0314e8261668964d01",
|
"3cb1b5107924c4d897efccaf8f5de93df2311609",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/metadata.py": [
|
"tools/wptrunner/wptrunner/metadata.py": [
|
||||||
"bf4d7a558abb7da117c95f896c1c8c3babd77219",
|
"aafc7d52250f62fdcd7025858f2273290c77d49e",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/products.py": [
|
"tools/wptrunner/wptrunner/products.py": [
|
||||||
"e3117042709f99f4e0443dc0dfaf561ad0b548b0",
|
"abd84094bb33dbd13b3594a7acbe8467512a99ce",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/stability.py": [
|
"tools/wptrunner/wptrunner/stability.py": [
|
||||||
|
@ -715598,7 +715866,7 @@
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/testloader.py": [
|
"tools/wptrunner/wptrunner/testloader.py": [
|
||||||
"fa54ca361576318cb35ec716a1a159bdb532e6c8",
|
"f16cc14ceada70f781a2aaabb1c2f547cb9d61d1",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/testrunner.py": [
|
"tools/wptrunner/wptrunner/testrunner.py": [
|
||||||
|
@ -715626,7 +715894,7 @@
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/tests/test_expectedtree.py": [
|
"tools/wptrunner/wptrunner/tests/test_expectedtree.py": [
|
||||||
"2308be9590e9004f41a492682d187a7b4fc57231",
|
"d71237a42dad58c69b686e6040b65f40064c9437",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/tests/test_formatters.py": [
|
"tools/wptrunner/wptrunner/tests/test_formatters.py": [
|
||||||
|
@ -715634,7 +715902,7 @@
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/tests/test_manifestexpected.py": [
|
"tools/wptrunner/wptrunner/tests/test_manifestexpected.py": [
|
||||||
"525915d1832ac8af1957a799615969e058eefca5",
|
"f3e4ce796a45c472a88fe022277e0347b4e98948",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/tests/test_products.py": [
|
"tools/wptrunner/wptrunner/tests/test_products.py": [
|
||||||
|
@ -715646,15 +715914,15 @@
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/tests/test_testloader.py": [
|
"tools/wptrunner/wptrunner/tests/test_testloader.py": [
|
||||||
"e857cd43db6d281f95414230f52c984aad915118",
|
"836003d106038ab4303035eecca31774c9a26ce1",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/tests/test_update.py": [
|
"tools/wptrunner/wptrunner/tests/test_update.py": [
|
||||||
"5ed366788067c94245a8f7e1dadccb93da0493ab",
|
"a24e4a733dae576bf82f5b6e17a7bbe3f6d351ef",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/tests/test_wpttest.py": [
|
"tools/wptrunner/wptrunner/tests/test_wpttest.py": [
|
||||||
"9bb3e1fd34e37c4430f752b87e4bb4e3bfa7f959",
|
"1a94a2f3303a7b5a1d5b2c553af6bbd1d8b45bc7",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/update/__init__.py": [
|
"tools/wptrunner/wptrunner/update/__init__.py": [
|
||||||
|
@ -715670,7 +715938,7 @@
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/update/state.py": [
|
"tools/wptrunner/wptrunner/update/state.py": [
|
||||||
"64dbf1180604cd8df7a468e036447f95b80371b0",
|
"f8a83525cbd4706bdfbc99a518d2bac123d34e96",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/update/sync.py": [
|
"tools/wptrunner/wptrunner/update/sync.py": [
|
||||||
|
@ -715694,11 +715962,11 @@
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/wptcommandline.py": [
|
"tools/wptrunner/wptrunner/wptcommandline.py": [
|
||||||
"923bdaa55857e793e8d6e8c587167360aed4ae94",
|
"91f1161b01b99f31ef1d3dde05333627bf4365b2",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/wptlogging.py": [
|
"tools/wptrunner/wptrunner/wptlogging.py": [
|
||||||
"69cee744879eb6780cb99ec93123922e166d9e16",
|
"444d1d962d25873109977b937d96c86cb293cd8f",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/wptmanifest/__init__.py": [
|
"tools/wptrunner/wptrunner/wptmanifest/__init__.py": [
|
||||||
|
@ -715758,11 +716026,11 @@
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/wptrunner.py": [
|
"tools/wptrunner/wptrunner/wptrunner.py": [
|
||||||
"cac172a5940ec696e3a3b279170f9712aaf4668d",
|
"7409dc26560af0be3a397bb73184137d8715811f",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptrunner/wptrunner/wpttest.py": [
|
"tools/wptrunner/wptrunner/wpttest.py": [
|
||||||
"67b57583424d08779114dc2fa030390e584d716f",
|
"4cbaedcdb0163776dfcf55d13afca4cdba05dc92",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"tools/wptserve/.gitignore": [
|
"tools/wptserve/.gitignore": [
|
||||||
|
@ -721278,7 +721546,7 @@
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
"wasm/jsapi/constructor/multi-value.any.js": [
|
"wasm/jsapi/constructor/multi-value.any.js": [
|
||||||
"7fbac5b24f1a50568170e257552bdc7a7783ae25",
|
"2c53e3611e044c8ba44a5c0436d4409bc9f1af42",
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
"wasm/jsapi/constructor/validate.any.js": [
|
"wasm/jsapi/constructor/validate.any.js": [
|
||||||
|
@ -721326,7 +721594,7 @@
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
"wasm/jsapi/instanceTestFactory.js": [
|
"wasm/jsapi/instanceTestFactory.js": [
|
||||||
"7ccf06c234a7ce5c17353f3bd74565b66c289952",
|
"c81672f208b1505430dd1ee909afaf12d9b2db20",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"wasm/jsapi/interface.any.js": [
|
"wasm/jsapi/interface.any.js": [
|
||||||
|
@ -721354,7 +721622,7 @@
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
"wasm/jsapi/module/customSections.any.js": [
|
"wasm/jsapi/module/customSections.any.js": [
|
||||||
"8e9732e5512d3295c445c110e949905cec0efbe6",
|
"09355979d84ade5385e7b3a5ac265eaa0da500cf",
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
"wasm/jsapi/module/exports.any.js": [
|
"wasm/jsapi/module/exports.any.js": [
|
||||||
|
@ -721394,7 +721662,7 @@
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
"wasm/jsapi/wasm-module-builder.js": [
|
"wasm/jsapi/wasm-module-builder.js": [
|
||||||
"09ff891f52e2b4e9dd80fbc88586129cd0a910b6",
|
"82c6e04135f1b86df1a1d8e72c5f829c3297bb10",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"wasm/resources/load_wasm.js": [
|
"wasm/resources/load_wasm.js": [
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
[no-transition-from-ua-to-blocking-stylesheet.html]
|
[no-transition-from-ua-to-blocking-stylesheet.html]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
|
@ -309,24 +309,21 @@
|
||||||
[<iframe>: separate response Content-Type: */* text/html]
|
[<iframe>: separate response Content-Type: */* text/html]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[<iframe>: combined response Content-Type: text/html;charset=gbk text/plain text/html]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[<iframe>: combined response Content-Type: text/html;" \\" text/plain]
|
[<iframe>: combined response Content-Type: text/html;" \\" text/plain]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[<iframe>: combined response Content-Type: text/html;" text/plain]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[<iframe>: separate response Content-Type: text/plain */*]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[<iframe>: combined response Content-Type: text/html */*]
|
[<iframe>: combined response Content-Type: text/html */*]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[<iframe>: combined response Content-Type: text/html */*;charset=gbk]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[<iframe>: combined response Content-Type: text/html;x=" text/plain]
|
[<iframe>: combined response Content-Type: text/html;x=" text/plain]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[<iframe>: combined response Content-Type: */* text/html]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[<iframe>: separate response Content-Type: text/html;" text/plain]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[<iframe>: separate response Content-Type: text/plain */*;charset=gbk]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,3 @@
|
||||||
[separate text/javascript x/x]
|
[separate text/javascript x/x]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[separate text/javascript;charset=windows-1252 error text/javascript]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,6 @@
|
||||||
[X-Content-Type-Options%3A%20nosniff%0C]
|
[X-Content-Type-Options%3A%20nosniff%0C]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[X-Content-Type-Options%3A%20%40%23%24%23%25%25%26%5E%26%5E*()()11!%2Cnosniff]
|
[X-Content-Type-Options%3A%20'NosniFF']
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[embedded-credentials.tentative.sub.html]
|
[embedded-credentials.tentative.sub.html]
|
||||||
type: testharness
|
type: testharness
|
||||||
expected: TIMEOUT
|
expected: CRASH
|
||||||
[Embedded credentials are treated as network errors.]
|
[Embedded credentials are treated as network errors.]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
[traverse_the_history_1.html]
|
||||||
|
[Multiple history traversals from the same task]
|
||||||
|
expected: FAIL
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
[skip-document-with-fragment.html]
|
[skip-document-with-fragment.html]
|
||||||
|
expected: TIMEOUT
|
||||||
[Autofocus elements in iframed documents with URL fragments should be skipped.]
|
[Autofocus elements in iframed documents with URL fragments should be skipped.]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
[Autofocus elements in top-level browsing context's documents with URI fragments should be skipped.]
|
||||||
|
expected: TIMEOUT
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,20 @@
|
||||||
[supported-elements.html]
|
[supported-elements.html]
|
||||||
|
expected: TIMEOUT
|
||||||
[Contenteditable element should support autofocus]
|
[Contenteditable element should support autofocus]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[Element with tabindex should support autofocus]
|
[Element with tabindex should support autofocus]
|
||||||
expected: FAIL
|
expected: TIMEOUT
|
||||||
|
|
||||||
[Host element with delegatesFocus including no focusable descendants should be skipped]
|
[Host element with delegatesFocus including no focusable descendants should be skipped]
|
||||||
expected: FAIL
|
expected: NOTRUN
|
||||||
|
|
||||||
[Area element should support autofocus]
|
[Area element should support autofocus]
|
||||||
expected: FAIL
|
expected: NOTRUN
|
||||||
|
|
||||||
[Host element with delegatesFocus should support autofocus]
|
[Host element with delegatesFocus should support autofocus]
|
||||||
expected: FAIL
|
expected: NOTRUN
|
||||||
|
|
||||||
|
[Non-HTMLElement should not support autofocus]
|
||||||
|
expected: NOTRUN
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
[crossorigin-sandwich-TAO.sub.html]
|
[crossorigin-sandwich-TAO.sub.html]
|
||||||
|
expected: ERROR
|
||||||
[There should be one entry.]
|
[There should be one entry.]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
[realtimeanalyser-fft-scaling.html]
|
[realtimeanalyser-fft-scaling.html]
|
||||||
|
expected: TIMEOUT
|
||||||
[X 2048-point FFT peak position is not equal to 64. Got 0.]
|
[X 2048-point FFT peak position is not equal to 64. Got 0.]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
[005.html]
|
[005.html]
|
||||||
expected: ERROR
|
|
||||||
[dedicated worker in shared worker in dedicated worker]
|
[dedicated worker in shared worker in dedicated worker]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<head>
|
||||||
|
<title>Images with loading='lazy' load being moved to another document
|
||||||
|
and then scrolled to</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="common.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Marked as tentative until https://github.com/whatwg/html/pull/3752 is landed.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="tall_div" style="height:1000vh"></div>
|
||||||
|
<div id="below_viewport_div"></div>
|
||||||
|
<img id="below_viewport" src='resources/image.png?below_viewport' loading="lazy">
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const tall_div = document.getElementById("tall_div");
|
||||||
|
const below_viewport_element = document.getElementById("below_viewport");
|
||||||
|
const below_viewport_div = document.getElementById("below_viewport_div");
|
||||||
|
|
||||||
|
async_test(function(t) {
|
||||||
|
below_viewport_element.onload =
|
||||||
|
t.unreached_func("The below viewport image should not load");
|
||||||
|
t.step_timeout(t.step_func_done(), 1000);
|
||||||
|
const iframe = document.createElement('iframe');
|
||||||
|
iframe.setAttribute("style", "display:none");
|
||||||
|
iframe.srcdoc = "<body></body>";
|
||||||
|
iframe.onload = () => {
|
||||||
|
const adopted_img = iframe.contentDocument.adoptNode(below_viewport_element);
|
||||||
|
iframe.contentDocument.body.appendChild(adopted_img);
|
||||||
|
below_viewport_div.scrollIntoView();
|
||||||
|
};
|
||||||
|
document.body.insertBefore(iframe, tall_div);
|
||||||
|
}, "Test that <img> below viewport is not loaded when moved to another " +
|
||||||
|
"document and then scrolled to");
|
||||||
|
</script>
|
||||||
|
</body>
|
|
@ -0,0 +1,36 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<head>
|
||||||
|
<title>Images with loading='lazy' load being removed and then scrolled to</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="common.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Marked as tentative until https://github.com/whatwg/html/pull/3752 is landed.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<img id="in_viewport" src='resources/image.png?in_viewport&pipe=trickle(d1)'>
|
||||||
|
<div style="height:1000vh"></div>
|
||||||
|
<div id="below_viewport_div"></div>
|
||||||
|
<img id="below_viewport" src='resources/image.png?below_viewport' loading="lazy">
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const in_viewport_element = document.getElementById("in_viewport");
|
||||||
|
const below_viewport_element = document.getElementById("below_viewport");
|
||||||
|
const below_viewport_div = document.getElementById("below_viewport_div");
|
||||||
|
|
||||||
|
async_test(t => {
|
||||||
|
below_viewport_element.onload = t.unreached_func("Removed loading=lazy image " +
|
||||||
|
"should not load when its old position is scrolled to.");
|
||||||
|
below_viewport_element.remove();
|
||||||
|
|
||||||
|
in_viewport_element.onload = () => {
|
||||||
|
below_viewport_div.scrollIntoView();
|
||||||
|
t.step_timeout(t.step_func_done(), 2000);
|
||||||
|
};
|
||||||
|
}, "Test that <img> below viewport is not loaded when removed from the " +
|
||||||
|
"document and then scrolled to");
|
||||||
|
</script>
|
||||||
|
</body>
|
|
@ -0,0 +1,4 @@
|
||||||
|
// META: script=/resources/testdriver.js
|
||||||
|
// META: script=resources/test-helpers.js
|
||||||
|
// META: script=resources/native-fs-test-helpers.js
|
||||||
|
// META: script=script-tests/FileSystemWritableFileStream-piped.js
|
|
@ -0,0 +1,4 @@
|
||||||
|
// META: script=/resources/testdriver.js
|
||||||
|
// META: script=resources/test-helpers.js
|
||||||
|
// META: script=resources/native-fs-test-helpers.js
|
||||||
|
// META: script=script-tests/FileSystemWritableFileStream-write.js
|
|
@ -0,0 +1,4 @@
|
||||||
|
// META: script=/resources/testdriver.js
|
||||||
|
// META: script=resources/test-helpers.js
|
||||||
|
// META: script=resources/native-fs-test-helpers.js
|
||||||
|
// META: script=script-tests/FileSystemWritableFileStream.js
|
|
@ -0,0 +1,4 @@
|
||||||
|
// META: script=resources/test-helpers.js
|
||||||
|
// META: script=resources/sandboxed-fs-test-helpers.js
|
||||||
|
// META: script=../streams/resources/recording-streams.js
|
||||||
|
// META: script=script-tests/FileSystemWritableFileStream-piped.js
|
|
@ -0,0 +1,3 @@
|
||||||
|
// META: script=resources/test-helpers.js
|
||||||
|
// META: script=resources/sandboxed-fs-test-helpers.js
|
||||||
|
// META: script=script-tests/FileSystemWritableFileStream-write.js
|
|
@ -0,0 +1,3 @@
|
||||||
|
// META: script=resources/test-helpers.js
|
||||||
|
// META: script=resources/sandboxed-fs-test-helpers.js
|
||||||
|
// META: script=script-tests/FileSystemWritableFileStream.js
|
|
@ -0,0 +1,135 @@
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createEmptyFile(t, 'foo_string.txt', root);
|
||||||
|
const wfs = await handle.createWritable();
|
||||||
|
|
||||||
|
const rs = recordingReadableStream({
|
||||||
|
start(controller) {
|
||||||
|
controller.enqueue('foo_string');
|
||||||
|
controller.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await rs.pipeTo(wfs, { preventCancel: true });
|
||||||
|
assert_equals(await getFileContents(handle), 'foo_string');
|
||||||
|
assert_equals(await getFileSize(handle), 10);
|
||||||
|
}, 'can be piped to with a string');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createEmptyFile(t, 'foo_arraybuf.txt', root);
|
||||||
|
const wfs = await handle.createWritable();
|
||||||
|
const buf = new ArrayBuffer(3);
|
||||||
|
const intView = new Uint8Array(buf);
|
||||||
|
intView[0] = 0x66;
|
||||||
|
intView[1] = 0x6f;
|
||||||
|
intView[2] = 0x6f;
|
||||||
|
|
||||||
|
const rs = recordingReadableStream({
|
||||||
|
start(controller) {
|
||||||
|
controller.enqueue(buf);
|
||||||
|
controller.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await rs.pipeTo(wfs, { preventCancel: true });
|
||||||
|
assert_equals(await getFileContents(handle), 'foo');
|
||||||
|
assert_equals(await getFileSize(handle), 3);
|
||||||
|
}, 'can be piped to with an ArrayBuffer');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createEmptyFile(t, 'foo_blob.txt', root);
|
||||||
|
const wfs = await handle.createWritable();
|
||||||
|
|
||||||
|
const rs = recordingReadableStream({
|
||||||
|
start(controller) {
|
||||||
|
controller.enqueue(new Blob(['foo']));
|
||||||
|
controller.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await rs.pipeTo(wfs, { preventCancel: true });
|
||||||
|
assert_equals(await getFileContents(handle), 'foo');
|
||||||
|
assert_equals(await getFileSize(handle), 3);
|
||||||
|
}, 'can be piped to with a Blob');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createEmptyFile(t, 'foo_write_param.txt', root);
|
||||||
|
const wfs = await handle.createWritable();
|
||||||
|
|
||||||
|
const rs = recordingReadableStream({
|
||||||
|
start(controller) {
|
||||||
|
controller.enqueue({type: 'write', data: 'foobar'});
|
||||||
|
controller.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await rs.pipeTo(wfs, { preventCancel: true });
|
||||||
|
assert_equals(await getFileContents(handle), 'foobar');
|
||||||
|
assert_equals(await getFileSize(handle), 6);
|
||||||
|
}, 'can be piped to with a param object with write command');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createEmptyFile(t, 'foo_write_param.txt', root);
|
||||||
|
const wfs = await handle.createWritable();
|
||||||
|
|
||||||
|
const rs = recordingReadableStream({
|
||||||
|
start(controller) {
|
||||||
|
controller.enqueue({type: 'write', data: 'foobar'});
|
||||||
|
controller.enqueue({type: 'truncate', size: 10});
|
||||||
|
controller.enqueue({type: 'write', position: 0, data: 'baz'});
|
||||||
|
controller.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await rs.pipeTo(wfs, { preventCancel: true });
|
||||||
|
assert_equals(await getFileContents(handle), 'bazbar\0\0\0\0');
|
||||||
|
assert_equals(await getFileSize(handle), 10);
|
||||||
|
}, 'can be piped to with a param object with multiple commands');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createEmptyFile(t, 'foo_write_queued.txt', root);
|
||||||
|
const wfs = await handle.createWritable();
|
||||||
|
|
||||||
|
const rs = recordingReadableStream({
|
||||||
|
start(controller) {
|
||||||
|
controller.enqueue('foo');
|
||||||
|
controller.enqueue('bar');
|
||||||
|
controller.enqueue('baz');
|
||||||
|
controller.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await rs.pipeTo(wfs, { preventCancel: true });
|
||||||
|
assert_equals(await getFileContents(handle), 'foobarbaz');
|
||||||
|
assert_equals(await getFileSize(handle), 9);
|
||||||
|
}, 'multiple operations can be queued');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createEmptyFile(t, 'fetched.txt', root);
|
||||||
|
const wfs = await handle.createWritable();
|
||||||
|
|
||||||
|
const response = await fetch('data:text/plain,fetched from far');
|
||||||
|
const body = await response.body;
|
||||||
|
await body.pipeTo(wfs, { preventCancel: true });
|
||||||
|
assert_equals(await getFileContents(handle), 'fetched from far');
|
||||||
|
assert_equals(await getFileSize(handle), 16);
|
||||||
|
}, 'plays well with fetch');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createEmptyFile(t, 'aborted should_be_empty.txt', root);
|
||||||
|
const wfs = await handle.createWritable();
|
||||||
|
|
||||||
|
const response = await fetch('data:text/plain,fetched from far');
|
||||||
|
const body = await response.body;
|
||||||
|
|
||||||
|
const abortController = new AbortController();
|
||||||
|
const signal = abortController.signal;
|
||||||
|
|
||||||
|
const promise = body.pipeTo(wfs, { signal });
|
||||||
|
await abortController.abort();
|
||||||
|
|
||||||
|
await promise_rejects(t, 'AbortError', promise, 'stream is aborted');
|
||||||
|
await promise_rejects(t, TypeError(), wfs.close(), 'stream cannot be closed to flush writes');
|
||||||
|
|
||||||
|
assert_equals(await getFileContents(handle), '');
|
||||||
|
assert_equals(await getFileSize(handle), 0);
|
||||||
|
}, 'abort() aborts write');
|
|
@ -0,0 +1,337 @@
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createEmptyFile(t, 'empty_blob', root);
|
||||||
|
const stream = await handle.createWritable();
|
||||||
|
|
||||||
|
await stream.write(new Blob([]));
|
||||||
|
await stream.close();
|
||||||
|
|
||||||
|
assert_equals(await getFileContents(handle), '');
|
||||||
|
assert_equals(await getFileSize(handle), 0);
|
||||||
|
}, 'write() with an empty blob to an empty file');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createEmptyFile(t, 'valid_blob', root);
|
||||||
|
const stream = await handle.createWritable();
|
||||||
|
|
||||||
|
await stream.write(new Blob(['1234567890']));
|
||||||
|
await stream.close();
|
||||||
|
|
||||||
|
assert_equals(await getFileContents(handle), '1234567890');
|
||||||
|
assert_equals(await getFileSize(handle), 10);
|
||||||
|
}, 'write() a blob to an empty file');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createEmptyFile(t, 'write_param_empty', root);
|
||||||
|
const stream = await handle.createWritable();
|
||||||
|
|
||||||
|
await stream.write({type: 'write', data: '1234567890'});
|
||||||
|
await stream.close();
|
||||||
|
|
||||||
|
assert_equals(await getFileContents(handle), '1234567890');
|
||||||
|
assert_equals(await getFileSize(handle), 10);
|
||||||
|
}, 'write() with WriteParams without position to an empty file');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createEmptyFile(t, 'string_zero_offset', root);
|
||||||
|
const stream = await handle.createWritable();
|
||||||
|
|
||||||
|
await stream.write({type: 'write', position: 0, data: '1234567890'});
|
||||||
|
await stream.close();
|
||||||
|
|
||||||
|
assert_equals(await getFileContents(handle), '1234567890');
|
||||||
|
assert_equals(await getFileSize(handle), 10);
|
||||||
|
}, 'write() a string to an empty file with zero offset');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createEmptyFile(t, 'blob_zero_offset', root);
|
||||||
|
const stream = await handle.createWritable();
|
||||||
|
|
||||||
|
await stream.write({type: 'write', position: 0, data: new Blob(['1234567890'])});
|
||||||
|
await stream.close();
|
||||||
|
|
||||||
|
assert_equals(await getFileContents(handle), '1234567890');
|
||||||
|
assert_equals(await getFileSize(handle), 10);
|
||||||
|
}, 'write() a blob to an empty file with zero offset');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createEmptyFile(t, 'write_appends', root);
|
||||||
|
const stream = await handle.createWritable();
|
||||||
|
|
||||||
|
await stream.write('12345');
|
||||||
|
await stream.write('67890');
|
||||||
|
await stream.close();
|
||||||
|
|
||||||
|
assert_equals(await getFileContents(handle), '1234567890');
|
||||||
|
assert_equals(await getFileSize(handle), 10);
|
||||||
|
}, 'write() called consecutively appends');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createEmptyFile(t, 'write_appends_object_string', root);
|
||||||
|
const stream = await handle.createWritable();
|
||||||
|
|
||||||
|
await stream.write('12345');
|
||||||
|
await stream.write({type: 'write', data: '67890'});
|
||||||
|
await stream.close();
|
||||||
|
|
||||||
|
assert_equals(await getFileContents(handle), '1234567890');
|
||||||
|
assert_equals(await getFileSize(handle), 10);
|
||||||
|
}, 'write() WriteParams without position and string appends');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createEmptyFile(t, 'write_appends_object_blob', root);
|
||||||
|
const stream = await handle.createWritable();
|
||||||
|
|
||||||
|
await stream.write('12345');
|
||||||
|
await stream.write({type: 'write', data: new Blob(['67890'])});
|
||||||
|
await stream.close();
|
||||||
|
|
||||||
|
assert_equals(await getFileContents(handle), '1234567890');
|
||||||
|
assert_equals(await getFileSize(handle), 10);
|
||||||
|
}, 'write() WriteParams without position and blob appends');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createEmptyFile(t, 'string_with_offset', root);
|
||||||
|
const stream = await handle.createWritable();
|
||||||
|
|
||||||
|
await stream.write('1234567890');
|
||||||
|
await stream.write({type: 'write', position: 4, data: 'abc'});
|
||||||
|
await stream.close();
|
||||||
|
|
||||||
|
assert_equals(await getFileContents(handle), '1234abc890');
|
||||||
|
assert_equals(await getFileSize(handle), 10);
|
||||||
|
}, 'write() called with a string and a valid offset');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createEmptyFile(t, 'blob_with_offset', root);
|
||||||
|
const stream = await handle.createWritable();
|
||||||
|
|
||||||
|
await stream.write('1234567890');
|
||||||
|
await stream.write({type: 'write', position: 4, data: new Blob(['abc'])});
|
||||||
|
await stream.close();
|
||||||
|
|
||||||
|
assert_equals(await getFileContents(handle), '1234abc890');
|
||||||
|
assert_equals(await getFileSize(handle), 10);
|
||||||
|
}, 'write() called with a blob and a valid offset');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createEmptyFile(t, 'bad_offset', root);
|
||||||
|
const stream = await handle.createWritable();
|
||||||
|
|
||||||
|
await promise_rejects(
|
||||||
|
t, 'InvalidStateError', stream.write({type: 'write', position: 4, data: new Blob(['abc'])}));
|
||||||
|
await promise_rejects(
|
||||||
|
t, TypeError(), stream.close(), 'stream is already closed');
|
||||||
|
|
||||||
|
assert_equals(await getFileContents(handle), '');
|
||||||
|
assert_equals(await getFileSize(handle), 0);
|
||||||
|
}, 'write() called with an invalid offset');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createEmptyFile(t, 'empty_string', root);
|
||||||
|
const stream = await handle.createWritable();
|
||||||
|
|
||||||
|
await stream.write('');
|
||||||
|
await stream.close();
|
||||||
|
assert_equals(await getFileContents(handle), '');
|
||||||
|
assert_equals(await getFileSize(handle), 0);
|
||||||
|
}, 'write() with an empty string to an empty file');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createEmptyFile(t, 'valid_utf8_string', root);
|
||||||
|
const stream = await handle.createWritable();
|
||||||
|
|
||||||
|
await stream.write('foo🤘');
|
||||||
|
await stream.close();
|
||||||
|
assert_equals(await getFileContents(handle), 'foo🤘');
|
||||||
|
assert_equals(await getFileSize(handle), 7);
|
||||||
|
}, 'write() with a valid utf-8 string');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createEmptyFile(t, 'string_with_unix_line_ending', root);
|
||||||
|
const stream = await handle.createWritable();
|
||||||
|
|
||||||
|
await stream.write('foo\n');
|
||||||
|
await stream.close();
|
||||||
|
assert_equals(await getFileContents(handle), 'foo\n');
|
||||||
|
assert_equals(await getFileSize(handle), 4);
|
||||||
|
}, 'write() with a string with unix line ending preserved');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle =
|
||||||
|
await createEmptyFile(t, 'string_with_windows_line_ending', root);
|
||||||
|
const stream = await handle.createWritable();
|
||||||
|
|
||||||
|
await stream.write('foo\r\n');
|
||||||
|
await stream.close();
|
||||||
|
assert_equals(await getFileContents(handle), 'foo\r\n');
|
||||||
|
assert_equals(await getFileSize(handle), 5);
|
||||||
|
}, 'write() with a string with windows line ending preserved');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createEmptyFile(t, 'empty_array_buffer', root);
|
||||||
|
const stream = await handle.createWritable();
|
||||||
|
|
||||||
|
const buf = new ArrayBuffer(0);
|
||||||
|
await stream.write(buf);
|
||||||
|
await stream.close();
|
||||||
|
assert_equals(await getFileContents(handle), '');
|
||||||
|
assert_equals(await getFileSize(handle), 0);
|
||||||
|
}, 'write() with an empty array buffer to an empty file');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle =
|
||||||
|
await createEmptyFile(t, 'valid_string_typed_byte_array', root);
|
||||||
|
const stream = await handle.createWritable();
|
||||||
|
|
||||||
|
const buf = new ArrayBuffer(3);
|
||||||
|
const intView = new Uint8Array(buf);
|
||||||
|
intView[0] = 0x66;
|
||||||
|
intView[1] = 0x6f;
|
||||||
|
intView[2] = 0x6f;
|
||||||
|
await stream.write(buf);
|
||||||
|
await stream.close();
|
||||||
|
assert_equals(await getFileContents(handle), 'foo');
|
||||||
|
assert_equals(await getFileSize(handle), 3);
|
||||||
|
}, 'write() with a valid typed array buffer');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const dir = await createDirectory(t, 'parent_dir', root);
|
||||||
|
const file_name = 'close_fails_when_dir_removed.txt';
|
||||||
|
const handle = await createEmptyFile(t, file_name, dir);
|
||||||
|
const stream = await handle.createWritable();
|
||||||
|
await stream.write('foo');
|
||||||
|
|
||||||
|
await root.removeEntry('parent_dir', {recursive: true});
|
||||||
|
await promise_rejects(t, 'NotFoundError', stream.close());
|
||||||
|
}, 'atomic writes: close() fails when parent directory is removed');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createEmptyFile(t, 'atomic_writes.txt', root);
|
||||||
|
const stream = await handle.createWritable();
|
||||||
|
await stream.write('foox');
|
||||||
|
|
||||||
|
const stream2 = await handle.createWritable();
|
||||||
|
await stream2.write('bar');
|
||||||
|
|
||||||
|
assert_equals(await getFileSize(handle), 0);
|
||||||
|
|
||||||
|
await stream2.close();
|
||||||
|
assert_equals(await getFileContents(handle), 'bar');
|
||||||
|
assert_equals(await getFileSize(handle), 3);
|
||||||
|
|
||||||
|
await stream.close();
|
||||||
|
assert_equals(await getFileContents(handle), 'foox');
|
||||||
|
assert_equals(await getFileSize(handle), 4);
|
||||||
|
}, 'atomic writes: writable file streams make atomic changes on close');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createEmptyFile(t, 'atomic_write_after_close.txt', root);
|
||||||
|
const stream = await handle.createWritable();
|
||||||
|
await stream.write('foo');
|
||||||
|
|
||||||
|
await stream.close();
|
||||||
|
assert_equals(await getFileContents(handle), 'foo');
|
||||||
|
assert_equals(await getFileSize(handle), 3);
|
||||||
|
|
||||||
|
await promise_rejects(
|
||||||
|
t, TypeError(), stream.write('abc'));
|
||||||
|
}, 'atomic writes: write() after close() fails');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle =
|
||||||
|
await createEmptyFile(t, 'atomic_truncate_after_close.txt', root);
|
||||||
|
const stream = await handle.createWritable();
|
||||||
|
await stream.write('foo');
|
||||||
|
|
||||||
|
await stream.close();
|
||||||
|
assert_equals(await getFileContents(handle), 'foo');
|
||||||
|
assert_equals(await getFileSize(handle), 3);
|
||||||
|
|
||||||
|
await promise_rejects(t, TypeError(), stream.truncate(0));
|
||||||
|
}, 'atomic writes: truncate() after close() fails');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createEmptyFile(t, 'atomic_close_after_close.txt', root);
|
||||||
|
const stream = await handle.createWritable();
|
||||||
|
await stream.write('foo');
|
||||||
|
|
||||||
|
await stream.close();
|
||||||
|
assert_equals(await getFileContents(handle), 'foo');
|
||||||
|
assert_equals(await getFileSize(handle), 3);
|
||||||
|
|
||||||
|
await promise_rejects(t, TypeError(), stream.close());
|
||||||
|
}, 'atomic writes: close() after close() fails');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createEmptyFile(t, 'there_can_be_only_one.txt', root);
|
||||||
|
const stream = await handle.createWritable();
|
||||||
|
await stream.write('foo');
|
||||||
|
|
||||||
|
// This test might be flaky if there is a race condition allowing
|
||||||
|
// close() to be called multiple times.
|
||||||
|
const success_promises =
|
||||||
|
[...Array(100)].map(() => stream.close().then(() => 1).catch(() => 0));
|
||||||
|
const close_attempts = await Promise.all(success_promises);
|
||||||
|
const success_count = close_attempts.reduce((x, y) => x + y);
|
||||||
|
assert_equals(success_count, 1);
|
||||||
|
}, 'atomic writes: only one close() operation may succeed');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const dir = await createDirectory(t, 'parent_dir', root);
|
||||||
|
const file_name = 'atomic_writable_file_stream_persists_removed.txt';
|
||||||
|
const handle = await createFileWithContents(t, file_name, 'foo', dir);
|
||||||
|
|
||||||
|
const stream = await handle.createWritable();
|
||||||
|
await stream.write('bar');
|
||||||
|
|
||||||
|
await dir.removeEntry(file_name);
|
||||||
|
await promise_rejects(t, 'NotFoundError', getFileContents(handle));
|
||||||
|
|
||||||
|
await stream.close();
|
||||||
|
assert_equals(await getFileContents(handle), 'bar');
|
||||||
|
assert_equals(await getFileSize(handle), 3);
|
||||||
|
}, 'atomic writes: writable file stream persists file on close, even if file is removed');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createEmptyFile(t, 'writer_written', root);
|
||||||
|
const stream = await handle.createWritable();
|
||||||
|
const writer = stream.getWriter();
|
||||||
|
|
||||||
|
await writer.write('foo');
|
||||||
|
await writer.write(new Blob(['bar']));
|
||||||
|
await writer.write({type: 'seek', position: 0});
|
||||||
|
await writer.write({type: 'write', data: 'baz'});
|
||||||
|
await writer.close();
|
||||||
|
|
||||||
|
assert_equals(await getFileContents(handle), 'bazbar');
|
||||||
|
assert_equals(await getFileSize(handle), 6);
|
||||||
|
}, 'getWriter() can be used');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createFileWithContents(
|
||||||
|
t, 'content.txt', 'very long string', root);
|
||||||
|
const stream = await handle.createWritable();
|
||||||
|
|
||||||
|
await promise_rejects(
|
||||||
|
t, SyntaxError(), stream.write({type: 'truncate'}), 'truncate without size');
|
||||||
|
|
||||||
|
}, 'WriteParams: truncate missing size param');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createEmptyFile(t, 'content.txt', root);
|
||||||
|
const stream = await handle.createWritable();
|
||||||
|
|
||||||
|
await promise_rejects(
|
||||||
|
t, SyntaxError(), stream.write({type: 'write'}), 'write without data');
|
||||||
|
|
||||||
|
}, 'WriteParams: write missing data param');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createFileWithContents(
|
||||||
|
t, 'content.txt', 'seekable', root);
|
||||||
|
const stream = await handle.createWritable();
|
||||||
|
|
||||||
|
await promise_rejects(
|
||||||
|
t, SyntaxError(), stream.write({type: 'seek'}), 'seek without position');
|
||||||
|
|
||||||
|
}, 'WriteParams: seek missing position param');
|
|
@ -0,0 +1,117 @@
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createEmptyFile(t, 'trunc_shrink', root);
|
||||||
|
const stream = await handle.createWritable();
|
||||||
|
|
||||||
|
await stream.write('1234567890');
|
||||||
|
await stream.truncate(5);
|
||||||
|
await stream.close();
|
||||||
|
|
||||||
|
assert_equals(await getFileContents(handle), '12345');
|
||||||
|
assert_equals(await getFileSize(handle), 5);
|
||||||
|
}, 'truncate() to shrink a file');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createEmptyFile(t, 'trunc_grow', root);
|
||||||
|
const stream = await handle.createWritable();
|
||||||
|
|
||||||
|
await stream.write('abc');
|
||||||
|
await stream.truncate(5);
|
||||||
|
await stream.close();
|
||||||
|
|
||||||
|
assert_equals(await getFileContents(handle), 'abc\0\0');
|
||||||
|
assert_equals(await getFileSize(handle), 5);
|
||||||
|
}, 'truncate() to grow a file');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const dir = await createDirectory(t, 'parent_dir', root);
|
||||||
|
const file_name = 'create_writable_fails_when_dir_removed.txt';
|
||||||
|
const handle = await createEmptyFile(t, file_name, dir);
|
||||||
|
|
||||||
|
await root.removeEntry('parent_dir', {recursive: true});
|
||||||
|
await promise_rejects(t, 'NotFoundError', handle.createWritable());
|
||||||
|
}, 'createWritable() fails when parent directory is removed');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const dir = await createDirectory(t, 'parent_dir', root);
|
||||||
|
const file_name = 'write_fails_when_dir_removed.txt';
|
||||||
|
const handle = await createEmptyFile(t, file_name, dir);
|
||||||
|
const stream = await handle.createWritable();
|
||||||
|
|
||||||
|
await root.removeEntry('parent_dir', {recursive: true});
|
||||||
|
await promise_rejects(t, 'NotFoundError', stream.write('foo'));
|
||||||
|
}, 'write() fails when parent directory is removed');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const dir = await createDirectory(t, 'parent_dir', root);
|
||||||
|
const file_name = 'truncate_fails_when_dir_removed.txt';
|
||||||
|
const handle = await createEmptyFile(t, file_name, dir);
|
||||||
|
const stream = await handle.createWritable();
|
||||||
|
|
||||||
|
await root.removeEntry('parent_dir', {recursive: true});
|
||||||
|
await promise_rejects(t, 'NotFoundError', stream.truncate(0));
|
||||||
|
}, 'truncate() fails when parent directory is removed');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createFileWithContents(
|
||||||
|
t, 'atomic_file_is_copied.txt', 'fooks', root);
|
||||||
|
const stream = await handle.createWritable({keepExistingData: true});
|
||||||
|
|
||||||
|
await stream.write('bar');
|
||||||
|
await stream.close();
|
||||||
|
assert_equals(await getFileContents(handle), 'barks');
|
||||||
|
assert_equals(await getFileSize(handle), 5);
|
||||||
|
}, 'createWritable({keepExistingData: true}): atomic writable file stream initialized with source contents');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createFileWithContents(
|
||||||
|
t, 'atomic_file_is_not_copied.txt', 'very long string', root);
|
||||||
|
const stream = await handle.createWritable({keepExistingData: false});
|
||||||
|
|
||||||
|
await stream.write('bar');
|
||||||
|
assert_equals(await getFileContents(handle), 'very long string');
|
||||||
|
await stream.close();
|
||||||
|
assert_equals(await getFileContents(handle), 'bar');
|
||||||
|
assert_equals(await getFileSize(handle), 3);
|
||||||
|
}, 'createWritable({keepExistingData: false}): atomic writable file stream initialized with empty file');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createFileWithContents(
|
||||||
|
t, 'trunc_smaller_offset.txt', '1234567890', root);
|
||||||
|
const stream = await handle.createWritable({keepExistingData: true});
|
||||||
|
|
||||||
|
await stream.truncate(5);
|
||||||
|
await stream.write('abc');
|
||||||
|
await stream.close();
|
||||||
|
|
||||||
|
assert_equals(await getFileContents(handle), 'abc45');
|
||||||
|
assert_equals(await getFileSize(handle), 5);
|
||||||
|
}, 'cursor position: truncate size > offset');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createFileWithContents(
|
||||||
|
t, 'trunc_bigger_offset.txt', '1234567890', root);
|
||||||
|
const stream = await handle.createWritable({keepExistingData: true});
|
||||||
|
|
||||||
|
await stream.seek(6);
|
||||||
|
await stream.truncate(5);
|
||||||
|
await stream.write('abc');
|
||||||
|
await stream.close();
|
||||||
|
|
||||||
|
assert_equals(await getFileContents(handle), '12345abc');
|
||||||
|
assert_equals(await getFileSize(handle), 8);
|
||||||
|
}, 'cursor position: truncate size < offset');
|
||||||
|
|
||||||
|
directory_test(async (t, root) => {
|
||||||
|
const handle = await createEmptyFile(t, 'contents', root);
|
||||||
|
const stream = await handle.createWritable();
|
||||||
|
|
||||||
|
stream.write('abc');
|
||||||
|
stream.write('def');
|
||||||
|
stream.truncate(9);
|
||||||
|
stream.seek(0);
|
||||||
|
stream.write('xyz');
|
||||||
|
await stream.close();
|
||||||
|
|
||||||
|
assert_equals(await getFileContents(handle), 'xyzdef\0\0\0');
|
||||||
|
assert_equals(await getFileSize(handle), 9);
|
||||||
|
}, 'commands are queued');
|
|
@ -1,3 +1,3 @@
|
||||||
mypy==0.760
|
mypy==0.761
|
||||||
mypy-extensions==0.4.3
|
mypy-extensions==0.4.3
|
||||||
typed-ast==1.4.0
|
typed-ast==1.4.0
|
||||||
|
|
|
@ -3,6 +3,7 @@ import platform
|
||||||
import socket
|
import socket
|
||||||
from abc import ABCMeta, abstractmethod
|
from abc import ABCMeta, abstractmethod
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
|
from six import iteritems
|
||||||
|
|
||||||
from ..wptcommandline import require_arg # noqa: F401
|
from ..wptcommandline import require_arg # noqa: F401
|
||||||
|
|
||||||
|
@ -199,5 +200,5 @@ class ExecutorBrowser(object):
|
||||||
up the browser from the runner process.
|
up the browser from the runner process.
|
||||||
"""
|
"""
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
for k, v in kwargs.iteritems():
|
for k, v in iteritems(kwargs):
|
||||||
setattr(self, k, v)
|
setattr(self, k, v)
|
||||||
|
|
|
@ -2,7 +2,8 @@ from .base import get_timeout_multiplier, maybe_add_args, certificate_domain_lis
|
||||||
from .webkit import WebKitBrowser
|
from .webkit import WebKitBrowser
|
||||||
from ..executors import executor_kwargs as base_executor_kwargs
|
from ..executors import executor_kwargs as base_executor_kwargs
|
||||||
from ..executors.executorwebdriver import (WebDriverTestharnessExecutor, # noqa: F401
|
from ..executors.executorwebdriver import (WebDriverTestharnessExecutor, # noqa: F401
|
||||||
WebDriverRefTestExecutor) # noqa: F401
|
WebDriverRefTestExecutor, # noqa: F401
|
||||||
|
WebDriverCrashtestExecutor) # noqa: F401
|
||||||
from ..executors.executorwebkit import WebKitDriverWdspecExecutor # noqa: F401
|
from ..executors.executorwebkit import WebKitDriverWdspecExecutor # noqa: F401
|
||||||
|
|
||||||
__wptrunner__ = {"product": "epiphany",
|
__wptrunner__ = {"product": "epiphany",
|
||||||
|
@ -11,7 +12,8 @@ __wptrunner__ = {"product": "epiphany",
|
||||||
"browser_kwargs": "browser_kwargs",
|
"browser_kwargs": "browser_kwargs",
|
||||||
"executor": {"testharness": "WebDriverTestharnessExecutor",
|
"executor": {"testharness": "WebDriverTestharnessExecutor",
|
||||||
"reftest": "WebDriverRefTestExecutor",
|
"reftest": "WebDriverRefTestExecutor",
|
||||||
"wdspec": "WebKitDriverWdspecExecutor"},
|
"wdspec": "WebKitDriverWdspecExecutor",
|
||||||
|
"crashtest": "WebDriverCrashtestExecutor"},
|
||||||
"executor_kwargs": "executor_kwargs",
|
"executor_kwargs": "executor_kwargs",
|
||||||
"env_extras": "env_extras",
|
"env_extras": "env_extras",
|
||||||
"env_options": "env_options",
|
"env_options": "env_options",
|
||||||
|
|
|
@ -2,7 +2,8 @@ from .base import Browser, ExecutorBrowser, require_arg
|
||||||
from .base import get_timeout_multiplier, certificate_domain_list # noqa: F401
|
from .base import get_timeout_multiplier, certificate_domain_list # noqa: F401
|
||||||
from ..executors import executor_kwargs as base_executor_kwargs
|
from ..executors import executor_kwargs as base_executor_kwargs
|
||||||
from ..executors.executorwebdriver import (WebDriverTestharnessExecutor, # noqa: F401
|
from ..executors.executorwebdriver import (WebDriverTestharnessExecutor, # noqa: F401
|
||||||
WebDriverRefTestExecutor) # noqa: F401
|
WebDriverRefTestExecutor, # noqa: F401
|
||||||
|
WebDriverCrashtestExecutor) # noqa: F401
|
||||||
from ..executors.executorwebkit import WebKitDriverWdspecExecutor # noqa: F401
|
from ..executors.executorwebkit import WebKitDriverWdspecExecutor # noqa: F401
|
||||||
from ..webdriver_server import WebKitDriverServer
|
from ..webdriver_server import WebKitDriverServer
|
||||||
|
|
||||||
|
@ -13,7 +14,8 @@ __wptrunner__ = {"product": "webkit",
|
||||||
"browser_kwargs": "browser_kwargs",
|
"browser_kwargs": "browser_kwargs",
|
||||||
"executor": {"testharness": "WebDriverTestharnessExecutor",
|
"executor": {"testharness": "WebDriverTestharnessExecutor",
|
||||||
"reftest": "WebDriverRefTestExecutor",
|
"reftest": "WebDriverRefTestExecutor",
|
||||||
"wdspec": "WebKitDriverWdspecExecutor"},
|
"wdspec": "WebKitDriverWdspecExecutor",
|
||||||
|
"crashtest": "WebDriverCrashtestExecutor"},
|
||||||
"executor_kwargs": "executor_kwargs",
|
"executor_kwargs": "executor_kwargs",
|
||||||
"env_extras": "env_extras",
|
"env_extras": "env_extras",
|
||||||
"env_options": "env_options",
|
"env_options": "env_options",
|
||||||
|
|
|
@ -2,7 +2,8 @@ from .base import get_timeout_multiplier, maybe_add_args, certificate_domain_lis
|
||||||
from .webkit import WebKitBrowser
|
from .webkit import WebKitBrowser
|
||||||
from ..executors import executor_kwargs as base_executor_kwargs
|
from ..executors import executor_kwargs as base_executor_kwargs
|
||||||
from ..executors.executorwebdriver import (WebDriverTestharnessExecutor, # noqa: F401
|
from ..executors.executorwebdriver import (WebDriverTestharnessExecutor, # noqa: F401
|
||||||
WebDriverRefTestExecutor) # noqa: F401
|
WebDriverRefTestExecutor, # noqa: F401
|
||||||
|
WebDriverCrashtestExecutor) # noqa: F401
|
||||||
from ..executors.executorwebkit import WebKitDriverWdspecExecutor # noqa: F401
|
from ..executors.executorwebkit import WebKitDriverWdspecExecutor # noqa: F401
|
||||||
|
|
||||||
__wptrunner__ = {"product": "webkitgtk_minibrowser",
|
__wptrunner__ = {"product": "webkitgtk_minibrowser",
|
||||||
|
@ -11,7 +12,8 @@ __wptrunner__ = {"product": "webkitgtk_minibrowser",
|
||||||
"browser_kwargs": "browser_kwargs",
|
"browser_kwargs": "browser_kwargs",
|
||||||
"executor": {"testharness": "WebDriverTestharnessExecutor",
|
"executor": {"testharness": "WebDriverTestharnessExecutor",
|
||||||
"reftest": "WebDriverRefTestExecutor",
|
"reftest": "WebDriverRefTestExecutor",
|
||||||
"wdspec": "WebKitDriverWdspecExecutor"},
|
"wdspec": "WebKitDriverWdspecExecutor",
|
||||||
|
"crashtest": "WebDriverCrashtestExecutor"},
|
||||||
"executor_kwargs": "executor_kwargs",
|
"executor_kwargs": "executor_kwargs",
|
||||||
"env_extras": "env_extras",
|
"env_extras": "env_extras",
|
||||||
"env_options": "env_options",
|
"env_options": "env_options",
|
||||||
|
|
|
@ -5,6 +5,7 @@ import signal
|
||||||
import socket
|
import socket
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
from six import iteritems
|
||||||
|
|
||||||
from mozlog import get_default_logger, handlers, proxy
|
from mozlog import get_default_logger, handlers, proxy
|
||||||
|
|
||||||
|
@ -98,7 +99,7 @@ class TestEnvironment(object):
|
||||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||||
self.process_interrupts()
|
self.process_interrupts()
|
||||||
|
|
||||||
for scheme, servers in self.servers.iteritems():
|
for scheme, servers in iteritems(self.servers):
|
||||||
for port, server in servers:
|
for port, server in servers:
|
||||||
server.kill()
|
server.kill()
|
||||||
for cm in self.env_extras_cms:
|
for cm in self.env_extras_cms:
|
||||||
|
@ -194,7 +195,7 @@ class TestEnvironment(object):
|
||||||
route_builder.add_handler(b"GET", b"/resources/testdriver.js",
|
route_builder.add_handler(b"GET", b"/resources/testdriver.js",
|
||||||
StringHandler(data, "text/javascript"))
|
StringHandler(data, "text/javascript"))
|
||||||
|
|
||||||
for url_base, paths in self.test_paths.iteritems():
|
for url_base, paths in iteritems(self.test_paths):
|
||||||
if url_base == "/":
|
if url_base == "/":
|
||||||
continue
|
continue
|
||||||
route_builder.add_mount_point(url_base, paths["tests_path"])
|
route_builder.add_mount_point(url_base, paths["tests_path"])
|
||||||
|
@ -220,7 +221,7 @@ class TestEnvironment(object):
|
||||||
def test_servers(self):
|
def test_servers(self):
|
||||||
failed = []
|
failed = []
|
||||||
host = self.config["server_host"]
|
host = self.config["server_host"]
|
||||||
for scheme, servers in self.servers.iteritems():
|
for scheme, servers in iteritems(self.servers):
|
||||||
for port, server in servers:
|
for port, server in servers:
|
||||||
if self.test_server_port:
|
if self.test_server_port:
|
||||||
s = socket.socket()
|
s = socket.socket()
|
||||||
|
|
|
@ -7,6 +7,7 @@ import tempfile
|
||||||
import threading
|
import threading
|
||||||
import traceback
|
import traceback
|
||||||
import uuid
|
import uuid
|
||||||
|
from six import iteritems
|
||||||
|
|
||||||
from mozprocess import ProcessHandler
|
from mozprocess import ProcessHandler
|
||||||
|
|
||||||
|
@ -45,7 +46,7 @@ def build_servo_command(test, test_url_func, browser, binary, pause_after_test,
|
||||||
args += ["-Z", debug_opts]
|
args += ["-Z", debug_opts]
|
||||||
for stylesheet in browser.user_stylesheets:
|
for stylesheet in browser.user_stylesheets:
|
||||||
args += ["--user-stylesheet", stylesheet]
|
args += ["--user-stylesheet", stylesheet]
|
||||||
for pref, value in test.environment.get('prefs', {}).iteritems():
|
for pref, value in iteritems(test.environment.get('prefs', {})):
|
||||||
args += ["--pref", "%s=%s" % (pref, value)]
|
args += ["--pref", "%s=%s" % (pref, value)]
|
||||||
if browser.ca_certificate_path:
|
if browser.ca_certificate_path:
|
||||||
args += ["--certificate-path", browser.ca_certificate_path]
|
args += ["--certificate-path", browser.ca_certificate_path]
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from math import log
|
from math import log
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
from six import iteritems, itervalues
|
||||||
|
|
||||||
class Node(object):
|
class Node(object):
|
||||||
def __init__(self, prop, value):
|
def __init__(self, prop, value):
|
||||||
|
@ -33,7 +34,7 @@ def entropy(results):
|
||||||
|
|
||||||
result_counts = defaultdict(int)
|
result_counts = defaultdict(int)
|
||||||
total = float(len(results))
|
total = float(len(results))
|
||||||
for values in results.itervalues():
|
for values in itervalues(results):
|
||||||
# Not sure this is right, possibly want to treat multiple values as
|
# Not sure this is right, possibly want to treat multiple values as
|
||||||
# distinct from multiple of the same value?
|
# distinct from multiple of the same value?
|
||||||
for value in values:
|
for value in values:
|
||||||
|
@ -41,7 +42,7 @@ def entropy(results):
|
||||||
|
|
||||||
entropy_sum = 0
|
entropy_sum = 0
|
||||||
|
|
||||||
for count in result_counts.itervalues():
|
for count in itervalues(result_counts):
|
||||||
prop = float(count) / total
|
prop = float(count) / total
|
||||||
entropy_sum -= prop * log(prop, 2)
|
entropy_sum -= prop * log(prop, 2)
|
||||||
|
|
||||||
|
@ -52,7 +53,7 @@ def split_results(prop, results):
|
||||||
"""Split a dictionary of results into a dictionary of dictionaries where
|
"""Split a dictionary of results into a dictionary of dictionaries where
|
||||||
each sub-dictionary has a specific value of the given property"""
|
each sub-dictionary has a specific value of the given property"""
|
||||||
by_prop = defaultdict(dict)
|
by_prop = defaultdict(dict)
|
||||||
for run_info, value in results.iteritems():
|
for run_info, value in iteritems(results):
|
||||||
by_prop[run_info[prop]][run_info] = value
|
by_prop[run_info[prop]][run_info] = value
|
||||||
|
|
||||||
return by_prop
|
return by_prop
|
||||||
|
@ -77,13 +78,13 @@ def build_tree(properties, dependent_props, results, tree=None):
|
||||||
prop_index = {prop: i for i, prop in enumerate(properties)}
|
prop_index = {prop: i for i, prop in enumerate(properties)}
|
||||||
|
|
||||||
all_results = defaultdict(int)
|
all_results = defaultdict(int)
|
||||||
for result_values in results.itervalues():
|
for result_values in itervalues(results):
|
||||||
for result_value, count in result_values.iteritems():
|
for result_value, count in iteritems(result_values):
|
||||||
all_results[result_value] += count
|
all_results[result_value] += count
|
||||||
|
|
||||||
# If there is only one result we are done
|
# If there is only one result we are done
|
||||||
if not properties or len(all_results) == 1:
|
if not properties or len(all_results) == 1:
|
||||||
for value, count in all_results.iteritems():
|
for value, count in iteritems(all_results):
|
||||||
tree.result_values[value] += count
|
tree.result_values[value] += count
|
||||||
tree.run_info |= set(results.keys())
|
tree.run_info |= set(results.keys())
|
||||||
return tree
|
return tree
|
||||||
|
@ -99,7 +100,7 @@ def build_tree(properties, dependent_props, results, tree=None):
|
||||||
continue
|
continue
|
||||||
new_entropy = 0.
|
new_entropy = 0.
|
||||||
results_sets_entropy = []
|
results_sets_entropy = []
|
||||||
for prop_value, result_set in result_sets.iteritems():
|
for prop_value, result_set in iteritems(result_sets):
|
||||||
results_sets_entropy.append((entropy(result_set), prop_value, result_set))
|
results_sets_entropy.append((entropy(result_set), prop_value, result_set))
|
||||||
new_entropy += (float(len(result_set)) / len(results)) * results_sets_entropy[-1][0]
|
new_entropy += (float(len(result_set)) / len(results)) * results_sets_entropy[-1][0]
|
||||||
|
|
||||||
|
@ -109,7 +110,7 @@ def build_tree(properties, dependent_props, results, tree=None):
|
||||||
|
|
||||||
# In the case that no properties partition the space
|
# In the case that no properties partition the space
|
||||||
if not results_partitions:
|
if not results_partitions:
|
||||||
for value, count in all_results.iteritems():
|
for value, count in iteritems(all_results):
|
||||||
tree.result_values[value] += count
|
tree.result_values[value] += count
|
||||||
tree.run_info |= set(results.keys())
|
tree.run_info |= set(results.keys())
|
||||||
return tree
|
return tree
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import os
|
import os
|
||||||
from six.moves.urllib.parse import urljoin
|
from six.moves.urllib.parse import urljoin
|
||||||
from collections import deque
|
from collections import deque
|
||||||
|
from six import text_type
|
||||||
|
|
||||||
from .wptmanifest.backends import static
|
from .wptmanifest.backends import static
|
||||||
from .wptmanifest.backends.base import ManifestItem
|
from .wptmanifest.backends.base import ManifestItem
|
||||||
|
@ -57,7 +58,7 @@ def tags(node):
|
||||||
"""Set of tags that have been applied to the test"""
|
"""Set of tags that have been applied to the test"""
|
||||||
try:
|
try:
|
||||||
value = node.get("tags")
|
value = node.get("tags")
|
||||||
if isinstance(value, (str, unicode)):
|
if isinstance(value, text_type):
|
||||||
return {value}
|
return {value}
|
||||||
return set(value)
|
return set(value)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
@ -66,7 +67,7 @@ def tags(node):
|
||||||
|
|
||||||
def prefs(node):
|
def prefs(node):
|
||||||
def value(ini_value):
|
def value(ini_value):
|
||||||
if isinstance(ini_value, (str, unicode)):
|
if isinstance(ini_value, text_type):
|
||||||
return tuple(pref_piece.strip() for pref_piece in ini_value.split(':', 1))
|
return tuple(pref_piece.strip() for pref_piece in ini_value.split(':', 1))
|
||||||
else:
|
else:
|
||||||
# this should be things like @Reset, which are apparently type 'object'
|
# this should be things like @Reset, which are apparently type 'object'
|
||||||
|
@ -74,7 +75,7 @@ def prefs(node):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
node_prefs = node.get("prefs")
|
node_prefs = node.get("prefs")
|
||||||
if type(node_prefs) in (str, unicode):
|
if isinstance(node_prefs, text_type):
|
||||||
rv = dict(value(node_prefs))
|
rv = dict(value(node_prefs))
|
||||||
else:
|
else:
|
||||||
rv = dict(value(item) for item in node_prefs)
|
rv = dict(value(item) for item in node_prefs)
|
||||||
|
@ -86,7 +87,7 @@ def prefs(node):
|
||||||
def set_prop(name, node):
|
def set_prop(name, node):
|
||||||
try:
|
try:
|
||||||
node_items = node.get(name)
|
node_items = node.get(name)
|
||||||
if isinstance(node_items, (str, unicode)):
|
if isinstance(node_items, text_type):
|
||||||
rv = {node_items}
|
rv = {node_items}
|
||||||
else:
|
else:
|
||||||
rv = set(node_items)
|
rv = set(node_items)
|
||||||
|
@ -99,7 +100,7 @@ def leak_threshold(node):
|
||||||
rv = {}
|
rv = {}
|
||||||
try:
|
try:
|
||||||
node_items = node.get("leak-threshold")
|
node_items = node.get("leak-threshold")
|
||||||
if isinstance(node_items, (str, unicode)):
|
if isinstance(node_items, text_type):
|
||||||
node_items = [node_items]
|
node_items = [node_items]
|
||||||
for item in node_items:
|
for item in node_items:
|
||||||
process, value = item.rsplit(":", 1)
|
process, value = item.rsplit(":", 1)
|
||||||
|
@ -156,7 +157,7 @@ def fuzzy_prop(node):
|
||||||
if not isinstance(value, list):
|
if not isinstance(value, list):
|
||||||
value = [value]
|
value = [value]
|
||||||
for item in value:
|
for item in value:
|
||||||
if not isinstance(item, (str, unicode)):
|
if not isinstance(item, text_type):
|
||||||
rv.append(item)
|
rv.append(item)
|
||||||
continue
|
continue
|
||||||
parts = item.rsplit(":", 1)
|
parts = item.rsplit(":", 1)
|
||||||
|
@ -478,7 +479,7 @@ def get_manifest(metadata_root, test_path, url_base, run_info):
|
||||||
"""
|
"""
|
||||||
manifest_path = expected.expected_path(metadata_root, test_path)
|
manifest_path = expected.expected_path(metadata_root, test_path)
|
||||||
try:
|
try:
|
||||||
with open(manifest_path) as f:
|
with open(manifest_path, "rb") as f:
|
||||||
return static.compile(f,
|
return static.compile(f,
|
||||||
run_info,
|
run_info,
|
||||||
data_cls_getter=data_cls_getter,
|
data_cls_getter=data_cls_getter,
|
||||||
|
@ -497,7 +498,7 @@ def get_dir_manifest(path, run_info):
|
||||||
values should be computed.
|
values should be computed.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
with open(path) as f:
|
with open(path, "rb") as f:
|
||||||
return static.compile(f,
|
return static.compile(f,
|
||||||
run_info,
|
run_info,
|
||||||
data_cls_getter=lambda x,y: DirectoryManifest)
|
data_cls_getter=lambda x,y: DirectoryManifest)
|
||||||
|
|
|
@ -150,5 +150,5 @@ class IncludeManifest(ManifestItem):
|
||||||
|
|
||||||
|
|
||||||
def get_manifest(manifest_path):
|
def get_manifest(manifest_path):
|
||||||
with open(manifest_path) as f:
|
with open(manifest_path, "rb") as f:
|
||||||
return conditional.compile(f, data_cls_getter=lambda x, y: IncludeManifest)
|
return conditional.compile(f, data_cls_getter=lambda x, y: IncludeManifest)
|
||||||
|
|
|
@ -3,7 +3,7 @@ import os
|
||||||
from six.moves.urllib.parse import urljoin, urlsplit
|
from six.moves.urllib.parse import urljoin, urlsplit
|
||||||
from collections import namedtuple, defaultdict, deque
|
from collections import namedtuple, defaultdict, deque
|
||||||
from math import ceil
|
from math import ceil
|
||||||
from six import iterkeys, itervalues, iteritems
|
from six import integer_types, iterkeys, itervalues, iteritems, string_types, text_type
|
||||||
|
|
||||||
from .wptmanifest import serialize
|
from .wptmanifest import serialize
|
||||||
from .wptmanifest.node import (DataNode, ConditionalNode, BinaryExpressionNode,
|
from .wptmanifest.node import (DataNode, ConditionalNode, BinaryExpressionNode,
|
||||||
|
@ -411,7 +411,7 @@ class PropertyUpdate(object):
|
||||||
for e in errors:
|
for e in errors:
|
||||||
if disable_intermittent:
|
if disable_intermittent:
|
||||||
condition = e.cond.children[0] if e.cond else None
|
condition = e.cond.children[0] if e.cond else None
|
||||||
msg = disable_intermittent if isinstance(disable_intermittent, (str, unicode)) else "unstable"
|
msg = disable_intermittent if isinstance(disable_intermittent, string_types+(text_type,)) else "unstable"
|
||||||
self.node.set("disabled", msg, condition)
|
self.node.set("disabled", msg, condition)
|
||||||
self.node.new_disabled = True
|
self.node.new_disabled = True
|
||||||
else:
|
else:
|
||||||
|
@ -774,7 +774,7 @@ class AppendOnlyListUpdate(PropertyUpdate):
|
||||||
for item in new:
|
for item in new:
|
||||||
if item is None:
|
if item is None:
|
||||||
continue
|
continue
|
||||||
elif isinstance(item, (str, unicode)):
|
elif isinstance(item, text_type):
|
||||||
rv.add(item)
|
rv.add(item)
|
||||||
else:
|
else:
|
||||||
rv |= item
|
rv |= item
|
||||||
|
@ -897,10 +897,10 @@ def make_expr(prop_set, rhs):
|
||||||
|
|
||||||
|
|
||||||
def make_node(value):
|
def make_node(value):
|
||||||
if type(value) in (int, float, long):
|
if isinstance(value, integer_types+(float,)):
|
||||||
node = NumberNode(value)
|
node = NumberNode(value)
|
||||||
elif type(value) in (str, unicode):
|
elif isinstance(value, text_type):
|
||||||
node = StringNode(unicode(value))
|
node = StringNode(text_type(value))
|
||||||
elif hasattr(value, "__iter__"):
|
elif hasattr(value, "__iter__"):
|
||||||
node = ListNode()
|
node = ListNode()
|
||||||
for item in value:
|
for item in value:
|
||||||
|
@ -909,10 +909,10 @@ def make_node(value):
|
||||||
|
|
||||||
|
|
||||||
def make_value_node(value):
|
def make_value_node(value):
|
||||||
if type(value) in (int, float, long):
|
if isinstance(value, integer_types+(float,)):
|
||||||
node = ValueNode(value)
|
node = ValueNode(value)
|
||||||
elif type(value) in (str, unicode):
|
elif isinstance(value, text_type):
|
||||||
node = ValueNode(unicode(value))
|
node = ValueNode(text_type(value))
|
||||||
elif hasattr(value, "__iter__"):
|
elif hasattr(value, "__iter__"):
|
||||||
node = ListNode()
|
node = ListNode()
|
||||||
for item in value:
|
for item in value:
|
||||||
|
|
|
@ -4,7 +4,7 @@ import os
|
||||||
from collections import defaultdict, namedtuple
|
from collections import defaultdict, namedtuple
|
||||||
|
|
||||||
from mozlog import structuredlog
|
from mozlog import structuredlog
|
||||||
from six import itervalues
|
from six import ensure_str, ensure_text, iteritems, iterkeys, itervalues, text_type
|
||||||
from six.moves import intern
|
from six.moves import intern
|
||||||
|
|
||||||
from . import manifestupdate
|
from . import manifestupdate
|
||||||
|
@ -44,11 +44,11 @@ class RunInfo(object):
|
||||||
return self.canonical_repr == other.canonical_repr
|
return self.canonical_repr == other.canonical_repr
|
||||||
|
|
||||||
def iteritems(self):
|
def iteritems(self):
|
||||||
for key, value in self.data.iteritems():
|
for key, value in iteritems(self.data):
|
||||||
yield key, value
|
yield key, value
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
return list(self.iteritems())
|
return list(iteritems(self))
|
||||||
|
|
||||||
|
|
||||||
def update_expected(test_paths, serve_root, log_file_names,
|
def update_expected(test_paths, serve_root, log_file_names,
|
||||||
|
@ -239,7 +239,7 @@ def pack_result(data):
|
||||||
def unpack_result(data):
|
def unpack_result(data):
|
||||||
if isinstance(data, int):
|
if isinstance(data, int):
|
||||||
return (status_intern.get(data), None)
|
return (status_intern.get(data), None)
|
||||||
if isinstance(data, unicode):
|
if isinstance(data, text_type):
|
||||||
return (data, None)
|
return (data, None)
|
||||||
# Unpack multiple statuses into a tuple to be used in the Results named tuple below,
|
# Unpack multiple statuses into a tuple to be used in the Results named tuple below,
|
||||||
# separating `status` and `known_intermittent`.
|
# separating `status` and `known_intermittent`.
|
||||||
|
@ -289,7 +289,7 @@ def update_results(id_test_map,
|
||||||
test_file_items = set(itervalues(id_test_map))
|
test_file_items = set(itervalues(id_test_map))
|
||||||
|
|
||||||
default_expected_by_type = {}
|
default_expected_by_type = {}
|
||||||
for test_type, test_cls in wpttest.manifest_test_cls.iteritems():
|
for test_type, test_cls in iteritems(wpttest.manifest_test_cls):
|
||||||
if test_cls.result_cls:
|
if test_cls.result_cls:
|
||||||
default_expected_by_type[(test_type, False)] = test_cls.result_cls.default_expected
|
default_expected_by_type[(test_type, False)] = test_cls.result_cls.default_expected
|
||||||
if test_cls.subtest_result_cls:
|
if test_cls.subtest_result_cls:
|
||||||
|
@ -427,7 +427,7 @@ class ExpectedUpdater(object):
|
||||||
action_map["lsan_leak"](item)
|
action_map["lsan_leak"](item)
|
||||||
|
|
||||||
mozleak_data = data.get("mozleak", {})
|
mozleak_data = data.get("mozleak", {})
|
||||||
for scope, scope_data in mozleak_data.iteritems():
|
for scope, scope_data in iteritems(mozleak_data):
|
||||||
for key, action in [("objects", "mozleak_object"),
|
for key, action in [("objects", "mozleak_object"),
|
||||||
("total", "mozleak_total")]:
|
("total", "mozleak_total")]:
|
||||||
for item in scope_data.get(key, []):
|
for item in scope_data.get(key, []):
|
||||||
|
@ -439,7 +439,7 @@ class ExpectedUpdater(object):
|
||||||
self.run_info = run_info_intern.store(RunInfo(data["run_info"]))
|
self.run_info = run_info_intern.store(RunInfo(data["run_info"]))
|
||||||
|
|
||||||
def test_start(self, data):
|
def test_start(self, data):
|
||||||
test_id = intern(data["test"].encode("utf8"))
|
test_id = intern(ensure_str(data["test"]))
|
||||||
try:
|
try:
|
||||||
self.id_test_map[test_id]
|
self.id_test_map[test_id]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
@ -449,8 +449,8 @@ class ExpectedUpdater(object):
|
||||||
self.tests_visited[test_id] = set()
|
self.tests_visited[test_id] = set()
|
||||||
|
|
||||||
def test_status(self, data):
|
def test_status(self, data):
|
||||||
test_id = intern(data["test"].encode("utf8"))
|
test_id = intern(ensure_str(data["test"]))
|
||||||
subtest = intern(data["subtest"].encode("utf8"))
|
subtest = intern(ensure_str(data["subtest"]))
|
||||||
test_data = self.id_test_map.get(test_id)
|
test_data = self.id_test_map.get(test_id)
|
||||||
if test_data is None:
|
if test_data is None:
|
||||||
return
|
return
|
||||||
|
@ -467,7 +467,7 @@ class ExpectedUpdater(object):
|
||||||
if data["status"] == "SKIP":
|
if data["status"] == "SKIP":
|
||||||
return
|
return
|
||||||
|
|
||||||
test_id = intern(data["test"].encode("utf8"))
|
test_id = intern(ensure_str(data["test"]))
|
||||||
test_data = self.id_test_map.get(test_id)
|
test_data = self.id_test_map.get(test_id)
|
||||||
if test_data is None:
|
if test_data is None:
|
||||||
return
|
return
|
||||||
|
@ -480,7 +480,7 @@ class ExpectedUpdater(object):
|
||||||
del self.tests_visited[test_id]
|
del self.tests_visited[test_id]
|
||||||
|
|
||||||
def assertion_count(self, data):
|
def assertion_count(self, data):
|
||||||
test_id = intern(data["test"].encode("utf8"))
|
test_id = intern(ensure_str(data["test"]))
|
||||||
test_data = self.id_test_map.get(test_id)
|
test_data = self.id_test_map.get(test_id)
|
||||||
if test_data is None:
|
if test_data is None:
|
||||||
return
|
return
|
||||||
|
@ -491,7 +491,7 @@ class ExpectedUpdater(object):
|
||||||
|
|
||||||
def test_for_scope(self, data):
|
def test_for_scope(self, data):
|
||||||
dir_path = data.get("scope", "/")
|
dir_path = data.get("scope", "/")
|
||||||
dir_id = intern(os.path.join(dir_path, "__dir__").replace(os.path.sep, "/").encode("utf8"))
|
dir_id = intern(ensure_str(os.path.join(dir_path, "__dir__").replace(os.path.sep, "/")))
|
||||||
if dir_id.startswith("/"):
|
if dir_id.startswith("/"):
|
||||||
dir_id = dir_id[1:]
|
dir_id = dir_id[1:]
|
||||||
return dir_id, self.id_test_map[dir_id]
|
return dir_id, self.id_test_map[dir_id]
|
||||||
|
@ -530,13 +530,13 @@ def create_test_tree(metadata_path, test_manifest):
|
||||||
assert all_types > exclude_types
|
assert all_types > exclude_types
|
||||||
include_types = all_types - exclude_types
|
include_types = all_types - exclude_types
|
||||||
for item_type, test_path, tests in test_manifest.itertypes(*include_types):
|
for item_type, test_path, tests in test_manifest.itertypes(*include_types):
|
||||||
test_file_data = TestFileData(intern(test_manifest.url_base.encode("utf8")),
|
test_file_data = TestFileData(intern(ensure_str(test_manifest.url_base)),
|
||||||
intern(item_type.encode("utf8")),
|
intern(ensure_str(item_type)),
|
||||||
metadata_path,
|
metadata_path,
|
||||||
test_path,
|
test_path,
|
||||||
tests)
|
tests)
|
||||||
for test in tests:
|
for test in tests:
|
||||||
id_test_map[intern(test.id.encode("utf8"))] = test_file_data
|
id_test_map[intern(ensure_str(test.id))] = test_file_data
|
||||||
|
|
||||||
dir_path = os.path.split(test_path)[0].replace(os.path.sep, "/")
|
dir_path = os.path.split(test_path)[0].replace(os.path.sep, "/")
|
||||||
while True:
|
while True:
|
||||||
|
@ -544,9 +544,9 @@ def create_test_tree(metadata_path, test_manifest):
|
||||||
dir_id = dir_path + "/__dir__"
|
dir_id = dir_path + "/__dir__"
|
||||||
else:
|
else:
|
||||||
dir_id = "__dir__"
|
dir_id = "__dir__"
|
||||||
dir_id = intern((test_manifest.url_base + dir_id).lstrip("/").encode("utf8"))
|
dir_id = intern(ensure_str((test_manifest.url_base + dir_id).lstrip("/")))
|
||||||
if dir_id not in id_test_map:
|
if dir_id not in id_test_map:
|
||||||
test_file_data = TestFileData(intern(test_manifest.url_base.encode("utf8")),
|
test_file_data = TestFileData(intern(ensure_str(test_manifest.url_base)),
|
||||||
None,
|
None,
|
||||||
metadata_path,
|
metadata_path,
|
||||||
dir_id,
|
dir_id,
|
||||||
|
@ -615,7 +615,7 @@ class TestFileData(object):
|
||||||
self.item_type = item_type
|
self.item_type = item_type
|
||||||
self.test_path = test_path
|
self.test_path = test_path
|
||||||
self.metadata_path = metadata_path
|
self.metadata_path = metadata_path
|
||||||
self.tests = {intern(item.id.encode("utf8")) for item in tests}
|
self.tests = {intern(ensure_str(item.id)) for item in tests}
|
||||||
self._requires_update = False
|
self._requires_update = False
|
||||||
self.data = defaultdict(lambda: defaultdict(PackedResultList))
|
self.data = defaultdict(lambda: defaultdict(PackedResultList))
|
||||||
|
|
||||||
|
@ -656,11 +656,11 @@ class TestFileData(object):
|
||||||
# Return subtest nodes present in the expected file, but missing from the data
|
# Return subtest nodes present in the expected file, but missing from the data
|
||||||
rv = []
|
rv = []
|
||||||
|
|
||||||
for test_id, subtests in self.data.iteritems():
|
for test_id, subtests in iteritems(self.data):
|
||||||
test = expected.get_test(test_id.decode("utf8"))
|
test = expected.get_test(ensure_text(test_id))
|
||||||
if not test:
|
if not test:
|
||||||
continue
|
continue
|
||||||
seen_subtests = set(item.decode("utf8") for item in subtests.iterkeys() if item is not None)
|
seen_subtests = set(ensure_text(item) for item in iterkeys(subtests) if item is not None)
|
||||||
missing_subtests = set(test.subtests.keys()) - seen_subtests
|
missing_subtests = set(test.subtests.keys()) - seen_subtests
|
||||||
for item in missing_subtests:
|
for item in missing_subtests:
|
||||||
expected_subtest = test.get_subtest(item)
|
expected_subtest = test.get_subtest(item)
|
||||||
|
@ -729,9 +729,9 @@ class TestFileData(object):
|
||||||
test_expected = expected.get_test(test_id)
|
test_expected = expected.get_test(test_id)
|
||||||
expected_by_test[test_id] = test_expected
|
expected_by_test[test_id] = test_expected
|
||||||
|
|
||||||
for test_id, test_data in self.data.iteritems():
|
for test_id, test_data in iteritems(self.data):
|
||||||
test_id = test_id.decode("utf8")
|
test_id = ensure_str(test_id)
|
||||||
for subtest_id, results_list in test_data.iteritems():
|
for subtest_id, results_list in iteritems(test_data):
|
||||||
for prop, run_info, value in results_list:
|
for prop, run_info, value in results_list:
|
||||||
# Special case directory metadata
|
# Special case directory metadata
|
||||||
if subtest_id is None and test_id.endswith("__dir__"):
|
if subtest_id is None and test_id.endswith("__dir__"):
|
||||||
|
@ -747,8 +747,7 @@ class TestFileData(object):
|
||||||
if subtest_id is None:
|
if subtest_id is None:
|
||||||
item_expected = test_expected
|
item_expected = test_expected
|
||||||
else:
|
else:
|
||||||
if isinstance(subtest_id, str):
|
subtest_id = ensure_text(subtest_id)
|
||||||
subtest_id = subtest_id.decode("utf8")
|
|
||||||
item_expected = test_expected.get_subtest(subtest_id)
|
item_expected = test_expected.get_subtest(subtest_id)
|
||||||
|
|
||||||
if prop == "status":
|
if prop == "status":
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import importlib
|
import importlib
|
||||||
import imp
|
import imp
|
||||||
|
from six import iteritems
|
||||||
|
|
||||||
from .browsers import product_list
|
from .browsers import product_list
|
||||||
|
|
||||||
|
@ -44,7 +45,7 @@ class Product(object):
|
||||||
self.get_timeout_multiplier = getattr(module, data["timeout_multiplier"])
|
self.get_timeout_multiplier = getattr(module, data["timeout_multiplier"])
|
||||||
|
|
||||||
self.executor_classes = {}
|
self.executor_classes = {}
|
||||||
for test_type, cls_name in data["executor"].iteritems():
|
for test_type, cls_name in iteritems(data["executor"]):
|
||||||
cls = getattr(module, cls_name)
|
cls = getattr(module, cls_name)
|
||||||
self.executor_classes[test_type] = cls
|
self.executor_classes[test_type] = cls
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,8 @@ from abc import ABCMeta, abstractmethod
|
||||||
from six.moves.queue import Empty
|
from six.moves.queue import Empty
|
||||||
from collections import defaultdict, deque
|
from collections import defaultdict, deque
|
||||||
from multiprocessing import Queue
|
from multiprocessing import Queue
|
||||||
|
from six import iteritems
|
||||||
|
from six.moves import xrange
|
||||||
|
|
||||||
from . import manifestinclude
|
from . import manifestinclude
|
||||||
from . import manifestexpected
|
from . import manifestexpected
|
||||||
|
@ -124,7 +126,7 @@ class ManifestLoader(object):
|
||||||
|
|
||||||
def load(self):
|
def load(self):
|
||||||
rv = {}
|
rv = {}
|
||||||
for url_base, paths in self.test_paths.iteritems():
|
for url_base, paths in iteritems(self.test_paths):
|
||||||
manifest_file = self.load_manifest(url_base=url_base,
|
manifest_file = self.load_manifest(url_base=url_base,
|
||||||
**paths)
|
**paths)
|
||||||
path_data = {"url_base": url_base}
|
path_data = {"url_base": url_base}
|
||||||
|
@ -236,7 +238,7 @@ class TestLoader(object):
|
||||||
manifest_items = self.chunker(manifest_items)
|
manifest_items = self.chunker(manifest_items)
|
||||||
|
|
||||||
for test_type, test_path, tests in manifest_items:
|
for test_type, test_path, tests in manifest_items:
|
||||||
manifest_file = manifests_by_url_base[iter(tests).next().url_base]
|
manifest_file = manifests_by_url_base[next(iter(tests)).url_base]
|
||||||
metadata_path = self.manifests[manifest_file]["metadata_path"]
|
metadata_path = self.manifests[manifest_file]["metadata_path"]
|
||||||
|
|
||||||
inherit_metadata, test_metadata = self.load_metadata(manifest_file, metadata_path, test_path)
|
inherit_metadata, test_metadata = self.load_metadata(manifest_file, metadata_path, test_path)
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
import sys
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
from .. import expectedtree, metadata
|
from .. import expectedtree, metadata
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
|
@ -32,8 +28,6 @@ def results_object(results):
|
||||||
return results_obj
|
return results_obj
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_build_tree_0():
|
def test_build_tree_0():
|
||||||
# Pass if debug
|
# Pass if debug
|
||||||
results = [({"os": "linux", "version": "18.04", "debug": True}, "FAIL"),
|
results = [({"os": "linux", "version": "18.04", "debug": True}, "FAIL"),
|
||||||
|
@ -53,8 +47,6 @@ def test_build_tree_0():
|
||||||
assert dump_tree(tree) == expected
|
assert dump_tree(tree) == expected
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_build_tree_1():
|
def test_build_tree_1():
|
||||||
# Pass if linux or windows 10
|
# Pass if linux or windows 10
|
||||||
results = [({"os": "linux", "version": "18.04", "debug": True}, "PASS"),
|
results = [({"os": "linux", "version": "18.04", "debug": True}, "PASS"),
|
||||||
|
@ -77,8 +69,6 @@ def test_build_tree_1():
|
||||||
assert dump_tree(tree) == expected
|
assert dump_tree(tree) == expected
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_build_tree_2():
|
def test_build_tree_2():
|
||||||
# Fails in a specific configuration
|
# Fails in a specific configuration
|
||||||
results = [({"os": "linux", "version": "18.04", "debug": True}, "PASS"),
|
results = [({"os": "linux", "version": "18.04", "debug": True}, "PASS"),
|
||||||
|
@ -104,8 +94,6 @@ def test_build_tree_2():
|
||||||
assert dump_tree(tree) == expected
|
assert dump_tree(tree) == expected
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_build_tree_3():
|
def test_build_tree_3():
|
||||||
|
|
||||||
results = [({"os": "linux", "version": "18.04", "debug": True, "unused": False}, "PASS"),
|
results = [({"os": "linux", "version": "18.04", "debug": True, "unused": False}, "PASS"),
|
||||||
|
@ -118,8 +106,6 @@ def test_build_tree_3():
|
||||||
assert dump_tree(tree) == expected
|
assert dump_tree(tree) == expected
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_build_tree_4():
|
def test_build_tree_4():
|
||||||
# Check counts for multiple statuses
|
# Check counts for multiple statuses
|
||||||
results = [({"os": "linux", "version": "18.04", "debug": False}, "FAIL"),
|
results = [({"os": "linux", "version": "18.04", "debug": False}, "FAIL"),
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import sys
|
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -6,8 +5,6 @@ import pytest
|
||||||
from .. import manifestexpected
|
from .. import manifestexpected
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="bytes/text confusion in py3")
|
|
||||||
@pytest.mark.parametrize("fuzzy, expected", [
|
@pytest.mark.parametrize("fuzzy, expected", [
|
||||||
(b"ref.html:1;200", [("ref.html", ((1, 1), (200, 200)))]),
|
(b"ref.html:1;200", [("ref.html", ((1, 1), (200, 200)))]),
|
||||||
(b"ref.html:0-1;100-200", [("ref.html", ((0, 1), (100, 200)))]),
|
(b"ref.html:0-1;100-200", [("ref.html", ((0, 1), (100, 200)))]),
|
||||||
|
@ -25,7 +22,7 @@ from .. import manifestexpected
|
||||||
((u"test.html", u"ref1.html", "=="), ((5,10), (100, 100)))]),
|
((u"test.html", u"ref1.html", "=="), ((5,10), (100, 100)))]),
|
||||||
])
|
])
|
||||||
def test_fuzzy(fuzzy, expected):
|
def test_fuzzy(fuzzy, expected):
|
||||||
data = """
|
data = b"""
|
||||||
[test.html]
|
[test.html]
|
||||||
fuzzy: %s""" % fuzzy
|
fuzzy: %s""" % fuzzy
|
||||||
f = BytesIO(data)
|
f = BytesIO(data)
|
||||||
|
|
|
@ -20,8 +20,6 @@ skip: true
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.platform == "win32",
|
@pytest.mark.xfail(sys.platform == "win32",
|
||||||
reason="NamedTemporaryFile cannot be reopened on Win32")
|
reason="NamedTemporaryFile cannot be reopened on Win32")
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="wptmanifest.parser doesn't support py3")
|
|
||||||
def test_filter_unicode():
|
def test_filter_unicode():
|
||||||
tests = make_mock_manifest(("test", "a", 10), ("test", "a/b", 10),
|
tests = make_mock_manifest(("test", "a", 10), ("test", "a/b", 10),
|
||||||
("test", "c", 10))
|
("test", "c", 10))
|
||||||
|
|
|
@ -108,7 +108,7 @@ def create_log(entries):
|
||||||
getattr(logger, action)(**kwargs)
|
getattr(logger, action)(**kwargs)
|
||||||
logger.remove_handler(handler)
|
logger.remove_handler(handler)
|
||||||
else:
|
else:
|
||||||
json.dump(entries, data)
|
data.write(json.dumps(entries).encode())
|
||||||
data.seek(0)
|
data.seek(0)
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
@ -132,11 +132,9 @@ def create_test_manifest(tests, url_base="/"):
|
||||||
return m
|
return m
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_0():
|
def test_update_0():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness",
|
tests = [("path/to/test.htm", [test_id], "testharness",
|
||||||
"""[test.htm]
|
b"""[test.htm]
|
||||||
[test1]
|
[test1]
|
||||||
expected: FAIL""")]
|
expected: FAIL""")]
|
||||||
|
|
||||||
|
@ -154,11 +152,9 @@ def test_update_0():
|
||||||
assert updated[0][1].is_empty
|
assert updated[0][1].is_empty
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_1():
|
def test_update_1():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness",
|
tests = [("path/to/test.htm", [test_id], "testharness",
|
||||||
"""[test.htm]
|
b"""[test.htm]
|
||||||
[test1]
|
[test1]
|
||||||
expected: ERROR""")]
|
expected: ERROR""")]
|
||||||
|
|
||||||
|
@ -177,11 +173,9 @@ def test_update_1():
|
||||||
assert new_manifest.get_test(test_id).children[0].get("expected", default_run_info) == "FAIL"
|
assert new_manifest.get_test(test_id).children[0].get("expected", default_run_info) == "FAIL"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_known_intermittent_1():
|
def test_update_known_intermittent_1():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness",
|
tests = [("path/to/test.htm", [test_id], "testharness",
|
||||||
"""[test.htm]
|
b"""[test.htm]
|
||||||
[test1]
|
[test1]
|
||||||
expected: PASS""")]
|
expected: PASS""")]
|
||||||
|
|
||||||
|
@ -218,11 +212,9 @@ def test_update_known_intermittent_1():
|
||||||
"expected", default_run_info) == ["PASS", "FAIL"]
|
"expected", default_run_info) == ["PASS", "FAIL"]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_known_intermittent_2():
|
def test_update_known_intermittent_2():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness",
|
tests = [("path/to/test.htm", [test_id], "testharness",
|
||||||
"""[test.htm]
|
b"""[test.htm]
|
||||||
[test1]
|
[test1]
|
||||||
expected: PASS""")]
|
expected: PASS""")]
|
||||||
|
|
||||||
|
@ -243,11 +235,9 @@ def test_update_known_intermittent_2():
|
||||||
"expected", default_run_info) == "FAIL"
|
"expected", default_run_info) == "FAIL"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_existing_known_intermittent():
|
def test_update_existing_known_intermittent():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness",
|
tests = [("path/to/test.htm", [test_id], "testharness",
|
||||||
"""[test.htm]
|
b"""[test.htm]
|
||||||
[test1]
|
[test1]
|
||||||
expected: [PASS, FAIL]""")]
|
expected: [PASS, FAIL]""")]
|
||||||
|
|
||||||
|
@ -286,11 +276,9 @@ def test_update_existing_known_intermittent():
|
||||||
"expected", default_run_info) == ["PASS", "ERROR", "FAIL"]
|
"expected", default_run_info) == ["PASS", "ERROR", "FAIL"]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_remove_previous_intermittent():
|
def test_update_remove_previous_intermittent():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness",
|
tests = [("path/to/test.htm", [test_id], "testharness",
|
||||||
"""[test.htm]
|
b"""[test.htm]
|
||||||
[test1]
|
[test1]
|
||||||
expected: [PASS, FAIL]""")]
|
expected: [PASS, FAIL]""")]
|
||||||
|
|
||||||
|
@ -334,8 +322,6 @@ def test_update_remove_previous_intermittent():
|
||||||
"expected", default_run_info) == ["PASS", "ERROR"]
|
"expected", default_run_info) == ["PASS", "ERROR"]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_new_test_with_intermittent():
|
def test_update_new_test_with_intermittent():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", None)]
|
tests = [("path/to/test.htm", [test_id], "testharness", None)]
|
||||||
|
|
||||||
|
@ -373,8 +359,6 @@ def test_update_new_test_with_intermittent():
|
||||||
"expected", default_run_info) == ["PASS", "FAIL"]
|
"expected", default_run_info) == ["PASS", "FAIL"]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_expected_tie_resolution():
|
def test_update_expected_tie_resolution():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", None)]
|
tests = [("path/to/test.htm", [test_id], "testharness", None)]
|
||||||
|
|
||||||
|
@ -402,11 +386,9 @@ def test_update_expected_tie_resolution():
|
||||||
"expected", default_run_info) == ["PASS", "FAIL"]
|
"expected", default_run_info) == ["PASS", "FAIL"]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_reorder_expected():
|
def test_update_reorder_expected():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness",
|
tests = [("path/to/test.htm", [test_id], "testharness",
|
||||||
"""[test.htm]
|
b"""[test.htm]
|
||||||
[test1]
|
[test1]
|
||||||
expected: [PASS, FAIL]""")]
|
expected: [PASS, FAIL]""")]
|
||||||
|
|
||||||
|
@ -445,10 +427,8 @@ def test_update_reorder_expected():
|
||||||
"expected", default_run_info) == ["FAIL", "PASS"]
|
"expected", default_run_info) == ["FAIL", "PASS"]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_and_preserve_unchanged_expected_intermittent():
|
def test_update_and_preserve_unchanged_expected_intermittent():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", """
|
tests = [("path/to/test.htm", [test_id], "testharness", b"""
|
||||||
[test.htm]
|
[test.htm]
|
||||||
expected:
|
expected:
|
||||||
if os == "android": [PASS, FAIL]
|
if os == "android": [PASS, FAIL]
|
||||||
|
@ -488,11 +468,9 @@ def test_update_and_preserve_unchanged_expected_intermittent():
|
||||||
"expected", default_run_info) == "PASS"
|
"expected", default_run_info) == "PASS"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_test_with_intermittent_to_one_expected_status():
|
def test_update_test_with_intermittent_to_one_expected_status():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness",
|
tests = [("path/to/test.htm", [test_id], "testharness",
|
||||||
"""[test.htm]
|
b"""[test.htm]
|
||||||
[test1]
|
[test1]
|
||||||
expected: [PASS, FAIL]""")]
|
expected: [PASS, FAIL]""")]
|
||||||
|
|
||||||
|
@ -513,10 +491,8 @@ def test_update_test_with_intermittent_to_one_expected_status():
|
||||||
"expected", default_run_info) == "ERROR"
|
"expected", default_run_info) == "ERROR"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_intermittent_with_conditions():
|
def test_update_intermittent_with_conditions():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", """
|
tests = [("path/to/test.htm", [test_id], "testharness", b"""
|
||||||
[test.htm]
|
[test.htm]
|
||||||
expected:
|
expected:
|
||||||
if os == "android": [PASS, FAIL]""")]
|
if os == "android": [PASS, FAIL]""")]
|
||||||
|
@ -548,10 +524,8 @@ def test_update_intermittent_with_conditions():
|
||||||
"expected", run_info_1) == ["PASS", "TIMEOUT", "FAIL"]
|
"expected", run_info_1) == ["PASS", "TIMEOUT", "FAIL"]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_and_remove_intermittent_with_conditions():
|
def test_update_and_remove_intermittent_with_conditions():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", """
|
tests = [("path/to/test.htm", [test_id], "testharness", b"""
|
||||||
[test.htm]
|
[test.htm]
|
||||||
expected:
|
expected:
|
||||||
if os == "android": [PASS, FAIL]""")]
|
if os == "android": [PASS, FAIL]""")]
|
||||||
|
@ -583,11 +557,9 @@ def test_update_and_remove_intermittent_with_conditions():
|
||||||
"expected", run_info_1) == ["PASS", "TIMEOUT"]
|
"expected", run_info_1) == ["PASS", "TIMEOUT"]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_intermittent_full():
|
def test_update_intermittent_full():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness",
|
tests = [("path/to/test.htm", [test_id], "testharness",
|
||||||
"""[test.htm]
|
b"""[test.htm]
|
||||||
[test1]
|
[test1]
|
||||||
expected:
|
expected:
|
||||||
if os == "mac": [FAIL, TIMEOUT]
|
if os == "mac": [FAIL, TIMEOUT]
|
||||||
|
@ -623,11 +595,9 @@ def test_update_intermittent_full():
|
||||||
"expected", default_run_info) == "FAIL"
|
"expected", default_run_info) == "FAIL"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_intermittent_full_remove():
|
def test_update_intermittent_full_remove():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness",
|
tests = [("path/to/test.htm", [test_id], "testharness",
|
||||||
"""[test.htm]
|
b"""[test.htm]
|
||||||
[test1]
|
[test1]
|
||||||
expected:
|
expected:
|
||||||
if os == "mac": [FAIL, TIMEOUT, PASS]
|
if os == "mac": [FAIL, TIMEOUT, PASS]
|
||||||
|
@ -674,11 +644,9 @@ def test_update_intermittent_full_remove():
|
||||||
"expected", default_run_info) == "FAIL"
|
"expected", default_run_info) == "FAIL"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_full_update():
|
def test_full_update():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness",
|
tests = [("path/to/test.htm", [test_id], "testharness",
|
||||||
"""[test.htm]
|
b"""[test.htm]
|
||||||
[test1]
|
[test1]
|
||||||
expected:
|
expected:
|
||||||
if os == "mac": [FAIL, TIMEOUT]
|
if os == "mac": [FAIL, TIMEOUT]
|
||||||
|
@ -714,11 +682,9 @@ def test_full_update():
|
||||||
"expected", default_run_info) == "FAIL"
|
"expected", default_run_info) == "FAIL"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_full_orphan():
|
def test_full_orphan():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness",
|
tests = [("path/to/test.htm", [test_id], "testharness",
|
||||||
"""[test.htm]
|
b"""[test.htm]
|
||||||
[test1]
|
[test1]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
[subsub test]
|
[subsub test]
|
||||||
|
@ -747,11 +713,9 @@ def test_full_orphan():
|
||||||
assert len(new_manifest.get_test(test_id).children) == 1
|
assert len(new_manifest.get_test(test_id).children) == 1
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_reorder_expected_full_conditions():
|
def test_update_reorder_expected_full_conditions():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness",
|
tests = [("path/to/test.htm", [test_id], "testharness",
|
||||||
"""[test.htm]
|
b"""[test.htm]
|
||||||
[test1]
|
[test1]
|
||||||
expected:
|
expected:
|
||||||
if os == "mac": [FAIL, TIMEOUT]
|
if os == "mac": [FAIL, TIMEOUT]
|
||||||
|
@ -808,11 +772,9 @@ def test_update_reorder_expected_full_conditions():
|
||||||
"expected", default_run_info) == ["PASS", "FAIL"]
|
"expected", default_run_info) == ["PASS", "FAIL"]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_skip_0():
|
def test_skip_0():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness",
|
tests = [("path/to/test.htm", [test_id], "testharness",
|
||||||
"""[test.htm]
|
b"""[test.htm]
|
||||||
[test1]
|
[test1]
|
||||||
expected: FAIL""")]
|
expected: FAIL""")]
|
||||||
|
|
||||||
|
@ -828,10 +790,8 @@ def test_skip_0():
|
||||||
assert not updated
|
assert not updated
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_new_subtest():
|
def test_new_subtest():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", """[test.htm]
|
tests = [("path/to/test.htm", [test_id], "testharness", b"""[test.htm]
|
||||||
[test1]
|
[test1]
|
||||||
expected: FAIL""")]
|
expected: FAIL""")]
|
||||||
|
|
||||||
|
@ -853,10 +813,8 @@ def test_new_subtest():
|
||||||
assert new_manifest.get_test(test_id).children[1].get("expected", default_run_info) == "FAIL"
|
assert new_manifest.get_test(test_id).children[1].get("expected", default_run_info) == "FAIL"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_multiple_0():
|
def test_update_multiple_0():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", """[test.htm]
|
tests = [("path/to/test.htm", [test_id], "testharness", b"""[test.htm]
|
||||||
[test1]
|
[test1]
|
||||||
expected: FAIL""")]
|
expected: FAIL""")]
|
||||||
|
|
||||||
|
@ -892,10 +850,8 @@ def test_update_multiple_0():
|
||||||
"expected", {"debug": False, "os": "linux"}) == "TIMEOUT"
|
"expected", {"debug": False, "os": "linux"}) == "TIMEOUT"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_multiple_1():
|
def test_update_multiple_1():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", """[test.htm]
|
tests = [("path/to/test.htm", [test_id], "testharness", b"""[test.htm]
|
||||||
[test1]
|
[test1]
|
||||||
expected: FAIL""")]
|
expected: FAIL""")]
|
||||||
|
|
||||||
|
@ -936,10 +892,8 @@ def test_update_multiple_1():
|
||||||
"expected", run_info_3) == "FAIL"
|
"expected", run_info_3) == "FAIL"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_multiple_2():
|
def test_update_multiple_2():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", """[test.htm]
|
tests = [("path/to/test.htm", [test_id], "testharness", b"""[test.htm]
|
||||||
[test1]
|
[test1]
|
||||||
expected: FAIL""")]
|
expected: FAIL""")]
|
||||||
|
|
||||||
|
@ -976,10 +930,8 @@ def test_update_multiple_2():
|
||||||
"expected", run_info_2) == "TIMEOUT"
|
"expected", run_info_2) == "TIMEOUT"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_multiple_3():
|
def test_update_multiple_3():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", """[test.htm]
|
tests = [("path/to/test.htm", [test_id], "testharness", b"""[test.htm]
|
||||||
[test1]
|
[test1]
|
||||||
expected:
|
expected:
|
||||||
if debug: FAIL
|
if debug: FAIL
|
||||||
|
@ -1018,10 +970,8 @@ def test_update_multiple_3():
|
||||||
"expected", run_info_2) == "TIMEOUT"
|
"expected", run_info_2) == "TIMEOUT"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_ignore_existing():
|
def test_update_ignore_existing():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", """[test.htm]
|
tests = [("path/to/test.htm", [test_id], "testharness", b"""[test.htm]
|
||||||
[test1]
|
[test1]
|
||||||
expected:
|
expected:
|
||||||
if debug: TIMEOUT
|
if debug: TIMEOUT
|
||||||
|
@ -1060,8 +1010,6 @@ def test_update_ignore_existing():
|
||||||
"expected", run_info_2) == "NOTRUN"
|
"expected", run_info_2) == "NOTRUN"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_new_test():
|
def test_update_new_test():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", None)]
|
tests = [("path/to/test.htm", [test_id], "testharness", None)]
|
||||||
|
|
||||||
|
@ -1084,10 +1032,8 @@ def test_update_new_test():
|
||||||
"expected", run_info_1) == "FAIL"
|
"expected", run_info_1) == "FAIL"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_duplicate():
|
def test_update_duplicate():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", """
|
tests = [("path/to/test.htm", [test_id], "testharness", b"""
|
||||||
[test.htm]
|
[test.htm]
|
||||||
expected: ERROR""")]
|
expected: ERROR""")]
|
||||||
|
|
||||||
|
@ -1106,10 +1052,8 @@ def test_update_duplicate():
|
||||||
"expected", run_info_1) == "ERROR"
|
"expected", run_info_1) == "ERROR"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_disable_intermittent():
|
def test_update_disable_intermittent():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", """
|
tests = [("path/to/test.htm", [test_id], "testharness", b"""
|
||||||
[test.htm]
|
[test.htm]
|
||||||
expected: ERROR""")]
|
expected: ERROR""")]
|
||||||
|
|
||||||
|
@ -1128,10 +1072,8 @@ def test_update_disable_intermittent():
|
||||||
"disabled", run_info_1) == "Some message"
|
"disabled", run_info_1) == "Some message"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_stability_conditional_instability():
|
def test_update_stability_conditional_instability():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", """
|
tests = [("path/to/test.htm", [test_id], "testharness", b"""
|
||||||
[test.htm]
|
[test.htm]
|
||||||
expected: ERROR""")]
|
expected: ERROR""")]
|
||||||
|
|
||||||
|
@ -1164,10 +1106,8 @@ def test_update_stability_conditional_instability():
|
||||||
"expected", run_info_2) == "FAIL"
|
"expected", run_info_2) == "FAIL"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_full():
|
def test_update_full():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", """[test.htm]
|
tests = [("path/to/test.htm", [test_id], "testharness", b"""[test.htm]
|
||||||
[test1]
|
[test1]
|
||||||
expected:
|
expected:
|
||||||
if debug: TIMEOUT
|
if debug: TIMEOUT
|
||||||
|
@ -1216,10 +1156,8 @@ def test_update_full():
|
||||||
"expected", run_info_2) == "ERROR"
|
"expected", run_info_2) == "ERROR"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_full_unknown():
|
def test_update_full_unknown():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", """[test.htm]
|
tests = [("path/to/test.htm", [test_id], "testharness", b"""[test.htm]
|
||||||
[test1]
|
[test1]
|
||||||
expected:
|
expected:
|
||||||
if release_or_beta: ERROR
|
if release_or_beta: ERROR
|
||||||
|
@ -1259,10 +1197,8 @@ def test_update_full_unknown():
|
||||||
"expected", run_info_2) == "ERROR"
|
"expected", run_info_2) == "ERROR"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_full_unknown_missing():
|
def test_update_full_unknown_missing():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", """[test.htm]
|
tests = [("path/to/test.htm", [test_id], "testharness", b"""[test.htm]
|
||||||
[subtest_deleted]
|
[subtest_deleted]
|
||||||
expected:
|
expected:
|
||||||
if release_or_beta: ERROR
|
if release_or_beta: ERROR
|
||||||
|
@ -1282,10 +1218,8 @@ def test_update_full_unknown_missing():
|
||||||
assert len(updated) == 0
|
assert len(updated) == 0
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_default():
|
def test_update_default():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", """[test.htm]
|
tests = [("path/to/test.htm", [test_id], "testharness", b"""[test.htm]
|
||||||
[test1]
|
[test1]
|
||||||
expected:
|
expected:
|
||||||
if os == "mac": FAIL
|
if os == "mac": FAIL
|
||||||
|
@ -1315,10 +1249,8 @@ def test_update_default():
|
||||||
assert new_manifest.is_empty
|
assert new_manifest.is_empty
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_default_1():
|
def test_update_default_1():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", """
|
tests = [("path/to/test.htm", [test_id], "testharness", b"""
|
||||||
[test.htm]
|
[test.htm]
|
||||||
expected:
|
expected:
|
||||||
if os == "mac": TIMEOUT
|
if os == "mac": TIMEOUT
|
||||||
|
@ -1347,10 +1279,8 @@ def test_update_default_1():
|
||||||
"expected", run_info_2) == "FAIL"
|
"expected", run_info_2) == "FAIL"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_default_2():
|
def test_update_default_2():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", """
|
tests = [("path/to/test.htm", [test_id], "testharness", b"""
|
||||||
[test.htm]
|
[test.htm]
|
||||||
expected:
|
expected:
|
||||||
if os == "mac": TIMEOUT
|
if os == "mac": TIMEOUT
|
||||||
|
@ -1379,10 +1309,8 @@ def test_update_default_2():
|
||||||
"expected", run_info_2) == "TIMEOUT"
|
"expected", run_info_2) == "TIMEOUT"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_assertion_count_0():
|
def test_update_assertion_count_0():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", """[test.htm]
|
tests = [("path/to/test.htm", [test_id], "testharness", b"""[test.htm]
|
||||||
max-asserts: 4
|
max-asserts: 4
|
||||||
min-asserts: 2
|
min-asserts: 2
|
||||||
""")]
|
""")]
|
||||||
|
@ -1403,10 +1331,8 @@ def test_update_assertion_count_0():
|
||||||
assert new_manifest.get_test(test_id).get("min-asserts") == "2"
|
assert new_manifest.get_test(test_id).get("min-asserts") == "2"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_assertion_count_1():
|
def test_update_assertion_count_1():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", """[test.htm]
|
tests = [("path/to/test.htm", [test_id], "testharness", b"""[test.htm]
|
||||||
max-asserts: 4
|
max-asserts: 4
|
||||||
min-asserts: 2
|
min-asserts: 2
|
||||||
""")]
|
""")]
|
||||||
|
@ -1427,10 +1353,8 @@ def test_update_assertion_count_1():
|
||||||
assert new_manifest.get_test(test_id).has_key("min-asserts") is False
|
assert new_manifest.get_test(test_id).has_key("min-asserts") is False
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_assertion_count_2():
|
def test_update_assertion_count_2():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", """[test.htm]
|
tests = [("path/to/test.htm", [test_id], "testharness", b"""[test.htm]
|
||||||
max-asserts: 4
|
max-asserts: 4
|
||||||
min-asserts: 2
|
min-asserts: 2
|
||||||
""")]
|
""")]
|
||||||
|
@ -1447,10 +1371,8 @@ def test_update_assertion_count_2():
|
||||||
assert not updated
|
assert not updated
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_assertion_count_3():
|
def test_update_assertion_count_3():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", """[test.htm]
|
tests = [("path/to/test.htm", [test_id], "testharness", b"""[test.htm]
|
||||||
max-asserts: 4
|
max-asserts: 4
|
||||||
min-asserts: 2
|
min-asserts: 2
|
||||||
""")]
|
""")]
|
||||||
|
@ -1481,10 +1403,8 @@ def test_update_assertion_count_3():
|
||||||
assert new_manifest.get_test(test_id).get("min-asserts") == "2"
|
assert new_manifest.get_test(test_id).get("min-asserts") == "2"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_assertion_count_4():
|
def test_update_assertion_count_4():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", """[test.htm]""")]
|
tests = [("path/to/test.htm", [test_id], "testharness", b"""[test.htm]""")]
|
||||||
|
|
||||||
log_0 = suite_log([("test_start", {"test": test_id}),
|
log_0 = suite_log([("test_start", {"test": test_id}),
|
||||||
("assertion_count", {"test": test_id,
|
("assertion_count", {"test": test_id,
|
||||||
|
@ -1512,11 +1432,9 @@ def test_update_assertion_count_4():
|
||||||
assert new_manifest.get_test(test_id).has_key("min-asserts") is False
|
assert new_manifest.get_test(test_id).has_key("min-asserts") is False
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_lsan_0():
|
def test_update_lsan_0():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", ""),
|
tests = [("path/to/test.htm", [test_id], "testharness", b""),
|
||||||
("path/to/__dir__", [dir_id], None, "")]
|
("path/to/__dir__", [dir_id], None, b"")]
|
||||||
|
|
||||||
log_0 = suite_log([("lsan_leak", {"scope": "path/to/",
|
log_0 = suite_log([("lsan_leak", {"scope": "path/to/",
|
||||||
"frames": ["foo", "bar"]})])
|
"frames": ["foo", "bar"]})])
|
||||||
|
@ -1529,11 +1447,9 @@ def test_update_lsan_0():
|
||||||
assert new_manifest.get("lsan-allowed") == ["foo"]
|
assert new_manifest.get("lsan-allowed") == ["foo"]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_lsan_1():
|
def test_update_lsan_1():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", ""),
|
tests = [("path/to/test.htm", [test_id], "testharness", b""),
|
||||||
("path/to/__dir__", [dir_id], None, """
|
("path/to/__dir__", [dir_id], None, b"""
|
||||||
lsan-allowed: [foo]""")]
|
lsan-allowed: [foo]""")]
|
||||||
|
|
||||||
log_0 = suite_log([("lsan_leak", {"scope": "path/to/",
|
log_0 = suite_log([("lsan_leak", {"scope": "path/to/",
|
||||||
|
@ -1549,13 +1465,11 @@ lsan-allowed: [foo]""")]
|
||||||
assert new_manifest.get("lsan-allowed") == ["baz", "foo"]
|
assert new_manifest.get("lsan-allowed") == ["baz", "foo"]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_lsan_2():
|
def test_update_lsan_2():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", ""),
|
tests = [("path/to/test.htm", [test_id], "testharness", b""),
|
||||||
("path/__dir__", ["path/__dir__"], None, """
|
("path/__dir__", ["path/__dir__"], None, b"""
|
||||||
lsan-allowed: [foo]"""),
|
lsan-allowed: [foo]"""),
|
||||||
("path/to/__dir__", [dir_id], None, "")]
|
("path/to/__dir__", [dir_id], None, b"")]
|
||||||
|
|
||||||
log_0 = suite_log([("lsan_leak", {"scope": "path/to/",
|
log_0 = suite_log([("lsan_leak", {"scope": "path/to/",
|
||||||
"frames": ["foo", "bar"],
|
"frames": ["foo", "bar"],
|
||||||
|
@ -1571,11 +1485,9 @@ lsan-allowed: [foo]"""),
|
||||||
assert new_manifest.get("lsan-allowed") == ["baz"]
|
assert new_manifest.get("lsan-allowed") == ["baz"]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_lsan_3():
|
def test_update_lsan_3():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", ""),
|
tests = [("path/to/test.htm", [test_id], "testharness", b""),
|
||||||
("path/to/__dir__", [dir_id], None, "")]
|
("path/to/__dir__", [dir_id], None, b"")]
|
||||||
|
|
||||||
log_0 = suite_log([("lsan_leak", {"scope": "path/to/",
|
log_0 = suite_log([("lsan_leak", {"scope": "path/to/",
|
||||||
"frames": ["foo", "bar"]})],
|
"frames": ["foo", "bar"]})],
|
||||||
|
@ -1593,11 +1505,9 @@ def test_update_lsan_3():
|
||||||
assert new_manifest.get("lsan-allowed") == ["baz", "foo"]
|
assert new_manifest.get("lsan-allowed") == ["baz", "foo"]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_wptreport_0():
|
def test_update_wptreport_0():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness",
|
tests = [("path/to/test.htm", [test_id], "testharness",
|
||||||
"""[test.htm]
|
b"""[test.htm]
|
||||||
[test1]
|
[test1]
|
||||||
expected: FAIL""")]
|
expected: FAIL""")]
|
||||||
|
|
||||||
|
@ -1615,11 +1525,9 @@ def test_update_wptreport_0():
|
||||||
assert updated[0][1].is_empty
|
assert updated[0][1].is_empty
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_wptreport_1():
|
def test_update_wptreport_1():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", ""),
|
tests = [("path/to/test.htm", [test_id], "testharness", b""),
|
||||||
("path/to/__dir__", [dir_id], None, "")]
|
("path/to/__dir__", [dir_id], None, b"")]
|
||||||
|
|
||||||
log = {"run_info": default_run_info.copy(),
|
log = {"run_info": default_run_info.copy(),
|
||||||
"results": [],
|
"results": [],
|
||||||
|
@ -1632,11 +1540,9 @@ def test_update_wptreport_1():
|
||||||
assert updated[0][1].get("lsan-allowed") == ["baz"]
|
assert updated[0][1].get("lsan-allowed") == ["baz"]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_leak_total_0():
|
def test_update_leak_total_0():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", ""),
|
tests = [("path/to/test.htm", [test_id], "testharness", b""),
|
||||||
("path/to/__dir__", [dir_id], None, "")]
|
("path/to/__dir__", [dir_id], None, b"")]
|
||||||
|
|
||||||
log_0 = suite_log([("mozleak_total", {"scope": "path/to/",
|
log_0 = suite_log([("mozleak_total", {"scope": "path/to/",
|
||||||
"process": "default",
|
"process": "default",
|
||||||
|
@ -1651,11 +1557,9 @@ def test_update_leak_total_0():
|
||||||
assert new_manifest.get("leak-threshold") == ['default:51200']
|
assert new_manifest.get("leak-threshold") == ['default:51200']
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_leak_total_1():
|
def test_update_leak_total_1():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", ""),
|
tests = [("path/to/test.htm", [test_id], "testharness", b""),
|
||||||
("path/to/__dir__", [dir_id], None, "")]
|
("path/to/__dir__", [dir_id], None, b"")]
|
||||||
|
|
||||||
log_0 = suite_log([("mozleak_total", {"scope": "path/to/",
|
log_0 = suite_log([("mozleak_total", {"scope": "path/to/",
|
||||||
"process": "default",
|
"process": "default",
|
||||||
|
@ -1667,11 +1571,9 @@ def test_update_leak_total_1():
|
||||||
assert not updated
|
assert not updated
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_leak_total_2():
|
def test_update_leak_total_2():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", ""),
|
tests = [("path/to/test.htm", [test_id], "testharness", b""),
|
||||||
("path/to/__dir__", [dir_id], None, """
|
("path/to/__dir__", [dir_id], None, b"""
|
||||||
leak-total: 110""")]
|
leak-total: 110""")]
|
||||||
|
|
||||||
log_0 = suite_log([("mozleak_total", {"scope": "path/to/",
|
log_0 = suite_log([("mozleak_total", {"scope": "path/to/",
|
||||||
|
@ -1684,11 +1586,9 @@ leak-total: 110""")]
|
||||||
assert not updated
|
assert not updated
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_leak_total_3():
|
def test_update_leak_total_3():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", ""),
|
tests = [("path/to/test.htm", [test_id], "testharness", b""),
|
||||||
("path/to/__dir__", [dir_id], None, """
|
("path/to/__dir__", [dir_id], None, b"""
|
||||||
leak-total: 100""")]
|
leak-total: 100""")]
|
||||||
|
|
||||||
log_0 = suite_log([("mozleak_total", {"scope": "path/to/",
|
log_0 = suite_log([("mozleak_total", {"scope": "path/to/",
|
||||||
|
@ -1704,11 +1604,9 @@ leak-total: 100""")]
|
||||||
assert new_manifest.get("leak-threshold") == ['default:51200']
|
assert new_manifest.get("leak-threshold") == ['default:51200']
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="metadata doesn't support py3")
|
|
||||||
def test_update_leak_total_4():
|
def test_update_leak_total_4():
|
||||||
tests = [("path/to/test.htm", [test_id], "testharness", ""),
|
tests = [("path/to/test.htm", [test_id], "testharness", b""),
|
||||||
("path/to/__dir__", [dir_id], None, """
|
("path/to/__dir__", [dir_id], None, b"""
|
||||||
leak-total: 110""")]
|
leak-total: 110""")]
|
||||||
|
|
||||||
log_0 = suite_log([
|
log_0 = suite_log([
|
||||||
|
@ -1737,8 +1635,6 @@ class UpdateRunner(StepRunner):
|
||||||
steps = [TestStep]
|
steps = [TestStep]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="update.state doesn't support py3")
|
|
||||||
def test_update_pickle():
|
def test_update_pickle():
|
||||||
logger = structuredlog.StructuredLogger("expected_test")
|
logger = structuredlog.StructuredLogger("expected_test")
|
||||||
args = {
|
args = {
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import pytest
|
|
||||||
import sys
|
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from mock import Mock
|
from mock import Mock
|
||||||
|
|
||||||
|
@ -7,29 +5,29 @@ from manifest import manifest as wptmanifest
|
||||||
from manifest.item import TestharnessTest
|
from manifest.item import TestharnessTest
|
||||||
from .. import manifestexpected, wpttest
|
from .. import manifestexpected, wpttest
|
||||||
|
|
||||||
dir_ini_0 = """\
|
dir_ini_0 = b"""\
|
||||||
prefs: [a:b]
|
prefs: [a:b]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
dir_ini_1 = """\
|
dir_ini_1 = b"""\
|
||||||
prefs: [@Reset, b:c]
|
prefs: [@Reset, b:c]
|
||||||
max-asserts: 2
|
max-asserts: 2
|
||||||
min-asserts: 1
|
min-asserts: 1
|
||||||
tags: [b, c]
|
tags: [b, c]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
dir_ini_2 = """\
|
dir_ini_2 = b"""\
|
||||||
lsan-max-stack-depth: 42
|
lsan-max-stack-depth: 42
|
||||||
"""
|
"""
|
||||||
|
|
||||||
test_0 = """\
|
test_0 = b"""\
|
||||||
[0.html]
|
[0.html]
|
||||||
prefs: [c:d]
|
prefs: [c:d]
|
||||||
max-asserts: 3
|
max-asserts: 3
|
||||||
tags: [a, @Reset]
|
tags: [a, @Reset]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
test_1 = """\
|
test_1 = b"""\
|
||||||
[1.html]
|
[1.html]
|
||||||
prefs:
|
prefs:
|
||||||
if os == 'win': [a:b, c:d]
|
if os == 'win': [a:b, c:d]
|
||||||
|
@ -37,12 +35,12 @@ test_1 = """\
|
||||||
if os == 'win': FAIL
|
if os == 'win': FAIL
|
||||||
"""
|
"""
|
||||||
|
|
||||||
test_2 = """\
|
test_2 = b"""\
|
||||||
[2.html]
|
[2.html]
|
||||||
lsan-max-stack-depth: 42
|
lsan-max-stack-depth: 42
|
||||||
"""
|
"""
|
||||||
|
|
||||||
test_3 = """\
|
test_3 = b"""\
|
||||||
[3.html]
|
[3.html]
|
||||||
[subtest1]
|
[subtest1]
|
||||||
expected: [PASS, FAIL]
|
expected: [PASS, FAIL]
|
||||||
|
@ -54,32 +52,32 @@ test_3 = """\
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
"""
|
"""
|
||||||
|
|
||||||
test_4 = """\
|
test_4 = b"""\
|
||||||
[4.html]
|
[4.html]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
"""
|
"""
|
||||||
|
|
||||||
test_5 = """\
|
test_5 = b"""\
|
||||||
[5.html]
|
[5.html]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
test_6 = """\
|
test_6 = b"""\
|
||||||
[6.html]
|
[6.html]
|
||||||
expected: [OK, FAIL]
|
expected: [OK, FAIL]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
test_7 = """\
|
test_7 = b"""\
|
||||||
[7.html]
|
[7.html]
|
||||||
blink_expect_any_subtest_status: yep
|
blink_expect_any_subtest_status: yep
|
||||||
"""
|
"""
|
||||||
|
|
||||||
test_fuzzy = """\
|
test_fuzzy = b"""\
|
||||||
[fuzzy.html]
|
[fuzzy.html]
|
||||||
fuzzy: fuzzy-ref.html:1;200
|
fuzzy: fuzzy-ref.html:1;200
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
testharness_test = """<script src="/resources/testharness.js"></script>
|
testharness_test = b"""<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>"""
|
<script src="/resources/testharnessreport.js"></script>"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -117,8 +115,6 @@ def make_test_object(test_name,
|
||||||
return wpttest.from_manifest(tests, test, inherit_metadata, test_metadata.get_test(test.id))
|
return wpttest.from_manifest(tests, test, inherit_metadata, test_metadata.get_test(test.id))
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="bytes/text confusion in py3")
|
|
||||||
def test_metadata_inherit():
|
def test_metadata_inherit():
|
||||||
items = [("test", "a", 10), ("test", "a/b", 10), ("test", "c", 10)]
|
items = [("test", "a", 10), ("test", "a/b", 10), ("test", "c", 10)]
|
||||||
inherit_metadata = [
|
inherit_metadata = [
|
||||||
|
@ -136,8 +132,6 @@ def test_metadata_inherit():
|
||||||
assert test_obj.tags == {"a", "dir:a"}
|
assert test_obj.tags == {"a", "dir:a"}
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="bytes/text confusion in py3")
|
|
||||||
def test_conditional():
|
def test_conditional():
|
||||||
items = [("test", "a", 10), ("test", "a/b", 10), ("test", "c", 10)]
|
items = [("test", "a", 10), ("test", "a/b", 10), ("test", "c", 10)]
|
||||||
|
|
||||||
|
@ -147,8 +141,6 @@ def test_conditional():
|
||||||
assert test_obj.expected() == "FAIL"
|
assert test_obj.expected() == "FAIL"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="bytes/text confusion in py3")
|
|
||||||
def test_metadata_lsan_stack_depth():
|
def test_metadata_lsan_stack_depth():
|
||||||
items = [("test", "a", 10), ("test", "a/b", 10)]
|
items = [("test", "a", 10), ("test", "a/b", 10)]
|
||||||
|
|
||||||
|
@ -172,8 +164,6 @@ def test_metadata_lsan_stack_depth():
|
||||||
assert test_obj.lsan_max_stack_depth == 42
|
assert test_obj.lsan_max_stack_depth == 42
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="bytes/text confusion in py3")
|
|
||||||
def test_subtests():
|
def test_subtests():
|
||||||
test_obj = make_test_object(test_3, "a/3.html", 3, ("test", "a", 4), None, False)
|
test_obj = make_test_object(test_3, "a/3.html", 3, ("test", "a", 4), None, False)
|
||||||
assert test_obj.expected("subtest1") == "PASS"
|
assert test_obj.expected("subtest1") == "PASS"
|
||||||
|
@ -184,40 +174,30 @@ def test_subtests():
|
||||||
assert test_obj.known_intermittent("subtest3") == []
|
assert test_obj.known_intermittent("subtest3") == []
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="bytes/text confusion in py3")
|
|
||||||
def test_expected_fail():
|
def test_expected_fail():
|
||||||
test_obj = make_test_object(test_4, "a/4.html", 4, ("test", "a", 5), None, False)
|
test_obj = make_test_object(test_4, "a/4.html", 4, ("test", "a", 5), None, False)
|
||||||
assert test_obj.expected() == "FAIL"
|
assert test_obj.expected() == "FAIL"
|
||||||
assert test_obj.known_intermittent() == []
|
assert test_obj.known_intermittent() == []
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="bytes/text confusion in py3")
|
|
||||||
def test_no_expected():
|
def test_no_expected():
|
||||||
test_obj = make_test_object(test_5, "a/5.html", 5, ("test", "a", 6), None, False)
|
test_obj = make_test_object(test_5, "a/5.html", 5, ("test", "a", 6), None, False)
|
||||||
assert test_obj.expected() == "OK"
|
assert test_obj.expected() == "OK"
|
||||||
assert test_obj.known_intermittent() == []
|
assert test_obj.known_intermittent() == []
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="bytes/text confusion in py3")
|
|
||||||
def test_known_intermittent():
|
def test_known_intermittent():
|
||||||
test_obj = make_test_object(test_6, "a/6.html", 6, ("test", "a", 7), None, False)
|
test_obj = make_test_object(test_6, "a/6.html", 6, ("test", "a", 7), None, False)
|
||||||
assert test_obj.expected() == "OK"
|
assert test_obj.expected() == "OK"
|
||||||
assert test_obj.known_intermittent() == ["FAIL"]
|
assert test_obj.known_intermittent() == ["FAIL"]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="bytes/text confusion in py3")
|
|
||||||
def test_expect_any_subtest_status():
|
def test_expect_any_subtest_status():
|
||||||
test_obj = make_test_object(test_7, "a/7.html", 7, ("test", "a", 8), None, False)
|
test_obj = make_test_object(test_7, "a/7.html", 7, ("test", "a", 8), None, False)
|
||||||
assert test_obj.expected() == "OK"
|
assert test_obj.expected() == "OK"
|
||||||
assert test_obj.expect_any_subtest_status() is True
|
assert test_obj.expect_any_subtest_status() is True
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.xfail(sys.version[0] == "3",
|
|
||||||
reason="bytes/text confusion in py3")
|
|
||||||
def test_metadata_fuzzy():
|
def test_metadata_fuzzy():
|
||||||
manifest_data = {
|
manifest_data = {
|
||||||
"items": {"reftest": {"a/fuzzy.html": [["a/fuzzy.html",
|
"items": {"reftest": {"a/fuzzy.html": [["a/fuzzy.html",
|
||||||
|
@ -234,7 +214,7 @@ def test_metadata_fuzzy():
|
||||||
test_path="a/fuzzy.html",
|
test_path="a/fuzzy.html",
|
||||||
url_base="/")
|
url_base="/")
|
||||||
|
|
||||||
test = manifest.iterpath("a/fuzzy.html").next()
|
test = next(manifest.iterpath("a/fuzzy.html"))
|
||||||
test_obj = wpttest.from_manifest(manifest, test, [], test_metadata.get_test(test.id))
|
test_obj = wpttest.from_manifest(manifest, test, [], test_metadata.get_test(test.id))
|
||||||
|
|
||||||
assert test_obj.fuzzy == {('/a/fuzzy.html', '/a/fuzzy-ref.html', '=='): [[2, 3], [10, 15]]}
|
assert test_obj.fuzzy == {('/a/fuzzy.html', '/a/fuzzy-ref.html', '=='): [[2, 3], [10, 15]]}
|
||||||
|
|
|
@ -11,7 +11,7 @@ class BaseState(object):
|
||||||
return rv
|
return rv
|
||||||
|
|
||||||
logger.debug("No existing state found")
|
logger.debug("No existing state found")
|
||||||
return object.__new__(cls, logger)
|
return super(BaseState, cls).__new__(cls)
|
||||||
|
|
||||||
def __init__(self, logger):
|
def __init__(self, logger):
|
||||||
"""Object containing state variables created when running Steps.
|
"""Object containing state variables created when running Steps.
|
||||||
|
|
|
@ -37,7 +37,7 @@ def require_arg(kwargs, name, value_func=None):
|
||||||
def create_parser(product_choices=None):
|
def create_parser(product_choices=None):
|
||||||
from mozlog import commandline
|
from mozlog import commandline
|
||||||
|
|
||||||
import products
|
from . import products
|
||||||
|
|
||||||
if product_choices is None:
|
if product_choices is None:
|
||||||
config_data = config.load()
|
config_data = config.load()
|
||||||
|
|
|
@ -14,7 +14,7 @@ def setup(args, defaults, formatter_defaults=None):
|
||||||
formatter_defaults=formatter_defaults)
|
formatter_defaults=formatter_defaults)
|
||||||
setup_stdlib_logger()
|
setup_stdlib_logger()
|
||||||
|
|
||||||
for name in args.keys():
|
for name in list(args.keys()):
|
||||||
if name.startswith("log_"):
|
if name.startswith("log_"):
|
||||||
args.pop(name)
|
args.pop(name)
|
||||||
|
|
||||||
|
|
|
@ -3,19 +3,20 @@ from __future__ import print_function, unicode_literals
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
from six import iteritems, itervalues
|
||||||
|
|
||||||
from wptserve import sslutils
|
from wptserve import sslutils
|
||||||
|
|
||||||
import environment as env
|
from . import environment as env
|
||||||
import products
|
from . import products
|
||||||
import testloader
|
from . import testloader
|
||||||
import wptcommandline
|
from . import wptcommandline
|
||||||
import wptlogging
|
from . import wptlogging
|
||||||
import wpttest
|
from . import wpttest
|
||||||
from mozlog import capture, handlers
|
from mozlog import capture, handlers
|
||||||
from font import FontInstaller
|
from .font import FontInstaller
|
||||||
from testrunner import ManagerGroup
|
from .testrunner import ManagerGroup
|
||||||
from browsers.base import NullBrowser
|
from .browsers.base import NullBrowser
|
||||||
|
|
||||||
here = os.path.split(__file__)[0]
|
here = os.path.split(__file__)[0]
|
||||||
|
|
||||||
|
@ -102,7 +103,7 @@ def list_disabled(test_paths, product, **kwargs):
|
||||||
run_info, test_loader = get_loader(test_paths, product,
|
run_info, test_loader = get_loader(test_paths, product,
|
||||||
run_info_extras=run_info_extras, **kwargs)
|
run_info_extras=run_info_extras, **kwargs)
|
||||||
|
|
||||||
for test_type, tests in test_loader.disabled_tests.iteritems():
|
for test_type, tests in iteritems(test_loader.disabled_tests):
|
||||||
for test in tests:
|
for test in tests:
|
||||||
rv.append({"test": test.id, "reason": test.disabled()})
|
rv.append({"test": test.id, "reason": test.disabled()})
|
||||||
print(json.dumps(rv, indent=2))
|
print(json.dumps(rv, indent=2))
|
||||||
|
@ -127,7 +128,7 @@ def get_pause_after_test(test_loader, **kwargs):
|
||||||
if kwargs["headless"]:
|
if kwargs["headless"]:
|
||||||
return False
|
return False
|
||||||
tests = test_loader.tests
|
tests = test_loader.tests
|
||||||
is_single_testharness = (sum(len(item) for item in tests.itervalues()) == 1 and
|
is_single_testharness = (sum(len(item) for item in itervalues(tests)) == 1 and
|
||||||
len(tests.get("testharness", [])) == 1)
|
len(tests.get("testharness", [])) == 1)
|
||||||
if kwargs["repeat"] == 1 and kwargs["rerun"] == 1 and is_single_testharness:
|
if kwargs["repeat"] == 1 and kwargs["rerun"] == 1 and is_single_testharness:
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -2,6 +2,7 @@ import os
|
||||||
import subprocess
|
import subprocess
|
||||||
from six.moves.urllib.parse import urljoin
|
from six.moves.urllib.parse import urljoin
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
from six import string_types
|
||||||
|
|
||||||
from .wptmanifest.parser import atoms
|
from .wptmanifest.parser import atoms
|
||||||
|
|
||||||
|
@ -337,7 +338,7 @@ class Test(object):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
expected = metadata.get("expected")
|
expected = metadata.get("expected")
|
||||||
if isinstance(expected, (basestring)):
|
if isinstance(expected, string_types):
|
||||||
return expected
|
return expected
|
||||||
elif isinstance(expected, list):
|
elif isinstance(expected, list):
|
||||||
return expected[0]
|
return expected[0]
|
||||||
|
|
|
@ -10,8 +10,8 @@ promise_test(async () => {
|
||||||
builder
|
builder
|
||||||
.addFunction("swap", type_if_fi)
|
.addFunction("swap", type_if_fi)
|
||||||
.addBody([
|
.addBody([
|
||||||
kExprGetLocal, 1,
|
kExprLocalGet, 1,
|
||||||
kExprGetLocal, 0,
|
kExprLocalGet, 0,
|
||||||
kExprReturn,
|
kExprReturn,
|
||||||
])
|
])
|
||||||
.exportFunc();
|
.exportFunc();
|
||||||
|
@ -31,8 +31,8 @@ promise_test(async () => {
|
||||||
const swap = builder
|
const swap = builder
|
||||||
.addFunction("swap", type_if_fi)
|
.addFunction("swap", type_if_fi)
|
||||||
.addBody([
|
.addBody([
|
||||||
kExprGetLocal, 1,
|
kExprLocalGet, 1,
|
||||||
kExprGetLocal, 0,
|
kExprLocalGet, 0,
|
||||||
kExprReturn,
|
kExprReturn,
|
||||||
]);
|
]);
|
||||||
builder
|
builder
|
||||||
|
|
|
@ -183,7 +183,7 @@ const instanceTestFactory = [
|
||||||
builder
|
builder
|
||||||
.addFunction("fn", kSig_i_v)
|
.addFunction("fn", kSig_i_v)
|
||||||
.addBody([
|
.addBody([
|
||||||
kExprGetGlobal,
|
kExprGlobalGet,
|
||||||
index,
|
index,
|
||||||
kExprReturn,
|
kExprReturn,
|
||||||
])
|
])
|
||||||
|
|
|
@ -81,22 +81,10 @@ test(() => {
|
||||||
const bytes1 = [87, 101, 98, 65, 115, 115, 101, 109, 98, 108, 121];
|
const bytes1 = [87, 101, 98, 65, 115, 115, 101, 109, 98, 108, 121];
|
||||||
const bytes2 = [74, 83, 65, 80, 73];
|
const bytes2 = [74, 83, 65, 80, 73];
|
||||||
|
|
||||||
const binary = new Binary;
|
|
||||||
binary.emit_section(kUnknownSectionCode, section => {
|
|
||||||
section.emit_string("name");
|
|
||||||
section.emit_bytes(bytes1);
|
|
||||||
});
|
|
||||||
binary.emit_section(kUnknownSectionCode, section => {
|
|
||||||
section.emit_string("name");
|
|
||||||
section.emit_bytes(bytes2);
|
|
||||||
});
|
|
||||||
binary.emit_section(kUnknownSectionCode, section => {
|
|
||||||
section.emit_string("foo");
|
|
||||||
section.emit_bytes(bytes1);
|
|
||||||
});
|
|
||||||
|
|
||||||
const builder = new WasmModuleBuilder();
|
const builder = new WasmModuleBuilder();
|
||||||
builder.addExplicitSection(binary.trunc_buffer());
|
builder.addCustomSection("name", bytes1);
|
||||||
|
builder.addCustomSection("name", bytes2);
|
||||||
|
builder.addCustomSection("foo", bytes1);
|
||||||
const buffer = builder.toBuffer()
|
const buffer = builder.toBuffer()
|
||||||
const module = new WebAssembly.Module(buffer);
|
const module = new WebAssembly.Module(buffer);
|
||||||
|
|
||||||
|
@ -119,14 +107,8 @@ test(() => {
|
||||||
const bytes = [87, 101, 98, 65, 115, 115, 101, 109, 98, 108, 121];
|
const bytes = [87, 101, 98, 65, 115, 115, 101, 109, 98, 108, 121];
|
||||||
const name = "yee\uD801\uDC37eey"
|
const name = "yee\uD801\uDC37eey"
|
||||||
|
|
||||||
const binary = new Binary;
|
|
||||||
binary.emit_section(kUnknownSectionCode, section => {
|
|
||||||
section.emit_string(name);
|
|
||||||
section.emit_bytes(bytes);
|
|
||||||
});
|
|
||||||
|
|
||||||
const builder = new WasmModuleBuilder();
|
const builder = new WasmModuleBuilder();
|
||||||
builder.addExplicitSection(binary.trunc_buffer());
|
builder.addCustomSection(name, bytes);
|
||||||
const buffer = builder.toBuffer();
|
const buffer = builder.toBuffer();
|
||||||
const module = new WebAssembly.Module(buffer);
|
const module = new WebAssembly.Module(buffer);
|
||||||
|
|
||||||
|
@ -140,14 +122,8 @@ test(() => {
|
||||||
test(() => {
|
test(() => {
|
||||||
const bytes = [87, 101, 98, 65, 115, 115, 101, 109, 98, 108, 121];
|
const bytes = [87, 101, 98, 65, 115, 115, 101, 109, 98, 108, 121];
|
||||||
|
|
||||||
const binary = new Binary;
|
|
||||||
binary.emit_section(kUnknownSectionCode, section => {
|
|
||||||
section.emit_string("na\uFFFDme");
|
|
||||||
section.emit_bytes(bytes);
|
|
||||||
});
|
|
||||||
|
|
||||||
const builder = new WasmModuleBuilder();
|
const builder = new WasmModuleBuilder();
|
||||||
builder.addExplicitSection(binary.trunc_buffer());
|
builder.addCustomSection("na\uFFFDme", bytes);
|
||||||
const buffer = builder.toBuffer();
|
const buffer = builder.toBuffer();
|
||||||
const module = new WebAssembly.Module(buffer);
|
const module = new WebAssembly.Module(buffer);
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,8 @@ let kStartSectionCode = 8; // Start function declaration
|
||||||
let kElementSectionCode = 9; // Elements section
|
let kElementSectionCode = 9; // Elements section
|
||||||
let kCodeSectionCode = 10; // Function code
|
let kCodeSectionCode = 10; // Function code
|
||||||
let kDataSectionCode = 11; // Data segments
|
let kDataSectionCode = 11; // Data segments
|
||||||
|
let kDataCountSectionCode = 12; // Data segment count (between Element & Code)
|
||||||
|
let kExceptionSectionCode = 13; // Exception section (between Global & Export)
|
||||||
|
|
||||||
// Name section types
|
// Name section types
|
||||||
let kModuleNameCode = 0;
|
let kModuleNameCode = 0;
|
||||||
|
@ -76,7 +78,13 @@ let kWasmFunctionTypeForm = 0x60;
|
||||||
let kWasmAnyFunctionTypeForm = 0x70;
|
let kWasmAnyFunctionTypeForm = 0x70;
|
||||||
|
|
||||||
let kHasMaximumFlag = 1;
|
let kHasMaximumFlag = 1;
|
||||||
let kResizableMaximumFlag = 1;
|
let kSharedHasMaximumFlag = 3;
|
||||||
|
|
||||||
|
// Segment flags
|
||||||
|
let kActiveNoIndex = 0;
|
||||||
|
let kPassive = 1;
|
||||||
|
let kActiveWithIndex = 2;
|
||||||
|
let kPassiveWithElements = 5;
|
||||||
|
|
||||||
// Function declaration flags
|
// Function declaration flags
|
||||||
let kDeclFunctionName = 0x01;
|
let kDeclFunctionName = 0x01;
|
||||||
|
@ -91,14 +99,21 @@ let kWasmI64 = 0x7e;
|
||||||
let kWasmF32 = 0x7d;
|
let kWasmF32 = 0x7d;
|
||||||
let kWasmF64 = 0x7c;
|
let kWasmF64 = 0x7c;
|
||||||
let kWasmS128 = 0x7b;
|
let kWasmS128 = 0x7b;
|
||||||
|
let kWasmAnyRef = 0x6f;
|
||||||
|
let kWasmAnyFunc = 0x70;
|
||||||
|
let kWasmExnRef = 0x68;
|
||||||
|
|
||||||
let kExternalFunction = 0;
|
let kExternalFunction = 0;
|
||||||
let kExternalTable = 1;
|
let kExternalTable = 1;
|
||||||
let kExternalMemory = 2;
|
let kExternalMemory = 2;
|
||||||
let kExternalGlobal = 3;
|
let kExternalGlobal = 3;
|
||||||
|
let kExternalException = 4;
|
||||||
|
|
||||||
let kTableZero = 0;
|
let kTableZero = 0;
|
||||||
let kMemoryZero = 0;
|
let kMemoryZero = 0;
|
||||||
|
let kSegmentZero = 0;
|
||||||
|
|
||||||
|
let kExceptionAttribute = 0;
|
||||||
|
|
||||||
// Useful signatures
|
// Useful signatures
|
||||||
let kSig_i_i = makeSig([kWasmI32], [kWasmI32]);
|
let kSig_i_i = makeSig([kWasmI32], [kWasmI32]);
|
||||||
|
@ -123,11 +138,30 @@ let kSig_v_l = makeSig([kWasmI64], []);
|
||||||
let kSig_v_d = makeSig([kWasmF64], []);
|
let kSig_v_d = makeSig([kWasmF64], []);
|
||||||
let kSig_v_dd = makeSig([kWasmF64, kWasmF64], []);
|
let kSig_v_dd = makeSig([kWasmF64, kWasmF64], []);
|
||||||
let kSig_v_ddi = makeSig([kWasmF64, kWasmF64, kWasmI32], []);
|
let kSig_v_ddi = makeSig([kWasmF64, kWasmF64, kWasmI32], []);
|
||||||
|
let kSig_ii_v = makeSig([], [kWasmI32, kWasmI32]);
|
||||||
|
let kSig_iii_v = makeSig([], [kWasmI32, kWasmI32, kWasmI32]);
|
||||||
|
let kSig_ii_i = makeSig([kWasmI32], [kWasmI32, kWasmI32]);
|
||||||
|
let kSig_iii_i = makeSig([kWasmI32], [kWasmI32, kWasmI32, kWasmI32]);
|
||||||
|
let kSig_ii_ii = makeSig([kWasmI32, kWasmI32], [kWasmI32, kWasmI32]);
|
||||||
|
let kSig_iii_ii = makeSig([kWasmI32, kWasmI32], [kWasmI32, kWasmI32, kWasmI32]);
|
||||||
|
|
||||||
let kSig_v_f = makeSig([kWasmF32], []);
|
let kSig_v_f = makeSig([kWasmF32], []);
|
||||||
let kSig_f_f = makeSig([kWasmF32], [kWasmF32]);
|
let kSig_f_f = makeSig([kWasmF32], [kWasmF32]);
|
||||||
let kSig_f_d = makeSig([kWasmF64], [kWasmF32]);
|
let kSig_f_d = makeSig([kWasmF64], [kWasmF32]);
|
||||||
let kSig_d_d = makeSig([kWasmF64], [kWasmF64]);
|
let kSig_d_d = makeSig([kWasmF64], [kWasmF64]);
|
||||||
|
let kSig_r_r = makeSig([kWasmAnyRef], [kWasmAnyRef]);
|
||||||
|
let kSig_a_a = makeSig([kWasmAnyFunc], [kWasmAnyFunc]);
|
||||||
|
let kSig_e_e = makeSig([kWasmExnRef], [kWasmExnRef]);
|
||||||
|
let kSig_i_r = makeSig([kWasmAnyRef], [kWasmI32]);
|
||||||
|
let kSig_v_r = makeSig([kWasmAnyRef], []);
|
||||||
|
let kSig_v_a = makeSig([kWasmAnyFunc], []);
|
||||||
|
let kSig_v_e = makeSig([kWasmExnRef], []);
|
||||||
|
let kSig_v_rr = makeSig([kWasmAnyRef, kWasmAnyRef], []);
|
||||||
|
let kSig_v_aa = makeSig([kWasmAnyFunc, kWasmAnyFunc], []);
|
||||||
|
let kSig_r_v = makeSig([], [kWasmAnyRef]);
|
||||||
|
let kSig_a_v = makeSig([], [kWasmAnyFunc]);
|
||||||
|
let kSig_a_i = makeSig([kWasmI32], [kWasmAnyFunc]);
|
||||||
|
let kSig_e_v = makeSig([], [kWasmExnRef]);
|
||||||
|
|
||||||
function makeSig(params, results) {
|
function makeSig(params, results) {
|
||||||
return {params: params, results: results};
|
return {params: params, results: results};
|
||||||
|
@ -163,6 +197,8 @@ let kExprElse = 0x05;
|
||||||
let kExprTry = 0x06;
|
let kExprTry = 0x06;
|
||||||
let kExprCatch = 0x07;
|
let kExprCatch = 0x07;
|
||||||
let kExprThrow = 0x08;
|
let kExprThrow = 0x08;
|
||||||
|
let kExprRethrow = 0x09;
|
||||||
|
let kExprBrOnExn = 0x0a;
|
||||||
let kExprEnd = 0x0b;
|
let kExprEnd = 0x0b;
|
||||||
let kExprBr = 0x0c;
|
let kExprBr = 0x0c;
|
||||||
let kExprBrIf = 0x0d;
|
let kExprBrIf = 0x0d;
|
||||||
|
@ -170,13 +206,17 @@ let kExprBrTable = 0x0e;
|
||||||
let kExprReturn = 0x0f;
|
let kExprReturn = 0x0f;
|
||||||
let kExprCallFunction = 0x10;
|
let kExprCallFunction = 0x10;
|
||||||
let kExprCallIndirect = 0x11;
|
let kExprCallIndirect = 0x11;
|
||||||
|
let kExprReturnCall = 0x12;
|
||||||
|
let kExprReturnCallIndirect = 0x13;
|
||||||
let kExprDrop = 0x1a;
|
let kExprDrop = 0x1a;
|
||||||
let kExprSelect = 0x1b;
|
let kExprSelect = 0x1b;
|
||||||
let kExprGetLocal = 0x20;
|
let kExprLocalGet = 0x20;
|
||||||
let kExprSetLocal = 0x21;
|
let kExprLocalSet = 0x21;
|
||||||
let kExprTeeLocal = 0x22;
|
let kExprLocalTee = 0x22;
|
||||||
let kExprGetGlobal = 0x23;
|
let kExprGlobalGet = 0x23;
|
||||||
let kExprSetGlobal = 0x24;
|
let kExprGlobalSet = 0x24;
|
||||||
|
let kExprTableGet = 0x25;
|
||||||
|
let kExprTableSet = 0x26;
|
||||||
let kExprI32LoadMem = 0x28;
|
let kExprI32LoadMem = 0x28;
|
||||||
let kExprI64LoadMem = 0x29;
|
let kExprI64LoadMem = 0x29;
|
||||||
let kExprF32LoadMem = 0x2a;
|
let kExprF32LoadMem = 0x2a;
|
||||||
|
@ -329,6 +369,108 @@ let kExprI32ReinterpretF32 = 0xbc;
|
||||||
let kExprI64ReinterpretF64 = 0xbd;
|
let kExprI64ReinterpretF64 = 0xbd;
|
||||||
let kExprF32ReinterpretI32 = 0xbe;
|
let kExprF32ReinterpretI32 = 0xbe;
|
||||||
let kExprF64ReinterpretI64 = 0xbf;
|
let kExprF64ReinterpretI64 = 0xbf;
|
||||||
|
let kExprI32SExtendI8 = 0xc0;
|
||||||
|
let kExprI32SExtendI16 = 0xc1;
|
||||||
|
let kExprI64SExtendI8 = 0xc2;
|
||||||
|
let kExprI64SExtendI16 = 0xc3;
|
||||||
|
let kExprI64SExtendI32 = 0xc4;
|
||||||
|
let kExprRefNull = 0xd0;
|
||||||
|
let kExprRefIsNull = 0xd1;
|
||||||
|
let kExprRefFunc = 0xd2;
|
||||||
|
|
||||||
|
// Prefix opcodes
|
||||||
|
let kNumericPrefix = 0xfc;
|
||||||
|
let kSimdPrefix = 0xfd;
|
||||||
|
let kAtomicPrefix = 0xfe;
|
||||||
|
|
||||||
|
// Numeric opcodes.
|
||||||
|
let kExprMemoryInit = 0x08;
|
||||||
|
let kExprDataDrop = 0x09;
|
||||||
|
let kExprMemoryCopy = 0x0a;
|
||||||
|
let kExprMemoryFill = 0x0b;
|
||||||
|
let kExprTableInit = 0x0c;
|
||||||
|
let kExprElemDrop = 0x0d;
|
||||||
|
let kExprTableCopy = 0x0e;
|
||||||
|
let kExprTableGrow = 0x0f;
|
||||||
|
let kExprTableSize = 0x10;
|
||||||
|
let kExprTableFill = 0x11;
|
||||||
|
|
||||||
|
// Atomic opcodes.
|
||||||
|
let kExprAtomicNotify = 0x00;
|
||||||
|
let kExprI32AtomicWait = 0x01;
|
||||||
|
let kExprI64AtomicWait = 0x02;
|
||||||
|
let kExprI32AtomicLoad = 0x10;
|
||||||
|
let kExprI32AtomicLoad8U = 0x12;
|
||||||
|
let kExprI32AtomicLoad16U = 0x13;
|
||||||
|
let kExprI32AtomicStore = 0x17;
|
||||||
|
let kExprI32AtomicStore8U = 0x19;
|
||||||
|
let kExprI32AtomicStore16U = 0x1a;
|
||||||
|
let kExprI32AtomicAdd = 0x1e;
|
||||||
|
let kExprI32AtomicAdd8U = 0x20;
|
||||||
|
let kExprI32AtomicAdd16U = 0x21;
|
||||||
|
let kExprI32AtomicSub = 0x25;
|
||||||
|
let kExprI32AtomicSub8U = 0x27;
|
||||||
|
let kExprI32AtomicSub16U = 0x28;
|
||||||
|
let kExprI32AtomicAnd = 0x2c;
|
||||||
|
let kExprI32AtomicAnd8U = 0x2e;
|
||||||
|
let kExprI32AtomicAnd16U = 0x2f;
|
||||||
|
let kExprI32AtomicOr = 0x33;
|
||||||
|
let kExprI32AtomicOr8U = 0x35;
|
||||||
|
let kExprI32AtomicOr16U = 0x36;
|
||||||
|
let kExprI32AtomicXor = 0x3a;
|
||||||
|
let kExprI32AtomicXor8U = 0x3c;
|
||||||
|
let kExprI32AtomicXor16U = 0x3d;
|
||||||
|
let kExprI32AtomicExchange = 0x41;
|
||||||
|
let kExprI32AtomicExchange8U = 0x43;
|
||||||
|
let kExprI32AtomicExchange16U = 0x44;
|
||||||
|
let kExprI32AtomicCompareExchange = 0x48;
|
||||||
|
let kExprI32AtomicCompareExchange8U = 0x4a;
|
||||||
|
let kExprI32AtomicCompareExchange16U = 0x4b;
|
||||||
|
|
||||||
|
let kExprI64AtomicLoad = 0x11;
|
||||||
|
let kExprI64AtomicLoad8U = 0x14;
|
||||||
|
let kExprI64AtomicLoad16U = 0x15;
|
||||||
|
let kExprI64AtomicLoad32U = 0x16;
|
||||||
|
let kExprI64AtomicStore = 0x18;
|
||||||
|
let kExprI64AtomicStore8U = 0x1b;
|
||||||
|
let kExprI64AtomicStore16U = 0x1c;
|
||||||
|
let kExprI64AtomicStore32U = 0x1d;
|
||||||
|
let kExprI64AtomicAdd = 0x1f;
|
||||||
|
let kExprI64AtomicAdd8U = 0x22;
|
||||||
|
let kExprI64AtomicAdd16U = 0x23;
|
||||||
|
let kExprI64AtomicAdd32U = 0x24;
|
||||||
|
let kExprI64AtomicSub = 0x26;
|
||||||
|
let kExprI64AtomicSub8U = 0x29;
|
||||||
|
let kExprI64AtomicSub16U = 0x2a;
|
||||||
|
let kExprI64AtomicSub32U = 0x2b;
|
||||||
|
let kExprI64AtomicAnd = 0x2d;
|
||||||
|
let kExprI64AtomicAnd8U = 0x30;
|
||||||
|
let kExprI64AtomicAnd16U = 0x31;
|
||||||
|
let kExprI64AtomicAnd32U = 0x32;
|
||||||
|
let kExprI64AtomicOr = 0x34;
|
||||||
|
let kExprI64AtomicOr8U = 0x37;
|
||||||
|
let kExprI64AtomicOr16U = 0x38;
|
||||||
|
let kExprI64AtomicOr32U = 0x39;
|
||||||
|
let kExprI64AtomicXor = 0x3b;
|
||||||
|
let kExprI64AtomicXor8U = 0x3e;
|
||||||
|
let kExprI64AtomicXor16U = 0x3f;
|
||||||
|
let kExprI64AtomicXor32U = 0x40;
|
||||||
|
let kExprI64AtomicExchange = 0x42;
|
||||||
|
let kExprI64AtomicExchange8U = 0x45;
|
||||||
|
let kExprI64AtomicExchange16U = 0x46;
|
||||||
|
let kExprI64AtomicExchange32U = 0x47;
|
||||||
|
let kExprI64AtomicCompareExchange = 0x49
|
||||||
|
let kExprI64AtomicCompareExchange8U = 0x4c;
|
||||||
|
let kExprI64AtomicCompareExchange16U = 0x4d;
|
||||||
|
let kExprI64AtomicCompareExchange32U = 0x4e;
|
||||||
|
|
||||||
|
// Simd opcodes.
|
||||||
|
let kExprS128LoadMem = 0x00;
|
||||||
|
let kExprS128StoreMem = 0x01;
|
||||||
|
let kExprI32x4Splat = 0x0c;
|
||||||
|
let kExprI32x4Eq = 0x2c;
|
||||||
|
let kExprS1x4AllTrue = 0x75;
|
||||||
|
let kExprF32x4Min = 0x9e;
|
||||||
|
|
||||||
class Binary {
|
class Binary {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -346,7 +488,7 @@ class Binary {
|
||||||
}
|
}
|
||||||
|
|
||||||
trunc_buffer() {
|
trunc_buffer() {
|
||||||
return this.buffer = this.buffer.slice(0, this.length);
|
return new Uint8Array(this.buffer.buffer, 0, this.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
|
@ -372,7 +514,7 @@ class Binary {
|
||||||
this.buffer[this.length++] = val >> 24;
|
this.buffer[this.length++] = val >> 24;
|
||||||
}
|
}
|
||||||
|
|
||||||
emit_leb(val, max_len) {
|
emit_leb_u(val, max_len) {
|
||||||
this.ensure_space(max_len);
|
this.ensure_space(max_len);
|
||||||
for (let i = 0; i < max_len; ++i) {
|
for (let i = 0; i < max_len; ++i) {
|
||||||
let v = val & 0xff;
|
let v = val & 0xff;
|
||||||
|
@ -387,11 +529,11 @@ class Binary {
|
||||||
}
|
}
|
||||||
|
|
||||||
emit_u32v(val) {
|
emit_u32v(val) {
|
||||||
this.emit_leb(val, kMaxVarInt32Size);
|
this.emit_leb_u(val, kMaxVarInt32Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
emit_u64v(val) {
|
emit_u64v(val) {
|
||||||
this.emit_leb(val, kMaxVarInt64Size);
|
this.emit_leb_u(val, kMaxVarInt64Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
emit_bytes(data) {
|
emit_bytes(data) {
|
||||||
|
@ -443,6 +585,16 @@ class WasmFunctionBuilder {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.type_index = type_index;
|
this.type_index = type_index;
|
||||||
this.body = [];
|
this.body = [];
|
||||||
|
this.locals = [];
|
||||||
|
this.local_names = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
numLocalNames() {
|
||||||
|
let num_local_names = 0;
|
||||||
|
for (let loc_name of this.local_names) {
|
||||||
|
if (loc_name !== undefined) ++num_local_names;
|
||||||
|
}
|
||||||
|
return num_local_names;
|
||||||
}
|
}
|
||||||
|
|
||||||
exportAs(name) {
|
exportAs(name) {
|
||||||
|
@ -456,9 +608,14 @@ class WasmFunctionBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
addBody(body) {
|
addBody(body) {
|
||||||
const bodyCopy = body.slice();
|
for (let b of body) {
|
||||||
bodyCopy.push(kExprEnd);
|
if (typeof b !== 'number' || (b & (~0xFF)) !== 0 )
|
||||||
return this.addBodyWithEnd(bodyCopy);
|
throw new Error('invalid body (entries must be 8 bit numbers): ' + body);
|
||||||
|
}
|
||||||
|
this.body = body.slice();
|
||||||
|
// Automatically add the end for the function block to the body.
|
||||||
|
this.body.push(kExprEnd);
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
addBodyWithEnd(body) {
|
addBodyWithEnd(body) {
|
||||||
|
@ -466,8 +623,23 @@ class WasmFunctionBuilder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
addLocals(locals) {
|
getNumLocals() {
|
||||||
this.locals = locals;
|
let total_locals = 0;
|
||||||
|
for (let l of this.locals) {
|
||||||
|
for (let type of ["i32", "i64", "f32", "f64", "s128"]) {
|
||||||
|
total_locals += l[type + "_count"] || 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return total_locals;
|
||||||
|
}
|
||||||
|
|
||||||
|
addLocals(locals, names) {
|
||||||
|
const old_num_locals = this.getNumLocals();
|
||||||
|
this.locals.push(locals);
|
||||||
|
if (names) {
|
||||||
|
const missing_names = old_num_locals - this.local_names.length;
|
||||||
|
this.local_names.push(...new Array(missing_names), ...names);
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -491,21 +663,38 @@ class WasmGlobalBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class WasmTableBuilder {
|
||||||
|
constructor(module, type, initial_size, max_size) {
|
||||||
|
this.module = module;
|
||||||
|
this.type = type;
|
||||||
|
this.initial_size = initial_size;
|
||||||
|
this.has_max = max_size != undefined;
|
||||||
|
this.max_size = max_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
exportAs(name) {
|
||||||
|
this.module.exports.push({name: name, kind: kExternalTable,
|
||||||
|
index: this.index});
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class WasmModuleBuilder {
|
class WasmModuleBuilder {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.types = [];
|
this.types = [];
|
||||||
this.imports = [];
|
this.imports = [];
|
||||||
this.exports = [];
|
this.exports = [];
|
||||||
this.globals = [];
|
this.globals = [];
|
||||||
|
this.tables = [];
|
||||||
|
this.exceptions = [];
|
||||||
this.functions = [];
|
this.functions = [];
|
||||||
this.table_length_min = 0;
|
|
||||||
this.table_length_max = undefined;
|
|
||||||
this.element_segments = [];
|
this.element_segments = [];
|
||||||
this.data_segments = [];
|
this.data_segments = [];
|
||||||
this.segments = [];
|
|
||||||
this.explicit = [];
|
this.explicit = [];
|
||||||
this.num_imported_funcs = 0;
|
this.num_imported_funcs = 0;
|
||||||
this.num_imported_globals = 0;
|
this.num_imported_globals = 0;
|
||||||
|
this.num_imported_tables = 0;
|
||||||
|
this.num_imported_exceptions = 0;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -514,8 +703,8 @@ class WasmModuleBuilder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
addMemory(min, max, exp) {
|
addMemory(min, max, exp, shared) {
|
||||||
this.memory = {min: min, max: max, exp: exp};
|
this.memory = {min: min, max: max, exp: exp, shared: shared};
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -524,6 +713,26 @@ class WasmModuleBuilder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stringToBytes(name) {
|
||||||
|
var result = new Binary();
|
||||||
|
result.emit_string(name);
|
||||||
|
return result.trunc_buffer()
|
||||||
|
}
|
||||||
|
|
||||||
|
createCustomSection(name, bytes) {
|
||||||
|
name = this.stringToBytes(name);
|
||||||
|
var section = new Binary();
|
||||||
|
section.emit_u8(kUnknownSectionCode);
|
||||||
|
section.emit_u32v(name.length + bytes.length);
|
||||||
|
section.emit_bytes(name);
|
||||||
|
section.emit_bytes(bytes);
|
||||||
|
return section.trunc_buffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
addCustomSection(name, bytes) {
|
||||||
|
this.explicit.push(this.createCustomSection(name, bytes));
|
||||||
|
}
|
||||||
|
|
||||||
addType(type) {
|
addType(type) {
|
||||||
this.types.push(type);
|
this.types.push(type);
|
||||||
var pl = type.params.length; // should have params
|
var pl = type.params.length; // should have params
|
||||||
|
@ -538,6 +747,24 @@ class WasmModuleBuilder {
|
||||||
return glob;
|
return glob;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addTable(type, initial_size, max_size = undefined) {
|
||||||
|
if (type != kWasmAnyRef && type != kWasmAnyFunc && type != kWasmExnRef) {
|
||||||
|
throw new Error(
|
||||||
|
'Tables must be of type kWasmAnyRef, kWasmAnyFunc, or kWasmExnRef');
|
||||||
|
}
|
||||||
|
let table = new WasmTableBuilder(this, type, initial_size, max_size);
|
||||||
|
table.index = this.tables.length + this.num_imported_tables;
|
||||||
|
this.tables.push(table);
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
|
||||||
|
addException(type) {
|
||||||
|
let type_index = (typeof type) == "number" ? type : this.addType(type);
|
||||||
|
let except_index = this.exceptions.length + this.num_imported_exceptions;
|
||||||
|
this.exceptions.push(type_index);
|
||||||
|
return except_index;
|
||||||
|
}
|
||||||
|
|
||||||
addFunction(name, type) {
|
addFunction(name, type) {
|
||||||
let type_index = (typeof type) == "number" ? type : this.addType(type);
|
let type_index = (typeof type) == "number" ? type : this.addType(type);
|
||||||
let func = new WasmFunctionBuilder(this, name, type_index);
|
let func = new WasmFunctionBuilder(this, name, type_index);
|
||||||
|
@ -547,6 +774,9 @@ class WasmModuleBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
addImport(module, name, type) {
|
addImport(module, name, type) {
|
||||||
|
if (this.functions.length != 0) {
|
||||||
|
throw new Error('Imported functions must be declared before local ones');
|
||||||
|
}
|
||||||
let type_index = (typeof type) == "number" ? type : this.addType(type);
|
let type_index = (typeof type) == "number" ? type : this.addType(type);
|
||||||
this.imports.push({module: module, name: name, kind: kExternalFunction,
|
this.imports.push({module: module, name: name, kind: kExternalFunction,
|
||||||
type: type_index});
|
type: type_index});
|
||||||
|
@ -554,23 +784,40 @@ class WasmModuleBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
addImportedGlobal(module, name, type, mutable = false) {
|
addImportedGlobal(module, name, type, mutable = false) {
|
||||||
|
if (this.globals.length != 0) {
|
||||||
|
throw new Error('Imported globals must be declared before local ones');
|
||||||
|
}
|
||||||
let o = {module: module, name: name, kind: kExternalGlobal, type: type,
|
let o = {module: module, name: name, kind: kExternalGlobal, type: type,
|
||||||
mutable: mutable};
|
mutable: mutable};
|
||||||
this.imports.push(o);
|
this.imports.push(o);
|
||||||
return this.num_imported_globals++;
|
return this.num_imported_globals++;
|
||||||
}
|
}
|
||||||
|
|
||||||
addImportedMemory(module, name, initial = 0, maximum) {
|
addImportedMemory(module, name, initial = 0, maximum, shared) {
|
||||||
let o = {module: module, name: name, kind: kExternalMemory,
|
let o = {module: module, name: name, kind: kExternalMemory,
|
||||||
initial: initial, maximum: maximum};
|
initial: initial, maximum: maximum, shared: shared};
|
||||||
this.imports.push(o);
|
this.imports.push(o);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
addImportedTable(module, name, initial, maximum) {
|
addImportedTable(module, name, initial, maximum, type) {
|
||||||
|
if (this.tables.length != 0) {
|
||||||
|
throw new Error('Imported tables must be declared before local ones');
|
||||||
|
}
|
||||||
let o = {module: module, name: name, kind: kExternalTable, initial: initial,
|
let o = {module: module, name: name, kind: kExternalTable, initial: initial,
|
||||||
maximum: maximum};
|
maximum: maximum, type: type || kWasmAnyFunctionTypeForm};
|
||||||
this.imports.push(o);
|
this.imports.push(o);
|
||||||
|
return this.num_imported_tables++;
|
||||||
|
}
|
||||||
|
|
||||||
|
addImportedException(module, name, type) {
|
||||||
|
if (this.exceptions.length != 0) {
|
||||||
|
throw new Error('Imported exceptions must be declared before local ones');
|
||||||
|
}
|
||||||
|
let type_index = (typeof type) == "number" ? type : this.addType(type);
|
||||||
|
let o = {module: module, name: name, kind: kExternalException, type: type_index};
|
||||||
|
this.imports.push(o);
|
||||||
|
return this.num_imported_exceptions++;
|
||||||
}
|
}
|
||||||
|
|
||||||
addExport(name, index) {
|
addExport(name, index) {
|
||||||
|
@ -585,7 +832,12 @@ class WasmModuleBuilder {
|
||||||
|
|
||||||
addDataSegment(addr, data, is_global = false) {
|
addDataSegment(addr, data, is_global = false) {
|
||||||
this.data_segments.push(
|
this.data_segments.push(
|
||||||
{addr: addr, data: data, is_global: is_global});
|
{addr: addr, data: data, is_global: is_global, is_active: true});
|
||||||
|
return this.data_segments.length - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
addPassiveDataSegment(data) {
|
||||||
|
this.data_segments.push({data: data, is_active: false});
|
||||||
return this.data_segments.length - 1;
|
return this.data_segments.length - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -593,18 +845,14 @@ class WasmModuleBuilder {
|
||||||
this.exports.push({name: name, kind: kExternalMemory, index: 0});
|
this.exports.push({name: name, kind: kExternalMemory, index: 0});
|
||||||
}
|
}
|
||||||
|
|
||||||
addElementSegment(base, is_global, array, is_import = false) {
|
addElementSegment(table, base, is_global, array) {
|
||||||
this.element_segments.push({base: base, is_global: is_global,
|
this.element_segments.push({table: table, base: base, is_global: is_global,
|
||||||
array: array});
|
array: array, is_active: true});
|
||||||
if (!is_global) {
|
return this;
|
||||||
var length = base + array.length;
|
}
|
||||||
if (length > this.table_length_min && !is_import) {
|
|
||||||
this.table_length_min = length;
|
addPassiveElementSegment(array, is_import = false) {
|
||||||
}
|
this.element_segments.push({array: array, is_active: false});
|
||||||
if (length > this.table_length_max && !is_import) {
|
|
||||||
this.table_length_max = length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -613,12 +861,30 @@ class WasmModuleBuilder {
|
||||||
if (typeof n != 'number')
|
if (typeof n != 'number')
|
||||||
throw new Error('invalid table (entries have to be numbers): ' + array);
|
throw new Error('invalid table (entries have to be numbers): ' + array);
|
||||||
}
|
}
|
||||||
return this.addElementSegment(this.table_length_min, false, array);
|
if (this.tables.length == 0) {
|
||||||
|
this.addTable(kWasmAnyFunc, 0);
|
||||||
|
}
|
||||||
|
// Adjust the table to the correct size.
|
||||||
|
let table = this.tables[0];
|
||||||
|
const base = table.initial_size;
|
||||||
|
const table_size = base + array.length;
|
||||||
|
table.initial_size = table_size;
|
||||||
|
if (table.has_max && table_size > table.max_size) {
|
||||||
|
table.max_size = table_size;
|
||||||
|
}
|
||||||
|
return this.addElementSegment(0, base, false, array);
|
||||||
}
|
}
|
||||||
|
|
||||||
setTableBounds(min, max = undefined) {
|
setTableBounds(min, max = undefined) {
|
||||||
this.table_length_min = min;
|
if (this.tables.length != 0) {
|
||||||
this.table_length_max = max;
|
throw new Error("The table bounds of table '0' have already been set.");
|
||||||
|
}
|
||||||
|
this.addTable(kWasmAnyFunc, min, max);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
setName(name) {
|
||||||
|
this.name = name;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -664,15 +930,23 @@ class WasmModuleBuilder {
|
||||||
section.emit_u8(imp.mutable);
|
section.emit_u8(imp.mutable);
|
||||||
} else if (imp.kind == kExternalMemory) {
|
} else if (imp.kind == kExternalMemory) {
|
||||||
var has_max = (typeof imp.maximum) != "undefined";
|
var has_max = (typeof imp.maximum) != "undefined";
|
||||||
section.emit_u8(has_max ? 1 : 0); // flags
|
var is_shared = (typeof imp.shared) != "undefined";
|
||||||
|
if (is_shared) {
|
||||||
|
section.emit_u8(has_max ? 3 : 2); // flags
|
||||||
|
} else {
|
||||||
|
section.emit_u8(has_max ? 1 : 0); // flags
|
||||||
|
}
|
||||||
section.emit_u32v(imp.initial); // initial
|
section.emit_u32v(imp.initial); // initial
|
||||||
if (has_max) section.emit_u32v(imp.maximum); // maximum
|
if (has_max) section.emit_u32v(imp.maximum); // maximum
|
||||||
} else if (imp.kind == kExternalTable) {
|
} else if (imp.kind == kExternalTable) {
|
||||||
section.emit_u8(kWasmAnyFunctionTypeForm);
|
section.emit_u8(imp.type);
|
||||||
var has_max = (typeof imp.maximum) != "undefined";
|
var has_max = (typeof imp.maximum) != "undefined";
|
||||||
section.emit_u8(has_max ? 1 : 0); // flags
|
section.emit_u8(has_max ? 1 : 0); // flags
|
||||||
section.emit_u32v(imp.initial); // initial
|
section.emit_u32v(imp.initial); // initial
|
||||||
if (has_max) section.emit_u32v(imp.maximum); // maximum
|
if (has_max) section.emit_u32v(imp.maximum); // maximum
|
||||||
|
} else if (imp.kind == kExternalException) {
|
||||||
|
section.emit_u32v(kExceptionAttribute);
|
||||||
|
section.emit_u32v(imp.type);
|
||||||
} else {
|
} else {
|
||||||
throw new Error("unknown/unsupported import kind " + imp.kind);
|
throw new Error("unknown/unsupported import kind " + imp.kind);
|
||||||
}
|
}
|
||||||
|
@ -681,31 +955,27 @@ class WasmModuleBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add functions declarations
|
// Add functions declarations
|
||||||
let has_names = false;
|
|
||||||
let names = false;
|
|
||||||
if (wasm.functions.length > 0) {
|
if (wasm.functions.length > 0) {
|
||||||
if (debug) print("emitting function decls @ " + binary.length);
|
if (debug) print("emitting function decls @ " + binary.length);
|
||||||
binary.emit_section(kFunctionSectionCode, section => {
|
binary.emit_section(kFunctionSectionCode, section => {
|
||||||
section.emit_u32v(wasm.functions.length);
|
section.emit_u32v(wasm.functions.length);
|
||||||
for (let func of wasm.functions) {
|
for (let func of wasm.functions) {
|
||||||
has_names = has_names || (func.name != undefined &&
|
|
||||||
func.name.length > 0);
|
|
||||||
section.emit_u32v(func.type_index);
|
section.emit_u32v(func.type_index);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add table section
|
// Add table section
|
||||||
if (wasm.table_length_min > 0) {
|
if (wasm.tables.length > 0) {
|
||||||
if (debug) print("emitting table @ " + binary.length);
|
if (debug) print ("emitting tables @ " + binary.length);
|
||||||
binary.emit_section(kTableSectionCode, section => {
|
binary.emit_section(kTableSectionCode, section => {
|
||||||
section.emit_u8(1); // one table entry
|
section.emit_u32v(wasm.tables.length);
|
||||||
section.emit_u8(kWasmAnyFunctionTypeForm);
|
for (let table of wasm.tables) {
|
||||||
const max = wasm.table_length_max;
|
section.emit_u8(table.type);
|
||||||
const has_max = max !== undefined;
|
section.emit_u8(table.has_max);
|
||||||
section.emit_u8(has_max ? kHasMaximumFlag : 0);
|
section.emit_u32v(table.initial_size);
|
||||||
section.emit_u32v(wasm.table_length_min);
|
if (table.has_max) section.emit_u32v(table.max_size);
|
||||||
if (has_max) section.emit_u32v(max);
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -715,7 +985,13 @@ class WasmModuleBuilder {
|
||||||
binary.emit_section(kMemorySectionCode, section => {
|
binary.emit_section(kMemorySectionCode, section => {
|
||||||
section.emit_u8(1); // one memory entry
|
section.emit_u8(1); // one memory entry
|
||||||
const has_max = wasm.memory.max !== undefined;
|
const has_max = wasm.memory.max !== undefined;
|
||||||
section.emit_u8(has_max ? 1 : 0);
|
const is_shared = wasm.memory.shared !== undefined;
|
||||||
|
// Emit flags (bit 0: reszeable max, bit 1: shared memory)
|
||||||
|
if (is_shared) {
|
||||||
|
section.emit_u8(has_max ? kSharedHasMaximumFlag : 2);
|
||||||
|
} else {
|
||||||
|
section.emit_u8(has_max ? kHasMaximumFlag : 0);
|
||||||
|
}
|
||||||
section.emit_u32v(wasm.memory.min);
|
section.emit_u32v(wasm.memory.min);
|
||||||
if (has_max) section.emit_u32v(wasm.memory.max);
|
if (has_max) section.emit_u32v(wasm.memory.max);
|
||||||
});
|
});
|
||||||
|
@ -738,7 +1014,7 @@ class WasmModuleBuilder {
|
||||||
break;
|
break;
|
||||||
case kWasmI64:
|
case kWasmI64:
|
||||||
section.emit_u8(kExprI64Const);
|
section.emit_u8(kExprI64Const);
|
||||||
section.emit_u8(global.init);
|
section.emit_u64v(global.init);
|
||||||
break;
|
break;
|
||||||
case kWasmF32:
|
case kWasmF32:
|
||||||
section.emit_u8(kExprF32Const);
|
section.emit_u8(kExprF32Const);
|
||||||
|
@ -750,10 +1026,22 @@ class WasmModuleBuilder {
|
||||||
f64_view[0] = global.init;
|
f64_view[0] = global.init;
|
||||||
section.emit_bytes(f64_bytes_view);
|
section.emit_bytes(f64_bytes_view);
|
||||||
break;
|
break;
|
||||||
|
case kWasmAnyFunc:
|
||||||
|
case kWasmAnyRef:
|
||||||
|
if (global.function_index !== undefined) {
|
||||||
|
section.emit_u8(kExprRefFunc);
|
||||||
|
section.emit_u32v(global.function_index);
|
||||||
|
} else {
|
||||||
|
section.emit_u8(kExprRefNull);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case kWasmExnRef:
|
||||||
|
section.emit_u8(kExprRefNull);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Emit a global-index initializer.
|
// Emit a global-index initializer.
|
||||||
section.emit_u8(kExprGetGlobal);
|
section.emit_u8(kExprGlobalGet);
|
||||||
section.emit_u32v(global.init_index);
|
section.emit_u32v(global.init_index);
|
||||||
}
|
}
|
||||||
section.emit_u8(kExprEnd); // end of init expression
|
section.emit_u8(kExprEnd); // end of init expression
|
||||||
|
@ -761,6 +1049,18 @@ class WasmModuleBuilder {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add exceptions.
|
||||||
|
if (wasm.exceptions.length > 0) {
|
||||||
|
if (debug) print("emitting exceptions @ " + binary.length);
|
||||||
|
binary.emit_section(kExceptionSectionCode, section => {
|
||||||
|
section.emit_u32v(wasm.exceptions.length);
|
||||||
|
for (let type of wasm.exceptions) {
|
||||||
|
section.emit_u32v(kExceptionAttribute);
|
||||||
|
section.emit_u32v(type);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Add export table.
|
// Add export table.
|
||||||
var mem_export = (wasm.memory !== undefined && wasm.memory.exp);
|
var mem_export = (wasm.memory !== undefined && wasm.memory.exp);
|
||||||
var exports_count = wasm.exports.length + (mem_export ? 1 : 0);
|
var exports_count = wasm.exports.length + (mem_export ? 1 : 0);
|
||||||
|
@ -797,22 +1097,55 @@ class WasmModuleBuilder {
|
||||||
section.emit_u32v(inits.length);
|
section.emit_u32v(inits.length);
|
||||||
|
|
||||||
for (let init of inits) {
|
for (let init of inits) {
|
||||||
section.emit_u8(0); // table index / flags
|
if (init.is_active) {
|
||||||
if (init.is_global) {
|
// Active segment.
|
||||||
section.emit_u8(kExprGetGlobal);
|
if (init.table == 0) {
|
||||||
|
section.emit_u32v(kActiveNoIndex);
|
||||||
|
} else {
|
||||||
|
section.emit_u32v(kActiveWithIndex);
|
||||||
|
section.emit_u32v(init.table);
|
||||||
|
}
|
||||||
|
if (init.is_global) {
|
||||||
|
section.emit_u8(kExprGlobalGet);
|
||||||
|
} else {
|
||||||
|
section.emit_u8(kExprI32Const);
|
||||||
|
}
|
||||||
|
section.emit_u32v(init.base);
|
||||||
|
section.emit_u8(kExprEnd);
|
||||||
|
if (init.table != 0) {
|
||||||
|
section.emit_u8(kExternalFunction);
|
||||||
|
}
|
||||||
|
section.emit_u32v(init.array.length);
|
||||||
|
for (let index of init.array) {
|
||||||
|
section.emit_u32v(index);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
section.emit_u8(kExprI32Const);
|
// Passive segment.
|
||||||
}
|
section.emit_u8(kPassiveWithElements); // flags
|
||||||
section.emit_u32v(init.base);
|
section.emit_u8(kWasmAnyFunc);
|
||||||
section.emit_u8(kExprEnd);
|
section.emit_u32v(init.array.length);
|
||||||
section.emit_u32v(init.array.length);
|
for (let index of init.array) {
|
||||||
for (let index of init.array) {
|
if (index === null) {
|
||||||
section.emit_u32v(index);
|
section.emit_u8(kExprRefNull);
|
||||||
|
section.emit_u8(kExprEnd);
|
||||||
|
} else {
|
||||||
|
section.emit_u8(kExprRefFunc);
|
||||||
|
section.emit_u32v(index);
|
||||||
|
section.emit_u8(kExprEnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If there are any passive data segments, add the DataCount section.
|
||||||
|
if (wasm.data_segments.some(seg => !seg.is_active)) {
|
||||||
|
binary.emit_section(kDataCountSectionCode, section => {
|
||||||
|
section.emit_u32v(wasm.data_segments.length);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Add function bodies.
|
// Add function bodies.
|
||||||
if (wasm.functions.length > 0) {
|
if (wasm.functions.length > 0) {
|
||||||
// emit function bodies
|
// emit function bodies
|
||||||
|
@ -824,9 +1157,7 @@ class WasmModuleBuilder {
|
||||||
header.reset();
|
header.reset();
|
||||||
// Function body length will be patched later.
|
// Function body length will be patched later.
|
||||||
let local_decls = [];
|
let local_decls = [];
|
||||||
let l = func.locals;
|
for (let l of func.locals || []) {
|
||||||
if (l != undefined) {
|
|
||||||
let local_decls_count = 0;
|
|
||||||
if (l.i32_count > 0) {
|
if (l.i32_count > 0) {
|
||||||
local_decls.push({count: l.i32_count, type: kWasmI32});
|
local_decls.push({count: l.i32_count, type: kWasmI32});
|
||||||
}
|
}
|
||||||
|
@ -839,6 +1170,18 @@ class WasmModuleBuilder {
|
||||||
if (l.f64_count > 0) {
|
if (l.f64_count > 0) {
|
||||||
local_decls.push({count: l.f64_count, type: kWasmF64});
|
local_decls.push({count: l.f64_count, type: kWasmF64});
|
||||||
}
|
}
|
||||||
|
if (l.s128_count > 0) {
|
||||||
|
local_decls.push({count: l.s128_count, type: kWasmS128});
|
||||||
|
}
|
||||||
|
if (l.anyref_count > 0) {
|
||||||
|
local_decls.push({count: l.anyref_count, type: kWasmAnyRef});
|
||||||
|
}
|
||||||
|
if (l.anyfunc_count > 0) {
|
||||||
|
local_decls.push({count: l.anyfunc_count, type: kWasmAnyFunc});
|
||||||
|
}
|
||||||
|
if (l.except_count > 0) {
|
||||||
|
local_decls.push({count: l.except_count, type: kWasmExnRef});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
header.emit_u32v(local_decls.length);
|
header.emit_u32v(local_decls.length);
|
||||||
|
@ -860,17 +1203,21 @@ class WasmModuleBuilder {
|
||||||
binary.emit_section(kDataSectionCode, section => {
|
binary.emit_section(kDataSectionCode, section => {
|
||||||
section.emit_u32v(wasm.data_segments.length);
|
section.emit_u32v(wasm.data_segments.length);
|
||||||
for (let seg of wasm.data_segments) {
|
for (let seg of wasm.data_segments) {
|
||||||
section.emit_u8(0); // linear memory index 0 / flags
|
if (seg.is_active) {
|
||||||
if (seg.is_global) {
|
section.emit_u8(0); // linear memory index 0 / flags
|
||||||
// initializer is a global variable
|
if (seg.is_global) {
|
||||||
section.emit_u8(kExprGetGlobal);
|
// initializer is a global variable
|
||||||
section.emit_u32v(seg.addr);
|
section.emit_u8(kExprGlobalGet);
|
||||||
|
section.emit_u32v(seg.addr);
|
||||||
|
} else {
|
||||||
|
// initializer is a constant
|
||||||
|
section.emit_u8(kExprI32Const);
|
||||||
|
section.emit_u32v(seg.addr);
|
||||||
|
}
|
||||||
|
section.emit_u8(kExprEnd);
|
||||||
} else {
|
} else {
|
||||||
// initializer is a constant
|
section.emit_u8(kPassive); // flags
|
||||||
section.emit_u8(kExprI32Const);
|
|
||||||
section.emit_u32v(seg.addr);
|
|
||||||
}
|
}
|
||||||
section.emit_u8(kExprEnd);
|
|
||||||
section.emit_u32v(seg.data.length);
|
section.emit_u32v(seg.data.length);
|
||||||
section.emit_bytes(seg.data);
|
section.emit_bytes(seg.data);
|
||||||
}
|
}
|
||||||
|
@ -883,21 +1230,50 @@ class WasmModuleBuilder {
|
||||||
binary.emit_bytes(exp);
|
binary.emit_bytes(exp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add function names.
|
// Add names.
|
||||||
if (has_names) {
|
let num_function_names = 0;
|
||||||
if (debug) print("emitting names @ " + binary.length);
|
let num_functions_with_local_names = 0;
|
||||||
|
for (let func of wasm.functions) {
|
||||||
|
if (func.name !== undefined) ++num_function_names;
|
||||||
|
if (func.numLocalNames() > 0) ++num_functions_with_local_names;
|
||||||
|
}
|
||||||
|
if (num_function_names > 0 || num_functions_with_local_names > 0 ||
|
||||||
|
wasm.name !== undefined) {
|
||||||
|
if (debug) print('emitting names @ ' + binary.length);
|
||||||
binary.emit_section(kUnknownSectionCode, section => {
|
binary.emit_section(kUnknownSectionCode, section => {
|
||||||
section.emit_string("name");
|
section.emit_string('name');
|
||||||
var count = wasm.functions.length + wasm.num_imported_funcs;
|
// Emit module name.
|
||||||
section.emit_u32v(count);
|
if (wasm.name !== undefined) {
|
||||||
for (var i = 0; i < wasm.num_imported_funcs; i++) {
|
section.emit_section(kModuleNameCode, name_section => {
|
||||||
section.emit_u8(0); // empty string
|
name_section.emit_string(wasm.name);
|
||||||
section.emit_u8(0); // local names count == 0
|
});
|
||||||
}
|
}
|
||||||
for (let func of wasm.functions) {
|
// Emit function names.
|
||||||
var name = func.name == undefined ? "" : func.name;
|
if (num_function_names > 0) {
|
||||||
section.emit_string(name);
|
section.emit_section(kFunctionNamesCode, name_section => {
|
||||||
section.emit_u8(0); // local names count == 0
|
name_section.emit_u32v(num_function_names);
|
||||||
|
for (let func of wasm.functions) {
|
||||||
|
if (func.name === undefined) continue;
|
||||||
|
name_section.emit_u32v(func.index);
|
||||||
|
name_section.emit_string(func.name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Emit local names.
|
||||||
|
if (num_functions_with_local_names > 0) {
|
||||||
|
section.emit_section(kLocalNamesCode, name_section => {
|
||||||
|
name_section.emit_u32v(num_functions_with_local_names);
|
||||||
|
for (let func of wasm.functions) {
|
||||||
|
if (func.numLocalNames() == 0) continue;
|
||||||
|
name_section.emit_u32v(func.index);
|
||||||
|
name_section.emit_u32v(func.numLocalNames());
|
||||||
|
for (let i = 0; i < func.local_names.length; ++i) {
|
||||||
|
if (func.local_names[i] === undefined) continue;
|
||||||
|
name_section.emit_u32v(i);
|
||||||
|
name_section.emit_string(func.local_names[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -925,13 +1301,24 @@ class WasmModuleBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function wasmI32Const(val) {
|
function wasmSignedLeb(val, max_len = 5) {
|
||||||
let bytes = [kExprI32Const];
|
let res = [];
|
||||||
for (let i = 0; i < 4; ++i) {
|
for (let i = 0; i < max_len; ++i) {
|
||||||
bytes.push(0x80 | ((val >> (7 * i)) & 0x7f));
|
let v = val & 0x7f;
|
||||||
|
// If {v} sign-extended from 7 to 32 bits is equal to val, we are done.
|
||||||
|
if (((v << 25) >> 25) == val) {
|
||||||
|
res.push(v);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
res.push(v | 0x80);
|
||||||
|
val = val >> 7;
|
||||||
}
|
}
|
||||||
bytes.push((val >> (7 * 4)) & 0x7f);
|
throw new Error(
|
||||||
return bytes;
|
'Leb value <' + val + '> exceeds maximum length of ' + max_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
function wasmI32Const(val) {
|
||||||
|
return [kExprI32Const, ...wasmSignedLeb(val, 5)];
|
||||||
}
|
}
|
||||||
|
|
||||||
function wasmF32Const(f) {
|
function wasmF32Const(f) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue