Commit c7be2f56 authored by Randell Jesup's avatar Randell Jesup
Browse files

Bug 1822058: Add more WebTransport web-platform tests to cover more of the API r=jib

parent b318737d
Loading
Loading
Loading
Loading
+101 −2
Original line number Diff line number Diff line
@@ -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) {
@@ -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'));
@@ -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)
  ]);

@@ -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');
+17 −0
Original line number Diff line number Diff line
@@ -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) {
+62 −0
Original line number Diff line number Diff line
@@ -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');