Bug 1523562 [wpt PR 14417] - Update RTCPeerConnection-helper.js, a=testonly
authoryouennf <youennf@users.noreply.github.com>
Thu, 31 Jan 2019 12:14:28 +0000
changeset 457788 603e8e8097b742115dca2e195f59f65618b97ac0
parent 457787 91f314cf9ea056321628ded8ad618d36bca9b6ff
child 457789 4acf41d59c72657ae06c000b71199f8b8de1af17
push id35518
push useropoprus@mozilla.com
push dateFri, 08 Feb 2019 09:55:14 +0000
treeherdermozilla-central@3a3e393396f4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstestonly
bugs1523562, 14417, 13499
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 1523562 [wpt PR 14417] - Update RTCPeerConnection-helper.js, a=testonly Automatic update from web-platform-tests Update RTCPeerConnection-helper.js (#14417) * Update RTCPeerConnection-helper.js according changes proposed in https://github.com/web-platform-tests/wpt/pull/13499 * Modernize doSignalingHandshake -- wpt-commits: b75b876e7d5843582f21e5b52c54d509dffb6da0 wpt-pr: 14417
testing/web-platform/tests/webrtc/RTCDataChannel-send.html
testing/web-platform/tests/webrtc/RTCPeerConnection-helper.js
testing/web-platform/tests/webrtc/tools/.eslintrc.js
--- a/testing/web-platform/tests/webrtc/RTCDataChannel-send.html
+++ b/testing/web-platform/tests/webrtc/RTCDataChannel-send.html
@@ -9,17 +9,17 @@
 
   // 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:
   //  createDataChannelPair
   //  awaitMessage
   //  blobToArrayBuffer
-  //  assert_equals_array_buffer
+  //  assert_equals_typed_array
 
   /*
     6.2.  RTCDataChannel
       interface RTCDataChannel : EventTarget {
         ...
         readonly  attribute RTCDataChannelState readyState;
         readonly  attribute unsigned long       bufferedAmount;
                   attribute EventHandler        onmessage;
@@ -135,17 +135,17 @@
     .then(([channel1, channel2]) => {
       channel2.binaryType = 'arraybuffer';
       channel1.send(helloBuffer);
       return awaitMessage(channel2)
     }).then(messageBuffer => {
       assert_true(messageBuffer instanceof ArrayBuffer,
         'Expect messageBuffer to be an ArrayBuffer');
 
-      assert_equals_array_buffer(messageBuffer, helloBuffer.buffer);
+      assert_equals_typed_array(messageBuffer, helloBuffer.buffer);
     });
   }, 'Data channel should be able to send Uint8Array message and receive as ArrayBuffer');
 
   /*
     6.2. send()
       3.  Execute the sub step that corresponds to the type of the methods argument:
           ArrayBuffer object
             Let data be the data stored in the buffer described by the ArrayBuffer
@@ -157,17 +157,17 @@
     .then(([channel1, channel2]) => {
       channel2.binaryType = 'arraybuffer';
       channel1.send(helloBuffer.buffer);
       return awaitMessage(channel2)
     }).then(messageBuffer => {
       assert_true(messageBuffer instanceof ArrayBuffer,
         'Expect messageBuffer to be an ArrayBuffer');
 
-      assert_equals_array_buffer(messageBuffer, helloBuffer.buffer);
+      assert_equals_typed_array(messageBuffer, helloBuffer.buffer);
     });
   }, 'Data channel should be able to send ArrayBuffer message and receive as ArrayBuffer');
 
   /*
     6.2. send()
       3.  Execute the sub step that corresponds to the type of the methods argument:
           Blob object
             Let data be the raw data represented by the Blob object and increase
@@ -178,17 +178,17 @@
     .then(([channel1, channel2]) => {
       channel2.binaryType = 'arraybuffer';
       channel1.send(helloBlob);
       return awaitMessage(channel2);
     }).then(messageBuffer => {
       assert_true(messageBuffer instanceof ArrayBuffer,
         'Expect messageBuffer to be an ArrayBuffer');
 
-      assert_equals_array_buffer(messageBuffer, helloBuffer.buffer);
+      assert_equals_typed_array(messageBuffer, helloBuffer.buffer);
     });
   }, 'Data channel should be able to send Blob message and receive as ArrayBuffer');
 
   /*
     [WebSocket]
     5.  Feedback from the protocol
       When a WebSocket message has been received
         4.  If binaryType is set to "blob", then initialize event's data attribute
@@ -205,17 +205,17 @@
       assert_true(messageBlob instanceof Blob,
         'Expect received messageBlob to be a Blob');
 
       return blobToArrayBuffer(messageBlob);
     }).then(messageBuffer => {
       assert_true(messageBuffer instanceof ArrayBuffer,
         'Expect messageBuffer to be an ArrayBuffer');
 
-      assert_equals_array_buffer(messageBuffer, helloBuffer.buffer);
+      assert_equals_typed_array(messageBuffer, helloBuffer.buffer);
     });
   }, 'Data channel should be able to send ArrayBuffer message and receive as Blob');
 
   /*
     6.2.  RTCDataChannel
       binaryType
         The binaryType attribute must, on getting, return the value to which it was
         last set. On setting, the user agent must set the IDL attribute to the new
@@ -235,32 +235,32 @@
       assert_true(messageBlob instanceof Blob,
         'Expect received messageBlob to be a Blob');
 
       return blobToArrayBuffer(messageBlob);
     }).then(messageBuffer => {
       assert_true(messageBuffer instanceof ArrayBuffer,
         'Expect messageBuffer to be an ArrayBuffer');
 
-      assert_equals_array_buffer(messageBuffer, helloBuffer.buffer);
+      assert_equals_typed_array(messageBuffer, helloBuffer.buffer);
     });
   }, 'Data channel binaryType should receive message as Blob by default');
 
   // Test sending 3 messages: helloBuffer, unicodeString, helloBlob
   async_test(t => {
     const receivedMessages = [];
 
     const onMessage = t.step_func(event => {
       const { data } = event;
       receivedMessages.push(data);
 
       if(receivedMessages.length === 3) {
-        assert_equals_array_buffer(receivedMessages[0], helloBuffer.buffer);
+        assert_equals_typed_array(receivedMessages[0], helloBuffer.buffer);
         assert_equals(receivedMessages[1], unicodeString);
-        assert_equals_array_buffer(receivedMessages[2], helloBuffer.buffer);
+        assert_equals_typed_array(receivedMessages[2], helloBuffer.buffer);
 
         t.done();
       }
     });
 
     createDataChannelPair()
     .then(([channel1, channel2]) => {
       channel2.binaryType = 'arraybuffer';
--- a/testing/web-platform/tests/webrtc/RTCPeerConnection-helper.js
+++ b/testing/web-platform/tests/webrtc/RTCPeerConnection-helper.js
@@ -177,26 +177,37 @@ function exchangeIceCandidates(pc1, pc2)
     });
   }
 
   doExchange(pc1, pc2);
   doExchange(pc2, pc1);
 }
 
 // Helper function for doing one round of offer/answer exchange
-// betweeen two local peer connections
-function doSignalingHandshake(localPc, remotePc) {
-  return localPc.createOffer()
-  .then(offer => Promise.all([
-    localPc.setLocalDescription(offer),
-    remotePc.setRemoteDescription(offer)]))
-  .then(() => remotePc.createAnswer())
-  .then(answer => Promise.all([
-    remotePc.setLocalDescription(answer),
-    localPc.setRemoteDescription(answer)]))
+// between two local peer connections
+async function doSignalingHandshake(localPc, remotePc, options={}) {
+  let offer = await localPc.createOffer();
+  // Modify offer if callback has been provided
+  if (options.modifyOffer) {
+    offer = await options.modifyOffer(offer);
+  }
+
+  // Apply offer
+  await localPc.setLocalDescription(offer);
+  await remotePc.setRemoteDescription(offer);
+
+  let answer = await remotePc.createAnswer();
+  // Modify answer if callback has been provided
+  if (options.modifyAnswer) {
+    answer = await options.modifyAnswer(answer);
+  }
+
+  // Apply answer
+  await remotePc.setLocalDescription(answer);
+  await localPc.setRemoteDescription(answer);
 }
 
 // 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(
@@ -290,33 +301,35 @@ function blobToArrayBuffer(blob) {
     });
 
     reader.addEventListener('error', reject);
 
     reader.readAsArrayBuffer(blob);
   });
 }
 
-// Assert that two ArrayBuffer objects have the same byte values
-function assert_equals_array_buffer(buffer1, buffer2) {
-  assert_true(buffer1 instanceof ArrayBuffer,
-    'Expect buffer to be instance of ArrayBuffer');
-
-  assert_true(buffer2 instanceof ArrayBuffer,
-    'Expect buffer to be instance of ArrayBuffer');
+// Assert that two TypedArray or ArrayBuffer objects have the same byte values
+function assert_equals_typed_array(array1, array2) {
+  const [view1, view2] = [array1, array2].map((array) => {
+    if (array instanceof ArrayBuffer) {
+      return new DataView(array);
+    } else {
+      assert_true(array.buffer instanceof ArrayBuffer,
+        'Expect buffer to be instance of ArrayBuffer');
+      return new DataView(array.buffer, array.byteOffset, array.byteLength);
+    }
+  });
 
-  assert_equals(buffer1.byteLength, buffer2.byteLength,
-    'Expect both array buffers to be of the same byte length');
+  assert_equals(view1.byteLength, view2.byteLength,
+    'Expect both arrays to be of the same byte length');
 
-  const byteLength = buffer1.byteLength;
-  const byteArray1 = new Uint8Array(buffer1);
-  const byteArray2 = new Uint8Array(buffer2);
+  const byteLength = view1.byteLength;
 
-  for(let i=0; i<byteLength; i++) {
-    assert_equals(byteArray1[i], byteArray2[i],
+  for (let i = 0; i < byteLength; ++i) {
+    assert_equals(view1.getUint8(i), view2.getUint8(i),
       `Expect byte at buffer position ${i} to be equal`);
   }
 }
 
 // These media tracks will be continually updated with deterministic "noise" in
 // order to ensure UAs do not cease transmission in response to apparent
 // silence.
 //
@@ -473,28 +486,55 @@ async function exchangeAnswerAndListenTo
 }
 // The returned promise is resolved with callee's ontrack event.
 async function exchangeOfferAndListenToOntrack(t, caller, callee) {
   const ontrackPromise = addEventListenerPromise(t, callee, 'track');
   await exchangeOffer(caller, callee);
   return ontrackPromise;
 }
 
-// The resolver has a |promise| that can be resolved or rejected using |resolve|
+// The resolver extends a |promise| that can be resolved or rejected using |resolve|
 // or |reject|.
-class Resolver {
-  constructor() {
-    let promiseResolve;
-    let promiseReject;
-    this.promise = new Promise(function(resolve, reject) {
-      promiseResolve = resolve;
-      promiseReject = reject;
+class Resolver extends Promise {
+  constructor(executor) {
+    let resolve, reject;
+    super((resolve_, reject_) => {
+      resolve = resolve_;
+      reject = reject_;
+      if (executor) {
+        return executor(resolve_, reject_);
+      }
     });
-    this.resolve = promiseResolve;
-    this.reject = promiseReject;
+
+    this._done = false;
+    this._resolve = resolve;
+    this._reject = reject;
+  }
+
+  /**
+   * Return whether the promise is done (resolved or rejected).
+   */
+  get done() {
+    return this._done;
+  }
+
+  /**
+   * Resolve the promise.
+   */
+  resolve(...args) {
+    this._done = true;
+    return this._resolve(...args);
+  }
+
+  /**
+   * Reject the promise.
+   */
+  reject(...args) {
+    this._done = true;
+    return this._reject(...args);
   }
 }
 
 function addEventListenerPromise(t, target, type, listener) {
   return new Promise((resolve, reject) => {
     target.addEventListener(type, t.step_func(e => {
       if (listener != undefined)
         e = listener(e);
@@ -521,8 +561,28 @@ async function createTrackAndStreamWithC
 function findTransceiverForSender(pc, sender) {
   const transceivers = pc.getTransceivers();
   for (let i = 0; i < transceivers.length; ++i) {
     if (transceivers[i].sender == sender)
       return transceivers[i];
   }
   return null;
 }
+
+// Contains a set of values and will yell at you if you try to add a value twice.
+class UniqueSet extends Set {
+  constructor(items) {
+    super();
+    if (items !== undefined) {
+      for (const item of items) {
+        this.add(item);
+      }
+    }
+  }
+
+  add(value, message) {
+    if (message === undefined) {
+      message = `Value '${value}' needs to be unique but it is already in the set`;
+    }
+    assert_true(!this.has(value), message);
+    super.add(value);
+  }
+}
--- a/testing/web-platform/tests/webrtc/tools/.eslintrc.js
+++ b/testing/web-platform/tests/webrtc/tools/.eslintrc.js
@@ -100,17 +100,17 @@ module.exports = {
     generateAnswer: true,
     test_state_change_event: true,
     test_never_resolve: true,
     exchangeIceCandidates: true,
     doSignalingHandshake: true,
     createDataChannelPair: true,
     awaitMessage: true,
     blobToArrayBuffer: true,
-    assert_equals_array_buffer: true,
+    assert_equals_typed_array: true,
     generateMediaStreamTrack: true,
     getTrackFromUserMedia: true,
     getUserMediaTracksAndStreams: true,
     performOffer: true,
     Resolver: true,
 
     // RTCRtpCapabilities-helper.js
     validateRtpCapabilities: true,