| // META: global=window,worker | |
| // META: script=/common/get-host-info.sub.js | |
| // META: script=resources/webtransport-test-helpers.sub.js | |
| function validate_rtt_stats(stats) { | |
| // The assumption below is that the RTT to localhost is under 5 seconds, | |
| // which is fairly generous. | |
| assert_greater_than(stats.minRtt, 0, "minRtt"); | |
| assert_less_than(stats.minRtt, 5 * 1000, "minRtt"); | |
| assert_greater_than(stats.smoothedRtt, 0, "smoothedRtt"); | |
| assert_less_than(stats.smoothedRtt, 5 * 1000, "smoothedRtt"); | |
| } | |
| promise_test(async t => { | |
| const wt = new WebTransport(webtransport_url('echo.py')); | |
| await wt.ready; | |
| const stats = await wt.getStats(); | |
| validate_rtt_stats(stats); | |
| assert_equals(stats.datagrams.expiredOutgoing, 0); | |
| assert_equals(stats.datagrams.droppedIncoming, 0); | |
| assert_equals(stats.datagrams.lostOutgoing, 0); | |
| }, "WebTransport client should be able to provide stats after connection has been established"); | |
| promise_test(async t => { | |
| const wt = new WebTransport(webtransport_url('echo.py')); | |
| await wt.ready; | |
| wt.close(); | |
| const stats = await wt.getStats(); | |
| validate_rtt_stats(stats); | |
| }, "WebTransport client should be able to provide stats after connection has been closed"); | |
| promise_test(async t => { | |
| const wt = new WebTransport(webtransport_url('echo.py')); | |
| await wt.ready; | |
| const statsPromise = wt.getStats(); | |
| wt.close(); | |
| const stats = await statsPromise; | |
| validate_rtt_stats(stats); | |
| }, "WebTransport client should be able to provide stats requested right before connection has been closed"); | |
| promise_test(async t => { | |
| const wt = new WebTransport(webtransport_url('echo.py')); | |
| const stats = await wt.getStats(); | |
| validate_rtt_stats(stats); | |
| }, "WebTransport client should be able to provide valid stats when requested before connection established"); | |
| promise_test(async t => { | |
| const wt = new WebTransport("https://webtransport.invalid/"); | |
| wt.ready.catch(e => {}); | |
| wt.closed.catch(e => {}); | |
| const error = await wt.getStats().catch(e => e); | |
| assert_equals(error.code, DOMException.INVALID_STATE_ERR); | |
| const error2 = await wt.getStats().catch(e => e); | |
| assert_equals(error2.code, DOMException.INVALID_STATE_ERR); | |
| }, "WebTransport client should throw an error when stats are requested for a failed connection"); | |
| promise_test(async t => { | |
| const wt = new WebTransport(webtransport_url('echo.py')); | |
| await wt.ready; | |
| const stats1 = wt.getStats(); | |
| const stats2 = wt.getStats(); | |
| assert_true(stats1 != stats2, "different promise returned for different getStats() calls"); | |
| validate_rtt_stats(await stats1); | |
| validate_rtt_stats(await stats2); | |
| }, "WebTransport client should be able to handle multiple concurrent stats requests"); | |
| promise_test(async t => { | |
| const wt = new WebTransport(webtransport_url('echo.py')); | |
| await wt.ready; | |
| const stats1 = await wt.getStats(); | |
| validate_rtt_stats(stats1); | |
| const stats2 = await wt.getStats(); | |
| validate_rtt_stats(stats2); | |
| }, "WebTransport client should be able to handle multiple sequential stats requests"); | |
| promise_test(async t => { | |
| const wt = new WebTransport(webtransport_url('echo.py')); | |
| await wt.ready; | |
| const numDatagrams = 64; | |
| wt.datagrams.incomingHighWaterMark = 4; | |
| const writer = wt.datagrams.writable.getWriter(); | |
| const encoder = new TextEncoder(); | |
| const promises = []; | |
| while (promises.length < numDatagrams) { | |
| const token = promises.length.toString(); | |
| promises.push(writer.write(encoder.encode(token))); | |
| } | |
| await Promise.all(promises); | |
| const maxAttempts = 40; | |
| let stats; | |
| for (let i = 0; i < maxAttempts; i++) { | |
| wait(50); | |
| stats = await wt.getStats(); | |
| if (stats.datagrams.droppedIncoming > 0) { | |
| break; | |
| } | |
| } | |
| assert_greater_than(stats.datagrams.droppedIncoming, 0); | |
| assert_less_than_equal(stats.datagrams.droppedIncoming, | |
| numDatagrams - wt.datagrams.incomingHighWaterMark); | |
| }, "WebTransport client should be able to provide droppedIncoming values for datagrams"); |