Skip to content

Commit 6dbe096

Browse files
domenicannevk
authored andcommitted
SharedArrayBuffer serializing and deserializing tests
Needed for whatwg/html#2518.
1 parent bfa83e8 commit 6dbe096

35 files changed

+812
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<!doctype html>
2+
<title>SharedArrayBuffer cannot cross agent clusters, BroadcastChannel edition</title>
3+
<script src=/resources/testharness.js></script>
4+
<script src=/resources/testharnessreport.js></script>
5+
<script>
6+
async_test(t => {
7+
const channel = new BroadcastChannel("anne was here"),
8+
dw = new Worker("resources/broadcastchannel-worker.js"),
9+
sw = new SharedWorker("resources/broadcastchannel-sharedworker.js");
10+
let startCounter = 0,
11+
dwStatus = "unknown",
12+
swStatus = "unknown";
13+
14+
channel.onmessage = t.step_func(({ data }) => {
15+
if(data === "hi") {
16+
startCounter++;
17+
if(startCounter === 2) {
18+
const sab = new SharedArrayBuffer();
19+
channel.postMessage(sab);
20+
} else if(startCounter > 2) {
21+
assert_unreached();
22+
}
23+
} else if(data === "dw-success") {
24+
dwStatus = "success";
25+
} else if(data === "sw-success") {
26+
swStatus = "success";
27+
} else {
28+
assert_unreached();
29+
}
30+
if(dwStatus === "success" && swStatus === "success") {
31+
t.done();
32+
}
33+
});
34+
});
35+
</script>
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<!DOCTYPE html>
2+
<meta charset="utf-8">
3+
<title>Structured cloning of SharedArrayBuffers: BroadcastChannel within the same agent cluster</title>
4+
<link rel="help" href="https://html.spec.whatwg.org/multipage/#structuredserialize">
5+
<link rel="help" href="https://html.spec.whatwg.org/multipage/#broadcasting-to-other-browsing-contexts">
6+
<link rel="author" title="Domenic Denicola" href="mailto:[email protected]">
7+
<script src="/resources/testharness.js"></script>
8+
<script src="/resources/testharnessreport.js"></script>
9+
10+
<div id="log"></div>
11+
12+
<script>
13+
"use strict";
14+
15+
promise_test(t => {
16+
return Promise.all([
17+
createIFrame("resources/broadcastchannel-iframe.html"),
18+
createIFrame("resources/broadcastchannel-iframe.html"),
19+
createIFrame("resources/broadcastchannel-iframe.html")
20+
]).then(() => {
21+
const sab = new SharedArrayBuffer(3);
22+
const view = new Uint8Array(sab);
23+
const channel = new BroadcastChannel("channel name");
24+
25+
return new Promise(resolve => {
26+
let soFar = 0;
27+
channel.onmessage = t.step_func(({ data: { sab: broadcastSAB, i } }) => {
28+
if (broadcastSAB) {
29+
// We only care about "broadcasts" from the workers.
30+
return;
31+
}
32+
33+
assert_true(i === 0 || i === 1 || i === 2, `Any message events must come from expected sources; got ${i}`);
34+
++soFar;
35+
36+
if (soFar === 3) {
37+
assert_equals(view[0], 1, "The first iframe must have set view[0] to 1");
38+
assert_equals(view[1], 2, "The second iframe must have set view[1] to 2");
39+
assert_equals(view[2], 3, "The third iframe must have set view[2] to 3");
40+
resolve();
41+
}
42+
});
43+
44+
channel.postMessage({ sab });
45+
});
46+
});
47+
});
48+
49+
function createIFrame(src) {
50+
return new Promise((resolve, reject) => {
51+
const iframe = document.createElement("iframe");
52+
iframe.src = src;
53+
iframe.onload = () => resolve(iframe);
54+
iframe.onerror = () => reject(`iframe with URL ${src} failed to load`);
55+
document.body.appendChild(iframe);
56+
});
57+
}
58+
</script>
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<!DOCTYPE html>
2+
<meta charset="utf-8">
3+
<title>SharedArrayBuffers, when cloned, do not give back the same object</title>
4+
<link rel="help" href="https://html.spec.whatwg.org/multipage/#structuredserialize">
5+
<link rel="author" title="Domenic Denicola" href="mailto:[email protected]">
6+
<script src="/resources/testharness.js"></script>
7+
<script src="/resources/testharnessreport.js"></script>
8+
<script src="resources/test-sab.js"></script>
9+
10+
<div id="log"></div>
11+
12+
<script>
13+
"use strict";
14+
15+
async_test(t => {
16+
const sab = new SharedArrayBuffer(1);
17+
window.addEventListener("message", t.step_func(({ data }) => {
18+
if (data.testId !== 1) {
19+
return;
20+
}
21+
22+
assertSABsHaveSameBackingBlock(sab, data.sab);
23+
24+
t.done();
25+
}));
26+
27+
window.postMessage({ sab, testId: 1 }, "*");
28+
}, "postMessaging to this window does not give back the same SharedArrayBuffer (but does use the same backing block)");
29+
30+
async_test(t => {
31+
const sab = new SharedArrayBuffer();
32+
const worker = new Worker("resources/echo-worker.js");
33+
34+
worker.addEventListener("message", t.step_func(({ data }) => {
35+
if (data.testId !== 2) {
36+
return;
37+
}
38+
39+
assert_not_equals(data.sab, sab);
40+
t.done();
41+
}));
42+
43+
worker.postMessage({ testId: 2, sab });
44+
}, "postMessaging to a worker and back does not give back the same SharedArrayBuffer");
45+
46+
async_test(t => {
47+
const sab = new SharedArrayBuffer();
48+
window.addEventListener("message", t.step_func(({ data }) => {
49+
if (data.testId !== 3) {
50+
return;
51+
}
52+
53+
assert_not_equals(data.sab, sab);
54+
t.done();
55+
}));
56+
57+
const iframe = document.createElement("iframe");
58+
iframe.onload = t.step_func(() => {
59+
iframe.contentWindow.postMessage({ testId: 3, sab }, "*");
60+
});
61+
iframe.src = "resources/echo-iframe.html";
62+
document.body.appendChild(iframe);
63+
}, "postMessaging to an iframe and back does not give back the same SharedArrayBuffer");
64+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!DOCTYPE html>
2+
<meta charset="utf-8">
3+
<title>Structured cloning of SharedArrayBuffers into a dedicated worker nested inside a dedicated worker</title>
4+
<link rel="help" href="https://html.spec.whatwg.org/multipage/#structuredserialize">
5+
<link rel="author" title="Domenic Denicola" href="mailto:[email protected]">
6+
<script src="/resources/testharness.js"></script>
7+
<script src="/resources/testharnessreport.js"></script>
8+
9+
<div id="log"></div>
10+
11+
<script>
12+
"use strict";
13+
fetch_tests_from_worker(new Worker("nested-worker-success.js"));
14+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!DOCTYPE html>
2+
<meta charset="utf-8">
3+
<title>Structured cloning of SharedArrayBuffers into a dedicated worker nested inside a shared worker</title>
4+
<link rel="help" href="https://html.spec.whatwg.org/multipage/#structuredserialize">
5+
<link rel="author" title="Domenic Denicola" href="mailto:[email protected]">
6+
<script src="/resources/testharness.js"></script>
7+
<script src="/resources/testharnessreport.js"></script>
8+
9+
<div id="log"></div>
10+
11+
<script>
12+
"use strict";
13+
fetch_tests_from_worker(new SharedWorker("nested-worker-success.js"));
14+
</script>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
"use strict";
2+
importScripts("/resources/testharness.js");
3+
importScripts("resources/test-incrementer.js");
4+
5+
promise_test(t => {
6+
const worker = new Worker("resources/incrementer-worker.js");
7+
8+
return testSharingViaIncrementerScript(t, worker, "parent worker", worker, "sub-worker");
9+
}, "postMessaging to a dedicated sub-worker allows them to see each others' modifications");
10+
11+
done();
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<!DOCTYPE html>
2+
<meta charset="utf-8">
3+
<title>SharedArrayBuffers cannot be transferred</title>
4+
<link rel="help" href="https://html.spec.whatwg.org/#structuredclone">
5+
<link rel="author" title="Domenic Denicola" href="mailto:[email protected]">
6+
<script src="/resources/testharness.js"></script>
7+
<script src="/resources/testharnessreport.js"></script>
8+
9+
<script>
10+
"use strict";
11+
12+
test(() => {
13+
const sab = new SharedArrayBuffer();
14+
assert_throws("DataCloneError", () => window.postMessage(sab, "*", [sab]));
15+
assert_throws("DataCloneError", () => window.postMessage("test", "*", [sab]));
16+
}, "Trying to transfer a SharedArrayBuffer to this window throws");
17+
18+
test(() => {
19+
const sab = new SharedArrayBuffer();
20+
const worker = new Worker("resources/incrementer.js");
21+
assert_throws("DataCloneError", () => worker.postMessage(sab, [sab]));
22+
assert_throws("DataCloneError", () => worker.postMessage("test", [sab]));
23+
}, "Trying to transfer a SharedArrayBuffer to a worker throws");
24+
25+
test(() => {
26+
const sab = new SharedArrayBuffer();
27+
const channel = new MessageChannel();
28+
assert_throws("DataCloneError", () => channel.port1.postMessage(sab, [sab]));
29+
assert_throws("DataCloneError", () => channel.port1.postMessage("test", [sab]));
30+
}, "Trying to transfer a SharedArrayBuffer through a MessagePort throws");
31+
</script>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<!DOCTYPE html>
2+
<title>Used as a service worker-controlled iframe</title>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<!DOCTYPE html>
2+
<meta charset="utf-8">
3+
<title>A test page that messes with a given SharedArrayBuffer sent from a BroadcastChannel</title>
4+
5+
<script>
6+
"use strict";
7+
const channel = new BroadcastChannel("channel name");
8+
9+
channel.onmessage = ({ data: { sab, i }, source }) => {
10+
if (!sab) {
11+
// We only care about "broadcasts" from the window
12+
return;
13+
}
14+
15+
const view = new Uint8Array(sab);
16+
view[i] = i + 1;
17+
channel.postMessage({ i });
18+
};
19+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
const channel = new BroadcastChannel("anne was here");
2+
channel.onmessageerror = ({ data }) => {
3+
if(data === null) {
4+
channel.postMessage("sw-success");
5+
}
6+
}
7+
channel.postMessage("hi");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
const channel = new BroadcastChannel("anne was here");
2+
channel.onmessage = ({ data }) => {
3+
if(data === "hi" || data === "sw-success") {
4+
return;
5+
} else if(data instanceof SharedArrayBuffer) {
6+
channel.postMessage("dw-success");
7+
}
8+
}
9+
channel.postMessage("hi");
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!DOCTYPE html>
2+
<meta charset="utf-8">
3+
<title>A test page that echos back anything postMessaged to it to its parent</title>
4+
5+
<script>
6+
"use strict";
7+
8+
window.onmessage = ({ data }) => {
9+
parent.postMessage(data, "*");
10+
};
11+
</script>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
"use strict";
2+
3+
self.onmessage = ({ data }) => {
4+
self.postMessage(data);
5+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!DOCTYPE html>
2+
<meta charset="utf-8">
3+
<title>A test page that messes with a given SharedArrayBuffer and also sets document.domain</title>
4+
<script src="test-incrementer.js"></script>
5+
6+
<script>
7+
"use strict";
8+
9+
document.domain = "{{host}}";
10+
setupDestinationIncrementer(self, parent, "*");
11+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!DOCTYPE html>
2+
<meta charset="utf-8">
3+
<title>A test page that messes with a given SharedArrayBuffer</title>
4+
<script src="test-incrementer.js"></script>
5+
6+
<script>
7+
"use strict";
8+
9+
setupDestinationIncrementer(self, parent, "*");
10+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!DOCTYPE html>
2+
<meta charset="utf-8">
3+
<title>A test page that messes with a given SharedArrayBuffer</title>
4+
<script src="test-incrementer.js"></script>
5+
6+
<script>
7+
"use strict";
8+
9+
setupDestinationIncrementer(self, opener, "*");
10+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
"use strict";
2+
importScripts("./test-incrementer.js");
3+
4+
self.onmessage = ({ data }) => {
5+
// data will be a MessagePort
6+
setupDestinationIncrementer(data, data);
7+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
"use strict";
2+
importScripts("./test-incrementer.js");
3+
4+
setupDestinationIncrementer(self, self);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<!DOCTYPE html>
2+
<meta charset="utf-8">
3+
<title>Nesting level 1</title>
4+
5+
<iframe src="nested-iframe-2.html"></iframe>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<!DOCTYPE html>
2+
<meta charset="utf-8">
3+
<title>Nesting level 2</title>
4+
5+
<iframe src="nested-iframe-3.html"></iframe>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<!DOCTYPE html>
2+
<meta charset="utf-8">
3+
<title>Nesting level 3</title>
4+
5+
<iframe src="nested-iframe-4-incrementer.html"></iframe>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!DOCTYPE html>
2+
<meta charset="utf-8">
3+
<title>A test page that messes with a given SharedArrayBuffer, nested 4 levels deep in iframes</title>
4+
<script src="test-incrementer.js"></script>
5+
6+
<script>
7+
"use strict";
8+
9+
setupDestinationIncrementer(self, parent.parent.parent.parent.parent, "*");
10+
</script>

0 commit comments

Comments
 (0)