<!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>
