mirror of
https://github.com/servo/servo.git
synced 2025-06-29 03:23:41 +01:00
646 lines
28 KiB
HTML
646 lines
28 KiB
HTML
<!doctype html>
|
|
<meta charset=utf-8>
|
|
<title>RTCQuicStream.https.html</title>
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
<script src="../webrtc/RTCIceTransport-extension-helper.js"></script>
|
|
<script src="RTCQuicTransport-helper.js"></script>
|
|
<script src="RTCQuicStream-helper.js"></script>
|
|
<script>
|
|
'use strict';
|
|
|
|
// These tests are based on the following specification:
|
|
// https://w3c.github.io/webrtc-quic/
|
|
|
|
// The following helper functions are called from RTCQuicTransport-helper.js:
|
|
// makeStandaloneQuicTransport
|
|
// makeTwoConnectedQuicTransports
|
|
// The following helper functions are called from RTCQuicStream-helper.js:
|
|
// closed_stream_test
|
|
|
|
promise_test(async t => {
|
|
const [ quicTransport, ] = await makeTwoConnectedQuicTransports(t);
|
|
const quicStream = quicTransport.createStream();
|
|
assert_equals(quicStream.transport, quicTransport,
|
|
'Expect transport to be set to the creating RTCQuicTransport.');
|
|
assert_equals(quicStream.state, 'open', `Expect state to be 'open'.`);
|
|
assert_equals(quicStream.readBufferedAmount, 0,
|
|
'Expect read buffered amount to be 0.');
|
|
assert_equals(quicStream.writeBufferedAmount, 0,
|
|
'Expect write buffered amount to be 0.');
|
|
assert_greater_than(quicStream.maxWriteBufferedAmount, 0,
|
|
'Expect max write buffered amount to be greater than 0.');
|
|
}, 'createStream() returns an RTCQuicStream with initial properties set.');
|
|
|
|
promise_test(async t => {
|
|
const quicTransport = await makeStandaloneQuicTransport(t);
|
|
assert_throws('InvalidStateError', () => quicTransport.createStream());
|
|
}, 'createStream() throws if the transport is not connected.');
|
|
|
|
promise_test(async t => {
|
|
const quicTransport = await makeStandaloneQuicTransport(t);
|
|
quicTransport.stop();
|
|
assert_throws('InvalidStateError', () => quicTransport.createStream());
|
|
}, 'createStream() throws if the transport is closed.');
|
|
|
|
promise_test(async t => {
|
|
const [ quicTransport, ] = await makeTwoConnectedQuicTransports(t);
|
|
const firstQuicStream = quicTransport.createStream();
|
|
const secondQuicStream = quicTransport.createStream();
|
|
quicTransport.stop();
|
|
assert_equals(firstQuicStream.state, 'closed');
|
|
assert_equals(secondQuicStream.state, 'closed');
|
|
}, 'RTCQuicTransport.stop() closes all local streams.');
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
localQuicTransport.createStream().write({ data: new Uint8Array([42]) });
|
|
localQuicTransport.createStream().write({ data: new Uint8Array([42]) });
|
|
const remoteWatcher =
|
|
new EventWatcher(t, remoteQuicTransport, [ 'quicstream', 'statechange' ]);
|
|
const { stream: firstRemoteStream } =
|
|
await remoteWatcher.wait_for('quicstream');
|
|
const { stream: secondRemoteStream } =
|
|
await remoteWatcher.wait_for('quicstream');
|
|
localQuicTransport.stop();
|
|
await remoteWatcher.wait_for('statechange');
|
|
assert_equals(firstRemoteStream.state, 'closed');
|
|
assert_equals(secondRemoteStream.state, 'closed');
|
|
}, 'RTCQuicTransport.stop() closes all remote streams.');
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
localStream.write({ finish: true });
|
|
assert_equals(localStream.state, 'closing');
|
|
}, `write() with a finish changes state to 'closing'.`);
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
localStream.write({ data: new Uint8Array(), finish: true });
|
|
assert_equals(localStream.state, 'closing');
|
|
}, 'write() with a finish and an empty array changes state ' +
|
|
`to 'closing'.`);
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
localStream.write({ finish: true });
|
|
assert_throws('InvalidStateError', () => {
|
|
localStream.write({ finish: true });
|
|
});
|
|
}, `write() with finish twice throws InvalidStateError.`);
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
localStream.reset();
|
|
assert_equals(localStream.state, 'closed');
|
|
}, `reset() changes state to 'closed'.`);
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
localStream.write({ finish: true });
|
|
localStream.reset();
|
|
assert_equals(localStream.state, 'closed');
|
|
}, `reset() following write with finish changes state to 'closed'.`);
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
localStream.reset();
|
|
const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
|
|
const { stream: remoteStream } = await remoteWatcher.wait_for('quicstream');
|
|
assert_equals(remoteStream.state, 'open');
|
|
const remoteStreamWatcher = new EventWatcher(t, remoteStream, 'statechange');
|
|
await remoteStreamWatcher.wait_for('statechange');
|
|
assert_equals(remoteStream.state, 'closed');
|
|
}, 'createStream() followed by reset() fires a quicstream event followed ' +
|
|
`by a statechange event to 'closed' on the remote side.`);
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
localStream.write({ finish: true });
|
|
const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
|
|
const { stream: remoteStream } = await remoteWatcher.wait_for('quicstream');
|
|
assert_equals(remoteStream.state, 'open');
|
|
const remoteStreamWatcher = new EventWatcher(t, remoteStream, 'statechange');
|
|
await remoteStream.waitForReadable(remoteStream.maxReadBufferedAmount);
|
|
assert_object_equals(
|
|
remoteStream.readInto(new Uint8Array(10)),
|
|
{ amount: 0, finished: true } );
|
|
assert_equals(remoteStream.state, 'closing');
|
|
}, 'waitForReadable() promise resolves with remote finish');
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
localStream.write({ finish: true });
|
|
const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
|
|
const { stream: remoteStream } = await remoteWatcher.wait_for('quicstream');
|
|
await remoteStream.waitForReadable(remoteStream.maxReadBufferedAmount);
|
|
assert_object_equals(
|
|
remoteStream.readInto(new Uint8Array(10)),
|
|
{ amount: 0, finished: true } );
|
|
assert_equals(remoteStream.state, 'closing');
|
|
remoteStream.write({ finish: true });
|
|
assert_equals(remoteStream.state, 'closed');
|
|
}, 'write() with a finish on a stream that has already read out finish ' +
|
|
`changes state to 'closed'.`);
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
localStream.write({ finish: true });
|
|
const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
|
|
const { stream: remoteStream } = await remoteWatcher.wait_for('quicstream');
|
|
remoteStream.write({ finish: true });
|
|
assert_equals(localStream.state, 'closing');
|
|
await localStream.waitForReadable(localStream.maxReadBufferedAmount);
|
|
assert_object_equals(
|
|
localStream.readInto(new Uint8Array(10)),
|
|
{ amount: 0, finished: true } );
|
|
assert_equals(localStream.state, 'closed');
|
|
}, 'Reading out finish on stream that has already called write() with a ' +
|
|
`finish state to 'closed'.`);
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
localStream.write({ finish: true });
|
|
const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
|
|
const { stream: remoteStream } = await remoteWatcher.wait_for('quicstream');
|
|
await remoteStream.waitForReadable(remoteStream.maxReadBufferedAmount);
|
|
assert_object_equals(
|
|
remoteStream.readInto(new Uint8Array(10)),
|
|
{ amount: 0, finished: true } );
|
|
assert_equals(remoteStream.state, 'closing');
|
|
localStream.reset();
|
|
const remoteStreamWatcher = new EventWatcher(t, remoteStream, 'statechange');
|
|
await remoteStreamWatcher.wait_for('statechange');
|
|
assert_equals(remoteStream.state, 'closed');
|
|
}, 'Reading out finish then a getting a remote reset fires a statechange event ' +
|
|
`to 'closed'.`);
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
assert_throws('NotSupportedError', () =>
|
|
localStream.write({ data: new Uint8Array() }));
|
|
}, 'write() without finish and an empty array throws NotSupportedError.');
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
assert_throws('NotSupportedError', () =>
|
|
localStream.write({}));
|
|
}, 'write() without finish and no data throws NotSupportedError.');
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
localStream.write({ data: new Uint8Array([65]) });
|
|
assert_equals(localStream.writeBufferedAmount, 1);
|
|
localStream.write({ data: new Uint8Array([66, 67]) });
|
|
assert_equals(localStream.writeBufferedAmount, 3);
|
|
localStream.write({ data: new Uint8Array([68, 69, 70]) });
|
|
assert_equals(localStream.writeBufferedAmount, 6);
|
|
}, 'write() adds to writeBufferedAmount each call.');
|
|
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
localStream.write({ data: new Uint8Array([42, 43]), finish: true });
|
|
assert_equals(localStream.writeBufferedAmount, 2);
|
|
}, `write() data with a finish adds to writeBufferedAmount.`);
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
localStream.write({
|
|
data: new Uint8Array(localStream.maxWriteBufferedAmount)
|
|
});
|
|
assert_equals(localStream.writeBufferedAmount,
|
|
localStream.maxWriteBufferedAmount);
|
|
}, 'write() can write exactly maxWriteBufferedAmount.');
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
assert_throws('OperationError', () => localStream.write({
|
|
data: new Uint8Array(localStream.maxWriteBufferedAmount + 1)
|
|
}));
|
|
assert_equals(localStream.writeBufferedAmount, 0);
|
|
}, 'write() throws if data longer than maxWriteBufferedAmount.');
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
localStream.write(
|
|
{ data: new Uint8Array(10)});
|
|
assert_throws('OperationError', () => localStream.write({
|
|
data: new Uint8Array(localStream.maxWriteBufferedAmount)
|
|
}));
|
|
assert_equals(localStream.writeBufferedAmount, 10);
|
|
}, 'write() throws if total write buffered amount would be greater than ' +
|
|
'maxWriteBufferedAmount.');
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
localStream.write({ data: new Uint8Array(10) });
|
|
const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
|
|
await remoteWatcher.wait_for('quicstream');
|
|
}, 'write() causes quicstream event to fire on the remote transport.');
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
localStream.write({ finish: true });;
|
|
const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
|
|
await remoteWatcher.wait_for('quicstream');
|
|
}, 'write() with a finish causes quicstream event to fire on the ' +
|
|
'remote transport.');
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
localStream.write({ finish: true });
|
|
assert_throws('InvalidStateError',
|
|
() => localStream.write({ data: new Uint8Array([65]) }));
|
|
}, 'write() throws InvalidStateError if write() with finish has been called.');
|
|
|
|
closed_stream_test(async (t, stream) => {
|
|
assert_throws('InvalidStateError',
|
|
() => stream.write({ data: new Uint8Array([65]) }));
|
|
}, 'write() throws InvalidStateError.');
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
localStream.write({ data: generateData(10) });
|
|
const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
|
|
const { stream : remoteStream} = await remoteWatcher.wait_for('quicstream');
|
|
await remoteStream.waitForReadable(10);
|
|
assert_equals(10, remoteStream.readBufferedAmount);
|
|
remoteStream.reset();
|
|
assert_equals(0, remoteStream.readBufferedAmount);
|
|
}, 'readBufferedAmount set to 0 after local reset().');
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
localStream.write({ data: generateData(10) });
|
|
const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
|
|
const { stream : remoteStream} = await remoteWatcher.wait_for('quicstream');
|
|
await remoteStream.waitForReadable(10);
|
|
assert_equals(10, remoteStream.readBufferedAmount);
|
|
localStream.reset();
|
|
const remoteStreamWatcher =
|
|
new EventWatcher(t, remoteStream, 'statechange');
|
|
await remoteStreamWatcher.wait_for('statechange');
|
|
assert_equals(remoteStream.state, 'closed');
|
|
assert_equals(0, remoteStream.readBufferedAmount);
|
|
}, 'readBufferedAmount set to 0 after remote reset().');
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
localStream.write({ data: new Uint8Array(10) });
|
|
localStream.reset();
|
|
assert_equals(localStream.writeBufferedAmount, 0);
|
|
}, 'writeBufferedAmount set to 0 after local reset().');
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
localStream.write({ finish: true });
|
|
const remoteWatcher =
|
|
new EventWatcher(t, remoteQuicTransport, 'quicstream');
|
|
const { stream: remoteStream } = await remoteWatcher.wait_for('quicstream');
|
|
await remoteStream.waitForReadable(10);
|
|
assert_object_equals(
|
|
remoteStream.readInto(new Uint8Array(10)),
|
|
{ amount: 0, finished: true });
|
|
remoteStream.write({ data: new Uint8Array(10) });
|
|
assert_equals(remoteStream.writeBufferedAmount, 10);
|
|
remoteStream.write({ finish: true });
|
|
assert_equals(remoteStream.writeBufferedAmount, 0);
|
|
}, 'writeBufferedAmount set to 0 after reading remote finish, followed ' +
|
|
'by write() with finish.');
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
localStream.write({ data: new Uint8Array(10) });
|
|
localQuicTransport.stop();
|
|
assert_equals(localStream.writeBufferedAmount, 0);
|
|
}, 'writeBufferedAmount set to 0 after local RTCQuicTransport stop().');
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
localStream.write({ data: new Uint8Array(10) });
|
|
localStream.write({ finish: true });
|
|
assert_equals(localStream.writeBufferedAmount, 10);
|
|
}, 'writeBufferedAmount maintained after write() with finish has been called.');
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
await localStream.waitForWriteBufferedAmountBelow(0);
|
|
}, 'waitForWriteBufferedAmountBelow(0) resolves immediately.');
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
await localStream.waitForWriteBufferedAmountBelow(
|
|
localStream.maxWriteBufferedAmount);
|
|
}, 'waitForWriteBufferedAmountBelow(maxWriteBufferedAmount) resolves ' +
|
|
'immediately.');
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
localStream.write({
|
|
data: new Uint8Array(localStream.maxWriteBufferedAmount)
|
|
});
|
|
const promise1 = localStream.waitForWriteBufferedAmountBelow(0);
|
|
const promise2 = localStream.waitForWriteBufferedAmountBelow(0);
|
|
localStream.write({ finish: true });
|
|
await Promise.all([
|
|
promise_rejects(t, 'InvalidStateError', promise1),
|
|
promise_rejects(t, 'InvalidStateError', promise2)]);
|
|
}, 'Pending waitForWriteBufferedAmountBelow() promises rejected after ' +
|
|
'write() with finish.');
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
localStream.write({
|
|
data: new Uint8Array(localStream.maxWriteBufferedAmount)
|
|
});
|
|
localStream.write({ finish: true });
|
|
const promise1 = localStream.waitForWriteBufferedAmountBelow(0);
|
|
const promise2 = localStream.waitForWriteBufferedAmountBelow(0);
|
|
await Promise.all([
|
|
promise_rejects(t, 'InvalidStateError', promise1),
|
|
promise_rejects(t, 'InvalidStateError', promise2)]);
|
|
}, 'waitForWriteBufferedAmountBelow() promises immediately rejected after ' +
|
|
'wrote finish.');
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
localStream.write({
|
|
data: new Uint8Array(localStream.maxWriteBufferedAmount)
|
|
});
|
|
const promise1 = localStream.waitForWriteBufferedAmountBelow(0);
|
|
const promise2 = localStream.waitForWriteBufferedAmountBelow(0);
|
|
localStream.reset();
|
|
await Promise.all([
|
|
promise_rejects(t, 'InvalidStateError', promise1),
|
|
promise_rejects(t, 'InvalidStateError', promise2)]);
|
|
}, 'Pending waitForWriteBufferedAmountBelow() promises rejected after ' +
|
|
'reset().');
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
localStream.write({
|
|
data: new Uint8Array(localStream.maxWriteBufferedAmount)
|
|
});
|
|
const promise1 = localStream.waitForWriteBufferedAmountBelow(0);
|
|
const promise2 = localStream.waitForWriteBufferedAmountBelow(0);
|
|
localQuicTransport.stop();
|
|
await Promise.all([
|
|
promise_rejects(t, 'InvalidStateError', promise1),
|
|
promise_rejects(t, 'InvalidStateError', promise2)]);
|
|
}, 'Pending waitForWriteBufferedAmountBelow() promises rejected after ' +
|
|
'RTCQuicTransport stop().');
|
|
|
|
closed_stream_test(async (t, stream) => {
|
|
await promise_rejects(t, 'InvalidStateError',
|
|
stream.waitForWriteBufferedAmountBelow(0));
|
|
}, 'waitForWriteBufferedBelow() rejects with InvalidStateError.');
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
assert_object_equals(
|
|
localStream.readInto(new Uint8Array(10)),
|
|
{ amount: 0, finished: false } );
|
|
}, 'readInto() on new local stream returns amount 0.');
|
|
|
|
closed_stream_test(async (t, stream) => {
|
|
assert_throws('InvalidStateError', () => stream.readInto(new Uint8Array(1)));
|
|
}, 'readInto() throws InvalidStateError.');
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
localStream.write({ data: new Uint8Array([ 65 ]) });
|
|
const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
|
|
const { stream: remoteStream } = await remoteWatcher.wait_for('quicstream');
|
|
await remoteStream.waitForReadable(1);
|
|
assert_equals(remoteStream.readBufferedAmount, 1);
|
|
const readBuffer = new Uint8Array(3);
|
|
assert_object_equals(
|
|
remoteStream.readInto(readBuffer),
|
|
{ amount: 1, finished: false } );
|
|
assert_array_equals(readBuffer, [ 65, 0, 0 ]);
|
|
assert_equals(remoteStream.readBufferedAmount, 0);
|
|
}, 'Read 1 byte.');
|
|
|
|
// Returns a Uint8Array of length |amount| with generated data.
|
|
function generateData(amount) {
|
|
const data = new Uint8Array(amount);
|
|
for (let i = 0; i < data.length; i++) {
|
|
data[i] = i % 256;
|
|
}
|
|
return data;
|
|
}
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
const data = generateData(10);
|
|
localStream.write({ data: data, finish: true });
|
|
const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
|
|
const { stream: remoteStream } = await remoteWatcher.wait_for('quicstream');
|
|
await remoteStream.waitForReadable(data.length + 1);
|
|
const readBuffer = new Uint8Array(5);
|
|
assert_object_equals(
|
|
remoteStream.readInto(readBuffer),
|
|
{ amount: 5, finished: false} );
|
|
assert_array_equals(
|
|
readBuffer, data.subarray(0, 5));
|
|
const finReadBuffer = new Uint8Array(5);
|
|
assert_object_equals(
|
|
remoteStream.readInto(finReadBuffer),
|
|
{ amount: 5, finished: true} );
|
|
assert_array_equals(
|
|
finReadBuffer, data.subarray(5, data.length));
|
|
}, 'readInto() reads out finish after reading all data.');
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
localStream.write({ finish: true });
|
|
const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
|
|
const { stream: remoteStream } = await remoteWatcher.wait_for('quicstream');
|
|
await remoteStream.waitForReadable(remoteStream.maxReadBufferedAmount);
|
|
assert_object_equals(
|
|
remoteStream.readInto(new Uint8Array(10)),
|
|
{ amount: 0, finished: true } );
|
|
}, 'waitForReadable() resolves with write() with finish.');
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
const writeData = generateData(10);
|
|
localStream.write({ data: writeData });
|
|
localStream.write({ finish: true });
|
|
const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
|
|
const { stream: remoteStream } = await remoteWatcher.wait_for('quicstream');
|
|
await remoteStream.waitForReadable(11);
|
|
assert_equals(remoteStream.readBufferedAmount, 10);
|
|
const readBuffer = new Uint8Array(10);
|
|
assert_object_equals(
|
|
remoteStream.readInto(readBuffer), { amount: 10, finished: true } );
|
|
assert_array_equals(readBuffer, writeData);
|
|
}, 'waitForReadable() resolves early if remote finish is received.');
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
await promise_rejects(t, new TypeError(),
|
|
localStream.waitForReadable(localStream.maxReadBufferedAmount + 1));
|
|
}, 'waitForReadable() rejects with TypeError if amount is more than ' +
|
|
'maxReadBufferedAmount.');
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
localStream.write({ finish: true });
|
|
const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
|
|
const { stream: remoteStream } = await remoteWatcher.wait_for('quicstream');
|
|
await remoteStream.waitForReadable(remoteStream.maxReadBufferedAmount);
|
|
assert_object_equals(
|
|
remoteStream.readInto(new Uint8Array(10)),
|
|
{ amount: 0, finished: true } );
|
|
|
|
const promise1 = remoteStream.waitForReadable(10);
|
|
const promise2 = remoteStream.waitForReadable(10);
|
|
await Promise.all([
|
|
promise_rejects(t, 'InvalidStateError', promise1),
|
|
promise_rejects(t, 'InvalidStateError', promise2)]);
|
|
}, 'waitForReadable() promises immediately rejected with InvalidStateError ' +
|
|
'after finish is read out.');
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
const promise1 = localStream.waitForReadable(10);
|
|
const promise2 = localStream.waitForReadable(10);
|
|
localStream.reset();
|
|
await Promise.all([
|
|
promise_rejects(t, 'InvalidStateError', promise1),
|
|
promise_rejects(t, 'InvalidStateError', promise2)]);
|
|
}, 'Pending waitForReadable() promises rejected after reset().');
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
localStream.write({ data: new Uint8Array(1) });
|
|
const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
|
|
const { stream : remoteStream} = await remoteWatcher.wait_for('quicstream');
|
|
const promise1 = remoteStream.waitForReadable(10);
|
|
const promise2 = remoteStream.waitForReadable(10);
|
|
localStream.reset();
|
|
await Promise.all([
|
|
promise_rejects(t, 'InvalidStateError', promise1),
|
|
promise_rejects(t, 'InvalidStateError', promise2)]);
|
|
}, 'Pending waitForReadable() promises rejected after remote reset().');
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
const promise1 = localStream.waitForReadable(10);
|
|
const promise2 = localStream.waitForReadable(10);
|
|
localQuicTransport.stop();
|
|
await Promise.all([
|
|
promise_rejects(t, 'InvalidStateError', promise1),
|
|
promise_rejects(t, 'InvalidStateError', promise2)]);
|
|
}, 'Pending waitForReadable() promises rejected after RTCQuicTransport ' +
|
|
'stop().');
|
|
|
|
promise_test(async t => {
|
|
const [ localQuicTransport, remoteQuicTransport ] =
|
|
await makeTwoConnectedQuicTransports(t);
|
|
const localStream = localQuicTransport.createStream();
|
|
localStream.write({ data: new Uint8Array(1) });
|
|
const remoteWatcher = new EventWatcher(t, remoteQuicTransport, 'quicstream');
|
|
const { stream : remoteStream} = await remoteWatcher.wait_for('quicstream');
|
|
const promise1 = remoteStream.waitForReadable(10);
|
|
const promise2 = remoteStream.waitForReadable(10);
|
|
localQuicTransport.stop();
|
|
await Promise.all([
|
|
promise_rejects(t, 'InvalidStateError', promise1),
|
|
promise_rejects(t, 'InvalidStateError', promise2)]);
|
|
}, 'Pending waitForReadable() promises rejected after remote RTCQuicTransport ' +
|
|
'stop().');
|
|
|
|
closed_stream_test(async (t, stream) => {
|
|
await promise_rejects(t, 'InvalidStateError',
|
|
stream.waitForReadable(1));
|
|
}, 'waitForReadable() rejects with InvalidStateError.');
|
|
|
|
</script>
|