WebRTC: Add media setup test where media is set up in one direction at a time
authoradam.bergkvist@ericsson.com <adam.bergkvist@ericsson.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 14 Jun 2016 15:13:20 +0000 (15:13 +0000)
committeradam.bergkvist@ericsson.com <adam.bergkvist@ericsson.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 14 Jun 2016 15:13:20 +0000 (15:13 +0000)
https://bugs.webkit.org/show_bug.cgi?id=158691

Reviewed by Eric Carlson.

Source/WebCore:

Add test for setting up media in one direction at a time. This requires a change in sdp.js
to allow an SDP that doesn't contain a stream id or track id (representing
a track being sent). In this test, the first answer doesn't contain any sending media.

Test: fast/mediastream/RTCPeerConnection-media-setup-two-dialogs.html

* Modules/mediastream/sdp.js:

LayoutTests:

Test setting up media in one direction at a time. This is achieved by first negotiating
media in one direction. In a second step, an updated offer is sent to add bi-directional
media.

* fast/mediastream/RTCPeerConnection-media-setup-two-dialogs-expected.txt: Added.
* fast/mediastream/RTCPeerConnection-media-setup-two-dialogs.html: Added.
* platform/mac/TestExpectations:
The mac port is not building with WEB_RTC yet.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@202043 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/mediastream/RTCPeerConnection-media-setup-two-dialogs-expected.txt [new file with mode: 0644]
LayoutTests/fast/mediastream/RTCPeerConnection-media-setup-two-dialogs.html [new file with mode: 0644]
LayoutTests/platform/mac/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/Modules/mediastream/sdp.js

index e00b617..b8d33ce 100644 (file)
@@ -1,3 +1,19 @@
+2016-06-14  Adam Bergkvist  <adam.bergkvist@ericsson.com>
+
+        WebRTC: Add media setup test where media is set up in one direction at a time
+        https://bugs.webkit.org/show_bug.cgi?id=158691
+
+        Reviewed by Eric Carlson.
+
+        Test setting up media in one direction at a time. This is achieved by first negotiating
+        media in one direction. In a second step, an updated offer is sent to add bi-directional
+        media.
+
+        * fast/mediastream/RTCPeerConnection-media-setup-two-dialogs-expected.txt: Added.
+        * fast/mediastream/RTCPeerConnection-media-setup-two-dialogs.html: Added.
+        * platform/mac/TestExpectations:
+        The mac port is not building with WEB_RTC yet.
+
 2016-06-13  Adam Bergkvist  <adam.bergkvist@ericsson.com>
 
         WebRTC: Imlement MediaEndpointPeerConnection::replaceTrack()
diff --git a/LayoutTests/fast/mediastream/RTCPeerConnection-media-setup-two-dialogs-expected.txt b/LayoutTests/fast/mediastream/RTCPeerConnection-media-setup-two-dialogs-expected.txt
new file mode 100644 (file)
index 0000000..8c6dac5
--- /dev/null
@@ -0,0 +1,106 @@
+Test setting up media between two RTCPeerConnection instances with a single SDP dialog.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Create RTCPeerConnection A
+PASS pcA.signalingState is 'stable'
+PASS pcA.pendingLocalDescription is null
+PASS pcA.currentLocalDescription is null
+PASS pcA.pendingRemoteDescription is null
+PASS pcA.currentRemoteDescription is null
+
+Create RTCPeerConnection B
+PASS pcB.signalingState is 'stable'
+PASS pcB.pendingLocalDescription is null
+PASS pcB.currentLocalDescription is null
+PASS pcB.pendingRemoteDescription is null
+PASS pcB.currentRemoteDescription is null
+
+A: add media
+A: create offer
+A: got offer, set it as local description
+A: local offer set
+PASS pcA.signalingState is 'have-local-offer'
+PASS pcA.pendingLocalDescription is an instance of RTCSessionDescription
+PASS pcA.currentLocalDescription is null
+
+A: send offer to B
+A --- offer --> B
+B: got offer from A, set it as remote description
+----------
+PASS B: got remote track event
+----------
+B: remote offer set
+PASS pcB.signalingState is 'have-remote-offer'
+PASS pcB.pendingRemoteDescription is an instance of RTCSessionDescription
+PASS pcB.currentRemoteDescription is null
+
+B: create answer (without local media)
+B: got answer, set it as local description
+B: local answer set
+PASS pcB.signalingState is 'stable'
+PASS pcB.pendingLocalDescription is null
+PASS pcB.currentLocalDescription is an instance of RTCSessionDescription
+PASS pcB.pendingRemoteDescription is null
+PASS pcB.currentRemoteDescription is an instance of RTCSessionDescription
+
+B: send answer to A
+A <-- answer -- B
+A: got answer from B, set it as remote description
+A: remote answer set
+PASS pcA.signalingState is 'stable'
+PASS pcA.pendingLocalDescription is null
+PASS pcA.currentLocalDescription is an instance of RTCSessionDescription
+PASS pcA.pendingRemoteDescription is null
+PASS pcA.currentRemoteDescription is an instance of RTCSessionDescription
+
+PASS First offer/answer dialog completed
+========================================
+
+PASS pcB.getSenders().length is 1
+B: add media (should reuse sender)
+PASS pcB.getSenders().length is 1
+B: create offer
+B: got offer, set it as local description
+B: local offer set (session update so we have both pending and current local descriptions)
+PASS pcB.signalingState is 'have-local-offer'
+PASS pcB.pendingLocalDescription is an instance of RTCSessionDescription
+PASS pcB.currentLocalDescription is an instance of RTCSessionDescription
+
+B: send offer to A
+A <-- offer --- B
+A: got offer from B, set it as remote description
+----------
+PASS A: got remote track event
+----------
+A: remote offer set (session update so we have both pending and current remote descriptions)
+PASS pcA.signalingState is 'have-remote-offer'
+PASS pcA.pendingRemoteDescription is an instance of RTCSessionDescription
+PASS pcA.currentRemoteDescription is an instance of RTCSessionDescription
+
+A: create answer
+A: got answer, set it as local description
+A: local answer set
+PASS pcA.signalingState is 'stable'
+PASS pcA.pendingLocalDescription is null
+PASS pcA.currentLocalDescription is an instance of RTCSessionDescription
+PASS pcA.pendingRemoteDescription is null
+PASS pcA.currentRemoteDescription is an instance of RTCSessionDescription
+
+A: send answer to B
+A --- answer -> B
+B: got answer from A, set it as remote description
+B: remote answer set
+PASS pcB.signalingState is 'stable'
+PASS pcB.pendingLocalDescription is null
+PASS pcB.currentLocalDescription is an instance of RTCSessionDescription
+PASS pcB.pendingRemoteDescription is null
+PASS pcB.currentRemoteDescription is an instance of RTCSessionDescription
+
+PASS Second offer/answer dialog completed
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/mediastream/RTCPeerConnection-media-setup-two-dialogs.html b/LayoutTests/fast/mediastream/RTCPeerConnection-media-setup-two-dialogs.html
new file mode 100644 (file)
index 0000000..8a7f135
--- /dev/null
@@ -0,0 +1,189 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+    <head>
+        <script src="../../resources/js-test-pre.js"></script>
+        <script src="resources/promise-utils.js"></script>
+    </head>
+    <body>
+        <script>
+            let stream;
+            let offer;
+
+            description("Test setting up media between two RTCPeerConnection instances with a single SDP dialog.");
+
+            if (window.testRunner)
+                testRunner.setUserMediaPermission(true);
+            else {
+                debug("This test can not be run without the testRunner");
+                finishJSTest();
+            }
+
+            debug("Create RTCPeerConnection A");
+            const pcA = new webkitRTCPeerConnection({iceServers:[{urls:'stun:foo.com'}]});
+
+            shouldBe("pcA.signalingState", "'stable'");
+            shouldBeNull("pcA.pendingLocalDescription");
+            shouldBeNull("pcA.currentLocalDescription");
+            shouldBeNull("pcA.pendingRemoteDescription");
+            shouldBeNull("pcA.currentRemoteDescription");
+
+            debug("<br>Create RTCPeerConnection B");
+            const pcB = new webkitRTCPeerConnection({iceServers:[{urls:'stun:foo.com'}]});
+
+            shouldBe("pcB.signalingState", "'stable'");
+            shouldBeNull("pcB.pendingLocalDescription");
+            shouldBeNull("pcB.currentLocalDescription");
+            shouldBeNull("pcB.pendingRemoteDescription");
+            shouldBeNull("pcB.currentRemoteDescription");
+            debug("");
+
+            pcA.ontrack = function () {
+                debug("----------");
+                testPassed("A: got remote track event");
+                debug("----------");
+            };
+
+            pcB.ontrack = function () {
+                debug("----------");
+                testPassed("B: got remote track event");
+                debug("----------");
+            };
+
+            navigator.mediaDevices.getUserMedia({ "audio": true })
+            .then(function (s) {
+                stream = s;
+
+                debug("A: add media");
+                pcA.addTrack(stream.getAudioTracks()[0], stream);
+
+                debug("A: create offer");
+                return pcA.createOffer();
+            })
+            .then(function (offer) {
+                debug("A: got offer, set it as local description");
+                return pcA.setLocalDescription(offer);
+            })
+            .then(function () {
+                debug("A: local offer set");
+                shouldBe("pcA.signalingState", "'have-local-offer'");
+                shouldBeType("pcA.pendingLocalDescription", "RTCSessionDescription");
+                shouldBeNull("pcA.currentLocalDescription");
+
+                debug("<br>A: send offer to B");
+                debug("A --- offer --> B");
+                debug("B: got offer from A, set it as remote description");
+                return pcB.setRemoteDescription(pcA.localDescription);
+            })
+            .then(function () {
+                debug("B: remote offer set");
+                shouldBe("pcB.signalingState", "'have-remote-offer'");
+                shouldBeType("pcB.pendingRemoteDescription", "RTCSessionDescription");
+                shouldBeNull("pcB.currentRemoteDescription");
+
+                debug("<br>B: create answer (without local media)");
+                return pcB.createAnswer();
+            })
+            .then(function (answer) {
+                debug("B: got answer, set it as local description");
+                return pcB.setLocalDescription(answer);
+            })
+            .then(function () {
+                debug("B: local answer set");
+                shouldBe("pcB.signalingState", "'stable'");
+                shouldBeNull("pcB.pendingLocalDescription");
+                shouldBeType("pcB.currentLocalDescription", "RTCSessionDescription");
+                shouldBeNull("pcB.pendingRemoteDescription");
+                shouldBeType("pcB.currentRemoteDescription", "RTCSessionDescription");
+
+                debug("<br>B: send answer to A");
+                debug("A <-- answer -- B");
+                debug("A: got answer from B, set it as remote description");
+                return pcA.setRemoteDescription(pcB.localDescription);
+            })
+            .then(function () {
+                debug("A: remote answer set");
+                shouldBe("pcA.signalingState", "'stable'");
+                shouldBeNull("pcA.pendingLocalDescription");
+                shouldBeType("pcA.currentLocalDescription", "RTCSessionDescription");
+                shouldBeNull("pcA.pendingRemoteDescription");
+                shouldBeType("pcA.currentRemoteDescription", "RTCSessionDescription");
+                debug("");
+
+                testPassed("First offer/answer dialog completed")
+                debug("========================================<br>")
+
+                shouldBe("pcB.getSenders().length", "1");
+                debug("B: add media (should reuse sender)");
+                pcB.addTrack(stream.getAudioTracks()[0], stream);
+                shouldBe("pcB.getSenders().length", "1");
+
+                debug("B: create offer");
+                return pcB.createOffer();
+            })
+            .then(function (offer) {
+                debug("B: got offer, set it as local description");
+                return pcB.setLocalDescription(offer);
+            })
+            .then(function () {
+                debug("B: local offer set (session update so we have both pending and current local descriptions)");
+                shouldBe("pcB.signalingState", "'have-local-offer'");
+                shouldBeType("pcB.pendingLocalDescription", "RTCSessionDescription");
+                shouldBeType("pcB.currentLocalDescription", "RTCSessionDescription");
+
+                debug("<br>B: send offer to A");
+                debug("A <-- offer --- B");
+                debug("A: got offer from B, set it as remote description");
+                return pcA.setRemoteDescription(pcB.localDescription);
+            })
+            .then(function () {
+                debug("A: remote offer set (session update so we have both pending and current remote descriptions)");
+                shouldBe("pcA.signalingState", "'have-remote-offer'");
+                shouldBeType("pcA.pendingRemoteDescription", "RTCSessionDescription");
+                shouldBeType("pcA.currentRemoteDescription", "RTCSessionDescription");
+
+                debug("<br>A: create answer");
+                return pcA.createAnswer();
+            })
+            .then(function (answer) {
+                debug("A: got answer, set it as local description");
+                return pcA.setLocalDescription(answer);
+            })
+            .then(function () {
+                debug("A: local answer set");
+                shouldBe("pcA.signalingState", "'stable'");
+                shouldBeNull("pcA.pendingLocalDescription");
+                shouldBeType("pcA.currentLocalDescription", "RTCSessionDescription");
+                shouldBeNull("pcA.pendingRemoteDescription");
+                shouldBeType("pcA.currentRemoteDescription", "RTCSessionDescription");
+
+                debug("<br>A: send answer to B");
+                debug("A --- answer -> B");
+                debug("B: got answer from A, set it as remote description");
+                return pcB.setRemoteDescription(pcA.localDescription);
+            })
+            .then(function () {
+                debug("B: remote answer set");
+                shouldBe("pcB.signalingState", "'stable'");
+                shouldBeNull("pcB.pendingLocalDescription");
+                shouldBeType("pcB.currentLocalDescription", "RTCSessionDescription");
+                shouldBeNull("pcB.pendingRemoteDescription");
+                shouldBeType("pcB.currentRemoteDescription", "RTCSessionDescription");
+                debug("");
+
+                testPassed("Second offer/answer dialog completed")
+                debug("");
+
+                finishJSTest();
+            })
+            .catch(function (error) {
+                testFailed("Error in promise chain: " + error);
+                finishJSTest();
+            });
+
+            window.jsTestIsAsync = true;
+            window.successfullyParsed = true;
+
+        </script>
+        <script src="../../resources/js-test-post.js"></script>
+    </body>
+</html>
index 4e8c3dd..bff1f54 100644 (file)
@@ -196,6 +196,7 @@ fast/mediastream/RTCPeerConnection-setRemoteDescription-offer.html
 fast/mediastream/RTCTrackEvent-constructor.html
 fast/mediastream/RTCPeerConnection-inspect-answer.html
 fast/mediastream/RTCPeerConnection-media-setup-single-dialog.html
+fast/mediastream/RTCPeerConnection-media-setup-two-dialogs.html
 
 # Asserts in debug.
 [ Debug ] fast/images/large-size-image-crash.html [ Skip ]
index 0c413fb..7da411f 100644 (file)
@@ -1,3 +1,18 @@
+2016-06-14  Adam Bergkvist  <adam.bergkvist@ericsson.com>
+
+        WebRTC: Add media setup test where media is set up in one direction at a time
+        https://bugs.webkit.org/show_bug.cgi?id=158691
+
+        Reviewed by Eric Carlson.
+
+        Add test for setting up media in one direction at a time. This requires a change in sdp.js
+        to allow an SDP that doesn't contain a stream id or track id (representing
+        a track being sent). In this test, the first answer doesn't contain any sending media.
+
+        Test: fast/mediastream/RTCPeerConnection-media-setup-two-dialogs.html
+
+        * Modules/mediastream/sdp.js:
+
 2016-06-14  Chris Dumez  <cdumez@apple.com>
 
         [Cocoa] Avoid extra copy of headers dictionary in ResourceResponse::platformLazyInit()
index 6076f79..ecd2560 100644 (file)
@@ -538,8 +538,7 @@ if (typeof(SDP) == "undefined")
 
     var expectedProperties = {
         "session": [ "version", "originator", "sessionName", "startTime", "stopTime" ],
-        "mline": [ "type", "port", "protocol", "mode", "payloads", "rtcp", "mediaStreamId",
-            "mediaStreamTrackId", "dtls", "ssrcs", "cname", "ice" ],
+        "mline": [ "type", "port", "protocol", "mode", "payloads", "rtcp", "dtls", "ice" ],
         "mlineSubObjects": {
             "rtcp": [ "mux" ],
             "ice": [ "ufrag", "password" ],