Commit c3cde9e2 authored by Reilly Grant's avatar Reilly Grant Committed by Commit Bot

serial: Add manual WPT test using a loopback device

This manual test architecture allows us to build integration tests. A
connected serial device with its transmit and receive pins connected
together is assumed.

Bug: 884928
Change-Id: I960faa894776723fd5a858ff7f35a1999afa2955
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2277582
Commit-Queue: Reilly Grant <reillyg@chromium.org>
Auto-Submit: Reilly Grant <reillyg@chromium.org>
Reviewed-by: default avatarOvidio de Jesús Ruiz-Henríquez <odejesush@chromium.org>
Cr-Commit-Position: refs/heads/master@{#789737}
parent 95e22d39
...@@ -2145,3 +2145,6 @@ virtual/subresource-web-bundles/external/wpt/web-bundle/subresource-loading/* [ ...@@ -2145,3 +2145,6 @@ virtual/subresource-web-bundles/external/wpt/web-bundle/subresource-loading/* [
# No good way to automate this test yet # No good way to automate this test yet
external/wpt/native-file-system/showSaveFilePicker-manual.https.html [ Skip ] external/wpt/native-file-system/showSaveFilePicker-manual.https.html [ Skip ]
# This test requires a physical device connected.
wpt_internal/serial/serialPort_loopback-manual.https.html [ Skip ]
\ No newline at end of file
...@@ -12,40 +12,6 @@ async function getFakeSerialPort(fake) { ...@@ -12,40 +12,6 @@ async function getFakeSerialPort(fake) {
return { port, fakePort }; return { port, fakePort };
} }
// Compare two Uint8Arrays.
function compareArrays(actual, expected) {
assert_true(actual instanceof Uint8Array, 'actual is Uint8Array');
assert_true(expected instanceof Uint8Array, 'expected is Uint8Array');
assert_equals(actual.byteLength, expected.byteLength, 'lengths equal');
for (let i = 0; i < expected.byteLength; ++i)
assert_equals(actual[i], expected[i], `Mismatch at position ${i}.`);
}
// Pull from |reader| until at least |targetLength| is read or the stream
// reports done. The data is returned as a combined Uint8Array.
async function readWithLength(reader, targetLength) {
const chunks = [];
let actualLength = 0;
while (true) {
let {value, done} = await reader.read();
chunks.push(value);
actualLength += value.byteLength;
if (actualLength >= targetLength || done) {
// It would be better to allocate |buffer| up front with the number of
// of bytes expected but this is the best that can be done without a BYOB
// reader to control the amount of data read.
const buffer = new Uint8Array(actualLength);
chunks.reduce((offset, chunk) => {
buffer.set(chunk, offset);
return offset + chunk.byteLength;
}, 0);
return buffer;
}
}
}
// Implementation of an UnderlyingSource to create a ReadableStream from a Mojo // Implementation of an UnderlyingSource to create a ReadableStream from a Mojo
// data pipe consumer handle. // data pipe consumer handle.
class DataPipeSource { class DataPipeSource {
......
// Compare two Uint8Arrays.
function compareArrays(actual, expected) {
assert_true(actual instanceof Uint8Array, 'actual is Uint8Array');
assert_true(expected instanceof Uint8Array, 'expected is Uint8Array');
assert_equals(actual.byteLength, expected.byteLength, 'lengths equal');
for (let i = 0; i < expected.byteLength; ++i)
assert_equals(actual[i], expected[i], `Mismatch at position ${i}.`);
}
// Reads from |reader| until at least |targetLength| is read or the stream is
// closed. The data is returned as a combined Uint8Array.
async function readWithLength(reader, targetLength) {
const chunks = [];
let actualLength = 0;
while (true) {
let {value, done} = await reader.read();
chunks.push(value);
actualLength += value.byteLength;
if (actualLength >= targetLength || done) {
// It would be better to allocate |buffer| up front with the number of
// of bytes expected but this is the best that can be done without a
// BYOB reader to control the amount of data read.
const buffer = new Uint8Array(actualLength);
chunks.reduce((offset, chunk) => {
buffer.set(chunk, offset);
return offset + chunk.byteLength;
}, 0);
return buffer;
}
}
}
let manualTestPort = null;
async function getPortForManualTest() {
if (manualTestPort) {
return manualTestPort;
}
const button = document.createElement('button');
button.textContent = 'Click to select a device';
button.style.display = 'block';
button.style.fontSize = '20px';
button.style.padding = '10px';
await new Promise((resolve) => {
button.onclick = () => {
document.body.removeChild(button);
resolve();
};
document.body.appendChild(button);
});
manualTestPort = await navigator.serial.requestPort({filters: []});
assert_true(manualTestPort instanceof SerialPort);
return manualTestPort;
}
function manual_loopback_serial_test(func, name, properties) {
promise_test(async (test) => {
await func(test, await getPortForManualTest());
}, name, properties);
}
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
// META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js // META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js
// META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js // META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js
// META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js // META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js
// META: script=resources/serial-test-utils.js // META: script=resources/common.js
// META: script=resources/automation.js
serial_test(async (t, fake) => { serial_test(async (t, fake) => {
const {port, fakePort} = await getFakeSerialPort(fake); const {port, fakePort} = await getFakeSerialPort(fake);
......
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
// META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js // META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js
// META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js // META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js
// META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js // META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js
// META: script=resources/serial-test-utils.js // META: script=resources/common.js
// META: script=resources/automation.js
serial_test(async (t, fake) => { serial_test(async (t, fake) => {
// Wait for getPorts() to resolve in order to ensure that the Mojo client // Wait for getPorts() to resolve in order to ensure that the Mojo client
......
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
// META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js // META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js
// META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js // META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js
// META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js // META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js
// META: script=resources/serial-test-utils.js // META: script=resources/common.js
// META: script=resources/automation.js
serial_test(async (t, fake) => { serial_test(async (t, fake) => {
const {port, fakePort} = await getFakeSerialPort(fake); const {port, fakePort} = await getFakeSerialPort(fake);
......
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/common.js"></script>
<script src="resources/manual.js"></script>
</head>
<body>
<p>
These tests require a connected serial device configured to act as a
"loopback" device, with the transmit and receive pins wired together.
</p>
<script>
manual_loopback_serial_test(async (t, port) => {
await port.open({baudrate: 9600, buffersize: 64});
const data = new Uint8Array(1024); // Much larger than buffersize above.
for (let i = 0; i < data.byteLength; ++i)
data[i] = i & 0xff;
const writer = port.writable.getWriter();
writer.write(data);
const writePromise = writer.close();
const reader = port.readable.getReader();
const value = await readWithLength(reader, data.byteLength);
reader.releaseLock();
await writePromise;
compareArrays(value, data);
await port.close();
}, 'Can perform a large write.');
manual_loopback_serial_test(async (t, port) => {
await port.open({baudrate: 115200, buffersize: 64});
let data = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]);
let writer = port.writable.getWriter();
writer.write(data);
// |data| is small enough to be completely transmitted.
await writer.close();
// Wait a little bit for the device to process the incoming data.
await new Promise((resolve) => setTimeout(resolve, 100));
await port.readable.cancel();
data = new Uint8Array([9, 10, 11, 12, 13, 14, 15, 16]);
writer = port.writable.getWriter();
writer.write(data);
await writer.close();
const reader = port.readable.getReader();
const value = await readWithLength(reader, data.byteLength);
reader.releaseLock();
compareArrays(value, data);
await port.close();
}, 'Canceling the reader discards buffered data.');
</script>
</body>
</html>
\ No newline at end of file
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
// META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js // META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js
// META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js // META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js
// META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js // META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js
// META: script=resources/serial-test-utils.js // META: script=resources/common.js
// META: script=resources/automation.js
serial_test(async (t, fake) => { serial_test(async (t, fake) => {
const {port, fakePort} = await getFakeSerialPort(fake); const {port, fakePort} = await getFakeSerialPort(fake);
......
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
// META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js // META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js
// META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js // META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js
// META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js // META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js
// META: script=resources/serial-test-utils.js // META: script=resources/common.js
// META: script=resources/automation.js
serial_test(async (t, fake) => { serial_test(async (t, fake) => {
const {port, fakePort} = await getFakeSerialPort(fake); const {port, fakePort} = await getFakeSerialPort(fake);
......
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
// META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js // META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js
// META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js // META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js
// META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js // META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js
// META: script=resources/serial-test-utils.js // META: script=resources/common.js
// META: script=resources/automation.js
serial_test(async (t, fake) => { serial_test(async (t, fake) => {
const {port, fakePort} = await getFakeSerialPort(fake); const {port, fakePort} = await getFakeSerialPort(fake);
......
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
// META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js // META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js
// META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js // META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js
// META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js // META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js
// META: script=resources/serial-test-utils.js // META: script=resources/common.js
// META: script=resources/automation.js
serial_test(async (t, fake) => { serial_test(async (t, fake) => {
const {port, fakePort} = await getFakeSerialPort(fake); const {port, fakePort} = await getFakeSerialPort(fake);
......
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
// META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js // META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js
// META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js // META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js
// META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js // META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js
// META: script=resources/serial-test-utils.js // META: script=resources/common.js
// META: script=resources/automation.js
serial_test(async (t, fake) => { serial_test(async (t, fake) => {
const {port, fakePort} = await getFakeSerialPort(fake); const {port, fakePort} = await getFakeSerialPort(fake);
......
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
// META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js // META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js
// META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js // META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js
// META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js // META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js
// META: script=resources/serial-test-utils.js // META: script=resources/common.js
// META: script=resources/automation.js
serial_test(async (t, fake) => { serial_test(async (t, fake) => {
let fakePort; let fakePort;
......
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
// META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js // META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js
// META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js // META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js
// META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js // META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js
// META: script=resources/serial-test-utils.js // META: script=resources/common.js
// META: script=resources/automation.js
serial_test(async (t, fake) => { serial_test(async (t, fake) => {
const {port, fakePort} = await getFakeSerialPort(fake); const {port, fakePort} = await getFakeSerialPort(fake);
......
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
// META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js // META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js
// META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js // META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js
// META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js // META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js
// META: script=resources/serial-test-utils.js // META: script=resources/common.js
// META: script=resources/automation.js
serial_test(async (t, fake) => { serial_test(async (t, fake) => {
const {port, fakePort} = await getFakeSerialPort(fake); const {port, fakePort} = await getFakeSerialPort(fake);
......
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
// META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js // META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js
// META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js // META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js
// META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js // META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js
// META: script=resources/serial-test-utils.js // META: script=resources/common.js
// META: script=resources/automation.js
// ParityError is not (as of 2020/03/23) a valid DOMException, so cannot use // ParityError is not (as of 2020/03/23) a valid DOMException, so cannot use
// promise_rejects_dom for it. // promise_rejects_dom for it.
......
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
// META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js // META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js
// META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js // META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js
// META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js // META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js
// META: script=resources/serial-test-utils.js // META: script=resources/common.js
// META: script=resources/automation.js
serial_test(async (t, fake) => { serial_test(async (t, fake) => {
const {port, fakePort} = await getFakeSerialPort(fake); const {port, fakePort} = await getFakeSerialPort(fake);
......
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
// META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js // META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js
// META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js // META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js
// META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js // META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js
// META: script=resources/serial-test-utils.js // META: script=resources/common.js
// META: script=resources/automation.js
serial_test(async (t, fake) => { serial_test(async (t, fake) => {
const {port, fakePort} = await getFakeSerialPort(fake); const {port, fakePort} = await getFakeSerialPort(fake);
......
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
// META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js // META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js
// META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js // META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js
// META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js // META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js
// META: script=resources/serial-test-utils.js // META: script=resources/common.js
// META: script=resources/automation.js
serial_test(async (t, fake) => { serial_test(async (t, fake) => {
const {port, fakePort} = await getFakeSerialPort(fake); const {port, fakePort} = await getFakeSerialPort(fake);
......
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
// META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js // META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js
// META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js // META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js
// META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js // META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js
// META: script=resources/serial-test-utils.js // META: script=resources/common.js
// META: script=resources/automation.js
serial_test(async (t, fake) => { serial_test(async (t, fake) => {
const {port, fakePort} = await getFakeSerialPort(fake); const {port, fakePort} = await getFakeSerialPort(fake);
......
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
// META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js // META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js
// META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js // META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js
// META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js // META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js
// META: script=resources/serial-test-utils.js // META: script=resources/common.js
// META: script=resources/automation.js
promise_test(async () => { promise_test(async () => {
let interceptor = let interceptor =
......
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
// META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js // META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js
// META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js // META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js
// META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js // META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js
// META: script=resources/serial-test-utils.js // META: script=resources/common.js
// META: script=resources/automation.js
serial_test(async (t, fake) => { serial_test(async (t, fake) => {
const eventWatcher = const eventWatcher =
......
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
// META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js // META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js
// META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js // META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js
// META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js // META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js
// META: script=resources/serial-test-utils.js // META: script=resources/common.js
// META: script=resources/automation.js
serial_test(async (t, fake) => { serial_test(async (t, fake) => {
const eventWatcher = const eventWatcher =
......
...@@ -5,7 +5,8 @@ ...@@ -5,7 +5,8 @@
// META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js // META: script=/gen/layout_test_data/mojo/public/js/mojo_bindings.js
// META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js // META: script=/gen/mojo/public/mojom/base/unguessable_token.mojom.js
// META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js // META: script=/gen/third_party/blink/public/mojom/serial/serial.mojom.js
// META: script=resources/serial-test-utils.js // META: script=resources/common.js
// META: script=resources/automation.js
promise_test((t) => { promise_test((t) => {
return promise_rejects_dom( return promise_rejects_dom(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment