Index: third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-getReceivers.html |
diff --git a/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-getReceivers.html b/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-getReceivers.html |
index 6bfbd5410d5faa75e9910663dd5d063457099985..45d3149547bdecf8f0a29dd46d27225d4a11408e 100644 |
--- a/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-getReceivers.html |
+++ b/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-getReceivers.html |
@@ -113,12 +113,102 @@ promise_test(function() { |
assert_equals(pc.getRemoteStreams().length, 0); |
assert_equals(pc.getReceivers().length, 0); |
}); |
-}, 'getReceivers() for streams being added and removed.'); |
+}, 'pc.getReceivers() for streams being added and removed.'); |
+ |
+// |RTCRtpReceiver::getContributingSources| is mocked to update the contributing |
+// sources with a predictable pattern, see |
+// |MockWebRTCRtpReceiver::getContributingSources|. This test ensures that the |
+// sources are correctly cached for subsequent calls in the same event task |
+// execution, that they are updated between event task execution calls and that |
+// object identities of contributing sources hold. |
+promise_test(function() { |
+ let pc = new RTCPeerConnection(); |
+ let receiver = null; |
+ let contributingSource0 = null; |
+ return createStreams({audio:true}, 1) |
+ .then(function(streams) { |
+ return addRemoteStreamsFromLocalStreams(pc, streams); |
+ }) |
+ .then(function() { |
+ verifyStreamAndTrackCounts(pc.getRemoteStreams(), 1, true, false); |
+ verifyRemoteTracksHaveReceivers(pc); |
+ |
+ assert_equals(pc.getReceivers().length, 1); |
+ receiver = pc.getReceivers()[0]; |
+ verifyContributingSourcesAreCached(receiver); |
+ |
+ let contributingSources = receiver.getContributingSources(); |
+ assert_equals(contributingSources.length, 1); |
+ assertContributingSourceEquals(contributingSources[0], 0, 0.0); |
+ |
+ // Remember the first contributing source for later. |
+ contributingSource0 = contributingSources[0]; |
+ // Pass |contributingSource0| to the next "then". |
+ return postTask(contributingSource0); |
+ }).then(function(prevContributingSource) { |
+ verifyContributingSourcesAreCached(receiver); |
+ |
+ let contributingSources = receiver.getContributingSources(); |
+ assert_equals(contributingSources.length, 2); |
+ assertContributingSourceEquals(contributingSources[0], 0, 0.0); |
+ assertContributingSourceEquals(contributingSources[1], 1, 5000.0); |
+ |
+ // Make sure object identities are preserved between event loop task |
+ // executions (between asynchronous calls and contributing sources |
+ // updates). |
+ assert_equals(contributingSources[0], prevContributingSource); |
+ |
+ return postTask(contributingSources[1]); |
+ }).then(function(prevContributingSource) { |
+ verifyContributingSourcesAreCached(receiver); |
+ |
+ let contributingSources = receiver.getContributingSources(); |
+ assert_equals(contributingSources.length, 2); |
+ assert_equals(contributingSources[0], prevContributingSource); |
+ assertContributingSourceEquals(contributingSources[0], 1, 5000.0); |
+ assertContributingSourceEquals(contributingSources[1], 2, 10000.0); |
+ |
+ // Make sure object identities are preserved between event loop task |
+ // executions (between asynchronous calls and contributing sources |
+ // updates). |
+ assert_equals(contributingSources[0], prevContributingSource); |
+ |
+ return postTask(contributingSources[1]); |
+ }).then(function(prevContributingSource) { |
+ verifyContributingSourcesAreCached(receiver); |
+ |
+ // It's source 0's turn to be updated. A contributing source should be |
+ // kept up-to-date in a new event loop task execution without having to |
+ // explicitly call |getContributingSources|. |
+ assertContributingSourceEquals(contributingSource0, 0, 15000.0); |
+ |
+ let contributingSources = receiver.getContributingSources(); |
+ assert_equals(contributingSources.length, 2); |
+ assertContributingSourceEquals(contributingSources[0], 2, 10000.0); |
+ assertContributingSourceEquals(contributingSources[1], 0, 15000.0); |
+ assert_equals(contributingSources[0], prevContributingSource); |
+ assert_equals(contributingSources[1], contributingSource0); |
+ |
+ return Promise.resolve(); |
+ }); |
+}, 'receiver.getContributingSources()'); |
/** |
* Helper functions to tests. |
*/ |
+/** |
+ * Returns a promise that is immediately resolved asynchronously, meaning "then" |
+ * is invoked in the next iteration of the event loop. |
foolip
2017/04/06 10:07:23
Promise.resolve().then(callback) is invoked at the
hbos_chromium
2017/04/06 11:10:15
Done.
|
+ */ |
+function postTask(valuePassed = undefined) { |
+ return new Promise(function(resolve, reject) { |
+ setTimeout(function() { |
+ resolve(valuePassed); |
+ }, 0); |
+ }); |
+} |
+ |
function createStreams(constraints, numStreams, streamsSoFar = []) { |
if (numStreams == 0) { |
return Promise.resolve(streamsSoFar);; |
@@ -211,6 +301,26 @@ function verifyRemoteTracksHaveReceivers(pc) { |
} |
assert_equals(receiverTracks.size, remoteTracks.size); |
} |
+ |
+/** |
+ * The |MockWebRTCRtpReceiver::getContributingSources| produces a new set of |
+ * contributing sources every call. The |RTCRtpReceiver| has a cache to make |
+ * sure its |getContributingSources| does not change during the same event loop |
+ * task execution. |
+ */ |
+function verifyContributingSourcesAreCached(receiver) { |
+ // If caching is working as intended, this is always true. It should only be |
+ // able to change between asynchronous calls, e.g. |postTask|. Since the mock |
+ // always produces a new set of sources, this would not be true if caching was |
+ // not enabled. |
+ assert_array_equals(receiver.getContributingSources(), |
+ receiver.getContributingSources()); |
+} |
+ |
+function assertContributingSourceEquals(contributingSource, source, timestamp) { |
+ assert_equals(contributingSource.source, source); |
+ assert_equals(contributingSource.timestamp, timestamp); |
+} |
</script> |
</body> |
</html> |