<!doctype html>
<meta charset=utf-8>
<meta name="timeout" content="long">
<title>RTCPeerConnection.prototype.getStats</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="RTCPeerConnection-helper.js"></script>
<script>
  'use strict';

  // Test is based on the following editor draft:
  // webrtc-pc 20171130
  // webrtc-stats 20171122

  // The following helper function is called from RTCPeerConnection-helper.js
  //   getTrackFromUserMedia

  // The following helper function is called from RTCPeerConnection-helper.js
  //   exchangeIceCandidates
  //   exchangeOfferAnswer

  /*
    8.2.  getStats
      1.  Let selectorArg be the method's first argument.
      2.  Let connection be the RTCPeerConnection object on which the method was invoked.
      3.  If selectorArg is null, let selector be null.
      4.  If selectorArg is a MediaStreamTrack let selector be an RTCRtpSender
          or RTCRtpReceiver on connection which track member matches selectorArg.
          If no such sender or receiver exists, or if more than one sender or
          receiver fit this criteria, return a promise rejected with a newly
          created InvalidAccessError.
      5.  Let p be a new promise.
      6.  Run the following steps in parallel:
        1.  Gather the stats indicated by selector according to the stats selection algorithm.
        2.  Resolve p with the resulting RTCStatsReport object, containing the gathered stats.
   */
  promise_test(t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    return pc.getStats();
  }, 'getStats() with no argument should succeed');

  promise_test(t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    return pc.getStats(null);
  }, 'getStats(null) should succeed');

  /*
    8.2.  getStats
      4.  If selectorArg is a MediaStreamTrack let selector be an RTCRtpSender
          or RTCRtpReceiver on connection which track member matches selectorArg.
          If no such sender or receiver exists, or if more than one sender or
          receiver fit this criteria, return a promise rejected with a newly
          created InvalidAccessError.
   */
  promise_test(t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    return getTrackFromUserMedia('audio')
    .then(([track, mediaStream]) => {
      return promise_rejects_dom(t, 'InvalidAccessError', pc.getStats(track));
    });
  }, 'getStats() with track not added to connection should reject with InvalidAccessError');

  promise_test(t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    return getTrackFromUserMedia('audio')
    .then(([track, mediaStream]) => {
      pc.addTrack(track, mediaStream);
      return pc.getStats(track);
    });
  }, 'getStats() with track added via addTrack should succeed');

  promise_test(async t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());

    const stream = await getNoiseStream({audio: true});
    t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
    const [track] = stream.getTracks();
    pc.addTransceiver(track);

    return pc.getStats(track);
  }, 'getStats() with track added via addTransceiver should succeed');

  promise_test(t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    const transceiver1 = pc.addTransceiver('audio');

    // Create another transceiver that resends what
    // is being received, kind of like echo
    const transceiver2 = pc.addTransceiver(transceiver1.receiver.track);
    assert_equals(transceiver1.receiver.track, transceiver2.sender.track);

    return promise_rejects_dom(t, 'InvalidAccessError', pc.getStats(transceiver1.receiver.track));
  }, 'getStats() with track associated with both sender and receiver should reject with InvalidAccessError');

  /*
    8.5.  The stats selection algorithm
      2.  If selector is null, gather stats for the whole connection, add them to result,
          return result, and abort these steps.
   */
  promise_test(t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    return pc.getStats()
    .then(statsReport => {
      assert_true(!![...statsReport.values()].find(({type}) => type === 'peer-connection'));
    });
  }, 'getStats() with no argument should return stats report containing peer-connection stats on an empty PC');

  promise_test(async t => {
    const pc = createPeerConnectionWithCleanup(t);
    const pc2 = createPeerConnectionWithCleanup(t);
    const [sendtrack, mediaStream] = await getTrackFromUserMedia('audio');
    pc.addTrack(sendtrack, mediaStream);
    exchangeIceCandidates(pc, pc2);
    await Promise.all([
      exchangeOfferAnswer(pc, pc2),
      new Promise(r => pc2.ontrack = e => e.track.onunmute = r)
    ]);
    const statsReport = await pc.getStats();
    assert_true(!![...statsReport.values()].find(({type}) => type === 'peer-connection'));
    assert_true(!![...statsReport.values()].find(({type}) => type === 'outbound-rtp'));
  }, 'getStats() track with stream returns peer-connection and outbound-rtp stats');

  promise_test(async t => {
    const pc = createPeerConnectionWithCleanup(t);
    const pc2 = createPeerConnectionWithCleanup(t);
    const [sendtrack, mediaStream] = await getTrackFromUserMedia('audio');
    pc.addTrack(sendtrack);
    exchangeIceCandidates(pc, pc2);
    await Promise.all([
      exchangeOfferAnswer(pc, pc2),
      new Promise(r => pc2.ontrack = e => e.track.onunmute = r)
    ]);
    const statsReport = await pc.getStats();
    assert_true(!![...statsReport.values()].find(({type}) => type === 'peer-connection'));
    assert_true(!![...statsReport.values()].find(({type}) => type === 'outbound-rtp'));
  }, 'getStats() track without stream returns peer-connection and outbound-rtp stats');

  promise_test(async t => {
    const pc = createPeerConnectionWithCleanup(t);
    const pc2 = createPeerConnectionWithCleanup(t);
    const [sendtrack, mediaStream] = await getTrackFromUserMedia('audio');
    pc.addTrack(sendtrack, mediaStream);
    exchangeIceCandidates(pc, pc2);
    await Promise.all([
      exchangeOfferAnswer(pc, pc2),
      new Promise(r => pc2.ontrack = e => e.track.onunmute = r)
    ]);
    const statsReport = await pc.getStats();
    assert_true(!![...statsReport.values()].find(({type}) => type === 'outbound-rtp'));
  }, 'getStats() audio contains outbound-rtp stats');

  promise_test(async t => {
    const pc = createPeerConnectionWithCleanup(t);
    const pc2 = createPeerConnectionWithCleanup(t);
    const [sendtrack, mediaStream] = await getTrackFromUserMedia('video');
    pc.addTrack(sendtrack, mediaStream);
    exchangeIceCandidates(pc, pc2);
    await Promise.all([
      exchangeOfferAnswer(pc, pc2),
      new Promise(r => pc2.ontrack = e => e.track.onunmute = r)
    ]);
    const statsReport = await pc.getStats();
    assert_true(!![...statsReport.values()].find(({type}) => type === 'outbound-rtp'));
  }, 'getStats() video contains outbound-rtp stats');

  /*
    8.5.  The stats selection algorithm
      3.  If selector is an RTCRtpSender, gather stats for and add the following objects
          to result:
        - All RTCOutboundRtpStreamStats objects corresponding to selector.
        - All stats objects referenced directly or indirectly by the RTCOutboundRtpStreamStats
          objects added.
  */
  promise_test(async t => {
    const pc = createPeerConnectionWithCleanup(t);
    const pc2 = createPeerConnectionWithCleanup(t);

    let [sendtrack, mediaStream] = await getTrackFromUserMedia('audio');
    pc.addTrack(sendtrack, mediaStream);
    exchangeIceCandidates(pc, pc2);
    await Promise.all([
      exchangeOfferAnswer(pc, pc2),
      new Promise(r => pc2.ontrack = e => e.track.onunmute = r)
    ]);
    const statsReport = await pc.getStats(sendtrack);
    assert_true(!![...statsReport.values()].find(({type}) => type === 'outbound-rtp'));
  }, `getStats() on track associated with RTCRtpSender should return stats report containing outbound-rtp stats`);

  /*
    8.5.  The stats selection algorithm
      4.  If selector is an RTCRtpReceiver, gather stats for and add the following objects
          to result:
        - All RTCInboundRtpStreamStats objects corresponding to selector.
        - All stats objects referenced directly or indirectly by the RTCInboundRtpStreamStats
          added.
   */
  promise_test(async t => {
    const pc = createPeerConnectionWithCleanup(t);
    const pc2 = createPeerConnectionWithCleanup(t);

    let [track, mediaStream] = await getTrackFromUserMedia('audio');
    pc.addTrack(track, mediaStream);
    exchangeIceCandidates(pc, pc2);
    await exchangeOfferAnswer(pc, pc2);
    // Wait for unmute if the track is not already unmuted.
    // According to spec, it should be muted when being created, but this
    // is not what this test is testing, so allow it to be unmuted.
    if (pc2.getReceivers()[0].track.muted) {
      await new Promise(resolve => {
        pc2.getReceivers()[0].track.addEventListener('unmute', resolve);
      });
    }
    const statsReport = await pc2.getStats(pc2.getReceivers()[0].track);
    assert_true(!![...statsReport.values()].find(({type}) => type === 'inbound-rtp'));
  }, `getStats() on track associated with RTCRtpReceiver should return stats report containing inbound-rtp stats`);

  promise_test(async t => {
    const pc = createPeerConnectionWithCleanup(t);
    const pc2 = createPeerConnectionWithCleanup(t);

    let [track, mediaStream] = await getTrackFromUserMedia('audio');
    pc.addTrack(track, mediaStream);
    exchangeIceCandidates(pc, pc2);
    await exchangeOfferAnswer(pc, pc2);
    // Wait for unmute if the track is not already unmuted.
    // According to spec, it should be muted when being created, but this
    // is not what this test is testing, so allow it to be unmuted.
    if (pc2.getReceivers()[0].track.muted) {
      await new Promise(resolve => {
        pc2.getReceivers()[0].track.addEventListener('unmute', resolve);
      });
    }
    const statsReport = await pc2.getStats(pc2.getReceivers()[0].track);
    assert_true(!![...statsReport.values()].find(({type}) => type === 'inbound-rtp'));
  }, `getStats() audio contains inbound-rtp stats`);

  promise_test(async t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    const [track, mediaStream] = await getTrackFromUserMedia('audio');
    pc.addTransceiver(track);
    pc.addTransceiver(track);
    await promise_rejects_dom(t, 'InvalidAccessError', pc.getStats(track));
  }, `getStats(track) should not work if multiple senders have the same track`);

  promise_test(async t => {
    const kMinimumTimeElapsedBetweenGetStatsCallsMs = 500;
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    const t0 = Math.floor(performance.now());
    const t0Stats = [...(await pc.getStats()).values()].find(({type}) => type === 'peer-connection');
    await new Promise(
        r => t.step_timeout(r, kMinimumTimeElapsedBetweenGetStatsCallsMs));
    const t1Stats = [...(await pc.getStats()).values()].find(({type}) => type === 'peer-connection');
    const t1 = Math.ceil(performance.now());
    const maximumTimeElapsedBetweenGetStatsCallsMs = t1 - t0;
    const deltaTimestampMs = t1Stats.timestamp - t0Stats.timestamp;
    // The delta must be at least the time we waited between calls.
    assert_greater_than_equal(deltaTimestampMs,
                              kMinimumTimeElapsedBetweenGetStatsCallsMs);
    // The delta must be at most the time elapsed before the first getStats()
    // call and after the second getStats() call.
    assert_less_than_equal(deltaTimestampMs,
                           maximumTimeElapsedBetweenGetStatsCallsMs);
  }, `RTCStats.timestamp increases with time passing`);

</script>
