blob: f0558eee3d45c7c25fe9b755960b7030f9ca9a22 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
2 * libjingle
jlmiller@webrtc.org5f93d0a2015-01-20 21:36:13 +00003 * Copyright 2012 Google Inc.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00004 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
deadbeefcbecd352015-09-23 11:50:27 -070028#include <vector>
29
henrike@webrtc.org28e20752013-07-10 00:45:36 +000030#include "talk/app/webrtc/audiotrack.h"
jbauchac8869e2015-07-03 01:36:14 -070031#include "talk/app/webrtc/fakemetricsobserver.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000032#include "talk/app/webrtc/jsepicecandidate.h"
33#include "talk/app/webrtc/jsepsessiondescription.h"
deadbeefab9b2d12015-10-14 11:33:11 -070034#include "talk/app/webrtc/peerconnection.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000035#include "talk/app/webrtc/mediastreamsignaling.h"
deadbeefab9b2d12015-10-14 11:33:11 -070036#include "talk/app/webrtc/sctputils.h"
37#include "talk/app/webrtc/streamcollection.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000038#include "talk/app/webrtc/streamcollection.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000039#include "talk/app/webrtc/test/fakeconstraints.h"
Henrik Boström5e56c592015-08-11 10:33:13 +020040#include "talk/app/webrtc/test/fakedtlsidentitystore.h"
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000041#include "talk/app/webrtc/videotrack.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000042#include "talk/app/webrtc/webrtcsession.h"
wu@webrtc.org91053e72013-08-10 07:18:04 +000043#include "talk/app/webrtc/webrtcsessiondescriptionfactory.h"
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000044#include "talk/media/base/fakemediaengine.h"
45#include "talk/media/base/fakevideorenderer.h"
46#include "talk/media/base/mediachannel.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000047#include "webrtc/p2p/base/stunserver.h"
48#include "webrtc/p2p/base/teststunserver.h"
49#include "webrtc/p2p/base/testturnserver.h"
pthatcher@webrtc.orgb4aac132015-03-13 18:25:21 +000050#include "webrtc/p2p/base/transportchannel.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000051#include "webrtc/p2p/client/basicportallocator.h"
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000052#include "talk/session/media/channelmanager.h"
53#include "talk/session/media/mediasession.h"
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000054#include "webrtc/base/fakenetwork.h"
55#include "webrtc/base/firewallsocketserver.h"
56#include "webrtc/base/gunit.h"
57#include "webrtc/base/logging.h"
58#include "webrtc/base/network.h"
59#include "webrtc/base/physicalsocketserver.h"
60#include "webrtc/base/ssladapter.h"
Henrik Boström5e56c592015-08-11 10:33:13 +020061#include "webrtc/base/sslidentity.h"
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000062#include "webrtc/base/sslstreamadapter.h"
63#include "webrtc/base/stringutils.h"
64#include "webrtc/base/thread.h"
65#include "webrtc/base/virtualsocketserver.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000066
67#define MAYBE_SKIP_TEST(feature) \
68 if (!(feature())) { \
69 LOG(LS_INFO) << "Feature disabled... skipping"; \
70 return; \
71 }
72
73using cricket::BaseSession;
74using cricket::DF_PLAY;
75using cricket::DF_SEND;
76using cricket::FakeVoiceMediaChannel;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000077using cricket::TransportInfo;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000078using rtc::SocketAddress;
79using rtc::scoped_ptr;
80using rtc::Thread;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000081using webrtc::CreateSessionDescription;
wu@webrtc.org91053e72013-08-10 07:18:04 +000082using webrtc::CreateSessionDescriptionObserver;
83using webrtc::CreateSessionDescriptionRequest;
deadbeefab9b2d12015-10-14 11:33:11 -070084using webrtc::DataChannel;
Henrik Boström5e56c592015-08-11 10:33:13 +020085using webrtc::DtlsIdentityStoreInterface;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000086using webrtc::FakeConstraints;
jbauchac8869e2015-07-03 01:36:14 -070087using webrtc::FakeMetricsObserver;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000088using webrtc::IceCandidateCollection;
deadbeefab9b2d12015-10-14 11:33:11 -070089using webrtc::InternalDataChannelInit;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000090using webrtc::JsepIceCandidate;
91using webrtc::JsepSessionDescription;
wu@webrtc.org97077a32013-10-25 21:18:33 +000092using webrtc::PeerConnectionFactoryInterface;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000093using webrtc::PeerConnectionInterface;
94using webrtc::SessionDescriptionInterface;
95using webrtc::StreamCollection;
wu@webrtc.org91053e72013-08-10 07:18:04 +000096using webrtc::WebRtcSession;
wu@webrtc.org364f2042013-11-20 21:49:41 +000097using webrtc::kBundleWithoutRtcpMux;
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +000098using webrtc::kCreateChannelFailed;
99using webrtc::kInvalidSdp;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000100using webrtc::kMlineMismatch;
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000101using webrtc::kPushDownTDFailed;
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000102using webrtc::kSdpWithoutIceUfragPwd;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000103using webrtc::kSdpWithoutDtlsFingerprint;
104using webrtc::kSdpWithoutSdesCrypto;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000105using webrtc::kSessionError;
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000106using webrtc::kSessionErrorDesc;
buildbot@webrtc.org53df88c2014-08-07 22:46:01 +0000107using webrtc::kMaxUnsignalledRecvStreams;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000108
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +0000109typedef PeerConnectionInterface::RTCOfferAnswerOptions RTCOfferAnswerOptions;
110
wu@webrtc.org364f2042013-11-20 21:49:41 +0000111static const int kClientAddrPort = 0;
112static const char kClientAddrHost1[] = "11.11.11.11";
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +0000113static const char kClientIPv6AddrHost1[] =
114 "2620:0:aaaa:bbbb:cccc:dddd:eeee:ffff";
wu@webrtc.org364f2042013-11-20 21:49:41 +0000115static const char kClientAddrHost2[] = "22.22.22.22";
116static const char kStunAddrHost[] = "99.99.99.1";
buildbot@webrtc.org41451d42014-05-03 05:39:45 +0000117static const SocketAddress kTurnUdpIntAddr("99.99.99.4", 3478);
118static const SocketAddress kTurnUdpExtAddr("99.99.99.6", 0);
mallinath@webrtc.org3d81b1b2014-09-09 14:38:10 +0000119static const char kTurnUsername[] = "test";
120static const char kTurnPassword[] = "test";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000121
122static const char kSessionVersion[] = "1";
123
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000124// Media index of candidates belonging to the first media content.
125static const int kMediaContentIndex0 = 0;
126static const char kMediaContentName0[] = "audio";
127
128// Media index of candidates belonging to the second media content.
129static const int kMediaContentIndex1 = 1;
130static const char kMediaContentName1[] = "video";
131
132static const int kIceCandidatesTimeout = 10000;
133
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +0000134static const char kFakeDtlsFingerprint[] =
135 "BB:CD:72:F7:2F:D0:BA:43:F3:68:B1:0C:23:72:B6:4A:"
136 "0F:DE:34:06:BC:E0:FE:01:BC:73:C8:6D:F4:65:D5:24";
137
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +0000138static const char kTooLongIceUfragPwd[] =
139 "IceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfrag"
140 "IceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfrag"
141 "IceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfrag"
142 "IceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfrag";
143
changbin.shao@webrtc.org2d25b442015-03-16 04:14:34 +0000144static const char kSdpWithRtx[] =
145 "v=0\r\n"
146 "o=- 4104004319237231850 2 IN IP4 127.0.0.1\r\n"
147 "s=-\r\n"
148 "t=0 0\r\n"
149 "a=msid-semantic: WMS stream1\r\n"
150 "m=video 9 RTP/SAVPF 0 96\r\n"
151 "c=IN IP4 0.0.0.0\r\n"
152 "a=rtcp:9 IN IP4 0.0.0.0\r\n"
153 "a=ice-ufrag:CerjGp19G7wpXwl7\r\n"
154 "a=ice-pwd:cMvOlFvQ6ochez1ZOoC2uBEC\r\n"
155 "a=mid:video\r\n"
156 "a=sendrecv\r\n"
157 "a=rtcp-mux\r\n"
158 "a=crypto:1 AES_CM_128_HMAC_SHA1_80 "
159 "inline:5/4N5CDvMiyDArHtBByUM71VIkguH17ZNoX60GrA\r\n"
160 "a=rtpmap:0 fake_video_codec/90000\r\n"
161 "a=rtpmap:96 rtx/90000\r\n"
162 "a=fmtp:96 apt=0\r\n";
163
deadbeefab9b2d12015-10-14 11:33:11 -0700164static const char kStream1[] = "stream1";
165static const char kVideoTrack1[] = "video1";
166static const char kAudioTrack1[] = "audio1";
167
168static const char kStream2[] = "stream2";
169static const char kVideoTrack2[] = "video2";
170static const char kAudioTrack2[] = "audio2";
171
Henrik Boström87713d02015-08-25 09:53:21 +0200172enum RTCCertificateGenerationMethod { ALREADY_GENERATED, DTLS_IDENTITY_STORE };
173
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000174// Add some extra |newlines| to the |message| after |line|.
175static void InjectAfter(const std::string& line,
176 const std::string& newlines,
177 std::string* message) {
178 const std::string tmp = line + newlines;
deadbeefcbecd352015-09-23 11:50:27 -0700179 rtc::replace_substrs(line.c_str(), line.length(), tmp.c_str(), tmp.length(),
180 message);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000181}
182
183class MockIceObserver : public webrtc::IceObserver {
184 public:
185 MockIceObserver()
186 : oncandidatesready_(false),
187 ice_connection_state_(PeerConnectionInterface::kIceConnectionNew),
188 ice_gathering_state_(PeerConnectionInterface::kIceGatheringNew) {
189 }
190
191 virtual void OnIceConnectionChange(
192 PeerConnectionInterface::IceConnectionState new_state) {
193 ice_connection_state_ = new_state;
194 }
195 virtual void OnIceGatheringChange(
196 PeerConnectionInterface::IceGatheringState new_state) {
197 // We can never transition back to "new".
198 EXPECT_NE(PeerConnectionInterface::kIceGatheringNew, new_state);
199 ice_gathering_state_ = new_state;
200
201 // oncandidatesready_ really means "ICE gathering is complete".
202 // This if statement ensures that this value remains correct when we
203 // transition from kIceGatheringComplete to kIceGatheringGathering.
204 if (new_state == PeerConnectionInterface::kIceGatheringGathering) {
205 oncandidatesready_ = false;
206 }
207 }
208
209 // Found a new candidate.
210 virtual void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) {
wu@webrtc.org364f2042013-11-20 21:49:41 +0000211 switch (candidate->sdp_mline_index()) {
212 case kMediaContentIndex0:
213 mline_0_candidates_.push_back(candidate->candidate());
214 break;
215 case kMediaContentIndex1:
216 mline_1_candidates_.push_back(candidate->candidate());
217 break;
218 default:
219 ASSERT(false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000220 }
wu@webrtc.org364f2042013-11-20 21:49:41 +0000221
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000222 // The ICE gathering state should always be Gathering when a candidate is
223 // received (or possibly Completed in the case of the final candidate).
224 EXPECT_NE(PeerConnectionInterface::kIceGatheringNew, ice_gathering_state_);
225 }
226
227 // TODO(bemasc): Remove this once callers transition to OnIceGatheringChange.
228 virtual void OnIceComplete() {
229 EXPECT_FALSE(oncandidatesready_);
230 oncandidatesready_ = true;
231
232 // OnIceGatheringChange(IceGatheringCompleted) and OnIceComplete() should
233 // be called approximately simultaneously. For ease of testing, this
234 // check additionally requires that they be called in the above order.
235 EXPECT_EQ(PeerConnectionInterface::kIceGatheringComplete,
236 ice_gathering_state_);
237 }
238
239 bool oncandidatesready_;
240 std::vector<cricket::Candidate> mline_0_candidates_;
241 std::vector<cricket::Candidate> mline_1_candidates_;
242 PeerConnectionInterface::IceConnectionState ice_connection_state_;
243 PeerConnectionInterface::IceGatheringState ice_gathering_state_;
244};
245
246class WebRtcSessionForTest : public webrtc::WebRtcSession {
247 public:
248 WebRtcSessionForTest(cricket::ChannelManager* cmgr,
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000249 rtc::Thread* signaling_thread,
250 rtc::Thread* worker_thread,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000251 cricket::PortAllocator* port_allocator,
deadbeefab9b2d12015-10-14 11:33:11 -0700252 webrtc::IceObserver* ice_observer)
253 : WebRtcSession(cmgr, signaling_thread, worker_thread, port_allocator) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000254 RegisterIceObserver(ice_observer);
255 }
256 virtual ~WebRtcSessionForTest() {}
257
deadbeefcbecd352015-09-23 11:50:27 -0700258 // Note that these methods are only safe to use if the signaling thread
259 // is the same as the worker thread
260 cricket::TransportChannel* voice_rtp_transport_channel() {
261 return rtp_transport_channel(voice_channel());
262 }
263
264 cricket::TransportChannel* voice_rtcp_transport_channel() {
265 return rtcp_transport_channel(voice_channel());
266 }
267
268 cricket::TransportChannel* video_rtp_transport_channel() {
269 return rtp_transport_channel(video_channel());
270 }
271
272 cricket::TransportChannel* video_rtcp_transport_channel() {
273 return rtcp_transport_channel(video_channel());
274 }
275
276 cricket::TransportChannel* data_rtp_transport_channel() {
277 return rtp_transport_channel(data_channel());
278 }
279
280 cricket::TransportChannel* data_rtcp_transport_channel() {
281 return rtcp_transport_channel(data_channel());
282 }
283
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000284 using webrtc::WebRtcSession::SetAudioPlayout;
285 using webrtc::WebRtcSession::SetAudioSend;
286 using webrtc::WebRtcSession::SetCaptureDevice;
287 using webrtc::WebRtcSession::SetVideoPlayout;
288 using webrtc::WebRtcSession::SetVideoSend;
deadbeefcbecd352015-09-23 11:50:27 -0700289
290 private:
291 cricket::TransportChannel* rtp_transport_channel(cricket::BaseChannel* ch) {
292 if (!ch) {
293 return nullptr;
294 }
295 return ch->transport_channel();
296 }
297
298 cricket::TransportChannel* rtcp_transport_channel(cricket::BaseChannel* ch) {
299 if (!ch) {
300 return nullptr;
301 }
302 return ch->rtcp_transport_channel();
303 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000304};
305
wu@webrtc.org91053e72013-08-10 07:18:04 +0000306class WebRtcSessionCreateSDPObserverForTest
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000307 : public rtc::RefCountedObject<CreateSessionDescriptionObserver> {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000308 public:
wu@webrtc.org91053e72013-08-10 07:18:04 +0000309 enum State {
310 kInit,
311 kFailed,
312 kSucceeded,
313 };
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000314 WebRtcSessionCreateSDPObserverForTest() : state_(kInit) {}
wu@webrtc.org91053e72013-08-10 07:18:04 +0000315
316 // CreateSessionDescriptionObserver implementation.
317 virtual void OnSuccess(SessionDescriptionInterface* desc) {
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000318 description_.reset(desc);
wu@webrtc.org91053e72013-08-10 07:18:04 +0000319 state_ = kSucceeded;
320 }
321 virtual void OnFailure(const std::string& error) {
322 state_ = kFailed;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000323 }
324
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000325 SessionDescriptionInterface* description() { return description_.get(); }
326
327 SessionDescriptionInterface* ReleaseDescription() {
328 return description_.release();
329 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000330
wu@webrtc.org91053e72013-08-10 07:18:04 +0000331 State state() const { return state_; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000332
wu@webrtc.org91053e72013-08-10 07:18:04 +0000333 protected:
334 ~WebRtcSessionCreateSDPObserverForTest() {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000335
336 private:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000337 rtc::scoped_ptr<SessionDescriptionInterface> description_;
wu@webrtc.org91053e72013-08-10 07:18:04 +0000338 State state_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000339};
340
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000341class FakeAudioRenderer : public cricket::AudioRenderer {
342 public:
solenberg98c68862015-10-09 03:27:14 -0700343 FakeAudioRenderer() : sink_(NULL) {}
henrike@webrtc.orga7b98182014-02-21 15:51:43 +0000344 virtual ~FakeAudioRenderer() {
345 if (sink_)
346 sink_->OnClose();
347 }
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000348
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000349 void SetSink(Sink* sink) override { sink_ = sink; }
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000350
henrike@webrtc.orga7b98182014-02-21 15:51:43 +0000351 cricket::AudioRenderer::Sink* sink() const { return sink_; }
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000352 private:
henrike@webrtc.orga7b98182014-02-21 15:51:43 +0000353 cricket::AudioRenderer::Sink* sink_;
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000354};
355
Henrik Boström87713d02015-08-25 09:53:21 +0200356class WebRtcSessionTest
deadbeefab9b2d12015-10-14 11:33:11 -0700357 : public testing::TestWithParam<RTCCertificateGenerationMethod>,
358 public sigslot::has_slots<> {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000359 protected:
360 // TODO Investigate why ChannelManager crashes, if it's created
361 // after stun_server.
362 WebRtcSessionTest()
363 : media_engine_(new cricket::FakeMediaEngine()),
364 data_engine_(new cricket::FakeDataEngine()),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000365 channel_manager_(new cricket::ChannelManager(
solenbergfacbbec2015-09-24 00:41:50 -0700366 media_engine_, data_engine_, new cricket::CaptureManager(),
367 rtc::Thread::Current())),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000368 tdesc_factory_(new cricket::TransportDescriptionFactory()),
369 desc_factory_(new cricket::MediaSessionDescriptionFactory(
370 channel_manager_.get(), tdesc_factory_.get())),
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000371 pss_(new rtc::PhysicalSocketServer),
372 vss_(new rtc::VirtualSocketServer(pss_.get())),
373 fss_(new rtc::FirewallSocketServer(vss_.get())),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000374 ss_scope_(fss_.get()),
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000375 stun_socket_addr_(rtc::SocketAddress(kStunAddrHost,
wu@webrtc.org364f2042013-11-20 21:49:41 +0000376 cricket::STUN_SERVER_PORT)),
jiayl@webrtc.orgbebc75e2014-09-26 23:01:11 +0000377 stun_server_(cricket::TestStunServer::Create(Thread::Current(),
378 stun_socket_addr_)),
buildbot@webrtc.org41451d42014-05-03 05:39:45 +0000379 turn_server_(Thread::Current(), kTurnUdpIntAddr, kTurnUdpExtAddr),
jbauchac8869e2015-07-03 01:36:14 -0700380 metrics_observer_(new rtc::RefCountedObject<FakeMetricsObserver>()) {
buildbot@webrtc.org51c55082014-07-28 22:26:15 +0000381 cricket::ServerAddresses stun_servers;
382 stun_servers.insert(stun_socket_addr_);
383 allocator_.reset(new cricket::BasicPortAllocator(
384 &network_manager_,
385 stun_servers,
386 SocketAddress(), SocketAddress(), SocketAddress()));
buildbot@webrtc.org41451d42014-05-03 05:39:45 +0000387 allocator_->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700388 cricket::PORTALLOCATOR_DISABLE_RELAY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000389 EXPECT_TRUE(channel_manager_->Init());
390 desc_factory_->set_add_legacy_streams(false);
buildbot@webrtc.org41451d42014-05-03 05:39:45 +0000391 allocator_->set_step_delay(cricket::kMinimumStepDelay);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000392 }
393
394 void AddInterface(const SocketAddress& addr) {
395 network_manager_.AddInterface(addr);
396 }
397
Henrik Boström87713d02015-08-25 09:53:21 +0200398 // If |dtls_identity_store| != null or |rtc_configuration| contains
399 // |certificates| then DTLS will be enabled unless explicitly disabled by
400 // |rtc_configuration| options. When DTLS is enabled a certificate will be
401 // used if provided, otherwise one will be generated using the
402 // |dtls_identity_store|.
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000403 void Init(
Henrik Boström5e56c592015-08-11 10:33:13 +0200404 rtc::scoped_ptr<webrtc::DtlsIdentityStoreInterface> dtls_identity_store,
Henrik Lundin64dad832015-05-11 12:44:23 +0200405 const PeerConnectionInterface::RTCConfiguration& rtc_configuration) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000406 ASSERT_TRUE(session_.get() == NULL);
407 session_.reset(new WebRtcSessionForTest(
deadbeefab9b2d12015-10-14 11:33:11 -0700408 channel_manager_.get(), rtc::Thread::Current(), rtc::Thread::Current(),
409 allocator_.get(), &observer_));
410 session_->SignalDataChannelOpenMessage.connect(
411 this, &WebRtcSessionTest::OnDataChannelOpenMessage);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000412
413 EXPECT_EQ(PeerConnectionInterface::kIceConnectionNew,
414 observer_.ice_connection_state_);
415 EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
416 observer_.ice_gathering_state_);
417
deadbeefcbecd352015-09-23 11:50:27 -0700418 EXPECT_TRUE(session_->Initialize(options_, constraints_.get(),
419 dtls_identity_store.Pass(),
420 rtc_configuration));
jbauchac8869e2015-07-03 01:36:14 -0700421 session_->set_metrics_observer(metrics_observer_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000422 }
423
deadbeefab9b2d12015-10-14 11:33:11 -0700424 void OnDataChannelOpenMessage(const std::string& label,
425 const InternalDataChannelInit& config) {
426 last_data_channel_label_ = label;
427 last_data_channel_config_ = config;
428 }
429
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000430 void Init() {
Henrik Lundin64dad832015-05-11 12:44:23 +0200431 PeerConnectionInterface::RTCConfiguration configuration;
Henrik Boström5e56c592015-08-11 10:33:13 +0200432 Init(nullptr, configuration);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000433 }
434
435 void InitWithIceTransport(
436 PeerConnectionInterface::IceTransportsType ice_transport_type) {
Henrik Lundin64dad832015-05-11 12:44:23 +0200437 PeerConnectionInterface::RTCConfiguration configuration;
438 configuration.type = ice_transport_type;
Henrik Boström5e56c592015-08-11 10:33:13 +0200439 Init(nullptr, configuration);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000440 }
441
442 void InitWithBundlePolicy(
443 PeerConnectionInterface::BundlePolicy bundle_policy) {
Henrik Lundin64dad832015-05-11 12:44:23 +0200444 PeerConnectionInterface::RTCConfiguration configuration;
Henrik Lundin64dad832015-05-11 12:44:23 +0200445 configuration.bundle_policy = bundle_policy;
Henrik Boström5e56c592015-08-11 10:33:13 +0200446 Init(nullptr, configuration);
Peter Thatcheraf55ccc2015-05-21 07:48:41 -0700447 }
448
449 void InitWithRtcpMuxPolicy(
450 PeerConnectionInterface::RtcpMuxPolicy rtcp_mux_policy) {
451 PeerConnectionInterface::RTCConfiguration configuration;
452 configuration.rtcp_mux_policy = rtcp_mux_policy;
Henrik Boström5e56c592015-08-11 10:33:13 +0200453 Init(nullptr, configuration);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000454 }
455
Henrik Boström87713d02015-08-25 09:53:21 +0200456 // Successfully init with DTLS; with a certificate generated and supplied or
457 // with a store that generates it for us.
458 void InitWithDtls(RTCCertificateGenerationMethod cert_gen_method) {
459 rtc::scoped_ptr<FakeDtlsIdentityStore> dtls_identity_store;
460 PeerConnectionInterface::RTCConfiguration configuration;
461 if (cert_gen_method == ALREADY_GENERATED) {
462 configuration.certificates.push_back(
463 FakeDtlsIdentityStore::GenerateCertificate());
464 } else if (cert_gen_method == DTLS_IDENTITY_STORE) {
465 dtls_identity_store.reset(new FakeDtlsIdentityStore());
466 dtls_identity_store->set_should_fail(false);
467 } else {
henrikg91d6ede2015-09-17 00:24:34 -0700468 RTC_CHECK(false);
Henrik Boström87713d02015-08-25 09:53:21 +0200469 }
470 Init(dtls_identity_store.Pass(), configuration);
471 }
472
473 // Init with DTLS with a store that will fail to generate a certificate.
474 void InitWithDtlsIdentityGenFail() {
Henrik Boström5e56c592015-08-11 10:33:13 +0200475 rtc::scoped_ptr<FakeDtlsIdentityStore> dtls_identity_store(
476 new FakeDtlsIdentityStore());
Henrik Boström87713d02015-08-25 09:53:21 +0200477 dtls_identity_store->set_should_fail(true);
Henrik Lundin64dad832015-05-11 12:44:23 +0200478 PeerConnectionInterface::RTCConfiguration configuration;
Henrik Boström5e56c592015-08-11 10:33:13 +0200479 Init(dtls_identity_store.Pass(), configuration);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000480 }
481
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000482 void InitWithDtmfCodec() {
483 // Add kTelephoneEventCodec for dtmf test.
wu@webrtc.org364f2042013-11-20 21:49:41 +0000484 const cricket::AudioCodec kTelephoneEventCodec(
485 106, "telephone-event", 8000, 0, 1, 0);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000486 std::vector<cricket::AudioCodec> codecs;
487 codecs.push_back(kTelephoneEventCodec);
488 media_engine_->SetAudioCodecs(codecs);
489 desc_factory_->set_audio_codecs(codecs);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000490 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000491 }
492
deadbeefab9b2d12015-10-14 11:33:11 -0700493 void SendAudioVideoStream1() {
494 send_stream_1_ = true;
495 send_stream_2_ = false;
496 send_audio_ = true;
497 send_video_ = true;
498 }
499
500 void SendAudioVideoStream2() {
501 send_stream_1_ = false;
502 send_stream_2_ = true;
503 send_audio_ = true;
504 send_video_ = true;
505 }
506
507 void SendAudioVideoStream1And2() {
508 send_stream_1_ = true;
509 send_stream_2_ = true;
510 send_audio_ = true;
511 send_video_ = true;
512 }
513
514 void SendNothing() {
515 send_stream_1_ = false;
516 send_stream_2_ = false;
517 send_audio_ = false;
518 send_video_ = false;
519 }
520
521 void SendAudioOnlyStream2() {
522 send_stream_1_ = false;
523 send_stream_2_ = true;
524 send_audio_ = true;
525 send_video_ = false;
526 }
527
528 void SendVideoOnlyStream2() {
529 send_stream_1_ = false;
530 send_stream_2_ = true;
531 send_audio_ = false;
532 send_video_ = true;
533 }
534
535 void AddStreamsToOptions(cricket::MediaSessionOptions* session_options) {
536 if (send_stream_1_ && send_audio_) {
537 session_options->AddSendStream(cricket::MEDIA_TYPE_AUDIO, kAudioTrack1,
538 kStream1);
539 }
540 if (send_stream_1_ && send_video_) {
541 session_options->AddSendStream(cricket::MEDIA_TYPE_VIDEO, kVideoTrack1,
542 kStream1);
543 }
544 if (send_stream_2_ && send_audio_) {
545 session_options->AddSendStream(cricket::MEDIA_TYPE_AUDIO, kAudioTrack2,
546 kStream2);
547 }
548 if (send_stream_2_ && send_video_) {
549 session_options->AddSendStream(cricket::MEDIA_TYPE_VIDEO, kVideoTrack2,
550 kStream2);
551 }
552 if (data_channel_ && session_->data_channel_type() == cricket::DCT_RTP) {
553 session_options->AddSendStream(cricket::MEDIA_TYPE_DATA,
554 data_channel_->label(),
555 data_channel_->label());
556 }
557 }
558
559 void GetOptionsForOffer(
560 const PeerConnectionInterface::RTCOfferAnswerOptions& rtc_options,
561 cricket::MediaSessionOptions* session_options) {
562 AddStreamsToOptions(session_options);
563 ASSERT_TRUE(ConvertRtcOptionsForOffer(rtc_options, session_options));
564
565 if (session_->data_channel_type() == cricket::DCT_SCTP && data_channel_) {
566 session_options->data_channel_type = cricket::DCT_SCTP;
567 }
568 }
569
570 void GetOptionsForAnswer(const webrtc::MediaConstraintsInterface* constraints,
571 cricket::MediaSessionOptions* session_options) {
572 AddStreamsToOptions(session_options);
573 session_options->recv_audio = false;
574 session_options->recv_video = false;
575 ASSERT_TRUE(ParseConstraintsForAnswer(constraints, session_options));
576
577 if (session_->data_channel_type() == cricket::DCT_SCTP) {
578 session_options->data_channel_type = cricket::DCT_SCTP;
579 }
580 }
581
582 // Creates a local offer and applies it. Starts ICE.
583 // Call SendAudioVideoStreamX() before this function
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000584 // to decide which streams to create.
585 void InitiateCall() {
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +0000586 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000587 SetLocalDescriptionWithoutError(offer);
588 EXPECT_TRUE_WAIT(PeerConnectionInterface::kIceGatheringNew !=
589 observer_.ice_gathering_state_,
590 kIceCandidatesTimeout);
591 }
592
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +0000593 SessionDescriptionInterface* CreateOffer() {
594 PeerConnectionInterface::RTCOfferAnswerOptions options;
595 options.offer_to_receive_audio =
596 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
597
598 return CreateOffer(options);
599 }
600
wu@webrtc.org91053e72013-08-10 07:18:04 +0000601 SessionDescriptionInterface* CreateOffer(
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +0000602 const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000603 rtc::scoped_refptr<WebRtcSessionCreateSDPObserverForTest>
wu@webrtc.org91053e72013-08-10 07:18:04 +0000604 observer = new WebRtcSessionCreateSDPObserverForTest();
deadbeefab9b2d12015-10-14 11:33:11 -0700605 cricket::MediaSessionOptions session_options;
606 GetOptionsForOffer(options, &session_options);
607 session_->CreateOffer(observer, options, session_options);
wu@webrtc.org91053e72013-08-10 07:18:04 +0000608 EXPECT_TRUE_WAIT(
609 observer->state() != WebRtcSessionCreateSDPObserverForTest::kInit,
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000610 2000);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000611 return observer->ReleaseDescription();
wu@webrtc.org91053e72013-08-10 07:18:04 +0000612 }
613
614 SessionDescriptionInterface* CreateAnswer(
615 const webrtc::MediaConstraintsInterface* constraints) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000616 rtc::scoped_refptr<WebRtcSessionCreateSDPObserverForTest> observer
wu@webrtc.org91053e72013-08-10 07:18:04 +0000617 = new WebRtcSessionCreateSDPObserverForTest();
deadbeefab9b2d12015-10-14 11:33:11 -0700618 cricket::MediaSessionOptions session_options;
619 GetOptionsForAnswer(constraints, &session_options);
620 session_->CreateAnswer(observer, constraints, session_options);
wu@webrtc.org91053e72013-08-10 07:18:04 +0000621 EXPECT_TRUE_WAIT(
622 observer->state() != WebRtcSessionCreateSDPObserverForTest::kInit,
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000623 2000);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000624 return observer->ReleaseDescription();
wu@webrtc.org91053e72013-08-10 07:18:04 +0000625 }
626
wu@webrtc.org364f2042013-11-20 21:49:41 +0000627 bool ChannelsExist() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000628 return (session_->voice_channel() != NULL &&
629 session_->video_channel() != NULL);
630 }
631
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000632 void VerifyCryptoParams(const cricket::SessionDescription* sdp) {
633 ASSERT_TRUE(session_.get() != NULL);
634 const cricket::ContentInfo* content = cricket::GetFirstAudioContent(sdp);
635 ASSERT_TRUE(content != NULL);
636 const cricket::AudioContentDescription* audio_content =
637 static_cast<const cricket::AudioContentDescription*>(
638 content->description);
639 ASSERT_TRUE(audio_content != NULL);
640 ASSERT_EQ(1U, audio_content->cryptos().size());
641 ASSERT_EQ(47U, audio_content->cryptos()[0].key_params.size());
642 ASSERT_EQ("AES_CM_128_HMAC_SHA1_80",
643 audio_content->cryptos()[0].cipher_suite);
644 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf),
645 audio_content->protocol());
646
647 content = cricket::GetFirstVideoContent(sdp);
648 ASSERT_TRUE(content != NULL);
649 const cricket::VideoContentDescription* video_content =
650 static_cast<const cricket::VideoContentDescription*>(
651 content->description);
652 ASSERT_TRUE(video_content != NULL);
653 ASSERT_EQ(1U, video_content->cryptos().size());
654 ASSERT_EQ("AES_CM_128_HMAC_SHA1_80",
655 video_content->cryptos()[0].cipher_suite);
656 ASSERT_EQ(47U, video_content->cryptos()[0].key_params.size());
657 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf),
658 video_content->protocol());
659 }
660
661 void VerifyNoCryptoParams(const cricket::SessionDescription* sdp, bool dtls) {
662 const cricket::ContentInfo* content = cricket::GetFirstAudioContent(sdp);
663 ASSERT_TRUE(content != NULL);
664 const cricket::AudioContentDescription* audio_content =
665 static_cast<const cricket::AudioContentDescription*>(
666 content->description);
667 ASSERT_TRUE(audio_content != NULL);
668 ASSERT_EQ(0U, audio_content->cryptos().size());
669
670 content = cricket::GetFirstVideoContent(sdp);
671 ASSERT_TRUE(content != NULL);
672 const cricket::VideoContentDescription* video_content =
673 static_cast<const cricket::VideoContentDescription*>(
674 content->description);
675 ASSERT_TRUE(video_content != NULL);
676 ASSERT_EQ(0U, video_content->cryptos().size());
677
678 if (dtls) {
deadbeeff3938292015-07-15 12:20:53 -0700679 EXPECT_EQ(std::string(cricket::kMediaProtocolDtlsSavpf),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000680 audio_content->protocol());
deadbeeff3938292015-07-15 12:20:53 -0700681 EXPECT_EQ(std::string(cricket::kMediaProtocolDtlsSavpf),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000682 video_content->protocol());
683 } else {
684 EXPECT_EQ(std::string(cricket::kMediaProtocolAvpf),
685 audio_content->protocol());
686 EXPECT_EQ(std::string(cricket::kMediaProtocolAvpf),
687 video_content->protocol());
688 }
689 }
690
691 // Set the internal fake description factories to do DTLS-SRTP.
692 void SetFactoryDtlsSrtp() {
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000693 desc_factory_->set_secure(cricket::SEC_DISABLED);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000694 std::string identity_name = "WebRTC" +
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000695 rtc::ToString(rtc::CreateRandomId());
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200696 // Confirmed to work with KT_RSA and KT_ECDSA.
Henrik Boström3a14bf32015-08-31 09:27:58 +0200697 tdesc_factory_->set_certificate(rtc::RTCCertificate::Create(
torbjorng335204c2015-10-08 02:30:14 -0700698 rtc::scoped_ptr<rtc::SSLIdentity>(rtc::SSLIdentity::Generate(
699 identity_name, rtc::KT_DEFAULT)).Pass()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000700 tdesc_factory_->set_secure(cricket::SEC_REQUIRED);
701 }
702
703 void VerifyFingerprintStatus(const cricket::SessionDescription* sdp,
704 bool expected) {
705 const TransportInfo* audio = sdp->GetTransportInfoByName("audio");
706 ASSERT_TRUE(audio != NULL);
707 ASSERT_EQ(expected, audio->description.identity_fingerprint.get() != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000708 const TransportInfo* video = sdp->GetTransportInfoByName("video");
709 ASSERT_TRUE(video != NULL);
710 ASSERT_EQ(expected, video->description.identity_fingerprint.get() != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000711 }
712
713 void VerifyAnswerFromNonCryptoOffer() {
jiayl@webrtc.org7d4891d2014-09-09 21:43:15 +0000714 // Create an SDP without Crypto.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000715 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +0000716 options.recv_video = true;
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000717 JsepSessionDescription* offer(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000718 CreateRemoteOffer(options, cricket::SEC_DISABLED));
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000719 ASSERT_TRUE(offer != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000720 VerifyNoCryptoParams(offer->description(), false);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000721 SetRemoteDescriptionOfferExpectError(kSdpWithoutSdesCrypto,
722 offer);
wu@webrtc.org91053e72013-08-10 07:18:04 +0000723 const webrtc::SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000724 // Answer should be NULL as no crypto params in offer.
725 ASSERT_TRUE(answer == NULL);
726 }
727
728 void VerifyAnswerFromCryptoOffer() {
729 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +0000730 options.recv_video = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000731 options.bundle_enabled = true;
732 scoped_ptr<JsepSessionDescription> offer(
733 CreateRemoteOffer(options, cricket::SEC_REQUIRED));
734 ASSERT_TRUE(offer.get() != NULL);
735 VerifyCryptoParams(offer->description());
736 SetRemoteDescriptionWithoutError(offer.release());
wu@webrtc.org91053e72013-08-10 07:18:04 +0000737 scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000738 ASSERT_TRUE(answer.get() != NULL);
739 VerifyCryptoParams(answer->description());
740 }
741
buildbot@webrtc.org53df88c2014-08-07 22:46:01 +0000742 void SetAndVerifyNumUnsignalledRecvStreams(
743 int value_set, int value_expected) {
744 constraints_.reset(new FakeConstraints());
745 constraints_->AddOptional(
746 webrtc::MediaConstraintsInterface::kNumUnsignalledRecvStreams,
747 value_set);
748 session_.reset();
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000749 Init();
deadbeefab9b2d12015-10-14 11:33:11 -0700750 SendAudioVideoStream1();
buildbot@webrtc.org53df88c2014-08-07 22:46:01 +0000751 SessionDescriptionInterface* offer = CreateOffer();
752
753 SetLocalDescriptionWithoutError(offer);
754
755 video_channel_ = media_engine_->GetVideoChannel(0);
756
757 ASSERT_TRUE(video_channel_ != NULL);
solenberg66f43392015-09-09 01:36:22 -0700758 const cricket::VideoOptions& video_options = video_channel_->options();
buildbot@webrtc.org53df88c2014-08-07 22:46:01 +0000759 EXPECT_EQ(value_expected,
760 video_options.unsignalled_recv_stream_limit.GetWithDefaultIfUnset(-1));
761 }
762
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000763 void CompareIceUfragAndPassword(const cricket::SessionDescription* desc1,
764 const cricket::SessionDescription* desc2,
765 bool expect_equal) {
766 if (desc1->contents().size() != desc2->contents().size()) {
767 EXPECT_FALSE(expect_equal);
768 return;
769 }
770
771 const cricket::ContentInfos& contents = desc1->contents();
772 cricket::ContentInfos::const_iterator it = contents.begin();
773
774 for (; it != contents.end(); ++it) {
775 const cricket::TransportDescription* transport_desc1 =
776 desc1->GetTransportDescriptionByName(it->name);
777 const cricket::TransportDescription* transport_desc2 =
778 desc2->GetTransportDescriptionByName(it->name);
779 if (!transport_desc1 || !transport_desc2) {
780 EXPECT_FALSE(expect_equal);
781 return;
782 }
783 if (transport_desc1->ice_pwd != transport_desc2->ice_pwd ||
784 transport_desc1->ice_ufrag != transport_desc2->ice_ufrag) {
785 EXPECT_FALSE(expect_equal);
786 return;
787 }
788 }
789 EXPECT_TRUE(expect_equal);
790 }
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000791
792 void RemoveIceUfragPwdLines(const SessionDescriptionInterface* current_desc,
793 std::string *sdp) {
794 const cricket::SessionDescription* desc = current_desc->description();
795 EXPECT_TRUE(current_desc->ToString(sdp));
796
797 const cricket::ContentInfos& contents = desc->contents();
798 cricket::ContentInfos::const_iterator it = contents.begin();
799 // Replace ufrag and pwd lines with empty strings.
800 for (; it != contents.end(); ++it) {
801 const cricket::TransportDescription* transport_desc =
802 desc->GetTransportDescriptionByName(it->name);
803 std::string ufrag_line = "a=ice-ufrag:" + transport_desc->ice_ufrag
804 + "\r\n";
805 std::string pwd_line = "a=ice-pwd:" + transport_desc->ice_pwd
806 + "\r\n";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000807 rtc::replace_substrs(ufrag_line.c_str(), ufrag_line.length(),
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000808 "", 0,
809 sdp);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000810 rtc::replace_substrs(pwd_line.c_str(), pwd_line.length(),
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000811 "", 0,
812 sdp);
813 }
814 }
815
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +0000816 void ModifyIceUfragPwdLines(const SessionDescriptionInterface* current_desc,
817 const std::string& modified_ice_ufrag,
818 const std::string& modified_ice_pwd,
819 std::string* sdp) {
820 const cricket::SessionDescription* desc = current_desc->description();
821 EXPECT_TRUE(current_desc->ToString(sdp));
822
823 const cricket::ContentInfos& contents = desc->contents();
824 cricket::ContentInfos::const_iterator it = contents.begin();
825 // Replace ufrag and pwd lines with |modified_ice_ufrag| and
826 // |modified_ice_pwd| strings.
827 for (; it != contents.end(); ++it) {
828 const cricket::TransportDescription* transport_desc =
829 desc->GetTransportDescriptionByName(it->name);
830 std::string ufrag_line = "a=ice-ufrag:" + transport_desc->ice_ufrag
831 + "\r\n";
832 std::string pwd_line = "a=ice-pwd:" + transport_desc->ice_pwd
833 + "\r\n";
834 std::string mod_ufrag = "a=ice-ufrag:" + modified_ice_ufrag + "\r\n";
835 std::string mod_pwd = "a=ice-pwd:" + modified_ice_pwd + "\r\n";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000836 rtc::replace_substrs(ufrag_line.c_str(), ufrag_line.length(),
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +0000837 mod_ufrag.c_str(), mod_ufrag.length(),
838 sdp);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000839 rtc::replace_substrs(pwd_line.c_str(), pwd_line.length(),
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +0000840 mod_pwd.c_str(), mod_pwd.length(),
841 sdp);
842 }
843 }
844
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000845 // Creates a remote offer and and applies it as a remote description,
846 // creates a local answer and applies is as a local description.
deadbeefab9b2d12015-10-14 11:33:11 -0700847 // Call SendAudioVideoStreamX() before this function
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000848 // to decide which local and remote streams to create.
849 void CreateAndSetRemoteOfferAndLocalAnswer() {
850 SessionDescriptionInterface* offer = CreateRemoteOffer();
851 SetRemoteDescriptionWithoutError(offer);
wu@webrtc.org91053e72013-08-10 07:18:04 +0000852 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000853 SetLocalDescriptionWithoutError(answer);
854 }
855 void SetLocalDescriptionWithoutError(SessionDescriptionInterface* desc) {
856 EXPECT_TRUE(session_->SetLocalDescription(desc, NULL));
deadbeefcbecd352015-09-23 11:50:27 -0700857 session_->MaybeStartGathering();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000858 }
859 void SetLocalDescriptionExpectState(SessionDescriptionInterface* desc,
860 BaseSession::State expected_state) {
861 SetLocalDescriptionWithoutError(desc);
862 EXPECT_EQ(expected_state, session_->state());
863 }
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000864 void SetLocalDescriptionExpectError(const std::string& action,
865 const std::string& expected_error,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000866 SessionDescriptionInterface* desc) {
867 std::string error;
868 EXPECT_FALSE(session_->SetLocalDescription(desc, &error));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000869 std::string sdp_type = "local ";
870 sdp_type.append(action);
871 EXPECT_NE(std::string::npos, error.find(sdp_type));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000872 EXPECT_NE(std::string::npos, error.find(expected_error));
873 }
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000874 void SetLocalDescriptionOfferExpectError(const std::string& expected_error,
875 SessionDescriptionInterface* desc) {
876 SetLocalDescriptionExpectError(SessionDescriptionInterface::kOffer,
877 expected_error, desc);
878 }
879 void SetLocalDescriptionAnswerExpectError(const std::string& expected_error,
880 SessionDescriptionInterface* desc) {
881 SetLocalDescriptionExpectError(SessionDescriptionInterface::kAnswer,
882 expected_error, desc);
883 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000884 void SetRemoteDescriptionWithoutError(SessionDescriptionInterface* desc) {
885 EXPECT_TRUE(session_->SetRemoteDescription(desc, NULL));
886 }
887 void SetRemoteDescriptionExpectState(SessionDescriptionInterface* desc,
888 BaseSession::State expected_state) {
889 SetRemoteDescriptionWithoutError(desc);
890 EXPECT_EQ(expected_state, session_->state());
891 }
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000892 void SetRemoteDescriptionExpectError(const std::string& action,
893 const std::string& expected_error,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000894 SessionDescriptionInterface* desc) {
895 std::string error;
896 EXPECT_FALSE(session_->SetRemoteDescription(desc, &error));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000897 std::string sdp_type = "remote ";
898 sdp_type.append(action);
899 EXPECT_NE(std::string::npos, error.find(sdp_type));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000900 EXPECT_NE(std::string::npos, error.find(expected_error));
901 }
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000902 void SetRemoteDescriptionOfferExpectError(
903 const std::string& expected_error, SessionDescriptionInterface* desc) {
904 SetRemoteDescriptionExpectError(SessionDescriptionInterface::kOffer,
905 expected_error, desc);
906 }
907 void SetRemoteDescriptionPranswerExpectError(
908 const std::string& expected_error, SessionDescriptionInterface* desc) {
909 SetRemoteDescriptionExpectError(SessionDescriptionInterface::kPrAnswer,
910 expected_error, desc);
911 }
912 void SetRemoteDescriptionAnswerExpectError(
913 const std::string& expected_error, SessionDescriptionInterface* desc) {
914 SetRemoteDescriptionExpectError(SessionDescriptionInterface::kAnswer,
915 expected_error, desc);
916 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000917
918 void CreateCryptoOfferAndNonCryptoAnswer(SessionDescriptionInterface** offer,
919 SessionDescriptionInterface** nocrypto_answer) {
920 // Create a SDP without Crypto.
921 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +0000922 options.recv_video = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000923 options.bundle_enabled = true;
924 *offer = CreateRemoteOffer(options, cricket::SEC_ENABLED);
925 ASSERT_TRUE(*offer != NULL);
926 VerifyCryptoParams((*offer)->description());
927
928 *nocrypto_answer = CreateRemoteAnswer(*offer, options,
929 cricket::SEC_DISABLED);
930 EXPECT_TRUE(*nocrypto_answer != NULL);
931 }
932
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000933 void CreateDtlsOfferAndNonDtlsAnswer(SessionDescriptionInterface** offer,
934 SessionDescriptionInterface** nodtls_answer) {
935 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +0000936 options.recv_video = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000937 options.bundle_enabled = true;
938
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000939 rtc::scoped_ptr<SessionDescriptionInterface> temp_offer(
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000940 CreateRemoteOffer(options, cricket::SEC_ENABLED));
941
942 *nodtls_answer =
943 CreateRemoteAnswer(temp_offer.get(), options, cricket::SEC_ENABLED);
944 EXPECT_TRUE(*nodtls_answer != NULL);
945 VerifyFingerprintStatus((*nodtls_answer)->description(), false);
946 VerifyCryptoParams((*nodtls_answer)->description());
947
948 SetFactoryDtlsSrtp();
949 *offer = CreateRemoteOffer(options, cricket::SEC_ENABLED);
950 ASSERT_TRUE(*offer != NULL);
951 VerifyFingerprintStatus((*offer)->description(), true);
952 VerifyCryptoParams((*offer)->description());
953 }
954
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000955 JsepSessionDescription* CreateRemoteOfferWithVersion(
956 cricket::MediaSessionOptions options,
957 cricket::SecurePolicy secure_policy,
958 const std::string& session_version,
959 const SessionDescriptionInterface* current_desc) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000960 std::string session_id = rtc::ToString(rtc::CreateRandomId64());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000961 const cricket::SessionDescription* cricket_desc = NULL;
962 if (current_desc) {
963 cricket_desc = current_desc->description();
964 session_id = current_desc->session_id();
965 }
966
967 desc_factory_->set_secure(secure_policy);
968 JsepSessionDescription* offer(
969 new JsepSessionDescription(JsepSessionDescription::kOffer));
970 if (!offer->Initialize(desc_factory_->CreateOffer(options, cricket_desc),
971 session_id, session_version)) {
972 delete offer;
973 offer = NULL;
974 }
975 return offer;
976 }
977 JsepSessionDescription* CreateRemoteOffer(
978 cricket::MediaSessionOptions options) {
979 return CreateRemoteOfferWithVersion(options, cricket::SEC_ENABLED,
980 kSessionVersion, NULL);
981 }
982 JsepSessionDescription* CreateRemoteOffer(
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000983 cricket::MediaSessionOptions options, cricket::SecurePolicy sdes_policy) {
984 return CreateRemoteOfferWithVersion(
985 options, sdes_policy, kSessionVersion, NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000986 }
987 JsepSessionDescription* CreateRemoteOffer(
988 cricket::MediaSessionOptions options,
989 const SessionDescriptionInterface* current_desc) {
990 return CreateRemoteOfferWithVersion(options, cricket::SEC_ENABLED,
991 kSessionVersion, current_desc);
992 }
993
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000994 JsepSessionDescription* CreateRemoteOfferWithSctpPort(
995 const char* sctp_stream_name, int new_port,
996 cricket::MediaSessionOptions options) {
997 options.data_channel_type = cricket::DCT_SCTP;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +0000998 options.AddSendStream(cricket::MEDIA_TYPE_DATA, "datachannel",
999 sctp_stream_name);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001000 return ChangeSDPSctpPort(new_port, CreateRemoteOffer(options));
1001 }
1002
1003 // Takes ownership of offer_basis (and deletes it).
1004 JsepSessionDescription* ChangeSDPSctpPort(
1005 int new_port, webrtc::SessionDescriptionInterface *offer_basis) {
1006 // Stringify the input SDP, swap the 5000 for 'new_port' and create a new
1007 // SessionDescription from the mutated string.
1008 const char* default_port_str = "5000";
1009 char new_port_str[16];
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001010 rtc::sprintfn(new_port_str, sizeof(new_port_str), "%d", new_port);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001011 std::string offer_str;
1012 offer_basis->ToString(&offer_str);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001013 rtc::replace_substrs(default_port_str, strlen(default_port_str),
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001014 new_port_str, strlen(new_port_str),
1015 &offer_str);
1016 JsepSessionDescription* offer = new JsepSessionDescription(
1017 offer_basis->type());
1018 delete offer_basis;
1019 offer->Initialize(offer_str, NULL);
1020 return offer;
1021 }
1022
deadbeefab9b2d12015-10-14 11:33:11 -07001023 // Create a remote offer. Call SendAudioVideoStreamX()
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001024 // before this function to decide which streams to create.
1025 JsepSessionDescription* CreateRemoteOffer() {
1026 cricket::MediaSessionOptions options;
deadbeefab9b2d12015-10-14 11:33:11 -07001027 GetOptionsForAnswer(NULL, &options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001028 return CreateRemoteOffer(options, session_->remote_description());
1029 }
1030
1031 JsepSessionDescription* CreateRemoteAnswer(
1032 const SessionDescriptionInterface* offer,
1033 cricket::MediaSessionOptions options,
1034 cricket::SecurePolicy policy) {
1035 desc_factory_->set_secure(policy);
1036 const std::string session_id =
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001037 rtc::ToString(rtc::CreateRandomId64());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001038 JsepSessionDescription* answer(
1039 new JsepSessionDescription(JsepSessionDescription::kAnswer));
1040 if (!answer->Initialize(desc_factory_->CreateAnswer(offer->description(),
1041 options, NULL),
1042 session_id, kSessionVersion)) {
1043 delete answer;
1044 answer = NULL;
1045 }
1046 return answer;
1047 }
1048
1049 JsepSessionDescription* CreateRemoteAnswer(
1050 const SessionDescriptionInterface* offer,
1051 cricket::MediaSessionOptions options) {
1052 return CreateRemoteAnswer(offer, options, cricket::SEC_REQUIRED);
1053 }
1054
deadbeefab9b2d12015-10-14 11:33:11 -07001055 // Creates an answer session description.
1056 // Call SendAudioVideoStreamX() before this function
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001057 // to decide which streams to create.
1058 JsepSessionDescription* CreateRemoteAnswer(
1059 const SessionDescriptionInterface* offer) {
1060 cricket::MediaSessionOptions options;
deadbeefab9b2d12015-10-14 11:33:11 -07001061 GetOptionsForAnswer(NULL, &options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001062 return CreateRemoteAnswer(offer, options, cricket::SEC_REQUIRED);
1063 }
1064
1065 void TestSessionCandidatesWithBundleRtcpMux(bool bundle, bool rtcp_mux) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001066 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001067 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07001068 SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001069
1070 PeerConnectionInterface::RTCOfferAnswerOptions options;
1071 options.use_rtp_mux = bundle;
1072
1073 SessionDescriptionInterface* offer = CreateOffer(options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001074 // SetLocalDescription and SetRemoteDescriptions takes ownership of offer
1075 // and answer.
1076 SetLocalDescriptionWithoutError(offer);
1077
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001078 rtc::scoped_ptr<SessionDescriptionInterface> answer(
henrike@webrtc.org723d6832013-07-12 16:04:50 +00001079 CreateRemoteAnswer(session_->local_description()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001080 std::string sdp;
1081 EXPECT_TRUE(answer->ToString(&sdp));
1082
1083 size_t expected_candidate_num = 2;
1084 if (!rtcp_mux) {
1085 // If rtcp_mux is enabled we should expect 4 candidates - host and srflex
1086 // for rtp and rtcp.
1087 expected_candidate_num = 4;
1088 // Disable rtcp-mux from the answer
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001089 const std::string kRtcpMux = "a=rtcp-mux";
1090 const std::string kXRtcpMux = "a=xrtcp-mux";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001091 rtc::replace_substrs(kRtcpMux.c_str(), kRtcpMux.length(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001092 kXRtcpMux.c_str(), kXRtcpMux.length(),
1093 &sdp);
1094 }
1095
1096 SessionDescriptionInterface* new_answer = CreateSessionDescription(
1097 JsepSessionDescription::kAnswer, sdp, NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001098
1099 // SetRemoteDescription to enable rtcp mux.
henrike@webrtc.org723d6832013-07-12 16:04:50 +00001100 SetRemoteDescriptionWithoutError(new_answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001101 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1102 EXPECT_EQ(expected_candidate_num, observer_.mline_0_candidates_.size());
deadbeefcbecd352015-09-23 11:50:27 -07001103 if (bundle) {
1104 EXPECT_EQ(0, observer_.mline_1_candidates_.size());
1105 } else {
1106 EXPECT_EQ(expected_candidate_num, observer_.mline_1_candidates_.size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001107 }
1108 }
1109 // Tests that we can only send DTMF when the dtmf codec is supported.
1110 void TestCanInsertDtmf(bool can) {
1111 if (can) {
1112 InitWithDtmfCodec();
1113 } else {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001114 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001115 }
deadbeefab9b2d12015-10-14 11:33:11 -07001116 SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001117 CreateAndSetRemoteOfferAndLocalAnswer();
1118 EXPECT_FALSE(session_->CanInsertDtmf(""));
1119 EXPECT_EQ(can, session_->CanInsertDtmf(kAudioTrack1));
1120 }
1121
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001122 // Helper class to configure loopback network and verify Best
1123 // Connection using right IP protocol for TestLoopbackCall
1124 // method. LoopbackNetworkManager applies firewall rules to block
1125 // all ping traffic once ICE completed, and remove them to observe
1126 // ICE reconnected again. This LoopbackNetworkConfiguration struct
1127 // verifies the best connection is using the right IP protocol after
1128 // initial ICE convergences.
1129
1130 class LoopbackNetworkConfiguration {
deadbeefcbecd352015-09-23 11:50:27 -07001131 public:
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001132 LoopbackNetworkConfiguration()
1133 : test_ipv6_network_(false),
1134 test_extra_ipv4_network_(false),
1135 best_connection_after_initial_ice_converged_(1, 0) {}
1136
1137 // Used to track the expected best connection count in each IP protocol.
1138 struct ExpectedBestConnection {
1139 ExpectedBestConnection(int ipv4_count, int ipv6_count)
1140 : ipv4_count_(ipv4_count),
1141 ipv6_count_(ipv6_count) {}
1142
1143 int ipv4_count_;
1144 int ipv6_count_;
1145 };
1146
1147 bool test_ipv6_network_;
1148 bool test_extra_ipv4_network_;
1149 ExpectedBestConnection best_connection_after_initial_ice_converged_;
1150
1151 void VerifyBestConnectionAfterIceConverge(
jbauchac8869e2015-07-03 01:36:14 -07001152 const rtc::scoped_refptr<FakeMetricsObserver> metrics_observer) const {
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001153 Verify(metrics_observer, best_connection_after_initial_ice_converged_);
1154 }
1155
1156 private:
jbauchac8869e2015-07-03 01:36:14 -07001157 void Verify(const rtc::scoped_refptr<FakeMetricsObserver> metrics_observer,
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001158 const ExpectedBestConnection& expected) const {
1159 EXPECT_EQ(
Guo-wei Shieh3d564c12015-08-19 16:51:15 -07001160 metrics_observer->GetEnumCounter(webrtc::kEnumCounterAddressFamily,
1161 webrtc::kBestConnections_IPv4),
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001162 expected.ipv4_count_);
1163 EXPECT_EQ(
Guo-wei Shieh3d564c12015-08-19 16:51:15 -07001164 metrics_observer->GetEnumCounter(webrtc::kEnumCounterAddressFamily,
1165 webrtc::kBestConnections_IPv6),
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001166 expected.ipv6_count_);
Guo-wei Shieh3d564c12015-08-19 16:51:15 -07001167 // This is used in the loopback call so there is only single host to host
1168 // candidate pair.
1169 EXPECT_EQ(metrics_observer->GetEnumCounter(
1170 webrtc::kEnumCounterIceCandidatePairTypeUdp,
1171 webrtc::kIceCandidatePairHostHost),
Guo-wei Shieh3cc834a2015-09-04 15:52:14 -07001172 0);
1173 EXPECT_EQ(metrics_observer->GetEnumCounter(
1174 webrtc::kEnumCounterIceCandidatePairTypeUdp,
1175 webrtc::kIceCandidatePairHostPublicHostPublic),
Guo-wei Shieh3d564c12015-08-19 16:51:15 -07001176 1);
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001177 }
1178 };
1179
1180 class LoopbackNetworkManager {
1181 public:
1182 LoopbackNetworkManager(WebRtcSessionTest* session,
1183 const LoopbackNetworkConfiguration& config)
1184 : config_(config) {
1185 session->AddInterface(
1186 rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
1187 if (config_.test_extra_ipv4_network_) {
1188 session->AddInterface(
1189 rtc::SocketAddress(kClientAddrHost2, kClientAddrPort));
1190 }
1191 if (config_.test_ipv6_network_) {
1192 session->AddInterface(
1193 rtc::SocketAddress(kClientIPv6AddrHost1, kClientAddrPort));
1194 }
1195 }
1196
1197 void ApplyFirewallRules(rtc::FirewallSocketServer* fss) {
1198 fss->AddRule(false, rtc::FP_ANY, rtc::FD_ANY,
1199 rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
1200 if (config_.test_extra_ipv4_network_) {
1201 fss->AddRule(false, rtc::FP_ANY, rtc::FD_ANY,
1202 rtc::SocketAddress(kClientAddrHost2, kClientAddrPort));
1203 }
1204 if (config_.test_ipv6_network_) {
1205 fss->AddRule(false, rtc::FP_ANY, rtc::FD_ANY,
1206 rtc::SocketAddress(kClientIPv6AddrHost1, kClientAddrPort));
1207 }
1208 }
1209
1210 void ClearRules(rtc::FirewallSocketServer* fss) { fss->ClearRules(); }
1211
1212 private:
1213 LoopbackNetworkConfiguration config_;
1214 };
1215
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001216 // The method sets up a call from the session to itself, in a loopback
1217 // arrangement. It also uses a firewall rule to create a temporary
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00001218 // disconnection, and then a permanent disconnection.
1219 // This code is placed in a method so that it can be invoked
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001220 // by multiple tests with different allocators (e.g. with and without BUNDLE).
1221 // While running the call, this method also checks if the session goes through
1222 // the correct sequence of ICE states when a connection is established,
1223 // broken, and re-established.
1224 // The Connection state should go:
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00001225 // New -> Checking -> (Connected) -> Completed -> Disconnected -> Completed
1226 // -> Failed.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001227 // The Gathering state should go: New -> Gathering -> Completed.
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001228
1229 void TestLoopbackCall(const LoopbackNetworkConfiguration& config) {
1230 LoopbackNetworkManager loopback_network_manager(this, config);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001231 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07001232 SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001233 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001234
1235 EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
1236 observer_.ice_gathering_state_);
1237 SetLocalDescriptionWithoutError(offer);
1238 EXPECT_EQ(PeerConnectionInterface::kIceConnectionNew,
1239 observer_.ice_connection_state_);
1240 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceGatheringGathering,
1241 observer_.ice_gathering_state_,
1242 kIceCandidatesTimeout);
1243 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1244 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
1245 observer_.ice_gathering_state_,
1246 kIceCandidatesTimeout);
1247
1248 std::string sdp;
1249 offer->ToString(&sdp);
1250 SessionDescriptionInterface* desc =
jbauchfabe2c92015-07-16 13:43:14 -07001251 webrtc::CreateSessionDescription(
1252 JsepSessionDescription::kAnswer, sdp, nullptr);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001253 ASSERT_TRUE(desc != NULL);
1254 SetRemoteDescriptionWithoutError(desc);
1255
1256 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionChecking,
1257 observer_.ice_connection_state_,
1258 kIceCandidatesTimeout);
mallinath@webrtc.orgd3dc4242014-03-01 00:05:52 +00001259
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00001260 // The ice connection state is "Connected" too briefly to catch in a test.
1261 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001262 observer_.ice_connection_state_,
1263 kIceCandidatesTimeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001264
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001265 config.VerifyBestConnectionAfterIceConverge(metrics_observer_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001266 // Adding firewall rule to block ping requests, which should cause
1267 // transport channel failure.
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001268
1269 loopback_network_manager.ApplyFirewallRules(fss_.get());
1270
1271 LOG(LS_INFO) << "Firewall Rules applied";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001272 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
1273 observer_.ice_connection_state_,
1274 kIceCandidatesTimeout);
1275
jbauchac8869e2015-07-03 01:36:14 -07001276 metrics_observer_->Reset();
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001277
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001278 // Clearing the rules, session should move back to completed state.
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001279 loopback_network_manager.ClearRules(fss_.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001280
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001281 LOG(LS_INFO) << "Firewall Rules cleared";
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00001282 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001283 observer_.ice_connection_state_,
1284 kIceCandidatesTimeout);
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00001285
1286 // Now we block ping requests and wait until the ICE connection transitions
1287 // to the Failed state. This will take at least 30 seconds because it must
1288 // wait for the Port to timeout.
1289 int port_timeout = 30000;
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001290
1291 loopback_network_manager.ApplyFirewallRules(fss_.get());
1292 LOG(LS_INFO) << "Firewall Rules applied again";
jlmiller@webrtc.org804eb462015-02-20 02:20:03 +00001293 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00001294 observer_.ice_connection_state_,
1295 kIceCandidatesTimeout + port_timeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001296 }
1297
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001298 void TestLoopbackCall() {
1299 LoopbackNetworkConfiguration config;
1300 TestLoopbackCall(config);
1301 }
1302
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001303 // Adds CN codecs to FakeMediaEngine and MediaDescriptionFactory.
1304 void AddCNCodecs() {
wu@webrtc.org364f2042013-11-20 21:49:41 +00001305 const cricket::AudioCodec kCNCodec1(102, "CN", 8000, 0, 1, 0);
1306 const cricket::AudioCodec kCNCodec2(103, "CN", 16000, 0, 1, 0);
1307
1308 // Add kCNCodec for dtmf test.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001309 std::vector<cricket::AudioCodec> codecs = media_engine_->audio_codecs();;
1310 codecs.push_back(kCNCodec1);
1311 codecs.push_back(kCNCodec2);
1312 media_engine_->SetAudioCodecs(codecs);
1313 desc_factory_->set_audio_codecs(codecs);
1314 }
1315
1316 bool VerifyNoCNCodecs(const cricket::ContentInfo* content) {
1317 const cricket::ContentDescription* description = content->description;
1318 ASSERT(description != NULL);
1319 const cricket::AudioContentDescription* audio_content_desc =
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00001320 static_cast<const cricket::AudioContentDescription*>(description);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001321 ASSERT(audio_content_desc != NULL);
1322 for (size_t i = 0; i < audio_content_desc->codecs().size(); ++i) {
1323 if (audio_content_desc->codecs()[i].name == "CN")
1324 return false;
1325 }
1326 return true;
1327 }
1328
deadbeefab9b2d12015-10-14 11:33:11 -07001329 void CreateDataChannel() {
deadbeeffc648b62015-10-13 16:42:33 -07001330 webrtc::InternalDataChannelInit dci;
deadbeefab9b2d12015-10-14 11:33:11 -07001331 dci.reliable = session_->data_channel_type() == cricket::DCT_SCTP;
1332 data_channel_ = DataChannel::Create(
1333 session_.get(), session_->data_channel_type(), "datachannel", dci);
1334 }
1335
1336 void SetLocalDescriptionWithDataChannel() {
1337 CreateDataChannel();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001338 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001339 SetLocalDescriptionWithoutError(offer);
1340 }
1341
wu@webrtc.org91053e72013-08-10 07:18:04 +00001342 void VerifyMultipleAsyncCreateDescription(
Henrik Boström87713d02015-08-25 09:53:21 +02001343 RTCCertificateGenerationMethod cert_gen_method,
1344 CreateSessionDescriptionRequest::Type type) {
1345 InitWithDtls(cert_gen_method);
1346 VerifyMultipleAsyncCreateDescriptionAfterInit(true, type);
1347 }
1348
1349 void VerifyMultipleAsyncCreateDescriptionIdentityGenFailure(
1350 CreateSessionDescriptionRequest::Type type) {
1351 InitWithDtlsIdentityGenFail();
1352 VerifyMultipleAsyncCreateDescriptionAfterInit(false, type);
1353 }
1354
1355 void VerifyMultipleAsyncCreateDescriptionAfterInit(
wu@webrtc.org91053e72013-08-10 07:18:04 +00001356 bool success, CreateSessionDescriptionRequest::Type type) {
henrikg91d6ede2015-09-17 00:24:34 -07001357 RTC_CHECK(session_);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001358 SetFactoryDtlsSrtp();
wu@webrtc.org91053e72013-08-10 07:18:04 +00001359 if (type == CreateSessionDescriptionRequest::kAnswer) {
1360 cricket::MediaSessionOptions options;
1361 scoped_ptr<JsepSessionDescription> offer(
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001362 CreateRemoteOffer(options, cricket::SEC_DISABLED));
wu@webrtc.org91053e72013-08-10 07:18:04 +00001363 ASSERT_TRUE(offer.get() != NULL);
1364 SetRemoteDescriptionWithoutError(offer.release());
1365 }
1366
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001367 PeerConnectionInterface::RTCOfferAnswerOptions options;
deadbeefab9b2d12015-10-14 11:33:11 -07001368 cricket::MediaSessionOptions session_options;
wu@webrtc.org91053e72013-08-10 07:18:04 +00001369 const int kNumber = 3;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001370 rtc::scoped_refptr<WebRtcSessionCreateSDPObserverForTest>
wu@webrtc.org91053e72013-08-10 07:18:04 +00001371 observers[kNumber];
1372 for (int i = 0; i < kNumber; ++i) {
1373 observers[i] = new WebRtcSessionCreateSDPObserverForTest();
1374 if (type == CreateSessionDescriptionRequest::kOffer) {
deadbeefab9b2d12015-10-14 11:33:11 -07001375 session_->CreateOffer(observers[i], options, session_options);
wu@webrtc.org91053e72013-08-10 07:18:04 +00001376 } else {
deadbeefab9b2d12015-10-14 11:33:11 -07001377 session_->CreateAnswer(observers[i], nullptr, session_options);
wu@webrtc.org91053e72013-08-10 07:18:04 +00001378 }
1379 }
1380
1381 WebRtcSessionCreateSDPObserverForTest::State expected_state =
1382 success ? WebRtcSessionCreateSDPObserverForTest::kSucceeded :
1383 WebRtcSessionCreateSDPObserverForTest::kFailed;
1384
1385 for (int i = 0; i < kNumber; ++i) {
1386 EXPECT_EQ_WAIT(expected_state, observers[i]->state(), 1000);
1387 if (success) {
1388 EXPECT_TRUE(observers[i]->description() != NULL);
1389 } else {
1390 EXPECT_TRUE(observers[i]->description() == NULL);
1391 }
1392 }
1393 }
1394
mallinath@webrtc.org3d81b1b2014-09-09 14:38:10 +00001395 void ConfigureAllocatorWithTurn() {
1396 cricket::RelayServerConfig relay_server(cricket::RELAY_TURN);
1397 cricket::RelayCredentials credentials(kTurnUsername, kTurnPassword);
1398 relay_server.credentials = credentials;
1399 relay_server.ports.push_back(cricket::ProtocolAddress(
1400 kTurnUdpIntAddr, cricket::PROTO_UDP, false));
1401 allocator_->AddRelay(relay_server);
1402 allocator_->set_step_delay(cricket::kMinimumStepDelay);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001403 allocator_->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP);
mallinath@webrtc.org3d81b1b2014-09-09 14:38:10 +00001404 }
1405
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001406 cricket::FakeMediaEngine* media_engine_;
1407 cricket::FakeDataEngine* data_engine_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001408 rtc::scoped_ptr<cricket::ChannelManager> channel_manager_;
1409 rtc::scoped_ptr<cricket::TransportDescriptionFactory> tdesc_factory_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001410 rtc::scoped_ptr<cricket::MediaSessionDescriptionFactory> desc_factory_;
1411 rtc::scoped_ptr<rtc::PhysicalSocketServer> pss_;
1412 rtc::scoped_ptr<rtc::VirtualSocketServer> vss_;
1413 rtc::scoped_ptr<rtc::FirewallSocketServer> fss_;
1414 rtc::SocketServerScope ss_scope_;
1415 rtc::SocketAddress stun_socket_addr_;
jiayl@webrtc.orgbebc75e2014-09-26 23:01:11 +00001416 rtc::scoped_ptr<cricket::TestStunServer> stun_server_;
buildbot@webrtc.org41451d42014-05-03 05:39:45 +00001417 cricket::TestTurnServer turn_server_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001418 rtc::FakeNetworkManager network_manager_;
1419 rtc::scoped_ptr<cricket::BasicPortAllocator> allocator_;
wu@webrtc.org97077a32013-10-25 21:18:33 +00001420 PeerConnectionFactoryInterface::Options options_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001421 rtc::scoped_ptr<FakeConstraints> constraints_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001422 rtc::scoped_ptr<WebRtcSessionForTest> session_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001423 MockIceObserver observer_;
1424 cricket::FakeVideoMediaChannel* video_channel_;
1425 cricket::FakeVoiceMediaChannel* voice_channel_;
jbauchac8869e2015-07-03 01:36:14 -07001426 rtc::scoped_refptr<FakeMetricsObserver> metrics_observer_;
deadbeefab9b2d12015-10-14 11:33:11 -07001427 // The following flags affect options created for CreateOffer/CreateAnswer.
1428 bool send_stream_1_ = false;
1429 bool send_stream_2_ = false;
1430 bool send_audio_ = false;
1431 bool send_video_ = false;
1432 rtc::scoped_refptr<DataChannel> data_channel_;
1433 // Last values received from data channel creation signal.
1434 std::string last_data_channel_label_;
1435 InternalDataChannelInit last_data_channel_config_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001436};
1437
Henrik Boström87713d02015-08-25 09:53:21 +02001438TEST_P(WebRtcSessionTest, TestInitializeWithDtls) {
1439 InitWithDtls(GetParam());
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001440 // SDES is disabled when DTLS is on.
1441 EXPECT_EQ(cricket::SEC_DISABLED, session_->SdesPolicy());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001442}
1443
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001444TEST_F(WebRtcSessionTest, TestInitializeWithoutDtls) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001445 Init();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001446 // SDES is required if DTLS is off.
1447 EXPECT_EQ(cricket::SEC_REQUIRED, session_->SdesPolicy());
wu@webrtc.org91053e72013-08-10 07:18:04 +00001448}
1449
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001450TEST_F(WebRtcSessionTest, TestSessionCandidates) {
1451 TestSessionCandidatesWithBundleRtcpMux(false, false);
1452}
1453
1454// Below test cases (TestSessionCandidatesWith*) verify the candidates gathered
1455// with rtcp-mux and/or bundle.
1456TEST_F(WebRtcSessionTest, TestSessionCandidatesWithRtcpMux) {
1457 TestSessionCandidatesWithBundleRtcpMux(false, true);
1458}
1459
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001460TEST_F(WebRtcSessionTest, TestSessionCandidatesWithBundleRtcpMux) {
1461 TestSessionCandidatesWithBundleRtcpMux(true, true);
1462}
1463
1464TEST_F(WebRtcSessionTest, TestMultihomeCandidates) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001465 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
1466 AddInterface(rtc::SocketAddress(kClientAddrHost2, kClientAddrPort));
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001467 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07001468 SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001469 InitiateCall();
1470 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1471 EXPECT_EQ(8u, observer_.mline_0_candidates_.size());
1472 EXPECT_EQ(8u, observer_.mline_1_candidates_.size());
1473}
1474
1475TEST_F(WebRtcSessionTest, TestStunError) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001476 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
1477 AddInterface(rtc::SocketAddress(kClientAddrHost2, kClientAddrPort));
wu@webrtc.org364f2042013-11-20 21:49:41 +00001478 fss_->AddRule(false,
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001479 rtc::FP_UDP,
1480 rtc::FD_ANY,
1481 rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001482 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07001483 SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001484 InitiateCall();
wu@webrtc.org364f2042013-11-20 21:49:41 +00001485 // Since kClientAddrHost1 is blocked, not expecting stun candidates for it.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001486 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1487 EXPECT_EQ(6u, observer_.mline_0_candidates_.size());
1488 EXPECT_EQ(6u, observer_.mline_1_candidates_.size());
1489}
1490
mallinath@webrtc.org3d81b1b2014-09-09 14:38:10 +00001491// Test session delivers no candidates gathered when constraint set to "none".
1492TEST_F(WebRtcSessionTest, TestIceTransportsNone) {
1493 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001494 InitWithIceTransport(PeerConnectionInterface::kNone);
deadbeefab9b2d12015-10-14 11:33:11 -07001495 SendAudioVideoStream1();
mallinath@webrtc.org3d81b1b2014-09-09 14:38:10 +00001496 InitiateCall();
1497 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1498 EXPECT_EQ(0u, observer_.mline_0_candidates_.size());
1499 EXPECT_EQ(0u, observer_.mline_1_candidates_.size());
1500}
1501
1502// Test session delivers only relay candidates gathered when constaint set to
1503// "relay".
1504TEST_F(WebRtcSessionTest, TestIceTransportsRelay) {
1505 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
1506 ConfigureAllocatorWithTurn();
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001507 InitWithIceTransport(PeerConnectionInterface::kRelay);
deadbeefab9b2d12015-10-14 11:33:11 -07001508 SendAudioVideoStream1();
mallinath@webrtc.org3d81b1b2014-09-09 14:38:10 +00001509 InitiateCall();
1510 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1511 EXPECT_EQ(2u, observer_.mline_0_candidates_.size());
1512 EXPECT_EQ(2u, observer_.mline_1_candidates_.size());
1513 for (size_t i = 0; i < observer_.mline_0_candidates_.size(); ++i) {
1514 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
1515 observer_.mline_0_candidates_[i].type());
1516 }
1517 for (size_t i = 0; i < observer_.mline_1_candidates_.size(); ++i) {
1518 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
1519 observer_.mline_1_candidates_[i].type());
1520 }
1521}
1522
1523// Test session delivers all candidates gathered when constaint set to "all".
1524TEST_F(WebRtcSessionTest, TestIceTransportsAll) {
1525 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001526 InitWithIceTransport(PeerConnectionInterface::kAll);
deadbeefab9b2d12015-10-14 11:33:11 -07001527 SendAudioVideoStream1();
mallinath@webrtc.org3d81b1b2014-09-09 14:38:10 +00001528 InitiateCall();
1529 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1530 // Host + STUN. By default allocator is disabled to gather relay candidates.
1531 EXPECT_EQ(4u, observer_.mline_0_candidates_.size());
1532 EXPECT_EQ(4u, observer_.mline_1_candidates_.size());
1533}
1534
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001535TEST_F(WebRtcSessionTest, SetSdpFailedOnInvalidSdp) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001536 Init();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001537 SessionDescriptionInterface* offer = NULL;
1538 // Since |offer| is NULL, there's no way to tell if it's an offer or answer.
1539 std::string unknown_action;
1540 SetLocalDescriptionExpectError(unknown_action, kInvalidSdp, offer);
1541 SetRemoteDescriptionExpectError(unknown_action, kInvalidSdp, offer);
1542}
1543
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001544// Test creating offers and receive answers and make sure the
1545// media engine creates the expected send and receive streams.
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001546TEST_F(WebRtcSessionTest, TestCreateSdesOfferReceiveSdesAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001547 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07001548 SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001549 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001550 const std::string session_id_orig = offer->session_id();
1551 const std::string session_version_orig = offer->session_version();
1552 SetLocalDescriptionWithoutError(offer);
1553
deadbeefab9b2d12015-10-14 11:33:11 -07001554 SendAudioVideoStream2();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001555 SessionDescriptionInterface* answer =
1556 CreateRemoteAnswer(session_->local_description());
1557 SetRemoteDescriptionWithoutError(answer);
1558
1559 video_channel_ = media_engine_->GetVideoChannel(0);
1560 voice_channel_ = media_engine_->GetVoiceChannel(0);
1561
1562 ASSERT_EQ(1u, video_channel_->recv_streams().size());
1563 EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].id);
1564
1565 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
1566 EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].id);
1567
1568 ASSERT_EQ(1u, video_channel_->send_streams().size());
1569 EXPECT_TRUE(kVideoTrack1 == video_channel_->send_streams()[0].id);
1570 ASSERT_EQ(1u, voice_channel_->send_streams().size());
1571 EXPECT_TRUE(kAudioTrack1 == voice_channel_->send_streams()[0].id);
1572
1573 // Create new offer without send streams.
deadbeefab9b2d12015-10-14 11:33:11 -07001574 SendNothing();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001575 offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001576
1577 // Verify the session id is the same and the session version is
1578 // increased.
1579 EXPECT_EQ(session_id_orig, offer->session_id());
Peter Boström0c4e06b2015-10-07 12:23:21 +02001580 EXPECT_LT(rtc::FromString<uint64_t>(session_version_orig),
1581 rtc::FromString<uint64_t>(offer->session_version()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001582
1583 SetLocalDescriptionWithoutError(offer);
jiayl@webrtc.org7d4891d2014-09-09 21:43:15 +00001584 EXPECT_EQ(0u, video_channel_->send_streams().size());
1585 EXPECT_EQ(0u, voice_channel_->send_streams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001586
deadbeefab9b2d12015-10-14 11:33:11 -07001587 SendAudioVideoStream2();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001588 answer = CreateRemoteAnswer(session_->local_description());
1589 SetRemoteDescriptionWithoutError(answer);
1590
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001591 // Make sure the receive streams have not changed.
1592 ASSERT_EQ(1u, video_channel_->recv_streams().size());
1593 EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].id);
1594 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
1595 EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].id);
1596}
1597
1598// Test receiving offers and creating answers and make sure the
1599// media engine creates the expected send and receive streams.
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001600TEST_F(WebRtcSessionTest, TestReceiveSdesOfferCreateSdesAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001601 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07001602 SendAudioVideoStream2();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001603 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001604 VerifyCryptoParams(offer->description());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001605 SetRemoteDescriptionWithoutError(offer);
1606
deadbeefab9b2d12015-10-14 11:33:11 -07001607 SendAudioVideoStream1();
wu@webrtc.org91053e72013-08-10 07:18:04 +00001608 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001609 VerifyCryptoParams(answer->description());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001610 SetLocalDescriptionWithoutError(answer);
1611
1612 const std::string session_id_orig = answer->session_id();
1613 const std::string session_version_orig = answer->session_version();
1614
1615 video_channel_ = media_engine_->GetVideoChannel(0);
1616 voice_channel_ = media_engine_->GetVoiceChannel(0);
1617
1618 ASSERT_EQ(1u, video_channel_->recv_streams().size());
1619 EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].id);
1620
1621 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
1622 EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].id);
1623
1624 ASSERT_EQ(1u, video_channel_->send_streams().size());
1625 EXPECT_TRUE(kVideoTrack1 == video_channel_->send_streams()[0].id);
1626 ASSERT_EQ(1u, voice_channel_->send_streams().size());
1627 EXPECT_TRUE(kAudioTrack1 == voice_channel_->send_streams()[0].id);
1628
deadbeefab9b2d12015-10-14 11:33:11 -07001629 SendAudioVideoStream1And2();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001630 offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001631 SetRemoteDescriptionWithoutError(offer);
1632
1633 // Answer by turning off all send streams.
deadbeefab9b2d12015-10-14 11:33:11 -07001634 SendNothing();
wu@webrtc.org91053e72013-08-10 07:18:04 +00001635 answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001636
1637 // Verify the session id is the same and the session version is
1638 // increased.
1639 EXPECT_EQ(session_id_orig, answer->session_id());
Peter Boström0c4e06b2015-10-07 12:23:21 +02001640 EXPECT_LT(rtc::FromString<uint64_t>(session_version_orig),
1641 rtc::FromString<uint64_t>(answer->session_version()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001642 SetLocalDescriptionWithoutError(answer);
1643
1644 ASSERT_EQ(2u, video_channel_->recv_streams().size());
1645 EXPECT_TRUE(kVideoTrack1 == video_channel_->recv_streams()[0].id);
1646 EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[1].id);
1647 ASSERT_EQ(2u, voice_channel_->recv_streams().size());
1648 EXPECT_TRUE(kAudioTrack1 == voice_channel_->recv_streams()[0].id);
1649 EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[1].id);
1650
1651 // Make sure we have no send streams.
1652 EXPECT_EQ(0u, video_channel_->send_streams().size());
1653 EXPECT_EQ(0u, voice_channel_->send_streams().size());
1654}
1655
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001656TEST_F(WebRtcSessionTest, SetLocalSdpFailedOnCreateChannel) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001657 Init();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001658 media_engine_->set_fail_create_channel(true);
1659
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001660 SessionDescriptionInterface* offer = CreateOffer();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001661 ASSERT_TRUE(offer != NULL);
1662 // SetRemoteDescription and SetLocalDescription will take the ownership of
1663 // the offer.
1664 SetRemoteDescriptionOfferExpectError(kCreateChannelFailed, offer);
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001665 offer = CreateOffer();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001666 ASSERT_TRUE(offer != NULL);
1667 SetLocalDescriptionOfferExpectError(kCreateChannelFailed, offer);
1668}
1669
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001670//
1671// Tests for creating/setting SDP under different SDES/DTLS polices:
1672//
1673// --DTLS off and SDES on
1674// TestCreateSdesOfferReceiveSdesAnswer/TestReceiveSdesOfferCreateSdesAnswer:
1675// set local/remote offer/answer with crypto --> success
1676// TestSetNonSdesOfferWhenSdesOn: set local/remote offer without crypto --->
1677// failure
1678// TestSetLocalNonSdesAnswerWhenSdesOn: set local answer without crypto -->
1679// failure
1680// TestSetRemoteNonSdesAnswerWhenSdesOn: set remote answer without crypto -->
1681// failure
1682//
1683// --DTLS on and SDES off
1684// TestCreateDtlsOfferReceiveDtlsAnswer/TestReceiveDtlsOfferCreateDtlsAnswer:
1685// set local/remote offer/answer with DTLS fingerprint --> success
1686// TestReceiveNonDtlsOfferWhenDtlsOn: set local/remote offer without DTLS
1687// fingerprint --> failure
1688// TestSetLocalNonDtlsAnswerWhenDtlsOn: set local answer without fingerprint
1689// --> failure
1690// TestSetRemoteNonDtlsAnswerWhenDtlsOn: set remote answer without fingerprint
1691// --> failure
1692//
1693// --Encryption disabled: DTLS off and SDES off
1694// TestCreateOfferReceiveAnswerWithoutEncryption: set local offer and remote
1695// answer without SDES or DTLS --> success
1696// TestCreateAnswerReceiveOfferWithoutEncryption: set remote offer and local
1697// answer without SDES or DTLS --> success
1698//
1699
1700// Test that we return a failure when applying a remote/local offer that doesn't
1701// have cryptos enabled when DTLS is off.
1702TEST_F(WebRtcSessionTest, TestSetNonSdesOfferWhenSdesOn) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001703 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001704 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001705 options.recv_video = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001706 JsepSessionDescription* offer = CreateRemoteOffer(
1707 options, cricket::SEC_DISABLED);
1708 ASSERT_TRUE(offer != NULL);
1709 VerifyNoCryptoParams(offer->description(), false);
1710 // SetRemoteDescription and SetLocalDescription will take the ownership of
1711 // the offer.
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001712 SetRemoteDescriptionOfferExpectError(kSdpWithoutSdesCrypto, offer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001713 offer = CreateRemoteOffer(options, cricket::SEC_DISABLED);
1714 ASSERT_TRUE(offer != NULL);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001715 SetLocalDescriptionOfferExpectError(kSdpWithoutSdesCrypto, offer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001716}
1717
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001718// Test that we return a failure when applying a local answer that doesn't have
1719// cryptos enabled when DTLS is off.
1720TEST_F(WebRtcSessionTest, TestSetLocalNonSdesAnswerWhenSdesOn) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001721 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001722 SessionDescriptionInterface* offer = NULL;
1723 SessionDescriptionInterface* answer = NULL;
1724 CreateCryptoOfferAndNonCryptoAnswer(&offer, &answer);
1725 // SetRemoteDescription and SetLocalDescription will take the ownership of
1726 // the offer.
1727 SetRemoteDescriptionWithoutError(offer);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001728 SetLocalDescriptionAnswerExpectError(kSdpWithoutSdesCrypto, answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001729}
1730
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001731// Test we will return fail when apply an remote answer that doesn't have
1732// crypto enabled when DTLS is off.
1733TEST_F(WebRtcSessionTest, TestSetRemoteNonSdesAnswerWhenSdesOn) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001734 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001735 SessionDescriptionInterface* offer = NULL;
1736 SessionDescriptionInterface* answer = NULL;
1737 CreateCryptoOfferAndNonCryptoAnswer(&offer, &answer);
1738 // SetRemoteDescription and SetLocalDescription will take the ownership of
1739 // the offer.
1740 SetLocalDescriptionWithoutError(offer);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001741 SetRemoteDescriptionAnswerExpectError(kSdpWithoutSdesCrypto, answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001742}
1743
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001744// Test that we accept an offer with a DTLS fingerprint when DTLS is on
1745// and that we return an answer with a DTLS fingerprint.
Henrik Boström87713d02015-08-25 09:53:21 +02001746TEST_P(WebRtcSessionTest, TestReceiveDtlsOfferCreateDtlsAnswer) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001747 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
deadbeefab9b2d12015-10-14 11:33:11 -07001748 SendAudioVideoStream1();
Henrik Boström87713d02015-08-25 09:53:21 +02001749 InitWithDtls(GetParam());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001750 SetFactoryDtlsSrtp();
1751 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001752 options.recv_video = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001753 JsepSessionDescription* offer =
1754 CreateRemoteOffer(options, cricket::SEC_DISABLED);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001755 ASSERT_TRUE(offer != NULL);
1756 VerifyFingerprintStatus(offer->description(), true);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001757 VerifyNoCryptoParams(offer->description(), true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001758
1759 // SetRemoteDescription will take the ownership of the offer.
1760 SetRemoteDescriptionWithoutError(offer);
1761
1762 // Verify that we get a crypto fingerprint in the answer.
wu@webrtc.org91053e72013-08-10 07:18:04 +00001763 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001764 ASSERT_TRUE(answer != NULL);
1765 VerifyFingerprintStatus(answer->description(), true);
1766 // Check that we don't have an a=crypto line in the answer.
1767 VerifyNoCryptoParams(answer->description(), true);
1768
1769 // Now set the local description, which should work, even without a=crypto.
1770 SetLocalDescriptionWithoutError(answer);
1771}
1772
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001773// Test that we set a local offer with a DTLS fingerprint when DTLS is on
1774// and then we accept a remote answer with a DTLS fingerprint successfully.
Henrik Boström87713d02015-08-25 09:53:21 +02001775TEST_P(WebRtcSessionTest, TestCreateDtlsOfferReceiveDtlsAnswer) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001776 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
deadbeefab9b2d12015-10-14 11:33:11 -07001777 SendAudioVideoStream1();
Henrik Boström87713d02015-08-25 09:53:21 +02001778 InitWithDtls(GetParam());
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001779 SetFactoryDtlsSrtp();
1780
1781 // Verify that we get a crypto fingerprint in the answer.
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001782 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001783 ASSERT_TRUE(offer != NULL);
1784 VerifyFingerprintStatus(offer->description(), true);
1785 // Check that we don't have an a=crypto line in the offer.
1786 VerifyNoCryptoParams(offer->description(), true);
1787
1788 // Now set the local description, which should work, even without a=crypto.
1789 SetLocalDescriptionWithoutError(offer);
1790
1791 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001792 options.recv_video = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001793 JsepSessionDescription* answer =
1794 CreateRemoteAnswer(offer, options, cricket::SEC_DISABLED);
1795 ASSERT_TRUE(answer != NULL);
1796 VerifyFingerprintStatus(answer->description(), true);
1797 VerifyNoCryptoParams(answer->description(), true);
1798
1799 // SetRemoteDescription will take the ownership of the answer.
1800 SetRemoteDescriptionWithoutError(answer);
1801}
1802
1803// Test that if we support DTLS and the other side didn't offer a fingerprint,
1804// we will fail to set the remote description.
Henrik Boström87713d02015-08-25 09:53:21 +02001805TEST_P(WebRtcSessionTest, TestReceiveNonDtlsOfferWhenDtlsOn) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001806 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
Henrik Boström87713d02015-08-25 09:53:21 +02001807 InitWithDtls(GetParam());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001808 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001809 options.recv_video = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001810 options.bundle_enabled = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001811 JsepSessionDescription* offer = CreateRemoteOffer(
1812 options, cricket::SEC_REQUIRED);
1813 ASSERT_TRUE(offer != NULL);
1814 VerifyFingerprintStatus(offer->description(), false);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001815 VerifyCryptoParams(offer->description());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001816
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001817 // SetRemoteDescription will take the ownership of the offer.
1818 SetRemoteDescriptionOfferExpectError(
1819 kSdpWithoutDtlsFingerprint, offer);
1820
1821 offer = CreateRemoteOffer(options, cricket::SEC_REQUIRED);
1822 // SetLocalDescription will take the ownership of the offer.
1823 SetLocalDescriptionOfferExpectError(
1824 kSdpWithoutDtlsFingerprint, offer);
1825}
1826
1827// Test that we return a failure when applying a local answer that doesn't have
1828// a DTLS fingerprint when DTLS is required.
Henrik Boström87713d02015-08-25 09:53:21 +02001829TEST_P(WebRtcSessionTest, TestSetLocalNonDtlsAnswerWhenDtlsOn) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001830 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
Henrik Boström87713d02015-08-25 09:53:21 +02001831 InitWithDtls(GetParam());
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001832 SessionDescriptionInterface* offer = NULL;
1833 SessionDescriptionInterface* answer = NULL;
1834 CreateDtlsOfferAndNonDtlsAnswer(&offer, &answer);
1835
1836 // SetRemoteDescription and SetLocalDescription will take the ownership of
1837 // the offer and answer.
1838 SetRemoteDescriptionWithoutError(offer);
1839 SetLocalDescriptionAnswerExpectError(
1840 kSdpWithoutDtlsFingerprint, answer);
1841}
1842
1843// Test that we return a failure when applying a remote answer that doesn't have
1844// a DTLS fingerprint when DTLS is required.
Henrik Boström87713d02015-08-25 09:53:21 +02001845TEST_P(WebRtcSessionTest, TestSetRemoteNonDtlsAnswerWhenDtlsOn) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001846 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
Henrik Boström87713d02015-08-25 09:53:21 +02001847 InitWithDtls(GetParam());
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001848 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001849 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001850 options.recv_video = true;
deadbeefcbecd352015-09-23 11:50:27 -07001851 rtc::scoped_ptr<SessionDescriptionInterface> temp_offer(
1852 CreateRemoteOffer(options, cricket::SEC_ENABLED));
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001853 JsepSessionDescription* answer =
deadbeefcbecd352015-09-23 11:50:27 -07001854 CreateRemoteAnswer(temp_offer.get(), options, cricket::SEC_ENABLED);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001855
1856 // SetRemoteDescription and SetLocalDescription will take the ownership of
1857 // the offer and answer.
1858 SetLocalDescriptionWithoutError(offer);
1859 SetRemoteDescriptionAnswerExpectError(
1860 kSdpWithoutDtlsFingerprint, answer);
1861}
1862
1863// Test that we create a local offer without SDES or DTLS and accept a remote
1864// answer without SDES or DTLS when encryption is disabled.
Henrik Boström87713d02015-08-25 09:53:21 +02001865TEST_P(WebRtcSessionTest, TestCreateOfferReceiveAnswerWithoutEncryption) {
deadbeefab9b2d12015-10-14 11:33:11 -07001866 SendAudioVideoStream1();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001867 options_.disable_encryption = true;
Henrik Boström87713d02015-08-25 09:53:21 +02001868 InitWithDtls(GetParam());
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001869
1870 // Verify that we get a crypto fingerprint in the answer.
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001871 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001872 ASSERT_TRUE(offer != NULL);
1873 VerifyFingerprintStatus(offer->description(), false);
1874 // Check that we don't have an a=crypto line in the offer.
1875 VerifyNoCryptoParams(offer->description(), false);
1876
1877 // Now set the local description, which should work, even without a=crypto.
1878 SetLocalDescriptionWithoutError(offer);
1879
1880 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001881 options.recv_video = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001882 JsepSessionDescription* answer =
1883 CreateRemoteAnswer(offer, options, cricket::SEC_DISABLED);
1884 ASSERT_TRUE(answer != NULL);
1885 VerifyFingerprintStatus(answer->description(), false);
1886 VerifyNoCryptoParams(answer->description(), false);
1887
1888 // SetRemoteDescription will take the ownership of the answer.
1889 SetRemoteDescriptionWithoutError(answer);
1890}
1891
1892// Test that we create a local answer without SDES or DTLS and accept a remote
1893// offer without SDES or DTLS when encryption is disabled.
Henrik Boström87713d02015-08-25 09:53:21 +02001894TEST_P(WebRtcSessionTest, TestCreateAnswerReceiveOfferWithoutEncryption) {
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001895 options_.disable_encryption = true;
Henrik Boström87713d02015-08-25 09:53:21 +02001896 InitWithDtls(GetParam());
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001897
1898 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001899 options.recv_video = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001900 JsepSessionDescription* offer =
1901 CreateRemoteOffer(options, cricket::SEC_DISABLED);
1902 ASSERT_TRUE(offer != NULL);
1903 VerifyFingerprintStatus(offer->description(), false);
1904 VerifyNoCryptoParams(offer->description(), false);
1905
1906 // SetRemoteDescription will take the ownership of the offer.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001907 SetRemoteDescriptionWithoutError(offer);
1908
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001909 // Verify that we get a crypto fingerprint in the answer.
wu@webrtc.org91053e72013-08-10 07:18:04 +00001910 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001911 ASSERT_TRUE(answer != NULL);
1912 VerifyFingerprintStatus(answer->description(), false);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001913 // Check that we don't have an a=crypto line in the answer.
1914 VerifyNoCryptoParams(answer->description(), false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001915
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001916 // Now set the local description, which should work, even without a=crypto.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001917 SetLocalDescriptionWithoutError(answer);
1918}
1919
1920TEST_F(WebRtcSessionTest, TestSetLocalOfferTwice) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001921 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07001922 SendNothing();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001923 // SetLocalDescription take ownership of offer.
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001924 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001925 SetLocalDescriptionWithoutError(offer);
1926
1927 // SetLocalDescription take ownership of offer.
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001928 SessionDescriptionInterface* offer2 = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001929 SetLocalDescriptionWithoutError(offer2);
1930}
1931
1932TEST_F(WebRtcSessionTest, TestSetRemoteOfferTwice) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001933 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07001934 SendNothing();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001935 // SetLocalDescription take ownership of offer.
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001936 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001937 SetRemoteDescriptionWithoutError(offer);
1938
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001939 SessionDescriptionInterface* offer2 = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001940 SetRemoteDescriptionWithoutError(offer2);
1941}
1942
1943TEST_F(WebRtcSessionTest, TestSetLocalAndRemoteOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001944 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07001945 SendNothing();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001946 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001947 SetLocalDescriptionWithoutError(offer);
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001948 offer = CreateOffer();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001949 SetRemoteDescriptionOfferExpectError(
1950 "Called in wrong state: STATE_SENTINITIATE", offer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001951}
1952
1953TEST_F(WebRtcSessionTest, TestSetRemoteAndLocalOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001954 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07001955 SendNothing();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001956 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001957 SetRemoteDescriptionWithoutError(offer);
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001958 offer = CreateOffer();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001959 SetLocalDescriptionOfferExpectError(
1960 "Called in wrong state: STATE_RECEIVEDINITIATE", offer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001961}
1962
1963TEST_F(WebRtcSessionTest, TestSetLocalPrAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001964 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07001965 SendNothing();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001966 SessionDescriptionInterface* offer = CreateRemoteOffer();
1967 SetRemoteDescriptionExpectState(offer, BaseSession::STATE_RECEIVEDINITIATE);
1968
1969 JsepSessionDescription* pranswer = static_cast<JsepSessionDescription*>(
wu@webrtc.org91053e72013-08-10 07:18:04 +00001970 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001971 pranswer->set_type(SessionDescriptionInterface::kPrAnswer);
1972 SetLocalDescriptionExpectState(pranswer, BaseSession::STATE_SENTPRACCEPT);
1973
deadbeefab9b2d12015-10-14 11:33:11 -07001974 SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001975 JsepSessionDescription* pranswer2 = static_cast<JsepSessionDescription*>(
wu@webrtc.org91053e72013-08-10 07:18:04 +00001976 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001977 pranswer2->set_type(SessionDescriptionInterface::kPrAnswer);
1978
1979 SetLocalDescriptionExpectState(pranswer2, BaseSession::STATE_SENTPRACCEPT);
1980
deadbeefab9b2d12015-10-14 11:33:11 -07001981 SendAudioVideoStream2();
wu@webrtc.org91053e72013-08-10 07:18:04 +00001982 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001983 SetLocalDescriptionExpectState(answer, BaseSession::STATE_SENTACCEPT);
1984}
1985
1986TEST_F(WebRtcSessionTest, TestSetRemotePrAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001987 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07001988 SendNothing();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001989 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001990 SetLocalDescriptionExpectState(offer, BaseSession::STATE_SENTINITIATE);
1991
1992 JsepSessionDescription* pranswer =
1993 CreateRemoteAnswer(session_->local_description());
1994 pranswer->set_type(SessionDescriptionInterface::kPrAnswer);
1995
1996 SetRemoteDescriptionExpectState(pranswer,
1997 BaseSession::STATE_RECEIVEDPRACCEPT);
1998
deadbeefab9b2d12015-10-14 11:33:11 -07001999 SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002000 JsepSessionDescription* pranswer2 =
2001 CreateRemoteAnswer(session_->local_description());
2002 pranswer2->set_type(SessionDescriptionInterface::kPrAnswer);
2003
2004 SetRemoteDescriptionExpectState(pranswer2,
2005 BaseSession::STATE_RECEIVEDPRACCEPT);
2006
deadbeefab9b2d12015-10-14 11:33:11 -07002007 SendAudioVideoStream2();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002008 SessionDescriptionInterface* answer =
2009 CreateRemoteAnswer(session_->local_description());
2010 SetRemoteDescriptionExpectState(answer, BaseSession::STATE_RECEIVEDACCEPT);
2011}
2012
2013TEST_F(WebRtcSessionTest, TestSetLocalAnswerWithoutOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002014 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07002015 SendNothing();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002016 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
2017
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002018 SessionDescriptionInterface* answer =
2019 CreateRemoteAnswer(offer.get());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00002020 SetLocalDescriptionAnswerExpectError("Called in wrong state: STATE_INIT",
2021 answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002022}
2023
2024TEST_F(WebRtcSessionTest, TestSetRemoteAnswerWithoutOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002025 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07002026 SendNothing();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002027 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
2028
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002029 SessionDescriptionInterface* answer =
2030 CreateRemoteAnswer(offer.get());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00002031 SetRemoteDescriptionAnswerExpectError(
2032 "Called in wrong state: STATE_INIT", answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002033}
2034
2035TEST_F(WebRtcSessionTest, TestAddRemoteCandidate) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002036 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07002037 SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002038
2039 cricket::Candidate candidate;
2040 candidate.set_component(1);
2041 JsepIceCandidate ice_candidate1(kMediaContentName0, 0, candidate);
2042
2043 // Fail since we have not set a offer description.
2044 EXPECT_FALSE(session_->ProcessIceMessage(&ice_candidate1));
2045
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002046 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002047 SetLocalDescriptionWithoutError(offer);
2048 // Candidate should be allowed to add before remote description.
2049 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate1));
2050 candidate.set_component(2);
2051 JsepIceCandidate ice_candidate2(kMediaContentName0, 0, candidate);
2052 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate2));
2053
2054 SessionDescriptionInterface* answer = CreateRemoteAnswer(
2055 session_->local_description());
2056 SetRemoteDescriptionWithoutError(answer);
2057
2058 // Verifying the candidates are copied properly from internal vector.
2059 const SessionDescriptionInterface* remote_desc =
2060 session_->remote_description();
2061 ASSERT_TRUE(remote_desc != NULL);
2062 ASSERT_EQ(2u, remote_desc->number_of_mediasections());
2063 const IceCandidateCollection* candidates =
2064 remote_desc->candidates(kMediaContentIndex0);
2065 ASSERT_EQ(2u, candidates->count());
2066 EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
2067 EXPECT_EQ(kMediaContentName0, candidates->at(0)->sdp_mid());
2068 EXPECT_EQ(1, candidates->at(0)->candidate().component());
2069 EXPECT_EQ(2, candidates->at(1)->candidate().component());
2070
mallinath@webrtc.org67ee6b92014-02-03 16:57:16 +00002071 // |ice_candidate3| is identical to |ice_candidate2|. It can be added
2072 // successfully, but the total count of candidates will not increase.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002073 candidate.set_component(2);
2074 JsepIceCandidate ice_candidate3(kMediaContentName0, 0, candidate);
2075 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate3));
mallinath@webrtc.org67ee6b92014-02-03 16:57:16 +00002076 ASSERT_EQ(2u, candidates->count());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002077
2078 JsepIceCandidate bad_ice_candidate("bad content name", 99, candidate);
2079 EXPECT_FALSE(session_->ProcessIceMessage(&bad_ice_candidate));
2080}
2081
2082// Test that a remote candidate is added to the remote session description and
2083// that it is retained if the remote session description is changed.
2084TEST_F(WebRtcSessionTest, TestRemoteCandidatesAddedToSessionDescription) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002085 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002086 cricket::Candidate candidate1;
2087 candidate1.set_component(1);
2088 JsepIceCandidate ice_candidate1(kMediaContentName0, kMediaContentIndex0,
2089 candidate1);
deadbeefab9b2d12015-10-14 11:33:11 -07002090 SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002091 CreateAndSetRemoteOfferAndLocalAnswer();
2092
2093 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate1));
2094 const SessionDescriptionInterface* remote_desc =
2095 session_->remote_description();
2096 ASSERT_TRUE(remote_desc != NULL);
2097 ASSERT_EQ(2u, remote_desc->number_of_mediasections());
2098 const IceCandidateCollection* candidates =
2099 remote_desc->candidates(kMediaContentIndex0);
2100 ASSERT_EQ(1u, candidates->count());
2101 EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
2102
2103 // Update the RemoteSessionDescription with a new session description and
2104 // a candidate and check that the new remote session description contains both
2105 // candidates.
2106 SessionDescriptionInterface* offer = CreateRemoteOffer();
2107 cricket::Candidate candidate2;
2108 JsepIceCandidate ice_candidate2(kMediaContentName0, kMediaContentIndex0,
2109 candidate2);
2110 EXPECT_TRUE(offer->AddCandidate(&ice_candidate2));
2111 SetRemoteDescriptionWithoutError(offer);
2112
2113 remote_desc = session_->remote_description();
2114 ASSERT_TRUE(remote_desc != NULL);
2115 ASSERT_EQ(2u, remote_desc->number_of_mediasections());
2116 candidates = remote_desc->candidates(kMediaContentIndex0);
2117 ASSERT_EQ(2u, candidates->count());
2118 EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
2119 // Username and password have be updated with the TransportInfo of the
2120 // SessionDescription, won't be equal to the original one.
2121 candidate2.set_username(candidates->at(0)->candidate().username());
2122 candidate2.set_password(candidates->at(0)->candidate().password());
2123 EXPECT_TRUE(candidate2.IsEquivalent(candidates->at(0)->candidate()));
2124 EXPECT_EQ(kMediaContentIndex0, candidates->at(1)->sdp_mline_index());
2125 // No need to verify the username and password.
2126 candidate1.set_username(candidates->at(1)->candidate().username());
2127 candidate1.set_password(candidates->at(1)->candidate().password());
2128 EXPECT_TRUE(candidate1.IsEquivalent(candidates->at(1)->candidate()));
2129
2130 // Test that the candidate is ignored if we can add the same candidate again.
2131 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate2));
2132}
2133
2134// Test that local candidates are added to the local session description and
2135// that they are retained if the local session description is changed.
2136TEST_F(WebRtcSessionTest, TestLocalCandidatesAddedToSessionDescription) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002137 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002138 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07002139 SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002140 CreateAndSetRemoteOfferAndLocalAnswer();
2141
2142 const SessionDescriptionInterface* local_desc = session_->local_description();
2143 const IceCandidateCollection* candidates =
2144 local_desc->candidates(kMediaContentIndex0);
2145 ASSERT_TRUE(candidates != NULL);
2146 EXPECT_EQ(0u, candidates->count());
2147
2148 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
2149
2150 local_desc = session_->local_description();
2151 candidates = local_desc->candidates(kMediaContentIndex0);
2152 ASSERT_TRUE(candidates != NULL);
2153 EXPECT_LT(0u, candidates->count());
2154 candidates = local_desc->candidates(1);
2155 ASSERT_TRUE(candidates != NULL);
deadbeefcbecd352015-09-23 11:50:27 -07002156 EXPECT_EQ(0u, candidates->count());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002157
2158 // Update the session descriptions.
deadbeefab9b2d12015-10-14 11:33:11 -07002159 SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002160 CreateAndSetRemoteOfferAndLocalAnswer();
2161
2162 local_desc = session_->local_description();
2163 candidates = local_desc->candidates(kMediaContentIndex0);
2164 ASSERT_TRUE(candidates != NULL);
2165 EXPECT_LT(0u, candidates->count());
2166 candidates = local_desc->candidates(1);
2167 ASSERT_TRUE(candidates != NULL);
deadbeefcbecd352015-09-23 11:50:27 -07002168 EXPECT_EQ(0u, candidates->count());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002169}
2170
2171// Test that we can set a remote session description with remote candidates.
2172TEST_F(WebRtcSessionTest, TestSetRemoteSessionDescriptionWithCandidates) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002173 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002174
2175 cricket::Candidate candidate1;
2176 candidate1.set_component(1);
2177 JsepIceCandidate ice_candidate(kMediaContentName0, kMediaContentIndex0,
2178 candidate1);
deadbeefab9b2d12015-10-14 11:33:11 -07002179 SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002180 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002181
2182 EXPECT_TRUE(offer->AddCandidate(&ice_candidate));
2183 SetRemoteDescriptionWithoutError(offer);
2184
2185 const SessionDescriptionInterface* remote_desc =
2186 session_->remote_description();
2187 ASSERT_TRUE(remote_desc != NULL);
2188 ASSERT_EQ(2u, remote_desc->number_of_mediasections());
2189 const IceCandidateCollection* candidates =
2190 remote_desc->candidates(kMediaContentIndex0);
2191 ASSERT_EQ(1u, candidates->count());
2192 EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
2193
wu@webrtc.org91053e72013-08-10 07:18:04 +00002194 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002195 SetLocalDescriptionWithoutError(answer);
2196}
2197
2198// Test that offers and answers contains ice candidates when Ice candidates have
2199// been gathered.
2200TEST_F(WebRtcSessionTest, TestSetLocalAndRemoteDescriptionWithCandidates) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002201 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002202 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07002203 SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002204 // Ice is started but candidates are not provided until SetLocalDescription
2205 // is called.
2206 EXPECT_EQ(0u, observer_.mline_0_candidates_.size());
2207 EXPECT_EQ(0u, observer_.mline_1_candidates_.size());
2208 CreateAndSetRemoteOfferAndLocalAnswer();
2209 // Wait until at least one local candidate has been collected.
2210 EXPECT_TRUE_WAIT(0u < observer_.mline_0_candidates_.size(),
2211 kIceCandidatesTimeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002212
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002213 rtc::scoped_ptr<SessionDescriptionInterface> local_offer(CreateOffer());
2214
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002215 ASSERT_TRUE(local_offer->candidates(kMediaContentIndex0) != NULL);
2216 EXPECT_LT(0u, local_offer->candidates(kMediaContentIndex0)->count());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002217
2218 SessionDescriptionInterface* remote_offer(CreateRemoteOffer());
2219 SetRemoteDescriptionWithoutError(remote_offer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00002220 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002221 ASSERT_TRUE(answer->candidates(kMediaContentIndex0) != NULL);
2222 EXPECT_LT(0u, answer->candidates(kMediaContentIndex0)->count());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002223 SetLocalDescriptionWithoutError(answer);
2224}
2225
2226// Verifies TransportProxy and media channels are created with content names
2227// present in the SessionDescription.
2228TEST_F(WebRtcSessionTest, TestChannelCreationsWithContentNames) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002229 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07002230 SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002231 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002232
2233 // CreateOffer creates session description with the content names "audio" and
2234 // "video". Goal is to modify these content names and verify transport channel
2235 // proxy in the BaseSession, as proxies are created with the content names
2236 // present in SDP.
2237 std::string sdp;
2238 EXPECT_TRUE(offer->ToString(&sdp));
2239 const std::string kAudioMid = "a=mid:audio";
2240 const std::string kAudioMidReplaceStr = "a=mid:audio_content_name";
2241 const std::string kVideoMid = "a=mid:video";
2242 const std::string kVideoMidReplaceStr = "a=mid:video_content_name";
2243
2244 // Replacing |audio| with |audio_content_name|.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002245 rtc::replace_substrs(kAudioMid.c_str(), kAudioMid.length(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002246 kAudioMidReplaceStr.c_str(),
2247 kAudioMidReplaceStr.length(),
2248 &sdp);
2249 // Replacing |video| with |video_content_name|.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002250 rtc::replace_substrs(kVideoMid.c_str(), kVideoMid.length(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002251 kVideoMidReplaceStr.c_str(),
2252 kVideoMidReplaceStr.length(),
2253 &sdp);
2254
2255 SessionDescriptionInterface* modified_offer =
2256 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
2257
2258 SetRemoteDescriptionWithoutError(modified_offer);
2259
2260 SessionDescriptionInterface* answer =
wu@webrtc.org91053e72013-08-10 07:18:04 +00002261 CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002262 SetLocalDescriptionWithoutError(answer);
2263
deadbeefcbecd352015-09-23 11:50:27 -07002264 cricket::TransportChannel* voice_transport_channel =
2265 session_->voice_rtp_transport_channel();
2266 EXPECT_TRUE(voice_transport_channel != NULL);
2267 EXPECT_EQ(voice_transport_channel->transport_name(), "audio_content_name");
2268 cricket::TransportChannel* video_transport_channel =
2269 session_->video_rtp_transport_channel();
2270 EXPECT_TRUE(video_transport_channel != NULL);
2271 EXPECT_EQ(video_transport_channel->transport_name(), "video_content_name");
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002272 EXPECT_TRUE((video_channel_ = media_engine_->GetVideoChannel(0)) != NULL);
2273 EXPECT_TRUE((voice_channel_ = media_engine_->GetVoiceChannel(0)) != NULL);
2274}
2275
2276// Test that an offer contains the correct media content descriptions based on
2277// the send streams when no constraints have been set.
2278TEST_F(WebRtcSessionTest, CreateOfferWithoutConstraintsOrStreams) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002279 Init();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002280 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
2281
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002282 ASSERT_TRUE(offer != NULL);
2283 const cricket::ContentInfo* content =
2284 cricket::GetFirstAudioContent(offer->description());
2285 EXPECT_TRUE(content != NULL);
2286 content = cricket::GetFirstVideoContent(offer->description());
2287 EXPECT_TRUE(content == NULL);
2288}
2289
2290// Test that an offer contains the correct media content descriptions based on
2291// the send streams when no constraints have been set.
2292TEST_F(WebRtcSessionTest, CreateOfferWithoutConstraints) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002293 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002294 // Test Audio only offer.
deadbeefab9b2d12015-10-14 11:33:11 -07002295 SendAudioOnlyStream2();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002296 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
2297
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002298 const cricket::ContentInfo* content =
2299 cricket::GetFirstAudioContent(offer->description());
2300 EXPECT_TRUE(content != NULL);
2301 content = cricket::GetFirstVideoContent(offer->description());
2302 EXPECT_TRUE(content == NULL);
2303
2304 // Test Audio / Video offer.
deadbeefab9b2d12015-10-14 11:33:11 -07002305 SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002306 offer.reset(CreateOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002307 content = cricket::GetFirstAudioContent(offer->description());
2308 EXPECT_TRUE(content != NULL);
2309 content = cricket::GetFirstVideoContent(offer->description());
2310 EXPECT_TRUE(content != NULL);
2311}
2312
2313// Test that an offer contains no media content descriptions if
2314// kOfferToReceiveVideo and kOfferToReceiveAudio constraints are set to false.
2315TEST_F(WebRtcSessionTest, CreateOfferWithConstraintsWithoutStreams) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002316 Init();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002317 PeerConnectionInterface::RTCOfferAnswerOptions options;
2318 options.offer_to_receive_audio = 0;
2319 options.offer_to_receive_video = 0;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002320
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002321 rtc::scoped_ptr<SessionDescriptionInterface> offer(
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002322 CreateOffer(options));
2323
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002324 ASSERT_TRUE(offer != NULL);
2325 const cricket::ContentInfo* content =
2326 cricket::GetFirstAudioContent(offer->description());
2327 EXPECT_TRUE(content == NULL);
2328 content = cricket::GetFirstVideoContent(offer->description());
2329 EXPECT_TRUE(content == NULL);
2330}
2331
2332// Test that an offer contains only audio media content descriptions if
2333// kOfferToReceiveAudio constraints are set to true.
2334TEST_F(WebRtcSessionTest, CreateAudioOnlyOfferWithConstraints) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002335 Init();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002336 PeerConnectionInterface::RTCOfferAnswerOptions options;
2337 options.offer_to_receive_audio =
2338 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
2339
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002340 rtc::scoped_ptr<SessionDescriptionInterface> offer(
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002341 CreateOffer(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002342
2343 const cricket::ContentInfo* content =
2344 cricket::GetFirstAudioContent(offer->description());
2345 EXPECT_TRUE(content != NULL);
2346 content = cricket::GetFirstVideoContent(offer->description());
2347 EXPECT_TRUE(content == NULL);
2348}
2349
2350// Test that an offer contains audio and video media content descriptions if
2351// kOfferToReceiveAudio and kOfferToReceiveVideo constraints are set to true.
2352TEST_F(WebRtcSessionTest, CreateOfferWithConstraints) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002353 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002354 // Test Audio / Video offer.
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002355 PeerConnectionInterface::RTCOfferAnswerOptions options;
2356 options.offer_to_receive_audio =
2357 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
2358 options.offer_to_receive_video =
2359 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
2360
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002361 rtc::scoped_ptr<SessionDescriptionInterface> offer(
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002362 CreateOffer(options));
2363
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002364 const cricket::ContentInfo* content =
2365 cricket::GetFirstAudioContent(offer->description());
jiayl@webrtc.orgc1723202014-09-08 20:44:36 +00002366 EXPECT_TRUE(content != NULL);
jiayl@webrtc.org7d4891d2014-09-09 21:43:15 +00002367
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002368 content = cricket::GetFirstVideoContent(offer->description());
2369 EXPECT_TRUE(content != NULL);
2370
jiayl@webrtc.org7d4891d2014-09-09 21:43:15 +00002371 // Sets constraints to false and verifies that audio/video contents are
2372 // removed.
2373 options.offer_to_receive_audio = 0;
2374 options.offer_to_receive_video = 0;
2375 offer.reset(CreateOffer(options));
2376
2377 content = cricket::GetFirstAudioContent(offer->description());
2378 EXPECT_TRUE(content == NULL);
2379 content = cricket::GetFirstVideoContent(offer->description());
2380 EXPECT_TRUE(content == NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002381}
2382
2383// Test that an answer can not be created if the last remote description is not
2384// an offer.
2385TEST_F(WebRtcSessionTest, CreateAnswerWithoutAnOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002386 Init();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002387 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002388 SetLocalDescriptionWithoutError(offer);
2389 SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
2390 SetRemoteDescriptionWithoutError(answer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00002391 EXPECT_TRUE(CreateAnswer(NULL) == NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002392}
2393
2394// Test that an answer contains the correct media content descriptions when no
2395// constraints have been set.
2396TEST_F(WebRtcSessionTest, CreateAnswerWithoutConstraintsOrStreams) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002397 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002398 // Create a remote offer with audio and video content.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002399 rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002400 SetRemoteDescriptionWithoutError(offer.release());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002401 rtc::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002402 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002403 const cricket::ContentInfo* content =
2404 cricket::GetFirstAudioContent(answer->description());
2405 ASSERT_TRUE(content != NULL);
2406 EXPECT_FALSE(content->rejected);
2407
2408 content = cricket::GetFirstVideoContent(answer->description());
2409 ASSERT_TRUE(content != NULL);
2410 EXPECT_FALSE(content->rejected);
2411}
2412
2413// Test that an answer contains the correct media content descriptions when no
2414// constraints have been set and the offer only contain audio.
2415TEST_F(WebRtcSessionTest, CreateAudioAnswerWithoutConstraintsOrStreams) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002416 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002417 // Create a remote offer with audio only.
2418 cricket::MediaSessionOptions options;
jiayl@webrtc.org7d4891d2014-09-09 21:43:15 +00002419
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002420 rtc::scoped_ptr<JsepSessionDescription> offer(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002421 CreateRemoteOffer(options));
2422 ASSERT_TRUE(cricket::GetFirstVideoContent(offer->description()) == NULL);
2423 ASSERT_TRUE(cricket::GetFirstAudioContent(offer->description()) != NULL);
2424
2425 SetRemoteDescriptionWithoutError(offer.release());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002426 rtc::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002427 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002428 const cricket::ContentInfo* content =
2429 cricket::GetFirstAudioContent(answer->description());
2430 ASSERT_TRUE(content != NULL);
2431 EXPECT_FALSE(content->rejected);
2432
2433 EXPECT_TRUE(cricket::GetFirstVideoContent(answer->description()) == NULL);
2434}
2435
2436// Test that an answer contains the correct media content descriptions when no
2437// constraints have been set.
2438TEST_F(WebRtcSessionTest, CreateAnswerWithoutConstraints) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002439 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002440 // Create a remote offer with audio and video content.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002441 rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002442 SetRemoteDescriptionWithoutError(offer.release());
2443 // Test with a stream with tracks.
deadbeefab9b2d12015-10-14 11:33:11 -07002444 SendAudioVideoStream1();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002445 rtc::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002446 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002447 const cricket::ContentInfo* content =
2448 cricket::GetFirstAudioContent(answer->description());
2449 ASSERT_TRUE(content != NULL);
2450 EXPECT_FALSE(content->rejected);
2451
2452 content = cricket::GetFirstVideoContent(answer->description());
2453 ASSERT_TRUE(content != NULL);
2454 EXPECT_FALSE(content->rejected);
2455}
2456
2457// Test that an answer contains the correct media content descriptions when
2458// constraints have been set but no stream is sent.
2459TEST_F(WebRtcSessionTest, CreateAnswerWithConstraintsWithoutStreams) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002460 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002461 // Create a remote offer with audio and video content.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002462 rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002463 SetRemoteDescriptionWithoutError(offer.release());
2464
2465 webrtc::FakeConstraints constraints_no_receive;
2466 constraints_no_receive.SetMandatoryReceiveAudio(false);
2467 constraints_no_receive.SetMandatoryReceiveVideo(false);
2468
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002469 rtc::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002470 CreateAnswer(&constraints_no_receive));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002471 const cricket::ContentInfo* content =
2472 cricket::GetFirstAudioContent(answer->description());
2473 ASSERT_TRUE(content != NULL);
2474 EXPECT_TRUE(content->rejected);
2475
2476 content = cricket::GetFirstVideoContent(answer->description());
2477 ASSERT_TRUE(content != NULL);
2478 EXPECT_TRUE(content->rejected);
2479}
2480
2481// Test that an answer contains the correct media content descriptions when
2482// constraints have been set and streams are sent.
2483TEST_F(WebRtcSessionTest, CreateAnswerWithConstraints) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002484 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002485 // Create a remote offer with audio and video content.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002486 rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002487 SetRemoteDescriptionWithoutError(offer.release());
2488
2489 webrtc::FakeConstraints constraints_no_receive;
2490 constraints_no_receive.SetMandatoryReceiveAudio(false);
2491 constraints_no_receive.SetMandatoryReceiveVideo(false);
2492
2493 // Test with a stream with tracks.
deadbeefab9b2d12015-10-14 11:33:11 -07002494 SendAudioVideoStream1();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002495 rtc::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002496 CreateAnswer(&constraints_no_receive));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002497
2498 // TODO(perkj): Should the direction be set to SEND_ONLY?
2499 const cricket::ContentInfo* content =
2500 cricket::GetFirstAudioContent(answer->description());
2501 ASSERT_TRUE(content != NULL);
2502 EXPECT_FALSE(content->rejected);
2503
2504 // TODO(perkj): Should the direction be set to SEND_ONLY?
2505 content = cricket::GetFirstVideoContent(answer->description());
2506 ASSERT_TRUE(content != NULL);
2507 EXPECT_FALSE(content->rejected);
2508}
2509
2510TEST_F(WebRtcSessionTest, CreateOfferWithoutCNCodecs) {
2511 AddCNCodecs();
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002512 Init();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002513 PeerConnectionInterface::RTCOfferAnswerOptions options;
2514 options.offer_to_receive_audio =
2515 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
2516 options.voice_activity_detection = false;
2517
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002518 rtc::scoped_ptr<SessionDescriptionInterface> offer(
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002519 CreateOffer(options));
2520
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002521 const cricket::ContentInfo* content =
2522 cricket::GetFirstAudioContent(offer->description());
2523 EXPECT_TRUE(content != NULL);
2524 EXPECT_TRUE(VerifyNoCNCodecs(content));
2525}
2526
2527TEST_F(WebRtcSessionTest, CreateAnswerWithoutCNCodecs) {
2528 AddCNCodecs();
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002529 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002530 // Create a remote offer with audio and video content.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002531 rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002532 SetRemoteDescriptionWithoutError(offer.release());
2533
2534 webrtc::FakeConstraints constraints;
2535 constraints.SetOptionalVAD(false);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002536 rtc::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002537 CreateAnswer(&constraints));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002538 const cricket::ContentInfo* content =
2539 cricket::GetFirstAudioContent(answer->description());
2540 ASSERT_TRUE(content != NULL);
2541 EXPECT_TRUE(VerifyNoCNCodecs(content));
2542}
2543
2544// This test verifies the call setup when remote answer with audio only and
2545// later updates with video.
2546TEST_F(WebRtcSessionTest, TestAVOfferWithAudioOnlyAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002547 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002548 EXPECT_TRUE(media_engine_->GetVideoChannel(0) == NULL);
2549 EXPECT_TRUE(media_engine_->GetVoiceChannel(0) == NULL);
2550
deadbeefab9b2d12015-10-14 11:33:11 -07002551 SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002552 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002553
2554 cricket::MediaSessionOptions options;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002555 SessionDescriptionInterface* answer = CreateRemoteAnswer(offer, options);
2556
2557 // SetLocalDescription and SetRemoteDescriptions takes ownership of offer
2558 // and answer;
2559 SetLocalDescriptionWithoutError(offer);
2560 SetRemoteDescriptionWithoutError(answer);
2561
2562 video_channel_ = media_engine_->GetVideoChannel(0);
2563 voice_channel_ = media_engine_->GetVoiceChannel(0);
2564
2565 ASSERT_TRUE(video_channel_ == NULL);
2566
2567 ASSERT_EQ(0u, voice_channel_->recv_streams().size());
2568 ASSERT_EQ(1u, voice_channel_->send_streams().size());
2569 EXPECT_EQ(kAudioTrack1, voice_channel_->send_streams()[0].id);
2570
2571 // Let the remote end update the session descriptions, with Audio and Video.
deadbeefab9b2d12015-10-14 11:33:11 -07002572 SendAudioVideoStream2();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002573 CreateAndSetRemoteOfferAndLocalAnswer();
2574
2575 video_channel_ = media_engine_->GetVideoChannel(0);
2576 voice_channel_ = media_engine_->GetVoiceChannel(0);
2577
2578 ASSERT_TRUE(video_channel_ != NULL);
2579 ASSERT_TRUE(voice_channel_ != NULL);
2580
2581 ASSERT_EQ(1u, video_channel_->recv_streams().size());
2582 ASSERT_EQ(1u, video_channel_->send_streams().size());
2583 EXPECT_EQ(kVideoTrack2, video_channel_->recv_streams()[0].id);
2584 EXPECT_EQ(kVideoTrack2, video_channel_->send_streams()[0].id);
2585 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
2586 ASSERT_EQ(1u, voice_channel_->send_streams().size());
2587 EXPECT_EQ(kAudioTrack2, voice_channel_->recv_streams()[0].id);
2588 EXPECT_EQ(kAudioTrack2, voice_channel_->send_streams()[0].id);
2589
2590 // Change session back to audio only.
deadbeefab9b2d12015-10-14 11:33:11 -07002591 SendAudioOnlyStream2();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002592 CreateAndSetRemoteOfferAndLocalAnswer();
2593
2594 EXPECT_EQ(0u, video_channel_->recv_streams().size());
2595 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
2596 EXPECT_EQ(kAudioTrack2, voice_channel_->recv_streams()[0].id);
2597 ASSERT_EQ(1u, voice_channel_->send_streams().size());
2598 EXPECT_EQ(kAudioTrack2, voice_channel_->send_streams()[0].id);
2599}
2600
2601// This test verifies the call setup when remote answer with video only and
2602// later updates with audio.
2603TEST_F(WebRtcSessionTest, TestAVOfferWithVideoOnlyAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002604 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002605 EXPECT_TRUE(media_engine_->GetVideoChannel(0) == NULL);
2606 EXPECT_TRUE(media_engine_->GetVoiceChannel(0) == NULL);
deadbeefab9b2d12015-10-14 11:33:11 -07002607 SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002608 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002609
2610 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00002611 options.recv_audio = false;
2612 options.recv_video = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002613 SessionDescriptionInterface* answer = CreateRemoteAnswer(
2614 offer, options, cricket::SEC_ENABLED);
2615
2616 // SetLocalDescription and SetRemoteDescriptions takes ownership of offer
2617 // and answer.
2618 SetLocalDescriptionWithoutError(offer);
2619 SetRemoteDescriptionWithoutError(answer);
2620
2621 video_channel_ = media_engine_->GetVideoChannel(0);
2622 voice_channel_ = media_engine_->GetVoiceChannel(0);
2623
2624 ASSERT_TRUE(voice_channel_ == NULL);
2625 ASSERT_TRUE(video_channel_ != NULL);
2626
2627 EXPECT_EQ(0u, video_channel_->recv_streams().size());
2628 ASSERT_EQ(1u, video_channel_->send_streams().size());
2629 EXPECT_EQ(kVideoTrack1, video_channel_->send_streams()[0].id);
2630
2631 // Update the session descriptions, with Audio and Video.
deadbeefab9b2d12015-10-14 11:33:11 -07002632 SendAudioVideoStream2();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002633 CreateAndSetRemoteOfferAndLocalAnswer();
2634
2635 voice_channel_ = media_engine_->GetVoiceChannel(0);
2636 ASSERT_TRUE(voice_channel_ != NULL);
2637
2638 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
2639 ASSERT_EQ(1u, voice_channel_->send_streams().size());
2640 EXPECT_EQ(kAudioTrack2, voice_channel_->recv_streams()[0].id);
2641 EXPECT_EQ(kAudioTrack2, voice_channel_->send_streams()[0].id);
2642
2643 // Change session back to video only.
deadbeefab9b2d12015-10-14 11:33:11 -07002644 SendVideoOnlyStream2();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002645 CreateAndSetRemoteOfferAndLocalAnswer();
2646
2647 video_channel_ = media_engine_->GetVideoChannel(0);
2648 voice_channel_ = media_engine_->GetVoiceChannel(0);
2649
2650 ASSERT_EQ(1u, video_channel_->recv_streams().size());
2651 EXPECT_EQ(kVideoTrack2, video_channel_->recv_streams()[0].id);
2652 ASSERT_EQ(1u, video_channel_->send_streams().size());
2653 EXPECT_EQ(kVideoTrack2, video_channel_->send_streams()[0].id);
2654}
2655
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002656TEST_F(WebRtcSessionTest, VerifyCryptoParamsInSDP) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002657 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07002658 SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002659 scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002660 VerifyCryptoParams(offer->description());
2661 SetRemoteDescriptionWithoutError(offer.release());
wu@webrtc.org91053e72013-08-10 07:18:04 +00002662 scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002663 VerifyCryptoParams(answer->description());
2664}
2665
2666TEST_F(WebRtcSessionTest, VerifyNoCryptoParamsInSDP) {
wu@webrtc.org97077a32013-10-25 21:18:33 +00002667 options_.disable_encryption = true;
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002668 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07002669 SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002670 scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002671 VerifyNoCryptoParams(offer->description(), false);
2672}
2673
2674TEST_F(WebRtcSessionTest, VerifyAnswerFromNonCryptoOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002675 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002676 VerifyAnswerFromNonCryptoOffer();
2677}
2678
2679TEST_F(WebRtcSessionTest, VerifyAnswerFromCryptoOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002680 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002681 VerifyAnswerFromCryptoOffer();
2682}
2683
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002684// This test verifies that setLocalDescription fails if
2685// no a=ice-ufrag and a=ice-pwd lines are present in the SDP.
2686TEST_F(WebRtcSessionTest, TestSetLocalDescriptionWithoutIce) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002687 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07002688 SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002689 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
2690
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002691 std::string sdp;
2692 RemoveIceUfragPwdLines(offer.get(), &sdp);
2693 SessionDescriptionInterface* modified_offer =
2694 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00002695 SetLocalDescriptionOfferExpectError(kSdpWithoutIceUfragPwd, modified_offer);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002696}
2697
2698// This test verifies that setRemoteDescription fails if
2699// no a=ice-ufrag and a=ice-pwd lines are present in the SDP.
2700TEST_F(WebRtcSessionTest, TestSetRemoteDescriptionWithoutIce) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002701 Init();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002702 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateRemoteOffer());
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002703 std::string sdp;
2704 RemoveIceUfragPwdLines(offer.get(), &sdp);
2705 SessionDescriptionInterface* modified_offer =
2706 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00002707 SetRemoteDescriptionOfferExpectError(kSdpWithoutIceUfragPwd, modified_offer);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002708}
2709
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +00002710// This test verifies that setLocalDescription fails if local offer has
2711// too short ice ufrag and pwd strings.
2712TEST_F(WebRtcSessionTest, TestSetLocalDescriptionInvalidIceCredentials) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002713 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07002714 SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002715 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
2716
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +00002717 std::string sdp;
2718 // Modifying ice ufrag and pwd in local offer with strings smaller than the
2719 // recommended values of 4 and 22 bytes respectively.
2720 ModifyIceUfragPwdLines(offer.get(), "ice", "icepwd", &sdp);
2721 SessionDescriptionInterface* modified_offer =
2722 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
2723 std::string error;
2724 EXPECT_FALSE(session_->SetLocalDescription(modified_offer, &error));
2725
2726 // Test with string greater than 256.
2727 sdp.clear();
2728 ModifyIceUfragPwdLines(offer.get(), kTooLongIceUfragPwd, kTooLongIceUfragPwd,
2729 &sdp);
2730 modified_offer = CreateSessionDescription(JsepSessionDescription::kOffer, sdp,
2731 NULL);
2732 EXPECT_FALSE(session_->SetLocalDescription(modified_offer, &error));
2733}
2734
2735// This test verifies that setRemoteDescription fails if remote offer has
2736// too short ice ufrag and pwd strings.
2737TEST_F(WebRtcSessionTest, TestSetRemoteDescriptionInvalidIceCredentials) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002738 Init();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002739 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateRemoteOffer());
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +00002740 std::string sdp;
2741 // Modifying ice ufrag and pwd in remote offer with strings smaller than the
2742 // recommended values of 4 and 22 bytes respectively.
2743 ModifyIceUfragPwdLines(offer.get(), "ice", "icepwd", &sdp);
2744 SessionDescriptionInterface* modified_offer =
2745 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
2746 std::string error;
2747 EXPECT_FALSE(session_->SetRemoteDescription(modified_offer, &error));
2748
2749 sdp.clear();
2750 ModifyIceUfragPwdLines(offer.get(), kTooLongIceUfragPwd, kTooLongIceUfragPwd,
2751 &sdp);
2752 modified_offer = CreateSessionDescription(JsepSessionDescription::kOffer, sdp,
2753 NULL);
2754 EXPECT_FALSE(session_->SetRemoteDescription(modified_offer, &error));
2755}
2756
honghaiz503726c2015-07-31 12:37:38 -07002757// Test that if the remote description indicates the peer requested ICE restart
2758// (via a new ufrag or pwd), the old ICE candidates are not copied,
2759// and vice versa.
2760TEST_F(WebRtcSessionTest, TestSetRemoteDescriptionWithIceRestart) {
2761 Init();
2762 scoped_ptr<SessionDescriptionInterface> offer(CreateRemoteOffer());
2763
2764 // Create the first offer.
2765 std::string sdp;
2766 ModifyIceUfragPwdLines(offer.get(), "0123456789012345",
2767 "abcdefghijklmnopqrstuvwx", &sdp);
2768 SessionDescriptionInterface* offer1 =
2769 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
2770 cricket::Candidate candidate1(1, "udp", rtc::SocketAddress("1.1.1.1", 5000),
2771 0, "", "", "relay", 0, "");
2772 JsepIceCandidate ice_candidate1(kMediaContentName0, kMediaContentIndex0,
2773 candidate1);
2774 EXPECT_TRUE(offer1->AddCandidate(&ice_candidate1));
2775 SetRemoteDescriptionWithoutError(offer1);
2776 EXPECT_EQ(1, session_->remote_description()->candidates(0)->count());
2777
2778 // The second offer has the same ufrag and pwd but different address.
2779 sdp.clear();
2780 ModifyIceUfragPwdLines(offer.get(), "0123456789012345",
2781 "abcdefghijklmnopqrstuvwx", &sdp);
2782 SessionDescriptionInterface* offer2 =
2783 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
2784 candidate1.set_address(rtc::SocketAddress("1.1.1.1", 6000));
2785 JsepIceCandidate ice_candidate2(kMediaContentName0, kMediaContentIndex0,
2786 candidate1);
2787 EXPECT_TRUE(offer2->AddCandidate(&ice_candidate2));
2788 SetRemoteDescriptionWithoutError(offer2);
2789 EXPECT_EQ(2, session_->remote_description()->candidates(0)->count());
2790
2791 // The third offer has a different ufrag and different address.
2792 sdp.clear();
2793 ModifyIceUfragPwdLines(offer.get(), "0123456789012333",
2794 "abcdefghijklmnopqrstuvwx", &sdp);
2795 SessionDescriptionInterface* offer3 =
2796 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
2797 candidate1.set_address(rtc::SocketAddress("1.1.1.1", 7000));
2798 JsepIceCandidate ice_candidate3(kMediaContentName0, kMediaContentIndex0,
2799 candidate1);
2800 EXPECT_TRUE(offer3->AddCandidate(&ice_candidate3));
2801 SetRemoteDescriptionWithoutError(offer3);
2802 EXPECT_EQ(1, session_->remote_description()->candidates(0)->count());
2803
2804 // The fourth offer has no candidate but a different ufrag/pwd.
2805 sdp.clear();
2806 ModifyIceUfragPwdLines(offer.get(), "0123456789012444",
2807 "abcdefghijklmnopqrstuvyz", &sdp);
2808 SessionDescriptionInterface* offer4 =
2809 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
2810 SetRemoteDescriptionWithoutError(offer4);
2811 EXPECT_EQ(0, session_->remote_description()->candidates(0)->count());
2812}
2813
Donald Curtisd4f769d2015-05-28 09:48:21 -07002814// Test that candidates sent to the "video" transport do not get pushed down to
2815// the "audio" transport channel when bundling using TransportProxy.
2816TEST_F(WebRtcSessionTest, TestIgnoreCandidatesForUnusedTransportWhenBundling) {
2817 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
2818
2819 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyBalanced);
deadbeefab9b2d12015-10-14 11:33:11 -07002820 SendAudioVideoStream1();
Donald Curtisd4f769d2015-05-28 09:48:21 -07002821
2822 PeerConnectionInterface::RTCOfferAnswerOptions options;
2823 options.use_rtp_mux = true;
2824
2825 SessionDescriptionInterface* offer = CreateRemoteOffer();
2826 SetRemoteDescriptionWithoutError(offer);
2827
2828 SessionDescriptionInterface* answer = CreateAnswer(NULL);
2829 SetLocalDescriptionWithoutError(answer);
2830
deadbeefcbecd352015-09-23 11:50:27 -07002831 EXPECT_EQ(session_->voice_rtp_transport_channel(),
2832 session_->video_rtp_transport_channel());
Donald Curtisd4f769d2015-05-28 09:48:21 -07002833
deadbeefcbecd352015-09-23 11:50:27 -07002834 cricket::BaseChannel* voice_channel = session_->voice_channel();
2835 ASSERT(voice_channel != NULL);
Donald Curtisd4f769d2015-05-28 09:48:21 -07002836
2837 // Checks if one of the transport channels contains a connection using a given
2838 // port.
deadbeefcbecd352015-09-23 11:50:27 -07002839 auto connection_with_remote_port = [this, voice_channel](int port) {
2840 cricket::SessionStats stats;
2841 session_->GetChannelTransportStats(voice_channel, &stats);
2842 for (auto& kv : stats.transport_stats) {
2843 for (auto& chan_stat : kv.second.channel_stats) {
2844 for (auto& conn_info : chan_stat.connection_infos) {
2845 if (conn_info.remote_candidate.address().port() == port) {
2846 return true;
2847 }
Donald Curtisd4f769d2015-05-28 09:48:21 -07002848 }
2849 }
2850 }
2851 return false;
2852 };
2853
2854 EXPECT_FALSE(connection_with_remote_port(5000));
2855 EXPECT_FALSE(connection_with_remote_port(5001));
2856 EXPECT_FALSE(connection_with_remote_port(6000));
2857
2858 // The way the *_WAIT checks work is they only wait if the condition fails,
2859 // which does not help in the case where state is not changing. This is
2860 // problematic in this test since we want to verify that adding a video
2861 // candidate does _not_ change state. So we interleave candidates and assume
2862 // that messages are executed in the order they were posted.
2863
2864 // First audio candidate.
2865 cricket::Candidate candidate0;
2866 candidate0.set_address(rtc::SocketAddress("1.1.1.1", 5000));
2867 candidate0.set_component(1);
2868 candidate0.set_protocol("udp");
2869 JsepIceCandidate ice_candidate0(kMediaContentName0, kMediaContentIndex0,
2870 candidate0);
2871 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate0));
2872
2873 // Video candidate.
2874 cricket::Candidate candidate1;
2875 candidate1.set_address(rtc::SocketAddress("1.1.1.1", 6000));
2876 candidate1.set_component(1);
2877 candidate1.set_protocol("udp");
2878 JsepIceCandidate ice_candidate1(kMediaContentName1, kMediaContentIndex1,
2879 candidate1);
2880 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate1));
2881
2882 // Second audio candidate.
2883 cricket::Candidate candidate2;
2884 candidate2.set_address(rtc::SocketAddress("1.1.1.1", 5001));
2885 candidate2.set_component(1);
2886 candidate2.set_protocol("udp");
2887 JsepIceCandidate ice_candidate2(kMediaContentName0, kMediaContentIndex0,
2888 candidate2);
2889 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate2));
2890
2891 EXPECT_TRUE_WAIT(connection_with_remote_port(5000), 1000);
2892 EXPECT_TRUE_WAIT(connection_with_remote_port(5001), 1000);
2893
2894 // No need here for a _WAIT check since we are checking that state hasn't
2895 // changed: if this is false we would be doing waits for nothing and if this
2896 // is true then there will be no messages processed anyways.
2897 EXPECT_FALSE(connection_with_remote_port(6000));
2898}
2899
deadbeefcbecd352015-09-23 11:50:27 -07002900// kBundlePolicyBalanced BUNDLE policy and answer contains BUNDLE.
Donald Curtis0e209b02015-03-24 09:29:54 -07002901TEST_F(WebRtcSessionTest, TestBalancedBundleInAnswer) {
2902 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyBalanced);
deadbeefab9b2d12015-10-14 11:33:11 -07002903 SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002904
2905 PeerConnectionInterface::RTCOfferAnswerOptions options;
2906 options.use_rtp_mux = true;
2907
2908 SessionDescriptionInterface* offer = CreateOffer(options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002909 SetLocalDescriptionWithoutError(offer);
Donald Curtis0e209b02015-03-24 09:29:54 -07002910
deadbeefcbecd352015-09-23 11:50:27 -07002911 EXPECT_NE(session_->voice_rtp_transport_channel(),
2912 session_->video_rtp_transport_channel());
Donald Curtis0e209b02015-03-24 09:29:54 -07002913
deadbeefab9b2d12015-10-14 11:33:11 -07002914 SendAudioVideoStream2();
Donald Curtis0e209b02015-03-24 09:29:54 -07002915 SessionDescriptionInterface* answer =
2916 CreateRemoteAnswer(session_->local_description());
2917 SetRemoteDescriptionWithoutError(answer);
2918
deadbeefcbecd352015-09-23 11:50:27 -07002919 EXPECT_EQ(session_->voice_rtp_transport_channel(),
2920 session_->video_rtp_transport_channel());
Donald Curtis0e209b02015-03-24 09:29:54 -07002921}
2922
deadbeefcbecd352015-09-23 11:50:27 -07002923// kBundlePolicyBalanced BUNDLE policy but no BUNDLE in the answer.
Donald Curtis0e209b02015-03-24 09:29:54 -07002924TEST_F(WebRtcSessionTest, TestBalancedNoBundleInAnswer) {
2925 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyBalanced);
deadbeefab9b2d12015-10-14 11:33:11 -07002926 SendAudioVideoStream1();
Peter Thatcher4eddf182015-04-30 10:55:59 -07002927
Donald Curtis0e209b02015-03-24 09:29:54 -07002928 PeerConnectionInterface::RTCOfferAnswerOptions options;
2929 options.use_rtp_mux = true;
2930
2931 SessionDescriptionInterface* offer = CreateOffer(options);
2932 SetLocalDescriptionWithoutError(offer);
2933
deadbeefcbecd352015-09-23 11:50:27 -07002934 EXPECT_NE(session_->voice_rtp_transport_channel(),
2935 session_->video_rtp_transport_channel());
Donald Curtis0e209b02015-03-24 09:29:54 -07002936
deadbeefab9b2d12015-10-14 11:33:11 -07002937 SendAudioVideoStream2();
Donald Curtis0e209b02015-03-24 09:29:54 -07002938
2939 // Remove BUNDLE from the answer.
2940 rtc::scoped_ptr<SessionDescriptionInterface> answer(
2941 CreateRemoteAnswer(session_->local_description()));
2942 cricket::SessionDescription* answer_copy = answer->description()->Copy();
2943 answer_copy->RemoveGroupByName(cricket::GROUP_TYPE_BUNDLE);
2944 JsepSessionDescription* modified_answer =
2945 new JsepSessionDescription(JsepSessionDescription::kAnswer);
2946 modified_answer->Initialize(answer_copy, "1", "1");
2947 SetRemoteDescriptionWithoutError(modified_answer); //
2948
deadbeefcbecd352015-09-23 11:50:27 -07002949 EXPECT_NE(session_->voice_rtp_transport_channel(),
2950 session_->video_rtp_transport_channel());
Donald Curtis0e209b02015-03-24 09:29:54 -07002951}
2952
2953// kBundlePolicyMaxBundle policy with BUNDLE in the answer.
2954TEST_F(WebRtcSessionTest, TestMaxBundleBundleInAnswer) {
2955 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxBundle);
deadbeefab9b2d12015-10-14 11:33:11 -07002956 SendAudioVideoStream1();
Donald Curtis0e209b02015-03-24 09:29:54 -07002957
2958 PeerConnectionInterface::RTCOfferAnswerOptions options;
2959 options.use_rtp_mux = true;
2960
2961 SessionDescriptionInterface* offer = CreateOffer(options);
2962 SetLocalDescriptionWithoutError(offer);
2963
deadbeefcbecd352015-09-23 11:50:27 -07002964 EXPECT_EQ(session_->voice_rtp_transport_channel(),
2965 session_->video_rtp_transport_channel());
Donald Curtis0e209b02015-03-24 09:29:54 -07002966
deadbeefab9b2d12015-10-14 11:33:11 -07002967 SendAudioVideoStream2();
Donald Curtis0e209b02015-03-24 09:29:54 -07002968 SessionDescriptionInterface* answer =
2969 CreateRemoteAnswer(session_->local_description());
2970 SetRemoteDescriptionWithoutError(answer);
2971
deadbeefcbecd352015-09-23 11:50:27 -07002972 EXPECT_EQ(session_->voice_rtp_transport_channel(),
2973 session_->video_rtp_transport_channel());
2974}
2975
2976// kBundlePolicyMaxBundle policy with BUNDLE in the answer, but no
2977// audio content in the answer.
2978TEST_F(WebRtcSessionTest, TestMaxBundleRejectAudio) {
2979 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxBundle);
deadbeefab9b2d12015-10-14 11:33:11 -07002980 SendAudioVideoStream1();
deadbeefcbecd352015-09-23 11:50:27 -07002981
2982 PeerConnectionInterface::RTCOfferAnswerOptions options;
2983 options.use_rtp_mux = true;
2984
2985 SessionDescriptionInterface* offer = CreateOffer(options);
2986 SetLocalDescriptionWithoutError(offer);
2987
2988 EXPECT_EQ(session_->voice_rtp_transport_channel(),
2989 session_->video_rtp_transport_channel());
2990
deadbeefab9b2d12015-10-14 11:33:11 -07002991 SendAudioVideoStream2();
deadbeefcbecd352015-09-23 11:50:27 -07002992 cricket::MediaSessionOptions recv_options;
2993 recv_options.recv_audio = false;
2994 recv_options.recv_video = true;
2995 SessionDescriptionInterface* answer =
2996 CreateRemoteAnswer(session_->local_description(), recv_options);
2997 SetRemoteDescriptionWithoutError(answer);
2998
2999 EXPECT_TRUE(NULL == session_->voice_channel());
3000 EXPECT_TRUE(NULL != session_->video_rtp_transport_channel());
3001
3002 session_->Terminate();
3003 EXPECT_TRUE(NULL == session_->voice_rtp_transport_channel());
3004 EXPECT_TRUE(NULL == session_->voice_rtcp_transport_channel());
3005 EXPECT_TRUE(NULL == session_->video_rtp_transport_channel());
3006 EXPECT_TRUE(NULL == session_->video_rtcp_transport_channel());
Donald Curtis0e209b02015-03-24 09:29:54 -07003007}
3008
3009// kBundlePolicyMaxBundle policy but no BUNDLE in the answer.
3010TEST_F(WebRtcSessionTest, TestMaxBundleNoBundleInAnswer) {
3011 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxBundle);
deadbeefab9b2d12015-10-14 11:33:11 -07003012 SendAudioVideoStream1();
Peter Thatcher4eddf182015-04-30 10:55:59 -07003013
Donald Curtis0e209b02015-03-24 09:29:54 -07003014 PeerConnectionInterface::RTCOfferAnswerOptions options;
3015 options.use_rtp_mux = true;
3016
3017 SessionDescriptionInterface* offer = CreateOffer(options);
3018 SetLocalDescriptionWithoutError(offer);
3019
deadbeefcbecd352015-09-23 11:50:27 -07003020 EXPECT_EQ(session_->voice_rtp_transport_channel(),
3021 session_->video_rtp_transport_channel());
Donald Curtis0e209b02015-03-24 09:29:54 -07003022
deadbeefab9b2d12015-10-14 11:33:11 -07003023 SendAudioVideoStream2();
Donald Curtis0e209b02015-03-24 09:29:54 -07003024
3025 // Remove BUNDLE from the answer.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003026 rtc::scoped_ptr<SessionDescriptionInterface> answer(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003027 CreateRemoteAnswer(session_->local_description()));
3028 cricket::SessionDescription* answer_copy = answer->description()->Copy();
3029 answer_copy->RemoveGroupByName(cricket::GROUP_TYPE_BUNDLE);
3030 JsepSessionDescription* modified_answer =
3031 new JsepSessionDescription(JsepSessionDescription::kAnswer);
3032 modified_answer->Initialize(answer_copy, "1", "1");
3033 SetRemoteDescriptionWithoutError(modified_answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003034
deadbeefcbecd352015-09-23 11:50:27 -07003035 EXPECT_EQ(session_->voice_rtp_transport_channel(),
3036 session_->video_rtp_transport_channel());
3037}
3038
3039// kBundlePolicyMaxBundle policy with BUNDLE in the remote offer.
3040TEST_F(WebRtcSessionTest, TestMaxBundleBundleInRemoteOffer) {
3041 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxBundle);
deadbeefab9b2d12015-10-14 11:33:11 -07003042 SendAudioVideoStream1();
deadbeefcbecd352015-09-23 11:50:27 -07003043
3044 SessionDescriptionInterface* offer = CreateRemoteOffer();
3045 SetRemoteDescriptionWithoutError(offer);
3046
3047 EXPECT_EQ(session_->voice_rtp_transport_channel(),
3048 session_->video_rtp_transport_channel());
3049
deadbeefab9b2d12015-10-14 11:33:11 -07003050 SendAudioVideoStream2();
deadbeefcbecd352015-09-23 11:50:27 -07003051 SessionDescriptionInterface* answer = CreateAnswer(nullptr);
3052 SetLocalDescriptionWithoutError(answer);
3053
3054 EXPECT_EQ(session_->voice_rtp_transport_channel(),
3055 session_->video_rtp_transport_channel());
3056}
3057
3058// kBundlePolicyMaxBundle policy but no BUNDLE in the remote offer.
3059TEST_F(WebRtcSessionTest, TestMaxBundleNoBundleInRemoteOffer) {
3060 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxBundle);
deadbeefab9b2d12015-10-14 11:33:11 -07003061 SendAudioVideoStream1();
deadbeefcbecd352015-09-23 11:50:27 -07003062
3063 // Remove BUNDLE from the offer.
3064 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateRemoteOffer());
3065 cricket::SessionDescription* offer_copy = offer->description()->Copy();
3066 offer_copy->RemoveGroupByName(cricket::GROUP_TYPE_BUNDLE);
3067 JsepSessionDescription* modified_offer =
3068 new JsepSessionDescription(JsepSessionDescription::kOffer);
3069 modified_offer->Initialize(offer_copy, "1", "1");
3070
3071 // Expect an error when applying the remote description
3072 SetRemoteDescriptionExpectError(JsepSessionDescription::kOffer,
3073 kCreateChannelFailed, modified_offer);
Donald Curtis0e209b02015-03-24 09:29:54 -07003074}
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003075
Peter Thatcher4eddf182015-04-30 10:55:59 -07003076// kBundlePolicyMaxCompat bundle policy and answer contains BUNDLE.
Donald Curtis0e209b02015-03-24 09:29:54 -07003077TEST_F(WebRtcSessionTest, TestMaxCompatBundleInAnswer) {
3078 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxCompat);
deadbeefab9b2d12015-10-14 11:33:11 -07003079 SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003080
Donald Curtis0e209b02015-03-24 09:29:54 -07003081 PeerConnectionInterface::RTCOfferAnswerOptions options;
3082 options.use_rtp_mux = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003083
Donald Curtis0e209b02015-03-24 09:29:54 -07003084 SessionDescriptionInterface* offer = CreateOffer(options);
3085 SetLocalDescriptionWithoutError(offer);
3086
deadbeefcbecd352015-09-23 11:50:27 -07003087 EXPECT_NE(session_->voice_rtp_transport_channel(),
3088 session_->video_rtp_transport_channel());
Donald Curtis0e209b02015-03-24 09:29:54 -07003089
deadbeefab9b2d12015-10-14 11:33:11 -07003090 SendAudioVideoStream2();
Donald Curtis0e209b02015-03-24 09:29:54 -07003091 SessionDescriptionInterface* answer =
3092 CreateRemoteAnswer(session_->local_description());
3093 SetRemoteDescriptionWithoutError(answer);
3094
3095 // This should lead to an audio-only call but isn't implemented
3096 // correctly yet.
deadbeefcbecd352015-09-23 11:50:27 -07003097 EXPECT_EQ(session_->voice_rtp_transport_channel(),
3098 session_->video_rtp_transport_channel());
Donald Curtis0e209b02015-03-24 09:29:54 -07003099}
3100
deadbeefcbecd352015-09-23 11:50:27 -07003101// kBundlePolicyMaxCompat BUNDLE policy but no BUNDLE in the answer.
Donald Curtis0e209b02015-03-24 09:29:54 -07003102TEST_F(WebRtcSessionTest, TestMaxCompatNoBundleInAnswer) {
3103 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxCompat);
deadbeefab9b2d12015-10-14 11:33:11 -07003104 SendAudioVideoStream1();
Donald Curtis0e209b02015-03-24 09:29:54 -07003105 PeerConnectionInterface::RTCOfferAnswerOptions options;
3106 options.use_rtp_mux = true;
3107
3108 SessionDescriptionInterface* offer = CreateOffer(options);
3109 SetLocalDescriptionWithoutError(offer);
3110
deadbeefcbecd352015-09-23 11:50:27 -07003111 EXPECT_NE(session_->voice_rtp_transport_channel(),
3112 session_->video_rtp_transport_channel());
Donald Curtis0e209b02015-03-24 09:29:54 -07003113
deadbeefab9b2d12015-10-14 11:33:11 -07003114 SendAudioVideoStream2();
Donald Curtis0e209b02015-03-24 09:29:54 -07003115
3116 // Remove BUNDLE from the answer.
3117 rtc::scoped_ptr<SessionDescriptionInterface> answer(
3118 CreateRemoteAnswer(session_->local_description()));
3119 cricket::SessionDescription* answer_copy = answer->description()->Copy();
3120 answer_copy->RemoveGroupByName(cricket::GROUP_TYPE_BUNDLE);
3121 JsepSessionDescription* modified_answer =
3122 new JsepSessionDescription(JsepSessionDescription::kAnswer);
3123 modified_answer->Initialize(answer_copy, "1", "1");
3124 SetRemoteDescriptionWithoutError(modified_answer); //
3125
deadbeefcbecd352015-09-23 11:50:27 -07003126 EXPECT_NE(session_->voice_rtp_transport_channel(),
3127 session_->video_rtp_transport_channel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003128}
3129
Peter Thatcher4eddf182015-04-30 10:55:59 -07003130// kBundlePolicyMaxbundle and then we call SetRemoteDescription first.
3131TEST_F(WebRtcSessionTest, TestMaxBundleWithSetRemoteDescriptionFirst) {
3132 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxBundle);
deadbeefab9b2d12015-10-14 11:33:11 -07003133 SendAudioVideoStream1();
Peter Thatcher4eddf182015-04-30 10:55:59 -07003134
3135 PeerConnectionInterface::RTCOfferAnswerOptions options;
3136 options.use_rtp_mux = true;
3137
3138 SessionDescriptionInterface* offer = CreateOffer(options);
3139 SetRemoteDescriptionWithoutError(offer);
3140
deadbeefcbecd352015-09-23 11:50:27 -07003141 EXPECT_EQ(session_->voice_rtp_transport_channel(),
3142 session_->video_rtp_transport_channel());
Peter Thatcher4eddf182015-04-30 10:55:59 -07003143}
3144
Peter Thatcheraf55ccc2015-05-21 07:48:41 -07003145TEST_F(WebRtcSessionTest, TestRequireRtcpMux) {
3146 InitWithRtcpMuxPolicy(PeerConnectionInterface::kRtcpMuxPolicyRequire);
deadbeefab9b2d12015-10-14 11:33:11 -07003147 SendAudioVideoStream1();
Peter Thatcheraf55ccc2015-05-21 07:48:41 -07003148
3149 PeerConnectionInterface::RTCOfferAnswerOptions options;
3150 SessionDescriptionInterface* offer = CreateOffer(options);
3151 SetLocalDescriptionWithoutError(offer);
3152
deadbeefcbecd352015-09-23 11:50:27 -07003153 EXPECT_TRUE(session_->voice_rtcp_transport_channel() == NULL);
3154 EXPECT_TRUE(session_->video_rtcp_transport_channel() == NULL);
Peter Thatcheraf55ccc2015-05-21 07:48:41 -07003155
deadbeefab9b2d12015-10-14 11:33:11 -07003156 SendAudioVideoStream2();
Peter Thatcheraf55ccc2015-05-21 07:48:41 -07003157 SessionDescriptionInterface* answer =
3158 CreateRemoteAnswer(session_->local_description());
3159 SetRemoteDescriptionWithoutError(answer);
3160
deadbeefcbecd352015-09-23 11:50:27 -07003161 EXPECT_TRUE(session_->voice_rtcp_transport_channel() == NULL);
3162 EXPECT_TRUE(session_->video_rtcp_transport_channel() == NULL);
Peter Thatcheraf55ccc2015-05-21 07:48:41 -07003163}
3164
3165TEST_F(WebRtcSessionTest, TestNegotiateRtcpMux) {
3166 InitWithRtcpMuxPolicy(PeerConnectionInterface::kRtcpMuxPolicyNegotiate);
deadbeefab9b2d12015-10-14 11:33:11 -07003167 SendAudioVideoStream1();
Peter Thatcheraf55ccc2015-05-21 07:48:41 -07003168
3169 PeerConnectionInterface::RTCOfferAnswerOptions options;
3170 SessionDescriptionInterface* offer = CreateOffer(options);
3171 SetLocalDescriptionWithoutError(offer);
3172
deadbeefcbecd352015-09-23 11:50:27 -07003173 EXPECT_TRUE(session_->voice_rtcp_transport_channel() != NULL);
3174 EXPECT_TRUE(session_->video_rtcp_transport_channel() != NULL);
Peter Thatcheraf55ccc2015-05-21 07:48:41 -07003175
deadbeefab9b2d12015-10-14 11:33:11 -07003176 SendAudioVideoStream2();
Peter Thatcheraf55ccc2015-05-21 07:48:41 -07003177 SessionDescriptionInterface* answer =
3178 CreateRemoteAnswer(session_->local_description());
3179 SetRemoteDescriptionWithoutError(answer);
3180
deadbeefcbecd352015-09-23 11:50:27 -07003181 EXPECT_TRUE(session_->voice_rtcp_transport_channel() == NULL);
3182 EXPECT_TRUE(session_->video_rtcp_transport_channel() == NULL);
Peter Thatcheraf55ccc2015-05-21 07:48:41 -07003183}
3184
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00003185// This test verifies that SetLocalDescription and SetRemoteDescription fails
3186// if BUNDLE is enabled but rtcp-mux is disabled in m-lines.
3187TEST_F(WebRtcSessionTest, TestDisabledRtcpMuxWithBundleEnabled) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003188 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07003189 SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003190
3191 PeerConnectionInterface::RTCOfferAnswerOptions options;
3192 options.use_rtp_mux = true;
3193
3194 SessionDescriptionInterface* offer = CreateOffer(options);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00003195 std::string offer_str;
3196 offer->ToString(&offer_str);
3197 // Disable rtcp-mux
3198 const std::string rtcp_mux = "rtcp-mux";
3199 const std::string xrtcp_mux = "xrtcp-mux";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003200 rtc::replace_substrs(rtcp_mux.c_str(), rtcp_mux.length(),
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00003201 xrtcp_mux.c_str(), xrtcp_mux.length(),
3202 &offer_str);
deadbeefcbecd352015-09-23 11:50:27 -07003203 JsepSessionDescription* local_offer =
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00003204 new JsepSessionDescription(JsepSessionDescription::kOffer);
3205 EXPECT_TRUE((local_offer)->Initialize(offer_str, NULL));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003206 SetLocalDescriptionOfferExpectError(kBundleWithoutRtcpMux, local_offer);
deadbeefcbecd352015-09-23 11:50:27 -07003207 JsepSessionDescription* remote_offer =
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00003208 new JsepSessionDescription(JsepSessionDescription::kOffer);
3209 EXPECT_TRUE((remote_offer)->Initialize(offer_str, NULL));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003210 SetRemoteDescriptionOfferExpectError(kBundleWithoutRtcpMux, remote_offer);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00003211 // Trying unmodified SDP.
3212 SetLocalDescriptionWithoutError(offer);
3213}
3214
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003215TEST_F(WebRtcSessionTest, SetAudioPlayout) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003216 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07003217 SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003218 CreateAndSetRemoteOfferAndLocalAnswer();
3219 cricket::FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0);
3220 ASSERT_TRUE(channel != NULL);
3221 ASSERT_EQ(1u, channel->recv_streams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003222 uint32_t receive_ssrc = channel->recv_streams()[0].first_ssrc();
solenberg4bac9c52015-10-09 02:32:53 -07003223 double volume;
3224 EXPECT_TRUE(channel->GetOutputVolume(receive_ssrc, &volume));
3225 EXPECT_EQ(1, volume);
solenbergd4cec0d2015-10-09 08:55:48 -07003226 session_->SetAudioPlayout(receive_ssrc, false);
solenberg4bac9c52015-10-09 02:32:53 -07003227 EXPECT_TRUE(channel->GetOutputVolume(receive_ssrc, &volume));
3228 EXPECT_EQ(0, volume);
solenbergd4cec0d2015-10-09 08:55:48 -07003229 session_->SetAudioPlayout(receive_ssrc, true);
solenberg4bac9c52015-10-09 02:32:53 -07003230 EXPECT_TRUE(channel->GetOutputVolume(receive_ssrc, &volume));
3231 EXPECT_EQ(1, volume);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003232}
3233
3234TEST_F(WebRtcSessionTest, SetAudioSend) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003235 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07003236 SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003237 CreateAndSetRemoteOfferAndLocalAnswer();
3238 cricket::FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0);
3239 ASSERT_TRUE(channel != NULL);
3240 ASSERT_EQ(1u, channel->send_streams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003241 uint32_t send_ssrc = channel->send_streams()[0].first_ssrc();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003242 EXPECT_FALSE(channel->IsStreamMuted(send_ssrc));
3243
3244 cricket::AudioOptions options;
3245 options.echo_cancellation.Set(true);
3246
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003247 rtc::scoped_ptr<FakeAudioRenderer> renderer(new FakeAudioRenderer());
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00003248 session_->SetAudioSend(send_ssrc, false, options, renderer.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003249 EXPECT_TRUE(channel->IsStreamMuted(send_ssrc));
3250 EXPECT_FALSE(channel->options().echo_cancellation.IsSet());
henrike@webrtc.orga7b98182014-02-21 15:51:43 +00003251 EXPECT_TRUE(renderer->sink() != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003252
henrike@webrtc.orga7b98182014-02-21 15:51:43 +00003253 // This will trigger SetSink(NULL) to the |renderer|.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00003254 session_->SetAudioSend(send_ssrc, true, options, NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003255 EXPECT_FALSE(channel->IsStreamMuted(send_ssrc));
3256 bool value;
3257 EXPECT_TRUE(channel->options().echo_cancellation.Get(&value));
3258 EXPECT_TRUE(value);
henrike@webrtc.orga7b98182014-02-21 15:51:43 +00003259 EXPECT_TRUE(renderer->sink() == NULL);
3260}
3261
3262TEST_F(WebRtcSessionTest, AudioRendererForLocalStream) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003263 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07003264 SendAudioVideoStream1();
henrike@webrtc.orga7b98182014-02-21 15:51:43 +00003265 CreateAndSetRemoteOfferAndLocalAnswer();
3266 cricket::FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0);
3267 ASSERT_TRUE(channel != NULL);
3268 ASSERT_EQ(1u, channel->send_streams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003269 uint32_t send_ssrc = channel->send_streams()[0].first_ssrc();
henrike@webrtc.orga7b98182014-02-21 15:51:43 +00003270
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003271 rtc::scoped_ptr<FakeAudioRenderer> renderer(new FakeAudioRenderer());
henrike@webrtc.orga7b98182014-02-21 15:51:43 +00003272 cricket::AudioOptions options;
3273 session_->SetAudioSend(send_ssrc, true, options, renderer.get());
3274 EXPECT_TRUE(renderer->sink() != NULL);
3275
3276 // Delete the |renderer| and it will trigger OnClose() to the sink, and this
3277 // will invalidate the |renderer_| pointer in the sink and prevent getting a
3278 // SetSink(NULL) callback afterwards.
3279 renderer.reset();
3280
3281 // This will trigger SetSink(NULL) if no OnClose() callback.
3282 session_->SetAudioSend(send_ssrc, true, options, NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003283}
3284
3285TEST_F(WebRtcSessionTest, SetVideoPlayout) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003286 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07003287 SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003288 CreateAndSetRemoteOfferAndLocalAnswer();
3289 cricket::FakeVideoMediaChannel* channel = media_engine_->GetVideoChannel(0);
3290 ASSERT_TRUE(channel != NULL);
3291 ASSERT_LT(0u, channel->renderers().size());
3292 EXPECT_TRUE(channel->renderers().begin()->second == NULL);
3293 ASSERT_EQ(1u, channel->recv_streams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003294 uint32_t receive_ssrc = channel->recv_streams()[0].first_ssrc();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003295 cricket::FakeVideoRenderer renderer;
3296 session_->SetVideoPlayout(receive_ssrc, true, &renderer);
3297 EXPECT_TRUE(channel->renderers().begin()->second == &renderer);
3298 session_->SetVideoPlayout(receive_ssrc, false, &renderer);
3299 EXPECT_TRUE(channel->renderers().begin()->second == NULL);
3300}
3301
3302TEST_F(WebRtcSessionTest, SetVideoSend) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003303 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07003304 SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003305 CreateAndSetRemoteOfferAndLocalAnswer();
3306 cricket::FakeVideoMediaChannel* channel = media_engine_->GetVideoChannel(0);
3307 ASSERT_TRUE(channel != NULL);
3308 ASSERT_EQ(1u, channel->send_streams().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003309 uint32_t send_ssrc = channel->send_streams()[0].first_ssrc();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003310 EXPECT_FALSE(channel->IsStreamMuted(send_ssrc));
3311 cricket::VideoOptions* options = NULL;
3312 session_->SetVideoSend(send_ssrc, false, options);
3313 EXPECT_TRUE(channel->IsStreamMuted(send_ssrc));
3314 session_->SetVideoSend(send_ssrc, true, options);
3315 EXPECT_FALSE(channel->IsStreamMuted(send_ssrc));
3316}
3317
3318TEST_F(WebRtcSessionTest, CanNotInsertDtmf) {
3319 TestCanInsertDtmf(false);
3320}
3321
3322TEST_F(WebRtcSessionTest, CanInsertDtmf) {
3323 TestCanInsertDtmf(true);
3324}
3325
3326TEST_F(WebRtcSessionTest, InsertDtmf) {
3327 // Setup
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003328 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07003329 SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003330 CreateAndSetRemoteOfferAndLocalAnswer();
3331 FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0);
3332 EXPECT_EQ(0U, channel->dtmf_info_queue().size());
3333
3334 // Insert DTMF
3335 const int expected_flags = DF_SEND;
3336 const int expected_duration = 90;
3337 session_->InsertDtmf(kAudioTrack1, 0, expected_duration);
3338 session_->InsertDtmf(kAudioTrack1, 1, expected_duration);
3339 session_->InsertDtmf(kAudioTrack1, 2, expected_duration);
3340
3341 // Verify
3342 ASSERT_EQ(3U, channel->dtmf_info_queue().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003343 const uint32_t send_ssrc = channel->send_streams()[0].first_ssrc();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003344 EXPECT_TRUE(CompareDtmfInfo(channel->dtmf_info_queue()[0], send_ssrc, 0,
3345 expected_duration, expected_flags));
3346 EXPECT_TRUE(CompareDtmfInfo(channel->dtmf_info_queue()[1], send_ssrc, 1,
3347 expected_duration, expected_flags));
3348 EXPECT_TRUE(CompareDtmfInfo(channel->dtmf_info_queue()[2], send_ssrc, 2,
3349 expected_duration, expected_flags));
3350}
3351
3352// This test verifies the |initiator| flag when session initiates the call.
3353TEST_F(WebRtcSessionTest, TestInitiatorFlagAsOriginator) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003354 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003355 EXPECT_FALSE(session_->initiator());
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003356 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003357 SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
3358 SetLocalDescriptionWithoutError(offer);
3359 EXPECT_TRUE(session_->initiator());
3360 SetRemoteDescriptionWithoutError(answer);
3361 EXPECT_TRUE(session_->initiator());
3362}
3363
3364// This test verifies the |initiator| flag when session receives the call.
3365TEST_F(WebRtcSessionTest, TestInitiatorFlagAsReceiver) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003366 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003367 EXPECT_FALSE(session_->initiator());
3368 SessionDescriptionInterface* offer = CreateRemoteOffer();
3369 SetRemoteDescriptionWithoutError(offer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003370 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003371
3372 EXPECT_FALSE(session_->initiator());
3373 SetLocalDescriptionWithoutError(answer);
3374 EXPECT_FALSE(session_->initiator());
3375}
3376
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003377// Verifing local offer and remote answer have matching m-lines as per RFC 3264.
3378TEST_F(WebRtcSessionTest, TestIncorrectMLinesInRemoteAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003379 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07003380 SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003381 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003382 SetLocalDescriptionWithoutError(offer);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003383 rtc::scoped_ptr<SessionDescriptionInterface> answer(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003384 CreateRemoteAnswer(session_->local_description()));
3385
3386 cricket::SessionDescription* answer_copy = answer->description()->Copy();
3387 answer_copy->RemoveContentByName("video");
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00003388 JsepSessionDescription* modified_answer =
3389 new JsepSessionDescription(JsepSessionDescription::kAnswer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003390
3391 EXPECT_TRUE(modified_answer->Initialize(answer_copy,
3392 answer->session_id(),
3393 answer->session_version()));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003394 SetRemoteDescriptionAnswerExpectError(kMlineMismatch, modified_answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003395
wu@webrtc.org4e393072014-04-07 17:04:35 +00003396 // Different content names.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003397 std::string sdp;
3398 EXPECT_TRUE(answer->ToString(&sdp));
3399 const std::string kAudioMid = "a=mid:audio";
3400 const std::string kAudioMidReplaceStr = "a=mid:audio_content_name";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003401 rtc::replace_substrs(kAudioMid.c_str(), kAudioMid.length(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003402 kAudioMidReplaceStr.c_str(),
3403 kAudioMidReplaceStr.length(),
3404 &sdp);
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00003405 SessionDescriptionInterface* modified_answer1 =
3406 CreateSessionDescription(JsepSessionDescription::kAnswer, sdp, NULL);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003407 SetRemoteDescriptionAnswerExpectError(kMlineMismatch, modified_answer1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003408
wu@webrtc.org4e393072014-04-07 17:04:35 +00003409 // Different media types.
3410 EXPECT_TRUE(answer->ToString(&sdp));
3411 const std::string kAudioMline = "m=audio";
3412 const std::string kAudioMlineReplaceStr = "m=video";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003413 rtc::replace_substrs(kAudioMline.c_str(), kAudioMline.length(),
wu@webrtc.org4e393072014-04-07 17:04:35 +00003414 kAudioMlineReplaceStr.c_str(),
3415 kAudioMlineReplaceStr.length(),
3416 &sdp);
3417 SessionDescriptionInterface* modified_answer2 =
3418 CreateSessionDescription(JsepSessionDescription::kAnswer, sdp, NULL);
3419 SetRemoteDescriptionAnswerExpectError(kMlineMismatch, modified_answer2);
3420
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003421 SetRemoteDescriptionWithoutError(answer.release());
3422}
3423
3424// Verifying remote offer and local answer have matching m-lines as per
3425// RFC 3264.
3426TEST_F(WebRtcSessionTest, TestIncorrectMLinesInLocalAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003427 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07003428 SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003429 SessionDescriptionInterface* offer = CreateRemoteOffer();
3430 SetRemoteDescriptionWithoutError(offer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003431 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003432
3433 cricket::SessionDescription* answer_copy = answer->description()->Copy();
3434 answer_copy->RemoveContentByName("video");
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00003435 JsepSessionDescription* modified_answer =
3436 new JsepSessionDescription(JsepSessionDescription::kAnswer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003437
3438 EXPECT_TRUE(modified_answer->Initialize(answer_copy,
3439 answer->session_id(),
3440 answer->session_version()));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003441 SetLocalDescriptionAnswerExpectError(kMlineMismatch, modified_answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003442 SetLocalDescriptionWithoutError(answer);
3443}
3444
3445// This test verifies that WebRtcSession does not start candidate allocation
3446// before SetLocalDescription is called.
3447TEST_F(WebRtcSessionTest, TestIceStartAfterSetLocalDescriptionOnly) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003448 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07003449 SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003450 SessionDescriptionInterface* offer = CreateRemoteOffer();
3451 cricket::Candidate candidate;
3452 candidate.set_component(1);
3453 JsepIceCandidate ice_candidate(kMediaContentName0, kMediaContentIndex0,
3454 candidate);
3455 EXPECT_TRUE(offer->AddCandidate(&ice_candidate));
3456 cricket::Candidate candidate1;
3457 candidate1.set_component(1);
3458 JsepIceCandidate ice_candidate1(kMediaContentName1, kMediaContentIndex1,
3459 candidate1);
3460 EXPECT_TRUE(offer->AddCandidate(&ice_candidate1));
3461 SetRemoteDescriptionWithoutError(offer);
deadbeefcbecd352015-09-23 11:50:27 -07003462 ASSERT_TRUE(session_->voice_rtp_transport_channel() != NULL);
3463 ASSERT_TRUE(session_->video_rtp_transport_channel() != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003464
3465 // Pump for 1 second and verify that no candidates are generated.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003466 rtc::Thread::Current()->ProcessMessages(1000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003467 EXPECT_TRUE(observer_.mline_0_candidates_.empty());
3468 EXPECT_TRUE(observer_.mline_1_candidates_.empty());
3469
wu@webrtc.org91053e72013-08-10 07:18:04 +00003470 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003471 SetLocalDescriptionWithoutError(answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003472 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
3473}
3474
3475// This test verifies that crypto parameter is updated in local session
3476// description as per security policy set in MediaSessionDescriptionFactory.
3477TEST_F(WebRtcSessionTest, TestCryptoAfterSetLocalDescription) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003478 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07003479 SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003480 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003481
3482 // Making sure SetLocalDescription correctly sets crypto value in
3483 // SessionDescription object after de-serialization of sdp string. The value
3484 // will be set as per MediaSessionDescriptionFactory.
3485 std::string offer_str;
3486 offer->ToString(&offer_str);
3487 SessionDescriptionInterface* jsep_offer_str =
3488 CreateSessionDescription(JsepSessionDescription::kOffer, offer_str, NULL);
3489 SetLocalDescriptionWithoutError(jsep_offer_str);
3490 EXPECT_TRUE(session_->voice_channel()->secure_required());
3491 EXPECT_TRUE(session_->video_channel()->secure_required());
3492}
3493
3494// This test verifies the crypto parameter when security is disabled.
3495TEST_F(WebRtcSessionTest, TestCryptoAfterSetLocalDescriptionWithDisabled) {
wu@webrtc.org97077a32013-10-25 21:18:33 +00003496 options_.disable_encryption = true;
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003497 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07003498 SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003499 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003500
3501 // Making sure SetLocalDescription correctly sets crypto value in
3502 // SessionDescription object after de-serialization of sdp string. The value
3503 // will be set as per MediaSessionDescriptionFactory.
3504 std::string offer_str;
3505 offer->ToString(&offer_str);
deadbeefcbecd352015-09-23 11:50:27 -07003506 SessionDescriptionInterface* jsep_offer_str =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003507 CreateSessionDescription(JsepSessionDescription::kOffer, offer_str, NULL);
3508 SetLocalDescriptionWithoutError(jsep_offer_str);
3509 EXPECT_FALSE(session_->voice_channel()->secure_required());
3510 EXPECT_FALSE(session_->video_channel()->secure_required());
3511}
3512
3513// This test verifies that an answer contains new ufrag and password if an offer
3514// with new ufrag and password is received.
3515TEST_F(WebRtcSessionTest, TestCreateAnswerWithNewUfragAndPassword) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003516 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003517 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00003518 options.recv_video = true;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003519 rtc::scoped_ptr<JsepSessionDescription> offer(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003520 CreateRemoteOffer(options));
3521 SetRemoteDescriptionWithoutError(offer.release());
3522
deadbeefab9b2d12015-10-14 11:33:11 -07003523 SendAudioVideoStream1();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003524 rtc::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00003525 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003526 SetLocalDescriptionWithoutError(answer.release());
3527
3528 // Receive an offer with new ufrag and password.
3529 options.transport_options.ice_restart = true;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003530 rtc::scoped_ptr<JsepSessionDescription> updated_offer1(
wu@webrtc.org91053e72013-08-10 07:18:04 +00003531 CreateRemoteOffer(options, session_->remote_description()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003532 SetRemoteDescriptionWithoutError(updated_offer1.release());
3533
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003534 rtc::scoped_ptr<SessionDescriptionInterface> updated_answer1(
wu@webrtc.org91053e72013-08-10 07:18:04 +00003535 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003536
3537 CompareIceUfragAndPassword(updated_answer1->description(),
3538 session_->local_description()->description(),
3539 false);
3540
3541 SetLocalDescriptionWithoutError(updated_answer1.release());
wu@webrtc.org91053e72013-08-10 07:18:04 +00003542}
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003543
wu@webrtc.org91053e72013-08-10 07:18:04 +00003544// This test verifies that an answer contains old ufrag and password if an offer
3545// with old ufrag and password is received.
3546TEST_F(WebRtcSessionTest, TestCreateAnswerWithOldUfragAndPassword) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003547 Init();
wu@webrtc.org91053e72013-08-10 07:18:04 +00003548 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00003549 options.recv_video = true;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003550 rtc::scoped_ptr<JsepSessionDescription> offer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00003551 CreateRemoteOffer(options));
3552 SetRemoteDescriptionWithoutError(offer.release());
3553
deadbeefab9b2d12015-10-14 11:33:11 -07003554 SendAudioVideoStream1();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003555 rtc::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00003556 CreateAnswer(NULL));
3557 SetLocalDescriptionWithoutError(answer.release());
3558
3559 // Receive an offer without changed ufrag or password.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003560 options.transport_options.ice_restart = false;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003561 rtc::scoped_ptr<JsepSessionDescription> updated_offer2(
wu@webrtc.org91053e72013-08-10 07:18:04 +00003562 CreateRemoteOffer(options, session_->remote_description()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003563 SetRemoteDescriptionWithoutError(updated_offer2.release());
3564
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003565 rtc::scoped_ptr<SessionDescriptionInterface> updated_answer2(
wu@webrtc.org91053e72013-08-10 07:18:04 +00003566 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003567
3568 CompareIceUfragAndPassword(updated_answer2->description(),
3569 session_->local_description()->description(),
3570 true);
3571
3572 SetLocalDescriptionWithoutError(updated_answer2.release());
3573}
3574
3575TEST_F(WebRtcSessionTest, TestSessionContentError) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003576 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07003577 SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003578 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003579 const std::string session_id_orig = offer->session_id();
3580 const std::string session_version_orig = offer->session_version();
3581 SetLocalDescriptionWithoutError(offer);
3582
3583 video_channel_ = media_engine_->GetVideoChannel(0);
3584 video_channel_->set_fail_set_send_codecs(true);
3585
deadbeefab9b2d12015-10-14 11:33:11 -07003586 SendAudioVideoStream2();
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00003587 SessionDescriptionInterface* answer =
3588 CreateRemoteAnswer(session_->local_description());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003589 SetRemoteDescriptionAnswerExpectError("ERROR_CONTENT", answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003590}
3591
3592// Runs the loopback call test with BUNDLE and STUN disabled.
3593TEST_F(WebRtcSessionTest, TestIceStatesBasic) {
3594 // Lets try with only UDP ports.
Peter Thatcher7cbd1882015-09-17 18:54:52 -07003595 allocator_->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00003596 cricket::PORTALLOCATOR_DISABLE_STUN |
3597 cricket::PORTALLOCATOR_DISABLE_RELAY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003598 TestLoopbackCall();
3599}
3600
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00003601TEST_F(WebRtcSessionTest, TestIceStatesBasicIPv6) {
Peter Thatcher7cbd1882015-09-17 18:54:52 -07003602 allocator_->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00003603 cricket::PORTALLOCATOR_DISABLE_STUN |
3604 cricket::PORTALLOCATOR_ENABLE_IPV6 |
3605 cricket::PORTALLOCATOR_DISABLE_RELAY);
3606
3607 // best connection is IPv6 since it has higher network preference.
3608 LoopbackNetworkConfiguration config;
3609 config.test_ipv6_network_ = true;
3610 config.best_connection_after_initial_ice_converged_ =
3611 LoopbackNetworkConfiguration::ExpectedBestConnection(0, 1);
3612
3613 TestLoopbackCall(config);
3614}
3615
mallinath@webrtc.orgd3dc4242014-03-01 00:05:52 +00003616// Runs the loopback call test with BUNDLE and STUN enabled.
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00003617TEST_F(WebRtcSessionTest, TestIceStatesBundle) {
Peter Thatcher7cbd1882015-09-17 18:54:52 -07003618 allocator_->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
3619 cricket::PORTALLOCATOR_DISABLE_RELAY);
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00003620 TestLoopbackCall();
3621}
3622
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003623TEST_F(WebRtcSessionTest, SetSdpFailedOnSessionError) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003624 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003625 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00003626 options.recv_video = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003627
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003628 cricket::BaseSession::Error error_code = cricket::BaseSession::ERROR_CONTENT;
3629 std::string error_code_str = "ERROR_CONTENT";
3630 std::string error_desc = "Fake session error description.";
3631 session_->SetError(error_code, error_desc);
3632
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003633 SessionDescriptionInterface* offer = CreateRemoteOffer(options);
3634 SessionDescriptionInterface* answer =
3635 CreateRemoteAnswer(offer, options);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003636
3637 std::string action;
3638 std::ostringstream session_error_msg;
3639 session_error_msg << kSessionError << error_code_str << ". ";
3640 session_error_msg << kSessionErrorDesc << error_desc << ".";
3641 SetRemoteDescriptionExpectError(action, session_error_msg.str(), offer);
3642 SetLocalDescriptionExpectError(action, session_error_msg.str(), answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003643}
3644
3645TEST_F(WebRtcSessionTest, TestRtpDataChannel) {
3646 constraints_.reset(new FakeConstraints());
3647 constraints_->AddOptional(
3648 webrtc::MediaConstraintsInterface::kEnableRtpDataChannels, true);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003649 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003650
3651 SetLocalDescriptionWithDataChannel();
3652 EXPECT_EQ(cricket::DCT_RTP, data_engine_->last_channel_type());
3653}
3654
Henrik Boström87713d02015-08-25 09:53:21 +02003655TEST_P(WebRtcSessionTest, TestRtpDataChannelConstraintTakesPrecedence) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003656 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003657
3658 constraints_.reset(new FakeConstraints());
3659 constraints_->AddOptional(
3660 webrtc::MediaConstraintsInterface::kEnableRtpDataChannels, true);
wu@webrtc.org97077a32013-10-25 21:18:33 +00003661 options_.disable_sctp_data_channels = false;
3662
Henrik Boström87713d02015-08-25 09:53:21 +02003663 InitWithDtls(GetParam());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003664
3665 SetLocalDescriptionWithDataChannel();
3666 EXPECT_EQ(cricket::DCT_RTP, data_engine_->last_channel_type());
3667}
3668
Henrik Boström87713d02015-08-25 09:53:21 +02003669TEST_P(WebRtcSessionTest, TestCreateOfferWithSctpEnabledWithoutStreams) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003670 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
wu@webrtc.org967bfff2013-09-19 05:49:50 +00003671
Henrik Boström87713d02015-08-25 09:53:21 +02003672 InitWithDtls(GetParam());
sergeyu@chromium.orga59696b2013-09-13 23:48:58 +00003673
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003674 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
sergeyu@chromium.orga59696b2013-09-13 23:48:58 +00003675 EXPECT_TRUE(offer->description()->GetContentByName("data") == NULL);
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00003676 EXPECT_TRUE(offer->description()->GetTransportInfoByName("data") == NULL);
3677}
3678
Henrik Boström87713d02015-08-25 09:53:21 +02003679TEST_P(WebRtcSessionTest, TestCreateAnswerWithSctpInOfferAndNoStreams) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003680 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00003681 SetFactoryDtlsSrtp();
Henrik Boström87713d02015-08-25 09:53:21 +02003682 InitWithDtls(GetParam());
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00003683
3684 // Create remote offer with SCTP.
3685 cricket::MediaSessionOptions options;
3686 options.data_channel_type = cricket::DCT_SCTP;
3687 JsepSessionDescription* offer =
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003688 CreateRemoteOffer(options, cricket::SEC_DISABLED);
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00003689 SetRemoteDescriptionWithoutError(offer);
3690
3691 // Verifies the answer contains SCTP.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003692 rtc::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00003693 EXPECT_TRUE(answer != NULL);
3694 EXPECT_TRUE(answer->description()->GetContentByName("data") != NULL);
3695 EXPECT_TRUE(answer->description()->GetTransportInfoByName("data") != NULL);
sergeyu@chromium.orga59696b2013-09-13 23:48:58 +00003696}
3697
Henrik Boström87713d02015-08-25 09:53:21 +02003698TEST_P(WebRtcSessionTest, TestSctpDataChannelWithoutDtls) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003699 constraints_.reset(new FakeConstraints());
3700 constraints_->AddOptional(
sergeyu@chromium.orga59696b2013-09-13 23:48:58 +00003701 webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, false);
Henrik Boström87713d02015-08-25 09:53:21 +02003702 InitWithDtls(GetParam());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003703
3704 SetLocalDescriptionWithDataChannel();
3705 EXPECT_EQ(cricket::DCT_NONE, data_engine_->last_channel_type());
3706}
3707
Henrik Boström87713d02015-08-25 09:53:21 +02003708TEST_P(WebRtcSessionTest, TestSctpDataChannelWithDtls) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003709 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003710
Henrik Boström87713d02015-08-25 09:53:21 +02003711 InitWithDtls(GetParam());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003712
3713 SetLocalDescriptionWithDataChannel();
3714 EXPECT_EQ(cricket::DCT_SCTP, data_engine_->last_channel_type());
3715}
wu@webrtc.org91053e72013-08-10 07:18:04 +00003716
Henrik Boström87713d02015-08-25 09:53:21 +02003717TEST_P(WebRtcSessionTest, TestDisableSctpDataChannels) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003718 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
wu@webrtc.org97077a32013-10-25 21:18:33 +00003719 options_.disable_sctp_data_channels = true;
Henrik Boström87713d02015-08-25 09:53:21 +02003720 InitWithDtls(GetParam());
wu@webrtc.org97077a32013-10-25 21:18:33 +00003721
3722 SetLocalDescriptionWithDataChannel();
3723 EXPECT_EQ(cricket::DCT_NONE, data_engine_->last_channel_type());
3724}
3725
Henrik Boström87713d02015-08-25 09:53:21 +02003726TEST_P(WebRtcSessionTest, TestSctpDataChannelSendPortParsing) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003727 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00003728 const int new_send_port = 9998;
3729 const int new_recv_port = 7775;
3730
Henrik Boström87713d02015-08-25 09:53:21 +02003731 InitWithDtls(GetParam());
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00003732 SetFactoryDtlsSrtp();
3733
3734 // By default, don't actually add the codecs to desc_factory_; they don't
3735 // actually get serialized for SCTP in BuildMediaDescription(). Instead,
3736 // let the session description get parsed. That'll get the proper codecs
3737 // into the stream.
3738 cricket::MediaSessionOptions options;
3739 JsepSessionDescription* offer = CreateRemoteOfferWithSctpPort(
3740 "stream1", new_send_port, options);
3741
3742 // SetRemoteDescription will take the ownership of the offer.
3743 SetRemoteDescriptionWithoutError(offer);
3744
3745 SessionDescriptionInterface* answer = ChangeSDPSctpPort(
3746 new_recv_port, CreateAnswer(NULL));
3747 ASSERT_TRUE(answer != NULL);
3748
3749 // Now set the local description, which'll take ownership of the answer.
3750 SetLocalDescriptionWithoutError(answer);
3751
3752 // TEST PLAN: Set the port number to something new, set it in the SDP,
3753 // and pass it all the way down.
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00003754 EXPECT_EQ(cricket::DCT_SCTP, data_engine_->last_channel_type());
deadbeefab9b2d12015-10-14 11:33:11 -07003755 CreateDataChannel();
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00003756
3757 cricket::FakeDataMediaChannel* ch = data_engine_->GetChannel(0);
3758 int portnum = -1;
3759 ASSERT_TRUE(ch != NULL);
3760 ASSERT_EQ(1UL, ch->send_codecs().size());
3761 EXPECT_EQ(cricket::kGoogleSctpDataCodecId, ch->send_codecs()[0].id);
Donald Curtisd4f769d2015-05-28 09:48:21 -07003762 EXPECT_EQ(0, strcmp(cricket::kGoogleSctpDataCodecName,
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00003763 ch->send_codecs()[0].name.c_str()));
3764 EXPECT_TRUE(ch->send_codecs()[0].GetParam(cricket::kCodecParamPort,
3765 &portnum));
3766 EXPECT_EQ(new_send_port, portnum);
3767
3768 ASSERT_EQ(1UL, ch->recv_codecs().size());
3769 EXPECT_EQ(cricket::kGoogleSctpDataCodecId, ch->recv_codecs()[0].id);
Donald Curtisd4f769d2015-05-28 09:48:21 -07003770 EXPECT_EQ(0, strcmp(cricket::kGoogleSctpDataCodecName,
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00003771 ch->recv_codecs()[0].name.c_str()));
3772 EXPECT_TRUE(ch->recv_codecs()[0].GetParam(cricket::kCodecParamPort,
3773 &portnum));
3774 EXPECT_EQ(new_recv_port, portnum);
3775}
3776
deadbeefab9b2d12015-10-14 11:33:11 -07003777// Verifies that when a session's DataChannel receives an OPEN message,
3778// WebRtcSession signals the DataChannel creation request with the expected
3779// config.
3780TEST_P(WebRtcSessionTest, TestSctpDataChannelOpenMessage) {
3781 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
3782
3783 InitWithDtls(GetParam());
3784
3785 SetLocalDescriptionWithDataChannel();
3786 EXPECT_EQ(cricket::DCT_SCTP, data_engine_->last_channel_type());
3787
3788 webrtc::DataChannelInit config;
3789 config.id = 1;
3790 rtc::Buffer payload;
3791 webrtc::WriteDataChannelOpenMessage("a", config, &payload);
3792 cricket::ReceiveDataParams params;
3793 params.ssrc = config.id;
3794 params.type = cricket::DMT_CONTROL;
3795
3796 cricket::DataChannel* data_channel = session_->data_channel();
3797 data_channel->SignalDataReceived(data_channel, params, payload);
3798
3799 EXPECT_EQ("a", last_data_channel_label_);
3800 EXPECT_EQ(config.id, last_data_channel_config_.id);
3801 EXPECT_FALSE(last_data_channel_config_.negotiated);
3802 EXPECT_EQ(webrtc::InternalDataChannelInit::kAcker,
3803 last_data_channel_config_.open_handshake_role);
3804}
3805
3806TEST_P(WebRtcSessionTest, TestUsesProvidedCertificate) {
Henrik Boströmd8281982015-08-27 10:12:24 +02003807 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
3808 FakeDtlsIdentityStore::GenerateCertificate();
3809
3810 PeerConnectionInterface::RTCConfiguration configuration;
3811 configuration.certificates.push_back(certificate);
3812 Init(nullptr, configuration);
3813 EXPECT_TRUE_WAIT(!session_->waiting_for_certificate_for_testing(), 1000);
3814
3815 EXPECT_EQ(session_->certificate_for_testing(), certificate);
3816}
wu@webrtc.org91053e72013-08-10 07:18:04 +00003817
Henrik Boström87713d02015-08-25 09:53:21 +02003818// Verifies that CreateOffer succeeds when CreateOffer is called before async
3819// identity generation is finished (even if a certificate is provided this is
3820// an async op).
3821TEST_P(WebRtcSessionTest, TestCreateOfferBeforeIdentityRequestReturnSuccess) {
3822 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
3823 InitWithDtls(GetParam());
3824
Henrik Boströmd8281982015-08-27 10:12:24 +02003825 EXPECT_TRUE(session_->waiting_for_certificate_for_testing());
deadbeefab9b2d12015-10-14 11:33:11 -07003826 SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003827 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
3828
wu@webrtc.org91053e72013-08-10 07:18:04 +00003829 EXPECT_TRUE(offer != NULL);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003830 VerifyNoCryptoParams(offer->description(), true);
3831 VerifyFingerprintStatus(offer->description(), true);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003832}
3833
3834// Verifies that CreateAnswer succeeds when CreateOffer is called before async
Henrik Boström87713d02015-08-25 09:53:21 +02003835// identity generation is finished (even if a certificate is provided this is
3836// an async op).
3837TEST_P(WebRtcSessionTest, TestCreateAnswerBeforeIdentityRequestReturnSuccess) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003838 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
Henrik Boström87713d02015-08-25 09:53:21 +02003839 InitWithDtls(GetParam());
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003840 SetFactoryDtlsSrtp();
wu@webrtc.org91053e72013-08-10 07:18:04 +00003841
3842 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00003843 options.recv_video = true;
wu@webrtc.org91053e72013-08-10 07:18:04 +00003844 scoped_ptr<JsepSessionDescription> offer(
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003845 CreateRemoteOffer(options, cricket::SEC_DISABLED));
wu@webrtc.org91053e72013-08-10 07:18:04 +00003846 ASSERT_TRUE(offer.get() != NULL);
3847 SetRemoteDescriptionWithoutError(offer.release());
3848
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003849 rtc::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
wu@webrtc.org91053e72013-08-10 07:18:04 +00003850 EXPECT_TRUE(answer != NULL);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003851 VerifyNoCryptoParams(answer->description(), true);
3852 VerifyFingerprintStatus(answer->description(), true);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003853}
3854
3855// Verifies that CreateOffer succeeds when CreateOffer is called after async
Henrik Boström87713d02015-08-25 09:53:21 +02003856// identity generation is finished (even if a certificate is provided this is
3857// an async op).
3858TEST_P(WebRtcSessionTest, TestCreateOfferAfterIdentityRequestReturnSuccess) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003859 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
Henrik Boström87713d02015-08-25 09:53:21 +02003860 InitWithDtls(GetParam());
wu@webrtc.org91053e72013-08-10 07:18:04 +00003861
Henrik Boströmd8281982015-08-27 10:12:24 +02003862 EXPECT_TRUE_WAIT(!session_->waiting_for_certificate_for_testing(), 1000);
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003863
3864 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
wu@webrtc.org91053e72013-08-10 07:18:04 +00003865 EXPECT_TRUE(offer != NULL);
3866}
3867
3868// Verifies that CreateOffer fails when CreateOffer is called after async
3869// identity generation fails.
3870TEST_F(WebRtcSessionTest, TestCreateOfferAfterIdentityRequestReturnFailure) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003871 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
Henrik Boström87713d02015-08-25 09:53:21 +02003872 InitWithDtlsIdentityGenFail();
wu@webrtc.org91053e72013-08-10 07:18:04 +00003873
Henrik Boströmd8281982015-08-27 10:12:24 +02003874 EXPECT_TRUE_WAIT(!session_->waiting_for_certificate_for_testing(), 1000);
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003875
3876 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
wu@webrtc.org91053e72013-08-10 07:18:04 +00003877 EXPECT_TRUE(offer == NULL);
3878}
3879
3880// Verifies that CreateOffer succeeds when Multiple CreateOffer calls are made
3881// before async identity generation is finished.
Henrik Boström87713d02015-08-25 09:53:21 +02003882TEST_P(WebRtcSessionTest,
wu@webrtc.org91053e72013-08-10 07:18:04 +00003883 TestMultipleCreateOfferBeforeIdentityRequestReturnSuccess) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003884 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
deadbeefcbecd352015-09-23 11:50:27 -07003885 VerifyMultipleAsyncCreateDescription(GetParam(),
3886 CreateSessionDescriptionRequest::kOffer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003887}
3888
3889// Verifies that CreateOffer fails when Multiple CreateOffer calls are made
3890// before async identity generation fails.
3891TEST_F(WebRtcSessionTest,
3892 TestMultipleCreateOfferBeforeIdentityRequestReturnFailure) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003893 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
Henrik Boström87713d02015-08-25 09:53:21 +02003894 VerifyMultipleAsyncCreateDescriptionIdentityGenFailure(
3895 CreateSessionDescriptionRequest::kOffer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003896}
3897
3898// Verifies that CreateAnswer succeeds when Multiple CreateAnswer calls are made
3899// before async identity generation is finished.
Henrik Boström87713d02015-08-25 09:53:21 +02003900TEST_P(WebRtcSessionTest,
wu@webrtc.org91053e72013-08-10 07:18:04 +00003901 TestMultipleCreateAnswerBeforeIdentityRequestReturnSuccess) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003902 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003903 VerifyMultipleAsyncCreateDescription(
Henrik Boström87713d02015-08-25 09:53:21 +02003904 GetParam(), CreateSessionDescriptionRequest::kAnswer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003905}
3906
3907// Verifies that CreateAnswer fails when Multiple CreateAnswer calls are made
3908// before async identity generation fails.
3909TEST_F(WebRtcSessionTest,
3910 TestMultipleCreateAnswerBeforeIdentityRequestReturnFailure) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003911 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
Henrik Boström87713d02015-08-25 09:53:21 +02003912 VerifyMultipleAsyncCreateDescriptionIdentityGenFailure(
3913 CreateSessionDescriptionRequest::kAnswer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003914}
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00003915
3916// Verifies that setRemoteDescription fails when DTLS is disabled and the remote
3917// offer has no SDES crypto but only DTLS fingerprint.
3918TEST_F(WebRtcSessionTest, TestSetRemoteOfferFailIfDtlsDisabledAndNoCrypto) {
3919 // Init without DTLS.
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003920 Init();
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00003921 // Create a remote offer with secured transport disabled.
3922 cricket::MediaSessionOptions options;
3923 JsepSessionDescription* offer(CreateRemoteOffer(
3924 options, cricket::SEC_DISABLED));
3925 // Adds a DTLS fingerprint to the remote offer.
3926 cricket::SessionDescription* sdp = offer->description();
3927 TransportInfo* audio = sdp->GetTransportInfoByName("audio");
3928 ASSERT_TRUE(audio != NULL);
3929 ASSERT_TRUE(audio->description.identity_fingerprint.get() == NULL);
3930 audio->description.identity_fingerprint.reset(
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003931 rtc::SSLFingerprint::CreateFromRfc4572(
3932 rtc::DIGEST_SHA_256, kFakeDtlsFingerprint));
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003933 SetRemoteDescriptionOfferExpectError(kSdpWithoutSdesCrypto,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003934 offer);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00003935}
3936
wu@webrtc.orgde305012013-10-31 15:40:38 +00003937// This test verifies DSCP is properly applied on the media channels.
3938TEST_F(WebRtcSessionTest, TestDscpConstraint) {
3939 constraints_.reset(new FakeConstraints());
3940 constraints_->AddOptional(
3941 webrtc::MediaConstraintsInterface::kEnableDscp, true);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003942 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07003943 SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003944 SessionDescriptionInterface* offer = CreateOffer();
wu@webrtc.orgde305012013-10-31 15:40:38 +00003945
3946 SetLocalDescriptionWithoutError(offer);
3947
3948 video_channel_ = media_engine_->GetVideoChannel(0);
3949 voice_channel_ = media_engine_->GetVoiceChannel(0);
3950
3951 ASSERT_TRUE(video_channel_ != NULL);
3952 ASSERT_TRUE(voice_channel_ != NULL);
solenberg66f43392015-09-09 01:36:22 -07003953 const cricket::AudioOptions& audio_options = voice_channel_->options();
3954 const cricket::VideoOptions& video_options = video_channel_->options();
wu@webrtc.orgde305012013-10-31 15:40:38 +00003955 EXPECT_TRUE(audio_options.dscp.IsSet());
3956 EXPECT_TRUE(audio_options.dscp.GetWithDefaultIfUnset(false));
3957 EXPECT_TRUE(video_options.dscp.IsSet());
3958 EXPECT_TRUE(video_options.dscp.GetWithDefaultIfUnset(false));
3959}
3960
henrike@webrtc.org6e3dbc22014-03-25 17:09:47 +00003961TEST_F(WebRtcSessionTest, TestSuspendBelowMinBitrateConstraint) {
3962 constraints_.reset(new FakeConstraints());
3963 constraints_->AddOptional(
3964 webrtc::MediaConstraintsInterface::kEnableVideoSuspendBelowMinBitrate,
3965 true);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003966 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07003967 SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003968 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org6e3dbc22014-03-25 17:09:47 +00003969
3970 SetLocalDescriptionWithoutError(offer);
3971
3972 video_channel_ = media_engine_->GetVideoChannel(0);
3973
3974 ASSERT_TRUE(video_channel_ != NULL);
solenberg66f43392015-09-09 01:36:22 -07003975 const cricket::VideoOptions& video_options = video_channel_->options();
henrike@webrtc.org6e3dbc22014-03-25 17:09:47 +00003976 EXPECT_TRUE(
3977 video_options.suspend_below_min_bitrate.GetWithDefaultIfUnset(false));
3978}
3979
buildbot@webrtc.org53df88c2014-08-07 22:46:01 +00003980TEST_F(WebRtcSessionTest, TestNumUnsignalledRecvStreamsConstraint) {
3981 // Number of unsignalled receiving streams should be between 0 and
3982 // kMaxUnsignalledRecvStreams.
3983 SetAndVerifyNumUnsignalledRecvStreams(10, 10);
3984 SetAndVerifyNumUnsignalledRecvStreams(kMaxUnsignalledRecvStreams + 1,
3985 kMaxUnsignalledRecvStreams);
3986 SetAndVerifyNumUnsignalledRecvStreams(-1, 0);
3987}
3988
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +00003989TEST_F(WebRtcSessionTest, TestCombinedAudioVideoBweConstraint) {
3990 constraints_.reset(new FakeConstraints());
3991 constraints_->AddOptional(
3992 webrtc::MediaConstraintsInterface::kCombinedAudioVideoBwe,
3993 true);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003994 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07003995 SendAudioVideoStream1();
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +00003996 SessionDescriptionInterface* offer = CreateOffer();
3997
3998 SetLocalDescriptionWithoutError(offer);
3999
4000 voice_channel_ = media_engine_->GetVoiceChannel(0);
4001
4002 ASSERT_TRUE(voice_channel_ != NULL);
solenberg66f43392015-09-09 01:36:22 -07004003 const cricket::AudioOptions& audio_options = voice_channel_->options();
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +00004004 EXPECT_TRUE(
4005 audio_options.combined_audio_video_bwe.GetWithDefaultIfUnset(false));
4006}
4007
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00004008// Tests that we can renegotiate new media content with ICE candidates in the
4009// new remote SDP.
Henrik Boström87713d02015-08-25 09:53:21 +02004010TEST_P(WebRtcSessionTest, TestRenegotiateNewMediaWithCandidatesInSdp) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00004011 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
Henrik Boström87713d02015-08-25 09:53:21 +02004012 InitWithDtls(GetParam());
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00004013 SetFactoryDtlsSrtp();
4014
deadbeefab9b2d12015-10-14 11:33:11 -07004015 SendAudioOnlyStream2();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00004016 SessionDescriptionInterface* offer = CreateOffer();
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00004017 SetLocalDescriptionWithoutError(offer);
4018
4019 SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
4020 SetRemoteDescriptionWithoutError(answer);
4021
4022 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00004023 options.recv_video = true;
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00004024 offer = CreateRemoteOffer(options, cricket::SEC_DISABLED);
4025
4026 cricket::Candidate candidate1;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00004027 candidate1.set_address(rtc::SocketAddress("1.1.1.1", 5000));
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00004028 candidate1.set_component(1);
4029 JsepIceCandidate ice_candidate(kMediaContentName1, kMediaContentIndex1,
4030 candidate1);
4031 EXPECT_TRUE(offer->AddCandidate(&ice_candidate));
4032 SetRemoteDescriptionWithoutError(offer);
4033
4034 answer = CreateAnswer(NULL);
4035 SetLocalDescriptionWithoutError(answer);
4036}
4037
4038// Tests that we can renegotiate new media content with ICE candidates separated
4039// from the remote SDP.
Henrik Boström87713d02015-08-25 09:53:21 +02004040TEST_P(WebRtcSessionTest, TestRenegotiateNewMediaWithCandidatesSeparated) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00004041 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
Henrik Boström87713d02015-08-25 09:53:21 +02004042 InitWithDtls(GetParam());
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00004043 SetFactoryDtlsSrtp();
4044
deadbeefab9b2d12015-10-14 11:33:11 -07004045 SendAudioOnlyStream2();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00004046 SessionDescriptionInterface* offer = CreateOffer();
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00004047 SetLocalDescriptionWithoutError(offer);
4048
4049 SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
4050 SetRemoteDescriptionWithoutError(answer);
4051
4052 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00004053 options.recv_video = true;
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00004054 offer = CreateRemoteOffer(options, cricket::SEC_DISABLED);
4055 SetRemoteDescriptionWithoutError(offer);
4056
4057 cricket::Candidate candidate1;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00004058 candidate1.set_address(rtc::SocketAddress("1.1.1.1", 5000));
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00004059 candidate1.set_component(1);
4060 JsepIceCandidate ice_candidate(kMediaContentName1, kMediaContentIndex1,
4061 candidate1);
4062 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate));
4063
4064 answer = CreateAnswer(NULL);
4065 SetLocalDescriptionWithoutError(answer);
4066}
changbin.shao@webrtc.org2d25b442015-03-16 04:14:34 +00004067// Tests that RTX codec is removed from the answer when it isn't supported
4068// by local side.
4069TEST_F(WebRtcSessionTest, TestRtxRemovedByCreateAnswer) {
4070 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07004071 SendAudioVideoStream1();
changbin.shao@webrtc.org2d25b442015-03-16 04:14:34 +00004072 std::string offer_sdp(kSdpWithRtx);
4073
4074 SessionDescriptionInterface* offer =
4075 CreateSessionDescription(JsepSessionDescription::kOffer, offer_sdp, NULL);
4076 EXPECT_TRUE(offer->ToString(&offer_sdp));
4077
4078 // Offer SDP contains the RTX codec.
4079 EXPECT_TRUE(offer_sdp.find("rtx") != std::string::npos);
4080 SetRemoteDescriptionWithoutError(offer);
4081
4082 SessionDescriptionInterface* answer = CreateAnswer(NULL);
4083 std::string answer_sdp;
4084 answer->ToString(&answer_sdp);
4085 // Answer SDP removes the unsupported RTX codec.
4086 EXPECT_TRUE(answer_sdp.find("rtx") == std::string::npos);
4087 SetLocalDescriptionWithoutError(answer);
4088}
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00004089
guoweis@webrtc.org4f852882015-03-12 20:09:44 +00004090// This verifies that the voice channel after bundle has both options from video
4091// and voice channels.
4092TEST_F(WebRtcSessionTest, TestSetSocketOptionBeforeBundle) {
4093 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyBalanced);
deadbeefab9b2d12015-10-14 11:33:11 -07004094 SendAudioVideoStream1();
guoweis@webrtc.org4f852882015-03-12 20:09:44 +00004095
4096 PeerConnectionInterface::RTCOfferAnswerOptions options;
4097 options.use_rtp_mux = true;
4098
4099 SessionDescriptionInterface* offer = CreateOffer(options);
4100 SetLocalDescriptionWithoutError(offer);
4101
4102 session_->video_channel()->SetOption(cricket::BaseChannel::ST_RTP,
4103 rtc::Socket::Option::OPT_SNDBUF, 4000);
4104
4105 session_->voice_channel()->SetOption(cricket::BaseChannel::ST_RTP,
4106 rtc::Socket::Option::OPT_RCVBUF, 8000);
4107
4108 int option_val;
deadbeefcbecd352015-09-23 11:50:27 -07004109 EXPECT_TRUE(session_->video_rtp_transport_channel()->GetOption(
guoweis@webrtc.org4f852882015-03-12 20:09:44 +00004110 rtc::Socket::Option::OPT_SNDBUF, &option_val));
4111 EXPECT_EQ(4000, option_val);
deadbeefcbecd352015-09-23 11:50:27 -07004112 EXPECT_FALSE(session_->voice_rtp_transport_channel()->GetOption(
guoweis@webrtc.org4f852882015-03-12 20:09:44 +00004113 rtc::Socket::Option::OPT_SNDBUF, &option_val));
4114
deadbeefcbecd352015-09-23 11:50:27 -07004115 EXPECT_TRUE(session_->voice_rtp_transport_channel()->GetOption(
guoweis@webrtc.org4f852882015-03-12 20:09:44 +00004116 rtc::Socket::Option::OPT_RCVBUF, &option_val));
4117 EXPECT_EQ(8000, option_val);
deadbeefcbecd352015-09-23 11:50:27 -07004118 EXPECT_FALSE(session_->video_rtp_transport_channel()->GetOption(
guoweis@webrtc.org4f852882015-03-12 20:09:44 +00004119 rtc::Socket::Option::OPT_RCVBUF, &option_val));
4120
deadbeefcbecd352015-09-23 11:50:27 -07004121 EXPECT_NE(session_->voice_rtp_transport_channel(),
4122 session_->video_rtp_transport_channel());
guoweis@webrtc.org4f852882015-03-12 20:09:44 +00004123
deadbeefab9b2d12015-10-14 11:33:11 -07004124 SendAudioVideoStream2();
guoweis@webrtc.org4f852882015-03-12 20:09:44 +00004125 SessionDescriptionInterface* answer =
4126 CreateRemoteAnswer(session_->local_description());
4127 SetRemoteDescriptionWithoutError(answer);
4128
deadbeefcbecd352015-09-23 11:50:27 -07004129 EXPECT_TRUE(session_->voice_rtp_transport_channel()->GetOption(
guoweis@webrtc.org4f852882015-03-12 20:09:44 +00004130 rtc::Socket::Option::OPT_SNDBUF, &option_val));
4131 EXPECT_EQ(4000, option_val);
4132
deadbeefcbecd352015-09-23 11:50:27 -07004133 EXPECT_TRUE(session_->voice_rtp_transport_channel()->GetOption(
guoweis@webrtc.org4f852882015-03-12 20:09:44 +00004134 rtc::Socket::Option::OPT_RCVBUF, &option_val));
4135 EXPECT_EQ(8000, option_val);
4136}
4137
tommi0f620f42015-07-09 03:25:02 -07004138// Test creating a session, request multiple offers, destroy the session
4139// and make sure we got success/failure callbacks for all of the requests.
4140// Background: crbug.com/507307
4141TEST_F(WebRtcSessionTest, CreateOffersAndShutdown) {
4142 Init();
4143
4144 rtc::scoped_refptr<WebRtcSessionCreateSDPObserverForTest> observers[100];
4145 PeerConnectionInterface::RTCOfferAnswerOptions options;
4146 options.offer_to_receive_audio =
4147 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
deadbeefab9b2d12015-10-14 11:33:11 -07004148 cricket::MediaSessionOptions session_options;
4149 session_options.recv_audio = true;
tommi0f620f42015-07-09 03:25:02 -07004150
4151 for (auto& o : observers) {
4152 o = new WebRtcSessionCreateSDPObserverForTest();
deadbeefab9b2d12015-10-14 11:33:11 -07004153 session_->CreateOffer(o, options, session_options);
tommi0f620f42015-07-09 03:25:02 -07004154 }
4155
4156 session_.reset();
4157
tommi0f620f42015-07-09 03:25:02 -07004158 for (auto& o : observers) {
4159 // We expect to have received a notification now even if the session was
4160 // terminated. The offer creation may or may not have succeeded, but we
4161 // must have received a notification which, so the only invalid state
4162 // is kInit.
4163 EXPECT_NE(WebRtcSessionCreateSDPObserverForTest::kInit, o->state());
4164 }
4165}
4166
henrike@webrtc.org28e20752013-07-10 00:45:36 +00004167// TODO(bemasc): Add a TestIceStatesBundle with BUNDLE enabled. That test
4168// currently fails because upon disconnection and reconnection OnIceComplete is
4169// called more than once without returning to IceGatheringGathering.
Henrik Boström87713d02015-08-25 09:53:21 +02004170
deadbeefcbecd352015-09-23 11:50:27 -07004171INSTANTIATE_TEST_CASE_P(WebRtcSessionTests,
4172 WebRtcSessionTest,
4173 testing::Values(ALREADY_GENERATED,
4174 DTLS_IDENTITY_STORE));