<!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 src="dictionary-helper.js"></script>
<script src="RTCStats-helper.js"></script>
<script>
  'use strict';

  // The following helper functions are called from RTCPeerConnection-helper.js:
  //   exchangeOfferAnswer
  //   getUserMediaTracksAndStreams
  //   waitForRtpAndRtcpStats

  // The following helper functions are called from RTCStats-helper.js
  // (depends on dictionary-helper.js):
  //   validateRtcStats

  async_test(t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    let track;
    return getUserMediaTracksAndStreams(1)
    .then(t.step_func(([tracks, streams]) => {
      t.add_cleanup(() => tracks.forEach(track => track.stop()));
      track = tracks[0];
      pc.addTrack(track, streams[0]);
      return pc.getStats();
    }))
    .then(t.step_func(report => {
      let trackStats = findStatsByTypeAndId(report, 'track', track.id);
      assert_true(trackStats != null, 'Has stats for track');
      // TODO(hbos): Here and elsewhere, validateRtcStats() only tests id,
      // timestamp and type is correct type. Should validate based on stats type
      // but it expects both audio and video members.
      // https://github.com/web-platform-tests/wpt/issues/9010
      validateRtcStats(report, trackStats);
      t.done();
    }))
    .catch(t.step_func(reason => {
      assert_unreached(reason);
    }));
  }, 'addTrack() without setLocalDescription() yields track stats');

  async_test(t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    let stream;
    return getUserMediaTracksAndStreams(1)
    .then(t.step_func(([tracks, streams]) => {
      t.add_cleanup(() => tracks.forEach(track => track.stop()));
      let track = tracks[0];
      stream = streams[0];
      pc.addTrack(track, stream);
      return pc.getStats();
    }))
    .then(t.step_func(report => {
      let streamStats = findStatsByTypeAndId(report, 'stream', stream.id);
      assert_true(streamStats != null, 'Has stats for stream');
      validateRtcStats(report, streamStats);
      t.done();
    }))
    .catch(t.step_func(reason => {
      assert_unreached(reason);
    }));
  }, 'addTrack() without setLocalDescription() yields media stream stats');

  async_test(t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    let track;
    return getUserMediaTracksAndStreams(1)
    .then(t.step_func(([tracks, streams]) => {
      t.add_cleanup(() => tracks.forEach(track => track.stop()));
      track = tracks[0];
      pc.addTrack(track, streams[0]);
      return pc.createOffer();
    }))
    .then(t.step_func(offer => {
      return pc.setLocalDescription(offer);
    }))
    .then(t.step_func(() => {
      return pc.getStats();
    }))
    .then(t.step_func(report => {
      let trackStats = findStatsByTypeAndId(report, 'track', track.id);
      assert_true(trackStats != null, 'Has stats for track');
      validateRtcStats(report, trackStats);
      t.done();
    }))
    .catch(t.step_func(reason => {
      assert_unreached(reason);
    }));
  }, 'addTrack() with setLocalDescription() yields track stats');

  async_test(t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    let stream;
    return getUserMediaTracksAndStreams(1)
    .then(t.step_func(([tracks, streams]) => {
      t.add_cleanup(() => tracks.forEach(track => track.stop()));
      let track = tracks[0];
      stream = streams[0];
      pc.addTrack(track, stream);
      return pc.createOffer();
    }))
    .then(t.step_func(offer => {
      return pc.setLocalDescription(offer);
    }))
    .then(t.step_func(() => {
      return pc.getStats();
    }))
    .then(t.step_func(report => {
      let streamStats = findStatsByTypeAndId(report, 'stream', stream.id);
      assert_true(streamStats != null, 'Has stats for stream');
      validateRtcStats(report, streamStats);
      t.done();
    }))
    .catch(t.step_func(reason => {
      assert_unreached(reason);
    }));
  }, 'addTrack() with setLocalDescription() yields media stream stats');

  async_test(t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    let track;
    let stream;
    return getUserMediaTracksAndStreams(1)
    .then(t.step_func(([tracks, streams]) => {
      t.add_cleanup(() => tracks.forEach(track => track.stop()));
      track = tracks[0];
      stream = streams[0];
      pc.addTrack(track, stream);
      return pc.createOffer();
    }))
    .then(t.step_func(offer => {
      return pc.setLocalDescription(offer);
    }))
    .then(t.step_func(() => {
      return pc.getStats();
    }))
    .then(t.step_func(report => {
      let trackStats = findStatsByTypeAndId(report, 'track', track.id);
      let streamStats = findStatsByTypeAndId(report, 'stream', stream.id);
      assert_true(trackStats != null && streamStats != null,
                  'Has stats for track and stream');
      assert_array_equals(streamStats.trackIds, [ trackStats.id ],
                          'streamStats.trackIds == [ trackStats.id ]');
      validateRtcStats(report, trackStats);
      validateRtcStats(report, streamStats);
      t.done();
    }))
    .catch(t.step_func(reason => {
      assert_unreached(reason);
    }));
  }, 'addTrack(): Media stream stats references track stats');

  async_test(t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    let track;
    let stream;
    return getUserMediaTracksAndStreams(1)
    .then(t.step_func(([tracks, streams]) => {
      t.add_cleanup(() => tracks.forEach(track => track.stop()));
      track = tracks[0];
      stream = streams[0];
      stream.addTrack(track);
      for (const track of stream.getTracks())
        pc.addTrack(track, stream);
      return pc.createOffer();
    }))
    .then(t.step_func(offer => {
      return pc.setLocalDescription(offer);
    }))
    .then(t.step_func(() => {
      return pc.getStats();
    }))
    .then(t.step_func(report => {
      let trackStats = findStatsByTypeAndId(report, 'track', track.id);
      let streamStats = findStatsByTypeAndId(report, 'stream', stream.id);
      assert_true(trackStats != null && streamStats != null,
                  'Has stats for track and stream');
      assert_array_equals(streamStats.trackIds, [ trackStats.id ],
                          'streamStats.trackIds == [ trackStats.id ]');
      validateRtcStats(report, trackStats);
      validateRtcStats(report, streamStats);
      t.done();
    }))
    .catch(t.step_func(reason => {
      assert_unreached(reason);
    }));
  }, 'Media stream stats references track stats');

  async_test(t => {
    const caller = new RTCPeerConnection();
    t.add_cleanup(() => caller.close());
    const callee = new RTCPeerConnection();
    t.add_cleanup(() => callee.close());
    let sendingTrack;
    return getUserMediaTracksAndStreams(1)
    .then(t.step_func(([tracks, streams]) => {
      t.add_cleanup(() => tracks.forEach(track => track.stop()));
      sendingTrack = tracks[0];
      caller.addTrack(sendingTrack, streams[0]);
      return exchangeOfferAnswer(caller, callee);
    }))
    .then(t.step_func(() => {
      return caller.getStats();
    }))
    .then(t.step_func(report => {
      let trackStats = findStatsByTypeAndId(report, 'track', sendingTrack.id);
      assert_true(trackStats != null, 'Has stats for sending track');
      let outboundStats = findStatsByTypeAndMember(report, 'outbound-rtp',
                                                   'trackId', trackStats.id);
      assert_true(outboundStats != null, 'Has stats for outbound RTP stream');
      validateRtcStats(report, trackStats);
      validateRtcStats(report, outboundStats);
      t.done();
    }))
    .catch(t.step_func(reason => {
      assert_unreached(reason);
    }));
  }, 'O/A exchange yields outbound RTP stream stats for sending track');

  async_test(t => {
    const caller = new RTCPeerConnection();
    t.add_cleanup(() => caller.close());
    const callee = new RTCPeerConnection();
    t.add_cleanup(() => callee.close());
    let receivingTrack;
    callee.ontrack = trackEvent => {
      assert_true(receivingTrack == undefined, 'ontrack has not fired before');
      receivingTrack = trackEvent.track;
    };
    return getUserMediaTracksAndStreams(1)
    .then(t.step_func(([tracks, streams]) => {
      t.add_cleanup(() => tracks.forEach(track => track.stop()));
      caller.addTrack(tracks[0], streams[0]);
      return exchangeOfferAnswer(caller, callee);
    }))
    .then(t.step_func(() => {
      return callee.getStats();
    }))
    .then(t.step_func(report => {
      assert_true(receivingTrack != null, 'Has a receiving track');
      let trackStats = findStatsByTypeAndId(report, 'track', receivingTrack.id);
      assert_true(trackStats != null, 'Has stats for receiving track');
      let inboundStats = findStatsByTypeAndMember(report, 'inbound-rtp',
                                                  'trackId', trackStats.id);
      assert_true(inboundStats != null, 'Has stats for outbound RTP stream');
      validateRtcStats(report, trackStats);
      validateRtcStats(report, inboundStats);
      t.done();
    }))
    .catch(t.step_func(reason => {
      assert_unreached(reason);
    }));
  }, 'O/A exchange yields inbound RTP stream stats for receiving track');

  async_test(t => {
    const caller = new RTCPeerConnection();
    t.add_cleanup(() => caller.close());
    const callee = new RTCPeerConnection();
    t.add_cleanup(() => callee.close());
    let sendingTrack1;
    let sendingTrack2;
    let sender;
    return getUserMediaTracksAndStreams(2)
    .then(t.step_func(([tracks, streams]) => {
      t.add_cleanup(() => tracks.forEach(track => track.stop()));
      sendingTrack1 = tracks[0];
      sendingTrack2 = tracks[1];
      sender = caller.addTrack(sendingTrack1, streams[0]);
      return sender.replaceTrack(sendingTrack2);
    }))
    .then(t.step_func(() => {
      return caller.getStats();
    }))
    .then(t.step_func(report => {
      let trackStats = findStatsByTypeAndId(report, 'track', sendingTrack2.id);
      assert_true(trackStats != null, 'Has stats for replaced track');
      validateRtcStats(report, trackStats);
      t.done();
    }))
    .catch(t.step_func(reason => {
      assert_unreached(reason);
    }));
  }, 'replaceTrack() before offer: new track attachment stats present');

  async_test(t => {
    const caller = new RTCPeerConnection();
    t.add_cleanup(() => caller.close());
    const callee = new RTCPeerConnection();
    t.add_cleanup(() => callee.close());
    let sendingTrack1;
    let sendingTrack2;
    let sender;
    return getUserMediaTracksAndStreams(2)
    .then(t.step_func(([tracks, streams]) => {
      t.add_cleanup(() => tracks.forEach(track => track.stop()));
      sendingTrack1 = tracks[0];
      sendingTrack2 = tracks[1];
      sender = caller.addTrack(sendingTrack1, streams[0]);
      return exchangeOffer(caller, callee);
    }))
    .then(t.step_func(() => {
      return sender.replaceTrack(sendingTrack2);
    }))
    .then(t.step_func(() => {
      return caller.getStats();
    }))
    .then(t.step_func(report => {
      let trackStats = findStatsByTypeAndId(report, 'track', sendingTrack2.id);
      assert_true(trackStats != null, 'Has stats for replaced track');
      let outboundStats = findStatsByTypeAndMember(report, 'outbound-rtp',
                                                   'trackId', trackStats.id);
      assert_true(outboundStats != null, 'Has stats for outbound RTP stream');
      validateRtcStats(report, trackStats);
      validateRtcStats(report, outboundStats);
      t.done();
    }))
    .catch(t.step_func(reason => {
      assert_unreached(reason);
    }));
  }, 'replaceTrack() after offer, before answer: new track attachment stats ' +
     'present');

  async_test(t => {
    const caller = new RTCPeerConnection();
    t.add_cleanup(() => caller.close());
    const callee = new RTCPeerConnection();
    t.add_cleanup(() => callee.close());
    let sendingTrack1;
    let sendingTrack2;
    let sender;
    return getUserMediaTracksAndStreams(2)
    .then(t.step_func(([tracks, streams]) => {
      t.add_cleanup(() => tracks.forEach(track => track.stop()));
      sendingTrack1 = tracks[0];
      sendingTrack2 = tracks[1];
      sender = caller.addTrack(sendingTrack1, streams[0]);
      return exchangeOfferAnswer(caller, callee);
    }))
    .then(t.step_func(() => {
      return sender.replaceTrack(sendingTrack2);
    }))
    .then(t.step_func(() => {
      return caller.getStats();
    }))
    .then(t.step_func(report => {
      let trackStats = findStatsByTypeAndId(report, 'track', sendingTrack2.id);
      assert_true(trackStats != null, 'Has stats for replaced track');
      let outboundStats = findStatsByTypeAndMember(report, 'outbound-rtp',
                                                   'trackId', trackStats.id);
      assert_true(outboundStats != null, 'Has stats for outbound RTP stream');
      validateRtcStats(report, trackStats);
      validateRtcStats(report, outboundStats);
      t.done();
    }))
    .catch(t.step_func(reason => {
      assert_unreached(reason);
    }));
  }, 'replaceTrack() after answer: new track attachment stats present');

  async_test(t => {
    const caller = new RTCPeerConnection();
    t.add_cleanup(() => caller.close());
    const callee = new RTCPeerConnection();
    t.add_cleanup(() => callee.close());
    let sendingTrack1;
    let sendingTrack2;
    let sender;
    return getUserMediaTracksAndStreams(2)
    .then(t.step_func(([tracks, streams]) => {
      t.add_cleanup(() => tracks.forEach(track => track.stop()));
      sendingTrack1 = tracks[0];
      sendingTrack2 = tracks[1];
      sender = caller.addTrack(sendingTrack1, streams[0]);
      return exchangeOfferAnswer(caller, callee);
    }))
    .then(t.step_func(() => {
      return sender.replaceTrack(sendingTrack2);
    }))
    .then(t.step_func(() => {
      return caller.getStats();
    }))
    .then(t.step_func(report => {
      let trackStats = findStatsByTypeAndId(report, 'track', sendingTrack1.id);
      assert_true(trackStats != null, 'Has stats for original track');
      assert_true(trackStats.objectDeleted);
      let outboundStats = findStatsByTypeAndMember(report, 'outbound-rtp',
                                                   'trackId', trackStats.id);
      assert_true(outboundStats == null,
                  'The outbound RTP stream should no longer reference the ' +
                  'original attachment');
      t.done();
    }))
    .catch(t.step_func(reason => {
      assert_unreached(reason);
    }));
  }, 'replaceTrack(): original track attachment stats present after replacing');

  promise_test(async t => {
    const caller = new RTCPeerConnection();
    t.add_cleanup(() => caller.close());
    const callee = new RTCPeerConnection();
    t.add_cleanup(() => callee.close());
    let [tracks, streams] = await getUserMediaTracksAndStreams(2);
    t.add_cleanup(() => tracks.forEach(track => track.stop()));
    let sender = caller.addTrack(tracks[0], streams[0]);
    callee.addTrack(tracks[1], streams[1]);
    exchangeIceCandidates(caller, callee);
    await exchangeOfferAnswer(caller, callee);
    await listenToConnected(caller);
    let receiver = caller.getReceivers()[0];

    // Obtain inbound and outbound RTP stream stats on a full stats report.
    let fullReport = await caller.getStats();
    let outboundTrackStats = findStatsByTypeAndId(
        fullReport, 'track', sender.track.id);
    let outboundStats = findStatsByTypeAndMember(
        fullReport, 'outbound-rtp', 'trackId', outboundTrackStats.id);
    assert_true(outboundStats != null, 'Has stats for outbound RTP stream');
    let inboundTrackStats = findStatsByTypeAndId(
        fullReport, 'track', receiver.track.id);
    let inboundStats = findStatsByTypeAndMember(
        fullReport, 'inbound-rtp', 'trackId', inboundTrackStats.id);
    assert_true(inboundStats != null, 'Has stats for inbound RTP stream');

    // Perform stats selection algorithm with sender selector. The result should
    // contain the outbound-rtp but not the inbound-rtp.
    let senderReport = await sender.getStats();
    assert_true(senderReport.has(outboundStats.id));
    assert_false(senderReport.has(inboundStats.id));

    // Validate the stats graph, ensuring all stats objects are reachable and
    // valid from the outbound-rtp stats.
    validateStatsGraph(senderReport, senderReport.get(outboundStats.id));
    // Ensure that the stats graph contains some expected dictionaries.
    assert_equals(findStatsOfType(senderReport, 'track').length, 1,
        'senderReport should contain track stats');
    assert_equals(findStatsOfType(senderReport, 'transport').length, 1,
        'senderReport should contain transport stats');
    assert_equals(findStatsOfType(senderReport, 'candidate-pair').length, 1,
        'senderReport should contain candidate-pair stats');
    assert_equals(findStatsOfType(senderReport, 'local-candidate').length, 1,
        'senderReport should contain local-candidate stats');
    assert_equals(findStatsOfType(senderReport, 'remote-candidate').length, 1,
        'senderReport should contain remote-candidate stats');
  }, 'RTCRtpSender.getStats() contains only outbound-rtp and related stats');

  promise_test(async t => {
    const caller = new RTCPeerConnection();
    t.add_cleanup(() => caller.close());
    const callee = new RTCPeerConnection();
    t.add_cleanup(() => callee.close());
    let [tracks, streams] = await getUserMediaTracksAndStreams(2);
    t.add_cleanup(() => tracks.forEach(track => track.stop()));
    let sender = caller.addTrack(tracks[0], streams[0]);
    callee.addTrack(tracks[1], streams[1]);
    exchangeIceCandidates(caller, callee);
    await exchangeOfferAnswer(caller, callee);
    await listenToConnected(caller);
    let receiver = caller.getReceivers()[0];

    // Obtain inbound and outbound RTP stream stats on a full stats report.
    let fullReport = await caller.getStats();
    let outboundTrackStats = findStatsByTypeAndId(
        fullReport, 'track', sender.track.id);
    let outboundStats = findStatsByTypeAndMember(
        fullReport, 'outbound-rtp', 'trackId', outboundTrackStats.id);
    assert_true(outboundStats != null, 'Has stats for outbound RTP stream');
    let inboundTrackStats = findStatsByTypeAndId(
        fullReport, 'track', receiver.track.id);
    let inboundStats = findStatsByTypeAndMember(
        fullReport, 'inbound-rtp', 'trackId', inboundTrackStats.id);
    assert_true(inboundStats != null, 'Has stats for inbound RTP stream');

    // Perform stats selection algorithm with receiver selector. The result
    // should contain the inbound-rtp but not the outbound-rtp.
    let receiverReport = await receiver.getStats();
    assert_true(receiverReport.has(inboundStats.id));
    assert_false(receiverReport.has(outboundStats.id));

    // Validate the stats graph, ensuring all stats objects are reachable and
    // valid from the outbound-rtp stats.
    validateStatsGraph(receiverReport, receiverReport.get(inboundStats.id));
    // Ensure that the stats graph contains some expected dictionaries.
    assert_equals(findStatsOfType(receiverReport, 'track').length, 1,
        'receiverReport should contain track stats');
    assert_equals(findStatsOfType(receiverReport, 'transport').length, 1,
        'receiverReport should contain transport stats');
    assert_equals(findStatsOfType(receiverReport, 'candidate-pair').length, 1,
        'receiverReport should contain candidate-pair stats');
    assert_equals(findStatsOfType(receiverReport, 'local-candidate').length, 1,
        'receiverReport should contain local-candidate stats');
    assert_equals(findStatsOfType(receiverReport, 'remote-candidate').length, 1,
        'receiverReport should contain remote-candidate stats');
  }, 'RTCRtpReceiver.getStats() contains only inbound-rtp and related stats');

  promise_test(async t => {
    const caller = new RTCPeerConnection();
    t.add_cleanup(() => caller.close());
    const callee = new RTCPeerConnection();
    t.add_cleanup(() => callee.close());
    let [tracks, streams] = await getUserMediaTracksAndStreams(2);
    t.add_cleanup(() => tracks.forEach(track => track.stop()));
    let sender = caller.addTrack(tracks[0], streams[0]);
    callee.addTrack(tracks[1], streams[1]);
    exchangeIceCandidates(caller, callee);
    await exchangeOfferAnswer(caller, callee);
    await listenToIceConnected(caller);

    // Wait until RTCP has arrived so that it can not arrive between
    // the two get stats calls.
    await waitForRtpAndRtcpStats(caller);

    let senderReport = await sender.getStats();
    let trackReport = await caller.getStats(sender.track);

    // Verify the same stats objects are returned but don't compare each
    // individual metric because timestamps and counters could have gone up
    // between the two getStats() calls.
    senderReport.forEach(senderReportStat => {
      assert_true(trackReport.has(senderReportStat.id));
    });
    trackReport.forEach(trackReportStat => {
      assert_true(senderReport.has(trackReportStat.id));
    });
  }, 'RTCPeerConnection.getStats(sendingTrack) is the same as ' +
     'RTCRtpSender.getStats()');

  promise_test(async t => {
    const caller = new RTCPeerConnection();
    t.add_cleanup(() => caller.close());
    const callee = new RTCPeerConnection();
    t.add_cleanup(() => callee.close());
    let [tracks, streams] = await getUserMediaTracksAndStreams(2);
    t.add_cleanup(() => tracks.forEach(track => track.stop()));
    let sender = caller.addTrack(tracks[0], streams[0]);
    callee.addTrack(tracks[1], streams[1]);
    exchangeIceCandidates(caller, callee);
    await exchangeOfferAnswer(caller, callee);
    await listenToIceConnected(caller);
    let receiver = caller.getReceivers()[0];

    // Wait until RTCP has arrived so that it can not arrive between
    // the two get stats calls.
    await waitForRtpAndRtcpStats(caller);

    let receiverReport = await receiver.getStats();
    let trackReport = await caller.getStats(receiver.track);

    // Verify the same stats objects are returned but don't compare each
    // individual metric because timestamps and counters could have gone up
    // between the two getStats() calls.
    receiverReport.forEach(receiverReportStat => {
      assert_true(trackReport.has(receiverReportStat.id));
    });
    trackReport.forEach(trackReportStat => {
      assert_true(receiverReport.has(trackReportStat.id));
    });
  }, 'RTCPeerConnection.getStats(receivingTrack) is the same as ' +
     'RTCRtpReceiver.getStats()');

  promise_test(async t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    let [tracks, streams] = await getUserMediaTracksAndStreams(1);
    t.add_cleanup(() => tracks.forEach(track => track.stop()));
    await promise_rejects_dom(t, 'InvalidAccessError', pc.getStats(tracks[0]));
  }, 'RTCPeerConnection.getStats(track) throws InvalidAccessError when there ' +
     'are zero senders or receivers for the track');

  promise_test(async t => {
    const pc = new RTCPeerConnection();
    t.add_cleanup(() => pc.close());
    let [tracks, streams] = await getUserMediaTracksAndStreams(2);
    t.add_cleanup(() => tracks.forEach(track => track.stop()));
    let sender1 = pc.addTrack(tracks[0], streams[0]);
    let sender2 = pc.addTrack(tracks[1], streams[1]);
    await sender2.replaceTrack(sender1.track);
    await promise_rejects_dom(t, 'InvalidAccessError', pc.getStats(sender1.track));
  }, 'RTCPeerConnection.getStats(track) throws InvalidAccessError when there ' +
     'are multiple senders for the track');

  // Helpers.

  function findStatsByTypeAndId(report, type, identifier) {
    return findStats(report, stats => {
      return stats.type == type && stats[type + 'Identifier'] == identifier;
    });
  }

  function findStatsByTypeAndMember(report, type, member, value) {
    return findStats(report, stats => {
      return stats.type == type && stats[member] == value;
    });
  }

  function findStats(report, findFunc) {
    for (let it = report.values(), n = it.next(); !n.done; n = it.next()) {
      if (findFunc(n.value))
        return n.value;
    }
    return null;
  }

  function findStatsOfType(report, type) {
    let stats = [];
    for (let it = report.values(), n = it.next(); !n.done; n = it.next()) {
      if (n.value.type == type)
        stats.push(n.value);
    }
    return stats;
  }

  // Explores the stats graph starting from |stat|, validating each stat
  // (validateRtcStats) and asserting that all stats of the report were visited.
  function validateStatsGraph(report, stat) {
    let visitedIds = new Set();
    validateStatsGraphRecursively(report, stat.id, visitedIds);
    assert_equals(visitedIds.size, report.size,
                  'Entire stats graph should have been explored.')
  }

  function validateStatsGraphRecursively(report, currentId, visitedIds) {
    if (visitedIds.has(currentId))
      return;
    visitedIds.add(currentId);
    assert_true(report.has(currentId), 'Broken reference.');
    let stat = report.get(currentId);
    validateRtcStats(report, stat);
    for (let member in stat) {
      if (member.endsWith('Id')) {
        validateStatsGraphRecursively(report, stat[member], visitedIds);
      } else if (member.endsWith('Ids')) {
        let ids = stat[member];
        for (let i = 0; i < ids.length; ++i) {
          validateStatsGraphRecursively(report, ids[i], visitedIds);
        }
      }
    }
  }
</script>
