Bug 1485845 [wpt PR 12661] - RTCIceTransport: start() implementation., a=testonly
authorSteve Anton <steveanton@chromium.org>
Wed, 29 Aug 2018 22:41:05 +0000
changeset 482559 746c205985b5e0d16d746299d1cb97a521409fff
parent 482558 046d8db5efa5c4b704e214b6d641ea8ac422f53b
child 482560 c80e34a74aa79fb6d4ce49fded45d5fc792b3298
push id232
push userfmarier@mozilla.com
push dateWed, 05 Sep 2018 20:45:54 +0000
reviewerstestonly
bugs1485845, 12661, 864871, 1161605, 585915
milestone63.0a1
Bug 1485845 [wpt PR 12661] - RTCIceTransport: start() implementation., a=testonly Automatic update from web-platform-testsRTCIceTransport: start() implementation. This change implements the RTCIceTransport.start() method and associated methods/events: addRemoteCandidate(), getRemoteCandidates(), role, onstatechange. Bug: 864871 Change-Id: Ic6ac7ce4c9ba98b1dc2610ed7847e6b9714f6c8d Reviewed-on: https://chromium-review.googlesource.com/1161605 Commit-Queue: Steve Anton <steveanton@chromium.org> Reviewed-by: Harald Alvestrand <hta@chromium.org> Reviewed-by: Guido Urdaneta <guidou@chromium.org> Cr-Commit-Position: refs/heads/master@{#585915} -- wpt-commits: 0ddf9024e1b3db119549d2f4769d4b35a78cb8d1 wpt-pr: 12661
testing/web-platform/meta/MANIFEST.json
testing/web-platform/tests/webrtc/RTCIceTransport-extension.https.html
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -651835,17 +651835,17 @@
    "0614364e9756ec933ca842b97b1dbd31489b35ee",
    "testharness"
   ],
   "webrtc/RTCIceCandidate-constructor.html": [
    "974ed0c76cfafb788e865c0b1c71fa19007c55b9",
    "testharness"
   ],
   "webrtc/RTCIceTransport-extension.https.html": [
-   "88a10bb464e5259899c777bb3608b77e4e4141d7",
+   "9c6cec7e1e4994ee58f6822d77048eca8e8af569",
    "testharness"
   ],
   "webrtc/RTCIceTransport.html": [
    "17ae6dca016fcd08cbb34b4819129f6338de28c6",
    "testharness"
   ],
   "webrtc/RTCPeerConnection-add-track-no-deadlock.https.html": [
    "81e3b736432d2c80d617ca2c05ef072e901d0283",
--- a/testing/web-platform/tests/webrtc/RTCIceTransport-extension.https.html
+++ b/testing/web-platform/tests/webrtc/RTCIceTransport-extension.https.html
@@ -12,17 +12,17 @@
 function makeIceTransport(t) {
   const iceTransport = new RTCIceTransport();
   t.add_cleanup(() => iceTransport.stop());
   return iceTransport;
 }
 
 test(() => {
   const iceTransport = new RTCIceTransport();
-}, 'RTCIceTransport constructor does not throw.');
+}, 'RTCIceTransport constructor does not throw');
 
 test(() => {
   const iceTransport = new RTCIceTransport();
   assert_equals(iceTransport.role, null, 'Expect role to be null');
   assert_equals(iceTransport.state, 'new', `Expect state to be 'new'`);
   assert_equals(iceTransport.gatheringState, 'new',
     `Expect gatheringState to be 'new'`);
   assert_array_equals(iceTransport.getLocalCandidates(), [],
@@ -30,17 +30,17 @@ test(() => {
   assert_array_equals(iceTransport.getRemoteCandidates(), [],
     'Expect no remote candidates');
   assert_equals(iceTransport.getSelectedCandidatePair(), null,
     'Expect no selected candidate pair');
   assert_not_equals(iceTransport.getLocalParameters(), null,
     'Expect local parameters generated');
   assert_equals(iceTransport.getRemoteParameters(), null,
     'Expect no remote parameters');
-}, 'RTCIceTransport initial properties are set.');
+}, 'RTCIceTransport initial properties are set');
 
 test(t => {
   const iceTransport = makeIceTransport(t);
   assert_throws(new TypeError(), () =>
     iceTransport.gather({ iceServers: null }));
 }, 'gather() with { iceServers: null } should throw TypeError');
 
 test(t => {
@@ -120,9 +120,152 @@ promise_test(async t => {
   const watcher = new EventWatcher(t, iceTransport, 'icecandidate');
   iceTransport.gather({ gatherPolicy: 'relay' });
   const { candidate } = await watcher.wait_for('icecandidate');
   assert_equals(candidate, null);
   assert_array_equals(iceTransport.getLocalCandidates(), []);
 }, `gather() returns no candidates with { gatherPolicy: 'relay'} and no turn` +
     ' servers');
 
+const dummyRemoteParameters = {
+  usernameFragment: 'dummyUsernameFragment',
+  password: 'dummyPassword',
+};
+
+test(() => {
+  const iceTransport = new RTCIceTransport();
+  iceTransport.stop();
+  assert_throws('InvalidStateError',
+    () => iceTransport.start(dummyRemoteParameters));
+  assert_equals(iceTransport.getRemoteParameters(), null);
+}, `start() throws if closed`);
+
+test(() => {
+  const iceTransport = new RTCIceTransport();
+  assert_throws(new TypeError(), () => iceTransport.start({}));
+  assert_throws(new TypeError(),
+    () => iceTransport.start({ usernameFragment: 'dummy' }));
+  assert_throws(new TypeError(),
+    () => iceTransport.start({ password: 'dummy' }));
+  assert_equals(iceTransport.getRemoteParameters(), null);
+}, 'start() throws if usernameFragment or password not set');
+
+const assert_ice_parameters_equals = (a, b) => {
+  assert_equals(a.usernameFragment, b.usernameFragment,
+      'usernameFragments are equal');
+  assert_equals(a.password, b.password, 'passwords are equal');
+};
+
+test(t => {
+  const iceTransport = makeIceTransport(t);
+  iceTransport.start(dummyRemoteParameters);
+  assert_equals(iceTransport.state, 'new');
+  assert_ice_parameters_equals(iceTransport.getRemoteParameters(),
+      dummyRemoteParameters);
+}, `start() does not transition state to 'checking' if no remote candidates ` +
+    'added');
+
+test(t => {
+  const iceTransport = makeIceTransport(t);
+  iceTransport.start(dummyRemoteParameters);
+  assert_equals(iceTransport.role, 'controlled');
+}, `start() with default role sets role attribute to 'controlled'`);
+
+test(t => {
+  const iceTransport = makeIceTransport(t);
+  iceTransport.start(dummyRemoteParameters, 'controlling');
+  assert_equals(iceTransport.role, 'controlling');
+}, `start() sets role attribute to 'controlling'`);
+
+const candidate1 = new RTCIceCandidate({
+  candidate: 'candidate:1 1 udp 2113929471 203.0.113.100 10100 typ host',
+});
+
+test(() => {
+  const iceTransport = new RTCIceTransport();
+  iceTransport.stop();
+  assert_throws('InvalidStateError',
+    () => iceTransport.addRemoteCandidate(candidate1));
+  assert_array_equals(iceTransport.getRemoteCandidates(), []);
+}, 'addRemoteCandidate() throws if closed');
+
+test(() => {
+  const iceTransport = new RTCIceTransport();
+  assert_throws('OperationError',
+    () => iceTransport.addRemoteCandidate(
+      new RTCIceCandidate({ candidate: 'invalid' })));
+  assert_array_equals(iceTransport.getRemoteCandidates(), []);
+}, 'addRemoteCandidate() throws on invalid candidate');
+
+test(t => {
+  const iceTransport = makeIceTransport(t);
+  iceTransport.addRemoteCandidate(candidate1);
+  iceTransport.start(dummyRemoteParameters);
+  assert_equals(iceTransport.state, 'checking');
+  assert_array_equals(iceTransport.getRemoteCandidates(), [candidate1]);
+}, `start() transitions state to 'checking' if one remote candidate had been ` +
+    'added');
+
+test(t => {
+  const iceTransport = makeIceTransport(t);
+  iceTransport.start(dummyRemoteParameters);
+  iceTransport.addRemoteCandidate(candidate1);
+  assert_equals(iceTransport.state, 'checking');
+  assert_array_equals(iceTransport.getRemoteCandidates(), [candidate1]);
+}, `addRemoteCandidate() transitions state to 'checking' if start() had been ` +
+    'called before');
+
+test(t => {
+  const iceTransport = makeIceTransport(t);
+  iceTransport.start(dummyRemoteParameters);
+  assert_throws('InvalidStateError',
+    () => iceTransport.start(dummyRemoteParameters, 'controlling'));
+}, 'start() throws if later called with a different role');
+
+test(t => {
+  const iceTransport = makeIceTransport(t);
+  iceTransport.start({
+    usernameFragment: 'user',
+    password: 'pass',
+  });
+  iceTransport.addRemoteCandidate(candidate1);
+  const changedRemoteParameters = {
+    usernameFragment: 'user2',
+    password: 'pass',
+  };
+  iceTransport.start(changedRemoteParameters);
+  assert_equals(iceTransport.state, 'new');
+  assert_array_equals(iceTransport.getRemoteCandidates(), []);
+  assert_ice_parameters_equals(iceTransport.getRemoteParameters(),
+      changedRemoteParameters);
+}, `start() flushes remote candidates and transitions state to 'new' if ` +
+   'later called with different remote parameters');
+
+promise_test(async t => {
+  const localTransport = makeIceTransport(t);
+  const remoteTransport = makeIceTransport(t);
+  localTransport.onicecandidate = e => {
+    if (e.candidate) {
+      remoteTransport.addRemoteCandidate(e.candidate);
+    }
+  };
+  remoteTransport.onicecandidate = e => {
+    if (e.candidate) {
+      localTransport.addRemoteCandidate(e.candidate);
+    }
+  };
+  localTransport.gather({});
+  remoteTransport.gather({});
+  localTransport.start(remoteTransport.getLocalParameters(), 'controlling');
+  remoteTransport.start(localTransport.getLocalParameters(), 'controlled');
+  const localWatcher = new EventWatcher(t, localTransport, 'statechange');
+  const remoteWatcher = new EventWatcher(t, remoteTransport, 'statechange');
+  await Promise.all([
+    localWatcher.wait_for('statechange').then(() => {
+      assert_equals(localTransport.state, 'connected');
+    }),
+    remoteWatcher.wait_for('statechange').then(() => {
+      assert_equals(remoteTransport.state, 'connected');
+    }),
+  ]);
+}, 'Two RTCIceTransports connect to each other');
+
 </script>