| <!doctype html> |
| <meta charset=utf-8> |
| <meta name="timeout" content="long"> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script src="RTCPeerConnection-helper.js"></script> |
| <script> |
| 'use strict'; |
| |
| // It is not possible to make `Date.now()` and `performance.timeOrigin + |
| // performance.now()` diverge inside of WPTs, so implementers beware that these |
| // tests may give FALSE positives if `timestamp` is implemented as Wall Clock. |
| |
| // TODO: crbug.com/372749742 - Timestamps from RTCStats differs slightly from |
| // performance.timeOrigin + performance.now(). We add an epsilon to the |
| // timestamp checks as a workaround to avoid making the tests flaky. |
| const kTimeEpsilon = 0.2; |
| |
| promise_test(async t => { |
| const pc = new RTCPeerConnection(); |
| t.add_cleanup(() => pc.close()); |
| |
| const t0 = performance.timeOrigin + performance.now(); |
| const report = await pc.getStats(); |
| const t1 = performance.timeOrigin + performance.now(); |
| |
| // Any locally sourced RTCStats would do for this test but we have to pick one |
| // for consistency between test runs and make no assumption about stats report |
| // iteration order. |
| const peerConnectionStats = |
| report.values().find(stats => stats.type == 'peer-connection'); |
| |
| assert_less_than_equal(t0, peerConnectionStats.timestamp + kTimeEpsilon, |
| 't0 < timestamp'); |
| assert_less_than_equal(peerConnectionStats.timestamp, t1 + kTimeEpsilon, |
| 'timestamp < t1'); |
| }, 'RTCStats.timestamp is expressed as Performance time'); |
| |
| promise_test(async t => { |
| const pc1 = new RTCPeerConnection(); |
| t.add_cleanup(() => pc1.close()); |
| const pc2 = new RTCPeerConnection(); |
| t.add_cleanup(() => pc1.close()); |
| |
| // Media is needed for RTCP reports. |
| const stream = await getNoiseStream({video: true}); |
| const [track] = stream.getTracks(); |
| t.add_cleanup(() => track.stop()); |
| pc1.addTrack(track); |
| |
| // Negotiate and ICE connect. |
| pc1.onicecandidate = e => pc2.addIceCandidate(e.candidate); |
| pc2.onicecandidate = e => pc1.addIceCandidate(e.candidate); |
| await pc1.setLocalDescription(); |
| await pc2.setRemoteDescription(pc1.localDescription); |
| await pc2.setLocalDescription(); |
| await pc1.setRemoteDescription(pc2.localDescription); |
| |
| // The report won't contain RTCP stats objects until the first RTCP report is |
| // received. This can take several seconds so we poll `getStats()` in a loop. |
| const t0 = performance.timeOrigin + performance.now(); |
| let remoteInboundRtp = null; |
| while (remoteInboundRtp == null) { |
| // When https://crbug.com/369369568 is fixed consider clearing stats cache |
| // here (e.g. SLD) and then making the interval tighter by updating `t0` to |
| // "now" if `remoteInboundRtp` was missing. |
| const report = await pc1.getStats(); |
| remoteInboundRtp = |
| report.values().find(stats => stats.type == 'remote-inbound-rtp'); |
| } |
| const t1 = performance.timeOrigin + performance.now(); |
| |
| assert_less_than_equal(t0, remoteInboundRtp.timestamp + kTimeEpsilon, |
| 't0 < timestamp'); |
| assert_less_than_equal(remoteInboundRtp.timestamp, t1 + kTimeEpsilon, |
| 'timestamp < t1'); |
| }, 'RTCRemoteInboundRtpStats.timestamp is expressed as Performance time'); |
| </script> |