Bug 1527044 [wpt PR 15133] - Deflake RTCPeerConnection-track-stats.https.html., a=testonly
authorHenrik Boström <hbos@chromium.org>
Tue, 19 Feb 2019 11:46:39 +0000
changeset 519222 e80d7b6fe06457552e2eb2d1b1751931984403a2
parent 519221 a52794d4ba349c03a5438d49293cda0bead134db
child 519223 f1592f48542df6cd9ee7b5f8a9e58d4b7fe42bcd
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstestonly
bugs1527044, 15133, 926170, 922955, 1442201, 627421
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1527044 [wpt PR 15133] - Deflake RTCPeerConnection-track-stats.https.html., a=testonly Automatic update from web-platform-tests Deflake RTCPeerConnection-track-stats.https.html. This CL does the following: 1. Add a test that verifies we have a succeeded candidate pair in getStats() as soon as iceConnectionState is "connected". This is currently flaky (https://crbug.com/926170) and marked as such. 2. Add workaround to RTCPeerConnection-track-stats.https.html so that it does not flake due to 1), and mark it not flaky. 3. Move shared helper functions to RTCPeerConnection-helper.js. 4. Add test coverage for making sure we can become connected in the recvonly use case. This requires changing the prefix to ".https.html" of "RTCPeerConnection-iceConnectionState". // Already reviewed by jonasolsson@chromium.org TBR=guidou@chromium.org Bug: 922955, 926170 Change-Id: I828e46273a84447c817595a466a5e143bde30eca Reviewed-on: https://chromium-review.googlesource.com/c/1442201 Reviewed-by: Henrik Boström <hbos@chromium.org> Commit-Queue: Henrik Boström <hbos@chromium.org> Cr-Commit-Position: refs/heads/master@{#627421} -- wpt-commits: 7179024d5dfb231073c7319948499d7e30f671cb wpt-pr: 15133
testing/web-platform/tests/webrtc/RTCIceConnectionState-candidate-pair.https.html
testing/web-platform/tests/webrtc/RTCPeerConnection-helper.js
testing/web-platform/tests/webrtc/RTCPeerConnection-iceConnectionState.html
testing/web-platform/tests/webrtc/RTCPeerConnection-iceConnectionState.https.html
testing/web-platform/tests/webrtc/RTCPeerConnection-track-stats.https.html
testing/web-platform/tests/webrtc/RTCRtpReceiver-getSynchronizationSources.https.html
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webrtc/RTCIceConnectionState-candidate-pair.https.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<meta charset=utf-8>
+<meta name="timeout" content="long">
+<title>RTCIceConnectionState and RTCIceCandidatePair</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="RTCPeerConnection-helper.js"></script>
+<script>
+'use strict';
+
+promise_test(async t => {
+  const caller = new RTCPeerConnection();
+  t.add_cleanup(() => caller.close());
+  const callee = new RTCPeerConnection();
+  t.add_cleanup(() => callee.close());
+
+  const stream = await navigator.mediaDevices.getUserMedia({audio:true});
+  const [track] = stream.getTracks();
+  caller.addTrack(track, stream);
+  exchangeIceCandidates(caller, callee);
+  await doSignalingHandshake(caller, callee);
+  await listenToIceConnected(t, caller);
+
+  const report = await caller.getStats();
+  let succeededPairFound = false;
+  report.forEach(stats => {
+    if (stats.type == 'candidate-pair' && stats.state == 'succeeded')
+      succeededPairFound = true;
+  });
+  assert_true(succeededPairFound, 'A succeeded candidate-pair should exist');
+}, 'On ICE connected, getStats() contains a connected candidate-pair');
+
+</script>
--- a/testing/web-platform/tests/webrtc/RTCPeerConnection-helper.js
+++ b/testing/web-platform/tests/webrtc/RTCPeerConnection-helper.js
@@ -200,16 +200,65 @@ async function doSignalingHandshake(loca
     answer = await options.modifyAnswer(answer);
   }
 
   // Apply answer
   await remotePc.setLocalDescription(answer);
   await localPc.setRemoteDescription(answer);
 }
 
+// Returns a promise that resolves when |pc.iceConnectionState| is 'connected'
+// or 'completed'.
+function listenToIceConnected(pc) {
+  return new Promise((resolve) => {
+    function isConnected(pc) {
+      return pc.iceConnectionState == 'connected' ||
+            pc.iceConnectionState == 'completed';
+    }
+    if (isConnected(pc)) {
+      resolve();
+      return;
+    }
+    pc.oniceconnectionstatechange = () => {
+      if (isConnected(pc))
+        resolve();
+    };
+  });
+}
+
+// Returns a promise that resolves when |pc.connectionState| is 'connected'.
+function listenToConnected(pc) {
+  return new Promise((resolve) => {
+    if (pc.connectionState == 'connected') {
+      resolve();
+      return;
+    }
+    pc.onconnectionstatechange = () => {
+      if (pc.connectionState == 'connected')
+        resolve();
+    };
+  });
+}
+
+// Resolves when RTP packets have been received.
+function listenForSSRCs(t, receiver) {
+  return new Promise((resolve) => {
+    function listen() {
+      const ssrcs = receiver.getSynchronizationSources();
+      assert_true(ssrcs != undefined);
+      if (ssrcs.length > 0) {
+        resolve(ssrcs);
+        return;
+      }
+      t.step_timeout(listen, 0);
+    };
+    listen();
+  });
+}
+
 // Helper function to create a pair of connected data channel.
 // On success the promise resolves to an array with two data channels.
 // It does the heavy lifting of performing signaling handshake,
 // ICE candidate exchange, and waiting for data channel at two
 // end points to open.
 function createDataChannelPair(
   pc1=new RTCPeerConnection(),
   pc2=new RTCPeerConnection())
deleted file mode 100644
--- a/testing/web-platform/tests/webrtc/RTCPeerConnection-iceConnectionState.html
+++ /dev/null
@@ -1,226 +0,0 @@
-<!doctype html>
-<meta charset=utf-8>
-<title>RTCPeerConnection.prototype.iceConnectionState</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:
-  // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
-
-  // The following helper functions are called from RTCPeerConnection-helper.js:
-  // exchangeIceCandidates
-  // doSignalingHandshake
-
-  /*
-    4.3.2.  Interface Definition
-      interface RTCPeerConnection : EventTarget {
-        ...
-        readonly  attribute RTCIceConnectionState  iceConnectionState;
-                  attribute EventHandler           oniceconnectionstatechange;
-      };
-
-    4.4.4 RTCIceConnectionState Enum
-      enum RTCIceConnectionState {
-        "new",
-        "checking",
-        "connected",
-        "completed",
-        "failed",
-        "disconnected",
-        "closed"
-      };
-
-    5.6.  RTCIceTransport Interface
-      interface RTCIceTransport {
-        readonly attribute RTCIceTransportState state;
-                 attribute EventHandler         onstatechange;
-
-        ...
-      };
-
-      enum RTCIceTransportState {
-        "new",
-        "checking",
-        "connected",
-        "completed",
-        "failed",
-        "disconnected",
-        "closed"
-      };
-   */
-
-  /*
-    4.4.4 RTCIceConnectionState Enum
-      new
-        Any of the RTCIceTransports are in the new state and none of them
-        are in the checking, failed or disconnected state, or all
-        RTCIceTransport s are in the closed state.
-   */
-  test(t => {
-    const pc = new RTCPeerConnection();
-    assert_equals(pc.iceConnectionState, 'new');
-  }, 'Initial iceConnectionState should be new');
-
-  test(t => {
-    const pc = new RTCPeerConnection();
-    pc.close();
-    assert_equals(pc.iceConnectionState, 'closed');
-  }, 'Closing the connection should set iceConnectionState to closed');
-
-  /*
-    4.4.4 RTCIceConnectionState Enum
-      checking
-        Any of the RTCIceTransport s are in the checking state and none of
-        them are in the failed or disconnected state.
-
-      connected
-        All RTCIceTransport s are in the connected, completed or closed state
-        and at least one of them is in the connected state.
-
-      completed
-        All RTCIceTransport s are in the completed or closed state and at least
-        one of them is in the completed state.
-
-      checking
-        The RTCIceTransport has received at least one remote candidate and
-        is checking candidate pairs and has either not yet found a connection
-        or consent checks [RFC7675] have failed on all previously successful
-        candidate pairs. In addition to checking, it may also still be gathering.
-
-    5.6.  enum RTCIceTransportState
-      connected
-        The RTCIceTransport has found a usable connection, but is still
-        checking other candidate pairs to see if there is a better connection.
-        It may also still be gathering and/or waiting for additional remote
-        candidates. If consent checks [RFC7675] fail on the connection in use,
-        and there are no other successful candidate pairs available, then the
-        state transitions to "checking" (if there are candidate pairs remaining
-        to be checked) or "disconnected" (if there are no candidate pairs to
-        check, but the peer is still gathering and/or waiting for additional
-        remote candidates).
-
-      completed
-        The RTCIceTransport has finished gathering, received an indication that
-        there are no more remote candidates, finished checking all candidate
-        pairs and found a connection. If consent checks [RFC7675] subsequently
-        fail on all successful candidate pairs, the state transitions to "failed".
-   */
-  async_test(t => {
-    const pc1 = new RTCPeerConnection();
-    t.add_cleanup(() => pc1.close());
-    const pc2 = new RTCPeerConnection();
-    t.add_cleanup(() => pc2.close());
-
-    let had_checking = false;
-
-    const onIceConnectionStateChange = t.step_func(() => {
-      const {iceConnectionState} = pc1;
-      if (iceConnectionState === 'checking') {
-        had_checking = true;
-      } else if (iceConnectionState === 'connected' ||
-                 iceConnectionState === 'completed') {
-        assert_true(had_checking, 'state should pass checking before' +
-                                  ' reaching connected or completed');
-        t.done();
-      }
-    });
-
-    pc1.createDataChannel('test');
-
-    pc1.addEventListener('iceconnectionstatechange', onIceConnectionStateChange);
-
-    exchangeIceCandidates(pc1, pc2);
-    doSignalingHandshake(pc1, pc2);
-  }, 'connection with one data channel should eventually have connected or ' +
-     'completed connection state');
-
-async_test(t => {
-    const pc1 = new RTCPeerConnection();
-    t.add_cleanup(() => pc1.close());
-    const pc2 = new RTCPeerConnection();
-
-    t.add_cleanup(() => pc2.close());
-
-    const onIceConnectionStateChange = t.step_func(() => {
-      const { iceConnectionState } = pc1;
-
-      if(iceConnectionState === 'checking') {
-        const iceTransport = pc1.sctp.transport.transport;
-
-        assert_equals(iceTransport.state, 'checking',
-          'Expect ICE transport to be in checking state when' +
-          ' iceConnectionState is checking');
-
-      } else if(iceConnectionState === 'connected') {
-        const iceTransport = pc1.sctp.transport.transport;
-
-        assert_equals(iceTransport.state, 'connected',
-          'Expect ICE transport to be in connected state when' +
-          ' iceConnectionState is connected');
-
-      } else if(iceConnectionState === 'completed') {
-        const iceTransport = pc1.sctp.transport.transport;
-
-        assert_equals(iceTransport.state, 'completed',
-          'Expect ICE transport to be in connected state when' +
-          ' iceConnectionState is completed');
-      }
-    });
-
-    pc1.createDataChannel('test');
-
-    assert_equals(pc1.oniceconnectionstatechange, null,
-      'Expect connection to have iceconnectionstatechange event');
-
-    pc1.addEventListener('iceconnectionstatechange', onIceConnectionStateChange);
-
-    exchangeIceCandidates(pc1, pc2);
-    doSignalingHandshake(pc1, pc2);
-  }, 'connection with one data channel should eventually ' +
-     'have connected connection state');
-
-  /*
-    TODO
-    4.4.4 RTCIceConnectionState Enum
-      failed
-        Any of the RTCIceTransport s are in the failed state.
-
-      disconnected
-        Any of the RTCIceTransport s are in the disconnected state and none of
-        them are in the failed state.
-
-      closed
-        The RTCPeerConnection object's [[ isClosed]] slot is true.
-
-    5.6.  enum RTCIceTransportState
-      new
-        The RTCIceTransport is gathering candidates and/or waiting for
-        remote candidates to be supplied, and has not yet started checking.
-
-      failed
-        The RTCIceTransport has finished gathering, received an indication that
-        there are no more remote candidates, finished checking all candidate pairs,
-        and all pairs have either failed connectivity checks or have lost consent.
-
-      disconnected
-        The ICE Agent has determined that connectivity is currently lost for this
-        RTCIceTransport . This is more aggressive than failed, and may trigger
-        intermittently (and resolve itself without action) on a flaky network.
-        The way this state is determined is implementation dependent.
-
-        Examples include:
-          Losing the network interface for the connection in use.
-          Repeatedly failing to receive a response to STUN requests.
-
-        Alternatively, the RTCIceTransport has finished checking all existing
-        candidates pairs and failed to find a connection (or consent checks
-        [RFC7675] once successful, have now failed), but it is still gathering
-        and/or waiting for additional remote candidates.
-
-      closed
-        The RTCIceTransport has shut down and is no longer responding to STUN requests.
-   */
-</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webrtc/RTCPeerConnection-iceConnectionState.https.html
@@ -0,0 +1,246 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>RTCPeerConnection.prototype.iceConnectionState</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:
+  // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
+
+  // The following helper functions are called from RTCPeerConnection-helper.js:
+  // exchangeIceCandidates
+  // doSignalingHandshake
+
+  /*
+    4.3.2.  Interface Definition
+      interface RTCPeerConnection : EventTarget {
+        ...
+        readonly  attribute RTCIceConnectionState  iceConnectionState;
+                  attribute EventHandler           oniceconnectionstatechange;
+      };
+
+    4.4.4 RTCIceConnectionState Enum
+      enum RTCIceConnectionState {
+        "new",
+        "checking",
+        "connected",
+        "completed",
+        "failed",
+        "disconnected",
+        "closed"
+      };
+
+    5.6.  RTCIceTransport Interface
+      interface RTCIceTransport {
+        readonly attribute RTCIceTransportState state;
+                 attribute EventHandler         onstatechange;
+
+        ...
+      };
+
+      enum RTCIceTransportState {
+        "new",
+        "checking",
+        "connected",
+        "completed",
+        "failed",
+        "disconnected",
+        "closed"
+      };
+   */
+
+  /*
+    4.4.4 RTCIceConnectionState Enum
+      new
+        Any of the RTCIceTransports are in the new state and none of them
+        are in the checking, failed or disconnected state, or all
+        RTCIceTransport s are in the closed state.
+   */
+  test(t => {
+    const pc = new RTCPeerConnection();
+    assert_equals(pc.iceConnectionState, 'new');
+  }, 'Initial iceConnectionState should be new');
+
+  test(t => {
+    const pc = new RTCPeerConnection();
+    pc.close();
+    assert_equals(pc.iceConnectionState, 'closed');
+  }, 'Closing the connection should set iceConnectionState to closed');
+
+  /*
+    4.4.4 RTCIceConnectionState Enum
+      checking
+        Any of the RTCIceTransport s are in the checking state and none of
+        them are in the failed or disconnected state.
+
+      connected
+        All RTCIceTransport s are in the connected, completed or closed state
+        and at least one of them is in the connected state.
+
+      completed
+        All RTCIceTransport s are in the completed or closed state and at least
+        one of them is in the completed state.
+
+      checking
+        The RTCIceTransport has received at least one remote candidate and
+        is checking candidate pairs and has either not yet found a connection
+        or consent checks [RFC7675] have failed on all previously successful
+        candidate pairs. In addition to checking, it may also still be gathering.
+
+    5.6.  enum RTCIceTransportState
+      connected
+        The RTCIceTransport has found a usable connection, but is still
+        checking other candidate pairs to see if there is a better connection.
+        It may also still be gathering and/or waiting for additional remote
+        candidates. If consent checks [RFC7675] fail on the connection in use,
+        and there are no other successful candidate pairs available, then the
+        state transitions to "checking" (if there are candidate pairs remaining
+        to be checked) or "disconnected" (if there are no candidate pairs to
+        check, but the peer is still gathering and/or waiting for additional
+        remote candidates).
+
+      completed
+        The RTCIceTransport has finished gathering, received an indication that
+        there are no more remote candidates, finished checking all candidate
+        pairs and found a connection. If consent checks [RFC7675] subsequently
+        fail on all successful candidate pairs, the state transitions to "failed".
+   */
+  async_test(t => {
+    const pc1 = new RTCPeerConnection();
+    t.add_cleanup(() => pc1.close());
+    const pc2 = new RTCPeerConnection();
+    t.add_cleanup(() => pc2.close());
+
+    let had_checking = false;
+
+    const onIceConnectionStateChange = t.step_func(() => {
+      const {iceConnectionState} = pc1;
+      if (iceConnectionState === 'checking') {
+        had_checking = true;
+      } else if (iceConnectionState === 'connected' ||
+                 iceConnectionState === 'completed') {
+        assert_true(had_checking, 'state should pass checking before' +
+                                  ' reaching connected or completed');
+        t.done();
+      }
+    });
+
+    pc1.createDataChannel('test');
+
+    pc1.addEventListener('iceconnectionstatechange', onIceConnectionStateChange);
+
+    exchangeIceCandidates(pc1, pc2);
+    doSignalingHandshake(pc1, pc2);
+  }, 'connection with one data channel should eventually have connected or ' +
+     'completed connection state');
+
+async_test(t => {
+    const pc1 = new RTCPeerConnection();
+    t.add_cleanup(() => pc1.close());
+    const pc2 = new RTCPeerConnection();
+
+    t.add_cleanup(() => pc2.close());
+
+    const onIceConnectionStateChange = t.step_func(() => {
+      const { iceConnectionState } = pc1;
+
+      if(iceConnectionState === 'checking') {
+        const iceTransport = pc1.sctp.transport.transport;
+
+        assert_equals(iceTransport.state, 'checking',
+          'Expect ICE transport to be in checking state when' +
+          ' iceConnectionState is checking');
+
+      } else if(iceConnectionState === 'connected') {
+        const iceTransport = pc1.sctp.transport.transport;
+
+        assert_equals(iceTransport.state, 'connected',
+          'Expect ICE transport to be in connected state when' +
+          ' iceConnectionState is connected');
+
+      } else if(iceConnectionState === 'completed') {
+        const iceTransport = pc1.sctp.transport.transport;
+
+        assert_equals(iceTransport.state, 'completed',
+          'Expect ICE transport to be in connected state when' +
+          ' iceConnectionState is completed');
+      }
+    });
+
+    pc1.createDataChannel('test');
+
+    assert_equals(pc1.oniceconnectionstatechange, null,
+      'Expect connection to have iceconnectionstatechange event');
+
+    pc1.addEventListener('iceconnectionstatechange', onIceConnectionStateChange);
+
+    exchangeIceCandidates(pc1, pc2);
+    doSignalingHandshake(pc1, pc2);
+  }, 'connection with one data channel should eventually ' +
+     'have connected connection state');
+
+  promise_test(async t => {
+    const caller = new RTCPeerConnection();
+    t.add_cleanup(() => caller.close());
+    const callee = new RTCPeerConnection();
+    t.add_cleanup(() => callee.close());
+
+    caller.addTransceiver('audio', {direction:'recvonly'});
+    const stream = await navigator.mediaDevices.getUserMedia({audio:true});
+    const [track] = stream.getTracks();
+    callee.addTrack(track, stream);
+    exchangeIceCandidates(caller, callee);
+    await doSignalingHandshake(caller, callee);
+
+    assert_equals(caller.getTransceivers().length, 1);
+    const [transceiver] = caller.getTransceivers();
+    assert_equals(transceiver.currentDirection, 'recvonly');
+
+    await listenToIceConnected(caller);
+  }, 'ICE can connect in a recvonly usecase');
+
+  /*
+    TODO
+    4.4.4 RTCIceConnectionState Enum
+      failed
+        Any of the RTCIceTransport s are in the failed state.
+
+      disconnected
+        Any of the RTCIceTransport s are in the disconnected state and none of
+        them are in the failed state.
+
+      closed
+        The RTCPeerConnection object's [[ isClosed]] slot is true.
+
+    5.6.  enum RTCIceTransportState
+      new
+        The RTCIceTransport is gathering candidates and/or waiting for
+        remote candidates to be supplied, and has not yet started checking.
+
+      failed
+        The RTCIceTransport has finished gathering, received an indication that
+        there are no more remote candidates, finished checking all candidate pairs,
+        and all pairs have either failed connectivity checks or have lost consent.
+
+      disconnected
+        The ICE Agent has determined that connectivity is currently lost for this
+        RTCIceTransport . This is more aggressive than failed, and may trigger
+        intermittently (and resolve itself without action) on a flaky network.
+        The way this state is determined is implementation dependent.
+
+        Examples include:
+          Losing the network interface for the connection in use.
+          Repeatedly failing to receive a response to STUN requests.
+
+        Alternatively, the RTCIceTransport has finished checking all existing
+        candidates pairs and failed to find a connection (or consent checks
+        [RFC7675] once successful, have now failed), but it is still gathering
+        and/or waiting for additional remote candidates.
+
+      closed
+        The RTCIceTransport has shut down and is no longer responding to STUN requests.
+   */
+</script>
--- a/testing/web-platform/tests/webrtc/RTCPeerConnection-track-stats.https.html
+++ b/testing/web-platform/tests/webrtc/RTCPeerConnection-track-stats.https.html
@@ -412,17 +412,17 @@
     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 doSignalingHandshake(caller, callee);
-    await onIceConnectionStateCompleted(caller);
+    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);
@@ -461,17 +461,17 @@
     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 doSignalingHandshake(caller, callee);
-    await onIceConnectionStateCompleted(caller);
+    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);
@@ -510,17 +510,17 @@
     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 doSignalingHandshake(caller, callee);
-    await onIceConnectionStateCompleted(caller);
+    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);
 
@@ -542,17 +542,17 @@
     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 doSignalingHandshake(caller, callee);
-    await onIceConnectionStateCompleted(caller);
+    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);
@@ -616,34 +616,16 @@
     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;
   }
 
-  // Returns a promise that is resolved when pc.iceConnectionState reaches the
-  // 'connected' or 'completed' state. This is when transport stats can be
-  // expected to have its selectedCandidatePairId defined.
-  async function onIceConnectionStateCompleted(pc) {
-    if (pc.iceConnectionState == 'connected' ||
-        pc.iceConnectionState == 'completed') {
-      return Promise.resolve();
-    }
-    let resolver = new Resolver();
-    pc.oniceconnectionstatechange = e => {
-      if (pc.iceConnectionState == 'connected' ||
-          pc.iceConnectionState == 'completed') {
-        resolver.resolve();
-      }
-    };
-    return resolver;
-  }
-
   // 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.')
   }
--- a/testing/web-platform/tests/webrtc/RTCRtpReceiver-getSynchronizationSources.https.html
+++ b/testing/web-platform/tests/webrtc/RTCRtpReceiver-getSynchronizationSources.https.html
@@ -21,31 +21,16 @@ async function initiateSingleTrackCallAn
   pc1.addTrack(track, stream);
 
   exchangeIceCandidates(pc1, pc2);
   const trackEvent = await exchangeOfferAndListenToOntrack(t, pc1, pc2);
   await exchangeAnswer(pc1, pc2);
   return trackEvent.receiver;
 }
 
-function listenForSSRCs(t, receiver) {
-  return new Promise((resolve) => {
-    function listen() {
-      const ssrcs = receiver.getSynchronizationSources();
-      assert_true(ssrcs != undefined);
-      if (ssrcs.length > 0) {
-        resolve(ssrcs);
-        return;
-      }
-      t.step_timeout(listen, 0);
-    };
-    listen();
-  });
-}
-
 for (const kind of ['audio', 'video']) {
   promise_test(async t => {
     const receiver = await initiateSingleTrackCallAndReturnReceiver(t, kind);
     await listenForSSRCs(t, receiver);
   }, '[' + kind + '] getSynchronizationSources() eventually returns a ' +
      'non-empty list');
 
   promise_test(async t => {