| <!doctype html> | |
| <meta charset=utf-8> | |
| <meta name="timeout" content="long"> | |
| <title>RTCRtpSender.transport</title> | |
| <script src="/resources/testharness.js"></script> | |
| <script src="/resources/testharnessreport.js"></script> | |
| <script src="dictionary-helper.js"></script> | |
| <script src="RTCPeerConnection-helper.js"></script> | |
| <script> | |
| 'use strict'; | |
| // Spec link: http://w3c.github.io/webrtc-pc/#dom-rtcrtpsender-transport | |
| promise_test(async t => { | |
| const caller = new RTCPeerConnection(); | |
| t.add_cleanup(() => caller.close()); | |
| const stream = await getNoiseStream({audio: true}); | |
| t.add_cleanup(() => stream.getTracks().forEach(track => track.stop())); | |
| const [track] = stream.getTracks(); | |
| const sender = caller.addTrack(track); | |
| assert_equals(sender.transport, null); | |
| }, 'RTCRtpSender.transport is null when unconnected'); | |
| // Test for the simple/happy path of connecting a single track | |
| promise_test(async t => { | |
| const caller = new RTCPeerConnection(); | |
| t.add_cleanup(() => caller.close()); | |
| const stream = await getNoiseStream({audio: true}); | |
| t.add_cleanup(() => stream.getTracks().forEach(track => track.stop())); | |
| const [track] = stream.getTracks(); | |
| const sender = caller.addTrack(track); | |
| const callee = new RTCPeerConnection(); | |
| t.add_cleanup(() => callee.close()); | |
| exchangeIceCandidates(caller, callee); | |
| await exchangeOfferAndListenToOntrack(t, caller, callee); | |
| assert_not_equals(sender.transport, null); | |
| const [transceiver] = caller.getTransceivers(); | |
| assert_equals(transceiver.sender.transport, | |
| transceiver.receiver.transport); | |
| assert_not_equals(sender.transport.iceTransport, null); | |
| }, 'RTCRtpSender/receiver.transport has a value when connected'); | |
| // Test with multiple tracks, and checking details of when things show up | |
| // for different bundle policies. | |
| for (let bundle_policy of ['balanced', 'max-bundle', 'max-compat']) { | |
| promise_test(async t => { | |
| const caller = new RTCPeerConnection({bundlePolicy: bundle_policy}); | |
| t.add_cleanup(() => caller.close()); | |
| const stream = await getNoiseStream( | |
| {audio: true, video:true}); | |
| t.add_cleanup(() => stream.getTracks().forEach(track => track.stop())); | |
| const [track1, track2] = stream.getTracks(); | |
| const sender1 = caller.addTrack(track1); | |
| const sender2 = caller.addTrack(track2); | |
| const callee = new RTCPeerConnection(); | |
| t.add_cleanup(() => callee.close()); | |
| exchangeIceCandidates(caller, callee); | |
| const offer = await caller.createOffer(); | |
| assert_equals(sender1.transport, null); | |
| assert_equals(sender2.transport, null); | |
| await caller.setLocalDescription(offer); | |
| assert_not_equals(sender1.transport, null); | |
| assert_not_equals(sender2.transport, null); | |
| const [caller_transceiver1, caller_transceiver2] = caller.getTransceivers(); | |
| assert_equals(sender1.transport, caller_transceiver1.sender.transport); | |
| if (bundle_policy == 'max-bundle') { | |
| assert_equals(caller_transceiver1.sender.transport, | |
| caller_transceiver2.sender.transport); | |
| } else { | |
| assert_not_equals(caller_transceiver1.sender.transport, | |
| caller_transceiver2.sender.transport); | |
| } | |
| await callee.setRemoteDescription(offer); | |
| const [callee_transceiver1, callee_transceiver2] = callee.getTransceivers(); | |
| // According to spec, setRemoteDescription only updates the transports | |
| // if the remote description is an answer. | |
| assert_equals(callee_transceiver1.receiver.transport, null); | |
| assert_equals(callee_transceiver2.receiver.transport, null); | |
| const answer = await callee.createAnswer(); | |
| await callee.setLocalDescription(answer); | |
| assert_not_equals(callee_transceiver1.receiver.transport, null); | |
| assert_not_equals(callee_transceiver2.receiver.transport, null); | |
| // At this point, bundle should have kicked in. | |
| assert_equals(callee_transceiver1.receiver.transport, | |
| callee_transceiver2.receiver.transport); | |
| await caller.setRemoteDescription(answer); | |
| assert_equals(caller_transceiver1.receiver.transport, | |
| caller_transceiver2.receiver.transport); | |
| }, 'RTCRtpSender/receiver.transport at the right time, with bundle policy ' + bundle_policy); | |
| // Do the same test again, with DataChannel in the mix. | |
| promise_test(async t => { | |
| const caller = new RTCPeerConnection({bundlePolicy: bundle_policy}); | |
| t.add_cleanup(() => caller.close()); | |
| const stream = await getNoiseStream( | |
| {audio: true, video:true}); | |
| t.add_cleanup(() => stream.getTracks().forEach(track => track.stop())); | |
| const [track1, track2] = stream.getTracks(); | |
| const sender1 = caller.addTrack(track1); | |
| const sender2 = caller.addTrack(track2); | |
| caller.createDataChannel('datachannel'); | |
| const callee = new RTCPeerConnection(); | |
| t.add_cleanup(() => callee.close()); | |
| exchangeIceCandidates(caller, callee); | |
| const offer = await caller.createOffer(); | |
| assert_equals(sender1.transport, null); | |
| assert_equals(sender2.transport, null); | |
| if (caller.sctp) { | |
| assert_equals(caller.sctp.transport, null); | |
| } | |
| await caller.setLocalDescription(offer); | |
| assert_not_equals(sender1.transport, null); | |
| assert_not_equals(sender2.transport, null); | |
| assert_not_equals(caller.sctp.transport, null); | |
| const [caller_transceiver1, caller_transceiver2] = caller.getTransceivers(); | |
| assert_equals(sender1.transport, caller_transceiver1.sender.transport); | |
| if (bundle_policy == 'max-bundle') { | |
| assert_equals(caller_transceiver1.sender.transport, | |
| caller_transceiver2.sender.transport); | |
| assert_equals(caller_transceiver1.sender.transport, | |
| caller.sctp.transport); | |
| } else { | |
| assert_not_equals(caller_transceiver1.sender.transport, | |
| caller_transceiver2.sender.transport); | |
| assert_not_equals(caller_transceiver1.sender.transport, | |
| caller.sctp.transport); | |
| } | |
| await callee.setRemoteDescription(offer); | |
| const [callee_transceiver1, callee_transceiver2] = callee.getTransceivers(); | |
| // According to spec, setRemoteDescription only updates the transports | |
| // if the remote description is an answer. | |
| assert_equals(callee_transceiver1.receiver.transport, null); | |
| assert_equals(callee_transceiver2.receiver.transport, null); | |
| const answer = await callee.createAnswer(); | |
| await callee.setLocalDescription(answer); | |
| assert_not_equals(callee_transceiver1.receiver.transport, null); | |
| assert_not_equals(callee_transceiver2.receiver.transport, null); | |
| assert_not_equals(callee.sctp.transport, null); | |
| // At this point, bundle should have kicked in. | |
| assert_equals(callee_transceiver1.receiver.transport, | |
| callee_transceiver2.receiver.transport); | |
| assert_equals(callee_transceiver1.receiver.transport, | |
| callee.sctp.transport, | |
| 'Callee SCTP transport does not match:'); | |
| await caller.setRemoteDescription(answer); | |
| assert_equals(caller_transceiver1.receiver.transport, | |
| caller_transceiver2.receiver.transport); | |
| assert_equals(caller_transceiver1.receiver.transport, | |
| caller.sctp.transport, | |
| 'Caller SCTP transport does not match:'); | |
| }, 'RTCRtpSender/receiver/SCTP transport at the right time, with bundle policy ' + bundle_policy); | |
| } | |
| </script> |