chromium/third_party/blink/web_tests/fast/peerconnection/RTCPeerConnection-undelivered-events-gc.html

<html>
<head>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../../resources/gc.js"></script>
</head>
<body>
<script>
promise_test(async t => {
  // Some scheduled events can hold Persistent references to RTCPeerConnection.
  // See |RTCPeerConnection::ChangeIceGatheringState()| or
  // |RTCPeerConnection::ChangePeerConnectionState()| for example.
  // This test checks that such undelivered events don't prevent their parent
  // RTCPeerConnection object from garbage collection after destroying
  // corresponding execution context.

  let iframe = document.createElement("iframe");
  document.body.appendChild(iframe);

  let iframe_pc = new iframe.contentWindow.RTCPeerConnection();
  assert_equals(iframe_pc.signalingState, 'stable');
  iframe_pc.createDataChannel('foo');

  let frameRemoved = new Promise(function(resolve, reject) {
    // Destroy frame (and |iframe_pc| related execution context) just before
    // delivering scheduled "icegatheringstatechange" event.
    internals.waitForPeerConnectionDispatchEventsTaskCreated(iframe_pc)
        .then(() => { iframe.remove(); resolve(); });
    iframe_pc.createOffer()
        .then((offer) => iframe_pc.setLocalDescription(offer));
  });
  await frameRemoved;

  assert_equals(iframe_pc.signalingState, 'closed');
  assert_equals(internals.peerConnectionCount(), 1);
  iframe_pc = null;
  await asyncGC();
  assert_equals(internals.peerConnectionCount(), 0);
}, 'PeerConnection with undelivered events is closed and garbage collected');
</script>
</body>
</html>