Loading testing/web-platform/tests/webtransport/datagrams.https.any.js +101 −2 Original line number Diff line number Diff line Loading @@ -23,6 +23,20 @@ async function write_datagrams(writer, signal) { return sentTokens; } // Write N datagrams without waiting, then wait for them async function write_N_datagrams(writer, n) { const encoder = new TextEncoder(); const sentTokens = []; const promises = []; while (sentTokens.length < n) { const token = sentTokens.length.toString(); sentTokens.push(token); promises.push(writer.write(encoder.encode(token))); } await Promise.all(promises); return sentTokens; } // Read datagrams until the consumer has received enough i.e. N datagrams. Call // abort() after reading. async function read_datagrams(reader, controller, N) { Loading Loading @@ -155,6 +169,37 @@ promise_test(async t => { assert_equals(error.name, 'RangeError'); }, 'Reading datagrams with insufficient buffer should be rejected.'); promise_test(async t => { // Establish a WebTransport session. const wt = new WebTransport(webtransport_url('echo.py')); await wt.ready; const writer = wt.datagrams.writable.getWriter(); const reader = wt.datagrams.readable.getReader(); // Write and read max-size datagram. await writer.write(new Uint8Array(wt.datagrams.maxDatagramSize)); const { value: token, done } = await reader.read(); assert_false(done); assert_equals(token.length, wt.datagrams.maxDatagramSize); }, 'Transfer max-size datagram'); promise_test(async t => { // Establish a WebTransport session. const wt = new WebTransport(webtransport_url('echo.py')); await wt.ready; const writer = wt.datagrams.writable.getWriter(); const reader = wt.datagrams.readable.getReader(); // Write and read max-size datagram. await writer.write(new Uint8Array(wt.datagrams.maxDatagramSize+1)); // This should resolve with no datagram sent, which is hard to test for. // Wait for incoming datagrams to arrive, and if they do, fail. const result = await Promise.race([reader.read(), wait(500)]); assert_equals(result, undefined); }, 'Fail to transfer max-size+1 datagram'); promise_test(async t => { // Make a WebTransport connection, but session is not necessarily established. const wt = new WebTransport(webtransport_url('echo.py')); Loading @@ -166,9 +211,10 @@ promise_test(async t => { const signal = controller.signal; // Write and read datagrams. const N = 1; const N = 5; wt.datagrams.outgoingHighWaterMark = N; const [sentTokens, receivedTokens] = await Promise.all([ write_datagrams(writer, signal), write_N_datagrams(writer, N), read_datagrams(reader, controller, N) ]); Loading Loading @@ -269,3 +315,56 @@ promise_test(async t => { // incomingHighWaterMark. assert_less_than_equal(receivedDatagrams, N); }, 'Datagrams read is less than or equal to the incomingHighWaterMark'); promise_test(async t => { // Establish a WebTransport session. const wt = new WebTransport(webtransport_url('echo.py')); await wt.ready; assert_equals(wt.datagrams.incomingMaxAge, Infinity); assert_equals(wt.datagrams.outgoingMaxAge, Infinity); wt.datagrams.incomingMaxAge = 5; assert_equals(wt.datagrams.incomingMaxAge, 5); wt.datagrams.outgoingMaxAge = 5; assert_equals(wt.datagrams.outgoingMaxAge, 5); assert_throws_js(RangeError, () => { wt.datagrams.incomingMaxAge = -1; }); assert_throws_js(RangeError, () => { wt.datagrams.outgoingMaxAge = -1; }); assert_throws_js(RangeError, () => { wt.datagrams.incomingMaxAge = NaN; }); assert_throws_js(RangeError, () => { wt.datagrams.outgoingMaxAge = NaN; }); wt.datagrams.incomingMaxAge = 0; assert_equals(wt.datagrams.incomingMaxAge, Infinity); wt.datagrams.outgoingMaxAge = 0; assert_equals(wt.datagrams.outgoingMaxAge, Infinity); }, 'Datagram MaxAge getters/setters work correctly'); promise_test(async t => { // Establish a WebTransport session. const wt = new WebTransport(webtransport_url('echo.py')); await wt.ready; // Initial values are implementation-defined assert_greater_than_equal(wt.datagrams.incomingHighWaterMark, 1); assert_greater_than_equal(wt.datagrams.outgoingHighWaterMark, 1); wt.datagrams.incomingHighWaterMark = 5; assert_equals(wt.datagrams.incomingHighWaterMark, 5); wt.datagrams.outgoingHighWaterMark = 5; assert_equals(wt.datagrams.outgoingHighWaterMark, 5); assert_throws_js(RangeError, () => { wt.datagrams.incomingHighWaterMark = -1; }); assert_throws_js(RangeError, () => { wt.datagrams.outgoingHighWaterMark = -1; }); assert_throws_js(RangeError, () => { wt.datagrams.incomingHighWaterMark = NaN; }); assert_throws_js(RangeError, () => { wt.datagrams.outgoingHighWaterMark = NaN; }); wt.datagrams.incomingHighWaterMark = 0.5; assert_equals(wt.datagrams.incomingHighWaterMark, 1); wt.datagrams.outgoingHighWaterMark = 0.5; assert_equals(wt.datagrams.outgoingHighWaterMark, 1); wt.datagrams.incomingHighWaterMark = 0; assert_equals(wt.datagrams.incomingHighWaterMark, 1); wt.datagrams.outgoingHighWaterMark = 0; assert_equals(wt.datagrams.outgoingHighWaterMark, 1); }, 'Datagram HighWaterMark getters/setters work correctly'); testing/web-platform/tests/webtransport/resources/webtransport-test-helpers.sub.js +17 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,23 @@ function webtransport_code_to_http_code(n) { return first + n + Math.floor(n / 0x1e); } // Read all chunks from |readable_stream| and return as an array of arrays async function read_stream(readable_stream) { const reader = readable_stream.getReader(); let chunks = []; while (true) { const {value: chunk, done} = await reader.read(); if (done) { break; } chunks.push(chunk); } reader.releaseLock(); return chunks; } // Read all chunks from |readable_stream|, decode chunks to a utf-8 string, then // return the string. async function read_stream_as_string(readable_stream) { Loading testing/web-platform/tests/webtransport/streams-echo.https.any.js +62 −0 Original line number Diff line number Diff line Loading @@ -151,3 +151,65 @@ promise_test(async t => { } reader.releaseLock(); }, 'Can read data from a unidirectional stream with BYOB reader'); promise_test(async t => { // Establish a WebTransport session. const wt = new WebTransport(webtransport_url('echo.py')); await wt.ready; // Create a bidirectional stream. const bidi_stream = await wt.createBidirectionalStream(); // Write a message to the writable end, and close it. const writer = bidi_stream.writable.getWriter(); const bytes = new Uint8Array(16384); const [reply] = await Promise.all([ read_stream(bidi_stream.readable), writer.write(bytes), writer.write(bytes), writer.write(bytes), writer.close() ]); let len = 0; for (chunk of reply) { len += chunk.length; } // Check that the message from the readable end matches the writable end. assert_equals(len, 3*bytes.length); }, 'Transfer large chunks of data on a bidirectional stream'); promise_test(async t => { // Establish a WebTransport session. const wt = new WebTransport(webtransport_url('echo.py')); await wt.ready; // Create a unidirectional stream. const uni_stream = await wt.createUnidirectionalStream(); // Write a message to the writable end, and close it. const writer = uni_stream.getWriter(); const bytes = new Uint8Array(16384); await Promise.all([ writer.write(bytes), writer.write(bytes), writer.write(bytes), writer.close() ]); // XXX Update once chrome fixes https://crbug.com/929585 // The echo handler creates a new unidirectional stream to echo back data from // the server to client. Accept the unidirectional stream. const readable = wt.incomingUnidirectionalStreams; const stream_reader = readable.getReader(); const { value: recv_stream } = await stream_reader.read(); stream_reader.releaseLock(); // Read the data on the readable end. const reply = await read_stream(recv_stream); let len = 0; for (chunk of reply) { len += chunk.length; } // Check that the message from the readable end matches the writable end. assert_equals(len, 3*bytes.length); }, 'Transfer large chunks of data on a unidirectional stream'); Loading
testing/web-platform/tests/webtransport/datagrams.https.any.js +101 −2 Original line number Diff line number Diff line Loading @@ -23,6 +23,20 @@ async function write_datagrams(writer, signal) { return sentTokens; } // Write N datagrams without waiting, then wait for them async function write_N_datagrams(writer, n) { const encoder = new TextEncoder(); const sentTokens = []; const promises = []; while (sentTokens.length < n) { const token = sentTokens.length.toString(); sentTokens.push(token); promises.push(writer.write(encoder.encode(token))); } await Promise.all(promises); return sentTokens; } // Read datagrams until the consumer has received enough i.e. N datagrams. Call // abort() after reading. async function read_datagrams(reader, controller, N) { Loading Loading @@ -155,6 +169,37 @@ promise_test(async t => { assert_equals(error.name, 'RangeError'); }, 'Reading datagrams with insufficient buffer should be rejected.'); promise_test(async t => { // Establish a WebTransport session. const wt = new WebTransport(webtransport_url('echo.py')); await wt.ready; const writer = wt.datagrams.writable.getWriter(); const reader = wt.datagrams.readable.getReader(); // Write and read max-size datagram. await writer.write(new Uint8Array(wt.datagrams.maxDatagramSize)); const { value: token, done } = await reader.read(); assert_false(done); assert_equals(token.length, wt.datagrams.maxDatagramSize); }, 'Transfer max-size datagram'); promise_test(async t => { // Establish a WebTransport session. const wt = new WebTransport(webtransport_url('echo.py')); await wt.ready; const writer = wt.datagrams.writable.getWriter(); const reader = wt.datagrams.readable.getReader(); // Write and read max-size datagram. await writer.write(new Uint8Array(wt.datagrams.maxDatagramSize+1)); // This should resolve with no datagram sent, which is hard to test for. // Wait for incoming datagrams to arrive, and if they do, fail. const result = await Promise.race([reader.read(), wait(500)]); assert_equals(result, undefined); }, 'Fail to transfer max-size+1 datagram'); promise_test(async t => { // Make a WebTransport connection, but session is not necessarily established. const wt = new WebTransport(webtransport_url('echo.py')); Loading @@ -166,9 +211,10 @@ promise_test(async t => { const signal = controller.signal; // Write and read datagrams. const N = 1; const N = 5; wt.datagrams.outgoingHighWaterMark = N; const [sentTokens, receivedTokens] = await Promise.all([ write_datagrams(writer, signal), write_N_datagrams(writer, N), read_datagrams(reader, controller, N) ]); Loading Loading @@ -269,3 +315,56 @@ promise_test(async t => { // incomingHighWaterMark. assert_less_than_equal(receivedDatagrams, N); }, 'Datagrams read is less than or equal to the incomingHighWaterMark'); promise_test(async t => { // Establish a WebTransport session. const wt = new WebTransport(webtransport_url('echo.py')); await wt.ready; assert_equals(wt.datagrams.incomingMaxAge, Infinity); assert_equals(wt.datagrams.outgoingMaxAge, Infinity); wt.datagrams.incomingMaxAge = 5; assert_equals(wt.datagrams.incomingMaxAge, 5); wt.datagrams.outgoingMaxAge = 5; assert_equals(wt.datagrams.outgoingMaxAge, 5); assert_throws_js(RangeError, () => { wt.datagrams.incomingMaxAge = -1; }); assert_throws_js(RangeError, () => { wt.datagrams.outgoingMaxAge = -1; }); assert_throws_js(RangeError, () => { wt.datagrams.incomingMaxAge = NaN; }); assert_throws_js(RangeError, () => { wt.datagrams.outgoingMaxAge = NaN; }); wt.datagrams.incomingMaxAge = 0; assert_equals(wt.datagrams.incomingMaxAge, Infinity); wt.datagrams.outgoingMaxAge = 0; assert_equals(wt.datagrams.outgoingMaxAge, Infinity); }, 'Datagram MaxAge getters/setters work correctly'); promise_test(async t => { // Establish a WebTransport session. const wt = new WebTransport(webtransport_url('echo.py')); await wt.ready; // Initial values are implementation-defined assert_greater_than_equal(wt.datagrams.incomingHighWaterMark, 1); assert_greater_than_equal(wt.datagrams.outgoingHighWaterMark, 1); wt.datagrams.incomingHighWaterMark = 5; assert_equals(wt.datagrams.incomingHighWaterMark, 5); wt.datagrams.outgoingHighWaterMark = 5; assert_equals(wt.datagrams.outgoingHighWaterMark, 5); assert_throws_js(RangeError, () => { wt.datagrams.incomingHighWaterMark = -1; }); assert_throws_js(RangeError, () => { wt.datagrams.outgoingHighWaterMark = -1; }); assert_throws_js(RangeError, () => { wt.datagrams.incomingHighWaterMark = NaN; }); assert_throws_js(RangeError, () => { wt.datagrams.outgoingHighWaterMark = NaN; }); wt.datagrams.incomingHighWaterMark = 0.5; assert_equals(wt.datagrams.incomingHighWaterMark, 1); wt.datagrams.outgoingHighWaterMark = 0.5; assert_equals(wt.datagrams.outgoingHighWaterMark, 1); wt.datagrams.incomingHighWaterMark = 0; assert_equals(wt.datagrams.incomingHighWaterMark, 1); wt.datagrams.outgoingHighWaterMark = 0; assert_equals(wt.datagrams.outgoingHighWaterMark, 1); }, 'Datagram HighWaterMark getters/setters work correctly');
testing/web-platform/tests/webtransport/resources/webtransport-test-helpers.sub.js +17 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,23 @@ function webtransport_code_to_http_code(n) { return first + n + Math.floor(n / 0x1e); } // Read all chunks from |readable_stream| and return as an array of arrays async function read_stream(readable_stream) { const reader = readable_stream.getReader(); let chunks = []; while (true) { const {value: chunk, done} = await reader.read(); if (done) { break; } chunks.push(chunk); } reader.releaseLock(); return chunks; } // Read all chunks from |readable_stream|, decode chunks to a utf-8 string, then // return the string. async function read_stream_as_string(readable_stream) { Loading
testing/web-platform/tests/webtransport/streams-echo.https.any.js +62 −0 Original line number Diff line number Diff line Loading @@ -151,3 +151,65 @@ promise_test(async t => { } reader.releaseLock(); }, 'Can read data from a unidirectional stream with BYOB reader'); promise_test(async t => { // Establish a WebTransport session. const wt = new WebTransport(webtransport_url('echo.py')); await wt.ready; // Create a bidirectional stream. const bidi_stream = await wt.createBidirectionalStream(); // Write a message to the writable end, and close it. const writer = bidi_stream.writable.getWriter(); const bytes = new Uint8Array(16384); const [reply] = await Promise.all([ read_stream(bidi_stream.readable), writer.write(bytes), writer.write(bytes), writer.write(bytes), writer.close() ]); let len = 0; for (chunk of reply) { len += chunk.length; } // Check that the message from the readable end matches the writable end. assert_equals(len, 3*bytes.length); }, 'Transfer large chunks of data on a bidirectional stream'); promise_test(async t => { // Establish a WebTransport session. const wt = new WebTransport(webtransport_url('echo.py')); await wt.ready; // Create a unidirectional stream. const uni_stream = await wt.createUnidirectionalStream(); // Write a message to the writable end, and close it. const writer = uni_stream.getWriter(); const bytes = new Uint8Array(16384); await Promise.all([ writer.write(bytes), writer.write(bytes), writer.write(bytes), writer.close() ]); // XXX Update once chrome fixes https://crbug.com/929585 // The echo handler creates a new unidirectional stream to echo back data from // the server to client. Accept the unidirectional stream. const readable = wt.incomingUnidirectionalStreams; const stream_reader = readable.getReader(); const { value: recv_stream } = await stream_reader.read(); stream_reader.releaseLock(); // Read the data on the readable end. const reply = await read_stream(recv_stream); let len = 0; for (chunk of reply) { len += chunk.length; } // Check that the message from the readable end matches the writable end. assert_equals(len, 3*bytes.length); }, 'Transfer large chunks of data on a unidirectional stream');