Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test has a WPT meta file that expects 4 subtest issues.
- This WPT test may be referenced by the following Test IDs:
- /webtransport/receive-stream-stats.https.any.html - WPT Dashboard Interop Dashboard
- /webtransport/receive-stream-stats.https.any.serviceworker.html - WPT Dashboard Interop Dashboard
- /webtransport/receive-stream-stats.https.any.sharedworker.html - WPT Dashboard Interop Dashboard
- /webtransport/receive-stream-stats.https.any.worker.html - WPT Dashboard Interop Dashboard
// META: global=window,worker
// META: script=resources/webtransport-test-helpers.sub.js
const server_data = 'stream0';
const server_data_byte_length =
new TextEncoder().encode(server_data).byteLength;
async function create_web_transport(t, handler) {
const wt = new WebTransport(webtransport_url(handler));
t.add_cleanup(() => wt.close());
wt.closed.catch(() => {});
await wt.ready;
return wt;
}
async function open_server_stream(t, type) {
const wt = await create_web_transport(
t, `server-create-multiple-streams.py?type=${type}&count=1`);
const incoming = type === 'unidi' ? wt.incomingUnidirectionalStreams :
wt.incomingBidirectionalStreams;
const reader = incoming.getReader();
const {value: stream} = await reader.read();
reader.releaseLock();
return type === 'unidi' ? stream : stream.readable;
}
async function assert_finalized_receive_stream_stats(stream) {
assert_true(stream instanceof WebTransportReceiveStream);
const data = await read_stream_as_string(stream);
assert_equals(data, server_data);
const stats = await stream.getStats();
assert_equals(stats.bytesReceived, server_data_byte_length, 'bytesReceived');
assert_equals(stats.bytesRead, server_data_byte_length, 'bytesRead');
}
const SERVER_STREAM_CASES = [
{type: 'unidi', description: 'incoming unidirectional'},
{type: 'bidi', description: 'incoming bidirectional'},
];
for (const {type, description} of SERVER_STREAM_CASES) {
promise_test(async t => {
const stream = await open_server_stream(t, type);
await assert_finalized_receive_stream_stats(stream);
}, `getStats() reports finalized ${description} stream counters`);
}
promise_test(async t => {
const wt = await create_web_transport(t, 'echo.py');
const stream = await wt.createBidirectionalStream();
const writer = stream.writable.getWriter();
await writer.write(new TextEncoder().encode(server_data));
await writer.close();
await assert_finalized_receive_stream_stats(stream.readable);
}, 'getStats() reports finalized client-initiated bidirectional stream counters');
promise_test(async t => {
const wt = await create_web_transport(t, 'echo.py');
const stream = await wt.createBidirectionalStream();
const data = new Uint8Array(64);
const writer = stream.writable.getWriter();
await writer.write(data);
await writer.close();
const initial_stats = await stream.readable.getStats();
assert_equals(initial_stats.bytesRead, 0, 'bytesRead before read');
const reader = stream.readable.getReader({mode: 'byob'});
const {value, done} = await reader.read(new Uint8Array(1));
assert_false(done);
assert_equals(value.byteLength, 1);
const before_cancel = await stream.readable.getStats();
assert_equals(before_cancel.bytesRead, 1, 'bytesRead before cancel');
assert_greater_than_equal(before_cancel.bytesReceived,
before_cancel.bytesRead,
'bytesReceived before cancel');
assert_less_than_equal(before_cancel.bytesReceived, data.byteLength,
'bytesReceived before cancel');
await reader.cancel();
reader.releaseLock();
const after_cancel = await stream.readable.getStats();
assert_equals(after_cancel.bytesRead, 1, 'bytesRead after cancel');
assert_greater_than_equal(after_cancel.bytesReceived,
before_cancel.bytesReceived,
'bytesReceived after cancel');
assert_less_than_equal(after_cancel.bytesReceived, data.byteLength,
'bytesReceived after cancel');
wt.close();
await wt.closed;
const after_close = await stream.readable.getStats();
assert_equals(after_close.bytesReceived, after_cancel.bytesReceived,
'bytesReceived after close');
assert_equals(after_close.bytesRead, after_cancel.bytesRead,
'bytesRead after close');
}, 'getStats() preserves partial BYOB read counters after cancellation');