blob: b30ab3ef13a492c436b9637be7038fe620ae43c8 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
2 * libjingle
3 * Copyright 2012, Google Inc.
4 *
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
28#include "talk/app/webrtc/audiotrack.h"
29#include "talk/app/webrtc/jsepicecandidate.h"
30#include "talk/app/webrtc/jsepsessiondescription.h"
31#include "talk/app/webrtc/mediastreamsignaling.h"
32#include "talk/app/webrtc/streamcollection.h"
33#include "talk/app/webrtc/videotrack.h"
34#include "talk/app/webrtc/test/fakeconstraints.h"
wu@webrtc.org91053e72013-08-10 07:18:04 +000035#include "talk/app/webrtc/test/fakedtlsidentityservice.h"
36#include "talk/app/webrtc/test/fakemediastreamsignaling.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000037#include "talk/app/webrtc/webrtcsession.h"
wu@webrtc.org91053e72013-08-10 07:18:04 +000038#include "talk/app/webrtc/webrtcsessiondescriptionfactory.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000039#include "talk/base/fakenetwork.h"
40#include "talk/base/firewallsocketserver.h"
41#include "talk/base/gunit.h"
42#include "talk/base/logging.h"
43#include "talk/base/network.h"
44#include "talk/base/physicalsocketserver.h"
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +000045#include "talk/base/ssladapter.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000046#include "talk/base/sslstreamadapter.h"
47#include "talk/base/stringutils.h"
48#include "talk/base/thread.h"
49#include "talk/base/virtualsocketserver.h"
50#include "talk/media/base/fakemediaengine.h"
51#include "talk/media/base/fakevideorenderer.h"
52#include "talk/media/base/mediachannel.h"
53#include "talk/media/devices/fakedevicemanager.h"
54#include "talk/p2p/base/stunserver.h"
55#include "talk/p2p/base/teststunserver.h"
56#include "talk/p2p/client/basicportallocator.h"
57#include "talk/session/media/channelmanager.h"
58#include "talk/session/media/mediasession.h"
59
60#define MAYBE_SKIP_TEST(feature) \
61 if (!(feature())) { \
62 LOG(LS_INFO) << "Feature disabled... skipping"; \
63 return; \
64 }
65
66using cricket::BaseSession;
67using cricket::DF_PLAY;
68using cricket::DF_SEND;
69using cricket::FakeVoiceMediaChannel;
70using cricket::NS_GINGLE_P2P;
71using cricket::NS_JINGLE_ICE_UDP;
72using cricket::TransportInfo;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000073using talk_base::SocketAddress;
74using talk_base::scoped_ptr;
75using webrtc::CreateSessionDescription;
wu@webrtc.org91053e72013-08-10 07:18:04 +000076using webrtc::CreateSessionDescriptionObserver;
77using webrtc::CreateSessionDescriptionRequest;
78using webrtc::DTLSIdentityRequestObserver;
79using webrtc::DTLSIdentityServiceInterface;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000080using webrtc::FakeConstraints;
81using webrtc::IceCandidateCollection;
82using webrtc::JsepIceCandidate;
83using webrtc::JsepSessionDescription;
wu@webrtc.org97077a32013-10-25 21:18:33 +000084using webrtc::PeerConnectionFactoryInterface;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000085using webrtc::PeerConnectionInterface;
86using webrtc::SessionDescriptionInterface;
87using webrtc::StreamCollection;
wu@webrtc.org91053e72013-08-10 07:18:04 +000088using webrtc::WebRtcSession;
wu@webrtc.org364f2042013-11-20 21:49:41 +000089using webrtc::kBundleWithoutRtcpMux;
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +000090using webrtc::kCreateChannelFailed;
91using webrtc::kInvalidSdp;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000092using webrtc::kMlineMismatch;
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +000093using webrtc::kPushDownTDFailed;
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +000094using webrtc::kSdpWithoutIceUfragPwd;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +000095using webrtc::kSdpWithoutDtlsFingerprint;
96using webrtc::kSdpWithoutSdesCrypto;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000097using webrtc::kSessionError;
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +000098using webrtc::kSessionErrorDesc;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000099
wu@webrtc.org364f2042013-11-20 21:49:41 +0000100static const int kClientAddrPort = 0;
101static const char kClientAddrHost1[] = "11.11.11.11";
102static const char kClientAddrHost2[] = "22.22.22.22";
103static const char kStunAddrHost[] = "99.99.99.1";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000104
105static const char kSessionVersion[] = "1";
106
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000107// Media index of candidates belonging to the first media content.
108static const int kMediaContentIndex0 = 0;
109static const char kMediaContentName0[] = "audio";
110
111// Media index of candidates belonging to the second media content.
112static const int kMediaContentIndex1 = 1;
113static const char kMediaContentName1[] = "video";
114
115static const int kIceCandidatesTimeout = 10000;
116
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +0000117static const char kFakeDtlsFingerprint[] =
118 "BB:CD:72:F7:2F:D0:BA:43:F3:68:B1:0C:23:72:B6:4A:"
119 "0F:DE:34:06:BC:E0:FE:01:BC:73:C8:6D:F4:65:D5:24";
120
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000121// Add some extra |newlines| to the |message| after |line|.
122static void InjectAfter(const std::string& line,
123 const std::string& newlines,
124 std::string* message) {
125 const std::string tmp = line + newlines;
126 talk_base::replace_substrs(line.c_str(), line.length(),
127 tmp.c_str(), tmp.length(), message);
128}
129
130class MockIceObserver : public webrtc::IceObserver {
131 public:
132 MockIceObserver()
133 : oncandidatesready_(false),
134 ice_connection_state_(PeerConnectionInterface::kIceConnectionNew),
135 ice_gathering_state_(PeerConnectionInterface::kIceGatheringNew) {
136 }
137
138 virtual void OnIceConnectionChange(
139 PeerConnectionInterface::IceConnectionState new_state) {
140 ice_connection_state_ = new_state;
141 }
142 virtual void OnIceGatheringChange(
143 PeerConnectionInterface::IceGatheringState new_state) {
144 // We can never transition back to "new".
145 EXPECT_NE(PeerConnectionInterface::kIceGatheringNew, new_state);
146 ice_gathering_state_ = new_state;
147
148 // oncandidatesready_ really means "ICE gathering is complete".
149 // This if statement ensures that this value remains correct when we
150 // transition from kIceGatheringComplete to kIceGatheringGathering.
151 if (new_state == PeerConnectionInterface::kIceGatheringGathering) {
152 oncandidatesready_ = false;
153 }
154 }
155
156 // Found a new candidate.
157 virtual void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) {
wu@webrtc.org364f2042013-11-20 21:49:41 +0000158 switch (candidate->sdp_mline_index()) {
159 case kMediaContentIndex0:
160 mline_0_candidates_.push_back(candidate->candidate());
161 break;
162 case kMediaContentIndex1:
163 mline_1_candidates_.push_back(candidate->candidate());
164 break;
165 default:
166 ASSERT(false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000167 }
wu@webrtc.org364f2042013-11-20 21:49:41 +0000168
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000169 // The ICE gathering state should always be Gathering when a candidate is
170 // received (or possibly Completed in the case of the final candidate).
171 EXPECT_NE(PeerConnectionInterface::kIceGatheringNew, ice_gathering_state_);
172 }
173
174 // TODO(bemasc): Remove this once callers transition to OnIceGatheringChange.
175 virtual void OnIceComplete() {
176 EXPECT_FALSE(oncandidatesready_);
177 oncandidatesready_ = true;
178
179 // OnIceGatheringChange(IceGatheringCompleted) and OnIceComplete() should
180 // be called approximately simultaneously. For ease of testing, this
181 // check additionally requires that they be called in the above order.
182 EXPECT_EQ(PeerConnectionInterface::kIceGatheringComplete,
183 ice_gathering_state_);
184 }
185
186 bool oncandidatesready_;
187 std::vector<cricket::Candidate> mline_0_candidates_;
188 std::vector<cricket::Candidate> mline_1_candidates_;
189 PeerConnectionInterface::IceConnectionState ice_connection_state_;
190 PeerConnectionInterface::IceGatheringState ice_gathering_state_;
191};
192
193class WebRtcSessionForTest : public webrtc::WebRtcSession {
194 public:
195 WebRtcSessionForTest(cricket::ChannelManager* cmgr,
196 talk_base::Thread* signaling_thread,
197 talk_base::Thread* worker_thread,
198 cricket::PortAllocator* port_allocator,
199 webrtc::IceObserver* ice_observer,
200 webrtc::MediaStreamSignaling* mediastream_signaling)
201 : WebRtcSession(cmgr, signaling_thread, worker_thread, port_allocator,
202 mediastream_signaling) {
203 RegisterIceObserver(ice_observer);
204 }
205 virtual ~WebRtcSessionForTest() {}
206
207 using cricket::BaseSession::GetTransportProxy;
208 using webrtc::WebRtcSession::SetAudioPlayout;
209 using webrtc::WebRtcSession::SetAudioSend;
210 using webrtc::WebRtcSession::SetCaptureDevice;
211 using webrtc::WebRtcSession::SetVideoPlayout;
212 using webrtc::WebRtcSession::SetVideoSend;
213};
214
wu@webrtc.org91053e72013-08-10 07:18:04 +0000215class WebRtcSessionCreateSDPObserverForTest
216 : public talk_base::RefCountedObject<CreateSessionDescriptionObserver> {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000217 public:
wu@webrtc.org91053e72013-08-10 07:18:04 +0000218 enum State {
219 kInit,
220 kFailed,
221 kSucceeded,
222 };
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000223 WebRtcSessionCreateSDPObserverForTest() : state_(kInit) {}
wu@webrtc.org91053e72013-08-10 07:18:04 +0000224
225 // CreateSessionDescriptionObserver implementation.
226 virtual void OnSuccess(SessionDescriptionInterface* desc) {
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000227 description_.reset(desc);
wu@webrtc.org91053e72013-08-10 07:18:04 +0000228 state_ = kSucceeded;
229 }
230 virtual void OnFailure(const std::string& error) {
231 state_ = kFailed;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000232 }
233
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000234 SessionDescriptionInterface* description() { return description_.get(); }
235
236 SessionDescriptionInterface* ReleaseDescription() {
237 return description_.release();
238 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000239
wu@webrtc.org91053e72013-08-10 07:18:04 +0000240 State state() const { return state_; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000241
wu@webrtc.org91053e72013-08-10 07:18:04 +0000242 protected:
243 ~WebRtcSessionCreateSDPObserverForTest() {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000244
245 private:
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000246 talk_base::scoped_ptr<SessionDescriptionInterface> description_;
wu@webrtc.org91053e72013-08-10 07:18:04 +0000247 State state_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000248};
249
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000250class FakeAudioRenderer : public cricket::AudioRenderer {
251 public:
henrike@webrtc.orga7b98182014-02-21 15:51:43 +0000252 FakeAudioRenderer() : channel_id_(-1), sink_(NULL) {}
253 virtual ~FakeAudioRenderer() {
254 if (sink_)
255 sink_->OnClose();
256 }
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000257
258 virtual void AddChannel(int channel_id) OVERRIDE {
259 ASSERT(channel_id_ == -1);
260 channel_id_ = channel_id;
261 }
262 virtual void RemoveChannel(int channel_id) OVERRIDE {
263 ASSERT(channel_id == channel_id_);
264 channel_id_ = -1;
265 }
henrike@webrtc.orga7b98182014-02-21 15:51:43 +0000266 virtual void SetSink(Sink* sink) OVERRIDE {
267 sink_ = sink;
268 }
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000269
270 int channel_id() const { return channel_id_; }
henrike@webrtc.orga7b98182014-02-21 15:51:43 +0000271 cricket::AudioRenderer::Sink* sink() const { return sink_; }
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000272 private:
273 int channel_id_;
henrike@webrtc.orga7b98182014-02-21 15:51:43 +0000274 cricket::AudioRenderer::Sink* sink_;
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000275};
276
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000277class WebRtcSessionTest : public testing::Test {
278 protected:
279 // TODO Investigate why ChannelManager crashes, if it's created
280 // after stun_server.
281 WebRtcSessionTest()
282 : media_engine_(new cricket::FakeMediaEngine()),
283 data_engine_(new cricket::FakeDataEngine()),
284 device_manager_(new cricket::FakeDeviceManager()),
285 channel_manager_(new cricket::ChannelManager(
286 media_engine_, data_engine_, device_manager_,
287 new cricket::CaptureManager(), talk_base::Thread::Current())),
288 tdesc_factory_(new cricket::TransportDescriptionFactory()),
289 desc_factory_(new cricket::MediaSessionDescriptionFactory(
290 channel_manager_.get(), tdesc_factory_.get())),
291 pss_(new talk_base::PhysicalSocketServer),
292 vss_(new talk_base::VirtualSocketServer(pss_.get())),
293 fss_(new talk_base::FirewallSocketServer(vss_.get())),
294 ss_scope_(fss_.get()),
wu@webrtc.org364f2042013-11-20 21:49:41 +0000295 stun_socket_addr_(talk_base::SocketAddress(kStunAddrHost,
296 cricket::STUN_SERVER_PORT)),
297 stun_server_(talk_base::Thread::Current(), stun_socket_addr_),
298 allocator_(&network_manager_, stun_socket_addr_,
wu@webrtc.org967bfff2013-09-19 05:49:50 +0000299 SocketAddress(), SocketAddress(), SocketAddress()),
300 mediastream_signaling_(channel_manager_.get()) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000301 tdesc_factory_->set_protocol(cricket::ICEPROTO_HYBRID);
302 allocator_.set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
303 cricket::PORTALLOCATOR_DISABLE_RELAY |
304 cricket::PORTALLOCATOR_ENABLE_BUNDLE);
305 EXPECT_TRUE(channel_manager_->Init());
306 desc_factory_->set_add_legacy_streams(false);
307 }
308
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000309 static void SetUpTestCase() {
310 talk_base::InitializeSSL();
311 }
312
313 static void TearDownTestCase() {
314 talk_base::CleanupSSL();
315 }
316
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000317 void AddInterface(const SocketAddress& addr) {
318 network_manager_.AddInterface(addr);
319 }
320
wu@webrtc.org91053e72013-08-10 07:18:04 +0000321 void Init(DTLSIdentityServiceInterface* identity_service) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000322 ASSERT_TRUE(session_.get() == NULL);
323 session_.reset(new WebRtcSessionForTest(
324 channel_manager_.get(), talk_base::Thread::Current(),
325 talk_base::Thread::Current(), &allocator_,
326 &observer_,
327 &mediastream_signaling_));
328
329 EXPECT_EQ(PeerConnectionInterface::kIceConnectionNew,
330 observer_.ice_connection_state_);
331 EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
332 observer_.ice_gathering_state_);
333
wu@webrtc.org97077a32013-10-25 21:18:33 +0000334 EXPECT_TRUE(session_->Initialize(options_, constraints_.get(),
335 identity_service));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000336 }
337
338 void InitWithDtmfCodec() {
339 // Add kTelephoneEventCodec for dtmf test.
wu@webrtc.org364f2042013-11-20 21:49:41 +0000340 const cricket::AudioCodec kTelephoneEventCodec(
341 106, "telephone-event", 8000, 0, 1, 0);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000342 std::vector<cricket::AudioCodec> codecs;
343 codecs.push_back(kTelephoneEventCodec);
344 media_engine_->SetAudioCodecs(codecs);
345 desc_factory_->set_audio_codecs(codecs);
wu@webrtc.org91053e72013-08-10 07:18:04 +0000346 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000347 }
348
henrike@webrtc.org7666db72013-08-22 14:45:42 +0000349 void InitWithDtls(bool identity_request_should_fail = false) {
wu@webrtc.org91053e72013-08-10 07:18:04 +0000350 FakeIdentityService* identity_service = new FakeIdentityService();
351 identity_service->set_should_fail(identity_request_should_fail);
352 Init(identity_service);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000353 }
354
355 // Creates a local offer and applies it. Starts ice.
356 // Call mediastream_signaling_.UseOptionsWithStreamX() before this function
357 // to decide which streams to create.
358 void InitiateCall() {
wu@webrtc.org91053e72013-08-10 07:18:04 +0000359 SessionDescriptionInterface* offer = CreateOffer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000360 SetLocalDescriptionWithoutError(offer);
361 EXPECT_TRUE_WAIT(PeerConnectionInterface::kIceGatheringNew !=
362 observer_.ice_gathering_state_,
363 kIceCandidatesTimeout);
364 }
365
wu@webrtc.org91053e72013-08-10 07:18:04 +0000366 SessionDescriptionInterface* CreateOffer(
367 const webrtc::MediaConstraintsInterface* constraints) {
368 talk_base::scoped_refptr<WebRtcSessionCreateSDPObserverForTest>
369 observer = new WebRtcSessionCreateSDPObserverForTest();
370 session_->CreateOffer(observer, constraints);
371 EXPECT_TRUE_WAIT(
372 observer->state() != WebRtcSessionCreateSDPObserverForTest::kInit,
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000373 2000);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000374 return observer->ReleaseDescription();
wu@webrtc.org91053e72013-08-10 07:18:04 +0000375 }
376
377 SessionDescriptionInterface* CreateAnswer(
378 const webrtc::MediaConstraintsInterface* constraints) {
379 talk_base::scoped_refptr<WebRtcSessionCreateSDPObserverForTest> observer
380 = new WebRtcSessionCreateSDPObserverForTest();
381 session_->CreateAnswer(observer, constraints);
382 EXPECT_TRUE_WAIT(
383 observer->state() != WebRtcSessionCreateSDPObserverForTest::kInit,
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000384 2000);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000385 return observer->ReleaseDescription();
wu@webrtc.org91053e72013-08-10 07:18:04 +0000386 }
387
wu@webrtc.org364f2042013-11-20 21:49:41 +0000388 bool ChannelsExist() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000389 return (session_->voice_channel() != NULL &&
390 session_->video_channel() != NULL);
391 }
392
wu@webrtc.org364f2042013-11-20 21:49:41 +0000393 void CheckTransportChannels() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000394 EXPECT_TRUE(session_->GetChannel(cricket::CN_AUDIO, 1) != NULL);
395 EXPECT_TRUE(session_->GetChannel(cricket::CN_AUDIO, 2) != NULL);
396 EXPECT_TRUE(session_->GetChannel(cricket::CN_VIDEO, 1) != NULL);
397 EXPECT_TRUE(session_->GetChannel(cricket::CN_VIDEO, 2) != NULL);
398 }
399
400 void VerifyCryptoParams(const cricket::SessionDescription* sdp) {
401 ASSERT_TRUE(session_.get() != NULL);
402 const cricket::ContentInfo* content = cricket::GetFirstAudioContent(sdp);
403 ASSERT_TRUE(content != NULL);
404 const cricket::AudioContentDescription* audio_content =
405 static_cast<const cricket::AudioContentDescription*>(
406 content->description);
407 ASSERT_TRUE(audio_content != NULL);
408 ASSERT_EQ(1U, audio_content->cryptos().size());
409 ASSERT_EQ(47U, audio_content->cryptos()[0].key_params.size());
410 ASSERT_EQ("AES_CM_128_HMAC_SHA1_80",
411 audio_content->cryptos()[0].cipher_suite);
412 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf),
413 audio_content->protocol());
414
415 content = cricket::GetFirstVideoContent(sdp);
416 ASSERT_TRUE(content != NULL);
417 const cricket::VideoContentDescription* video_content =
418 static_cast<const cricket::VideoContentDescription*>(
419 content->description);
420 ASSERT_TRUE(video_content != NULL);
421 ASSERT_EQ(1U, video_content->cryptos().size());
422 ASSERT_EQ("AES_CM_128_HMAC_SHA1_80",
423 video_content->cryptos()[0].cipher_suite);
424 ASSERT_EQ(47U, video_content->cryptos()[0].key_params.size());
425 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf),
426 video_content->protocol());
427 }
428
429 void VerifyNoCryptoParams(const cricket::SessionDescription* sdp, bool dtls) {
430 const cricket::ContentInfo* content = cricket::GetFirstAudioContent(sdp);
431 ASSERT_TRUE(content != NULL);
432 const cricket::AudioContentDescription* audio_content =
433 static_cast<const cricket::AudioContentDescription*>(
434 content->description);
435 ASSERT_TRUE(audio_content != NULL);
436 ASSERT_EQ(0U, audio_content->cryptos().size());
437
438 content = cricket::GetFirstVideoContent(sdp);
439 ASSERT_TRUE(content != NULL);
440 const cricket::VideoContentDescription* video_content =
441 static_cast<const cricket::VideoContentDescription*>(
442 content->description);
443 ASSERT_TRUE(video_content != NULL);
444 ASSERT_EQ(0U, video_content->cryptos().size());
445
446 if (dtls) {
447 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf),
448 audio_content->protocol());
449 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf),
450 video_content->protocol());
451 } else {
452 EXPECT_EQ(std::string(cricket::kMediaProtocolAvpf),
453 audio_content->protocol());
454 EXPECT_EQ(std::string(cricket::kMediaProtocolAvpf),
455 video_content->protocol());
456 }
457 }
458
459 // Set the internal fake description factories to do DTLS-SRTP.
460 void SetFactoryDtlsSrtp() {
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000461 desc_factory_->set_secure(cricket::SEC_DISABLED);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000462 std::string identity_name = "WebRTC" +
463 talk_base::ToString(talk_base::CreateRandomId());
henrike@webrtc.org723d6832013-07-12 16:04:50 +0000464 identity_.reset(talk_base::SSLIdentity::Generate(identity_name));
465 tdesc_factory_->set_identity(identity_.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000466 tdesc_factory_->set_secure(cricket::SEC_REQUIRED);
467 }
468
469 void VerifyFingerprintStatus(const cricket::SessionDescription* sdp,
470 bool expected) {
471 const TransportInfo* audio = sdp->GetTransportInfoByName("audio");
472 ASSERT_TRUE(audio != NULL);
473 ASSERT_EQ(expected, audio->description.identity_fingerprint.get() != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000474 const TransportInfo* video = sdp->GetTransportInfoByName("video");
475 ASSERT_TRUE(video != NULL);
476 ASSERT_EQ(expected, video->description.identity_fingerprint.get() != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000477 }
478
479 void VerifyAnswerFromNonCryptoOffer() {
480 // Create a SDP without Crypto.
481 cricket::MediaSessionOptions options;
482 options.has_video = true;
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000483 JsepSessionDescription* offer(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000484 CreateRemoteOffer(options, cricket::SEC_DISABLED));
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000485 ASSERT_TRUE(offer != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000486 VerifyNoCryptoParams(offer->description(), false);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000487 SetRemoteDescriptionOfferExpectError(kSdpWithoutSdesCrypto,
488 offer);
wu@webrtc.org91053e72013-08-10 07:18:04 +0000489 const webrtc::SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000490 // Answer should be NULL as no crypto params in offer.
491 ASSERT_TRUE(answer == NULL);
492 }
493
494 void VerifyAnswerFromCryptoOffer() {
495 cricket::MediaSessionOptions options;
496 options.has_video = true;
497 options.bundle_enabled = true;
498 scoped_ptr<JsepSessionDescription> offer(
499 CreateRemoteOffer(options, cricket::SEC_REQUIRED));
500 ASSERT_TRUE(offer.get() != NULL);
501 VerifyCryptoParams(offer->description());
502 SetRemoteDescriptionWithoutError(offer.release());
wu@webrtc.org91053e72013-08-10 07:18:04 +0000503 scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000504 ASSERT_TRUE(answer.get() != NULL);
505 VerifyCryptoParams(answer->description());
506 }
507
508 void CompareIceUfragAndPassword(const cricket::SessionDescription* desc1,
509 const cricket::SessionDescription* desc2,
510 bool expect_equal) {
511 if (desc1->contents().size() != desc2->contents().size()) {
512 EXPECT_FALSE(expect_equal);
513 return;
514 }
515
516 const cricket::ContentInfos& contents = desc1->contents();
517 cricket::ContentInfos::const_iterator it = contents.begin();
518
519 for (; it != contents.end(); ++it) {
520 const cricket::TransportDescription* transport_desc1 =
521 desc1->GetTransportDescriptionByName(it->name);
522 const cricket::TransportDescription* transport_desc2 =
523 desc2->GetTransportDescriptionByName(it->name);
524 if (!transport_desc1 || !transport_desc2) {
525 EXPECT_FALSE(expect_equal);
526 return;
527 }
528 if (transport_desc1->ice_pwd != transport_desc2->ice_pwd ||
529 transport_desc1->ice_ufrag != transport_desc2->ice_ufrag) {
530 EXPECT_FALSE(expect_equal);
531 return;
532 }
533 }
534 EXPECT_TRUE(expect_equal);
535 }
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000536
537 void RemoveIceUfragPwdLines(const SessionDescriptionInterface* current_desc,
538 std::string *sdp) {
539 const cricket::SessionDescription* desc = current_desc->description();
540 EXPECT_TRUE(current_desc->ToString(sdp));
541
542 const cricket::ContentInfos& contents = desc->contents();
543 cricket::ContentInfos::const_iterator it = contents.begin();
544 // Replace ufrag and pwd lines with empty strings.
545 for (; it != contents.end(); ++it) {
546 const cricket::TransportDescription* transport_desc =
547 desc->GetTransportDescriptionByName(it->name);
548 std::string ufrag_line = "a=ice-ufrag:" + transport_desc->ice_ufrag
549 + "\r\n";
550 std::string pwd_line = "a=ice-pwd:" + transport_desc->ice_pwd
551 + "\r\n";
552 talk_base::replace_substrs(ufrag_line.c_str(), ufrag_line.length(),
553 "", 0,
554 sdp);
555 talk_base::replace_substrs(pwd_line.c_str(), pwd_line.length(),
556 "", 0,
557 sdp);
558 }
559 }
560
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000561 // Creates a remote offer and and applies it as a remote description,
562 // creates a local answer and applies is as a local description.
563 // Call mediastream_signaling_.UseOptionsWithStreamX() before this function
564 // to decide which local and remote streams to create.
565 void CreateAndSetRemoteOfferAndLocalAnswer() {
566 SessionDescriptionInterface* offer = CreateRemoteOffer();
567 SetRemoteDescriptionWithoutError(offer);
wu@webrtc.org91053e72013-08-10 07:18:04 +0000568 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000569 SetLocalDescriptionWithoutError(answer);
570 }
571 void SetLocalDescriptionWithoutError(SessionDescriptionInterface* desc) {
572 EXPECT_TRUE(session_->SetLocalDescription(desc, NULL));
573 }
574 void SetLocalDescriptionExpectState(SessionDescriptionInterface* desc,
575 BaseSession::State expected_state) {
576 SetLocalDescriptionWithoutError(desc);
577 EXPECT_EQ(expected_state, session_->state());
578 }
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000579 void SetLocalDescriptionExpectError(const std::string& action,
580 const std::string& expected_error,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000581 SessionDescriptionInterface* desc) {
582 std::string error;
583 EXPECT_FALSE(session_->SetLocalDescription(desc, &error));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000584 std::string sdp_type = "local ";
585 sdp_type.append(action);
586 EXPECT_NE(std::string::npos, error.find(sdp_type));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000587 EXPECT_NE(std::string::npos, error.find(expected_error));
588 }
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000589 void SetLocalDescriptionOfferExpectError(const std::string& expected_error,
590 SessionDescriptionInterface* desc) {
591 SetLocalDescriptionExpectError(SessionDescriptionInterface::kOffer,
592 expected_error, desc);
593 }
594 void SetLocalDescriptionAnswerExpectError(const std::string& expected_error,
595 SessionDescriptionInterface* desc) {
596 SetLocalDescriptionExpectError(SessionDescriptionInterface::kAnswer,
597 expected_error, desc);
598 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000599 void SetRemoteDescriptionWithoutError(SessionDescriptionInterface* desc) {
600 EXPECT_TRUE(session_->SetRemoteDescription(desc, NULL));
601 }
602 void SetRemoteDescriptionExpectState(SessionDescriptionInterface* desc,
603 BaseSession::State expected_state) {
604 SetRemoteDescriptionWithoutError(desc);
605 EXPECT_EQ(expected_state, session_->state());
606 }
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000607 void SetRemoteDescriptionExpectError(const std::string& action,
608 const std::string& expected_error,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000609 SessionDescriptionInterface* desc) {
610 std::string error;
611 EXPECT_FALSE(session_->SetRemoteDescription(desc, &error));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000612 std::string sdp_type = "remote ";
613 sdp_type.append(action);
614 EXPECT_NE(std::string::npos, error.find(sdp_type));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000615 EXPECT_NE(std::string::npos, error.find(expected_error));
616 }
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000617 void SetRemoteDescriptionOfferExpectError(
618 const std::string& expected_error, SessionDescriptionInterface* desc) {
619 SetRemoteDescriptionExpectError(SessionDescriptionInterface::kOffer,
620 expected_error, desc);
621 }
622 void SetRemoteDescriptionPranswerExpectError(
623 const std::string& expected_error, SessionDescriptionInterface* desc) {
624 SetRemoteDescriptionExpectError(SessionDescriptionInterface::kPrAnswer,
625 expected_error, desc);
626 }
627 void SetRemoteDescriptionAnswerExpectError(
628 const std::string& expected_error, SessionDescriptionInterface* desc) {
629 SetRemoteDescriptionExpectError(SessionDescriptionInterface::kAnswer,
630 expected_error, desc);
631 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000632
633 void CreateCryptoOfferAndNonCryptoAnswer(SessionDescriptionInterface** offer,
634 SessionDescriptionInterface** nocrypto_answer) {
635 // Create a SDP without Crypto.
636 cricket::MediaSessionOptions options;
637 options.has_video = true;
638 options.bundle_enabled = true;
639 *offer = CreateRemoteOffer(options, cricket::SEC_ENABLED);
640 ASSERT_TRUE(*offer != NULL);
641 VerifyCryptoParams((*offer)->description());
642
643 *nocrypto_answer = CreateRemoteAnswer(*offer, options,
644 cricket::SEC_DISABLED);
645 EXPECT_TRUE(*nocrypto_answer != NULL);
646 }
647
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000648 void CreateDtlsOfferAndNonDtlsAnswer(SessionDescriptionInterface** offer,
649 SessionDescriptionInterface** nodtls_answer) {
650 cricket::MediaSessionOptions options;
651 options.has_video = true;
652 options.bundle_enabled = true;
653
654 talk_base::scoped_ptr<SessionDescriptionInterface> temp_offer(
655 CreateRemoteOffer(options, cricket::SEC_ENABLED));
656
657 *nodtls_answer =
658 CreateRemoteAnswer(temp_offer.get(), options, cricket::SEC_ENABLED);
659 EXPECT_TRUE(*nodtls_answer != NULL);
660 VerifyFingerprintStatus((*nodtls_answer)->description(), false);
661 VerifyCryptoParams((*nodtls_answer)->description());
662
663 SetFactoryDtlsSrtp();
664 *offer = CreateRemoteOffer(options, cricket::SEC_ENABLED);
665 ASSERT_TRUE(*offer != NULL);
666 VerifyFingerprintStatus((*offer)->description(), true);
667 VerifyCryptoParams((*offer)->description());
668 }
669
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000670 JsepSessionDescription* CreateRemoteOfferWithVersion(
671 cricket::MediaSessionOptions options,
672 cricket::SecurePolicy secure_policy,
673 const std::string& session_version,
674 const SessionDescriptionInterface* current_desc) {
675 std::string session_id = talk_base::ToString(talk_base::CreateRandomId64());
676 const cricket::SessionDescription* cricket_desc = NULL;
677 if (current_desc) {
678 cricket_desc = current_desc->description();
679 session_id = current_desc->session_id();
680 }
681
682 desc_factory_->set_secure(secure_policy);
683 JsepSessionDescription* offer(
684 new JsepSessionDescription(JsepSessionDescription::kOffer));
685 if (!offer->Initialize(desc_factory_->CreateOffer(options, cricket_desc),
686 session_id, session_version)) {
687 delete offer;
688 offer = NULL;
689 }
690 return offer;
691 }
692 JsepSessionDescription* CreateRemoteOffer(
693 cricket::MediaSessionOptions options) {
694 return CreateRemoteOfferWithVersion(options, cricket::SEC_ENABLED,
695 kSessionVersion, NULL);
696 }
697 JsepSessionDescription* CreateRemoteOffer(
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000698 cricket::MediaSessionOptions options, cricket::SecurePolicy sdes_policy) {
699 return CreateRemoteOfferWithVersion(
700 options, sdes_policy, kSessionVersion, NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000701 }
702 JsepSessionDescription* CreateRemoteOffer(
703 cricket::MediaSessionOptions options,
704 const SessionDescriptionInterface* current_desc) {
705 return CreateRemoteOfferWithVersion(options, cricket::SEC_ENABLED,
706 kSessionVersion, current_desc);
707 }
708
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000709 JsepSessionDescription* CreateRemoteOfferWithSctpPort(
710 const char* sctp_stream_name, int new_port,
711 cricket::MediaSessionOptions options) {
712 options.data_channel_type = cricket::DCT_SCTP;
713 options.AddStream(cricket::MEDIA_TYPE_DATA, "datachannel",
714 sctp_stream_name);
715 return ChangeSDPSctpPort(new_port, CreateRemoteOffer(options));
716 }
717
718 // Takes ownership of offer_basis (and deletes it).
719 JsepSessionDescription* ChangeSDPSctpPort(
720 int new_port, webrtc::SessionDescriptionInterface *offer_basis) {
721 // Stringify the input SDP, swap the 5000 for 'new_port' and create a new
722 // SessionDescription from the mutated string.
723 const char* default_port_str = "5000";
724 char new_port_str[16];
725 talk_base::sprintfn(new_port_str, sizeof(new_port_str), "%d", new_port);
726 std::string offer_str;
727 offer_basis->ToString(&offer_str);
728 talk_base::replace_substrs(default_port_str, strlen(default_port_str),
729 new_port_str, strlen(new_port_str),
730 &offer_str);
731 JsepSessionDescription* offer = new JsepSessionDescription(
732 offer_basis->type());
733 delete offer_basis;
734 offer->Initialize(offer_str, NULL);
735 return offer;
736 }
737
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000738 // Create a remote offer. Call mediastream_signaling_.UseOptionsWithStreamX()
739 // before this function to decide which streams to create.
740 JsepSessionDescription* CreateRemoteOffer() {
741 cricket::MediaSessionOptions options;
742 mediastream_signaling_.GetOptionsForAnswer(NULL, &options);
743 return CreateRemoteOffer(options, session_->remote_description());
744 }
745
746 JsepSessionDescription* CreateRemoteAnswer(
747 const SessionDescriptionInterface* offer,
748 cricket::MediaSessionOptions options,
749 cricket::SecurePolicy policy) {
750 desc_factory_->set_secure(policy);
751 const std::string session_id =
752 talk_base::ToString(talk_base::CreateRandomId64());
753 JsepSessionDescription* answer(
754 new JsepSessionDescription(JsepSessionDescription::kAnswer));
755 if (!answer->Initialize(desc_factory_->CreateAnswer(offer->description(),
756 options, NULL),
757 session_id, kSessionVersion)) {
758 delete answer;
759 answer = NULL;
760 }
761 return answer;
762 }
763
764 JsepSessionDescription* CreateRemoteAnswer(
765 const SessionDescriptionInterface* offer,
766 cricket::MediaSessionOptions options) {
767 return CreateRemoteAnswer(offer, options, cricket::SEC_REQUIRED);
768 }
769
770 // Creates an answer session description with streams based on
771 // |mediastream_signaling_|. Call
772 // mediastream_signaling_.UseOptionsWithStreamX() before this function
773 // to decide which streams to create.
774 JsepSessionDescription* CreateRemoteAnswer(
775 const SessionDescriptionInterface* offer) {
776 cricket::MediaSessionOptions options;
777 mediastream_signaling_.GetOptionsForAnswer(NULL, &options);
778 return CreateRemoteAnswer(offer, options, cricket::SEC_REQUIRED);
779 }
780
781 void TestSessionCandidatesWithBundleRtcpMux(bool bundle, bool rtcp_mux) {
wu@webrtc.org364f2042013-11-20 21:49:41 +0000782 AddInterface(talk_base::SocketAddress(kClientAddrHost1, kClientAddrPort));
wu@webrtc.org91053e72013-08-10 07:18:04 +0000783 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000784 mediastream_signaling_.SendAudioVideoStream1();
785 FakeConstraints constraints;
786 constraints.SetMandatoryUseRtpMux(bundle);
wu@webrtc.org91053e72013-08-10 07:18:04 +0000787 SessionDescriptionInterface* offer = CreateOffer(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000788 // SetLocalDescription and SetRemoteDescriptions takes ownership of offer
789 // and answer.
790 SetLocalDescriptionWithoutError(offer);
791
henrike@webrtc.org723d6832013-07-12 16:04:50 +0000792 talk_base::scoped_ptr<SessionDescriptionInterface> answer(
793 CreateRemoteAnswer(session_->local_description()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000794 std::string sdp;
795 EXPECT_TRUE(answer->ToString(&sdp));
796
797 size_t expected_candidate_num = 2;
798 if (!rtcp_mux) {
799 // If rtcp_mux is enabled we should expect 4 candidates - host and srflex
800 // for rtp and rtcp.
801 expected_candidate_num = 4;
802 // Disable rtcp-mux from the answer
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000803 const std::string kRtcpMux = "a=rtcp-mux";
804 const std::string kXRtcpMux = "a=xrtcp-mux";
805 talk_base::replace_substrs(kRtcpMux.c_str(), kRtcpMux.length(),
806 kXRtcpMux.c_str(), kXRtcpMux.length(),
807 &sdp);
808 }
809
810 SessionDescriptionInterface* new_answer = CreateSessionDescription(
811 JsepSessionDescription::kAnswer, sdp, NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000812
813 // SetRemoteDescription to enable rtcp mux.
henrike@webrtc.org723d6832013-07-12 16:04:50 +0000814 SetRemoteDescriptionWithoutError(new_answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000815 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
816 EXPECT_EQ(expected_candidate_num, observer_.mline_0_candidates_.size());
817 EXPECT_EQ(expected_candidate_num, observer_.mline_1_candidates_.size());
818 for (size_t i = 0; i < observer_.mline_0_candidates_.size(); ++i) {
819 cricket::Candidate c0 = observer_.mline_0_candidates_[i];
820 cricket::Candidate c1 = observer_.mline_1_candidates_[i];
821 if (bundle) {
822 EXPECT_TRUE(c0.IsEquivalent(c1));
823 } else {
824 EXPECT_FALSE(c0.IsEquivalent(c1));
825 }
826 }
827 }
828 // Tests that we can only send DTMF when the dtmf codec is supported.
829 void TestCanInsertDtmf(bool can) {
830 if (can) {
831 InitWithDtmfCodec();
832 } else {
wu@webrtc.org91053e72013-08-10 07:18:04 +0000833 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000834 }
835 mediastream_signaling_.SendAudioVideoStream1();
836 CreateAndSetRemoteOfferAndLocalAnswer();
837 EXPECT_FALSE(session_->CanInsertDtmf(""));
838 EXPECT_EQ(can, session_->CanInsertDtmf(kAudioTrack1));
839 }
840
841 // The method sets up a call from the session to itself, in a loopback
842 // arrangement. It also uses a firewall rule to create a temporary
mallinath@webrtc.org385857d2014-02-14 00:56:12 +0000843 // disconnection, and then a permanent disconnection.
844 // This code is placed in a method so that it can be invoked
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000845 // by multiple tests with different allocators (e.g. with and without BUNDLE).
846 // While running the call, this method also checks if the session goes through
847 // the correct sequence of ICE states when a connection is established,
848 // broken, and re-established.
849 // The Connection state should go:
mallinath@webrtc.org385857d2014-02-14 00:56:12 +0000850 // New -> Checking -> (Connected) -> Completed -> Disconnected -> Completed
851 // -> Failed.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000852 // The Gathering state should go: New -> Gathering -> Completed.
853 void TestLoopbackCall() {
wu@webrtc.org364f2042013-11-20 21:49:41 +0000854 AddInterface(talk_base::SocketAddress(kClientAddrHost1, kClientAddrPort));
wu@webrtc.org91053e72013-08-10 07:18:04 +0000855 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000856 mediastream_signaling_.SendAudioVideoStream1();
wu@webrtc.org91053e72013-08-10 07:18:04 +0000857 SessionDescriptionInterface* offer = CreateOffer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000858
859 EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
860 observer_.ice_gathering_state_);
861 SetLocalDescriptionWithoutError(offer);
862 EXPECT_EQ(PeerConnectionInterface::kIceConnectionNew,
863 observer_.ice_connection_state_);
864 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceGatheringGathering,
865 observer_.ice_gathering_state_,
866 kIceCandidatesTimeout);
867 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
868 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
869 observer_.ice_gathering_state_,
870 kIceCandidatesTimeout);
871
872 std::string sdp;
873 offer->ToString(&sdp);
874 SessionDescriptionInterface* desc =
875 webrtc::CreateSessionDescription(JsepSessionDescription::kAnswer, sdp);
876 ASSERT_TRUE(desc != NULL);
877 SetRemoteDescriptionWithoutError(desc);
878
879 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionChecking,
880 observer_.ice_connection_state_,
881 kIceCandidatesTimeout);
mallinath@webrtc.orgd3dc4242014-03-01 00:05:52 +0000882
mallinath@webrtc.org385857d2014-02-14 00:56:12 +0000883 // The ice connection state is "Connected" too briefly to catch in a test.
884 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000885 observer_.ice_connection_state_,
886 kIceCandidatesTimeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000887
888 // Adding firewall rule to block ping requests, which should cause
889 // transport channel failure.
wu@webrtc.org364f2042013-11-20 21:49:41 +0000890 fss_->AddRule(false,
891 talk_base::FP_ANY,
892 talk_base::FD_ANY,
893 talk_base::SocketAddress(kClientAddrHost1, kClientAddrPort));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000894 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
895 observer_.ice_connection_state_,
896 kIceCandidatesTimeout);
897
898 // Clearing the rules, session should move back to completed state.
899 fss_->ClearRules();
900 // Session is automatically calling OnSignalingReady after creation of
901 // new portallocator session which will allocate new set of candidates.
902
mallinath@webrtc.org385857d2014-02-14 00:56:12 +0000903 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000904 observer_.ice_connection_state_,
905 kIceCandidatesTimeout);
mallinath@webrtc.org385857d2014-02-14 00:56:12 +0000906
907 // Now we block ping requests and wait until the ICE connection transitions
908 // to the Failed state. This will take at least 30 seconds because it must
909 // wait for the Port to timeout.
910 int port_timeout = 30000;
911 fss_->AddRule(false,
912 talk_base::FP_ANY,
913 talk_base::FD_ANY,
914 talk_base::SocketAddress(kClientAddrHost1, kClientAddrPort));
915 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionFailed,
916 observer_.ice_connection_state_,
917 kIceCandidatesTimeout + port_timeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000918 }
919
920 void VerifyTransportType(const std::string& content_name,
921 cricket::TransportProtocol protocol) {
922 const cricket::Transport* transport = session_->GetTransport(content_name);
923 ASSERT_TRUE(transport != NULL);
924 EXPECT_EQ(protocol, transport->protocol());
925 }
926
927 // Adds CN codecs to FakeMediaEngine and MediaDescriptionFactory.
928 void AddCNCodecs() {
wu@webrtc.org364f2042013-11-20 21:49:41 +0000929 const cricket::AudioCodec kCNCodec1(102, "CN", 8000, 0, 1, 0);
930 const cricket::AudioCodec kCNCodec2(103, "CN", 16000, 0, 1, 0);
931
932 // Add kCNCodec for dtmf test.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000933 std::vector<cricket::AudioCodec> codecs = media_engine_->audio_codecs();;
934 codecs.push_back(kCNCodec1);
935 codecs.push_back(kCNCodec2);
936 media_engine_->SetAudioCodecs(codecs);
937 desc_factory_->set_audio_codecs(codecs);
938 }
939
940 bool VerifyNoCNCodecs(const cricket::ContentInfo* content) {
941 const cricket::ContentDescription* description = content->description;
942 ASSERT(description != NULL);
943 const cricket::AudioContentDescription* audio_content_desc =
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000944 static_cast<const cricket::AudioContentDescription*>(description);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000945 ASSERT(audio_content_desc != NULL);
946 for (size_t i = 0; i < audio_content_desc->codecs().size(); ++i) {
947 if (audio_content_desc->codecs()[i].name == "CN")
948 return false;
949 }
950 return true;
951 }
952
953 void SetLocalDescriptionWithDataChannel() {
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +0000954 webrtc::InternalDataChannelInit dci;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000955 dci.reliable = false;
956 session_->CreateDataChannel("datachannel", &dci);
wu@webrtc.org91053e72013-08-10 07:18:04 +0000957 SessionDescriptionInterface* offer = CreateOffer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000958 SetLocalDescriptionWithoutError(offer);
959 }
960
wu@webrtc.org91053e72013-08-10 07:18:04 +0000961 void VerifyMultipleAsyncCreateDescription(
962 bool success, CreateSessionDescriptionRequest::Type type) {
henrike@webrtc.org7666db72013-08-22 14:45:42 +0000963 InitWithDtls(!success);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000964 SetFactoryDtlsSrtp();
wu@webrtc.org91053e72013-08-10 07:18:04 +0000965 if (type == CreateSessionDescriptionRequest::kAnswer) {
966 cricket::MediaSessionOptions options;
967 scoped_ptr<JsepSessionDescription> offer(
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000968 CreateRemoteOffer(options, cricket::SEC_DISABLED));
wu@webrtc.org91053e72013-08-10 07:18:04 +0000969 ASSERT_TRUE(offer.get() != NULL);
970 SetRemoteDescriptionWithoutError(offer.release());
971 }
972
973 const int kNumber = 3;
974 talk_base::scoped_refptr<WebRtcSessionCreateSDPObserverForTest>
975 observers[kNumber];
976 for (int i = 0; i < kNumber; ++i) {
977 observers[i] = new WebRtcSessionCreateSDPObserverForTest();
978 if (type == CreateSessionDescriptionRequest::kOffer) {
979 session_->CreateOffer(observers[i], NULL);
980 } else {
981 session_->CreateAnswer(observers[i], NULL);
982 }
983 }
984
985 WebRtcSessionCreateSDPObserverForTest::State expected_state =
986 success ? WebRtcSessionCreateSDPObserverForTest::kSucceeded :
987 WebRtcSessionCreateSDPObserverForTest::kFailed;
988
989 for (int i = 0; i < kNumber; ++i) {
990 EXPECT_EQ_WAIT(expected_state, observers[i]->state(), 1000);
991 if (success) {
992 EXPECT_TRUE(observers[i]->description() != NULL);
993 } else {
994 EXPECT_TRUE(observers[i]->description() == NULL);
995 }
996 }
997 }
998
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000999 cricket::FakeMediaEngine* media_engine_;
1000 cricket::FakeDataEngine* data_engine_;
1001 cricket::FakeDeviceManager* device_manager_;
1002 talk_base::scoped_ptr<cricket::ChannelManager> channel_manager_;
1003 talk_base::scoped_ptr<cricket::TransportDescriptionFactory> tdesc_factory_;
henrike@webrtc.org723d6832013-07-12 16:04:50 +00001004 talk_base::scoped_ptr<talk_base::SSLIdentity> identity_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001005 talk_base::scoped_ptr<cricket::MediaSessionDescriptionFactory> desc_factory_;
1006 talk_base::scoped_ptr<talk_base::PhysicalSocketServer> pss_;
1007 talk_base::scoped_ptr<talk_base::VirtualSocketServer> vss_;
1008 talk_base::scoped_ptr<talk_base::FirewallSocketServer> fss_;
1009 talk_base::SocketServerScope ss_scope_;
wu@webrtc.org364f2042013-11-20 21:49:41 +00001010 talk_base::SocketAddress stun_socket_addr_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001011 cricket::TestStunServer stun_server_;
1012 talk_base::FakeNetworkManager network_manager_;
1013 cricket::BasicPortAllocator allocator_;
wu@webrtc.org97077a32013-10-25 21:18:33 +00001014 PeerConnectionFactoryInterface::Options options_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001015 talk_base::scoped_ptr<FakeConstraints> constraints_;
1016 FakeMediaStreamSignaling mediastream_signaling_;
1017 talk_base::scoped_ptr<WebRtcSessionForTest> session_;
1018 MockIceObserver observer_;
1019 cricket::FakeVideoMediaChannel* video_channel_;
1020 cricket::FakeVoiceMediaChannel* voice_channel_;
1021};
1022
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001023TEST_F(WebRtcSessionTest, TestInitializeWithDtls) {
1024 InitWithDtls();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001025 // SDES is disabled when DTLS is on.
1026 EXPECT_EQ(cricket::SEC_DISABLED, session_->SdesPolicy());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001027}
1028
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001029TEST_F(WebRtcSessionTest, TestInitializeWithoutDtls) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00001030 Init(NULL);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001031 // SDES is required if DTLS is off.
1032 EXPECT_EQ(cricket::SEC_REQUIRED, session_->SdesPolicy());
wu@webrtc.org91053e72013-08-10 07:18:04 +00001033}
1034
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001035TEST_F(WebRtcSessionTest, TestSessionCandidates) {
1036 TestSessionCandidatesWithBundleRtcpMux(false, false);
1037}
1038
1039// Below test cases (TestSessionCandidatesWith*) verify the candidates gathered
1040// with rtcp-mux and/or bundle.
1041TEST_F(WebRtcSessionTest, TestSessionCandidatesWithRtcpMux) {
1042 TestSessionCandidatesWithBundleRtcpMux(false, true);
1043}
1044
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001045TEST_F(WebRtcSessionTest, TestSessionCandidatesWithBundleRtcpMux) {
1046 TestSessionCandidatesWithBundleRtcpMux(true, true);
1047}
1048
1049TEST_F(WebRtcSessionTest, TestMultihomeCandidates) {
wu@webrtc.org364f2042013-11-20 21:49:41 +00001050 AddInterface(talk_base::SocketAddress(kClientAddrHost1, kClientAddrPort));
1051 AddInterface(talk_base::SocketAddress(kClientAddrHost2, kClientAddrPort));
wu@webrtc.org91053e72013-08-10 07:18:04 +00001052 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001053 mediastream_signaling_.SendAudioVideoStream1();
1054 InitiateCall();
1055 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1056 EXPECT_EQ(8u, observer_.mline_0_candidates_.size());
1057 EXPECT_EQ(8u, observer_.mline_1_candidates_.size());
1058}
1059
1060TEST_F(WebRtcSessionTest, TestStunError) {
wu@webrtc.org364f2042013-11-20 21:49:41 +00001061 AddInterface(talk_base::SocketAddress(kClientAddrHost1, kClientAddrPort));
1062 AddInterface(talk_base::SocketAddress(kClientAddrHost2, kClientAddrPort));
1063 fss_->AddRule(false,
1064 talk_base::FP_UDP,
1065 talk_base::FD_ANY,
1066 talk_base::SocketAddress(kClientAddrHost1, kClientAddrPort));
wu@webrtc.org91053e72013-08-10 07:18:04 +00001067 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001068 mediastream_signaling_.SendAudioVideoStream1();
1069 InitiateCall();
wu@webrtc.org364f2042013-11-20 21:49:41 +00001070 // Since kClientAddrHost1 is blocked, not expecting stun candidates for it.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001071 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1072 EXPECT_EQ(6u, observer_.mline_0_candidates_.size());
1073 EXPECT_EQ(6u, observer_.mline_1_candidates_.size());
1074}
1075
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001076TEST_F(WebRtcSessionTest, SetSdpFailedOnInvalidSdp) {
1077 Init(NULL);
1078 SessionDescriptionInterface* offer = NULL;
1079 // Since |offer| is NULL, there's no way to tell if it's an offer or answer.
1080 std::string unknown_action;
1081 SetLocalDescriptionExpectError(unknown_action, kInvalidSdp, offer);
1082 SetRemoteDescriptionExpectError(unknown_action, kInvalidSdp, offer);
1083}
1084
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001085// Test creating offers and receive answers and make sure the
1086// media engine creates the expected send and receive streams.
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001087TEST_F(WebRtcSessionTest, TestCreateSdesOfferReceiveSdesAnswer) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00001088 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001089 mediastream_signaling_.SendAudioVideoStream1();
wu@webrtc.org91053e72013-08-10 07:18:04 +00001090 SessionDescriptionInterface* offer = CreateOffer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001091 const std::string session_id_orig = offer->session_id();
1092 const std::string session_version_orig = offer->session_version();
1093 SetLocalDescriptionWithoutError(offer);
1094
1095 mediastream_signaling_.SendAudioVideoStream2();
1096 SessionDescriptionInterface* answer =
1097 CreateRemoteAnswer(session_->local_description());
1098 SetRemoteDescriptionWithoutError(answer);
1099
1100 video_channel_ = media_engine_->GetVideoChannel(0);
1101 voice_channel_ = media_engine_->GetVoiceChannel(0);
1102
1103 ASSERT_EQ(1u, video_channel_->recv_streams().size());
1104 EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].id);
1105
1106 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
1107 EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].id);
1108
1109 ASSERT_EQ(1u, video_channel_->send_streams().size());
1110 EXPECT_TRUE(kVideoTrack1 == video_channel_->send_streams()[0].id);
1111 ASSERT_EQ(1u, voice_channel_->send_streams().size());
1112 EXPECT_TRUE(kAudioTrack1 == voice_channel_->send_streams()[0].id);
1113
1114 // Create new offer without send streams.
1115 mediastream_signaling_.SendNothing();
wu@webrtc.org91053e72013-08-10 07:18:04 +00001116 offer = CreateOffer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001117
1118 // Verify the session id is the same and the session version is
1119 // increased.
1120 EXPECT_EQ(session_id_orig, offer->session_id());
1121 EXPECT_LT(talk_base::FromString<uint64>(session_version_orig),
1122 talk_base::FromString<uint64>(offer->session_version()));
1123
1124 SetLocalDescriptionWithoutError(offer);
1125
1126 mediastream_signaling_.SendAudioVideoStream2();
1127 answer = CreateRemoteAnswer(session_->local_description());
1128 SetRemoteDescriptionWithoutError(answer);
1129
1130 EXPECT_EQ(0u, video_channel_->send_streams().size());
1131 EXPECT_EQ(0u, voice_channel_->send_streams().size());
1132
1133 // Make sure the receive streams have not changed.
1134 ASSERT_EQ(1u, video_channel_->recv_streams().size());
1135 EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].id);
1136 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
1137 EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].id);
1138}
1139
1140// Test receiving offers and creating answers and make sure the
1141// media engine creates the expected send and receive streams.
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001142TEST_F(WebRtcSessionTest, TestReceiveSdesOfferCreateSdesAnswer) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00001143 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001144 mediastream_signaling_.SendAudioVideoStream2();
wu@webrtc.org91053e72013-08-10 07:18:04 +00001145 SessionDescriptionInterface* offer = CreateOffer(NULL);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001146 VerifyCryptoParams(offer->description());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001147 SetRemoteDescriptionWithoutError(offer);
1148
1149 mediastream_signaling_.SendAudioVideoStream1();
wu@webrtc.org91053e72013-08-10 07:18:04 +00001150 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001151 VerifyCryptoParams(answer->description());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001152 SetLocalDescriptionWithoutError(answer);
1153
1154 const std::string session_id_orig = answer->session_id();
1155 const std::string session_version_orig = answer->session_version();
1156
1157 video_channel_ = media_engine_->GetVideoChannel(0);
1158 voice_channel_ = media_engine_->GetVoiceChannel(0);
1159
1160 ASSERT_EQ(1u, video_channel_->recv_streams().size());
1161 EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].id);
1162
1163 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
1164 EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].id);
1165
1166 ASSERT_EQ(1u, video_channel_->send_streams().size());
1167 EXPECT_TRUE(kVideoTrack1 == video_channel_->send_streams()[0].id);
1168 ASSERT_EQ(1u, voice_channel_->send_streams().size());
1169 EXPECT_TRUE(kAudioTrack1 == voice_channel_->send_streams()[0].id);
1170
1171 mediastream_signaling_.SendAudioVideoStream1And2();
wu@webrtc.org91053e72013-08-10 07:18:04 +00001172 offer = CreateOffer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001173 SetRemoteDescriptionWithoutError(offer);
1174
1175 // Answer by turning off all send streams.
1176 mediastream_signaling_.SendNothing();
wu@webrtc.org91053e72013-08-10 07:18:04 +00001177 answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001178
1179 // Verify the session id is the same and the session version is
1180 // increased.
1181 EXPECT_EQ(session_id_orig, answer->session_id());
1182 EXPECT_LT(talk_base::FromString<uint64>(session_version_orig),
1183 talk_base::FromString<uint64>(answer->session_version()));
1184 SetLocalDescriptionWithoutError(answer);
1185
1186 ASSERT_EQ(2u, video_channel_->recv_streams().size());
1187 EXPECT_TRUE(kVideoTrack1 == video_channel_->recv_streams()[0].id);
1188 EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[1].id);
1189 ASSERT_EQ(2u, voice_channel_->recv_streams().size());
1190 EXPECT_TRUE(kAudioTrack1 == voice_channel_->recv_streams()[0].id);
1191 EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[1].id);
1192
1193 // Make sure we have no send streams.
1194 EXPECT_EQ(0u, video_channel_->send_streams().size());
1195 EXPECT_EQ(0u, voice_channel_->send_streams().size());
1196}
1197
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001198TEST_F(WebRtcSessionTest, SetLocalSdpFailedOnCreateChannel) {
1199 Init(NULL);
1200 media_engine_->set_fail_create_channel(true);
1201
1202 SessionDescriptionInterface* offer = CreateOffer(NULL);
1203 ASSERT_TRUE(offer != NULL);
1204 // SetRemoteDescription and SetLocalDescription will take the ownership of
1205 // the offer.
1206 SetRemoteDescriptionOfferExpectError(kCreateChannelFailed, offer);
1207 offer = CreateOffer(NULL);
1208 ASSERT_TRUE(offer != NULL);
1209 SetLocalDescriptionOfferExpectError(kCreateChannelFailed, offer);
1210}
1211
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001212//
1213// Tests for creating/setting SDP under different SDES/DTLS polices:
1214//
1215// --DTLS off and SDES on
1216// TestCreateSdesOfferReceiveSdesAnswer/TestReceiveSdesOfferCreateSdesAnswer:
1217// set local/remote offer/answer with crypto --> success
1218// TestSetNonSdesOfferWhenSdesOn: set local/remote offer without crypto --->
1219// failure
1220// TestSetLocalNonSdesAnswerWhenSdesOn: set local answer without crypto -->
1221// failure
1222// TestSetRemoteNonSdesAnswerWhenSdesOn: set remote answer without crypto -->
1223// failure
1224//
1225// --DTLS on and SDES off
1226// TestCreateDtlsOfferReceiveDtlsAnswer/TestReceiveDtlsOfferCreateDtlsAnswer:
1227// set local/remote offer/answer with DTLS fingerprint --> success
1228// TestReceiveNonDtlsOfferWhenDtlsOn: set local/remote offer without DTLS
1229// fingerprint --> failure
1230// TestSetLocalNonDtlsAnswerWhenDtlsOn: set local answer without fingerprint
1231// --> failure
1232// TestSetRemoteNonDtlsAnswerWhenDtlsOn: set remote answer without fingerprint
1233// --> failure
1234//
1235// --Encryption disabled: DTLS off and SDES off
1236// TestCreateOfferReceiveAnswerWithoutEncryption: set local offer and remote
1237// answer without SDES or DTLS --> success
1238// TestCreateAnswerReceiveOfferWithoutEncryption: set remote offer and local
1239// answer without SDES or DTLS --> success
1240//
1241
1242// Test that we return a failure when applying a remote/local offer that doesn't
1243// have cryptos enabled when DTLS is off.
1244TEST_F(WebRtcSessionTest, TestSetNonSdesOfferWhenSdesOn) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00001245 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001246 cricket::MediaSessionOptions options;
1247 options.has_video = true;
1248 JsepSessionDescription* offer = CreateRemoteOffer(
1249 options, cricket::SEC_DISABLED);
1250 ASSERT_TRUE(offer != NULL);
1251 VerifyNoCryptoParams(offer->description(), false);
1252 // SetRemoteDescription and SetLocalDescription will take the ownership of
1253 // the offer.
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001254 SetRemoteDescriptionOfferExpectError(kSdpWithoutSdesCrypto, offer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001255 offer = CreateRemoteOffer(options, cricket::SEC_DISABLED);
1256 ASSERT_TRUE(offer != NULL);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001257 SetLocalDescriptionOfferExpectError(kSdpWithoutSdesCrypto, offer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001258}
1259
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001260// Test that we return a failure when applying a local answer that doesn't have
1261// cryptos enabled when DTLS is off.
1262TEST_F(WebRtcSessionTest, TestSetLocalNonSdesAnswerWhenSdesOn) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00001263 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001264 SessionDescriptionInterface* offer = NULL;
1265 SessionDescriptionInterface* answer = NULL;
1266 CreateCryptoOfferAndNonCryptoAnswer(&offer, &answer);
1267 // SetRemoteDescription and SetLocalDescription will take the ownership of
1268 // the offer.
1269 SetRemoteDescriptionWithoutError(offer);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001270 SetLocalDescriptionAnswerExpectError(kSdpWithoutSdesCrypto, answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001271}
1272
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001273// Test we will return fail when apply an remote answer that doesn't have
1274// crypto enabled when DTLS is off.
1275TEST_F(WebRtcSessionTest, TestSetRemoteNonSdesAnswerWhenSdesOn) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00001276 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001277 SessionDescriptionInterface* offer = NULL;
1278 SessionDescriptionInterface* answer = NULL;
1279 CreateCryptoOfferAndNonCryptoAnswer(&offer, &answer);
1280 // SetRemoteDescription and SetLocalDescription will take the ownership of
1281 // the offer.
1282 SetLocalDescriptionWithoutError(offer);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001283 SetRemoteDescriptionAnswerExpectError(kSdpWithoutSdesCrypto, answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001284}
1285
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001286// Test that we accept an offer with a DTLS fingerprint when DTLS is on
1287// and that we return an answer with a DTLS fingerprint.
1288TEST_F(WebRtcSessionTest, TestReceiveDtlsOfferCreateDtlsAnswer) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001289 MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001290 mediastream_signaling_.SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001291 InitWithDtls();
1292 SetFactoryDtlsSrtp();
1293 cricket::MediaSessionOptions options;
1294 options.has_video = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001295 JsepSessionDescription* offer =
1296 CreateRemoteOffer(options, cricket::SEC_DISABLED);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001297 ASSERT_TRUE(offer != NULL);
1298 VerifyFingerprintStatus(offer->description(), true);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001299 VerifyNoCryptoParams(offer->description(), true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001300
1301 // SetRemoteDescription will take the ownership of the offer.
1302 SetRemoteDescriptionWithoutError(offer);
1303
1304 // Verify that we get a crypto fingerprint in the answer.
wu@webrtc.org91053e72013-08-10 07:18:04 +00001305 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001306 ASSERT_TRUE(answer != NULL);
1307 VerifyFingerprintStatus(answer->description(), true);
1308 // Check that we don't have an a=crypto line in the answer.
1309 VerifyNoCryptoParams(answer->description(), true);
1310
1311 // Now set the local description, which should work, even without a=crypto.
1312 SetLocalDescriptionWithoutError(answer);
1313}
1314
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001315// Test that we set a local offer with a DTLS fingerprint when DTLS is on
1316// and then we accept a remote answer with a DTLS fingerprint successfully.
1317TEST_F(WebRtcSessionTest, TestCreateDtlsOfferReceiveDtlsAnswer) {
1318 MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
1319 mediastream_signaling_.SendAudioVideoStream1();
1320 InitWithDtls();
1321 SetFactoryDtlsSrtp();
1322
1323 // Verify that we get a crypto fingerprint in the answer.
1324 SessionDescriptionInterface* offer = CreateOffer(NULL);
1325 ASSERT_TRUE(offer != NULL);
1326 VerifyFingerprintStatus(offer->description(), true);
1327 // Check that we don't have an a=crypto line in the offer.
1328 VerifyNoCryptoParams(offer->description(), true);
1329
1330 // Now set the local description, which should work, even without a=crypto.
1331 SetLocalDescriptionWithoutError(offer);
1332
1333 cricket::MediaSessionOptions options;
1334 options.has_video = true;
1335 JsepSessionDescription* answer =
1336 CreateRemoteAnswer(offer, options, cricket::SEC_DISABLED);
1337 ASSERT_TRUE(answer != NULL);
1338 VerifyFingerprintStatus(answer->description(), true);
1339 VerifyNoCryptoParams(answer->description(), true);
1340
1341 // SetRemoteDescription will take the ownership of the answer.
1342 SetRemoteDescriptionWithoutError(answer);
1343}
1344
1345// Test that if we support DTLS and the other side didn't offer a fingerprint,
1346// we will fail to set the remote description.
1347TEST_F(WebRtcSessionTest, TestReceiveNonDtlsOfferWhenDtlsOn) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001348 MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
1349 InitWithDtls();
1350 cricket::MediaSessionOptions options;
1351 options.has_video = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001352 options.bundle_enabled = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001353 JsepSessionDescription* offer = CreateRemoteOffer(
1354 options, cricket::SEC_REQUIRED);
1355 ASSERT_TRUE(offer != NULL);
1356 VerifyFingerprintStatus(offer->description(), false);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001357 VerifyCryptoParams(offer->description());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001358
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001359 // SetRemoteDescription will take the ownership of the offer.
1360 SetRemoteDescriptionOfferExpectError(
1361 kSdpWithoutDtlsFingerprint, offer);
1362
1363 offer = CreateRemoteOffer(options, cricket::SEC_REQUIRED);
1364 // SetLocalDescription will take the ownership of the offer.
1365 SetLocalDescriptionOfferExpectError(
1366 kSdpWithoutDtlsFingerprint, offer);
1367}
1368
1369// Test that we return a failure when applying a local answer that doesn't have
1370// a DTLS fingerprint when DTLS is required.
1371TEST_F(WebRtcSessionTest, TestSetLocalNonDtlsAnswerWhenDtlsOn) {
1372 MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
1373 InitWithDtls();
1374 SessionDescriptionInterface* offer = NULL;
1375 SessionDescriptionInterface* answer = NULL;
1376 CreateDtlsOfferAndNonDtlsAnswer(&offer, &answer);
1377
1378 // SetRemoteDescription and SetLocalDescription will take the ownership of
1379 // the offer and answer.
1380 SetRemoteDescriptionWithoutError(offer);
1381 SetLocalDescriptionAnswerExpectError(
1382 kSdpWithoutDtlsFingerprint, answer);
1383}
1384
1385// Test that we return a failure when applying a remote answer that doesn't have
1386// a DTLS fingerprint when DTLS is required.
1387TEST_F(WebRtcSessionTest, TestSetRemoteNonDtlsAnswerWhenDtlsOn) {
1388 MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
1389 InitWithDtls();
1390 SessionDescriptionInterface* offer = CreateOffer(NULL);
1391 cricket::MediaSessionOptions options;
1392 options.has_video = true;
1393 JsepSessionDescription* answer =
1394 CreateRemoteAnswer(offer, options, cricket::SEC_ENABLED);
1395
1396 // SetRemoteDescription and SetLocalDescription will take the ownership of
1397 // the offer and answer.
1398 SetLocalDescriptionWithoutError(offer);
1399 SetRemoteDescriptionAnswerExpectError(
1400 kSdpWithoutDtlsFingerprint, answer);
1401}
1402
1403// Test that we create a local offer without SDES or DTLS and accept a remote
1404// answer without SDES or DTLS when encryption is disabled.
1405TEST_F(WebRtcSessionTest, TestCreateOfferReceiveAnswerWithoutEncryption) {
1406 mediastream_signaling_.SendAudioVideoStream1();
1407 options_.disable_encryption = true;
1408 InitWithDtls();
1409
1410 // Verify that we get a crypto fingerprint in the answer.
1411 SessionDescriptionInterface* offer = CreateOffer(NULL);
1412 ASSERT_TRUE(offer != NULL);
1413 VerifyFingerprintStatus(offer->description(), false);
1414 // Check that we don't have an a=crypto line in the offer.
1415 VerifyNoCryptoParams(offer->description(), false);
1416
1417 // Now set the local description, which should work, even without a=crypto.
1418 SetLocalDescriptionWithoutError(offer);
1419
1420 cricket::MediaSessionOptions options;
1421 options.has_video = true;
1422 JsepSessionDescription* answer =
1423 CreateRemoteAnswer(offer, options, cricket::SEC_DISABLED);
1424 ASSERT_TRUE(answer != NULL);
1425 VerifyFingerprintStatus(answer->description(), false);
1426 VerifyNoCryptoParams(answer->description(), false);
1427
1428 // SetRemoteDescription will take the ownership of the answer.
1429 SetRemoteDescriptionWithoutError(answer);
1430}
1431
1432// Test that we create a local answer without SDES or DTLS and accept a remote
1433// offer without SDES or DTLS when encryption is disabled.
1434TEST_F(WebRtcSessionTest, TestCreateAnswerReceiveOfferWithoutEncryption) {
1435 options_.disable_encryption = true;
1436 InitWithDtls();
1437
1438 cricket::MediaSessionOptions options;
1439 options.has_video = true;
1440 JsepSessionDescription* offer =
1441 CreateRemoteOffer(options, cricket::SEC_DISABLED);
1442 ASSERT_TRUE(offer != NULL);
1443 VerifyFingerprintStatus(offer->description(), false);
1444 VerifyNoCryptoParams(offer->description(), false);
1445
1446 // SetRemoteDescription will take the ownership of the offer.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001447 SetRemoteDescriptionWithoutError(offer);
1448
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001449 // Verify that we get a crypto fingerprint in the answer.
wu@webrtc.org91053e72013-08-10 07:18:04 +00001450 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001451 ASSERT_TRUE(answer != NULL);
1452 VerifyFingerprintStatus(answer->description(), false);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001453 // Check that we don't have an a=crypto line in the answer.
1454 VerifyNoCryptoParams(answer->description(), false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001455
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001456 // Now set the local description, which should work, even without a=crypto.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001457 SetLocalDescriptionWithoutError(answer);
1458}
1459
1460TEST_F(WebRtcSessionTest, TestSetLocalOfferTwice) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00001461 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001462 mediastream_signaling_.SendNothing();
1463 // SetLocalDescription take ownership of offer.
wu@webrtc.org91053e72013-08-10 07:18:04 +00001464 SessionDescriptionInterface* offer = CreateOffer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001465 SetLocalDescriptionWithoutError(offer);
1466
1467 // SetLocalDescription take ownership of offer.
wu@webrtc.org91053e72013-08-10 07:18:04 +00001468 SessionDescriptionInterface* offer2 = CreateOffer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001469 SetLocalDescriptionWithoutError(offer2);
1470}
1471
1472TEST_F(WebRtcSessionTest, TestSetRemoteOfferTwice) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00001473 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001474 mediastream_signaling_.SendNothing();
1475 // SetLocalDescription take ownership of offer.
wu@webrtc.org91053e72013-08-10 07:18:04 +00001476 SessionDescriptionInterface* offer = CreateOffer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001477 SetRemoteDescriptionWithoutError(offer);
1478
wu@webrtc.org91053e72013-08-10 07:18:04 +00001479 SessionDescriptionInterface* offer2 = CreateOffer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001480 SetRemoteDescriptionWithoutError(offer2);
1481}
1482
1483TEST_F(WebRtcSessionTest, TestSetLocalAndRemoteOffer) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00001484 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001485 mediastream_signaling_.SendNothing();
wu@webrtc.org91053e72013-08-10 07:18:04 +00001486 SessionDescriptionInterface* offer = CreateOffer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001487 SetLocalDescriptionWithoutError(offer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00001488 offer = CreateOffer(NULL);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001489 SetRemoteDescriptionOfferExpectError(
1490 "Called in wrong state: STATE_SENTINITIATE", offer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001491}
1492
1493TEST_F(WebRtcSessionTest, TestSetRemoteAndLocalOffer) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00001494 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001495 mediastream_signaling_.SendNothing();
wu@webrtc.org91053e72013-08-10 07:18:04 +00001496 SessionDescriptionInterface* offer = CreateOffer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001497 SetRemoteDescriptionWithoutError(offer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00001498 offer = CreateOffer(NULL);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001499 SetLocalDescriptionOfferExpectError(
1500 "Called in wrong state: STATE_RECEIVEDINITIATE", offer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001501}
1502
1503TEST_F(WebRtcSessionTest, TestSetLocalPrAnswer) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00001504 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001505 mediastream_signaling_.SendNothing();
1506 SessionDescriptionInterface* offer = CreateRemoteOffer();
1507 SetRemoteDescriptionExpectState(offer, BaseSession::STATE_RECEIVEDINITIATE);
1508
1509 JsepSessionDescription* pranswer = static_cast<JsepSessionDescription*>(
wu@webrtc.org91053e72013-08-10 07:18:04 +00001510 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001511 pranswer->set_type(SessionDescriptionInterface::kPrAnswer);
1512 SetLocalDescriptionExpectState(pranswer, BaseSession::STATE_SENTPRACCEPT);
1513
1514 mediastream_signaling_.SendAudioVideoStream1();
1515 JsepSessionDescription* pranswer2 = static_cast<JsepSessionDescription*>(
wu@webrtc.org91053e72013-08-10 07:18:04 +00001516 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001517 pranswer2->set_type(SessionDescriptionInterface::kPrAnswer);
1518
1519 SetLocalDescriptionExpectState(pranswer2, BaseSession::STATE_SENTPRACCEPT);
1520
1521 mediastream_signaling_.SendAudioVideoStream2();
wu@webrtc.org91053e72013-08-10 07:18:04 +00001522 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001523 SetLocalDescriptionExpectState(answer, BaseSession::STATE_SENTACCEPT);
1524}
1525
1526TEST_F(WebRtcSessionTest, TestSetRemotePrAnswer) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00001527 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001528 mediastream_signaling_.SendNothing();
wu@webrtc.org91053e72013-08-10 07:18:04 +00001529 SessionDescriptionInterface* offer = CreateOffer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001530 SetLocalDescriptionExpectState(offer, BaseSession::STATE_SENTINITIATE);
1531
1532 JsepSessionDescription* pranswer =
1533 CreateRemoteAnswer(session_->local_description());
1534 pranswer->set_type(SessionDescriptionInterface::kPrAnswer);
1535
1536 SetRemoteDescriptionExpectState(pranswer,
1537 BaseSession::STATE_RECEIVEDPRACCEPT);
1538
1539 mediastream_signaling_.SendAudioVideoStream1();
1540 JsepSessionDescription* pranswer2 =
1541 CreateRemoteAnswer(session_->local_description());
1542 pranswer2->set_type(SessionDescriptionInterface::kPrAnswer);
1543
1544 SetRemoteDescriptionExpectState(pranswer2,
1545 BaseSession::STATE_RECEIVEDPRACCEPT);
1546
1547 mediastream_signaling_.SendAudioVideoStream2();
1548 SessionDescriptionInterface* answer =
1549 CreateRemoteAnswer(session_->local_description());
1550 SetRemoteDescriptionExpectState(answer, BaseSession::STATE_RECEIVEDACCEPT);
1551}
1552
1553TEST_F(WebRtcSessionTest, TestSetLocalAnswerWithoutOffer) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00001554 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001555 mediastream_signaling_.SendNothing();
1556 talk_base::scoped_ptr<SessionDescriptionInterface> offer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00001557 CreateOffer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001558 SessionDescriptionInterface* answer =
1559 CreateRemoteAnswer(offer.get());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001560 SetLocalDescriptionAnswerExpectError("Called in wrong state: STATE_INIT",
1561 answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001562}
1563
1564TEST_F(WebRtcSessionTest, TestSetRemoteAnswerWithoutOffer) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00001565 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001566 mediastream_signaling_.SendNothing();
1567 talk_base::scoped_ptr<SessionDescriptionInterface> offer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00001568 CreateOffer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001569 SessionDescriptionInterface* answer =
1570 CreateRemoteAnswer(offer.get());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001571 SetRemoteDescriptionAnswerExpectError(
1572 "Called in wrong state: STATE_INIT", answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001573}
1574
1575TEST_F(WebRtcSessionTest, TestAddRemoteCandidate) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00001576 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001577 mediastream_signaling_.SendAudioVideoStream1();
1578
1579 cricket::Candidate candidate;
1580 candidate.set_component(1);
1581 JsepIceCandidate ice_candidate1(kMediaContentName0, 0, candidate);
1582
1583 // Fail since we have not set a offer description.
1584 EXPECT_FALSE(session_->ProcessIceMessage(&ice_candidate1));
1585
wu@webrtc.org91053e72013-08-10 07:18:04 +00001586 SessionDescriptionInterface* offer = CreateOffer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001587 SetLocalDescriptionWithoutError(offer);
1588 // Candidate should be allowed to add before remote description.
1589 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate1));
1590 candidate.set_component(2);
1591 JsepIceCandidate ice_candidate2(kMediaContentName0, 0, candidate);
1592 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate2));
1593
1594 SessionDescriptionInterface* answer = CreateRemoteAnswer(
1595 session_->local_description());
1596 SetRemoteDescriptionWithoutError(answer);
1597
1598 // Verifying the candidates are copied properly from internal vector.
1599 const SessionDescriptionInterface* remote_desc =
1600 session_->remote_description();
1601 ASSERT_TRUE(remote_desc != NULL);
1602 ASSERT_EQ(2u, remote_desc->number_of_mediasections());
1603 const IceCandidateCollection* candidates =
1604 remote_desc->candidates(kMediaContentIndex0);
1605 ASSERT_EQ(2u, candidates->count());
1606 EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
1607 EXPECT_EQ(kMediaContentName0, candidates->at(0)->sdp_mid());
1608 EXPECT_EQ(1, candidates->at(0)->candidate().component());
1609 EXPECT_EQ(2, candidates->at(1)->candidate().component());
1610
mallinath@webrtc.org67ee6b92014-02-03 16:57:16 +00001611 // |ice_candidate3| is identical to |ice_candidate2|. It can be added
1612 // successfully, but the total count of candidates will not increase.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001613 candidate.set_component(2);
1614 JsepIceCandidate ice_candidate3(kMediaContentName0, 0, candidate);
1615 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate3));
mallinath@webrtc.org67ee6b92014-02-03 16:57:16 +00001616 ASSERT_EQ(2u, candidates->count());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001617
1618 JsepIceCandidate bad_ice_candidate("bad content name", 99, candidate);
1619 EXPECT_FALSE(session_->ProcessIceMessage(&bad_ice_candidate));
1620}
1621
1622// Test that a remote candidate is added to the remote session description and
1623// that it is retained if the remote session description is changed.
1624TEST_F(WebRtcSessionTest, TestRemoteCandidatesAddedToSessionDescription) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00001625 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001626 cricket::Candidate candidate1;
1627 candidate1.set_component(1);
1628 JsepIceCandidate ice_candidate1(kMediaContentName0, kMediaContentIndex0,
1629 candidate1);
1630 mediastream_signaling_.SendAudioVideoStream1();
1631 CreateAndSetRemoteOfferAndLocalAnswer();
1632
1633 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate1));
1634 const SessionDescriptionInterface* remote_desc =
1635 session_->remote_description();
1636 ASSERT_TRUE(remote_desc != NULL);
1637 ASSERT_EQ(2u, remote_desc->number_of_mediasections());
1638 const IceCandidateCollection* candidates =
1639 remote_desc->candidates(kMediaContentIndex0);
1640 ASSERT_EQ(1u, candidates->count());
1641 EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
1642
1643 // Update the RemoteSessionDescription with a new session description and
1644 // a candidate and check that the new remote session description contains both
1645 // candidates.
1646 SessionDescriptionInterface* offer = CreateRemoteOffer();
1647 cricket::Candidate candidate2;
1648 JsepIceCandidate ice_candidate2(kMediaContentName0, kMediaContentIndex0,
1649 candidate2);
1650 EXPECT_TRUE(offer->AddCandidate(&ice_candidate2));
1651 SetRemoteDescriptionWithoutError(offer);
1652
1653 remote_desc = session_->remote_description();
1654 ASSERT_TRUE(remote_desc != NULL);
1655 ASSERT_EQ(2u, remote_desc->number_of_mediasections());
1656 candidates = remote_desc->candidates(kMediaContentIndex0);
1657 ASSERT_EQ(2u, candidates->count());
1658 EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
1659 // Username and password have be updated with the TransportInfo of the
1660 // SessionDescription, won't be equal to the original one.
1661 candidate2.set_username(candidates->at(0)->candidate().username());
1662 candidate2.set_password(candidates->at(0)->candidate().password());
1663 EXPECT_TRUE(candidate2.IsEquivalent(candidates->at(0)->candidate()));
1664 EXPECT_EQ(kMediaContentIndex0, candidates->at(1)->sdp_mline_index());
1665 // No need to verify the username and password.
1666 candidate1.set_username(candidates->at(1)->candidate().username());
1667 candidate1.set_password(candidates->at(1)->candidate().password());
1668 EXPECT_TRUE(candidate1.IsEquivalent(candidates->at(1)->candidate()));
1669
1670 // Test that the candidate is ignored if we can add the same candidate again.
1671 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate2));
1672}
1673
1674// Test that local candidates are added to the local session description and
1675// that they are retained if the local session description is changed.
1676TEST_F(WebRtcSessionTest, TestLocalCandidatesAddedToSessionDescription) {
wu@webrtc.org364f2042013-11-20 21:49:41 +00001677 AddInterface(talk_base::SocketAddress(kClientAddrHost1, kClientAddrPort));
wu@webrtc.org91053e72013-08-10 07:18:04 +00001678 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001679 mediastream_signaling_.SendAudioVideoStream1();
1680 CreateAndSetRemoteOfferAndLocalAnswer();
1681
1682 const SessionDescriptionInterface* local_desc = session_->local_description();
1683 const IceCandidateCollection* candidates =
1684 local_desc->candidates(kMediaContentIndex0);
1685 ASSERT_TRUE(candidates != NULL);
1686 EXPECT_EQ(0u, candidates->count());
1687
1688 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1689
1690 local_desc = session_->local_description();
1691 candidates = local_desc->candidates(kMediaContentIndex0);
1692 ASSERT_TRUE(candidates != NULL);
1693 EXPECT_LT(0u, candidates->count());
1694 candidates = local_desc->candidates(1);
1695 ASSERT_TRUE(candidates != NULL);
1696 EXPECT_LT(0u, candidates->count());
1697
1698 // Update the session descriptions.
1699 mediastream_signaling_.SendAudioVideoStream1();
1700 CreateAndSetRemoteOfferAndLocalAnswer();
1701
1702 local_desc = session_->local_description();
1703 candidates = local_desc->candidates(kMediaContentIndex0);
1704 ASSERT_TRUE(candidates != NULL);
1705 EXPECT_LT(0u, candidates->count());
1706 candidates = local_desc->candidates(1);
1707 ASSERT_TRUE(candidates != NULL);
1708 EXPECT_LT(0u, candidates->count());
1709}
1710
1711// Test that we can set a remote session description with remote candidates.
1712TEST_F(WebRtcSessionTest, TestSetRemoteSessionDescriptionWithCandidates) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00001713 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001714
1715 cricket::Candidate candidate1;
1716 candidate1.set_component(1);
1717 JsepIceCandidate ice_candidate(kMediaContentName0, kMediaContentIndex0,
1718 candidate1);
1719 mediastream_signaling_.SendAudioVideoStream1();
wu@webrtc.org91053e72013-08-10 07:18:04 +00001720 SessionDescriptionInterface* offer = CreateOffer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001721
1722 EXPECT_TRUE(offer->AddCandidate(&ice_candidate));
1723 SetRemoteDescriptionWithoutError(offer);
1724
1725 const SessionDescriptionInterface* remote_desc =
1726 session_->remote_description();
1727 ASSERT_TRUE(remote_desc != NULL);
1728 ASSERT_EQ(2u, remote_desc->number_of_mediasections());
1729 const IceCandidateCollection* candidates =
1730 remote_desc->candidates(kMediaContentIndex0);
1731 ASSERT_EQ(1u, candidates->count());
1732 EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
1733
wu@webrtc.org91053e72013-08-10 07:18:04 +00001734 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001735 SetLocalDescriptionWithoutError(answer);
1736}
1737
1738// Test that offers and answers contains ice candidates when Ice candidates have
1739// been gathered.
1740TEST_F(WebRtcSessionTest, TestSetLocalAndRemoteDescriptionWithCandidates) {
wu@webrtc.org364f2042013-11-20 21:49:41 +00001741 AddInterface(talk_base::SocketAddress(kClientAddrHost1, kClientAddrPort));
wu@webrtc.org91053e72013-08-10 07:18:04 +00001742 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001743 mediastream_signaling_.SendAudioVideoStream1();
1744 // Ice is started but candidates are not provided until SetLocalDescription
1745 // is called.
1746 EXPECT_EQ(0u, observer_.mline_0_candidates_.size());
1747 EXPECT_EQ(0u, observer_.mline_1_candidates_.size());
1748 CreateAndSetRemoteOfferAndLocalAnswer();
1749 // Wait until at least one local candidate has been collected.
1750 EXPECT_TRUE_WAIT(0u < observer_.mline_0_candidates_.size(),
1751 kIceCandidatesTimeout);
1752 EXPECT_TRUE_WAIT(0u < observer_.mline_1_candidates_.size(),
1753 kIceCandidatesTimeout);
1754
1755 talk_base::scoped_ptr<SessionDescriptionInterface> local_offer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00001756 CreateOffer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001757 ASSERT_TRUE(local_offer->candidates(kMediaContentIndex0) != NULL);
1758 EXPECT_LT(0u, local_offer->candidates(kMediaContentIndex0)->count());
1759 ASSERT_TRUE(local_offer->candidates(kMediaContentIndex1) != NULL);
1760 EXPECT_LT(0u, local_offer->candidates(kMediaContentIndex1)->count());
1761
1762 SessionDescriptionInterface* remote_offer(CreateRemoteOffer());
1763 SetRemoteDescriptionWithoutError(remote_offer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00001764 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001765 ASSERT_TRUE(answer->candidates(kMediaContentIndex0) != NULL);
1766 EXPECT_LT(0u, answer->candidates(kMediaContentIndex0)->count());
1767 ASSERT_TRUE(answer->candidates(kMediaContentIndex1) != NULL);
1768 EXPECT_LT(0u, answer->candidates(kMediaContentIndex1)->count());
1769 SetLocalDescriptionWithoutError(answer);
1770}
1771
1772// Verifies TransportProxy and media channels are created with content names
1773// present in the SessionDescription.
1774TEST_F(WebRtcSessionTest, TestChannelCreationsWithContentNames) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00001775 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001776 mediastream_signaling_.SendAudioVideoStream1();
1777 talk_base::scoped_ptr<SessionDescriptionInterface> offer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00001778 CreateOffer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001779
1780 // CreateOffer creates session description with the content names "audio" and
1781 // "video". Goal is to modify these content names and verify transport channel
1782 // proxy in the BaseSession, as proxies are created with the content names
1783 // present in SDP.
1784 std::string sdp;
1785 EXPECT_TRUE(offer->ToString(&sdp));
1786 const std::string kAudioMid = "a=mid:audio";
1787 const std::string kAudioMidReplaceStr = "a=mid:audio_content_name";
1788 const std::string kVideoMid = "a=mid:video";
1789 const std::string kVideoMidReplaceStr = "a=mid:video_content_name";
1790
1791 // Replacing |audio| with |audio_content_name|.
1792 talk_base::replace_substrs(kAudioMid.c_str(), kAudioMid.length(),
1793 kAudioMidReplaceStr.c_str(),
1794 kAudioMidReplaceStr.length(),
1795 &sdp);
1796 // Replacing |video| with |video_content_name|.
1797 talk_base::replace_substrs(kVideoMid.c_str(), kVideoMid.length(),
1798 kVideoMidReplaceStr.c_str(),
1799 kVideoMidReplaceStr.length(),
1800 &sdp);
1801
1802 SessionDescriptionInterface* modified_offer =
1803 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
1804
1805 SetRemoteDescriptionWithoutError(modified_offer);
1806
1807 SessionDescriptionInterface* answer =
wu@webrtc.org91053e72013-08-10 07:18:04 +00001808 CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001809 SetLocalDescriptionWithoutError(answer);
1810
1811 EXPECT_TRUE(session_->GetTransportProxy("audio_content_name") != NULL);
1812 EXPECT_TRUE(session_->GetTransportProxy("video_content_name") != NULL);
1813 EXPECT_TRUE((video_channel_ = media_engine_->GetVideoChannel(0)) != NULL);
1814 EXPECT_TRUE((voice_channel_ = media_engine_->GetVoiceChannel(0)) != NULL);
1815}
1816
1817// Test that an offer contains the correct media content descriptions based on
1818// the send streams when no constraints have been set.
1819TEST_F(WebRtcSessionTest, CreateOfferWithoutConstraintsOrStreams) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00001820 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001821 talk_base::scoped_ptr<SessionDescriptionInterface> offer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00001822 CreateOffer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001823 ASSERT_TRUE(offer != NULL);
1824 const cricket::ContentInfo* content =
1825 cricket::GetFirstAudioContent(offer->description());
1826 EXPECT_TRUE(content != NULL);
1827 content = cricket::GetFirstVideoContent(offer->description());
1828 EXPECT_TRUE(content == NULL);
1829}
1830
1831// Test that an offer contains the correct media content descriptions based on
1832// the send streams when no constraints have been set.
1833TEST_F(WebRtcSessionTest, CreateOfferWithoutConstraints) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00001834 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001835 // Test Audio only offer.
1836 mediastream_signaling_.UseOptionsAudioOnly();
1837 talk_base::scoped_ptr<SessionDescriptionInterface> offer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00001838 CreateOffer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001839 const cricket::ContentInfo* content =
1840 cricket::GetFirstAudioContent(offer->description());
1841 EXPECT_TRUE(content != NULL);
1842 content = cricket::GetFirstVideoContent(offer->description());
1843 EXPECT_TRUE(content == NULL);
1844
1845 // Test Audio / Video offer.
1846 mediastream_signaling_.SendAudioVideoStream1();
wu@webrtc.org91053e72013-08-10 07:18:04 +00001847 offer.reset(CreateOffer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001848 content = cricket::GetFirstAudioContent(offer->description());
1849 EXPECT_TRUE(content != NULL);
1850 content = cricket::GetFirstVideoContent(offer->description());
1851 EXPECT_TRUE(content != NULL);
1852}
1853
1854// Test that an offer contains no media content descriptions if
1855// kOfferToReceiveVideo and kOfferToReceiveAudio constraints are set to false.
1856TEST_F(WebRtcSessionTest, CreateOfferWithConstraintsWithoutStreams) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00001857 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001858 webrtc::FakeConstraints constraints_no_receive;
1859 constraints_no_receive.SetMandatoryReceiveAudio(false);
1860 constraints_no_receive.SetMandatoryReceiveVideo(false);
1861
1862 talk_base::scoped_ptr<SessionDescriptionInterface> offer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00001863 CreateOffer(&constraints_no_receive));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001864 ASSERT_TRUE(offer != NULL);
1865 const cricket::ContentInfo* content =
1866 cricket::GetFirstAudioContent(offer->description());
1867 EXPECT_TRUE(content == NULL);
1868 content = cricket::GetFirstVideoContent(offer->description());
1869 EXPECT_TRUE(content == NULL);
1870}
1871
1872// Test that an offer contains only audio media content descriptions if
1873// kOfferToReceiveAudio constraints are set to true.
1874TEST_F(WebRtcSessionTest, CreateAudioOnlyOfferWithConstraints) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00001875 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001876 webrtc::FakeConstraints constraints_audio_only;
1877 constraints_audio_only.SetMandatoryReceiveAudio(true);
1878 talk_base::scoped_ptr<SessionDescriptionInterface> offer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00001879 CreateOffer(&constraints_audio_only));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001880
1881 const cricket::ContentInfo* content =
1882 cricket::GetFirstAudioContent(offer->description());
1883 EXPECT_TRUE(content != NULL);
1884 content = cricket::GetFirstVideoContent(offer->description());
1885 EXPECT_TRUE(content == NULL);
1886}
1887
1888// Test that an offer contains audio and video media content descriptions if
1889// kOfferToReceiveAudio and kOfferToReceiveVideo constraints are set to true.
1890TEST_F(WebRtcSessionTest, CreateOfferWithConstraints) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00001891 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001892 // Test Audio / Video offer.
1893 webrtc::FakeConstraints constraints_audio_video;
1894 constraints_audio_video.SetMandatoryReceiveAudio(true);
1895 constraints_audio_video.SetMandatoryReceiveVideo(true);
1896 talk_base::scoped_ptr<SessionDescriptionInterface> offer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00001897 CreateOffer(&constraints_audio_video));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001898 const cricket::ContentInfo* content =
1899 cricket::GetFirstAudioContent(offer->description());
1900
1901 EXPECT_TRUE(content != NULL);
1902 content = cricket::GetFirstVideoContent(offer->description());
1903 EXPECT_TRUE(content != NULL);
1904
1905 // TODO(perkj): Should the direction be set to SEND_ONLY if
1906 // The constraints is set to not receive audio or video but a track is added?
1907}
1908
1909// Test that an answer can not be created if the last remote description is not
1910// an offer.
1911TEST_F(WebRtcSessionTest, CreateAnswerWithoutAnOffer) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00001912 Init(NULL);
1913 SessionDescriptionInterface* offer = CreateOffer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001914 SetLocalDescriptionWithoutError(offer);
1915 SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
1916 SetRemoteDescriptionWithoutError(answer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00001917 EXPECT_TRUE(CreateAnswer(NULL) == NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001918}
1919
1920// Test that an answer contains the correct media content descriptions when no
1921// constraints have been set.
1922TEST_F(WebRtcSessionTest, CreateAnswerWithoutConstraintsOrStreams) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00001923 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001924 // Create a remote offer with audio and video content.
1925 talk_base::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
1926 SetRemoteDescriptionWithoutError(offer.release());
1927 talk_base::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00001928 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001929 const cricket::ContentInfo* content =
1930 cricket::GetFirstAudioContent(answer->description());
1931 ASSERT_TRUE(content != NULL);
1932 EXPECT_FALSE(content->rejected);
1933
1934 content = cricket::GetFirstVideoContent(answer->description());
1935 ASSERT_TRUE(content != NULL);
1936 EXPECT_FALSE(content->rejected);
1937}
1938
1939// Test that an answer contains the correct media content descriptions when no
1940// constraints have been set and the offer only contain audio.
1941TEST_F(WebRtcSessionTest, CreateAudioAnswerWithoutConstraintsOrStreams) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00001942 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001943 // Create a remote offer with audio only.
1944 cricket::MediaSessionOptions options;
1945 options.has_audio = true;
1946 options.has_video = false;
1947 talk_base::scoped_ptr<JsepSessionDescription> offer(
1948 CreateRemoteOffer(options));
1949 ASSERT_TRUE(cricket::GetFirstVideoContent(offer->description()) == NULL);
1950 ASSERT_TRUE(cricket::GetFirstAudioContent(offer->description()) != NULL);
1951
1952 SetRemoteDescriptionWithoutError(offer.release());
1953 talk_base::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00001954 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001955 const cricket::ContentInfo* content =
1956 cricket::GetFirstAudioContent(answer->description());
1957 ASSERT_TRUE(content != NULL);
1958 EXPECT_FALSE(content->rejected);
1959
1960 EXPECT_TRUE(cricket::GetFirstVideoContent(answer->description()) == NULL);
1961}
1962
1963// Test that an answer contains the correct media content descriptions when no
1964// constraints have been set.
1965TEST_F(WebRtcSessionTest, CreateAnswerWithoutConstraints) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00001966 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001967 // Create a remote offer with audio and video content.
1968 talk_base::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
1969 SetRemoteDescriptionWithoutError(offer.release());
1970 // Test with a stream with tracks.
1971 mediastream_signaling_.SendAudioVideoStream1();
1972 talk_base::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00001973 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001974 const cricket::ContentInfo* content =
1975 cricket::GetFirstAudioContent(answer->description());
1976 ASSERT_TRUE(content != NULL);
1977 EXPECT_FALSE(content->rejected);
1978
1979 content = cricket::GetFirstVideoContent(answer->description());
1980 ASSERT_TRUE(content != NULL);
1981 EXPECT_FALSE(content->rejected);
1982}
1983
1984// Test that an answer contains the correct media content descriptions when
1985// constraints have been set but no stream is sent.
1986TEST_F(WebRtcSessionTest, CreateAnswerWithConstraintsWithoutStreams) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00001987 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001988 // Create a remote offer with audio and video content.
1989 talk_base::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
1990 SetRemoteDescriptionWithoutError(offer.release());
1991
1992 webrtc::FakeConstraints constraints_no_receive;
1993 constraints_no_receive.SetMandatoryReceiveAudio(false);
1994 constraints_no_receive.SetMandatoryReceiveVideo(false);
1995
1996 talk_base::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00001997 CreateAnswer(&constraints_no_receive));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001998 const cricket::ContentInfo* content =
1999 cricket::GetFirstAudioContent(answer->description());
2000 ASSERT_TRUE(content != NULL);
2001 EXPECT_TRUE(content->rejected);
2002
2003 content = cricket::GetFirstVideoContent(answer->description());
2004 ASSERT_TRUE(content != NULL);
2005 EXPECT_TRUE(content->rejected);
2006}
2007
2008// Test that an answer contains the correct media content descriptions when
2009// constraints have been set and streams are sent.
2010TEST_F(WebRtcSessionTest, CreateAnswerWithConstraints) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00002011 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002012 // Create a remote offer with audio and video content.
2013 talk_base::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
2014 SetRemoteDescriptionWithoutError(offer.release());
2015
2016 webrtc::FakeConstraints constraints_no_receive;
2017 constraints_no_receive.SetMandatoryReceiveAudio(false);
2018 constraints_no_receive.SetMandatoryReceiveVideo(false);
2019
2020 // Test with a stream with tracks.
2021 mediastream_signaling_.SendAudioVideoStream1();
2022 talk_base::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002023 CreateAnswer(&constraints_no_receive));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002024
2025 // TODO(perkj): Should the direction be set to SEND_ONLY?
2026 const cricket::ContentInfo* content =
2027 cricket::GetFirstAudioContent(answer->description());
2028 ASSERT_TRUE(content != NULL);
2029 EXPECT_FALSE(content->rejected);
2030
2031 // TODO(perkj): Should the direction be set to SEND_ONLY?
2032 content = cricket::GetFirstVideoContent(answer->description());
2033 ASSERT_TRUE(content != NULL);
2034 EXPECT_FALSE(content->rejected);
2035}
2036
2037TEST_F(WebRtcSessionTest, CreateOfferWithoutCNCodecs) {
2038 AddCNCodecs();
wu@webrtc.org91053e72013-08-10 07:18:04 +00002039 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002040 webrtc::FakeConstraints constraints;
2041 constraints.SetOptionalVAD(false);
2042 talk_base::scoped_ptr<SessionDescriptionInterface> offer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002043 CreateOffer(&constraints));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002044 const cricket::ContentInfo* content =
2045 cricket::GetFirstAudioContent(offer->description());
2046 EXPECT_TRUE(content != NULL);
2047 EXPECT_TRUE(VerifyNoCNCodecs(content));
2048}
2049
2050TEST_F(WebRtcSessionTest, CreateAnswerWithoutCNCodecs) {
2051 AddCNCodecs();
wu@webrtc.org91053e72013-08-10 07:18:04 +00002052 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002053 // Create a remote offer with audio and video content.
2054 talk_base::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
2055 SetRemoteDescriptionWithoutError(offer.release());
2056
2057 webrtc::FakeConstraints constraints;
2058 constraints.SetOptionalVAD(false);
2059 talk_base::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002060 CreateAnswer(&constraints));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002061 const cricket::ContentInfo* content =
2062 cricket::GetFirstAudioContent(answer->description());
2063 ASSERT_TRUE(content != NULL);
2064 EXPECT_TRUE(VerifyNoCNCodecs(content));
2065}
2066
2067// This test verifies the call setup when remote answer with audio only and
2068// later updates with video.
2069TEST_F(WebRtcSessionTest, TestAVOfferWithAudioOnlyAnswer) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00002070 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002071 EXPECT_TRUE(media_engine_->GetVideoChannel(0) == NULL);
2072 EXPECT_TRUE(media_engine_->GetVoiceChannel(0) == NULL);
2073
2074 mediastream_signaling_.SendAudioVideoStream1();
wu@webrtc.org91053e72013-08-10 07:18:04 +00002075 SessionDescriptionInterface* offer = CreateOffer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002076
2077 cricket::MediaSessionOptions options;
2078 options.has_video = false;
2079 SessionDescriptionInterface* answer = CreateRemoteAnswer(offer, options);
2080
2081 // SetLocalDescription and SetRemoteDescriptions takes ownership of offer
2082 // and answer;
2083 SetLocalDescriptionWithoutError(offer);
2084 SetRemoteDescriptionWithoutError(answer);
2085
2086 video_channel_ = media_engine_->GetVideoChannel(0);
2087 voice_channel_ = media_engine_->GetVoiceChannel(0);
2088
2089 ASSERT_TRUE(video_channel_ == NULL);
2090
2091 ASSERT_EQ(0u, voice_channel_->recv_streams().size());
2092 ASSERT_EQ(1u, voice_channel_->send_streams().size());
2093 EXPECT_EQ(kAudioTrack1, voice_channel_->send_streams()[0].id);
2094
2095 // Let the remote end update the session descriptions, with Audio and Video.
2096 mediastream_signaling_.SendAudioVideoStream2();
2097 CreateAndSetRemoteOfferAndLocalAnswer();
2098
2099 video_channel_ = media_engine_->GetVideoChannel(0);
2100 voice_channel_ = media_engine_->GetVoiceChannel(0);
2101
2102 ASSERT_TRUE(video_channel_ != NULL);
2103 ASSERT_TRUE(voice_channel_ != NULL);
2104
2105 ASSERT_EQ(1u, video_channel_->recv_streams().size());
2106 ASSERT_EQ(1u, video_channel_->send_streams().size());
2107 EXPECT_EQ(kVideoTrack2, video_channel_->recv_streams()[0].id);
2108 EXPECT_EQ(kVideoTrack2, video_channel_->send_streams()[0].id);
2109 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
2110 ASSERT_EQ(1u, voice_channel_->send_streams().size());
2111 EXPECT_EQ(kAudioTrack2, voice_channel_->recv_streams()[0].id);
2112 EXPECT_EQ(kAudioTrack2, voice_channel_->send_streams()[0].id);
2113
2114 // Change session back to audio only.
2115 mediastream_signaling_.UseOptionsAudioOnly();
2116 CreateAndSetRemoteOfferAndLocalAnswer();
2117
2118 EXPECT_EQ(0u, video_channel_->recv_streams().size());
2119 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
2120 EXPECT_EQ(kAudioTrack2, voice_channel_->recv_streams()[0].id);
2121 ASSERT_EQ(1u, voice_channel_->send_streams().size());
2122 EXPECT_EQ(kAudioTrack2, voice_channel_->send_streams()[0].id);
2123}
2124
2125// This test verifies the call setup when remote answer with video only and
2126// later updates with audio.
2127TEST_F(WebRtcSessionTest, TestAVOfferWithVideoOnlyAnswer) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00002128 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002129 EXPECT_TRUE(media_engine_->GetVideoChannel(0) == NULL);
2130 EXPECT_TRUE(media_engine_->GetVoiceChannel(0) == NULL);
2131 mediastream_signaling_.SendAudioVideoStream1();
wu@webrtc.org91053e72013-08-10 07:18:04 +00002132 SessionDescriptionInterface* offer = CreateOffer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002133
2134 cricket::MediaSessionOptions options;
2135 options.has_audio = false;
2136 options.has_video = true;
2137 SessionDescriptionInterface* answer = CreateRemoteAnswer(
2138 offer, options, cricket::SEC_ENABLED);
2139
2140 // SetLocalDescription and SetRemoteDescriptions takes ownership of offer
2141 // and answer.
2142 SetLocalDescriptionWithoutError(offer);
2143 SetRemoteDescriptionWithoutError(answer);
2144
2145 video_channel_ = media_engine_->GetVideoChannel(0);
2146 voice_channel_ = media_engine_->GetVoiceChannel(0);
2147
2148 ASSERT_TRUE(voice_channel_ == NULL);
2149 ASSERT_TRUE(video_channel_ != NULL);
2150
2151 EXPECT_EQ(0u, video_channel_->recv_streams().size());
2152 ASSERT_EQ(1u, video_channel_->send_streams().size());
2153 EXPECT_EQ(kVideoTrack1, video_channel_->send_streams()[0].id);
2154
2155 // Update the session descriptions, with Audio and Video.
2156 mediastream_signaling_.SendAudioVideoStream2();
2157 CreateAndSetRemoteOfferAndLocalAnswer();
2158
2159 voice_channel_ = media_engine_->GetVoiceChannel(0);
2160 ASSERT_TRUE(voice_channel_ != NULL);
2161
2162 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
2163 ASSERT_EQ(1u, voice_channel_->send_streams().size());
2164 EXPECT_EQ(kAudioTrack2, voice_channel_->recv_streams()[0].id);
2165 EXPECT_EQ(kAudioTrack2, voice_channel_->send_streams()[0].id);
2166
2167 // Change session back to video only.
2168 mediastream_signaling_.UseOptionsVideoOnly();
2169 CreateAndSetRemoteOfferAndLocalAnswer();
2170
2171 video_channel_ = media_engine_->GetVideoChannel(0);
2172 voice_channel_ = media_engine_->GetVoiceChannel(0);
2173
2174 ASSERT_EQ(1u, video_channel_->recv_streams().size());
2175 EXPECT_EQ(kVideoTrack2, video_channel_->recv_streams()[0].id);
2176 ASSERT_EQ(1u, video_channel_->send_streams().size());
2177 EXPECT_EQ(kVideoTrack2, video_channel_->send_streams()[0].id);
2178}
2179
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002180TEST_F(WebRtcSessionTest, VerifyCryptoParamsInSDP) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00002181 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002182 mediastream_signaling_.SendAudioVideoStream1();
2183 scoped_ptr<SessionDescriptionInterface> offer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002184 CreateOffer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002185 VerifyCryptoParams(offer->description());
2186 SetRemoteDescriptionWithoutError(offer.release());
wu@webrtc.org91053e72013-08-10 07:18:04 +00002187 scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002188 VerifyCryptoParams(answer->description());
2189}
2190
2191TEST_F(WebRtcSessionTest, VerifyNoCryptoParamsInSDP) {
wu@webrtc.org97077a32013-10-25 21:18:33 +00002192 options_.disable_encryption = true;
wu@webrtc.org91053e72013-08-10 07:18:04 +00002193 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002194 mediastream_signaling_.SendAudioVideoStream1();
2195 scoped_ptr<SessionDescriptionInterface> offer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002196 CreateOffer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002197 VerifyNoCryptoParams(offer->description(), false);
2198}
2199
2200TEST_F(WebRtcSessionTest, VerifyAnswerFromNonCryptoOffer) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00002201 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002202 VerifyAnswerFromNonCryptoOffer();
2203}
2204
2205TEST_F(WebRtcSessionTest, VerifyAnswerFromCryptoOffer) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00002206 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002207 VerifyAnswerFromCryptoOffer();
2208}
2209
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002210// This test verifies that setLocalDescription fails if
2211// no a=ice-ufrag and a=ice-pwd lines are present in the SDP.
2212TEST_F(WebRtcSessionTest, TestSetLocalDescriptionWithoutIce) {
2213 Init(NULL);
2214 mediastream_signaling_.SendAudioVideoStream1();
2215 talk_base::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer(NULL));
2216 std::string sdp;
2217 RemoveIceUfragPwdLines(offer.get(), &sdp);
2218 SessionDescriptionInterface* modified_offer =
2219 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00002220 SetLocalDescriptionOfferExpectError(kSdpWithoutIceUfragPwd, modified_offer);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002221}
2222
2223// This test verifies that setRemoteDescription fails if
2224// no a=ice-ufrag and a=ice-pwd lines are present in the SDP.
2225TEST_F(WebRtcSessionTest, TestSetRemoteDescriptionWithoutIce) {
2226 Init(NULL);
2227 talk_base::scoped_ptr<SessionDescriptionInterface> offer(CreateRemoteOffer());
2228 std::string sdp;
2229 RemoveIceUfragPwdLines(offer.get(), &sdp);
2230 SessionDescriptionInterface* modified_offer =
2231 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00002232 SetRemoteDescriptionOfferExpectError(kSdpWithoutIceUfragPwd, modified_offer);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002233}
2234
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002235TEST_F(WebRtcSessionTest, VerifyBundleFlagInPA) {
2236 // This test verifies BUNDLE flag in PortAllocator, if BUNDLE information in
2237 // local description is removed by the application, BUNDLE flag should be
2238 // disabled in PortAllocator. By default BUNDLE is enabled in the WebRtc.
wu@webrtc.org91053e72013-08-10 07:18:04 +00002239 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002240 EXPECT_TRUE((cricket::PORTALLOCATOR_ENABLE_BUNDLE & allocator_.flags()) ==
2241 cricket::PORTALLOCATOR_ENABLE_BUNDLE);
2242 talk_base::scoped_ptr<SessionDescriptionInterface> offer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002243 CreateOffer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002244 cricket::SessionDescription* offer_copy =
2245 offer->description()->Copy();
2246 offer_copy->RemoveGroupByName(cricket::GROUP_TYPE_BUNDLE);
2247 JsepSessionDescription* modified_offer =
2248 new JsepSessionDescription(JsepSessionDescription::kOffer);
2249 modified_offer->Initialize(offer_copy, "1", "1");
2250
2251 SetLocalDescriptionWithoutError(modified_offer);
2252 EXPECT_FALSE(allocator_.flags() & cricket::PORTALLOCATOR_ENABLE_BUNDLE);
2253}
2254
2255TEST_F(WebRtcSessionTest, TestDisabledBundleInAnswer) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00002256 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002257 mediastream_signaling_.SendAudioVideoStream1();
2258 EXPECT_TRUE((cricket::PORTALLOCATOR_ENABLE_BUNDLE & allocator_.flags()) ==
2259 cricket::PORTALLOCATOR_ENABLE_BUNDLE);
2260 FakeConstraints constraints;
2261 constraints.SetMandatoryUseRtpMux(true);
wu@webrtc.org91053e72013-08-10 07:18:04 +00002262 SessionDescriptionInterface* offer = CreateOffer(&constraints);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002263 SetLocalDescriptionWithoutError(offer);
2264 mediastream_signaling_.SendAudioVideoStream2();
2265 talk_base::scoped_ptr<SessionDescriptionInterface> answer(
2266 CreateRemoteAnswer(session_->local_description()));
2267 cricket::SessionDescription* answer_copy = answer->description()->Copy();
2268 answer_copy->RemoveGroupByName(cricket::GROUP_TYPE_BUNDLE);
2269 JsepSessionDescription* modified_answer =
2270 new JsepSessionDescription(JsepSessionDescription::kAnswer);
2271 modified_answer->Initialize(answer_copy, "1", "1");
2272 SetRemoteDescriptionWithoutError(modified_answer);
2273 EXPECT_TRUE((cricket::PORTALLOCATOR_ENABLE_BUNDLE & allocator_.flags()) ==
2274 cricket::PORTALLOCATOR_ENABLE_BUNDLE);
2275
2276 video_channel_ = media_engine_->GetVideoChannel(0);
2277 voice_channel_ = media_engine_->GetVoiceChannel(0);
2278
2279 ASSERT_EQ(1u, video_channel_->recv_streams().size());
2280 EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].id);
2281
2282 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
2283 EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].id);
2284
2285 ASSERT_EQ(1u, video_channel_->send_streams().size());
2286 EXPECT_TRUE(kVideoTrack1 == video_channel_->send_streams()[0].id);
2287 ASSERT_EQ(1u, voice_channel_->send_streams().size());
2288 EXPECT_TRUE(kAudioTrack1 == voice_channel_->send_streams()[0].id);
2289}
2290
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002291// This test verifies that SetLocalDescription and SetRemoteDescription fails
2292// if BUNDLE is enabled but rtcp-mux is disabled in m-lines.
2293TEST_F(WebRtcSessionTest, TestDisabledRtcpMuxWithBundleEnabled) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00002294 WebRtcSessionTest::Init(NULL);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002295 mediastream_signaling_.SendAudioVideoStream1();
2296 EXPECT_TRUE((cricket::PORTALLOCATOR_ENABLE_BUNDLE & allocator_.flags()) ==
2297 cricket::PORTALLOCATOR_ENABLE_BUNDLE);
2298 FakeConstraints constraints;
2299 constraints.SetMandatoryUseRtpMux(true);
wu@webrtc.org91053e72013-08-10 07:18:04 +00002300 SessionDescriptionInterface* offer = CreateOffer(&constraints);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002301 std::string offer_str;
2302 offer->ToString(&offer_str);
2303 // Disable rtcp-mux
2304 const std::string rtcp_mux = "rtcp-mux";
2305 const std::string xrtcp_mux = "xrtcp-mux";
2306 talk_base::replace_substrs(rtcp_mux.c_str(), rtcp_mux.length(),
2307 xrtcp_mux.c_str(), xrtcp_mux.length(),
2308 &offer_str);
2309 JsepSessionDescription *local_offer =
2310 new JsepSessionDescription(JsepSessionDescription::kOffer);
2311 EXPECT_TRUE((local_offer)->Initialize(offer_str, NULL));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00002312 SetLocalDescriptionOfferExpectError(kBundleWithoutRtcpMux, local_offer);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002313 JsepSessionDescription *remote_offer =
2314 new JsepSessionDescription(JsepSessionDescription::kOffer);
2315 EXPECT_TRUE((remote_offer)->Initialize(offer_str, NULL));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00002316 SetRemoteDescriptionOfferExpectError(kBundleWithoutRtcpMux, remote_offer);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002317 // Trying unmodified SDP.
2318 SetLocalDescriptionWithoutError(offer);
2319}
2320
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002321TEST_F(WebRtcSessionTest, SetAudioPlayout) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00002322 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002323 mediastream_signaling_.SendAudioVideoStream1();
2324 CreateAndSetRemoteOfferAndLocalAnswer();
2325 cricket::FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0);
2326 ASSERT_TRUE(channel != NULL);
2327 ASSERT_EQ(1u, channel->recv_streams().size());
2328 uint32 receive_ssrc = channel->recv_streams()[0].first_ssrc();
2329 double left_vol, right_vol;
2330 EXPECT_TRUE(channel->GetOutputScaling(receive_ssrc, &left_vol, &right_vol));
2331 EXPECT_EQ(1, left_vol);
2332 EXPECT_EQ(1, right_vol);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002333 talk_base::scoped_ptr<FakeAudioRenderer> renderer(new FakeAudioRenderer());
2334 session_->SetAudioPlayout(receive_ssrc, false, renderer.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002335 EXPECT_TRUE(channel->GetOutputScaling(receive_ssrc, &left_vol, &right_vol));
2336 EXPECT_EQ(0, left_vol);
2337 EXPECT_EQ(0, right_vol);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002338 EXPECT_EQ(0, renderer->channel_id());
2339 session_->SetAudioPlayout(receive_ssrc, true, NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002340 EXPECT_TRUE(channel->GetOutputScaling(receive_ssrc, &left_vol, &right_vol));
2341 EXPECT_EQ(1, left_vol);
2342 EXPECT_EQ(1, right_vol);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002343 EXPECT_EQ(-1, renderer->channel_id());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002344}
2345
2346TEST_F(WebRtcSessionTest, SetAudioSend) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00002347 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002348 mediastream_signaling_.SendAudioVideoStream1();
2349 CreateAndSetRemoteOfferAndLocalAnswer();
2350 cricket::FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0);
2351 ASSERT_TRUE(channel != NULL);
2352 ASSERT_EQ(1u, channel->send_streams().size());
2353 uint32 send_ssrc = channel->send_streams()[0].first_ssrc();
2354 EXPECT_FALSE(channel->IsStreamMuted(send_ssrc));
2355
2356 cricket::AudioOptions options;
2357 options.echo_cancellation.Set(true);
2358
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002359 talk_base::scoped_ptr<FakeAudioRenderer> renderer(new FakeAudioRenderer());
2360 session_->SetAudioSend(send_ssrc, false, options, renderer.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002361 EXPECT_TRUE(channel->IsStreamMuted(send_ssrc));
2362 EXPECT_FALSE(channel->options().echo_cancellation.IsSet());
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002363 EXPECT_EQ(0, renderer->channel_id());
henrike@webrtc.orga7b98182014-02-21 15:51:43 +00002364 EXPECT_TRUE(renderer->sink() != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002365
henrike@webrtc.orga7b98182014-02-21 15:51:43 +00002366 // This will trigger SetSink(NULL) to the |renderer|.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002367 session_->SetAudioSend(send_ssrc, true, options, NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002368 EXPECT_FALSE(channel->IsStreamMuted(send_ssrc));
2369 bool value;
2370 EXPECT_TRUE(channel->options().echo_cancellation.Get(&value));
2371 EXPECT_TRUE(value);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002372 EXPECT_EQ(-1, renderer->channel_id());
henrike@webrtc.orga7b98182014-02-21 15:51:43 +00002373 EXPECT_TRUE(renderer->sink() == NULL);
2374}
2375
2376TEST_F(WebRtcSessionTest, AudioRendererForLocalStream) {
2377 Init(NULL);
2378 mediastream_signaling_.SendAudioVideoStream1();
2379 CreateAndSetRemoteOfferAndLocalAnswer();
2380 cricket::FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0);
2381 ASSERT_TRUE(channel != NULL);
2382 ASSERT_EQ(1u, channel->send_streams().size());
2383 uint32 send_ssrc = channel->send_streams()[0].first_ssrc();
2384
2385 talk_base::scoped_ptr<FakeAudioRenderer> renderer(new FakeAudioRenderer());
2386 cricket::AudioOptions options;
2387 session_->SetAudioSend(send_ssrc, true, options, renderer.get());
2388 EXPECT_TRUE(renderer->sink() != NULL);
2389
2390 // Delete the |renderer| and it will trigger OnClose() to the sink, and this
2391 // will invalidate the |renderer_| pointer in the sink and prevent getting a
2392 // SetSink(NULL) callback afterwards.
2393 renderer.reset();
2394
2395 // This will trigger SetSink(NULL) if no OnClose() callback.
2396 session_->SetAudioSend(send_ssrc, true, options, NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002397}
2398
2399TEST_F(WebRtcSessionTest, SetVideoPlayout) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00002400 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002401 mediastream_signaling_.SendAudioVideoStream1();
2402 CreateAndSetRemoteOfferAndLocalAnswer();
2403 cricket::FakeVideoMediaChannel* channel = media_engine_->GetVideoChannel(0);
2404 ASSERT_TRUE(channel != NULL);
2405 ASSERT_LT(0u, channel->renderers().size());
2406 EXPECT_TRUE(channel->renderers().begin()->second == NULL);
2407 ASSERT_EQ(1u, channel->recv_streams().size());
2408 uint32 receive_ssrc = channel->recv_streams()[0].first_ssrc();
2409 cricket::FakeVideoRenderer renderer;
2410 session_->SetVideoPlayout(receive_ssrc, true, &renderer);
2411 EXPECT_TRUE(channel->renderers().begin()->second == &renderer);
2412 session_->SetVideoPlayout(receive_ssrc, false, &renderer);
2413 EXPECT_TRUE(channel->renderers().begin()->second == NULL);
2414}
2415
2416TEST_F(WebRtcSessionTest, SetVideoSend) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00002417 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002418 mediastream_signaling_.SendAudioVideoStream1();
2419 CreateAndSetRemoteOfferAndLocalAnswer();
2420 cricket::FakeVideoMediaChannel* channel = media_engine_->GetVideoChannel(0);
2421 ASSERT_TRUE(channel != NULL);
2422 ASSERT_EQ(1u, channel->send_streams().size());
2423 uint32 send_ssrc = channel->send_streams()[0].first_ssrc();
2424 EXPECT_FALSE(channel->IsStreamMuted(send_ssrc));
2425 cricket::VideoOptions* options = NULL;
2426 session_->SetVideoSend(send_ssrc, false, options);
2427 EXPECT_TRUE(channel->IsStreamMuted(send_ssrc));
2428 session_->SetVideoSend(send_ssrc, true, options);
2429 EXPECT_FALSE(channel->IsStreamMuted(send_ssrc));
2430}
2431
2432TEST_F(WebRtcSessionTest, CanNotInsertDtmf) {
2433 TestCanInsertDtmf(false);
2434}
2435
2436TEST_F(WebRtcSessionTest, CanInsertDtmf) {
2437 TestCanInsertDtmf(true);
2438}
2439
2440TEST_F(WebRtcSessionTest, InsertDtmf) {
2441 // Setup
wu@webrtc.org91053e72013-08-10 07:18:04 +00002442 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002443 mediastream_signaling_.SendAudioVideoStream1();
2444 CreateAndSetRemoteOfferAndLocalAnswer();
2445 FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0);
2446 EXPECT_EQ(0U, channel->dtmf_info_queue().size());
2447
2448 // Insert DTMF
2449 const int expected_flags = DF_SEND;
2450 const int expected_duration = 90;
2451 session_->InsertDtmf(kAudioTrack1, 0, expected_duration);
2452 session_->InsertDtmf(kAudioTrack1, 1, expected_duration);
2453 session_->InsertDtmf(kAudioTrack1, 2, expected_duration);
2454
2455 // Verify
2456 ASSERT_EQ(3U, channel->dtmf_info_queue().size());
2457 const uint32 send_ssrc = channel->send_streams()[0].first_ssrc();
2458 EXPECT_TRUE(CompareDtmfInfo(channel->dtmf_info_queue()[0], send_ssrc, 0,
2459 expected_duration, expected_flags));
2460 EXPECT_TRUE(CompareDtmfInfo(channel->dtmf_info_queue()[1], send_ssrc, 1,
2461 expected_duration, expected_flags));
2462 EXPECT_TRUE(CompareDtmfInfo(channel->dtmf_info_queue()[2], send_ssrc, 2,
2463 expected_duration, expected_flags));
2464}
2465
2466// This test verifies the |initiator| flag when session initiates the call.
2467TEST_F(WebRtcSessionTest, TestInitiatorFlagAsOriginator) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00002468 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002469 EXPECT_FALSE(session_->initiator());
wu@webrtc.org91053e72013-08-10 07:18:04 +00002470 SessionDescriptionInterface* offer = CreateOffer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002471 SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
2472 SetLocalDescriptionWithoutError(offer);
2473 EXPECT_TRUE(session_->initiator());
2474 SetRemoteDescriptionWithoutError(answer);
2475 EXPECT_TRUE(session_->initiator());
2476}
2477
2478// This test verifies the |initiator| flag when session receives the call.
2479TEST_F(WebRtcSessionTest, TestInitiatorFlagAsReceiver) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00002480 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002481 EXPECT_FALSE(session_->initiator());
2482 SessionDescriptionInterface* offer = CreateRemoteOffer();
2483 SetRemoteDescriptionWithoutError(offer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00002484 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002485
2486 EXPECT_FALSE(session_->initiator());
2487 SetLocalDescriptionWithoutError(answer);
2488 EXPECT_FALSE(session_->initiator());
2489}
2490
2491// This test verifies the ice protocol type at initiator of the call
2492// if |a=ice-options:google-ice| is present in answer.
2493TEST_F(WebRtcSessionTest, TestInitiatorGIceInAnswer) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00002494 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002495 mediastream_signaling_.SendAudioVideoStream1();
wu@webrtc.org91053e72013-08-10 07:18:04 +00002496 SessionDescriptionInterface* offer = CreateOffer(NULL);
henrike@webrtc.org723d6832013-07-12 16:04:50 +00002497 talk_base::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002498 CreateRemoteAnswer(offer));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002499 SetLocalDescriptionWithoutError(offer);
2500 std::string sdp;
2501 EXPECT_TRUE(answer->ToString(&sdp));
2502 // Adding ice-options to the session level.
2503 InjectAfter("t=0 0\r\n",
2504 "a=ice-options:google-ice\r\n",
2505 &sdp);
2506 SessionDescriptionInterface* answer_with_gice =
2507 CreateSessionDescription(JsepSessionDescription::kAnswer, sdp, NULL);
2508 SetRemoteDescriptionWithoutError(answer_with_gice);
2509 VerifyTransportType("audio", cricket::ICEPROTO_GOOGLE);
2510 VerifyTransportType("video", cricket::ICEPROTO_GOOGLE);
2511}
2512
2513// This test verifies the ice protocol type at initiator of the call
2514// if ICE RFC5245 is supported in answer.
2515TEST_F(WebRtcSessionTest, TestInitiatorIceInAnswer) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00002516 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002517 mediastream_signaling_.SendAudioVideoStream1();
wu@webrtc.org91053e72013-08-10 07:18:04 +00002518 SessionDescriptionInterface* offer = CreateOffer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002519 SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
2520 SetLocalDescriptionWithoutError(offer);
2521
2522 SetRemoteDescriptionWithoutError(answer);
2523 VerifyTransportType("audio", cricket::ICEPROTO_RFC5245);
2524 VerifyTransportType("video", cricket::ICEPROTO_RFC5245);
2525}
2526
2527// This test verifies the ice protocol type at receiver side of the call if
2528// receiver decides to use google-ice.
2529TEST_F(WebRtcSessionTest, TestReceiverGIceInOffer) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00002530 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002531 mediastream_signaling_.SendAudioVideoStream1();
wu@webrtc.org91053e72013-08-10 07:18:04 +00002532 SessionDescriptionInterface* offer = CreateOffer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002533 SetRemoteDescriptionWithoutError(offer);
henrike@webrtc.org723d6832013-07-12 16:04:50 +00002534 talk_base::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002535 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002536 std::string sdp;
2537 EXPECT_TRUE(answer->ToString(&sdp));
2538 // Adding ice-options to the session level.
2539 InjectAfter("t=0 0\r\n",
2540 "a=ice-options:google-ice\r\n",
2541 &sdp);
2542 SessionDescriptionInterface* answer_with_gice =
2543 CreateSessionDescription(JsepSessionDescription::kAnswer, sdp, NULL);
2544 SetLocalDescriptionWithoutError(answer_with_gice);
2545 VerifyTransportType("audio", cricket::ICEPROTO_GOOGLE);
2546 VerifyTransportType("video", cricket::ICEPROTO_GOOGLE);
2547}
2548
2549// This test verifies the ice protocol type at receiver side of the call if
2550// receiver decides to use ice RFC 5245.
2551TEST_F(WebRtcSessionTest, TestReceiverIceInOffer) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00002552 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002553 mediastream_signaling_.SendAudioVideoStream1();
wu@webrtc.org91053e72013-08-10 07:18:04 +00002554 SessionDescriptionInterface* offer = CreateOffer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002555 SetRemoteDescriptionWithoutError(offer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00002556 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002557 SetLocalDescriptionWithoutError(answer);
2558 VerifyTransportType("audio", cricket::ICEPROTO_RFC5245);
2559 VerifyTransportType("video", cricket::ICEPROTO_RFC5245);
2560}
2561
2562// This test verifies the session state when ICE RFC5245 in offer and
2563// ICE google-ice in answer.
2564TEST_F(WebRtcSessionTest, TestIceOfferGIceOnlyAnswer) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00002565 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002566 mediastream_signaling_.SendAudioVideoStream1();
2567 talk_base::scoped_ptr<SessionDescriptionInterface> offer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002568 CreateOffer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002569 std::string offer_str;
2570 offer->ToString(&offer_str);
2571 // Disable google-ice
2572 const std::string gice_option = "google-ice";
2573 const std::string xgoogle_xice = "xgoogle-xice";
2574 talk_base::replace_substrs(gice_option.c_str(), gice_option.length(),
2575 xgoogle_xice.c_str(), xgoogle_xice.length(),
2576 &offer_str);
2577 JsepSessionDescription *ice_only_offer =
2578 new JsepSessionDescription(JsepSessionDescription::kOffer);
2579 EXPECT_TRUE((ice_only_offer)->Initialize(offer_str, NULL));
2580 SetLocalDescriptionWithoutError(ice_only_offer);
2581 std::string original_offer_sdp;
2582 EXPECT_TRUE(offer->ToString(&original_offer_sdp));
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00002583 SessionDescriptionInterface* pranswer_with_gice =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002584 CreateSessionDescription(JsepSessionDescription::kPrAnswer,
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00002585 original_offer_sdp, NULL);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00002586 SetRemoteDescriptionPranswerExpectError(kPushDownTDFailed,
2587 pranswer_with_gice);
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00002588 SessionDescriptionInterface* answer_with_gice =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002589 CreateSessionDescription(JsepSessionDescription::kAnswer,
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00002590 original_offer_sdp, NULL);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00002591 SetRemoteDescriptionAnswerExpectError(kPushDownTDFailed,
2592 answer_with_gice);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002593}
2594
2595// Verifing local offer and remote answer have matching m-lines as per RFC 3264.
2596TEST_F(WebRtcSessionTest, TestIncorrectMLinesInRemoteAnswer) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00002597 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002598 mediastream_signaling_.SendAudioVideoStream1();
wu@webrtc.org91053e72013-08-10 07:18:04 +00002599 SessionDescriptionInterface* offer = CreateOffer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002600 SetLocalDescriptionWithoutError(offer);
2601 talk_base::scoped_ptr<SessionDescriptionInterface> answer(
2602 CreateRemoteAnswer(session_->local_description()));
2603
2604 cricket::SessionDescription* answer_copy = answer->description()->Copy();
2605 answer_copy->RemoveContentByName("video");
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00002606 JsepSessionDescription* modified_answer =
2607 new JsepSessionDescription(JsepSessionDescription::kAnswer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002608
2609 EXPECT_TRUE(modified_answer->Initialize(answer_copy,
2610 answer->session_id(),
2611 answer->session_version()));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00002612 SetRemoteDescriptionAnswerExpectError(kMlineMismatch, modified_answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002613
2614 // Modifying content names.
2615 std::string sdp;
2616 EXPECT_TRUE(answer->ToString(&sdp));
2617 const std::string kAudioMid = "a=mid:audio";
2618 const std::string kAudioMidReplaceStr = "a=mid:audio_content_name";
2619
2620 // Replacing |audio| with |audio_content_name|.
2621 talk_base::replace_substrs(kAudioMid.c_str(), kAudioMid.length(),
2622 kAudioMidReplaceStr.c_str(),
2623 kAudioMidReplaceStr.length(),
2624 &sdp);
2625
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00002626 SessionDescriptionInterface* modified_answer1 =
2627 CreateSessionDescription(JsepSessionDescription::kAnswer, sdp, NULL);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00002628 SetRemoteDescriptionAnswerExpectError(kMlineMismatch, modified_answer1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002629
2630 SetRemoteDescriptionWithoutError(answer.release());
2631}
2632
2633// Verifying remote offer and local answer have matching m-lines as per
2634// RFC 3264.
2635TEST_F(WebRtcSessionTest, TestIncorrectMLinesInLocalAnswer) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00002636 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002637 mediastream_signaling_.SendAudioVideoStream1();
2638 SessionDescriptionInterface* offer = CreateRemoteOffer();
2639 SetRemoteDescriptionWithoutError(offer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00002640 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002641
2642 cricket::SessionDescription* answer_copy = answer->description()->Copy();
2643 answer_copy->RemoveContentByName("video");
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00002644 JsepSessionDescription* modified_answer =
2645 new JsepSessionDescription(JsepSessionDescription::kAnswer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002646
2647 EXPECT_TRUE(modified_answer->Initialize(answer_copy,
2648 answer->session_id(),
2649 answer->session_version()));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00002650 SetLocalDescriptionAnswerExpectError(kMlineMismatch, modified_answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002651 SetLocalDescriptionWithoutError(answer);
2652}
2653
2654// This test verifies that WebRtcSession does not start candidate allocation
2655// before SetLocalDescription is called.
2656TEST_F(WebRtcSessionTest, TestIceStartAfterSetLocalDescriptionOnly) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00002657 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002658 mediastream_signaling_.SendAudioVideoStream1();
2659 SessionDescriptionInterface* offer = CreateRemoteOffer();
2660 cricket::Candidate candidate;
2661 candidate.set_component(1);
2662 JsepIceCandidate ice_candidate(kMediaContentName0, kMediaContentIndex0,
2663 candidate);
2664 EXPECT_TRUE(offer->AddCandidate(&ice_candidate));
2665 cricket::Candidate candidate1;
2666 candidate1.set_component(1);
2667 JsepIceCandidate ice_candidate1(kMediaContentName1, kMediaContentIndex1,
2668 candidate1);
2669 EXPECT_TRUE(offer->AddCandidate(&ice_candidate1));
2670 SetRemoteDescriptionWithoutError(offer);
2671 ASSERT_TRUE(session_->GetTransportProxy("audio") != NULL);
2672 ASSERT_TRUE(session_->GetTransportProxy("video") != NULL);
2673
2674 // Pump for 1 second and verify that no candidates are generated.
2675 talk_base::Thread::Current()->ProcessMessages(1000);
2676 EXPECT_TRUE(observer_.mline_0_candidates_.empty());
2677 EXPECT_TRUE(observer_.mline_1_candidates_.empty());
2678
wu@webrtc.org91053e72013-08-10 07:18:04 +00002679 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002680 SetLocalDescriptionWithoutError(answer);
2681 EXPECT_TRUE(session_->GetTransportProxy("audio")->negotiated());
2682 EXPECT_TRUE(session_->GetTransportProxy("video")->negotiated());
2683 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
2684}
2685
2686// This test verifies that crypto parameter is updated in local session
2687// description as per security policy set in MediaSessionDescriptionFactory.
2688TEST_F(WebRtcSessionTest, TestCryptoAfterSetLocalDescription) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00002689 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002690 mediastream_signaling_.SendAudioVideoStream1();
2691 talk_base::scoped_ptr<SessionDescriptionInterface> offer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002692 CreateOffer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002693
2694 // Making sure SetLocalDescription correctly sets crypto value in
2695 // SessionDescription object after de-serialization of sdp string. The value
2696 // will be set as per MediaSessionDescriptionFactory.
2697 std::string offer_str;
2698 offer->ToString(&offer_str);
2699 SessionDescriptionInterface* jsep_offer_str =
2700 CreateSessionDescription(JsepSessionDescription::kOffer, offer_str, NULL);
2701 SetLocalDescriptionWithoutError(jsep_offer_str);
2702 EXPECT_TRUE(session_->voice_channel()->secure_required());
2703 EXPECT_TRUE(session_->video_channel()->secure_required());
2704}
2705
2706// This test verifies the crypto parameter when security is disabled.
2707TEST_F(WebRtcSessionTest, TestCryptoAfterSetLocalDescriptionWithDisabled) {
wu@webrtc.org97077a32013-10-25 21:18:33 +00002708 options_.disable_encryption = true;
wu@webrtc.org91053e72013-08-10 07:18:04 +00002709 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002710 mediastream_signaling_.SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002711 talk_base::scoped_ptr<SessionDescriptionInterface> offer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002712 CreateOffer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002713
2714 // Making sure SetLocalDescription correctly sets crypto value in
2715 // SessionDescription object after de-serialization of sdp string. The value
2716 // will be set as per MediaSessionDescriptionFactory.
2717 std::string offer_str;
2718 offer->ToString(&offer_str);
2719 SessionDescriptionInterface *jsep_offer_str =
2720 CreateSessionDescription(JsepSessionDescription::kOffer, offer_str, NULL);
2721 SetLocalDescriptionWithoutError(jsep_offer_str);
2722 EXPECT_FALSE(session_->voice_channel()->secure_required());
2723 EXPECT_FALSE(session_->video_channel()->secure_required());
2724}
2725
2726// This test verifies that an answer contains new ufrag and password if an offer
2727// with new ufrag and password is received.
2728TEST_F(WebRtcSessionTest, TestCreateAnswerWithNewUfragAndPassword) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00002729 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002730 cricket::MediaSessionOptions options;
2731 options.has_audio = true;
2732 options.has_video = true;
2733 talk_base::scoped_ptr<JsepSessionDescription> offer(
2734 CreateRemoteOffer(options));
2735 SetRemoteDescriptionWithoutError(offer.release());
2736
2737 mediastream_signaling_.SendAudioVideoStream1();
2738 talk_base::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002739 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002740 SetLocalDescriptionWithoutError(answer.release());
2741
2742 // Receive an offer with new ufrag and password.
2743 options.transport_options.ice_restart = true;
2744 talk_base::scoped_ptr<JsepSessionDescription> updated_offer1(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002745 CreateRemoteOffer(options, session_->remote_description()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002746 SetRemoteDescriptionWithoutError(updated_offer1.release());
2747
2748 talk_base::scoped_ptr<SessionDescriptionInterface> updated_answer1(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002749 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002750
2751 CompareIceUfragAndPassword(updated_answer1->description(),
2752 session_->local_description()->description(),
2753 false);
2754
2755 SetLocalDescriptionWithoutError(updated_answer1.release());
wu@webrtc.org91053e72013-08-10 07:18:04 +00002756}
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002757
wu@webrtc.org91053e72013-08-10 07:18:04 +00002758// This test verifies that an answer contains old ufrag and password if an offer
2759// with old ufrag and password is received.
2760TEST_F(WebRtcSessionTest, TestCreateAnswerWithOldUfragAndPassword) {
2761 Init(NULL);
2762 cricket::MediaSessionOptions options;
2763 options.has_audio = true;
2764 options.has_video = true;
2765 talk_base::scoped_ptr<JsepSessionDescription> offer(
2766 CreateRemoteOffer(options));
2767 SetRemoteDescriptionWithoutError(offer.release());
2768
2769 mediastream_signaling_.SendAudioVideoStream1();
2770 talk_base::scoped_ptr<SessionDescriptionInterface> answer(
2771 CreateAnswer(NULL));
2772 SetLocalDescriptionWithoutError(answer.release());
2773
2774 // Receive an offer without changed ufrag or password.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002775 options.transport_options.ice_restart = false;
2776 talk_base::scoped_ptr<JsepSessionDescription> updated_offer2(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002777 CreateRemoteOffer(options, session_->remote_description()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002778 SetRemoteDescriptionWithoutError(updated_offer2.release());
2779
2780 talk_base::scoped_ptr<SessionDescriptionInterface> updated_answer2(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002781 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002782
2783 CompareIceUfragAndPassword(updated_answer2->description(),
2784 session_->local_description()->description(),
2785 true);
2786
2787 SetLocalDescriptionWithoutError(updated_answer2.release());
2788}
2789
2790TEST_F(WebRtcSessionTest, TestSessionContentError) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00002791 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002792 mediastream_signaling_.SendAudioVideoStream1();
wu@webrtc.org91053e72013-08-10 07:18:04 +00002793 SessionDescriptionInterface* offer = CreateOffer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002794 const std::string session_id_orig = offer->session_id();
2795 const std::string session_version_orig = offer->session_version();
2796 SetLocalDescriptionWithoutError(offer);
2797
2798 video_channel_ = media_engine_->GetVideoChannel(0);
2799 video_channel_->set_fail_set_send_codecs(true);
2800
2801 mediastream_signaling_.SendAudioVideoStream2();
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00002802 SessionDescriptionInterface* answer =
2803 CreateRemoteAnswer(session_->local_description());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00002804 SetRemoteDescriptionAnswerExpectError("ERROR_CONTENT", answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002805}
2806
2807// Runs the loopback call test with BUNDLE and STUN disabled.
2808TEST_F(WebRtcSessionTest, TestIceStatesBasic) {
2809 // Lets try with only UDP ports.
2810 allocator_.set_flags(cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
2811 cricket::PORTALLOCATOR_DISABLE_TCP |
2812 cricket::PORTALLOCATOR_DISABLE_STUN |
2813 cricket::PORTALLOCATOR_DISABLE_RELAY);
2814 TestLoopbackCall();
2815}
2816
mallinath@webrtc.orgd3dc4242014-03-01 00:05:52 +00002817// Runs the loopback call test with BUNDLE and STUN enabled.
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00002818TEST_F(WebRtcSessionTest, TestIceStatesBundle) {
2819 allocator_.set_flags(cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
2820 cricket::PORTALLOCATOR_ENABLE_BUNDLE |
mallinath@webrtc.orgd3dc4242014-03-01 00:05:52 +00002821 cricket::PORTALLOCATOR_DISABLE_TCP |
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00002822 cricket::PORTALLOCATOR_DISABLE_RELAY);
2823 TestLoopbackCall();
2824}
2825
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00002826TEST_F(WebRtcSessionTest, SetSdpFailedOnSessionError) {
wu@webrtc.org91053e72013-08-10 07:18:04 +00002827 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002828 cricket::MediaSessionOptions options;
2829 options.has_audio = true;
2830 options.has_video = true;
2831
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00002832 cricket::BaseSession::Error error_code = cricket::BaseSession::ERROR_CONTENT;
2833 std::string error_code_str = "ERROR_CONTENT";
2834 std::string error_desc = "Fake session error description.";
2835 session_->SetError(error_code, error_desc);
2836
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002837 SessionDescriptionInterface* offer = CreateRemoteOffer(options);
2838 SessionDescriptionInterface* answer =
2839 CreateRemoteAnswer(offer, options);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00002840
2841 std::string action;
2842 std::ostringstream session_error_msg;
2843 session_error_msg << kSessionError << error_code_str << ". ";
2844 session_error_msg << kSessionErrorDesc << error_desc << ".";
2845 SetRemoteDescriptionExpectError(action, session_error_msg.str(), offer);
2846 SetLocalDescriptionExpectError(action, session_error_msg.str(), answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002847}
2848
2849TEST_F(WebRtcSessionTest, TestRtpDataChannel) {
2850 constraints_.reset(new FakeConstraints());
2851 constraints_->AddOptional(
2852 webrtc::MediaConstraintsInterface::kEnableRtpDataChannels, true);
wu@webrtc.org91053e72013-08-10 07:18:04 +00002853 Init(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002854
2855 SetLocalDescriptionWithDataChannel();
2856 EXPECT_EQ(cricket::DCT_RTP, data_engine_->last_channel_type());
2857}
2858
2859TEST_F(WebRtcSessionTest, TestRtpDataChannelConstraintTakesPrecedence) {
2860 MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
2861
2862 constraints_.reset(new FakeConstraints());
2863 constraints_->AddOptional(
2864 webrtc::MediaConstraintsInterface::kEnableRtpDataChannels, true);
wu@webrtc.org97077a32013-10-25 21:18:33 +00002865 options_.disable_sctp_data_channels = false;
2866
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00002867 InitWithDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002868
2869 SetLocalDescriptionWithDataChannel();
2870 EXPECT_EQ(cricket::DCT_RTP, data_engine_->last_channel_type());
2871}
2872
wu@webrtc.org967bfff2013-09-19 05:49:50 +00002873TEST_F(WebRtcSessionTest, TestCreateOfferWithSctpEnabledWithoutStreams) {
2874 MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
2875
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00002876 InitWithDtls();
sergeyu@chromium.orga59696b2013-09-13 23:48:58 +00002877
2878 talk_base::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer(NULL));
2879 EXPECT_TRUE(offer->description()->GetContentByName("data") == NULL);
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00002880 EXPECT_TRUE(offer->description()->GetTransportInfoByName("data") == NULL);
2881}
2882
2883TEST_F(WebRtcSessionTest, TestCreateAnswerWithSctpInOfferAndNoStreams) {
2884 MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
2885 SetFactoryDtlsSrtp();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00002886 InitWithDtls();
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00002887
2888 // Create remote offer with SCTP.
2889 cricket::MediaSessionOptions options;
2890 options.data_channel_type = cricket::DCT_SCTP;
2891 JsepSessionDescription* offer =
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00002892 CreateRemoteOffer(options, cricket::SEC_DISABLED);
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00002893 SetRemoteDescriptionWithoutError(offer);
2894
2895 // Verifies the answer contains SCTP.
2896 talk_base::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
2897 EXPECT_TRUE(answer != NULL);
2898 EXPECT_TRUE(answer->description()->GetContentByName("data") != NULL);
2899 EXPECT_TRUE(answer->description()->GetTransportInfoByName("data") != NULL);
sergeyu@chromium.orga59696b2013-09-13 23:48:58 +00002900}
2901
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002902TEST_F(WebRtcSessionTest, TestSctpDataChannelWithoutDtls) {
2903 constraints_.reset(new FakeConstraints());
2904 constraints_->AddOptional(
sergeyu@chromium.orga59696b2013-09-13 23:48:58 +00002905 webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, false);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00002906 InitWithDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002907
2908 SetLocalDescriptionWithDataChannel();
2909 EXPECT_EQ(cricket::DCT_NONE, data_engine_->last_channel_type());
2910}
2911
2912TEST_F(WebRtcSessionTest, TestSctpDataChannelWithDtls) {
2913 MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
2914
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00002915 InitWithDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002916
2917 SetLocalDescriptionWithDataChannel();
2918 EXPECT_EQ(cricket::DCT_SCTP, data_engine_->last_channel_type());
2919}
wu@webrtc.org91053e72013-08-10 07:18:04 +00002920
wu@webrtc.org97077a32013-10-25 21:18:33 +00002921TEST_F(WebRtcSessionTest, TestDisableSctpDataChannels) {
2922 MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
2923 options_.disable_sctp_data_channels = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00002924 InitWithDtls();
wu@webrtc.org97077a32013-10-25 21:18:33 +00002925
2926 SetLocalDescriptionWithDataChannel();
2927 EXPECT_EQ(cricket::DCT_NONE, data_engine_->last_channel_type());
2928}
2929
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002930TEST_F(WebRtcSessionTest, TestSctpDataChannelSendPortParsing) {
2931 MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
2932 const int new_send_port = 9998;
2933 const int new_recv_port = 7775;
2934
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00002935 InitWithDtls();
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002936 SetFactoryDtlsSrtp();
2937
2938 // By default, don't actually add the codecs to desc_factory_; they don't
2939 // actually get serialized for SCTP in BuildMediaDescription(). Instead,
2940 // let the session description get parsed. That'll get the proper codecs
2941 // into the stream.
2942 cricket::MediaSessionOptions options;
2943 JsepSessionDescription* offer = CreateRemoteOfferWithSctpPort(
2944 "stream1", new_send_port, options);
2945
2946 // SetRemoteDescription will take the ownership of the offer.
2947 SetRemoteDescriptionWithoutError(offer);
2948
2949 SessionDescriptionInterface* answer = ChangeSDPSctpPort(
2950 new_recv_port, CreateAnswer(NULL));
2951 ASSERT_TRUE(answer != NULL);
2952
2953 // Now set the local description, which'll take ownership of the answer.
2954 SetLocalDescriptionWithoutError(answer);
2955
2956 // TEST PLAN: Set the port number to something new, set it in the SDP,
2957 // and pass it all the way down.
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +00002958 webrtc::InternalDataChannelInit dci;
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002959 dci.reliable = true;
2960 EXPECT_EQ(cricket::DCT_SCTP, data_engine_->last_channel_type());
2961 talk_base::scoped_refptr<webrtc::DataChannel> dc =
2962 session_->CreateDataChannel("datachannel", &dci);
2963
2964 cricket::FakeDataMediaChannel* ch = data_engine_->GetChannel(0);
2965 int portnum = -1;
2966 ASSERT_TRUE(ch != NULL);
2967 ASSERT_EQ(1UL, ch->send_codecs().size());
2968 EXPECT_EQ(cricket::kGoogleSctpDataCodecId, ch->send_codecs()[0].id);
2969 EXPECT_TRUE(!strcmp(cricket::kGoogleSctpDataCodecName,
2970 ch->send_codecs()[0].name.c_str()));
2971 EXPECT_TRUE(ch->send_codecs()[0].GetParam(cricket::kCodecParamPort,
2972 &portnum));
2973 EXPECT_EQ(new_send_port, portnum);
2974
2975 ASSERT_EQ(1UL, ch->recv_codecs().size());
2976 EXPECT_EQ(cricket::kGoogleSctpDataCodecId, ch->recv_codecs()[0].id);
2977 EXPECT_TRUE(!strcmp(cricket::kGoogleSctpDataCodecName,
2978 ch->recv_codecs()[0].name.c_str()));
2979 EXPECT_TRUE(ch->recv_codecs()[0].GetParam(cricket::kCodecParamPort,
2980 &portnum));
2981 EXPECT_EQ(new_recv_port, portnum);
2982}
2983
wu@webrtc.org91053e72013-08-10 07:18:04 +00002984// Verifies that CreateOffer succeeds when CreateOffer is called before async
2985// identity generation is finished.
2986TEST_F(WebRtcSessionTest, TestCreateOfferBeforeIdentityRequestReturnSuccess) {
2987 MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00002988 InitWithDtls();
wu@webrtc.org91053e72013-08-10 07:18:04 +00002989
2990 EXPECT_TRUE(session_->waiting_for_identity());
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00002991 mediastream_signaling_.SendAudioVideoStream1();
wu@webrtc.org91053e72013-08-10 07:18:04 +00002992 talk_base::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer(NULL));
2993 EXPECT_TRUE(offer != NULL);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00002994 VerifyNoCryptoParams(offer->description(), true);
2995 VerifyFingerprintStatus(offer->description(), true);
wu@webrtc.org91053e72013-08-10 07:18:04 +00002996}
2997
2998// Verifies that CreateAnswer succeeds when CreateOffer is called before async
2999// identity generation is finished.
3000TEST_F(WebRtcSessionTest, TestCreateAnswerBeforeIdentityRequestReturnSuccess) {
3001 MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003002 InitWithDtls();
3003 SetFactoryDtlsSrtp();
wu@webrtc.org91053e72013-08-10 07:18:04 +00003004
3005 cricket::MediaSessionOptions options;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003006 options.has_video = true;
wu@webrtc.org91053e72013-08-10 07:18:04 +00003007 scoped_ptr<JsepSessionDescription> offer(
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003008 CreateRemoteOffer(options, cricket::SEC_DISABLED));
wu@webrtc.org91053e72013-08-10 07:18:04 +00003009 ASSERT_TRUE(offer.get() != NULL);
3010 SetRemoteDescriptionWithoutError(offer.release());
3011
3012 talk_base::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
3013 EXPECT_TRUE(answer != NULL);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003014 VerifyNoCryptoParams(answer->description(), true);
3015 VerifyFingerprintStatus(answer->description(), true);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003016}
3017
3018// Verifies that CreateOffer succeeds when CreateOffer is called after async
3019// identity generation is finished.
3020TEST_F(WebRtcSessionTest, TestCreateOfferAfterIdentityRequestReturnSuccess) {
3021 MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003022 InitWithDtls();
wu@webrtc.org91053e72013-08-10 07:18:04 +00003023
3024 EXPECT_TRUE_WAIT(!session_->waiting_for_identity(), 1000);
3025 talk_base::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer(NULL));
3026 EXPECT_TRUE(offer != NULL);
3027}
3028
3029// Verifies that CreateOffer fails when CreateOffer is called after async
3030// identity generation fails.
3031TEST_F(WebRtcSessionTest, TestCreateOfferAfterIdentityRequestReturnFailure) {
3032 MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.org7666db72013-08-22 14:45:42 +00003033 InitWithDtls(true);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003034
3035 EXPECT_TRUE_WAIT(!session_->waiting_for_identity(), 1000);
3036 talk_base::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer(NULL));
3037 EXPECT_TRUE(offer == NULL);
3038}
3039
3040// Verifies that CreateOffer succeeds when Multiple CreateOffer calls are made
3041// before async identity generation is finished.
3042TEST_F(WebRtcSessionTest,
3043 TestMultipleCreateOfferBeforeIdentityRequestReturnSuccess) {
3044 MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
3045 VerifyMultipleAsyncCreateDescription(
3046 true, CreateSessionDescriptionRequest::kOffer);
3047}
3048
3049// Verifies that CreateOffer fails when Multiple CreateOffer calls are made
3050// before async identity generation fails.
3051TEST_F(WebRtcSessionTest,
3052 TestMultipleCreateOfferBeforeIdentityRequestReturnFailure) {
3053 MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
3054 VerifyMultipleAsyncCreateDescription(
3055 false, CreateSessionDescriptionRequest::kOffer);
3056}
3057
3058// Verifies that CreateAnswer succeeds when Multiple CreateAnswer calls are made
3059// before async identity generation is finished.
3060TEST_F(WebRtcSessionTest,
3061 TestMultipleCreateAnswerBeforeIdentityRequestReturnSuccess) {
3062 MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
3063 VerifyMultipleAsyncCreateDescription(
3064 true, CreateSessionDescriptionRequest::kAnswer);
3065}
3066
3067// Verifies that CreateAnswer fails when Multiple CreateAnswer calls are made
3068// before async identity generation fails.
3069TEST_F(WebRtcSessionTest,
3070 TestMultipleCreateAnswerBeforeIdentityRequestReturnFailure) {
3071 MAYBE_SKIP_TEST(talk_base::SSLStreamAdapter::HaveDtlsSrtp);
3072 VerifyMultipleAsyncCreateDescription(
3073 false, CreateSessionDescriptionRequest::kAnswer);
3074}
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00003075
3076// Verifies that setRemoteDescription fails when DTLS is disabled and the remote
3077// offer has no SDES crypto but only DTLS fingerprint.
3078TEST_F(WebRtcSessionTest, TestSetRemoteOfferFailIfDtlsDisabledAndNoCrypto) {
3079 // Init without DTLS.
3080 Init(NULL);
3081 // Create a remote offer with secured transport disabled.
3082 cricket::MediaSessionOptions options;
3083 JsepSessionDescription* offer(CreateRemoteOffer(
3084 options, cricket::SEC_DISABLED));
3085 // Adds a DTLS fingerprint to the remote offer.
3086 cricket::SessionDescription* sdp = offer->description();
3087 TransportInfo* audio = sdp->GetTransportInfoByName("audio");
3088 ASSERT_TRUE(audio != NULL);
3089 ASSERT_TRUE(audio->description.identity_fingerprint.get() == NULL);
3090 audio->description.identity_fingerprint.reset(
3091 talk_base::SSLFingerprint::CreateFromRfc4572(
3092 talk_base::DIGEST_SHA_256, kFakeDtlsFingerprint));
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003093 SetRemoteDescriptionOfferExpectError(kSdpWithoutSdesCrypto,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003094 offer);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00003095}
3096
wu@webrtc.orgde305012013-10-31 15:40:38 +00003097// This test verifies DSCP is properly applied on the media channels.
3098TEST_F(WebRtcSessionTest, TestDscpConstraint) {
3099 constraints_.reset(new FakeConstraints());
3100 constraints_->AddOptional(
3101 webrtc::MediaConstraintsInterface::kEnableDscp, true);
3102 Init(NULL);
3103 mediastream_signaling_.SendAudioVideoStream1();
3104 SessionDescriptionInterface* offer = CreateOffer(NULL);
3105
3106 SetLocalDescriptionWithoutError(offer);
3107
3108 video_channel_ = media_engine_->GetVideoChannel(0);
3109 voice_channel_ = media_engine_->GetVoiceChannel(0);
3110
3111 ASSERT_TRUE(video_channel_ != NULL);
3112 ASSERT_TRUE(voice_channel_ != NULL);
3113 cricket::AudioOptions audio_options;
3114 EXPECT_TRUE(voice_channel_->GetOptions(&audio_options));
3115 cricket::VideoOptions video_options;
3116 EXPECT_TRUE(video_channel_->GetOptions(&video_options));
3117 EXPECT_TRUE(audio_options.dscp.IsSet());
3118 EXPECT_TRUE(audio_options.dscp.GetWithDefaultIfUnset(false));
3119 EXPECT_TRUE(video_options.dscp.IsSet());
3120 EXPECT_TRUE(video_options.dscp.GetWithDefaultIfUnset(false));
3121}
3122
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003123// TODO(bemasc): Add a TestIceStatesBundle with BUNDLE enabled. That test
3124// currently fails because upon disconnection and reconnection OnIceComplete is
3125// called more than once without returning to IceGatheringGathering.