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..61b09a97b0cc40f22d507293c1f6536957468698 100644 |
--- a/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-getReceivers.html |
+++ b/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-getReceivers.html |
@@ -113,7 +113,88 @@ 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". By resolving a promise |
+ // we get an asynchronous callback, i.e. the "then" happens in the next |
+ // iteration of the event loop. This should invalidate the contributing |
+ // sources cache. |
+ return Promise.resolve(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 Promise.resolve(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 Promise.resolve(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. |
@@ -211,6 +292,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. |Promise.resolve().then()|. |
+ // 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> |