Skip to content

Commit

Permalink
Add WPTs that RTCStats.timestamp is expressed in "Performance time".
Browse files Browse the repository at this point in the history
For w3c/webrtc-pc#3005

Sadly Date.now() and performance.timeOrigin + performance.now() only
diverge in edge cases (e.g. laptop going to sleep or wall clock
changing while web page is still open?) so these WPTs may give false
positives to Wall Clock implementations, but they will at least
fail if clock is completely off and document correct behavior.

The current implementation is wrong, but we still pass the test because
of no divergence here. We need to exclude Windows at the moment though
because some of its clocks has precision limitations (example: [1]) and
there seems to be some mismatch between WebRTC's current clock impl and
Performance that becomes visible in this WPT (just a few ms delta).

[1] https://source.chromium.org/chromium/chromium/src/+/main:base/time/time.h;l=1180;drc=1a6106ec2fc932237359fe1f54334a66bc4886f1

Bug: chromium:369369568
Change-Id: Iad452519800aa4c41427317d29e4fb11235b2f37
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5887191
Commit-Queue: Henrik Boström <[email protected]>
Reviewed-by: Harald Alvestrand <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1361140}
  • Loading branch information
henbos authored and chromium-wpt-export-bot committed Sep 27, 2024
1 parent a6337a9 commit e093609
Showing 1 changed file with 69 additions and 0 deletions.
69 changes: 69 additions & 0 deletions webrtc/RTCPeerConnection-getStats-timestamp.https.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<!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.

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);
assert_less_than_equal(peerConnectionStats.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);
assert_less_than_equal(remoteInboundRtp.timestamp, t1);
}, 'RTCRemoteInboundRtpStats.timestamp is expressed as Performance time');
</script>

0 comments on commit e093609

Please sign in to comment.