blob: a96f62435d8cf5f4d0bc47f290c5ea1498c65d71 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
2 * libjingle
jlmiller@webrtc.org5f93d0a2015-01-20 21:36:13 +00003 * Copyright 2012 Google Inc.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00004 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include "talk/app/webrtc/audiotrack.h"
jbauchac8869e2015-07-03 01:36:14 -070029#include "talk/app/webrtc/fakemetricsobserver.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000030#include "talk/app/webrtc/jsepicecandidate.h"
31#include "talk/app/webrtc/jsepsessiondescription.h"
32#include "talk/app/webrtc/mediastreamsignaling.h"
33#include "talk/app/webrtc/streamcollection.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000034#include "talk/app/webrtc/test/fakeconstraints.h"
Henrik Boström5e56c592015-08-11 10:33:13 +020035#include "talk/app/webrtc/test/fakedtlsidentitystore.h"
wu@webrtc.org91053e72013-08-10 07:18:04 +000036#include "talk/app/webrtc/test/fakemediastreamsignaling.h"
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000037#include "talk/app/webrtc/videotrack.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000038#include "talk/app/webrtc/webrtcsession.h"
wu@webrtc.org91053e72013-08-10 07:18:04 +000039#include "talk/app/webrtc/webrtcsessiondescriptionfactory.h"
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000040#include "talk/media/base/fakemediaengine.h"
41#include "talk/media/base/fakevideorenderer.h"
42#include "talk/media/base/mediachannel.h"
43#include "talk/media/devices/fakedevicemanager.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000044#include "webrtc/p2p/base/stunserver.h"
45#include "webrtc/p2p/base/teststunserver.h"
46#include "webrtc/p2p/base/testturnserver.h"
pthatcher@webrtc.orgb4aac132015-03-13 18:25:21 +000047#include "webrtc/p2p/base/transportchannel.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000048#include "webrtc/p2p/client/basicportallocator.h"
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000049#include "talk/session/media/channelmanager.h"
50#include "talk/session/media/mediasession.h"
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000051#include "webrtc/base/fakenetwork.h"
52#include "webrtc/base/firewallsocketserver.h"
53#include "webrtc/base/gunit.h"
54#include "webrtc/base/logging.h"
55#include "webrtc/base/network.h"
56#include "webrtc/base/physicalsocketserver.h"
57#include "webrtc/base/ssladapter.h"
Henrik Boström5e56c592015-08-11 10:33:13 +020058#include "webrtc/base/sslidentity.h"
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000059#include "webrtc/base/sslstreamadapter.h"
60#include "webrtc/base/stringutils.h"
61#include "webrtc/base/thread.h"
62#include "webrtc/base/virtualsocketserver.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000063
64#define MAYBE_SKIP_TEST(feature) \
65 if (!(feature())) { \
66 LOG(LS_INFO) << "Feature disabled... skipping"; \
67 return; \
68 }
69
70using cricket::BaseSession;
71using cricket::DF_PLAY;
72using cricket::DF_SEND;
73using cricket::FakeVoiceMediaChannel;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000074using cricket::TransportInfo;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000075using rtc::SocketAddress;
76using rtc::scoped_ptr;
77using rtc::Thread;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000078using webrtc::CreateSessionDescription;
wu@webrtc.org91053e72013-08-10 07:18:04 +000079using webrtc::CreateSessionDescriptionObserver;
80using webrtc::CreateSessionDescriptionRequest;
Henrik Boström5e56c592015-08-11 10:33:13 +020081using webrtc::DtlsIdentityStoreInterface;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000082using webrtc::FakeConstraints;
jbauchac8869e2015-07-03 01:36:14 -070083using webrtc::FakeMetricsObserver;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000084using webrtc::IceCandidateCollection;
85using webrtc::JsepIceCandidate;
86using webrtc::JsepSessionDescription;
wu@webrtc.org97077a32013-10-25 21:18:33 +000087using webrtc::PeerConnectionFactoryInterface;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000088using webrtc::PeerConnectionInterface;
89using webrtc::SessionDescriptionInterface;
90using webrtc::StreamCollection;
wu@webrtc.org91053e72013-08-10 07:18:04 +000091using webrtc::WebRtcSession;
wu@webrtc.org364f2042013-11-20 21:49:41 +000092using webrtc::kBundleWithoutRtcpMux;
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +000093using webrtc::kCreateChannelFailed;
94using webrtc::kInvalidSdp;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000095using webrtc::kMlineMismatch;
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +000096using webrtc::kPushDownTDFailed;
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +000097using webrtc::kSdpWithoutIceUfragPwd;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +000098using webrtc::kSdpWithoutDtlsFingerprint;
99using webrtc::kSdpWithoutSdesCrypto;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000100using webrtc::kSessionError;
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000101using webrtc::kSessionErrorDesc;
buildbot@webrtc.org53df88c2014-08-07 22:46:01 +0000102using webrtc::kMaxUnsignalledRecvStreams;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000103
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +0000104typedef PeerConnectionInterface::RTCOfferAnswerOptions RTCOfferAnswerOptions;
105
wu@webrtc.org364f2042013-11-20 21:49:41 +0000106static const int kClientAddrPort = 0;
107static const char kClientAddrHost1[] = "11.11.11.11";
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +0000108static const char kClientIPv6AddrHost1[] =
109 "2620:0:aaaa:bbbb:cccc:dddd:eeee:ffff";
wu@webrtc.org364f2042013-11-20 21:49:41 +0000110static const char kClientAddrHost2[] = "22.22.22.22";
111static const char kStunAddrHost[] = "99.99.99.1";
buildbot@webrtc.org41451d42014-05-03 05:39:45 +0000112static const SocketAddress kTurnUdpIntAddr("99.99.99.4", 3478);
113static const SocketAddress kTurnUdpExtAddr("99.99.99.6", 0);
mallinath@webrtc.org3d81b1b2014-09-09 14:38:10 +0000114static const char kTurnUsername[] = "test";
115static const char kTurnPassword[] = "test";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000116
117static const char kSessionVersion[] = "1";
118
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000119// Media index of candidates belonging to the first media content.
120static const int kMediaContentIndex0 = 0;
121static const char kMediaContentName0[] = "audio";
122
123// Media index of candidates belonging to the second media content.
124static const int kMediaContentIndex1 = 1;
125static const char kMediaContentName1[] = "video";
126
127static const int kIceCandidatesTimeout = 10000;
128
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +0000129static const char kFakeDtlsFingerprint[] =
130 "BB:CD:72:F7:2F:D0:BA:43:F3:68:B1:0C:23:72:B6:4A:"
131 "0F:DE:34:06:BC:E0:FE:01:BC:73:C8:6D:F4:65:D5:24";
132
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +0000133static const char kTooLongIceUfragPwd[] =
134 "IceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfrag"
135 "IceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfrag"
136 "IceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfrag"
137 "IceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfrag";
138
changbin.shao@webrtc.org2d25b442015-03-16 04:14:34 +0000139static const char kSdpWithRtx[] =
140 "v=0\r\n"
141 "o=- 4104004319237231850 2 IN IP4 127.0.0.1\r\n"
142 "s=-\r\n"
143 "t=0 0\r\n"
144 "a=msid-semantic: WMS stream1\r\n"
145 "m=video 9 RTP/SAVPF 0 96\r\n"
146 "c=IN IP4 0.0.0.0\r\n"
147 "a=rtcp:9 IN IP4 0.0.0.0\r\n"
148 "a=ice-ufrag:CerjGp19G7wpXwl7\r\n"
149 "a=ice-pwd:cMvOlFvQ6ochez1ZOoC2uBEC\r\n"
150 "a=mid:video\r\n"
151 "a=sendrecv\r\n"
152 "a=rtcp-mux\r\n"
153 "a=crypto:1 AES_CM_128_HMAC_SHA1_80 "
154 "inline:5/4N5CDvMiyDArHtBByUM71VIkguH17ZNoX60GrA\r\n"
155 "a=rtpmap:0 fake_video_codec/90000\r\n"
156 "a=rtpmap:96 rtx/90000\r\n"
157 "a=fmtp:96 apt=0\r\n";
158
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000159// Add some extra |newlines| to the |message| after |line|.
160static void InjectAfter(const std::string& line,
161 const std::string& newlines,
162 std::string* message) {
163 const std::string tmp = line + newlines;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000164 rtc::replace_substrs(line.c_str(), line.length(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000165 tmp.c_str(), tmp.length(), message);
166}
167
168class MockIceObserver : public webrtc::IceObserver {
169 public:
170 MockIceObserver()
171 : oncandidatesready_(false),
172 ice_connection_state_(PeerConnectionInterface::kIceConnectionNew),
173 ice_gathering_state_(PeerConnectionInterface::kIceGatheringNew) {
174 }
175
176 virtual void OnIceConnectionChange(
177 PeerConnectionInterface::IceConnectionState new_state) {
178 ice_connection_state_ = new_state;
179 }
180 virtual void OnIceGatheringChange(
181 PeerConnectionInterface::IceGatheringState new_state) {
182 // We can never transition back to "new".
183 EXPECT_NE(PeerConnectionInterface::kIceGatheringNew, new_state);
184 ice_gathering_state_ = new_state;
185
186 // oncandidatesready_ really means "ICE gathering is complete".
187 // This if statement ensures that this value remains correct when we
188 // transition from kIceGatheringComplete to kIceGatheringGathering.
189 if (new_state == PeerConnectionInterface::kIceGatheringGathering) {
190 oncandidatesready_ = false;
191 }
192 }
193
194 // Found a new candidate.
195 virtual void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) {
wu@webrtc.org364f2042013-11-20 21:49:41 +0000196 switch (candidate->sdp_mline_index()) {
197 case kMediaContentIndex0:
198 mline_0_candidates_.push_back(candidate->candidate());
199 break;
200 case kMediaContentIndex1:
201 mline_1_candidates_.push_back(candidate->candidate());
202 break;
203 default:
204 ASSERT(false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000205 }
wu@webrtc.org364f2042013-11-20 21:49:41 +0000206
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000207 // The ICE gathering state should always be Gathering when a candidate is
208 // received (or possibly Completed in the case of the final candidate).
209 EXPECT_NE(PeerConnectionInterface::kIceGatheringNew, ice_gathering_state_);
210 }
211
212 // TODO(bemasc): Remove this once callers transition to OnIceGatheringChange.
213 virtual void OnIceComplete() {
214 EXPECT_FALSE(oncandidatesready_);
215 oncandidatesready_ = true;
216
217 // OnIceGatheringChange(IceGatheringCompleted) and OnIceComplete() should
218 // be called approximately simultaneously. For ease of testing, this
219 // check additionally requires that they be called in the above order.
220 EXPECT_EQ(PeerConnectionInterface::kIceGatheringComplete,
221 ice_gathering_state_);
222 }
223
224 bool oncandidatesready_;
225 std::vector<cricket::Candidate> mline_0_candidates_;
226 std::vector<cricket::Candidate> mline_1_candidates_;
227 PeerConnectionInterface::IceConnectionState ice_connection_state_;
228 PeerConnectionInterface::IceGatheringState ice_gathering_state_;
229};
230
231class WebRtcSessionForTest : public webrtc::WebRtcSession {
232 public:
233 WebRtcSessionForTest(cricket::ChannelManager* cmgr,
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000234 rtc::Thread* signaling_thread,
235 rtc::Thread* worker_thread,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000236 cricket::PortAllocator* port_allocator,
237 webrtc::IceObserver* ice_observer,
238 webrtc::MediaStreamSignaling* mediastream_signaling)
239 : WebRtcSession(cmgr, signaling_thread, worker_thread, port_allocator,
240 mediastream_signaling) {
241 RegisterIceObserver(ice_observer);
242 }
243 virtual ~WebRtcSessionForTest() {}
244
245 using cricket::BaseSession::GetTransportProxy;
246 using webrtc::WebRtcSession::SetAudioPlayout;
247 using webrtc::WebRtcSession::SetAudioSend;
248 using webrtc::WebRtcSession::SetCaptureDevice;
249 using webrtc::WebRtcSession::SetVideoPlayout;
250 using webrtc::WebRtcSession::SetVideoSend;
251};
252
wu@webrtc.org91053e72013-08-10 07:18:04 +0000253class WebRtcSessionCreateSDPObserverForTest
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000254 : public rtc::RefCountedObject<CreateSessionDescriptionObserver> {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000255 public:
wu@webrtc.org91053e72013-08-10 07:18:04 +0000256 enum State {
257 kInit,
258 kFailed,
259 kSucceeded,
260 };
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000261 WebRtcSessionCreateSDPObserverForTest() : state_(kInit) {}
wu@webrtc.org91053e72013-08-10 07:18:04 +0000262
263 // CreateSessionDescriptionObserver implementation.
264 virtual void OnSuccess(SessionDescriptionInterface* desc) {
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000265 description_.reset(desc);
wu@webrtc.org91053e72013-08-10 07:18:04 +0000266 state_ = kSucceeded;
267 }
268 virtual void OnFailure(const std::string& error) {
269 state_ = kFailed;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000270 }
271
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000272 SessionDescriptionInterface* description() { return description_.get(); }
273
274 SessionDescriptionInterface* ReleaseDescription() {
275 return description_.release();
276 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000277
wu@webrtc.org91053e72013-08-10 07:18:04 +0000278 State state() const { return state_; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000279
wu@webrtc.org91053e72013-08-10 07:18:04 +0000280 protected:
281 ~WebRtcSessionCreateSDPObserverForTest() {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000282
283 private:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000284 rtc::scoped_ptr<SessionDescriptionInterface> description_;
wu@webrtc.org91053e72013-08-10 07:18:04 +0000285 State state_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000286};
287
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000288class FakeAudioRenderer : public cricket::AudioRenderer {
289 public:
henrike@webrtc.orga7b98182014-02-21 15:51:43 +0000290 FakeAudioRenderer() : channel_id_(-1), sink_(NULL) {}
291 virtual ~FakeAudioRenderer() {
292 if (sink_)
293 sink_->OnClose();
294 }
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000295
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000296 void AddChannel(int channel_id) override {
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000297 ASSERT(channel_id_ == -1);
298 channel_id_ = channel_id;
299 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000300 void RemoveChannel(int channel_id) override {
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000301 ASSERT(channel_id == channel_id_);
302 channel_id_ = -1;
303 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000304 void SetSink(Sink* sink) override { sink_ = sink; }
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000305
306 int channel_id() const { return channel_id_; }
henrike@webrtc.orga7b98182014-02-21 15:51:43 +0000307 cricket::AudioRenderer::Sink* sink() const { return sink_; }
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000308 private:
309 int channel_id_;
henrike@webrtc.orga7b98182014-02-21 15:51:43 +0000310 cricket::AudioRenderer::Sink* sink_;
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000311};
312
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000313class WebRtcSessionTest : public testing::Test {
314 protected:
315 // TODO Investigate why ChannelManager crashes, if it's created
316 // after stun_server.
317 WebRtcSessionTest()
318 : media_engine_(new cricket::FakeMediaEngine()),
319 data_engine_(new cricket::FakeDataEngine()),
320 device_manager_(new cricket::FakeDeviceManager()),
321 channel_manager_(new cricket::ChannelManager(
322 media_engine_, data_engine_, device_manager_,
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000323 new cricket::CaptureManager(), rtc::Thread::Current())),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000324 tdesc_factory_(new cricket::TransportDescriptionFactory()),
325 desc_factory_(new cricket::MediaSessionDescriptionFactory(
326 channel_manager_.get(), tdesc_factory_.get())),
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000327 pss_(new rtc::PhysicalSocketServer),
328 vss_(new rtc::VirtualSocketServer(pss_.get())),
329 fss_(new rtc::FirewallSocketServer(vss_.get())),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000330 ss_scope_(fss_.get()),
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000331 stun_socket_addr_(rtc::SocketAddress(kStunAddrHost,
wu@webrtc.org364f2042013-11-20 21:49:41 +0000332 cricket::STUN_SERVER_PORT)),
jiayl@webrtc.orgbebc75e2014-09-26 23:01:11 +0000333 stun_server_(cricket::TestStunServer::Create(Thread::Current(),
334 stun_socket_addr_)),
buildbot@webrtc.org41451d42014-05-03 05:39:45 +0000335 turn_server_(Thread::Current(), kTurnUdpIntAddr, kTurnUdpExtAddr),
jbauchac8869e2015-07-03 01:36:14 -0700336 mediastream_signaling_(channel_manager_.get()),
337 metrics_observer_(new rtc::RefCountedObject<FakeMetricsObserver>()) {
buildbot@webrtc.org51c55082014-07-28 22:26:15 +0000338 cricket::ServerAddresses stun_servers;
339 stun_servers.insert(stun_socket_addr_);
340 allocator_.reset(new cricket::BasicPortAllocator(
341 &network_manager_,
342 stun_servers,
343 SocketAddress(), SocketAddress(), SocketAddress()));
buildbot@webrtc.org41451d42014-05-03 05:39:45 +0000344 allocator_->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
Peter Thatcher3449faa2015-08-10 12:22:51 -0700345 cricket::PORTALLOCATOR_DISABLE_RELAY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000346 EXPECT_TRUE(channel_manager_->Init());
347 desc_factory_->set_add_legacy_streams(false);
buildbot@webrtc.org41451d42014-05-03 05:39:45 +0000348 allocator_->set_step_delay(cricket::kMinimumStepDelay);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000349 }
350
351 void AddInterface(const SocketAddress& addr) {
352 network_manager_.AddInterface(addr);
353 }
354
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000355 void Init(
Henrik Boström5e56c592015-08-11 10:33:13 +0200356 rtc::scoped_ptr<webrtc::DtlsIdentityStoreInterface> dtls_identity_store,
Henrik Lundin64dad832015-05-11 12:44:23 +0200357 const PeerConnectionInterface::RTCConfiguration& rtc_configuration) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000358 ASSERT_TRUE(session_.get() == NULL);
359 session_.reset(new WebRtcSessionForTest(
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000360 channel_manager_.get(), rtc::Thread::Current(),
361 rtc::Thread::Current(), allocator_.get(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000362 &observer_,
363 &mediastream_signaling_));
364
365 EXPECT_EQ(PeerConnectionInterface::kIceConnectionNew,
366 observer_.ice_connection_state_);
367 EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
368 observer_.ice_gathering_state_);
369
Henrik Boström5e56c592015-08-11 10:33:13 +0200370 EXPECT_TRUE(session_->Initialize(
371 options_, constraints_.get(), dtls_identity_store.Pass(),
372 rtc_configuration));
jbauchac8869e2015-07-03 01:36:14 -0700373 session_->set_metrics_observer(metrics_observer_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000374 }
375
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000376 void Init() {
Henrik Lundin64dad832015-05-11 12:44:23 +0200377 PeerConnectionInterface::RTCConfiguration configuration;
Henrik Boström5e56c592015-08-11 10:33:13 +0200378 Init(nullptr, configuration);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000379 }
380
381 void InitWithIceTransport(
382 PeerConnectionInterface::IceTransportsType ice_transport_type) {
Henrik Lundin64dad832015-05-11 12:44:23 +0200383 PeerConnectionInterface::RTCConfiguration configuration;
384 configuration.type = ice_transport_type;
Henrik Boström5e56c592015-08-11 10:33:13 +0200385 Init(nullptr, configuration);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000386 }
387
388 void InitWithBundlePolicy(
389 PeerConnectionInterface::BundlePolicy bundle_policy) {
Henrik Lundin64dad832015-05-11 12:44:23 +0200390 PeerConnectionInterface::RTCConfiguration configuration;
Henrik Lundin64dad832015-05-11 12:44:23 +0200391 configuration.bundle_policy = bundle_policy;
Henrik Boström5e56c592015-08-11 10:33:13 +0200392 Init(nullptr, configuration);
Peter Thatcheraf55ccc2015-05-21 07:48:41 -0700393 }
394
395 void InitWithRtcpMuxPolicy(
396 PeerConnectionInterface::RtcpMuxPolicy rtcp_mux_policy) {
397 PeerConnectionInterface::RTCConfiguration configuration;
398 configuration.rtcp_mux_policy = rtcp_mux_policy;
Henrik Boström5e56c592015-08-11 10:33:13 +0200399 Init(nullptr, configuration);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000400 }
401
402 void InitWithDtls(bool identity_request_should_fail = false) {
Henrik Boström5e56c592015-08-11 10:33:13 +0200403 rtc::scoped_ptr<FakeDtlsIdentityStore> dtls_identity_store(
404 new FakeDtlsIdentityStore());
405 dtls_identity_store->set_should_fail(identity_request_should_fail);
Henrik Lundin64dad832015-05-11 12:44:23 +0200406 PeerConnectionInterface::RTCConfiguration configuration;
Henrik Boström5e56c592015-08-11 10:33:13 +0200407 Init(dtls_identity_store.Pass(), configuration);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000408 }
409
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000410 void InitWithDtmfCodec() {
411 // Add kTelephoneEventCodec for dtmf test.
wu@webrtc.org364f2042013-11-20 21:49:41 +0000412 const cricket::AudioCodec kTelephoneEventCodec(
413 106, "telephone-event", 8000, 0, 1, 0);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000414 std::vector<cricket::AudioCodec> codecs;
415 codecs.push_back(kTelephoneEventCodec);
416 media_engine_->SetAudioCodecs(codecs);
417 desc_factory_->set_audio_codecs(codecs);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000418 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000419 }
420
421 // Creates a local offer and applies it. Starts ice.
422 // Call mediastream_signaling_.UseOptionsWithStreamX() before this function
423 // to decide which streams to create.
424 void InitiateCall() {
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +0000425 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000426 SetLocalDescriptionWithoutError(offer);
427 EXPECT_TRUE_WAIT(PeerConnectionInterface::kIceGatheringNew !=
428 observer_.ice_gathering_state_,
429 kIceCandidatesTimeout);
430 }
431
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +0000432 SessionDescriptionInterface* CreateOffer() {
433 PeerConnectionInterface::RTCOfferAnswerOptions options;
434 options.offer_to_receive_audio =
435 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
436
437 return CreateOffer(options);
438 }
439
wu@webrtc.org91053e72013-08-10 07:18:04 +0000440 SessionDescriptionInterface* CreateOffer(
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +0000441 const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000442 rtc::scoped_refptr<WebRtcSessionCreateSDPObserverForTest>
wu@webrtc.org91053e72013-08-10 07:18:04 +0000443 observer = new WebRtcSessionCreateSDPObserverForTest();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +0000444 session_->CreateOffer(observer, options);
wu@webrtc.org91053e72013-08-10 07:18:04 +0000445 EXPECT_TRUE_WAIT(
446 observer->state() != WebRtcSessionCreateSDPObserverForTest::kInit,
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000447 2000);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000448 return observer->ReleaseDescription();
wu@webrtc.org91053e72013-08-10 07:18:04 +0000449 }
450
451 SessionDescriptionInterface* CreateAnswer(
452 const webrtc::MediaConstraintsInterface* constraints) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000453 rtc::scoped_refptr<WebRtcSessionCreateSDPObserverForTest> observer
wu@webrtc.org91053e72013-08-10 07:18:04 +0000454 = new WebRtcSessionCreateSDPObserverForTest();
455 session_->CreateAnswer(observer, constraints);
456 EXPECT_TRUE_WAIT(
457 observer->state() != WebRtcSessionCreateSDPObserverForTest::kInit,
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000458 2000);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000459 return observer->ReleaseDescription();
wu@webrtc.org91053e72013-08-10 07:18:04 +0000460 }
461
wu@webrtc.org364f2042013-11-20 21:49:41 +0000462 bool ChannelsExist() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000463 return (session_->voice_channel() != NULL &&
464 session_->video_channel() != NULL);
465 }
466
wu@webrtc.org364f2042013-11-20 21:49:41 +0000467 void CheckTransportChannels() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000468 EXPECT_TRUE(session_->GetChannel(cricket::CN_AUDIO, 1) != NULL);
469 EXPECT_TRUE(session_->GetChannel(cricket::CN_AUDIO, 2) != NULL);
470 EXPECT_TRUE(session_->GetChannel(cricket::CN_VIDEO, 1) != NULL);
471 EXPECT_TRUE(session_->GetChannel(cricket::CN_VIDEO, 2) != NULL);
472 }
473
474 void VerifyCryptoParams(const cricket::SessionDescription* sdp) {
475 ASSERT_TRUE(session_.get() != NULL);
476 const cricket::ContentInfo* content = cricket::GetFirstAudioContent(sdp);
477 ASSERT_TRUE(content != NULL);
478 const cricket::AudioContentDescription* audio_content =
479 static_cast<const cricket::AudioContentDescription*>(
480 content->description);
481 ASSERT_TRUE(audio_content != NULL);
482 ASSERT_EQ(1U, audio_content->cryptos().size());
483 ASSERT_EQ(47U, audio_content->cryptos()[0].key_params.size());
484 ASSERT_EQ("AES_CM_128_HMAC_SHA1_80",
485 audio_content->cryptos()[0].cipher_suite);
486 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf),
487 audio_content->protocol());
488
489 content = cricket::GetFirstVideoContent(sdp);
490 ASSERT_TRUE(content != NULL);
491 const cricket::VideoContentDescription* video_content =
492 static_cast<const cricket::VideoContentDescription*>(
493 content->description);
494 ASSERT_TRUE(video_content != NULL);
495 ASSERT_EQ(1U, video_content->cryptos().size());
496 ASSERT_EQ("AES_CM_128_HMAC_SHA1_80",
497 video_content->cryptos()[0].cipher_suite);
498 ASSERT_EQ(47U, video_content->cryptos()[0].key_params.size());
499 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf),
500 video_content->protocol());
501 }
502
503 void VerifyNoCryptoParams(const cricket::SessionDescription* sdp, bool dtls) {
504 const cricket::ContentInfo* content = cricket::GetFirstAudioContent(sdp);
505 ASSERT_TRUE(content != NULL);
506 const cricket::AudioContentDescription* audio_content =
507 static_cast<const cricket::AudioContentDescription*>(
508 content->description);
509 ASSERT_TRUE(audio_content != NULL);
510 ASSERT_EQ(0U, audio_content->cryptos().size());
511
512 content = cricket::GetFirstVideoContent(sdp);
513 ASSERT_TRUE(content != NULL);
514 const cricket::VideoContentDescription* video_content =
515 static_cast<const cricket::VideoContentDescription*>(
516 content->description);
517 ASSERT_TRUE(video_content != NULL);
518 ASSERT_EQ(0U, video_content->cryptos().size());
519
520 if (dtls) {
deadbeeff3938292015-07-15 12:20:53 -0700521 EXPECT_EQ(std::string(cricket::kMediaProtocolDtlsSavpf),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000522 audio_content->protocol());
deadbeeff3938292015-07-15 12:20:53 -0700523 EXPECT_EQ(std::string(cricket::kMediaProtocolDtlsSavpf),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000524 video_content->protocol());
525 } else {
526 EXPECT_EQ(std::string(cricket::kMediaProtocolAvpf),
527 audio_content->protocol());
528 EXPECT_EQ(std::string(cricket::kMediaProtocolAvpf),
529 video_content->protocol());
530 }
531 }
532
533 // Set the internal fake description factories to do DTLS-SRTP.
534 void SetFactoryDtlsSrtp() {
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000535 desc_factory_->set_secure(cricket::SEC_DISABLED);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000536 std::string identity_name = "WebRTC" +
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000537 rtc::ToString(rtc::CreateRandomId());
538 identity_.reset(rtc::SSLIdentity::Generate(identity_name));
henrike@webrtc.org723d6832013-07-12 16:04:50 +0000539 tdesc_factory_->set_identity(identity_.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000540 tdesc_factory_->set_secure(cricket::SEC_REQUIRED);
541 }
542
543 void VerifyFingerprintStatus(const cricket::SessionDescription* sdp,
544 bool expected) {
545 const TransportInfo* audio = sdp->GetTransportInfoByName("audio");
546 ASSERT_TRUE(audio != NULL);
547 ASSERT_EQ(expected, audio->description.identity_fingerprint.get() != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000548 const TransportInfo* video = sdp->GetTransportInfoByName("video");
549 ASSERT_TRUE(video != NULL);
550 ASSERT_EQ(expected, video->description.identity_fingerprint.get() != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000551 }
552
553 void VerifyAnswerFromNonCryptoOffer() {
jiayl@webrtc.org7d4891d2014-09-09 21:43:15 +0000554 // Create an SDP without Crypto.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000555 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +0000556 options.recv_video = true;
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000557 JsepSessionDescription* offer(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000558 CreateRemoteOffer(options, cricket::SEC_DISABLED));
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000559 ASSERT_TRUE(offer != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000560 VerifyNoCryptoParams(offer->description(), false);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000561 SetRemoteDescriptionOfferExpectError(kSdpWithoutSdesCrypto,
562 offer);
wu@webrtc.org91053e72013-08-10 07:18:04 +0000563 const webrtc::SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000564 // Answer should be NULL as no crypto params in offer.
565 ASSERT_TRUE(answer == NULL);
566 }
567
568 void VerifyAnswerFromCryptoOffer() {
569 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +0000570 options.recv_video = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000571 options.bundle_enabled = true;
572 scoped_ptr<JsepSessionDescription> offer(
573 CreateRemoteOffer(options, cricket::SEC_REQUIRED));
574 ASSERT_TRUE(offer.get() != NULL);
575 VerifyCryptoParams(offer->description());
576 SetRemoteDescriptionWithoutError(offer.release());
wu@webrtc.org91053e72013-08-10 07:18:04 +0000577 scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000578 ASSERT_TRUE(answer.get() != NULL);
579 VerifyCryptoParams(answer->description());
580 }
581
buildbot@webrtc.org53df88c2014-08-07 22:46:01 +0000582 void SetAndVerifyNumUnsignalledRecvStreams(
583 int value_set, int value_expected) {
584 constraints_.reset(new FakeConstraints());
585 constraints_->AddOptional(
586 webrtc::MediaConstraintsInterface::kNumUnsignalledRecvStreams,
587 value_set);
588 session_.reset();
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000589 Init();
buildbot@webrtc.org53df88c2014-08-07 22:46:01 +0000590 mediastream_signaling_.SendAudioVideoStream1();
591 SessionDescriptionInterface* offer = CreateOffer();
592
593 SetLocalDescriptionWithoutError(offer);
594
595 video_channel_ = media_engine_->GetVideoChannel(0);
596
597 ASSERT_TRUE(video_channel_ != NULL);
598 cricket::VideoOptions video_options;
599 EXPECT_TRUE(video_channel_->GetOptions(&video_options));
600 EXPECT_EQ(value_expected,
601 video_options.unsignalled_recv_stream_limit.GetWithDefaultIfUnset(-1));
602 }
603
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000604 void CompareIceUfragAndPassword(const cricket::SessionDescription* desc1,
605 const cricket::SessionDescription* desc2,
606 bool expect_equal) {
607 if (desc1->contents().size() != desc2->contents().size()) {
608 EXPECT_FALSE(expect_equal);
609 return;
610 }
611
612 const cricket::ContentInfos& contents = desc1->contents();
613 cricket::ContentInfos::const_iterator it = contents.begin();
614
615 for (; it != contents.end(); ++it) {
616 const cricket::TransportDescription* transport_desc1 =
617 desc1->GetTransportDescriptionByName(it->name);
618 const cricket::TransportDescription* transport_desc2 =
619 desc2->GetTransportDescriptionByName(it->name);
620 if (!transport_desc1 || !transport_desc2) {
621 EXPECT_FALSE(expect_equal);
622 return;
623 }
624 if (transport_desc1->ice_pwd != transport_desc2->ice_pwd ||
625 transport_desc1->ice_ufrag != transport_desc2->ice_ufrag) {
626 EXPECT_FALSE(expect_equal);
627 return;
628 }
629 }
630 EXPECT_TRUE(expect_equal);
631 }
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000632
633 void RemoveIceUfragPwdLines(const SessionDescriptionInterface* current_desc,
634 std::string *sdp) {
635 const cricket::SessionDescription* desc = current_desc->description();
636 EXPECT_TRUE(current_desc->ToString(sdp));
637
638 const cricket::ContentInfos& contents = desc->contents();
639 cricket::ContentInfos::const_iterator it = contents.begin();
640 // Replace ufrag and pwd lines with empty strings.
641 for (; it != contents.end(); ++it) {
642 const cricket::TransportDescription* transport_desc =
643 desc->GetTransportDescriptionByName(it->name);
644 std::string ufrag_line = "a=ice-ufrag:" + transport_desc->ice_ufrag
645 + "\r\n";
646 std::string pwd_line = "a=ice-pwd:" + transport_desc->ice_pwd
647 + "\r\n";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000648 rtc::replace_substrs(ufrag_line.c_str(), ufrag_line.length(),
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000649 "", 0,
650 sdp);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000651 rtc::replace_substrs(pwd_line.c_str(), pwd_line.length(),
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000652 "", 0,
653 sdp);
654 }
655 }
656
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +0000657 void ModifyIceUfragPwdLines(const SessionDescriptionInterface* current_desc,
658 const std::string& modified_ice_ufrag,
659 const std::string& modified_ice_pwd,
660 std::string* sdp) {
661 const cricket::SessionDescription* desc = current_desc->description();
662 EXPECT_TRUE(current_desc->ToString(sdp));
663
664 const cricket::ContentInfos& contents = desc->contents();
665 cricket::ContentInfos::const_iterator it = contents.begin();
666 // Replace ufrag and pwd lines with |modified_ice_ufrag| and
667 // |modified_ice_pwd| strings.
668 for (; it != contents.end(); ++it) {
669 const cricket::TransportDescription* transport_desc =
670 desc->GetTransportDescriptionByName(it->name);
671 std::string ufrag_line = "a=ice-ufrag:" + transport_desc->ice_ufrag
672 + "\r\n";
673 std::string pwd_line = "a=ice-pwd:" + transport_desc->ice_pwd
674 + "\r\n";
675 std::string mod_ufrag = "a=ice-ufrag:" + modified_ice_ufrag + "\r\n";
676 std::string mod_pwd = "a=ice-pwd:" + modified_ice_pwd + "\r\n";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000677 rtc::replace_substrs(ufrag_line.c_str(), ufrag_line.length(),
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +0000678 mod_ufrag.c_str(), mod_ufrag.length(),
679 sdp);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000680 rtc::replace_substrs(pwd_line.c_str(), pwd_line.length(),
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +0000681 mod_pwd.c_str(), mod_pwd.length(),
682 sdp);
683 }
684 }
685
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000686 // Creates a remote offer and and applies it as a remote description,
687 // creates a local answer and applies is as a local description.
688 // Call mediastream_signaling_.UseOptionsWithStreamX() before this function
689 // to decide which local and remote streams to create.
690 void CreateAndSetRemoteOfferAndLocalAnswer() {
691 SessionDescriptionInterface* offer = CreateRemoteOffer();
692 SetRemoteDescriptionWithoutError(offer);
wu@webrtc.org91053e72013-08-10 07:18:04 +0000693 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000694 SetLocalDescriptionWithoutError(answer);
695 }
696 void SetLocalDescriptionWithoutError(SessionDescriptionInterface* desc) {
697 EXPECT_TRUE(session_->SetLocalDescription(desc, NULL));
698 }
699 void SetLocalDescriptionExpectState(SessionDescriptionInterface* desc,
700 BaseSession::State expected_state) {
701 SetLocalDescriptionWithoutError(desc);
702 EXPECT_EQ(expected_state, session_->state());
703 }
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000704 void SetLocalDescriptionExpectError(const std::string& action,
705 const std::string& expected_error,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000706 SessionDescriptionInterface* desc) {
707 std::string error;
708 EXPECT_FALSE(session_->SetLocalDescription(desc, &error));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000709 std::string sdp_type = "local ";
710 sdp_type.append(action);
711 EXPECT_NE(std::string::npos, error.find(sdp_type));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000712 EXPECT_NE(std::string::npos, error.find(expected_error));
713 }
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000714 void SetLocalDescriptionOfferExpectError(const std::string& expected_error,
715 SessionDescriptionInterface* desc) {
716 SetLocalDescriptionExpectError(SessionDescriptionInterface::kOffer,
717 expected_error, desc);
718 }
719 void SetLocalDescriptionAnswerExpectError(const std::string& expected_error,
720 SessionDescriptionInterface* desc) {
721 SetLocalDescriptionExpectError(SessionDescriptionInterface::kAnswer,
722 expected_error, desc);
723 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000724 void SetRemoteDescriptionWithoutError(SessionDescriptionInterface* desc) {
725 EXPECT_TRUE(session_->SetRemoteDescription(desc, NULL));
726 }
727 void SetRemoteDescriptionExpectState(SessionDescriptionInterface* desc,
728 BaseSession::State expected_state) {
729 SetRemoteDescriptionWithoutError(desc);
730 EXPECT_EQ(expected_state, session_->state());
731 }
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000732 void SetRemoteDescriptionExpectError(const std::string& action,
733 const std::string& expected_error,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000734 SessionDescriptionInterface* desc) {
735 std::string error;
736 EXPECT_FALSE(session_->SetRemoteDescription(desc, &error));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000737 std::string sdp_type = "remote ";
738 sdp_type.append(action);
739 EXPECT_NE(std::string::npos, error.find(sdp_type));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000740 EXPECT_NE(std::string::npos, error.find(expected_error));
741 }
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000742 void SetRemoteDescriptionOfferExpectError(
743 const std::string& expected_error, SessionDescriptionInterface* desc) {
744 SetRemoteDescriptionExpectError(SessionDescriptionInterface::kOffer,
745 expected_error, desc);
746 }
747 void SetRemoteDescriptionPranswerExpectError(
748 const std::string& expected_error, SessionDescriptionInterface* desc) {
749 SetRemoteDescriptionExpectError(SessionDescriptionInterface::kPrAnswer,
750 expected_error, desc);
751 }
752 void SetRemoteDescriptionAnswerExpectError(
753 const std::string& expected_error, SessionDescriptionInterface* desc) {
754 SetRemoteDescriptionExpectError(SessionDescriptionInterface::kAnswer,
755 expected_error, desc);
756 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000757
758 void CreateCryptoOfferAndNonCryptoAnswer(SessionDescriptionInterface** offer,
759 SessionDescriptionInterface** nocrypto_answer) {
760 // Create a SDP without Crypto.
761 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +0000762 options.recv_video = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000763 options.bundle_enabled = true;
764 *offer = CreateRemoteOffer(options, cricket::SEC_ENABLED);
765 ASSERT_TRUE(*offer != NULL);
766 VerifyCryptoParams((*offer)->description());
767
768 *nocrypto_answer = CreateRemoteAnswer(*offer, options,
769 cricket::SEC_DISABLED);
770 EXPECT_TRUE(*nocrypto_answer != NULL);
771 }
772
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000773 void CreateDtlsOfferAndNonDtlsAnswer(SessionDescriptionInterface** offer,
774 SessionDescriptionInterface** nodtls_answer) {
775 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +0000776 options.recv_video = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000777 options.bundle_enabled = true;
778
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000779 rtc::scoped_ptr<SessionDescriptionInterface> temp_offer(
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000780 CreateRemoteOffer(options, cricket::SEC_ENABLED));
781
782 *nodtls_answer =
783 CreateRemoteAnswer(temp_offer.get(), options, cricket::SEC_ENABLED);
784 EXPECT_TRUE(*nodtls_answer != NULL);
785 VerifyFingerprintStatus((*nodtls_answer)->description(), false);
786 VerifyCryptoParams((*nodtls_answer)->description());
787
788 SetFactoryDtlsSrtp();
789 *offer = CreateRemoteOffer(options, cricket::SEC_ENABLED);
790 ASSERT_TRUE(*offer != NULL);
791 VerifyFingerprintStatus((*offer)->description(), true);
792 VerifyCryptoParams((*offer)->description());
793 }
794
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000795 JsepSessionDescription* CreateRemoteOfferWithVersion(
796 cricket::MediaSessionOptions options,
797 cricket::SecurePolicy secure_policy,
798 const std::string& session_version,
799 const SessionDescriptionInterface* current_desc) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000800 std::string session_id = rtc::ToString(rtc::CreateRandomId64());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000801 const cricket::SessionDescription* cricket_desc = NULL;
802 if (current_desc) {
803 cricket_desc = current_desc->description();
804 session_id = current_desc->session_id();
805 }
806
807 desc_factory_->set_secure(secure_policy);
808 JsepSessionDescription* offer(
809 new JsepSessionDescription(JsepSessionDescription::kOffer));
810 if (!offer->Initialize(desc_factory_->CreateOffer(options, cricket_desc),
811 session_id, session_version)) {
812 delete offer;
813 offer = NULL;
814 }
815 return offer;
816 }
817 JsepSessionDescription* CreateRemoteOffer(
818 cricket::MediaSessionOptions options) {
819 return CreateRemoteOfferWithVersion(options, cricket::SEC_ENABLED,
820 kSessionVersion, NULL);
821 }
822 JsepSessionDescription* CreateRemoteOffer(
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000823 cricket::MediaSessionOptions options, cricket::SecurePolicy sdes_policy) {
824 return CreateRemoteOfferWithVersion(
825 options, sdes_policy, kSessionVersion, NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000826 }
827 JsepSessionDescription* CreateRemoteOffer(
828 cricket::MediaSessionOptions options,
829 const SessionDescriptionInterface* current_desc) {
830 return CreateRemoteOfferWithVersion(options, cricket::SEC_ENABLED,
831 kSessionVersion, current_desc);
832 }
833
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000834 JsepSessionDescription* CreateRemoteOfferWithSctpPort(
835 const char* sctp_stream_name, int new_port,
836 cricket::MediaSessionOptions options) {
837 options.data_channel_type = cricket::DCT_SCTP;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +0000838 options.AddSendStream(cricket::MEDIA_TYPE_DATA, "datachannel",
839 sctp_stream_name);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000840 return ChangeSDPSctpPort(new_port, CreateRemoteOffer(options));
841 }
842
843 // Takes ownership of offer_basis (and deletes it).
844 JsepSessionDescription* ChangeSDPSctpPort(
845 int new_port, webrtc::SessionDescriptionInterface *offer_basis) {
846 // Stringify the input SDP, swap the 5000 for 'new_port' and create a new
847 // SessionDescription from the mutated string.
848 const char* default_port_str = "5000";
849 char new_port_str[16];
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000850 rtc::sprintfn(new_port_str, sizeof(new_port_str), "%d", new_port);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000851 std::string offer_str;
852 offer_basis->ToString(&offer_str);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000853 rtc::replace_substrs(default_port_str, strlen(default_port_str),
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000854 new_port_str, strlen(new_port_str),
855 &offer_str);
856 JsepSessionDescription* offer = new JsepSessionDescription(
857 offer_basis->type());
858 delete offer_basis;
859 offer->Initialize(offer_str, NULL);
860 return offer;
861 }
862
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000863 // Create a remote offer. Call mediastream_signaling_.UseOptionsWithStreamX()
864 // before this function to decide which streams to create.
865 JsepSessionDescription* CreateRemoteOffer() {
866 cricket::MediaSessionOptions options;
867 mediastream_signaling_.GetOptionsForAnswer(NULL, &options);
868 return CreateRemoteOffer(options, session_->remote_description());
869 }
870
871 JsepSessionDescription* CreateRemoteAnswer(
872 const SessionDescriptionInterface* offer,
873 cricket::MediaSessionOptions options,
874 cricket::SecurePolicy policy) {
875 desc_factory_->set_secure(policy);
876 const std::string session_id =
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000877 rtc::ToString(rtc::CreateRandomId64());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000878 JsepSessionDescription* answer(
879 new JsepSessionDescription(JsepSessionDescription::kAnswer));
880 if (!answer->Initialize(desc_factory_->CreateAnswer(offer->description(),
881 options, NULL),
882 session_id, kSessionVersion)) {
883 delete answer;
884 answer = NULL;
885 }
886 return answer;
887 }
888
889 JsepSessionDescription* CreateRemoteAnswer(
890 const SessionDescriptionInterface* offer,
891 cricket::MediaSessionOptions options) {
892 return CreateRemoteAnswer(offer, options, cricket::SEC_REQUIRED);
893 }
894
895 // Creates an answer session description with streams based on
896 // |mediastream_signaling_|. Call
897 // mediastream_signaling_.UseOptionsWithStreamX() before this function
898 // to decide which streams to create.
899 JsepSessionDescription* CreateRemoteAnswer(
900 const SessionDescriptionInterface* offer) {
901 cricket::MediaSessionOptions options;
902 mediastream_signaling_.GetOptionsForAnswer(NULL, &options);
903 return CreateRemoteAnswer(offer, options, cricket::SEC_REQUIRED);
904 }
905
906 void TestSessionCandidatesWithBundleRtcpMux(bool bundle, bool rtcp_mux) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000907 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000908 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000909 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +0000910
911 PeerConnectionInterface::RTCOfferAnswerOptions options;
912 options.use_rtp_mux = bundle;
913
914 SessionDescriptionInterface* offer = CreateOffer(options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000915 // SetLocalDescription and SetRemoteDescriptions takes ownership of offer
916 // and answer.
917 SetLocalDescriptionWithoutError(offer);
918
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000919 rtc::scoped_ptr<SessionDescriptionInterface> answer(
henrike@webrtc.org723d6832013-07-12 16:04:50 +0000920 CreateRemoteAnswer(session_->local_description()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000921 std::string sdp;
922 EXPECT_TRUE(answer->ToString(&sdp));
923
924 size_t expected_candidate_num = 2;
925 if (!rtcp_mux) {
926 // If rtcp_mux is enabled we should expect 4 candidates - host and srflex
927 // for rtp and rtcp.
928 expected_candidate_num = 4;
929 // Disable rtcp-mux from the answer
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000930 const std::string kRtcpMux = "a=rtcp-mux";
931 const std::string kXRtcpMux = "a=xrtcp-mux";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000932 rtc::replace_substrs(kRtcpMux.c_str(), kRtcpMux.length(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000933 kXRtcpMux.c_str(), kXRtcpMux.length(),
934 &sdp);
935 }
936
937 SessionDescriptionInterface* new_answer = CreateSessionDescription(
938 JsepSessionDescription::kAnswer, sdp, NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000939
940 // SetRemoteDescription to enable rtcp mux.
henrike@webrtc.org723d6832013-07-12 16:04:50 +0000941 SetRemoteDescriptionWithoutError(new_answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000942 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
943 EXPECT_EQ(expected_candidate_num, observer_.mline_0_candidates_.size());
944 EXPECT_EQ(expected_candidate_num, observer_.mline_1_candidates_.size());
945 for (size_t i = 0; i < observer_.mline_0_candidates_.size(); ++i) {
946 cricket::Candidate c0 = observer_.mline_0_candidates_[i];
947 cricket::Candidate c1 = observer_.mline_1_candidates_[i];
948 if (bundle) {
949 EXPECT_TRUE(c0.IsEquivalent(c1));
950 } else {
951 EXPECT_FALSE(c0.IsEquivalent(c1));
952 }
953 }
954 }
955 // Tests that we can only send DTMF when the dtmf codec is supported.
956 void TestCanInsertDtmf(bool can) {
957 if (can) {
958 InitWithDtmfCodec();
959 } else {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000960 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000961 }
962 mediastream_signaling_.SendAudioVideoStream1();
963 CreateAndSetRemoteOfferAndLocalAnswer();
964 EXPECT_FALSE(session_->CanInsertDtmf(""));
965 EXPECT_EQ(can, session_->CanInsertDtmf(kAudioTrack1));
966 }
967
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +0000968 // Helper class to configure loopback network and verify Best
969 // Connection using right IP protocol for TestLoopbackCall
970 // method. LoopbackNetworkManager applies firewall rules to block
971 // all ping traffic once ICE completed, and remove them to observe
972 // ICE reconnected again. This LoopbackNetworkConfiguration struct
973 // verifies the best connection is using the right IP protocol after
974 // initial ICE convergences.
975
976 class LoopbackNetworkConfiguration {
977 public:
978 LoopbackNetworkConfiguration()
979 : test_ipv6_network_(false),
980 test_extra_ipv4_network_(false),
981 best_connection_after_initial_ice_converged_(1, 0) {}
982
983 // Used to track the expected best connection count in each IP protocol.
984 struct ExpectedBestConnection {
985 ExpectedBestConnection(int ipv4_count, int ipv6_count)
986 : ipv4_count_(ipv4_count),
987 ipv6_count_(ipv6_count) {}
988
989 int ipv4_count_;
990 int ipv6_count_;
991 };
992
993 bool test_ipv6_network_;
994 bool test_extra_ipv4_network_;
995 ExpectedBestConnection best_connection_after_initial_ice_converged_;
996
997 void VerifyBestConnectionAfterIceConverge(
jbauchac8869e2015-07-03 01:36:14 -0700998 const rtc::scoped_refptr<FakeMetricsObserver> metrics_observer) const {
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +0000999 Verify(metrics_observer, best_connection_after_initial_ice_converged_);
1000 }
1001
1002 private:
jbauchac8869e2015-07-03 01:36:14 -07001003 void Verify(const rtc::scoped_refptr<FakeMetricsObserver> metrics_observer,
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001004 const ExpectedBestConnection& expected) const {
1005 EXPECT_EQ(
jbauchac8869e2015-07-03 01:36:14 -07001006 metrics_observer->GetCounter(webrtc::kBestConnections_IPv4),
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001007 expected.ipv4_count_);
1008 EXPECT_EQ(
jbauchac8869e2015-07-03 01:36:14 -07001009 metrics_observer->GetCounter(webrtc::kBestConnections_IPv6),
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001010 expected.ipv6_count_);
1011 }
1012 };
1013
1014 class LoopbackNetworkManager {
1015 public:
1016 LoopbackNetworkManager(WebRtcSessionTest* session,
1017 const LoopbackNetworkConfiguration& config)
1018 : config_(config) {
1019 session->AddInterface(
1020 rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
1021 if (config_.test_extra_ipv4_network_) {
1022 session->AddInterface(
1023 rtc::SocketAddress(kClientAddrHost2, kClientAddrPort));
1024 }
1025 if (config_.test_ipv6_network_) {
1026 session->AddInterface(
1027 rtc::SocketAddress(kClientIPv6AddrHost1, kClientAddrPort));
1028 }
1029 }
1030
1031 void ApplyFirewallRules(rtc::FirewallSocketServer* fss) {
1032 fss->AddRule(false, rtc::FP_ANY, rtc::FD_ANY,
1033 rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
1034 if (config_.test_extra_ipv4_network_) {
1035 fss->AddRule(false, rtc::FP_ANY, rtc::FD_ANY,
1036 rtc::SocketAddress(kClientAddrHost2, kClientAddrPort));
1037 }
1038 if (config_.test_ipv6_network_) {
1039 fss->AddRule(false, rtc::FP_ANY, rtc::FD_ANY,
1040 rtc::SocketAddress(kClientIPv6AddrHost1, kClientAddrPort));
1041 }
1042 }
1043
1044 void ClearRules(rtc::FirewallSocketServer* fss) { fss->ClearRules(); }
1045
1046 private:
1047 LoopbackNetworkConfiguration config_;
1048 };
1049
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001050 // The method sets up a call from the session to itself, in a loopback
1051 // arrangement. It also uses a firewall rule to create a temporary
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00001052 // disconnection, and then a permanent disconnection.
1053 // This code is placed in a method so that it can be invoked
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001054 // by multiple tests with different allocators (e.g. with and without BUNDLE).
1055 // While running the call, this method also checks if the session goes through
1056 // the correct sequence of ICE states when a connection is established,
1057 // broken, and re-established.
1058 // The Connection state should go:
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00001059 // New -> Checking -> (Connected) -> Completed -> Disconnected -> Completed
1060 // -> Failed.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001061 // The Gathering state should go: New -> Gathering -> Completed.
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001062
1063 void TestLoopbackCall(const LoopbackNetworkConfiguration& config) {
1064 LoopbackNetworkManager loopback_network_manager(this, config);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001065 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001066 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001067 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001068
1069 EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
1070 observer_.ice_gathering_state_);
1071 SetLocalDescriptionWithoutError(offer);
1072 EXPECT_EQ(PeerConnectionInterface::kIceConnectionNew,
1073 observer_.ice_connection_state_);
1074 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceGatheringGathering,
1075 observer_.ice_gathering_state_,
1076 kIceCandidatesTimeout);
1077 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1078 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
1079 observer_.ice_gathering_state_,
1080 kIceCandidatesTimeout);
1081
1082 std::string sdp;
1083 offer->ToString(&sdp);
1084 SessionDescriptionInterface* desc =
jbauchfabe2c92015-07-16 13:43:14 -07001085 webrtc::CreateSessionDescription(
1086 JsepSessionDescription::kAnswer, sdp, nullptr);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001087 ASSERT_TRUE(desc != NULL);
1088 SetRemoteDescriptionWithoutError(desc);
1089
1090 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionChecking,
1091 observer_.ice_connection_state_,
1092 kIceCandidatesTimeout);
mallinath@webrtc.orgd3dc4242014-03-01 00:05:52 +00001093
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00001094 // The ice connection state is "Connected" too briefly to catch in a test.
1095 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001096 observer_.ice_connection_state_,
1097 kIceCandidatesTimeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001098
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001099 config.VerifyBestConnectionAfterIceConverge(metrics_observer_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001100 // Adding firewall rule to block ping requests, which should cause
1101 // transport channel failure.
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001102
1103 loopback_network_manager.ApplyFirewallRules(fss_.get());
1104
1105 LOG(LS_INFO) << "Firewall Rules applied";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001106 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
1107 observer_.ice_connection_state_,
1108 kIceCandidatesTimeout);
1109
jbauchac8869e2015-07-03 01:36:14 -07001110 metrics_observer_->Reset();
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001111
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001112 // Clearing the rules, session should move back to completed state.
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001113 loopback_network_manager.ClearRules(fss_.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001114 // Session is automatically calling OnSignalingReady after creation of
1115 // new portallocator session which will allocate new set of candidates.
1116
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001117 LOG(LS_INFO) << "Firewall Rules cleared";
1118
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00001119 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001120 observer_.ice_connection_state_,
1121 kIceCandidatesTimeout);
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00001122
1123 // Now we block ping requests and wait until the ICE connection transitions
1124 // to the Failed state. This will take at least 30 seconds because it must
1125 // wait for the Port to timeout.
1126 int port_timeout = 30000;
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001127
1128 loopback_network_manager.ApplyFirewallRules(fss_.get());
1129 LOG(LS_INFO) << "Firewall Rules applied again";
jlmiller@webrtc.org804eb462015-02-20 02:20:03 +00001130 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00001131 observer_.ice_connection_state_,
1132 kIceCandidatesTimeout + port_timeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001133 }
1134
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001135 void TestLoopbackCall() {
1136 LoopbackNetworkConfiguration config;
1137 TestLoopbackCall(config);
1138 }
1139
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001140 // Adds CN codecs to FakeMediaEngine and MediaDescriptionFactory.
1141 void AddCNCodecs() {
wu@webrtc.org364f2042013-11-20 21:49:41 +00001142 const cricket::AudioCodec kCNCodec1(102, "CN", 8000, 0, 1, 0);
1143 const cricket::AudioCodec kCNCodec2(103, "CN", 16000, 0, 1, 0);
1144
1145 // Add kCNCodec for dtmf test.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001146 std::vector<cricket::AudioCodec> codecs = media_engine_->audio_codecs();;
1147 codecs.push_back(kCNCodec1);
1148 codecs.push_back(kCNCodec2);
1149 media_engine_->SetAudioCodecs(codecs);
1150 desc_factory_->set_audio_codecs(codecs);
1151 }
1152
1153 bool VerifyNoCNCodecs(const cricket::ContentInfo* content) {
1154 const cricket::ContentDescription* description = content->description;
1155 ASSERT(description != NULL);
1156 const cricket::AudioContentDescription* audio_content_desc =
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00001157 static_cast<const cricket::AudioContentDescription*>(description);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001158 ASSERT(audio_content_desc != NULL);
1159 for (size_t i = 0; i < audio_content_desc->codecs().size(); ++i) {
1160 if (audio_content_desc->codecs()[i].name == "CN")
1161 return false;
1162 }
1163 return true;
1164 }
1165
1166 void SetLocalDescriptionWithDataChannel() {
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +00001167 webrtc::InternalDataChannelInit dci;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001168 dci.reliable = false;
1169 session_->CreateDataChannel("datachannel", &dci);
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001170 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001171 SetLocalDescriptionWithoutError(offer);
1172 }
1173
wu@webrtc.org91053e72013-08-10 07:18:04 +00001174 void VerifyMultipleAsyncCreateDescription(
1175 bool success, CreateSessionDescriptionRequest::Type type) {
henrike@webrtc.org7666db72013-08-22 14:45:42 +00001176 InitWithDtls(!success);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001177 SetFactoryDtlsSrtp();
wu@webrtc.org91053e72013-08-10 07:18:04 +00001178 if (type == CreateSessionDescriptionRequest::kAnswer) {
1179 cricket::MediaSessionOptions options;
1180 scoped_ptr<JsepSessionDescription> offer(
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001181 CreateRemoteOffer(options, cricket::SEC_DISABLED));
wu@webrtc.org91053e72013-08-10 07:18:04 +00001182 ASSERT_TRUE(offer.get() != NULL);
1183 SetRemoteDescriptionWithoutError(offer.release());
1184 }
1185
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001186 PeerConnectionInterface::RTCOfferAnswerOptions options;
wu@webrtc.org91053e72013-08-10 07:18:04 +00001187 const int kNumber = 3;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001188 rtc::scoped_refptr<WebRtcSessionCreateSDPObserverForTest>
wu@webrtc.org91053e72013-08-10 07:18:04 +00001189 observers[kNumber];
1190 for (int i = 0; i < kNumber; ++i) {
1191 observers[i] = new WebRtcSessionCreateSDPObserverForTest();
1192 if (type == CreateSessionDescriptionRequest::kOffer) {
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001193 session_->CreateOffer(observers[i], options);
wu@webrtc.org91053e72013-08-10 07:18:04 +00001194 } else {
1195 session_->CreateAnswer(observers[i], NULL);
1196 }
1197 }
1198
1199 WebRtcSessionCreateSDPObserverForTest::State expected_state =
1200 success ? WebRtcSessionCreateSDPObserverForTest::kSucceeded :
1201 WebRtcSessionCreateSDPObserverForTest::kFailed;
1202
1203 for (int i = 0; i < kNumber; ++i) {
1204 EXPECT_EQ_WAIT(expected_state, observers[i]->state(), 1000);
1205 if (success) {
1206 EXPECT_TRUE(observers[i]->description() != NULL);
1207 } else {
1208 EXPECT_TRUE(observers[i]->description() == NULL);
1209 }
1210 }
1211 }
1212
mallinath@webrtc.org3d81b1b2014-09-09 14:38:10 +00001213 void ConfigureAllocatorWithTurn() {
1214 cricket::RelayServerConfig relay_server(cricket::RELAY_TURN);
1215 cricket::RelayCredentials credentials(kTurnUsername, kTurnPassword);
1216 relay_server.credentials = credentials;
1217 relay_server.ports.push_back(cricket::ProtocolAddress(
1218 kTurnUdpIntAddr, cricket::PROTO_UDP, false));
1219 allocator_->AddRelay(relay_server);
1220 allocator_->set_step_delay(cricket::kMinimumStepDelay);
Peter Thatcher3449faa2015-08-10 12:22:51 -07001221 allocator_->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP);
mallinath@webrtc.org3d81b1b2014-09-09 14:38:10 +00001222 }
1223
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001224 cricket::FakeMediaEngine* media_engine_;
1225 cricket::FakeDataEngine* data_engine_;
1226 cricket::FakeDeviceManager* device_manager_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001227 rtc::scoped_ptr<cricket::ChannelManager> channel_manager_;
1228 rtc::scoped_ptr<cricket::TransportDescriptionFactory> tdesc_factory_;
1229 rtc::scoped_ptr<rtc::SSLIdentity> identity_;
1230 rtc::scoped_ptr<cricket::MediaSessionDescriptionFactory> desc_factory_;
1231 rtc::scoped_ptr<rtc::PhysicalSocketServer> pss_;
1232 rtc::scoped_ptr<rtc::VirtualSocketServer> vss_;
1233 rtc::scoped_ptr<rtc::FirewallSocketServer> fss_;
1234 rtc::SocketServerScope ss_scope_;
1235 rtc::SocketAddress stun_socket_addr_;
jiayl@webrtc.orgbebc75e2014-09-26 23:01:11 +00001236 rtc::scoped_ptr<cricket::TestStunServer> stun_server_;
buildbot@webrtc.org41451d42014-05-03 05:39:45 +00001237 cricket::TestTurnServer turn_server_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001238 rtc::FakeNetworkManager network_manager_;
1239 rtc::scoped_ptr<cricket::BasicPortAllocator> allocator_;
wu@webrtc.org97077a32013-10-25 21:18:33 +00001240 PeerConnectionFactoryInterface::Options options_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001241 rtc::scoped_ptr<FakeConstraints> constraints_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001242 FakeMediaStreamSignaling mediastream_signaling_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001243 rtc::scoped_ptr<WebRtcSessionForTest> session_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001244 MockIceObserver observer_;
1245 cricket::FakeVideoMediaChannel* video_channel_;
1246 cricket::FakeVoiceMediaChannel* voice_channel_;
jbauchac8869e2015-07-03 01:36:14 -07001247 rtc::scoped_refptr<FakeMetricsObserver> metrics_observer_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001248};
1249
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001250TEST_F(WebRtcSessionTest, TestInitializeWithDtls) {
1251 InitWithDtls();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001252 // SDES is disabled when DTLS is on.
1253 EXPECT_EQ(cricket::SEC_DISABLED, session_->SdesPolicy());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001254}
1255
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001256TEST_F(WebRtcSessionTest, TestInitializeWithoutDtls) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001257 Init();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001258 // SDES is required if DTLS is off.
1259 EXPECT_EQ(cricket::SEC_REQUIRED, session_->SdesPolicy());
wu@webrtc.org91053e72013-08-10 07:18:04 +00001260}
1261
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001262TEST_F(WebRtcSessionTest, TestSessionCandidates) {
1263 TestSessionCandidatesWithBundleRtcpMux(false, false);
1264}
1265
1266// Below test cases (TestSessionCandidatesWith*) verify the candidates gathered
1267// with rtcp-mux and/or bundle.
1268TEST_F(WebRtcSessionTest, TestSessionCandidatesWithRtcpMux) {
1269 TestSessionCandidatesWithBundleRtcpMux(false, true);
1270}
1271
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001272TEST_F(WebRtcSessionTest, TestSessionCandidatesWithBundleRtcpMux) {
1273 TestSessionCandidatesWithBundleRtcpMux(true, true);
1274}
1275
1276TEST_F(WebRtcSessionTest, TestMultihomeCandidates) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001277 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
1278 AddInterface(rtc::SocketAddress(kClientAddrHost2, kClientAddrPort));
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001279 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001280 mediastream_signaling_.SendAudioVideoStream1();
1281 InitiateCall();
1282 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1283 EXPECT_EQ(8u, observer_.mline_0_candidates_.size());
1284 EXPECT_EQ(8u, observer_.mline_1_candidates_.size());
1285}
1286
1287TEST_F(WebRtcSessionTest, TestStunError) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001288 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
1289 AddInterface(rtc::SocketAddress(kClientAddrHost2, kClientAddrPort));
wu@webrtc.org364f2042013-11-20 21:49:41 +00001290 fss_->AddRule(false,
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001291 rtc::FP_UDP,
1292 rtc::FD_ANY,
1293 rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001294 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001295 mediastream_signaling_.SendAudioVideoStream1();
1296 InitiateCall();
wu@webrtc.org364f2042013-11-20 21:49:41 +00001297 // Since kClientAddrHost1 is blocked, not expecting stun candidates for it.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001298 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1299 EXPECT_EQ(6u, observer_.mline_0_candidates_.size());
1300 EXPECT_EQ(6u, observer_.mline_1_candidates_.size());
1301}
1302
mallinath@webrtc.org3d81b1b2014-09-09 14:38:10 +00001303// Test session delivers no candidates gathered when constraint set to "none".
1304TEST_F(WebRtcSessionTest, TestIceTransportsNone) {
1305 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001306 InitWithIceTransport(PeerConnectionInterface::kNone);
mallinath@webrtc.org3d81b1b2014-09-09 14:38:10 +00001307 mediastream_signaling_.SendAudioVideoStream1();
1308 InitiateCall();
1309 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1310 EXPECT_EQ(0u, observer_.mline_0_candidates_.size());
1311 EXPECT_EQ(0u, observer_.mline_1_candidates_.size());
1312}
1313
1314// Test session delivers only relay candidates gathered when constaint set to
1315// "relay".
1316TEST_F(WebRtcSessionTest, TestIceTransportsRelay) {
1317 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
1318 ConfigureAllocatorWithTurn();
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001319 InitWithIceTransport(PeerConnectionInterface::kRelay);
mallinath@webrtc.org3d81b1b2014-09-09 14:38:10 +00001320 mediastream_signaling_.SendAudioVideoStream1();
1321 InitiateCall();
1322 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1323 EXPECT_EQ(2u, observer_.mline_0_candidates_.size());
1324 EXPECT_EQ(2u, observer_.mline_1_candidates_.size());
1325 for (size_t i = 0; i < observer_.mline_0_candidates_.size(); ++i) {
1326 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
1327 observer_.mline_0_candidates_[i].type());
1328 }
1329 for (size_t i = 0; i < observer_.mline_1_candidates_.size(); ++i) {
1330 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
1331 observer_.mline_1_candidates_[i].type());
1332 }
1333}
1334
1335// Test session delivers all candidates gathered when constaint set to "all".
1336TEST_F(WebRtcSessionTest, TestIceTransportsAll) {
1337 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001338 InitWithIceTransport(PeerConnectionInterface::kAll);
mallinath@webrtc.org3d81b1b2014-09-09 14:38:10 +00001339 mediastream_signaling_.SendAudioVideoStream1();
1340 InitiateCall();
1341 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1342 // Host + STUN. By default allocator is disabled to gather relay candidates.
1343 EXPECT_EQ(4u, observer_.mline_0_candidates_.size());
1344 EXPECT_EQ(4u, observer_.mline_1_candidates_.size());
1345}
1346
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001347TEST_F(WebRtcSessionTest, SetSdpFailedOnInvalidSdp) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001348 Init();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001349 SessionDescriptionInterface* offer = NULL;
1350 // Since |offer| is NULL, there's no way to tell if it's an offer or answer.
1351 std::string unknown_action;
1352 SetLocalDescriptionExpectError(unknown_action, kInvalidSdp, offer);
1353 SetRemoteDescriptionExpectError(unknown_action, kInvalidSdp, offer);
1354}
1355
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001356// Test creating offers and receive answers and make sure the
1357// media engine creates the expected send and receive streams.
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001358TEST_F(WebRtcSessionTest, TestCreateSdesOfferReceiveSdesAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001359 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001360 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001361 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001362 const std::string session_id_orig = offer->session_id();
1363 const std::string session_version_orig = offer->session_version();
1364 SetLocalDescriptionWithoutError(offer);
1365
1366 mediastream_signaling_.SendAudioVideoStream2();
1367 SessionDescriptionInterface* answer =
1368 CreateRemoteAnswer(session_->local_description());
1369 SetRemoteDescriptionWithoutError(answer);
1370
1371 video_channel_ = media_engine_->GetVideoChannel(0);
1372 voice_channel_ = media_engine_->GetVoiceChannel(0);
1373
1374 ASSERT_EQ(1u, video_channel_->recv_streams().size());
1375 EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].id);
1376
1377 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
1378 EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].id);
1379
1380 ASSERT_EQ(1u, video_channel_->send_streams().size());
1381 EXPECT_TRUE(kVideoTrack1 == video_channel_->send_streams()[0].id);
1382 ASSERT_EQ(1u, voice_channel_->send_streams().size());
1383 EXPECT_TRUE(kAudioTrack1 == voice_channel_->send_streams()[0].id);
1384
1385 // Create new offer without send streams.
1386 mediastream_signaling_.SendNothing();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001387 offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001388
1389 // Verify the session id is the same and the session version is
1390 // increased.
1391 EXPECT_EQ(session_id_orig, offer->session_id());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001392 EXPECT_LT(rtc::FromString<uint64>(session_version_orig),
1393 rtc::FromString<uint64>(offer->session_version()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001394
1395 SetLocalDescriptionWithoutError(offer);
jiayl@webrtc.org7d4891d2014-09-09 21:43:15 +00001396 EXPECT_EQ(0u, video_channel_->send_streams().size());
1397 EXPECT_EQ(0u, voice_channel_->send_streams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001398
1399 mediastream_signaling_.SendAudioVideoStream2();
1400 answer = CreateRemoteAnswer(session_->local_description());
1401 SetRemoteDescriptionWithoutError(answer);
1402
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001403 // Make sure the receive streams have not changed.
1404 ASSERT_EQ(1u, video_channel_->recv_streams().size());
1405 EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].id);
1406 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
1407 EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].id);
1408}
1409
1410// Test receiving offers and creating answers and make sure the
1411// media engine creates the expected send and receive streams.
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001412TEST_F(WebRtcSessionTest, TestReceiveSdesOfferCreateSdesAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001413 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001414 mediastream_signaling_.SendAudioVideoStream2();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001415 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001416 VerifyCryptoParams(offer->description());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001417 SetRemoteDescriptionWithoutError(offer);
1418
1419 mediastream_signaling_.SendAudioVideoStream1();
wu@webrtc.org91053e72013-08-10 07:18:04 +00001420 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001421 VerifyCryptoParams(answer->description());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001422 SetLocalDescriptionWithoutError(answer);
1423
1424 const std::string session_id_orig = answer->session_id();
1425 const std::string session_version_orig = answer->session_version();
1426
1427 video_channel_ = media_engine_->GetVideoChannel(0);
1428 voice_channel_ = media_engine_->GetVoiceChannel(0);
1429
1430 ASSERT_EQ(1u, video_channel_->recv_streams().size());
1431 EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].id);
1432
1433 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
1434 EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].id);
1435
1436 ASSERT_EQ(1u, video_channel_->send_streams().size());
1437 EXPECT_TRUE(kVideoTrack1 == video_channel_->send_streams()[0].id);
1438 ASSERT_EQ(1u, voice_channel_->send_streams().size());
1439 EXPECT_TRUE(kAudioTrack1 == voice_channel_->send_streams()[0].id);
1440
1441 mediastream_signaling_.SendAudioVideoStream1And2();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001442 offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001443 SetRemoteDescriptionWithoutError(offer);
1444
1445 // Answer by turning off all send streams.
1446 mediastream_signaling_.SendNothing();
wu@webrtc.org91053e72013-08-10 07:18:04 +00001447 answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001448
1449 // Verify the session id is the same and the session version is
1450 // increased.
1451 EXPECT_EQ(session_id_orig, answer->session_id());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001452 EXPECT_LT(rtc::FromString<uint64>(session_version_orig),
1453 rtc::FromString<uint64>(answer->session_version()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001454 SetLocalDescriptionWithoutError(answer);
1455
1456 ASSERT_EQ(2u, video_channel_->recv_streams().size());
1457 EXPECT_TRUE(kVideoTrack1 == video_channel_->recv_streams()[0].id);
1458 EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[1].id);
1459 ASSERT_EQ(2u, voice_channel_->recv_streams().size());
1460 EXPECT_TRUE(kAudioTrack1 == voice_channel_->recv_streams()[0].id);
1461 EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[1].id);
1462
1463 // Make sure we have no send streams.
1464 EXPECT_EQ(0u, video_channel_->send_streams().size());
1465 EXPECT_EQ(0u, voice_channel_->send_streams().size());
1466}
1467
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001468TEST_F(WebRtcSessionTest, SetLocalSdpFailedOnCreateChannel) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001469 Init();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001470 media_engine_->set_fail_create_channel(true);
1471
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001472 SessionDescriptionInterface* offer = CreateOffer();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001473 ASSERT_TRUE(offer != NULL);
1474 // SetRemoteDescription and SetLocalDescription will take the ownership of
1475 // the offer.
1476 SetRemoteDescriptionOfferExpectError(kCreateChannelFailed, offer);
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001477 offer = CreateOffer();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001478 ASSERT_TRUE(offer != NULL);
1479 SetLocalDescriptionOfferExpectError(kCreateChannelFailed, offer);
1480}
1481
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001482//
1483// Tests for creating/setting SDP under different SDES/DTLS polices:
1484//
1485// --DTLS off and SDES on
1486// TestCreateSdesOfferReceiveSdesAnswer/TestReceiveSdesOfferCreateSdesAnswer:
1487// set local/remote offer/answer with crypto --> success
1488// TestSetNonSdesOfferWhenSdesOn: set local/remote offer without crypto --->
1489// failure
1490// TestSetLocalNonSdesAnswerWhenSdesOn: set local answer without crypto -->
1491// failure
1492// TestSetRemoteNonSdesAnswerWhenSdesOn: set remote answer without crypto -->
1493// failure
1494//
1495// --DTLS on and SDES off
1496// TestCreateDtlsOfferReceiveDtlsAnswer/TestReceiveDtlsOfferCreateDtlsAnswer:
1497// set local/remote offer/answer with DTLS fingerprint --> success
1498// TestReceiveNonDtlsOfferWhenDtlsOn: set local/remote offer without DTLS
1499// fingerprint --> failure
1500// TestSetLocalNonDtlsAnswerWhenDtlsOn: set local answer without fingerprint
1501// --> failure
1502// TestSetRemoteNonDtlsAnswerWhenDtlsOn: set remote answer without fingerprint
1503// --> failure
1504//
1505// --Encryption disabled: DTLS off and SDES off
1506// TestCreateOfferReceiveAnswerWithoutEncryption: set local offer and remote
1507// answer without SDES or DTLS --> success
1508// TestCreateAnswerReceiveOfferWithoutEncryption: set remote offer and local
1509// answer without SDES or DTLS --> success
1510//
1511
1512// Test that we return a failure when applying a remote/local offer that doesn't
1513// have cryptos enabled when DTLS is off.
1514TEST_F(WebRtcSessionTest, TestSetNonSdesOfferWhenSdesOn) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001515 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001516 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001517 options.recv_video = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001518 JsepSessionDescription* offer = CreateRemoteOffer(
1519 options, cricket::SEC_DISABLED);
1520 ASSERT_TRUE(offer != NULL);
1521 VerifyNoCryptoParams(offer->description(), false);
1522 // SetRemoteDescription and SetLocalDescription will take the ownership of
1523 // the offer.
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001524 SetRemoteDescriptionOfferExpectError(kSdpWithoutSdesCrypto, offer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001525 offer = CreateRemoteOffer(options, cricket::SEC_DISABLED);
1526 ASSERT_TRUE(offer != NULL);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001527 SetLocalDescriptionOfferExpectError(kSdpWithoutSdesCrypto, offer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001528}
1529
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001530// Test that we return a failure when applying a local answer that doesn't have
1531// cryptos enabled when DTLS is off.
1532TEST_F(WebRtcSessionTest, TestSetLocalNonSdesAnswerWhenSdesOn) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001533 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001534 SessionDescriptionInterface* offer = NULL;
1535 SessionDescriptionInterface* answer = NULL;
1536 CreateCryptoOfferAndNonCryptoAnswer(&offer, &answer);
1537 // SetRemoteDescription and SetLocalDescription will take the ownership of
1538 // the offer.
1539 SetRemoteDescriptionWithoutError(offer);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001540 SetLocalDescriptionAnswerExpectError(kSdpWithoutSdesCrypto, answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001541}
1542
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001543// Test we will return fail when apply an remote answer that doesn't have
1544// crypto enabled when DTLS is off.
1545TEST_F(WebRtcSessionTest, TestSetRemoteNonSdesAnswerWhenSdesOn) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001546 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001547 SessionDescriptionInterface* offer = NULL;
1548 SessionDescriptionInterface* answer = NULL;
1549 CreateCryptoOfferAndNonCryptoAnswer(&offer, &answer);
1550 // SetRemoteDescription and SetLocalDescription will take the ownership of
1551 // the offer.
1552 SetLocalDescriptionWithoutError(offer);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001553 SetRemoteDescriptionAnswerExpectError(kSdpWithoutSdesCrypto, answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001554}
1555
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001556// Test that we accept an offer with a DTLS fingerprint when DTLS is on
1557// and that we return an answer with a DTLS fingerprint.
1558TEST_F(WebRtcSessionTest, TestReceiveDtlsOfferCreateDtlsAnswer) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001559 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001560 mediastream_signaling_.SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001561 InitWithDtls();
1562 SetFactoryDtlsSrtp();
1563 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001564 options.recv_video = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001565 JsepSessionDescription* offer =
1566 CreateRemoteOffer(options, cricket::SEC_DISABLED);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001567 ASSERT_TRUE(offer != NULL);
1568 VerifyFingerprintStatus(offer->description(), true);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001569 VerifyNoCryptoParams(offer->description(), true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001570
1571 // SetRemoteDescription will take the ownership of the offer.
1572 SetRemoteDescriptionWithoutError(offer);
1573
1574 // Verify that we get a crypto fingerprint in the answer.
wu@webrtc.org91053e72013-08-10 07:18:04 +00001575 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001576 ASSERT_TRUE(answer != NULL);
1577 VerifyFingerprintStatus(answer->description(), true);
1578 // Check that we don't have an a=crypto line in the answer.
1579 VerifyNoCryptoParams(answer->description(), true);
1580
1581 // Now set the local description, which should work, even without a=crypto.
1582 SetLocalDescriptionWithoutError(answer);
1583}
1584
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001585// Test that we set a local offer with a DTLS fingerprint when DTLS is on
1586// and then we accept a remote answer with a DTLS fingerprint successfully.
1587TEST_F(WebRtcSessionTest, TestCreateDtlsOfferReceiveDtlsAnswer) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001588 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001589 mediastream_signaling_.SendAudioVideoStream1();
1590 InitWithDtls();
1591 SetFactoryDtlsSrtp();
1592
1593 // Verify that we get a crypto fingerprint in the answer.
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001594 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001595 ASSERT_TRUE(offer != NULL);
1596 VerifyFingerprintStatus(offer->description(), true);
1597 // Check that we don't have an a=crypto line in the offer.
1598 VerifyNoCryptoParams(offer->description(), true);
1599
1600 // Now set the local description, which should work, even without a=crypto.
1601 SetLocalDescriptionWithoutError(offer);
1602
1603 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001604 options.recv_video = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001605 JsepSessionDescription* answer =
1606 CreateRemoteAnswer(offer, options, cricket::SEC_DISABLED);
1607 ASSERT_TRUE(answer != NULL);
1608 VerifyFingerprintStatus(answer->description(), true);
1609 VerifyNoCryptoParams(answer->description(), true);
1610
1611 // SetRemoteDescription will take the ownership of the answer.
1612 SetRemoteDescriptionWithoutError(answer);
1613}
1614
1615// Test that if we support DTLS and the other side didn't offer a fingerprint,
1616// we will fail to set the remote description.
1617TEST_F(WebRtcSessionTest, TestReceiveNonDtlsOfferWhenDtlsOn) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001618 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001619 InitWithDtls();
1620 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001621 options.recv_video = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001622 options.bundle_enabled = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001623 JsepSessionDescription* offer = CreateRemoteOffer(
1624 options, cricket::SEC_REQUIRED);
1625 ASSERT_TRUE(offer != NULL);
1626 VerifyFingerprintStatus(offer->description(), false);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001627 VerifyCryptoParams(offer->description());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001628
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001629 // SetRemoteDescription will take the ownership of the offer.
1630 SetRemoteDescriptionOfferExpectError(
1631 kSdpWithoutDtlsFingerprint, offer);
1632
1633 offer = CreateRemoteOffer(options, cricket::SEC_REQUIRED);
1634 // SetLocalDescription will take the ownership of the offer.
1635 SetLocalDescriptionOfferExpectError(
1636 kSdpWithoutDtlsFingerprint, offer);
1637}
1638
1639// Test that we return a failure when applying a local answer that doesn't have
1640// a DTLS fingerprint when DTLS is required.
1641TEST_F(WebRtcSessionTest, TestSetLocalNonDtlsAnswerWhenDtlsOn) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001642 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001643 InitWithDtls();
1644 SessionDescriptionInterface* offer = NULL;
1645 SessionDescriptionInterface* answer = NULL;
1646 CreateDtlsOfferAndNonDtlsAnswer(&offer, &answer);
1647
1648 // SetRemoteDescription and SetLocalDescription will take the ownership of
1649 // the offer and answer.
1650 SetRemoteDescriptionWithoutError(offer);
1651 SetLocalDescriptionAnswerExpectError(
1652 kSdpWithoutDtlsFingerprint, answer);
1653}
1654
1655// Test that we return a failure when applying a remote answer that doesn't have
1656// a DTLS fingerprint when DTLS is required.
1657TEST_F(WebRtcSessionTest, TestSetRemoteNonDtlsAnswerWhenDtlsOn) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001658 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
deadbeeff3938292015-07-15 12:20:53 -07001659 // Enable both SDES and DTLS, so that offer won't be outright rejected as a
1660 // result of using the "UDP/TLS/RTP/SAVPF" profile.
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001661 InitWithDtls();
deadbeeff3938292015-07-15 12:20:53 -07001662 session_->SetSdesPolicy(cricket::SEC_ENABLED);
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001663 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001664 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001665 options.recv_video = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001666 JsepSessionDescription* answer =
1667 CreateRemoteAnswer(offer, options, cricket::SEC_ENABLED);
1668
1669 // SetRemoteDescription and SetLocalDescription will take the ownership of
1670 // the offer and answer.
1671 SetLocalDescriptionWithoutError(offer);
1672 SetRemoteDescriptionAnswerExpectError(
1673 kSdpWithoutDtlsFingerprint, answer);
1674}
1675
1676// Test that we create a local offer without SDES or DTLS and accept a remote
1677// answer without SDES or DTLS when encryption is disabled.
1678TEST_F(WebRtcSessionTest, TestCreateOfferReceiveAnswerWithoutEncryption) {
1679 mediastream_signaling_.SendAudioVideoStream1();
1680 options_.disable_encryption = true;
1681 InitWithDtls();
1682
1683 // Verify that we get a crypto fingerprint in the answer.
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001684 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001685 ASSERT_TRUE(offer != NULL);
1686 VerifyFingerprintStatus(offer->description(), false);
1687 // Check that we don't have an a=crypto line in the offer.
1688 VerifyNoCryptoParams(offer->description(), false);
1689
1690 // Now set the local description, which should work, even without a=crypto.
1691 SetLocalDescriptionWithoutError(offer);
1692
1693 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001694 options.recv_video = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001695 JsepSessionDescription* answer =
1696 CreateRemoteAnswer(offer, options, cricket::SEC_DISABLED);
1697 ASSERT_TRUE(answer != NULL);
1698 VerifyFingerprintStatus(answer->description(), false);
1699 VerifyNoCryptoParams(answer->description(), false);
1700
1701 // SetRemoteDescription will take the ownership of the answer.
1702 SetRemoteDescriptionWithoutError(answer);
1703}
1704
1705// Test that we create a local answer without SDES or DTLS and accept a remote
1706// offer without SDES or DTLS when encryption is disabled.
1707TEST_F(WebRtcSessionTest, TestCreateAnswerReceiveOfferWithoutEncryption) {
1708 options_.disable_encryption = true;
1709 InitWithDtls();
1710
1711 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001712 options.recv_video = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001713 JsepSessionDescription* offer =
1714 CreateRemoteOffer(options, cricket::SEC_DISABLED);
1715 ASSERT_TRUE(offer != NULL);
1716 VerifyFingerprintStatus(offer->description(), false);
1717 VerifyNoCryptoParams(offer->description(), false);
1718
1719 // SetRemoteDescription will take the ownership of the offer.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001720 SetRemoteDescriptionWithoutError(offer);
1721
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001722 // Verify that we get a crypto fingerprint in the answer.
wu@webrtc.org91053e72013-08-10 07:18:04 +00001723 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001724 ASSERT_TRUE(answer != NULL);
1725 VerifyFingerprintStatus(answer->description(), false);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001726 // Check that we don't have an a=crypto line in the answer.
1727 VerifyNoCryptoParams(answer->description(), false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001728
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001729 // Now set the local description, which should work, even without a=crypto.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001730 SetLocalDescriptionWithoutError(answer);
1731}
1732
1733TEST_F(WebRtcSessionTest, TestSetLocalOfferTwice) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001734 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001735 mediastream_signaling_.SendNothing();
1736 // SetLocalDescription take ownership of offer.
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001737 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001738 SetLocalDescriptionWithoutError(offer);
1739
1740 // SetLocalDescription take ownership of offer.
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001741 SessionDescriptionInterface* offer2 = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001742 SetLocalDescriptionWithoutError(offer2);
1743}
1744
1745TEST_F(WebRtcSessionTest, TestSetRemoteOfferTwice) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001746 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001747 mediastream_signaling_.SendNothing();
1748 // SetLocalDescription take ownership of offer.
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001749 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001750 SetRemoteDescriptionWithoutError(offer);
1751
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001752 SessionDescriptionInterface* offer2 = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001753 SetRemoteDescriptionWithoutError(offer2);
1754}
1755
1756TEST_F(WebRtcSessionTest, TestSetLocalAndRemoteOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001757 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001758 mediastream_signaling_.SendNothing();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001759 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001760 SetLocalDescriptionWithoutError(offer);
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001761 offer = CreateOffer();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001762 SetRemoteDescriptionOfferExpectError(
1763 "Called in wrong state: STATE_SENTINITIATE", offer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001764}
1765
1766TEST_F(WebRtcSessionTest, TestSetRemoteAndLocalOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001767 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001768 mediastream_signaling_.SendNothing();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001769 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001770 SetRemoteDescriptionWithoutError(offer);
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001771 offer = CreateOffer();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001772 SetLocalDescriptionOfferExpectError(
1773 "Called in wrong state: STATE_RECEIVEDINITIATE", offer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001774}
1775
1776TEST_F(WebRtcSessionTest, TestSetLocalPrAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001777 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001778 mediastream_signaling_.SendNothing();
1779 SessionDescriptionInterface* offer = CreateRemoteOffer();
1780 SetRemoteDescriptionExpectState(offer, BaseSession::STATE_RECEIVEDINITIATE);
1781
1782 JsepSessionDescription* pranswer = static_cast<JsepSessionDescription*>(
wu@webrtc.org91053e72013-08-10 07:18:04 +00001783 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001784 pranswer->set_type(SessionDescriptionInterface::kPrAnswer);
1785 SetLocalDescriptionExpectState(pranswer, BaseSession::STATE_SENTPRACCEPT);
1786
1787 mediastream_signaling_.SendAudioVideoStream1();
1788 JsepSessionDescription* pranswer2 = static_cast<JsepSessionDescription*>(
wu@webrtc.org91053e72013-08-10 07:18:04 +00001789 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001790 pranswer2->set_type(SessionDescriptionInterface::kPrAnswer);
1791
1792 SetLocalDescriptionExpectState(pranswer2, BaseSession::STATE_SENTPRACCEPT);
1793
1794 mediastream_signaling_.SendAudioVideoStream2();
wu@webrtc.org91053e72013-08-10 07:18:04 +00001795 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001796 SetLocalDescriptionExpectState(answer, BaseSession::STATE_SENTACCEPT);
1797}
1798
1799TEST_F(WebRtcSessionTest, TestSetRemotePrAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001800 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001801 mediastream_signaling_.SendNothing();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001802 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001803 SetLocalDescriptionExpectState(offer, BaseSession::STATE_SENTINITIATE);
1804
1805 JsepSessionDescription* pranswer =
1806 CreateRemoteAnswer(session_->local_description());
1807 pranswer->set_type(SessionDescriptionInterface::kPrAnswer);
1808
1809 SetRemoteDescriptionExpectState(pranswer,
1810 BaseSession::STATE_RECEIVEDPRACCEPT);
1811
1812 mediastream_signaling_.SendAudioVideoStream1();
1813 JsepSessionDescription* pranswer2 =
1814 CreateRemoteAnswer(session_->local_description());
1815 pranswer2->set_type(SessionDescriptionInterface::kPrAnswer);
1816
1817 SetRemoteDescriptionExpectState(pranswer2,
1818 BaseSession::STATE_RECEIVEDPRACCEPT);
1819
1820 mediastream_signaling_.SendAudioVideoStream2();
1821 SessionDescriptionInterface* answer =
1822 CreateRemoteAnswer(session_->local_description());
1823 SetRemoteDescriptionExpectState(answer, BaseSession::STATE_RECEIVEDACCEPT);
1824}
1825
1826TEST_F(WebRtcSessionTest, TestSetLocalAnswerWithoutOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001827 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001828 mediastream_signaling_.SendNothing();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001829 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
1830
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001831 SessionDescriptionInterface* answer =
1832 CreateRemoteAnswer(offer.get());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001833 SetLocalDescriptionAnswerExpectError("Called in wrong state: STATE_INIT",
1834 answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001835}
1836
1837TEST_F(WebRtcSessionTest, TestSetRemoteAnswerWithoutOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001838 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001839 mediastream_signaling_.SendNothing();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001840 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
1841
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001842 SessionDescriptionInterface* answer =
1843 CreateRemoteAnswer(offer.get());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001844 SetRemoteDescriptionAnswerExpectError(
1845 "Called in wrong state: STATE_INIT", answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001846}
1847
1848TEST_F(WebRtcSessionTest, TestAddRemoteCandidate) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001849 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001850 mediastream_signaling_.SendAudioVideoStream1();
1851
1852 cricket::Candidate candidate;
1853 candidate.set_component(1);
1854 JsepIceCandidate ice_candidate1(kMediaContentName0, 0, candidate);
1855
1856 // Fail since we have not set a offer description.
1857 EXPECT_FALSE(session_->ProcessIceMessage(&ice_candidate1));
1858
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001859 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001860 SetLocalDescriptionWithoutError(offer);
1861 // Candidate should be allowed to add before remote description.
1862 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate1));
1863 candidate.set_component(2);
1864 JsepIceCandidate ice_candidate2(kMediaContentName0, 0, candidate);
1865 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate2));
1866
1867 SessionDescriptionInterface* answer = CreateRemoteAnswer(
1868 session_->local_description());
1869 SetRemoteDescriptionWithoutError(answer);
1870
1871 // Verifying the candidates are copied properly from internal vector.
1872 const SessionDescriptionInterface* remote_desc =
1873 session_->remote_description();
1874 ASSERT_TRUE(remote_desc != NULL);
1875 ASSERT_EQ(2u, remote_desc->number_of_mediasections());
1876 const IceCandidateCollection* candidates =
1877 remote_desc->candidates(kMediaContentIndex0);
1878 ASSERT_EQ(2u, candidates->count());
1879 EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
1880 EXPECT_EQ(kMediaContentName0, candidates->at(0)->sdp_mid());
1881 EXPECT_EQ(1, candidates->at(0)->candidate().component());
1882 EXPECT_EQ(2, candidates->at(1)->candidate().component());
1883
mallinath@webrtc.org67ee6b92014-02-03 16:57:16 +00001884 // |ice_candidate3| is identical to |ice_candidate2|. It can be added
1885 // successfully, but the total count of candidates will not increase.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001886 candidate.set_component(2);
1887 JsepIceCandidate ice_candidate3(kMediaContentName0, 0, candidate);
1888 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate3));
mallinath@webrtc.org67ee6b92014-02-03 16:57:16 +00001889 ASSERT_EQ(2u, candidates->count());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001890
1891 JsepIceCandidate bad_ice_candidate("bad content name", 99, candidate);
1892 EXPECT_FALSE(session_->ProcessIceMessage(&bad_ice_candidate));
1893}
1894
1895// Test that a remote candidate is added to the remote session description and
1896// that it is retained if the remote session description is changed.
1897TEST_F(WebRtcSessionTest, TestRemoteCandidatesAddedToSessionDescription) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001898 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001899 cricket::Candidate candidate1;
1900 candidate1.set_component(1);
1901 JsepIceCandidate ice_candidate1(kMediaContentName0, kMediaContentIndex0,
1902 candidate1);
1903 mediastream_signaling_.SendAudioVideoStream1();
1904 CreateAndSetRemoteOfferAndLocalAnswer();
1905
1906 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate1));
1907 const SessionDescriptionInterface* remote_desc =
1908 session_->remote_description();
1909 ASSERT_TRUE(remote_desc != NULL);
1910 ASSERT_EQ(2u, remote_desc->number_of_mediasections());
1911 const IceCandidateCollection* candidates =
1912 remote_desc->candidates(kMediaContentIndex0);
1913 ASSERT_EQ(1u, candidates->count());
1914 EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
1915
1916 // Update the RemoteSessionDescription with a new session description and
1917 // a candidate and check that the new remote session description contains both
1918 // candidates.
1919 SessionDescriptionInterface* offer = CreateRemoteOffer();
1920 cricket::Candidate candidate2;
1921 JsepIceCandidate ice_candidate2(kMediaContentName0, kMediaContentIndex0,
1922 candidate2);
1923 EXPECT_TRUE(offer->AddCandidate(&ice_candidate2));
1924 SetRemoteDescriptionWithoutError(offer);
1925
1926 remote_desc = session_->remote_description();
1927 ASSERT_TRUE(remote_desc != NULL);
1928 ASSERT_EQ(2u, remote_desc->number_of_mediasections());
1929 candidates = remote_desc->candidates(kMediaContentIndex0);
1930 ASSERT_EQ(2u, candidates->count());
1931 EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
1932 // Username and password have be updated with the TransportInfo of the
1933 // SessionDescription, won't be equal to the original one.
1934 candidate2.set_username(candidates->at(0)->candidate().username());
1935 candidate2.set_password(candidates->at(0)->candidate().password());
1936 EXPECT_TRUE(candidate2.IsEquivalent(candidates->at(0)->candidate()));
1937 EXPECT_EQ(kMediaContentIndex0, candidates->at(1)->sdp_mline_index());
1938 // No need to verify the username and password.
1939 candidate1.set_username(candidates->at(1)->candidate().username());
1940 candidate1.set_password(candidates->at(1)->candidate().password());
1941 EXPECT_TRUE(candidate1.IsEquivalent(candidates->at(1)->candidate()));
1942
1943 // Test that the candidate is ignored if we can add the same candidate again.
1944 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate2));
1945}
1946
1947// Test that local candidates are added to the local session description and
1948// that they are retained if the local session description is changed.
1949TEST_F(WebRtcSessionTest, TestLocalCandidatesAddedToSessionDescription) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001950 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001951 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001952 mediastream_signaling_.SendAudioVideoStream1();
1953 CreateAndSetRemoteOfferAndLocalAnswer();
1954
1955 const SessionDescriptionInterface* local_desc = session_->local_description();
1956 const IceCandidateCollection* candidates =
1957 local_desc->candidates(kMediaContentIndex0);
1958 ASSERT_TRUE(candidates != NULL);
1959 EXPECT_EQ(0u, candidates->count());
1960
1961 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1962
1963 local_desc = session_->local_description();
1964 candidates = local_desc->candidates(kMediaContentIndex0);
1965 ASSERT_TRUE(candidates != NULL);
1966 EXPECT_LT(0u, candidates->count());
1967 candidates = local_desc->candidates(1);
1968 ASSERT_TRUE(candidates != NULL);
1969 EXPECT_LT(0u, candidates->count());
1970
1971 // Update the session descriptions.
1972 mediastream_signaling_.SendAudioVideoStream1();
1973 CreateAndSetRemoteOfferAndLocalAnswer();
1974
1975 local_desc = session_->local_description();
1976 candidates = local_desc->candidates(kMediaContentIndex0);
1977 ASSERT_TRUE(candidates != NULL);
1978 EXPECT_LT(0u, candidates->count());
1979 candidates = local_desc->candidates(1);
1980 ASSERT_TRUE(candidates != NULL);
1981 EXPECT_LT(0u, candidates->count());
1982}
1983
1984// Test that we can set a remote session description with remote candidates.
1985TEST_F(WebRtcSessionTest, TestSetRemoteSessionDescriptionWithCandidates) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001986 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001987
1988 cricket::Candidate candidate1;
1989 candidate1.set_component(1);
1990 JsepIceCandidate ice_candidate(kMediaContentName0, kMediaContentIndex0,
1991 candidate1);
1992 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001993 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001994
1995 EXPECT_TRUE(offer->AddCandidate(&ice_candidate));
1996 SetRemoteDescriptionWithoutError(offer);
1997
1998 const SessionDescriptionInterface* remote_desc =
1999 session_->remote_description();
2000 ASSERT_TRUE(remote_desc != NULL);
2001 ASSERT_EQ(2u, remote_desc->number_of_mediasections());
2002 const IceCandidateCollection* candidates =
2003 remote_desc->candidates(kMediaContentIndex0);
2004 ASSERT_EQ(1u, candidates->count());
2005 EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
2006
wu@webrtc.org91053e72013-08-10 07:18:04 +00002007 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002008 SetLocalDescriptionWithoutError(answer);
2009}
2010
2011// Test that offers and answers contains ice candidates when Ice candidates have
2012// been gathered.
2013TEST_F(WebRtcSessionTest, TestSetLocalAndRemoteDescriptionWithCandidates) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002014 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002015 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002016 mediastream_signaling_.SendAudioVideoStream1();
2017 // Ice is started but candidates are not provided until SetLocalDescription
2018 // is called.
2019 EXPECT_EQ(0u, observer_.mline_0_candidates_.size());
2020 EXPECT_EQ(0u, observer_.mline_1_candidates_.size());
2021 CreateAndSetRemoteOfferAndLocalAnswer();
2022 // Wait until at least one local candidate has been collected.
2023 EXPECT_TRUE_WAIT(0u < observer_.mline_0_candidates_.size(),
2024 kIceCandidatesTimeout);
2025 EXPECT_TRUE_WAIT(0u < observer_.mline_1_candidates_.size(),
2026 kIceCandidatesTimeout);
2027
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002028 rtc::scoped_ptr<SessionDescriptionInterface> local_offer(CreateOffer());
2029
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002030 ASSERT_TRUE(local_offer->candidates(kMediaContentIndex0) != NULL);
2031 EXPECT_LT(0u, local_offer->candidates(kMediaContentIndex0)->count());
2032 ASSERT_TRUE(local_offer->candidates(kMediaContentIndex1) != NULL);
2033 EXPECT_LT(0u, local_offer->candidates(kMediaContentIndex1)->count());
2034
2035 SessionDescriptionInterface* remote_offer(CreateRemoteOffer());
2036 SetRemoteDescriptionWithoutError(remote_offer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00002037 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002038 ASSERT_TRUE(answer->candidates(kMediaContentIndex0) != NULL);
2039 EXPECT_LT(0u, answer->candidates(kMediaContentIndex0)->count());
2040 ASSERT_TRUE(answer->candidates(kMediaContentIndex1) != NULL);
2041 EXPECT_LT(0u, answer->candidates(kMediaContentIndex1)->count());
2042 SetLocalDescriptionWithoutError(answer);
2043}
2044
2045// Verifies TransportProxy and media channels are created with content names
2046// present in the SessionDescription.
2047TEST_F(WebRtcSessionTest, TestChannelCreationsWithContentNames) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002048 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002049 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002050 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002051
2052 // CreateOffer creates session description with the content names "audio" and
2053 // "video". Goal is to modify these content names and verify transport channel
2054 // proxy in the BaseSession, as proxies are created with the content names
2055 // present in SDP.
2056 std::string sdp;
2057 EXPECT_TRUE(offer->ToString(&sdp));
2058 const std::string kAudioMid = "a=mid:audio";
2059 const std::string kAudioMidReplaceStr = "a=mid:audio_content_name";
2060 const std::string kVideoMid = "a=mid:video";
2061 const std::string kVideoMidReplaceStr = "a=mid:video_content_name";
2062
2063 // Replacing |audio| with |audio_content_name|.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002064 rtc::replace_substrs(kAudioMid.c_str(), kAudioMid.length(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002065 kAudioMidReplaceStr.c_str(),
2066 kAudioMidReplaceStr.length(),
2067 &sdp);
2068 // Replacing |video| with |video_content_name|.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002069 rtc::replace_substrs(kVideoMid.c_str(), kVideoMid.length(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002070 kVideoMidReplaceStr.c_str(),
2071 kVideoMidReplaceStr.length(),
2072 &sdp);
2073
2074 SessionDescriptionInterface* modified_offer =
2075 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
2076
2077 SetRemoteDescriptionWithoutError(modified_offer);
2078
2079 SessionDescriptionInterface* answer =
wu@webrtc.org91053e72013-08-10 07:18:04 +00002080 CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002081 SetLocalDescriptionWithoutError(answer);
2082
2083 EXPECT_TRUE(session_->GetTransportProxy("audio_content_name") != NULL);
2084 EXPECT_TRUE(session_->GetTransportProxy("video_content_name") != NULL);
2085 EXPECT_TRUE((video_channel_ = media_engine_->GetVideoChannel(0)) != NULL);
2086 EXPECT_TRUE((voice_channel_ = media_engine_->GetVoiceChannel(0)) != NULL);
2087}
2088
2089// Test that an offer contains the correct media content descriptions based on
2090// the send streams when no constraints have been set.
2091TEST_F(WebRtcSessionTest, CreateOfferWithoutConstraintsOrStreams) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002092 Init();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002093 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
2094
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002095 ASSERT_TRUE(offer != NULL);
2096 const cricket::ContentInfo* content =
2097 cricket::GetFirstAudioContent(offer->description());
2098 EXPECT_TRUE(content != NULL);
2099 content = cricket::GetFirstVideoContent(offer->description());
2100 EXPECT_TRUE(content == NULL);
2101}
2102
2103// Test that an offer contains the correct media content descriptions based on
2104// the send streams when no constraints have been set.
2105TEST_F(WebRtcSessionTest, CreateOfferWithoutConstraints) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002106 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002107 // Test Audio only offer.
2108 mediastream_signaling_.UseOptionsAudioOnly();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002109 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
2110
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002111 const cricket::ContentInfo* content =
2112 cricket::GetFirstAudioContent(offer->description());
2113 EXPECT_TRUE(content != NULL);
2114 content = cricket::GetFirstVideoContent(offer->description());
2115 EXPECT_TRUE(content == NULL);
2116
2117 // Test Audio / Video offer.
2118 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002119 offer.reset(CreateOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002120 content = cricket::GetFirstAudioContent(offer->description());
2121 EXPECT_TRUE(content != NULL);
2122 content = cricket::GetFirstVideoContent(offer->description());
2123 EXPECT_TRUE(content != NULL);
2124}
2125
2126// Test that an offer contains no media content descriptions if
2127// kOfferToReceiveVideo and kOfferToReceiveAudio constraints are set to false.
2128TEST_F(WebRtcSessionTest, CreateOfferWithConstraintsWithoutStreams) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002129 Init();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002130 PeerConnectionInterface::RTCOfferAnswerOptions options;
2131 options.offer_to_receive_audio = 0;
2132 options.offer_to_receive_video = 0;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002133
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002134 rtc::scoped_ptr<SessionDescriptionInterface> offer(
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002135 CreateOffer(options));
2136
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002137 ASSERT_TRUE(offer != NULL);
2138 const cricket::ContentInfo* content =
2139 cricket::GetFirstAudioContent(offer->description());
2140 EXPECT_TRUE(content == NULL);
2141 content = cricket::GetFirstVideoContent(offer->description());
2142 EXPECT_TRUE(content == NULL);
2143}
2144
2145// Test that an offer contains only audio media content descriptions if
2146// kOfferToReceiveAudio constraints are set to true.
2147TEST_F(WebRtcSessionTest, CreateAudioOnlyOfferWithConstraints) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002148 Init();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002149 PeerConnectionInterface::RTCOfferAnswerOptions options;
2150 options.offer_to_receive_audio =
2151 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
2152
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002153 rtc::scoped_ptr<SessionDescriptionInterface> offer(
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002154 CreateOffer(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002155
2156 const cricket::ContentInfo* content =
2157 cricket::GetFirstAudioContent(offer->description());
2158 EXPECT_TRUE(content != NULL);
2159 content = cricket::GetFirstVideoContent(offer->description());
2160 EXPECT_TRUE(content == NULL);
2161}
2162
2163// Test that an offer contains audio and video media content descriptions if
2164// kOfferToReceiveAudio and kOfferToReceiveVideo constraints are set to true.
2165TEST_F(WebRtcSessionTest, CreateOfferWithConstraints) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002166 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002167 // Test Audio / Video offer.
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002168 PeerConnectionInterface::RTCOfferAnswerOptions options;
2169 options.offer_to_receive_audio =
2170 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
2171 options.offer_to_receive_video =
2172 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
2173
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002174 rtc::scoped_ptr<SessionDescriptionInterface> offer(
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002175 CreateOffer(options));
2176
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002177 const cricket::ContentInfo* content =
2178 cricket::GetFirstAudioContent(offer->description());
jiayl@webrtc.orgc1723202014-09-08 20:44:36 +00002179 EXPECT_TRUE(content != NULL);
jiayl@webrtc.org7d4891d2014-09-09 21:43:15 +00002180
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002181 content = cricket::GetFirstVideoContent(offer->description());
2182 EXPECT_TRUE(content != NULL);
2183
jiayl@webrtc.org7d4891d2014-09-09 21:43:15 +00002184 // Sets constraints to false and verifies that audio/video contents are
2185 // removed.
2186 options.offer_to_receive_audio = 0;
2187 options.offer_to_receive_video = 0;
2188 offer.reset(CreateOffer(options));
2189
2190 content = cricket::GetFirstAudioContent(offer->description());
2191 EXPECT_TRUE(content == NULL);
2192 content = cricket::GetFirstVideoContent(offer->description());
2193 EXPECT_TRUE(content == NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002194}
2195
2196// Test that an answer can not be created if the last remote description is not
2197// an offer.
2198TEST_F(WebRtcSessionTest, CreateAnswerWithoutAnOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002199 Init();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002200 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002201 SetLocalDescriptionWithoutError(offer);
2202 SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
2203 SetRemoteDescriptionWithoutError(answer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00002204 EXPECT_TRUE(CreateAnswer(NULL) == NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002205}
2206
2207// Test that an answer contains the correct media content descriptions when no
2208// constraints have been set.
2209TEST_F(WebRtcSessionTest, CreateAnswerWithoutConstraintsOrStreams) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002210 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002211 // Create a remote offer with audio and video content.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002212 rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002213 SetRemoteDescriptionWithoutError(offer.release());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002214 rtc::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002215 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002216 const cricket::ContentInfo* content =
2217 cricket::GetFirstAudioContent(answer->description());
2218 ASSERT_TRUE(content != NULL);
2219 EXPECT_FALSE(content->rejected);
2220
2221 content = cricket::GetFirstVideoContent(answer->description());
2222 ASSERT_TRUE(content != NULL);
2223 EXPECT_FALSE(content->rejected);
2224}
2225
2226// Test that an answer contains the correct media content descriptions when no
2227// constraints have been set and the offer only contain audio.
2228TEST_F(WebRtcSessionTest, CreateAudioAnswerWithoutConstraintsOrStreams) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002229 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002230 // Create a remote offer with audio only.
2231 cricket::MediaSessionOptions options;
jiayl@webrtc.org7d4891d2014-09-09 21:43:15 +00002232
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002233 rtc::scoped_ptr<JsepSessionDescription> offer(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002234 CreateRemoteOffer(options));
2235 ASSERT_TRUE(cricket::GetFirstVideoContent(offer->description()) == NULL);
2236 ASSERT_TRUE(cricket::GetFirstAudioContent(offer->description()) != NULL);
2237
2238 SetRemoteDescriptionWithoutError(offer.release());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002239 rtc::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002240 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002241 const cricket::ContentInfo* content =
2242 cricket::GetFirstAudioContent(answer->description());
2243 ASSERT_TRUE(content != NULL);
2244 EXPECT_FALSE(content->rejected);
2245
2246 EXPECT_TRUE(cricket::GetFirstVideoContent(answer->description()) == NULL);
2247}
2248
2249// Test that an answer contains the correct media content descriptions when no
2250// constraints have been set.
2251TEST_F(WebRtcSessionTest, CreateAnswerWithoutConstraints) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002252 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002253 // Create a remote offer with audio and video content.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002254 rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002255 SetRemoteDescriptionWithoutError(offer.release());
2256 // Test with a stream with tracks.
2257 mediastream_signaling_.SendAudioVideoStream1();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002258 rtc::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002259 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002260 const cricket::ContentInfo* content =
2261 cricket::GetFirstAudioContent(answer->description());
2262 ASSERT_TRUE(content != NULL);
2263 EXPECT_FALSE(content->rejected);
2264
2265 content = cricket::GetFirstVideoContent(answer->description());
2266 ASSERT_TRUE(content != NULL);
2267 EXPECT_FALSE(content->rejected);
2268}
2269
2270// Test that an answer contains the correct media content descriptions when
2271// constraints have been set but no stream is sent.
2272TEST_F(WebRtcSessionTest, CreateAnswerWithConstraintsWithoutStreams) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002273 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002274 // Create a remote offer with audio and video content.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002275 rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002276 SetRemoteDescriptionWithoutError(offer.release());
2277
2278 webrtc::FakeConstraints constraints_no_receive;
2279 constraints_no_receive.SetMandatoryReceiveAudio(false);
2280 constraints_no_receive.SetMandatoryReceiveVideo(false);
2281
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002282 rtc::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002283 CreateAnswer(&constraints_no_receive));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002284 const cricket::ContentInfo* content =
2285 cricket::GetFirstAudioContent(answer->description());
2286 ASSERT_TRUE(content != NULL);
2287 EXPECT_TRUE(content->rejected);
2288
2289 content = cricket::GetFirstVideoContent(answer->description());
2290 ASSERT_TRUE(content != NULL);
2291 EXPECT_TRUE(content->rejected);
2292}
2293
2294// Test that an answer contains the correct media content descriptions when
2295// constraints have been set and streams are sent.
2296TEST_F(WebRtcSessionTest, CreateAnswerWithConstraints) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002297 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002298 // Create a remote offer with audio and video content.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002299 rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002300 SetRemoteDescriptionWithoutError(offer.release());
2301
2302 webrtc::FakeConstraints constraints_no_receive;
2303 constraints_no_receive.SetMandatoryReceiveAudio(false);
2304 constraints_no_receive.SetMandatoryReceiveVideo(false);
2305
2306 // Test with a stream with tracks.
2307 mediastream_signaling_.SendAudioVideoStream1();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002308 rtc::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002309 CreateAnswer(&constraints_no_receive));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002310
2311 // TODO(perkj): Should the direction be set to SEND_ONLY?
2312 const cricket::ContentInfo* content =
2313 cricket::GetFirstAudioContent(answer->description());
2314 ASSERT_TRUE(content != NULL);
2315 EXPECT_FALSE(content->rejected);
2316
2317 // TODO(perkj): Should the direction be set to SEND_ONLY?
2318 content = cricket::GetFirstVideoContent(answer->description());
2319 ASSERT_TRUE(content != NULL);
2320 EXPECT_FALSE(content->rejected);
2321}
2322
2323TEST_F(WebRtcSessionTest, CreateOfferWithoutCNCodecs) {
2324 AddCNCodecs();
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002325 Init();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002326 PeerConnectionInterface::RTCOfferAnswerOptions options;
2327 options.offer_to_receive_audio =
2328 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
2329 options.voice_activity_detection = false;
2330
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002331 rtc::scoped_ptr<SessionDescriptionInterface> offer(
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002332 CreateOffer(options));
2333
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002334 const cricket::ContentInfo* content =
2335 cricket::GetFirstAudioContent(offer->description());
2336 EXPECT_TRUE(content != NULL);
2337 EXPECT_TRUE(VerifyNoCNCodecs(content));
2338}
2339
2340TEST_F(WebRtcSessionTest, CreateAnswerWithoutCNCodecs) {
2341 AddCNCodecs();
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002342 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002343 // Create a remote offer with audio and video content.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002344 rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002345 SetRemoteDescriptionWithoutError(offer.release());
2346
2347 webrtc::FakeConstraints constraints;
2348 constraints.SetOptionalVAD(false);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002349 rtc::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002350 CreateAnswer(&constraints));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002351 const cricket::ContentInfo* content =
2352 cricket::GetFirstAudioContent(answer->description());
2353 ASSERT_TRUE(content != NULL);
2354 EXPECT_TRUE(VerifyNoCNCodecs(content));
2355}
2356
2357// This test verifies the call setup when remote answer with audio only and
2358// later updates with video.
2359TEST_F(WebRtcSessionTest, TestAVOfferWithAudioOnlyAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002360 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002361 EXPECT_TRUE(media_engine_->GetVideoChannel(0) == NULL);
2362 EXPECT_TRUE(media_engine_->GetVoiceChannel(0) == NULL);
2363
2364 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002365 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002366
2367 cricket::MediaSessionOptions options;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002368 SessionDescriptionInterface* answer = CreateRemoteAnswer(offer, options);
2369
2370 // SetLocalDescription and SetRemoteDescriptions takes ownership of offer
2371 // and answer;
2372 SetLocalDescriptionWithoutError(offer);
2373 SetRemoteDescriptionWithoutError(answer);
2374
2375 video_channel_ = media_engine_->GetVideoChannel(0);
2376 voice_channel_ = media_engine_->GetVoiceChannel(0);
2377
2378 ASSERT_TRUE(video_channel_ == NULL);
2379
2380 ASSERT_EQ(0u, voice_channel_->recv_streams().size());
2381 ASSERT_EQ(1u, voice_channel_->send_streams().size());
2382 EXPECT_EQ(kAudioTrack1, voice_channel_->send_streams()[0].id);
2383
2384 // Let the remote end update the session descriptions, with Audio and Video.
2385 mediastream_signaling_.SendAudioVideoStream2();
2386 CreateAndSetRemoteOfferAndLocalAnswer();
2387
2388 video_channel_ = media_engine_->GetVideoChannel(0);
2389 voice_channel_ = media_engine_->GetVoiceChannel(0);
2390
2391 ASSERT_TRUE(video_channel_ != NULL);
2392 ASSERT_TRUE(voice_channel_ != NULL);
2393
2394 ASSERT_EQ(1u, video_channel_->recv_streams().size());
2395 ASSERT_EQ(1u, video_channel_->send_streams().size());
2396 EXPECT_EQ(kVideoTrack2, video_channel_->recv_streams()[0].id);
2397 EXPECT_EQ(kVideoTrack2, video_channel_->send_streams()[0].id);
2398 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
2399 ASSERT_EQ(1u, voice_channel_->send_streams().size());
2400 EXPECT_EQ(kAudioTrack2, voice_channel_->recv_streams()[0].id);
2401 EXPECT_EQ(kAudioTrack2, voice_channel_->send_streams()[0].id);
2402
2403 // Change session back to audio only.
2404 mediastream_signaling_.UseOptionsAudioOnly();
2405 CreateAndSetRemoteOfferAndLocalAnswer();
2406
2407 EXPECT_EQ(0u, video_channel_->recv_streams().size());
2408 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
2409 EXPECT_EQ(kAudioTrack2, voice_channel_->recv_streams()[0].id);
2410 ASSERT_EQ(1u, voice_channel_->send_streams().size());
2411 EXPECT_EQ(kAudioTrack2, voice_channel_->send_streams()[0].id);
2412}
2413
2414// This test verifies the call setup when remote answer with video only and
2415// later updates with audio.
2416TEST_F(WebRtcSessionTest, TestAVOfferWithVideoOnlyAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002417 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002418 EXPECT_TRUE(media_engine_->GetVideoChannel(0) == NULL);
2419 EXPECT_TRUE(media_engine_->GetVoiceChannel(0) == NULL);
2420 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002421 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002422
2423 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00002424 options.recv_audio = false;
2425 options.recv_video = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002426 SessionDescriptionInterface* answer = CreateRemoteAnswer(
2427 offer, options, cricket::SEC_ENABLED);
2428
2429 // SetLocalDescription and SetRemoteDescriptions takes ownership of offer
2430 // and answer.
2431 SetLocalDescriptionWithoutError(offer);
2432 SetRemoteDescriptionWithoutError(answer);
2433
2434 video_channel_ = media_engine_->GetVideoChannel(0);
2435 voice_channel_ = media_engine_->GetVoiceChannel(0);
2436
2437 ASSERT_TRUE(voice_channel_ == NULL);
2438 ASSERT_TRUE(video_channel_ != NULL);
2439
2440 EXPECT_EQ(0u, video_channel_->recv_streams().size());
2441 ASSERT_EQ(1u, video_channel_->send_streams().size());
2442 EXPECT_EQ(kVideoTrack1, video_channel_->send_streams()[0].id);
2443
2444 // Update the session descriptions, with Audio and Video.
2445 mediastream_signaling_.SendAudioVideoStream2();
2446 CreateAndSetRemoteOfferAndLocalAnswer();
2447
2448 voice_channel_ = media_engine_->GetVoiceChannel(0);
2449 ASSERT_TRUE(voice_channel_ != NULL);
2450
2451 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
2452 ASSERT_EQ(1u, voice_channel_->send_streams().size());
2453 EXPECT_EQ(kAudioTrack2, voice_channel_->recv_streams()[0].id);
2454 EXPECT_EQ(kAudioTrack2, voice_channel_->send_streams()[0].id);
2455
2456 // Change session back to video only.
2457 mediastream_signaling_.UseOptionsVideoOnly();
2458 CreateAndSetRemoteOfferAndLocalAnswer();
2459
2460 video_channel_ = media_engine_->GetVideoChannel(0);
2461 voice_channel_ = media_engine_->GetVoiceChannel(0);
2462
2463 ASSERT_EQ(1u, video_channel_->recv_streams().size());
2464 EXPECT_EQ(kVideoTrack2, video_channel_->recv_streams()[0].id);
2465 ASSERT_EQ(1u, video_channel_->send_streams().size());
2466 EXPECT_EQ(kVideoTrack2, video_channel_->send_streams()[0].id);
2467}
2468
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002469TEST_F(WebRtcSessionTest, VerifyCryptoParamsInSDP) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002470 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002471 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002472 scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002473 VerifyCryptoParams(offer->description());
2474 SetRemoteDescriptionWithoutError(offer.release());
wu@webrtc.org91053e72013-08-10 07:18:04 +00002475 scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002476 VerifyCryptoParams(answer->description());
2477}
2478
2479TEST_F(WebRtcSessionTest, VerifyNoCryptoParamsInSDP) {
wu@webrtc.org97077a32013-10-25 21:18:33 +00002480 options_.disable_encryption = true;
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002481 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002482 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002483 scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002484 VerifyNoCryptoParams(offer->description(), false);
2485}
2486
2487TEST_F(WebRtcSessionTest, VerifyAnswerFromNonCryptoOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002488 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002489 VerifyAnswerFromNonCryptoOffer();
2490}
2491
2492TEST_F(WebRtcSessionTest, VerifyAnswerFromCryptoOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002493 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002494 VerifyAnswerFromCryptoOffer();
2495}
2496
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002497// This test verifies that setLocalDescription fails if
2498// no a=ice-ufrag and a=ice-pwd lines are present in the SDP.
2499TEST_F(WebRtcSessionTest, TestSetLocalDescriptionWithoutIce) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002500 Init();
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002501 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002502 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
2503
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002504 std::string sdp;
2505 RemoveIceUfragPwdLines(offer.get(), &sdp);
2506 SessionDescriptionInterface* modified_offer =
2507 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00002508 SetLocalDescriptionOfferExpectError(kSdpWithoutIceUfragPwd, modified_offer);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002509}
2510
2511// This test verifies that setRemoteDescription fails if
2512// no a=ice-ufrag and a=ice-pwd lines are present in the SDP.
2513TEST_F(WebRtcSessionTest, TestSetRemoteDescriptionWithoutIce) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002514 Init();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002515 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateRemoteOffer());
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002516 std::string sdp;
2517 RemoveIceUfragPwdLines(offer.get(), &sdp);
2518 SessionDescriptionInterface* modified_offer =
2519 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00002520 SetRemoteDescriptionOfferExpectError(kSdpWithoutIceUfragPwd, modified_offer);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002521}
2522
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +00002523// This test verifies that setLocalDescription fails if local offer has
2524// too short ice ufrag and pwd strings.
2525TEST_F(WebRtcSessionTest, TestSetLocalDescriptionInvalidIceCredentials) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002526 Init();
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +00002527 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002528 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
2529
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +00002530 std::string sdp;
2531 // Modifying ice ufrag and pwd in local offer with strings smaller than the
2532 // recommended values of 4 and 22 bytes respectively.
2533 ModifyIceUfragPwdLines(offer.get(), "ice", "icepwd", &sdp);
2534 SessionDescriptionInterface* modified_offer =
2535 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
2536 std::string error;
2537 EXPECT_FALSE(session_->SetLocalDescription(modified_offer, &error));
2538
2539 // Test with string greater than 256.
2540 sdp.clear();
2541 ModifyIceUfragPwdLines(offer.get(), kTooLongIceUfragPwd, kTooLongIceUfragPwd,
2542 &sdp);
2543 modified_offer = CreateSessionDescription(JsepSessionDescription::kOffer, sdp,
2544 NULL);
2545 EXPECT_FALSE(session_->SetLocalDescription(modified_offer, &error));
2546}
2547
2548// This test verifies that setRemoteDescription fails if remote offer has
2549// too short ice ufrag and pwd strings.
2550TEST_F(WebRtcSessionTest, TestSetRemoteDescriptionInvalidIceCredentials) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002551 Init();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002552 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateRemoteOffer());
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +00002553 std::string sdp;
2554 // Modifying ice ufrag and pwd in remote offer with strings smaller than the
2555 // recommended values of 4 and 22 bytes respectively.
2556 ModifyIceUfragPwdLines(offer.get(), "ice", "icepwd", &sdp);
2557 SessionDescriptionInterface* modified_offer =
2558 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
2559 std::string error;
2560 EXPECT_FALSE(session_->SetRemoteDescription(modified_offer, &error));
2561
2562 sdp.clear();
2563 ModifyIceUfragPwdLines(offer.get(), kTooLongIceUfragPwd, kTooLongIceUfragPwd,
2564 &sdp);
2565 modified_offer = CreateSessionDescription(JsepSessionDescription::kOffer, sdp,
2566 NULL);
2567 EXPECT_FALSE(session_->SetRemoteDescription(modified_offer, &error));
2568}
2569
honghaiz503726c2015-07-31 12:37:38 -07002570// Test that if the remote description indicates the peer requested ICE restart
2571// (via a new ufrag or pwd), the old ICE candidates are not copied,
2572// and vice versa.
2573TEST_F(WebRtcSessionTest, TestSetRemoteDescriptionWithIceRestart) {
2574 Init();
2575 scoped_ptr<SessionDescriptionInterface> offer(CreateRemoteOffer());
2576
2577 // Create the first offer.
2578 std::string sdp;
2579 ModifyIceUfragPwdLines(offer.get(), "0123456789012345",
2580 "abcdefghijklmnopqrstuvwx", &sdp);
2581 SessionDescriptionInterface* offer1 =
2582 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
2583 cricket::Candidate candidate1(1, "udp", rtc::SocketAddress("1.1.1.1", 5000),
2584 0, "", "", "relay", 0, "");
2585 JsepIceCandidate ice_candidate1(kMediaContentName0, kMediaContentIndex0,
2586 candidate1);
2587 EXPECT_TRUE(offer1->AddCandidate(&ice_candidate1));
2588 SetRemoteDescriptionWithoutError(offer1);
2589 EXPECT_EQ(1, session_->remote_description()->candidates(0)->count());
2590
2591 // The second offer has the same ufrag and pwd but different address.
2592 sdp.clear();
2593 ModifyIceUfragPwdLines(offer.get(), "0123456789012345",
2594 "abcdefghijklmnopqrstuvwx", &sdp);
2595 SessionDescriptionInterface* offer2 =
2596 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
2597 candidate1.set_address(rtc::SocketAddress("1.1.1.1", 6000));
2598 JsepIceCandidate ice_candidate2(kMediaContentName0, kMediaContentIndex0,
2599 candidate1);
2600 EXPECT_TRUE(offer2->AddCandidate(&ice_candidate2));
2601 SetRemoteDescriptionWithoutError(offer2);
2602 EXPECT_EQ(2, session_->remote_description()->candidates(0)->count());
2603
2604 // The third offer has a different ufrag and different address.
2605 sdp.clear();
2606 ModifyIceUfragPwdLines(offer.get(), "0123456789012333",
2607 "abcdefghijklmnopqrstuvwx", &sdp);
2608 SessionDescriptionInterface* offer3 =
2609 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
2610 candidate1.set_address(rtc::SocketAddress("1.1.1.1", 7000));
2611 JsepIceCandidate ice_candidate3(kMediaContentName0, kMediaContentIndex0,
2612 candidate1);
2613 EXPECT_TRUE(offer3->AddCandidate(&ice_candidate3));
2614 SetRemoteDescriptionWithoutError(offer3);
2615 EXPECT_EQ(1, session_->remote_description()->candidates(0)->count());
2616
2617 // The fourth offer has no candidate but a different ufrag/pwd.
2618 sdp.clear();
2619 ModifyIceUfragPwdLines(offer.get(), "0123456789012444",
2620 "abcdefghijklmnopqrstuvyz", &sdp);
2621 SessionDescriptionInterface* offer4 =
2622 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
2623 SetRemoteDescriptionWithoutError(offer4);
2624 EXPECT_EQ(0, session_->remote_description()->candidates(0)->count());
2625}
2626
Donald Curtisd4f769d2015-05-28 09:48:21 -07002627// Test that candidates sent to the "video" transport do not get pushed down to
2628// the "audio" transport channel when bundling using TransportProxy.
2629TEST_F(WebRtcSessionTest, TestIgnoreCandidatesForUnusedTransportWhenBundling) {
2630 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
2631
2632 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyBalanced);
2633 mediastream_signaling_.SendAudioVideoStream1();
2634
2635 PeerConnectionInterface::RTCOfferAnswerOptions options;
2636 options.use_rtp_mux = true;
2637
2638 SessionDescriptionInterface* offer = CreateRemoteOffer();
2639 SetRemoteDescriptionWithoutError(offer);
2640
2641 SessionDescriptionInterface* answer = CreateAnswer(NULL);
2642 SetLocalDescriptionWithoutError(answer);
2643
2644 EXPECT_EQ(session_->GetTransportProxy("audio")->impl(),
2645 session_->GetTransportProxy("video")->impl());
2646
2647 cricket::Transport* t = session_->GetTransport("audio");
2648
2649 // Checks if one of the transport channels contains a connection using a given
2650 // port.
2651 auto connection_with_remote_port = [t](int port) {
2652 cricket::TransportStats stats;
2653 t->GetStats(&stats);
2654 for (auto& chan_stat : stats.channel_stats) {
2655 for (auto& conn_info : chan_stat.connection_infos) {
2656 if (conn_info.remote_candidate.address().port() == port) {
2657 return true;
2658 }
2659 }
2660 }
2661 return false;
2662 };
2663
2664 EXPECT_FALSE(connection_with_remote_port(5000));
2665 EXPECT_FALSE(connection_with_remote_port(5001));
2666 EXPECT_FALSE(connection_with_remote_port(6000));
2667
2668 // The way the *_WAIT checks work is they only wait if the condition fails,
2669 // which does not help in the case where state is not changing. This is
2670 // problematic in this test since we want to verify that adding a video
2671 // candidate does _not_ change state. So we interleave candidates and assume
2672 // that messages are executed in the order they were posted.
2673
2674 // First audio candidate.
2675 cricket::Candidate candidate0;
2676 candidate0.set_address(rtc::SocketAddress("1.1.1.1", 5000));
2677 candidate0.set_component(1);
2678 candidate0.set_protocol("udp");
2679 JsepIceCandidate ice_candidate0(kMediaContentName0, kMediaContentIndex0,
2680 candidate0);
2681 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate0));
2682
2683 // Video candidate.
2684 cricket::Candidate candidate1;
2685 candidate1.set_address(rtc::SocketAddress("1.1.1.1", 6000));
2686 candidate1.set_component(1);
2687 candidate1.set_protocol("udp");
2688 JsepIceCandidate ice_candidate1(kMediaContentName1, kMediaContentIndex1,
2689 candidate1);
2690 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate1));
2691
2692 // Second audio candidate.
2693 cricket::Candidate candidate2;
2694 candidate2.set_address(rtc::SocketAddress("1.1.1.1", 5001));
2695 candidate2.set_component(1);
2696 candidate2.set_protocol("udp");
2697 JsepIceCandidate ice_candidate2(kMediaContentName0, kMediaContentIndex0,
2698 candidate2);
2699 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate2));
2700
2701 EXPECT_TRUE_WAIT(connection_with_remote_port(5000), 1000);
2702 EXPECT_TRUE_WAIT(connection_with_remote_port(5001), 1000);
2703
2704 // No need here for a _WAIT check since we are checking that state hasn't
2705 // changed: if this is false we would be doing waits for nothing and if this
2706 // is true then there will be no messages processed anyways.
2707 EXPECT_FALSE(connection_with_remote_port(6000));
2708}
2709
Peter Thatcher4eddf182015-04-30 10:55:59 -07002710// kBundlePolicyBalanced bundle policy and answer contains BUNDLE.
Donald Curtis0e209b02015-03-24 09:29:54 -07002711TEST_F(WebRtcSessionTest, TestBalancedBundleInAnswer) {
2712 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyBalanced);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002713 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002714
2715 PeerConnectionInterface::RTCOfferAnswerOptions options;
2716 options.use_rtp_mux = true;
2717
2718 SessionDescriptionInterface* offer = CreateOffer(options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002719 SetLocalDescriptionWithoutError(offer);
Donald Curtis0e209b02015-03-24 09:29:54 -07002720
2721 EXPECT_NE(session_->GetTransportProxy("audio")->impl(),
2722 session_->GetTransportProxy("video")->impl());
2723
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002724 mediastream_signaling_.SendAudioVideoStream2();
Donald Curtis0e209b02015-03-24 09:29:54 -07002725 SessionDescriptionInterface* answer =
2726 CreateRemoteAnswer(session_->local_description());
2727 SetRemoteDescriptionWithoutError(answer);
2728
2729 EXPECT_EQ(session_->GetTransportProxy("audio")->impl(),
2730 session_->GetTransportProxy("video")->impl());
2731}
2732
2733// kBundlePolicyBalanced bundle policy but no BUNDLE in the answer.
2734TEST_F(WebRtcSessionTest, TestBalancedNoBundleInAnswer) {
2735 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyBalanced);
2736 mediastream_signaling_.SendAudioVideoStream1();
Peter Thatcher4eddf182015-04-30 10:55:59 -07002737
Donald Curtis0e209b02015-03-24 09:29:54 -07002738 PeerConnectionInterface::RTCOfferAnswerOptions options;
2739 options.use_rtp_mux = true;
2740
2741 SessionDescriptionInterface* offer = CreateOffer(options);
2742 SetLocalDescriptionWithoutError(offer);
2743
2744 EXPECT_NE(session_->GetTransportProxy("audio")->impl(),
2745 session_->GetTransportProxy("video")->impl());
2746
2747 mediastream_signaling_.SendAudioVideoStream2();
2748
2749 // Remove BUNDLE from the answer.
2750 rtc::scoped_ptr<SessionDescriptionInterface> answer(
2751 CreateRemoteAnswer(session_->local_description()));
2752 cricket::SessionDescription* answer_copy = answer->description()->Copy();
2753 answer_copy->RemoveGroupByName(cricket::GROUP_TYPE_BUNDLE);
2754 JsepSessionDescription* modified_answer =
2755 new JsepSessionDescription(JsepSessionDescription::kAnswer);
2756 modified_answer->Initialize(answer_copy, "1", "1");
2757 SetRemoteDescriptionWithoutError(modified_answer); //
2758
2759 EXPECT_NE(session_->GetTransportProxy("audio")->impl(),
2760 session_->GetTransportProxy("video")->impl());
2761}
2762
2763// kBundlePolicyMaxBundle policy with BUNDLE in the answer.
2764TEST_F(WebRtcSessionTest, TestMaxBundleBundleInAnswer) {
2765 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxBundle);
2766 mediastream_signaling_.SendAudioVideoStream1();
2767
2768 PeerConnectionInterface::RTCOfferAnswerOptions options;
2769 options.use_rtp_mux = true;
2770
2771 SessionDescriptionInterface* offer = CreateOffer(options);
2772 SetLocalDescriptionWithoutError(offer);
2773
2774 EXPECT_EQ(session_->GetTransportProxy("audio")->impl(),
2775 session_->GetTransportProxy("video")->impl());
2776
2777 mediastream_signaling_.SendAudioVideoStream2();
2778 SessionDescriptionInterface* answer =
2779 CreateRemoteAnswer(session_->local_description());
2780 SetRemoteDescriptionWithoutError(answer);
2781
2782 EXPECT_EQ(session_->GetTransportProxy("audio")->impl(),
2783 session_->GetTransportProxy("video")->impl());
2784}
2785
2786// kBundlePolicyMaxBundle policy but no BUNDLE in the answer.
2787TEST_F(WebRtcSessionTest, TestMaxBundleNoBundleInAnswer) {
2788 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxBundle);
2789 mediastream_signaling_.SendAudioVideoStream1();
Peter Thatcher4eddf182015-04-30 10:55:59 -07002790
Donald Curtis0e209b02015-03-24 09:29:54 -07002791 PeerConnectionInterface::RTCOfferAnswerOptions options;
2792 options.use_rtp_mux = true;
2793
2794 SessionDescriptionInterface* offer = CreateOffer(options);
2795 SetLocalDescriptionWithoutError(offer);
2796
2797 EXPECT_EQ(session_->GetTransportProxy("audio")->impl(),
2798 session_->GetTransportProxy("video")->impl());
2799
2800 mediastream_signaling_.SendAudioVideoStream2();
2801
2802 // Remove BUNDLE from the answer.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002803 rtc::scoped_ptr<SessionDescriptionInterface> answer(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002804 CreateRemoteAnswer(session_->local_description()));
2805 cricket::SessionDescription* answer_copy = answer->description()->Copy();
2806 answer_copy->RemoveGroupByName(cricket::GROUP_TYPE_BUNDLE);
2807 JsepSessionDescription* modified_answer =
2808 new JsepSessionDescription(JsepSessionDescription::kAnswer);
2809 modified_answer->Initialize(answer_copy, "1", "1");
2810 SetRemoteDescriptionWithoutError(modified_answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002811
Donald Curtis0e209b02015-03-24 09:29:54 -07002812 EXPECT_EQ(session_->GetTransportProxy("audio")->impl(),
2813 session_->GetTransportProxy("video")->impl());
2814}
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002815
Peter Thatcher4eddf182015-04-30 10:55:59 -07002816// kBundlePolicyMaxCompat bundle policy and answer contains BUNDLE.
Donald Curtis0e209b02015-03-24 09:29:54 -07002817TEST_F(WebRtcSessionTest, TestMaxCompatBundleInAnswer) {
2818 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxCompat);
2819 mediastream_signaling_.SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002820
Donald Curtis0e209b02015-03-24 09:29:54 -07002821 PeerConnectionInterface::RTCOfferAnswerOptions options;
2822 options.use_rtp_mux = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002823
Donald Curtis0e209b02015-03-24 09:29:54 -07002824 SessionDescriptionInterface* offer = CreateOffer(options);
2825 SetLocalDescriptionWithoutError(offer);
2826
2827 EXPECT_NE(session_->GetTransportProxy("audio")->impl(),
2828 session_->GetTransportProxy("video")->impl());
2829
2830 mediastream_signaling_.SendAudioVideoStream2();
2831 SessionDescriptionInterface* answer =
2832 CreateRemoteAnswer(session_->local_description());
2833 SetRemoteDescriptionWithoutError(answer);
2834
2835 // This should lead to an audio-only call but isn't implemented
2836 // correctly yet.
2837 EXPECT_EQ(session_->GetTransportProxy("audio")->impl(),
2838 session_->GetTransportProxy("video")->impl());
2839}
2840
2841// kBundlePolicyMaxCompat bundle policy but no BUNDLE in the answer.
2842TEST_F(WebRtcSessionTest, TestMaxCompatNoBundleInAnswer) {
2843 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxCompat);
2844 mediastream_signaling_.SendAudioVideoStream1();
2845 PeerConnectionInterface::RTCOfferAnswerOptions options;
2846 options.use_rtp_mux = true;
2847
2848 SessionDescriptionInterface* offer = CreateOffer(options);
2849 SetLocalDescriptionWithoutError(offer);
2850
2851 EXPECT_NE(session_->GetTransportProxy("audio")->impl(),
2852 session_->GetTransportProxy("video")->impl());
2853
2854 mediastream_signaling_.SendAudioVideoStream2();
2855
2856 // Remove BUNDLE from the answer.
2857 rtc::scoped_ptr<SessionDescriptionInterface> answer(
2858 CreateRemoteAnswer(session_->local_description()));
2859 cricket::SessionDescription* answer_copy = answer->description()->Copy();
2860 answer_copy->RemoveGroupByName(cricket::GROUP_TYPE_BUNDLE);
2861 JsepSessionDescription* modified_answer =
2862 new JsepSessionDescription(JsepSessionDescription::kAnswer);
2863 modified_answer->Initialize(answer_copy, "1", "1");
2864 SetRemoteDescriptionWithoutError(modified_answer); //
2865
2866 EXPECT_NE(session_->GetTransportProxy("audio")->impl(),
2867 session_->GetTransportProxy("video")->impl());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002868}
2869
Peter Thatcher4eddf182015-04-30 10:55:59 -07002870// kBundlePolicyMaxbundle and then we call SetRemoteDescription first.
2871TEST_F(WebRtcSessionTest, TestMaxBundleWithSetRemoteDescriptionFirst) {
2872 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxBundle);
2873 mediastream_signaling_.SendAudioVideoStream1();
2874
2875 PeerConnectionInterface::RTCOfferAnswerOptions options;
2876 options.use_rtp_mux = true;
2877
2878 SessionDescriptionInterface* offer = CreateOffer(options);
2879 SetRemoteDescriptionWithoutError(offer);
2880
2881 EXPECT_EQ(session_->GetTransportProxy("audio")->impl(),
2882 session_->GetTransportProxy("video")->impl());
2883}
2884
Peter Thatcheraf55ccc2015-05-21 07:48:41 -07002885TEST_F(WebRtcSessionTest, TestRequireRtcpMux) {
2886 InitWithRtcpMuxPolicy(PeerConnectionInterface::kRtcpMuxPolicyRequire);
2887 mediastream_signaling_.SendAudioVideoStream1();
2888
2889 PeerConnectionInterface::RTCOfferAnswerOptions options;
2890 SessionDescriptionInterface* offer = CreateOffer(options);
2891 SetLocalDescriptionWithoutError(offer);
2892
2893 EXPECT_FALSE(session_->GetTransportProxy("audio")->impl()->HasChannel(2));
2894 EXPECT_FALSE(session_->GetTransportProxy("video")->impl()->HasChannel(2));
2895
2896 mediastream_signaling_.SendAudioVideoStream2();
2897 SessionDescriptionInterface* answer =
2898 CreateRemoteAnswer(session_->local_description());
2899 SetRemoteDescriptionWithoutError(answer);
2900
2901 EXPECT_FALSE(session_->GetTransportProxy("audio")->impl()->HasChannel(2));
2902 EXPECT_FALSE(session_->GetTransportProxy("video")->impl()->HasChannel(2));
2903}
2904
2905TEST_F(WebRtcSessionTest, TestNegotiateRtcpMux) {
2906 InitWithRtcpMuxPolicy(PeerConnectionInterface::kRtcpMuxPolicyNegotiate);
2907 mediastream_signaling_.SendAudioVideoStream1();
2908
2909 PeerConnectionInterface::RTCOfferAnswerOptions options;
2910 SessionDescriptionInterface* offer = CreateOffer(options);
2911 SetLocalDescriptionWithoutError(offer);
2912
2913 EXPECT_TRUE(session_->GetTransportProxy("audio")->impl()->HasChannel(2));
2914 EXPECT_TRUE(session_->GetTransportProxy("video")->impl()->HasChannel(2));
2915
2916 mediastream_signaling_.SendAudioVideoStream2();
2917 SessionDescriptionInterface* answer =
2918 CreateRemoteAnswer(session_->local_description());
2919 SetRemoteDescriptionWithoutError(answer);
2920
2921 EXPECT_FALSE(session_->GetTransportProxy("audio")->impl()->HasChannel(2));
2922 EXPECT_FALSE(session_->GetTransportProxy("video")->impl()->HasChannel(2));
2923}
2924
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002925// This test verifies that SetLocalDescription and SetRemoteDescription fails
2926// if BUNDLE is enabled but rtcp-mux is disabled in m-lines.
2927TEST_F(WebRtcSessionTest, TestDisabledRtcpMuxWithBundleEnabled) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002928 Init();
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002929 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002930
2931 PeerConnectionInterface::RTCOfferAnswerOptions options;
2932 options.use_rtp_mux = true;
2933
2934 SessionDescriptionInterface* offer = CreateOffer(options);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002935 std::string offer_str;
2936 offer->ToString(&offer_str);
2937 // Disable rtcp-mux
2938 const std::string rtcp_mux = "rtcp-mux";
2939 const std::string xrtcp_mux = "xrtcp-mux";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002940 rtc::replace_substrs(rtcp_mux.c_str(), rtcp_mux.length(),
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002941 xrtcp_mux.c_str(), xrtcp_mux.length(),
2942 &offer_str);
2943 JsepSessionDescription *local_offer =
2944 new JsepSessionDescription(JsepSessionDescription::kOffer);
2945 EXPECT_TRUE((local_offer)->Initialize(offer_str, NULL));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00002946 SetLocalDescriptionOfferExpectError(kBundleWithoutRtcpMux, local_offer);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002947 JsepSessionDescription *remote_offer =
2948 new JsepSessionDescription(JsepSessionDescription::kOffer);
2949 EXPECT_TRUE((remote_offer)->Initialize(offer_str, NULL));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00002950 SetRemoteDescriptionOfferExpectError(kBundleWithoutRtcpMux, remote_offer);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002951 // Trying unmodified SDP.
2952 SetLocalDescriptionWithoutError(offer);
2953}
2954
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002955TEST_F(WebRtcSessionTest, SetAudioPlayout) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002956 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002957 mediastream_signaling_.SendAudioVideoStream1();
2958 CreateAndSetRemoteOfferAndLocalAnswer();
2959 cricket::FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0);
2960 ASSERT_TRUE(channel != NULL);
2961 ASSERT_EQ(1u, channel->recv_streams().size());
2962 uint32 receive_ssrc = channel->recv_streams()[0].first_ssrc();
2963 double left_vol, right_vol;
2964 EXPECT_TRUE(channel->GetOutputScaling(receive_ssrc, &left_vol, &right_vol));
2965 EXPECT_EQ(1, left_vol);
2966 EXPECT_EQ(1, right_vol);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002967 rtc::scoped_ptr<FakeAudioRenderer> renderer(new FakeAudioRenderer());
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002968 session_->SetAudioPlayout(receive_ssrc, false, renderer.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002969 EXPECT_TRUE(channel->GetOutputScaling(receive_ssrc, &left_vol, &right_vol));
2970 EXPECT_EQ(0, left_vol);
2971 EXPECT_EQ(0, right_vol);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002972 EXPECT_EQ(0, renderer->channel_id());
2973 session_->SetAudioPlayout(receive_ssrc, true, NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002974 EXPECT_TRUE(channel->GetOutputScaling(receive_ssrc, &left_vol, &right_vol));
2975 EXPECT_EQ(1, left_vol);
2976 EXPECT_EQ(1, right_vol);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002977 EXPECT_EQ(-1, renderer->channel_id());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002978}
2979
2980TEST_F(WebRtcSessionTest, SetAudioSend) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002981 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002982 mediastream_signaling_.SendAudioVideoStream1();
2983 CreateAndSetRemoteOfferAndLocalAnswer();
2984 cricket::FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0);
2985 ASSERT_TRUE(channel != NULL);
2986 ASSERT_EQ(1u, channel->send_streams().size());
2987 uint32 send_ssrc = channel->send_streams()[0].first_ssrc();
2988 EXPECT_FALSE(channel->IsStreamMuted(send_ssrc));
2989
2990 cricket::AudioOptions options;
2991 options.echo_cancellation.Set(true);
2992
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002993 rtc::scoped_ptr<FakeAudioRenderer> renderer(new FakeAudioRenderer());
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002994 session_->SetAudioSend(send_ssrc, false, options, renderer.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002995 EXPECT_TRUE(channel->IsStreamMuted(send_ssrc));
2996 EXPECT_FALSE(channel->options().echo_cancellation.IsSet());
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002997 EXPECT_EQ(0, renderer->channel_id());
henrike@webrtc.orga7b98182014-02-21 15:51:43 +00002998 EXPECT_TRUE(renderer->sink() != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002999
henrike@webrtc.orga7b98182014-02-21 15:51:43 +00003000 // This will trigger SetSink(NULL) to the |renderer|.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00003001 session_->SetAudioSend(send_ssrc, true, options, NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003002 EXPECT_FALSE(channel->IsStreamMuted(send_ssrc));
3003 bool value;
3004 EXPECT_TRUE(channel->options().echo_cancellation.Get(&value));
3005 EXPECT_TRUE(value);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00003006 EXPECT_EQ(-1, renderer->channel_id());
henrike@webrtc.orga7b98182014-02-21 15:51:43 +00003007 EXPECT_TRUE(renderer->sink() == NULL);
3008}
3009
3010TEST_F(WebRtcSessionTest, AudioRendererForLocalStream) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003011 Init();
henrike@webrtc.orga7b98182014-02-21 15:51:43 +00003012 mediastream_signaling_.SendAudioVideoStream1();
3013 CreateAndSetRemoteOfferAndLocalAnswer();
3014 cricket::FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0);
3015 ASSERT_TRUE(channel != NULL);
3016 ASSERT_EQ(1u, channel->send_streams().size());
3017 uint32 send_ssrc = channel->send_streams()[0].first_ssrc();
3018
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003019 rtc::scoped_ptr<FakeAudioRenderer> renderer(new FakeAudioRenderer());
henrike@webrtc.orga7b98182014-02-21 15:51:43 +00003020 cricket::AudioOptions options;
3021 session_->SetAudioSend(send_ssrc, true, options, renderer.get());
3022 EXPECT_TRUE(renderer->sink() != NULL);
3023
3024 // Delete the |renderer| and it will trigger OnClose() to the sink, and this
3025 // will invalidate the |renderer_| pointer in the sink and prevent getting a
3026 // SetSink(NULL) callback afterwards.
3027 renderer.reset();
3028
3029 // This will trigger SetSink(NULL) if no OnClose() callback.
3030 session_->SetAudioSend(send_ssrc, true, options, NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003031}
3032
3033TEST_F(WebRtcSessionTest, SetVideoPlayout) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003034 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003035 mediastream_signaling_.SendAudioVideoStream1();
3036 CreateAndSetRemoteOfferAndLocalAnswer();
3037 cricket::FakeVideoMediaChannel* channel = media_engine_->GetVideoChannel(0);
3038 ASSERT_TRUE(channel != NULL);
3039 ASSERT_LT(0u, channel->renderers().size());
3040 EXPECT_TRUE(channel->renderers().begin()->second == NULL);
3041 ASSERT_EQ(1u, channel->recv_streams().size());
3042 uint32 receive_ssrc = channel->recv_streams()[0].first_ssrc();
3043 cricket::FakeVideoRenderer renderer;
3044 session_->SetVideoPlayout(receive_ssrc, true, &renderer);
3045 EXPECT_TRUE(channel->renderers().begin()->second == &renderer);
3046 session_->SetVideoPlayout(receive_ssrc, false, &renderer);
3047 EXPECT_TRUE(channel->renderers().begin()->second == NULL);
3048}
3049
3050TEST_F(WebRtcSessionTest, SetVideoSend) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003051 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003052 mediastream_signaling_.SendAudioVideoStream1();
3053 CreateAndSetRemoteOfferAndLocalAnswer();
3054 cricket::FakeVideoMediaChannel* channel = media_engine_->GetVideoChannel(0);
3055 ASSERT_TRUE(channel != NULL);
3056 ASSERT_EQ(1u, channel->send_streams().size());
3057 uint32 send_ssrc = channel->send_streams()[0].first_ssrc();
3058 EXPECT_FALSE(channel->IsStreamMuted(send_ssrc));
3059 cricket::VideoOptions* options = NULL;
3060 session_->SetVideoSend(send_ssrc, false, options);
3061 EXPECT_TRUE(channel->IsStreamMuted(send_ssrc));
3062 session_->SetVideoSend(send_ssrc, true, options);
3063 EXPECT_FALSE(channel->IsStreamMuted(send_ssrc));
3064}
3065
3066TEST_F(WebRtcSessionTest, CanNotInsertDtmf) {
3067 TestCanInsertDtmf(false);
3068}
3069
3070TEST_F(WebRtcSessionTest, CanInsertDtmf) {
3071 TestCanInsertDtmf(true);
3072}
3073
3074TEST_F(WebRtcSessionTest, InsertDtmf) {
3075 // Setup
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003076 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003077 mediastream_signaling_.SendAudioVideoStream1();
3078 CreateAndSetRemoteOfferAndLocalAnswer();
3079 FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0);
3080 EXPECT_EQ(0U, channel->dtmf_info_queue().size());
3081
3082 // Insert DTMF
3083 const int expected_flags = DF_SEND;
3084 const int expected_duration = 90;
3085 session_->InsertDtmf(kAudioTrack1, 0, expected_duration);
3086 session_->InsertDtmf(kAudioTrack1, 1, expected_duration);
3087 session_->InsertDtmf(kAudioTrack1, 2, expected_duration);
3088
3089 // Verify
3090 ASSERT_EQ(3U, channel->dtmf_info_queue().size());
3091 const uint32 send_ssrc = channel->send_streams()[0].first_ssrc();
3092 EXPECT_TRUE(CompareDtmfInfo(channel->dtmf_info_queue()[0], send_ssrc, 0,
3093 expected_duration, expected_flags));
3094 EXPECT_TRUE(CompareDtmfInfo(channel->dtmf_info_queue()[1], send_ssrc, 1,
3095 expected_duration, expected_flags));
3096 EXPECT_TRUE(CompareDtmfInfo(channel->dtmf_info_queue()[2], send_ssrc, 2,
3097 expected_duration, expected_flags));
3098}
3099
3100// This test verifies the |initiator| flag when session initiates the call.
3101TEST_F(WebRtcSessionTest, TestInitiatorFlagAsOriginator) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003102 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003103 EXPECT_FALSE(session_->initiator());
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003104 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003105 SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
3106 SetLocalDescriptionWithoutError(offer);
3107 EXPECT_TRUE(session_->initiator());
3108 SetRemoteDescriptionWithoutError(answer);
3109 EXPECT_TRUE(session_->initiator());
3110}
3111
3112// This test verifies the |initiator| flag when session receives the call.
3113TEST_F(WebRtcSessionTest, TestInitiatorFlagAsReceiver) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003114 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003115 EXPECT_FALSE(session_->initiator());
3116 SessionDescriptionInterface* offer = CreateRemoteOffer();
3117 SetRemoteDescriptionWithoutError(offer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003118 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003119
3120 EXPECT_FALSE(session_->initiator());
3121 SetLocalDescriptionWithoutError(answer);
3122 EXPECT_FALSE(session_->initiator());
3123}
3124
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003125// Verifing local offer and remote answer have matching m-lines as per RFC 3264.
3126TEST_F(WebRtcSessionTest, TestIncorrectMLinesInRemoteAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003127 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003128 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003129 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003130 SetLocalDescriptionWithoutError(offer);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003131 rtc::scoped_ptr<SessionDescriptionInterface> answer(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003132 CreateRemoteAnswer(session_->local_description()));
3133
3134 cricket::SessionDescription* answer_copy = answer->description()->Copy();
3135 answer_copy->RemoveContentByName("video");
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00003136 JsepSessionDescription* modified_answer =
3137 new JsepSessionDescription(JsepSessionDescription::kAnswer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003138
3139 EXPECT_TRUE(modified_answer->Initialize(answer_copy,
3140 answer->session_id(),
3141 answer->session_version()));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003142 SetRemoteDescriptionAnswerExpectError(kMlineMismatch, modified_answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003143
wu@webrtc.org4e393072014-04-07 17:04:35 +00003144 // Different content names.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003145 std::string sdp;
3146 EXPECT_TRUE(answer->ToString(&sdp));
3147 const std::string kAudioMid = "a=mid:audio";
3148 const std::string kAudioMidReplaceStr = "a=mid:audio_content_name";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003149 rtc::replace_substrs(kAudioMid.c_str(), kAudioMid.length(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003150 kAudioMidReplaceStr.c_str(),
3151 kAudioMidReplaceStr.length(),
3152 &sdp);
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00003153 SessionDescriptionInterface* modified_answer1 =
3154 CreateSessionDescription(JsepSessionDescription::kAnswer, sdp, NULL);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003155 SetRemoteDescriptionAnswerExpectError(kMlineMismatch, modified_answer1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003156
wu@webrtc.org4e393072014-04-07 17:04:35 +00003157 // Different media types.
3158 EXPECT_TRUE(answer->ToString(&sdp));
3159 const std::string kAudioMline = "m=audio";
3160 const std::string kAudioMlineReplaceStr = "m=video";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003161 rtc::replace_substrs(kAudioMline.c_str(), kAudioMline.length(),
wu@webrtc.org4e393072014-04-07 17:04:35 +00003162 kAudioMlineReplaceStr.c_str(),
3163 kAudioMlineReplaceStr.length(),
3164 &sdp);
3165 SessionDescriptionInterface* modified_answer2 =
3166 CreateSessionDescription(JsepSessionDescription::kAnswer, sdp, NULL);
3167 SetRemoteDescriptionAnswerExpectError(kMlineMismatch, modified_answer2);
3168
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003169 SetRemoteDescriptionWithoutError(answer.release());
3170}
3171
3172// Verifying remote offer and local answer have matching m-lines as per
3173// RFC 3264.
3174TEST_F(WebRtcSessionTest, TestIncorrectMLinesInLocalAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003175 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003176 mediastream_signaling_.SendAudioVideoStream1();
3177 SessionDescriptionInterface* offer = CreateRemoteOffer();
3178 SetRemoteDescriptionWithoutError(offer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003179 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003180
3181 cricket::SessionDescription* answer_copy = answer->description()->Copy();
3182 answer_copy->RemoveContentByName("video");
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00003183 JsepSessionDescription* modified_answer =
3184 new JsepSessionDescription(JsepSessionDescription::kAnswer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003185
3186 EXPECT_TRUE(modified_answer->Initialize(answer_copy,
3187 answer->session_id(),
3188 answer->session_version()));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003189 SetLocalDescriptionAnswerExpectError(kMlineMismatch, modified_answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003190 SetLocalDescriptionWithoutError(answer);
3191}
3192
3193// This test verifies that WebRtcSession does not start candidate allocation
3194// before SetLocalDescription is called.
3195TEST_F(WebRtcSessionTest, TestIceStartAfterSetLocalDescriptionOnly) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003196 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003197 mediastream_signaling_.SendAudioVideoStream1();
3198 SessionDescriptionInterface* offer = CreateRemoteOffer();
3199 cricket::Candidate candidate;
3200 candidate.set_component(1);
3201 JsepIceCandidate ice_candidate(kMediaContentName0, kMediaContentIndex0,
3202 candidate);
3203 EXPECT_TRUE(offer->AddCandidate(&ice_candidate));
3204 cricket::Candidate candidate1;
3205 candidate1.set_component(1);
3206 JsepIceCandidate ice_candidate1(kMediaContentName1, kMediaContentIndex1,
3207 candidate1);
3208 EXPECT_TRUE(offer->AddCandidate(&ice_candidate1));
3209 SetRemoteDescriptionWithoutError(offer);
3210 ASSERT_TRUE(session_->GetTransportProxy("audio") != NULL);
3211 ASSERT_TRUE(session_->GetTransportProxy("video") != NULL);
3212
3213 // Pump for 1 second and verify that no candidates are generated.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003214 rtc::Thread::Current()->ProcessMessages(1000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003215 EXPECT_TRUE(observer_.mline_0_candidates_.empty());
3216 EXPECT_TRUE(observer_.mline_1_candidates_.empty());
3217
wu@webrtc.org91053e72013-08-10 07:18:04 +00003218 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003219 SetLocalDescriptionWithoutError(answer);
3220 EXPECT_TRUE(session_->GetTransportProxy("audio")->negotiated());
3221 EXPECT_TRUE(session_->GetTransportProxy("video")->negotiated());
3222 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
3223}
3224
3225// This test verifies that crypto parameter is updated in local session
3226// description as per security policy set in MediaSessionDescriptionFactory.
3227TEST_F(WebRtcSessionTest, TestCryptoAfterSetLocalDescription) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003228 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003229 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003230 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003231
3232 // Making sure SetLocalDescription correctly sets crypto value in
3233 // SessionDescription object after de-serialization of sdp string. The value
3234 // will be set as per MediaSessionDescriptionFactory.
3235 std::string offer_str;
3236 offer->ToString(&offer_str);
3237 SessionDescriptionInterface* jsep_offer_str =
3238 CreateSessionDescription(JsepSessionDescription::kOffer, offer_str, NULL);
3239 SetLocalDescriptionWithoutError(jsep_offer_str);
3240 EXPECT_TRUE(session_->voice_channel()->secure_required());
3241 EXPECT_TRUE(session_->video_channel()->secure_required());
3242}
3243
3244// This test verifies the crypto parameter when security is disabled.
3245TEST_F(WebRtcSessionTest, TestCryptoAfterSetLocalDescriptionWithDisabled) {
wu@webrtc.org97077a32013-10-25 21:18:33 +00003246 options_.disable_encryption = true;
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003247 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003248 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003249 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003250
3251 // Making sure SetLocalDescription correctly sets crypto value in
3252 // SessionDescription object after de-serialization of sdp string. The value
3253 // will be set as per MediaSessionDescriptionFactory.
3254 std::string offer_str;
3255 offer->ToString(&offer_str);
3256 SessionDescriptionInterface *jsep_offer_str =
3257 CreateSessionDescription(JsepSessionDescription::kOffer, offer_str, NULL);
3258 SetLocalDescriptionWithoutError(jsep_offer_str);
3259 EXPECT_FALSE(session_->voice_channel()->secure_required());
3260 EXPECT_FALSE(session_->video_channel()->secure_required());
3261}
3262
3263// This test verifies that an answer contains new ufrag and password if an offer
3264// with new ufrag and password is received.
3265TEST_F(WebRtcSessionTest, TestCreateAnswerWithNewUfragAndPassword) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003266 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003267 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00003268 options.recv_video = true;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003269 rtc::scoped_ptr<JsepSessionDescription> offer(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003270 CreateRemoteOffer(options));
3271 SetRemoteDescriptionWithoutError(offer.release());
3272
3273 mediastream_signaling_.SendAudioVideoStream1();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003274 rtc::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00003275 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003276 SetLocalDescriptionWithoutError(answer.release());
3277
3278 // Receive an offer with new ufrag and password.
3279 options.transport_options.ice_restart = true;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003280 rtc::scoped_ptr<JsepSessionDescription> updated_offer1(
wu@webrtc.org91053e72013-08-10 07:18:04 +00003281 CreateRemoteOffer(options, session_->remote_description()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003282 SetRemoteDescriptionWithoutError(updated_offer1.release());
3283
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003284 rtc::scoped_ptr<SessionDescriptionInterface> updated_answer1(
wu@webrtc.org91053e72013-08-10 07:18:04 +00003285 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003286
3287 CompareIceUfragAndPassword(updated_answer1->description(),
3288 session_->local_description()->description(),
3289 false);
3290
3291 SetLocalDescriptionWithoutError(updated_answer1.release());
wu@webrtc.org91053e72013-08-10 07:18:04 +00003292}
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003293
wu@webrtc.org91053e72013-08-10 07:18:04 +00003294// This test verifies that an answer contains old ufrag and password if an offer
3295// with old ufrag and password is received.
3296TEST_F(WebRtcSessionTest, TestCreateAnswerWithOldUfragAndPassword) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003297 Init();
wu@webrtc.org91053e72013-08-10 07:18:04 +00003298 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00003299 options.recv_video = true;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003300 rtc::scoped_ptr<JsepSessionDescription> offer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00003301 CreateRemoteOffer(options));
3302 SetRemoteDescriptionWithoutError(offer.release());
3303
3304 mediastream_signaling_.SendAudioVideoStream1();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003305 rtc::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00003306 CreateAnswer(NULL));
3307 SetLocalDescriptionWithoutError(answer.release());
3308
3309 // Receive an offer without changed ufrag or password.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003310 options.transport_options.ice_restart = false;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003311 rtc::scoped_ptr<JsepSessionDescription> updated_offer2(
wu@webrtc.org91053e72013-08-10 07:18:04 +00003312 CreateRemoteOffer(options, session_->remote_description()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003313 SetRemoteDescriptionWithoutError(updated_offer2.release());
3314
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003315 rtc::scoped_ptr<SessionDescriptionInterface> updated_answer2(
wu@webrtc.org91053e72013-08-10 07:18:04 +00003316 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003317
3318 CompareIceUfragAndPassword(updated_answer2->description(),
3319 session_->local_description()->description(),
3320 true);
3321
3322 SetLocalDescriptionWithoutError(updated_answer2.release());
3323}
3324
3325TEST_F(WebRtcSessionTest, TestSessionContentError) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003326 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003327 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003328 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003329 const std::string session_id_orig = offer->session_id();
3330 const std::string session_version_orig = offer->session_version();
3331 SetLocalDescriptionWithoutError(offer);
3332
3333 video_channel_ = media_engine_->GetVideoChannel(0);
3334 video_channel_->set_fail_set_send_codecs(true);
3335
3336 mediastream_signaling_.SendAudioVideoStream2();
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00003337 SessionDescriptionInterface* answer =
3338 CreateRemoteAnswer(session_->local_description());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003339 SetRemoteDescriptionAnswerExpectError("ERROR_CONTENT", answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003340}
3341
3342// Runs the loopback call test with BUNDLE and STUN disabled.
3343TEST_F(WebRtcSessionTest, TestIceStatesBasic) {
3344 // Lets try with only UDP ports.
Peter Thatcher3449faa2015-08-10 12:22:51 -07003345 allocator_->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00003346 cricket::PORTALLOCATOR_DISABLE_STUN |
3347 cricket::PORTALLOCATOR_DISABLE_RELAY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003348 TestLoopbackCall();
3349}
3350
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00003351TEST_F(WebRtcSessionTest, TestIceStatesBasicIPv6) {
Peter Thatcher3449faa2015-08-10 12:22:51 -07003352 allocator_->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00003353 cricket::PORTALLOCATOR_DISABLE_STUN |
3354 cricket::PORTALLOCATOR_ENABLE_IPV6 |
3355 cricket::PORTALLOCATOR_DISABLE_RELAY);
3356
3357 // best connection is IPv6 since it has higher network preference.
3358 LoopbackNetworkConfiguration config;
3359 config.test_ipv6_network_ = true;
3360 config.best_connection_after_initial_ice_converged_ =
3361 LoopbackNetworkConfiguration::ExpectedBestConnection(0, 1);
3362
3363 TestLoopbackCall(config);
3364}
3365
mallinath@webrtc.orgd3dc4242014-03-01 00:05:52 +00003366// Runs the loopback call test with BUNDLE and STUN enabled.
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00003367TEST_F(WebRtcSessionTest, TestIceStatesBundle) {
Peter Thatcher3449faa2015-08-10 12:22:51 -07003368 allocator_->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
3369 cricket::PORTALLOCATOR_DISABLE_RELAY);
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00003370 TestLoopbackCall();
3371}
3372
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003373TEST_F(WebRtcSessionTest, SetSdpFailedOnSessionError) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003374 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003375 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00003376 options.recv_video = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003377
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003378 cricket::BaseSession::Error error_code = cricket::BaseSession::ERROR_CONTENT;
3379 std::string error_code_str = "ERROR_CONTENT";
3380 std::string error_desc = "Fake session error description.";
3381 session_->SetError(error_code, error_desc);
3382
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003383 SessionDescriptionInterface* offer = CreateRemoteOffer(options);
3384 SessionDescriptionInterface* answer =
3385 CreateRemoteAnswer(offer, options);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003386
3387 std::string action;
3388 std::ostringstream session_error_msg;
3389 session_error_msg << kSessionError << error_code_str << ". ";
3390 session_error_msg << kSessionErrorDesc << error_desc << ".";
3391 SetRemoteDescriptionExpectError(action, session_error_msg.str(), offer);
3392 SetLocalDescriptionExpectError(action, session_error_msg.str(), answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003393}
3394
3395TEST_F(WebRtcSessionTest, TestRtpDataChannel) {
3396 constraints_.reset(new FakeConstraints());
3397 constraints_->AddOptional(
3398 webrtc::MediaConstraintsInterface::kEnableRtpDataChannels, true);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003399 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003400
3401 SetLocalDescriptionWithDataChannel();
3402 EXPECT_EQ(cricket::DCT_RTP, data_engine_->last_channel_type());
3403}
3404
3405TEST_F(WebRtcSessionTest, TestRtpDataChannelConstraintTakesPrecedence) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003406 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003407
3408 constraints_.reset(new FakeConstraints());
3409 constraints_->AddOptional(
3410 webrtc::MediaConstraintsInterface::kEnableRtpDataChannels, true);
wu@webrtc.org97077a32013-10-25 21:18:33 +00003411 options_.disable_sctp_data_channels = false;
3412
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003413 InitWithDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003414
3415 SetLocalDescriptionWithDataChannel();
3416 EXPECT_EQ(cricket::DCT_RTP, data_engine_->last_channel_type());
3417}
3418
wu@webrtc.org967bfff2013-09-19 05:49:50 +00003419TEST_F(WebRtcSessionTest, TestCreateOfferWithSctpEnabledWithoutStreams) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003420 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
wu@webrtc.org967bfff2013-09-19 05:49:50 +00003421
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003422 InitWithDtls();
sergeyu@chromium.orga59696b2013-09-13 23:48:58 +00003423
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003424 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
sergeyu@chromium.orga59696b2013-09-13 23:48:58 +00003425 EXPECT_TRUE(offer->description()->GetContentByName("data") == NULL);
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00003426 EXPECT_TRUE(offer->description()->GetTransportInfoByName("data") == NULL);
3427}
3428
3429TEST_F(WebRtcSessionTest, TestCreateAnswerWithSctpInOfferAndNoStreams) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003430 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00003431 SetFactoryDtlsSrtp();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003432 InitWithDtls();
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00003433
3434 // Create remote offer with SCTP.
3435 cricket::MediaSessionOptions options;
3436 options.data_channel_type = cricket::DCT_SCTP;
3437 JsepSessionDescription* offer =
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003438 CreateRemoteOffer(options, cricket::SEC_DISABLED);
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00003439 SetRemoteDescriptionWithoutError(offer);
3440
3441 // Verifies the answer contains SCTP.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003442 rtc::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00003443 EXPECT_TRUE(answer != NULL);
3444 EXPECT_TRUE(answer->description()->GetContentByName("data") != NULL);
3445 EXPECT_TRUE(answer->description()->GetTransportInfoByName("data") != NULL);
sergeyu@chromium.orga59696b2013-09-13 23:48:58 +00003446}
3447
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003448TEST_F(WebRtcSessionTest, TestSctpDataChannelWithoutDtls) {
3449 constraints_.reset(new FakeConstraints());
3450 constraints_->AddOptional(
sergeyu@chromium.orga59696b2013-09-13 23:48:58 +00003451 webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, false);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003452 InitWithDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003453
3454 SetLocalDescriptionWithDataChannel();
3455 EXPECT_EQ(cricket::DCT_NONE, data_engine_->last_channel_type());
3456}
3457
3458TEST_F(WebRtcSessionTest, TestSctpDataChannelWithDtls) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003459 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003460
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003461 InitWithDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003462
3463 SetLocalDescriptionWithDataChannel();
3464 EXPECT_EQ(cricket::DCT_SCTP, data_engine_->last_channel_type());
3465}
wu@webrtc.org91053e72013-08-10 07:18:04 +00003466
wu@webrtc.org97077a32013-10-25 21:18:33 +00003467TEST_F(WebRtcSessionTest, TestDisableSctpDataChannels) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003468 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
wu@webrtc.org97077a32013-10-25 21:18:33 +00003469 options_.disable_sctp_data_channels = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003470 InitWithDtls();
wu@webrtc.org97077a32013-10-25 21:18:33 +00003471
3472 SetLocalDescriptionWithDataChannel();
3473 EXPECT_EQ(cricket::DCT_NONE, data_engine_->last_channel_type());
3474}
3475
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00003476TEST_F(WebRtcSessionTest, TestSctpDataChannelSendPortParsing) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003477 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00003478 const int new_send_port = 9998;
3479 const int new_recv_port = 7775;
3480
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003481 InitWithDtls();
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00003482 SetFactoryDtlsSrtp();
3483
3484 // By default, don't actually add the codecs to desc_factory_; they don't
3485 // actually get serialized for SCTP in BuildMediaDescription(). Instead,
3486 // let the session description get parsed. That'll get the proper codecs
3487 // into the stream.
3488 cricket::MediaSessionOptions options;
3489 JsepSessionDescription* offer = CreateRemoteOfferWithSctpPort(
3490 "stream1", new_send_port, options);
3491
3492 // SetRemoteDescription will take the ownership of the offer.
3493 SetRemoteDescriptionWithoutError(offer);
3494
3495 SessionDescriptionInterface* answer = ChangeSDPSctpPort(
3496 new_recv_port, CreateAnswer(NULL));
3497 ASSERT_TRUE(answer != NULL);
3498
3499 // Now set the local description, which'll take ownership of the answer.
3500 SetLocalDescriptionWithoutError(answer);
3501
3502 // TEST PLAN: Set the port number to something new, set it in the SDP,
3503 // and pass it all the way down.
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +00003504 webrtc::InternalDataChannelInit dci;
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00003505 dci.reliable = true;
3506 EXPECT_EQ(cricket::DCT_SCTP, data_engine_->last_channel_type());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003507 rtc::scoped_refptr<webrtc::DataChannel> dc =
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00003508 session_->CreateDataChannel("datachannel", &dci);
3509
3510 cricket::FakeDataMediaChannel* ch = data_engine_->GetChannel(0);
3511 int portnum = -1;
3512 ASSERT_TRUE(ch != NULL);
3513 ASSERT_EQ(1UL, ch->send_codecs().size());
3514 EXPECT_EQ(cricket::kGoogleSctpDataCodecId, ch->send_codecs()[0].id);
Donald Curtisd4f769d2015-05-28 09:48:21 -07003515 EXPECT_EQ(0, strcmp(cricket::kGoogleSctpDataCodecName,
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00003516 ch->send_codecs()[0].name.c_str()));
3517 EXPECT_TRUE(ch->send_codecs()[0].GetParam(cricket::kCodecParamPort,
3518 &portnum));
3519 EXPECT_EQ(new_send_port, portnum);
3520
3521 ASSERT_EQ(1UL, ch->recv_codecs().size());
3522 EXPECT_EQ(cricket::kGoogleSctpDataCodecId, ch->recv_codecs()[0].id);
Donald Curtisd4f769d2015-05-28 09:48:21 -07003523 EXPECT_EQ(0, strcmp(cricket::kGoogleSctpDataCodecName,
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00003524 ch->recv_codecs()[0].name.c_str()));
3525 EXPECT_TRUE(ch->recv_codecs()[0].GetParam(cricket::kCodecParamPort,
3526 &portnum));
3527 EXPECT_EQ(new_recv_port, portnum);
3528}
3529
wu@webrtc.org91053e72013-08-10 07:18:04 +00003530// Verifies that CreateOffer succeeds when CreateOffer is called before async
3531// identity generation is finished.
3532TEST_F(WebRtcSessionTest, TestCreateOfferBeforeIdentityRequestReturnSuccess) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003533 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003534 InitWithDtls();
wu@webrtc.org91053e72013-08-10 07:18:04 +00003535
3536 EXPECT_TRUE(session_->waiting_for_identity());
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003537 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003538 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
3539
wu@webrtc.org91053e72013-08-10 07:18:04 +00003540 EXPECT_TRUE(offer != NULL);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003541 VerifyNoCryptoParams(offer->description(), true);
3542 VerifyFingerprintStatus(offer->description(), true);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003543}
3544
3545// Verifies that CreateAnswer succeeds when CreateOffer is called before async
3546// identity generation is finished.
3547TEST_F(WebRtcSessionTest, TestCreateAnswerBeforeIdentityRequestReturnSuccess) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003548 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003549 InitWithDtls();
3550 SetFactoryDtlsSrtp();
wu@webrtc.org91053e72013-08-10 07:18:04 +00003551
3552 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00003553 options.recv_video = true;
wu@webrtc.org91053e72013-08-10 07:18:04 +00003554 scoped_ptr<JsepSessionDescription> offer(
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003555 CreateRemoteOffer(options, cricket::SEC_DISABLED));
wu@webrtc.org91053e72013-08-10 07:18:04 +00003556 ASSERT_TRUE(offer.get() != NULL);
3557 SetRemoteDescriptionWithoutError(offer.release());
3558
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003559 rtc::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
wu@webrtc.org91053e72013-08-10 07:18:04 +00003560 EXPECT_TRUE(answer != NULL);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003561 VerifyNoCryptoParams(answer->description(), true);
3562 VerifyFingerprintStatus(answer->description(), true);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003563}
3564
3565// Verifies that CreateOffer succeeds when CreateOffer is called after async
3566// identity generation is finished.
3567TEST_F(WebRtcSessionTest, TestCreateOfferAfterIdentityRequestReturnSuccess) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003568 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003569 InitWithDtls();
wu@webrtc.org91053e72013-08-10 07:18:04 +00003570
3571 EXPECT_TRUE_WAIT(!session_->waiting_for_identity(), 1000);
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003572
3573 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
wu@webrtc.org91053e72013-08-10 07:18:04 +00003574 EXPECT_TRUE(offer != NULL);
3575}
3576
3577// Verifies that CreateOffer fails when CreateOffer is called after async
3578// identity generation fails.
3579TEST_F(WebRtcSessionTest, TestCreateOfferAfterIdentityRequestReturnFailure) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003580 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.org7666db72013-08-22 14:45:42 +00003581 InitWithDtls(true);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003582
3583 EXPECT_TRUE_WAIT(!session_->waiting_for_identity(), 1000);
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003584
3585 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
wu@webrtc.org91053e72013-08-10 07:18:04 +00003586 EXPECT_TRUE(offer == NULL);
3587}
3588
3589// Verifies that CreateOffer succeeds when Multiple CreateOffer calls are made
3590// before async identity generation is finished.
3591TEST_F(WebRtcSessionTest,
3592 TestMultipleCreateOfferBeforeIdentityRequestReturnSuccess) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003593 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003594 VerifyMultipleAsyncCreateDescription(
3595 true, CreateSessionDescriptionRequest::kOffer);
3596}
3597
3598// Verifies that CreateOffer fails when Multiple CreateOffer calls are made
3599// before async identity generation fails.
3600TEST_F(WebRtcSessionTest,
3601 TestMultipleCreateOfferBeforeIdentityRequestReturnFailure) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003602 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003603 VerifyMultipleAsyncCreateDescription(
3604 false, CreateSessionDescriptionRequest::kOffer);
3605}
3606
3607// Verifies that CreateAnswer succeeds when Multiple CreateAnswer calls are made
3608// before async identity generation is finished.
3609TEST_F(WebRtcSessionTest,
3610 TestMultipleCreateAnswerBeforeIdentityRequestReturnSuccess) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003611 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003612 VerifyMultipleAsyncCreateDescription(
3613 true, CreateSessionDescriptionRequest::kAnswer);
3614}
3615
3616// Verifies that CreateAnswer fails when Multiple CreateAnswer calls are made
3617// before async identity generation fails.
3618TEST_F(WebRtcSessionTest,
3619 TestMultipleCreateAnswerBeforeIdentityRequestReturnFailure) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003620 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003621 VerifyMultipleAsyncCreateDescription(
3622 false, CreateSessionDescriptionRequest::kAnswer);
3623}
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00003624
3625// Verifies that setRemoteDescription fails when DTLS is disabled and the remote
3626// offer has no SDES crypto but only DTLS fingerprint.
3627TEST_F(WebRtcSessionTest, TestSetRemoteOfferFailIfDtlsDisabledAndNoCrypto) {
3628 // Init without DTLS.
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003629 Init();
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00003630 // Create a remote offer with secured transport disabled.
3631 cricket::MediaSessionOptions options;
3632 JsepSessionDescription* offer(CreateRemoteOffer(
3633 options, cricket::SEC_DISABLED));
3634 // Adds a DTLS fingerprint to the remote offer.
3635 cricket::SessionDescription* sdp = offer->description();
3636 TransportInfo* audio = sdp->GetTransportInfoByName("audio");
3637 ASSERT_TRUE(audio != NULL);
3638 ASSERT_TRUE(audio->description.identity_fingerprint.get() == NULL);
3639 audio->description.identity_fingerprint.reset(
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003640 rtc::SSLFingerprint::CreateFromRfc4572(
3641 rtc::DIGEST_SHA_256, kFakeDtlsFingerprint));
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003642 SetRemoteDescriptionOfferExpectError(kSdpWithoutSdesCrypto,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003643 offer);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00003644}
3645
wu@webrtc.orgde305012013-10-31 15:40:38 +00003646// This test verifies DSCP is properly applied on the media channels.
3647TEST_F(WebRtcSessionTest, TestDscpConstraint) {
3648 constraints_.reset(new FakeConstraints());
3649 constraints_->AddOptional(
3650 webrtc::MediaConstraintsInterface::kEnableDscp, true);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003651 Init();
wu@webrtc.orgde305012013-10-31 15:40:38 +00003652 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003653 SessionDescriptionInterface* offer = CreateOffer();
wu@webrtc.orgde305012013-10-31 15:40:38 +00003654
3655 SetLocalDescriptionWithoutError(offer);
3656
3657 video_channel_ = media_engine_->GetVideoChannel(0);
3658 voice_channel_ = media_engine_->GetVoiceChannel(0);
3659
3660 ASSERT_TRUE(video_channel_ != NULL);
3661 ASSERT_TRUE(voice_channel_ != NULL);
3662 cricket::AudioOptions audio_options;
3663 EXPECT_TRUE(voice_channel_->GetOptions(&audio_options));
3664 cricket::VideoOptions video_options;
3665 EXPECT_TRUE(video_channel_->GetOptions(&video_options));
3666 EXPECT_TRUE(audio_options.dscp.IsSet());
3667 EXPECT_TRUE(audio_options.dscp.GetWithDefaultIfUnset(false));
3668 EXPECT_TRUE(video_options.dscp.IsSet());
3669 EXPECT_TRUE(video_options.dscp.GetWithDefaultIfUnset(false));
3670}
3671
henrike@webrtc.org6e3dbc22014-03-25 17:09:47 +00003672TEST_F(WebRtcSessionTest, TestSuspendBelowMinBitrateConstraint) {
3673 constraints_.reset(new FakeConstraints());
3674 constraints_->AddOptional(
3675 webrtc::MediaConstraintsInterface::kEnableVideoSuspendBelowMinBitrate,
3676 true);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003677 Init();
henrike@webrtc.org6e3dbc22014-03-25 17:09:47 +00003678 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003679 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org6e3dbc22014-03-25 17:09:47 +00003680
3681 SetLocalDescriptionWithoutError(offer);
3682
3683 video_channel_ = media_engine_->GetVideoChannel(0);
3684
3685 ASSERT_TRUE(video_channel_ != NULL);
3686 cricket::VideoOptions video_options;
3687 EXPECT_TRUE(video_channel_->GetOptions(&video_options));
3688 EXPECT_TRUE(
3689 video_options.suspend_below_min_bitrate.GetWithDefaultIfUnset(false));
3690}
3691
buildbot@webrtc.org53df88c2014-08-07 22:46:01 +00003692TEST_F(WebRtcSessionTest, TestNumUnsignalledRecvStreamsConstraint) {
3693 // Number of unsignalled receiving streams should be between 0 and
3694 // kMaxUnsignalledRecvStreams.
3695 SetAndVerifyNumUnsignalledRecvStreams(10, 10);
3696 SetAndVerifyNumUnsignalledRecvStreams(kMaxUnsignalledRecvStreams + 1,
3697 kMaxUnsignalledRecvStreams);
3698 SetAndVerifyNumUnsignalledRecvStreams(-1, 0);
3699}
3700
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +00003701TEST_F(WebRtcSessionTest, TestCombinedAudioVideoBweConstraint) {
3702 constraints_.reset(new FakeConstraints());
3703 constraints_->AddOptional(
3704 webrtc::MediaConstraintsInterface::kCombinedAudioVideoBwe,
3705 true);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003706 Init();
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +00003707 mediastream_signaling_.SendAudioVideoStream1();
3708 SessionDescriptionInterface* offer = CreateOffer();
3709
3710 SetLocalDescriptionWithoutError(offer);
3711
3712 voice_channel_ = media_engine_->GetVoiceChannel(0);
3713
3714 ASSERT_TRUE(voice_channel_ != NULL);
3715 cricket::AudioOptions audio_options;
3716 EXPECT_TRUE(voice_channel_->GetOptions(&audio_options));
3717 EXPECT_TRUE(
3718 audio_options.combined_audio_video_bwe.GetWithDefaultIfUnset(false));
3719}
3720
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00003721// Tests that we can renegotiate new media content with ICE candidates in the
3722// new remote SDP.
3723TEST_F(WebRtcSessionTest, TestRenegotiateNewMediaWithCandidatesInSdp) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003724 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00003725 InitWithDtls();
3726 SetFactoryDtlsSrtp();
3727
3728 mediastream_signaling_.UseOptionsAudioOnly();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003729 SessionDescriptionInterface* offer = CreateOffer();
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00003730 SetLocalDescriptionWithoutError(offer);
3731
3732 SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
3733 SetRemoteDescriptionWithoutError(answer);
3734
3735 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00003736 options.recv_video = true;
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00003737 offer = CreateRemoteOffer(options, cricket::SEC_DISABLED);
3738
3739 cricket::Candidate candidate1;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003740 candidate1.set_address(rtc::SocketAddress("1.1.1.1", 5000));
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00003741 candidate1.set_component(1);
3742 JsepIceCandidate ice_candidate(kMediaContentName1, kMediaContentIndex1,
3743 candidate1);
3744 EXPECT_TRUE(offer->AddCandidate(&ice_candidate));
3745 SetRemoteDescriptionWithoutError(offer);
3746
3747 answer = CreateAnswer(NULL);
3748 SetLocalDescriptionWithoutError(answer);
3749}
3750
3751// Tests that we can renegotiate new media content with ICE candidates separated
3752// from the remote SDP.
3753TEST_F(WebRtcSessionTest, TestRenegotiateNewMediaWithCandidatesSeparated) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003754 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00003755 InitWithDtls();
3756 SetFactoryDtlsSrtp();
3757
3758 mediastream_signaling_.UseOptionsAudioOnly();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003759 SessionDescriptionInterface* offer = CreateOffer();
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00003760 SetLocalDescriptionWithoutError(offer);
3761
3762 SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
3763 SetRemoteDescriptionWithoutError(answer);
3764
3765 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00003766 options.recv_video = true;
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00003767 offer = CreateRemoteOffer(options, cricket::SEC_DISABLED);
3768 SetRemoteDescriptionWithoutError(offer);
3769
3770 cricket::Candidate candidate1;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003771 candidate1.set_address(rtc::SocketAddress("1.1.1.1", 5000));
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00003772 candidate1.set_component(1);
3773 JsepIceCandidate ice_candidate(kMediaContentName1, kMediaContentIndex1,
3774 candidate1);
3775 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate));
3776
3777 answer = CreateAnswer(NULL);
3778 SetLocalDescriptionWithoutError(answer);
3779}
changbin.shao@webrtc.org2d25b442015-03-16 04:14:34 +00003780// Tests that RTX codec is removed from the answer when it isn't supported
3781// by local side.
3782TEST_F(WebRtcSessionTest, TestRtxRemovedByCreateAnswer) {
3783 Init();
3784 mediastream_signaling_.SendAudioVideoStream1();
3785 std::string offer_sdp(kSdpWithRtx);
3786
3787 SessionDescriptionInterface* offer =
3788 CreateSessionDescription(JsepSessionDescription::kOffer, offer_sdp, NULL);
3789 EXPECT_TRUE(offer->ToString(&offer_sdp));
3790
3791 // Offer SDP contains the RTX codec.
3792 EXPECT_TRUE(offer_sdp.find("rtx") != std::string::npos);
3793 SetRemoteDescriptionWithoutError(offer);
3794
3795 SessionDescriptionInterface* answer = CreateAnswer(NULL);
3796 std::string answer_sdp;
3797 answer->ToString(&answer_sdp);
3798 // Answer SDP removes the unsupported RTX codec.
3799 EXPECT_TRUE(answer_sdp.find("rtx") == std::string::npos);
3800 SetLocalDescriptionWithoutError(answer);
3801}
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00003802
guoweis@webrtc.org4f852882015-03-12 20:09:44 +00003803// This verifies that the voice channel after bundle has both options from video
3804// and voice channels.
3805TEST_F(WebRtcSessionTest, TestSetSocketOptionBeforeBundle) {
3806 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyBalanced);
3807 mediastream_signaling_.SendAudioVideoStream1();
3808
3809 PeerConnectionInterface::RTCOfferAnswerOptions options;
3810 options.use_rtp_mux = true;
3811
3812 SessionDescriptionInterface* offer = CreateOffer(options);
3813 SetLocalDescriptionWithoutError(offer);
3814
3815 session_->video_channel()->SetOption(cricket::BaseChannel::ST_RTP,
3816 rtc::Socket::Option::OPT_SNDBUF, 4000);
3817
3818 session_->voice_channel()->SetOption(cricket::BaseChannel::ST_RTP,
3819 rtc::Socket::Option::OPT_RCVBUF, 8000);
3820
3821 int option_val;
3822 EXPECT_TRUE(session_->video_channel()->transport_channel()->GetOption(
3823 rtc::Socket::Option::OPT_SNDBUF, &option_val));
3824 EXPECT_EQ(4000, option_val);
3825 EXPECT_FALSE(session_->voice_channel()->transport_channel()->GetOption(
3826 rtc::Socket::Option::OPT_SNDBUF, &option_val));
3827
3828 EXPECT_TRUE(session_->voice_channel()->transport_channel()->GetOption(
3829 rtc::Socket::Option::OPT_RCVBUF, &option_val));
3830 EXPECT_EQ(8000, option_val);
3831 EXPECT_FALSE(session_->video_channel()->transport_channel()->GetOption(
3832 rtc::Socket::Option::OPT_RCVBUF, &option_val));
3833
3834 EXPECT_NE(session_->voice_channel()->transport_channel(),
3835 session_->video_channel()->transport_channel());
3836
3837 mediastream_signaling_.SendAudioVideoStream2();
3838 SessionDescriptionInterface* answer =
3839 CreateRemoteAnswer(session_->local_description());
3840 SetRemoteDescriptionWithoutError(answer);
3841
3842 EXPECT_TRUE(session_->voice_channel()->transport_channel()->GetOption(
3843 rtc::Socket::Option::OPT_SNDBUF, &option_val));
3844 EXPECT_EQ(4000, option_val);
3845
3846 EXPECT_TRUE(session_->voice_channel()->transport_channel()->GetOption(
3847 rtc::Socket::Option::OPT_RCVBUF, &option_val));
3848 EXPECT_EQ(8000, option_val);
3849}
3850
tommi0f620f42015-07-09 03:25:02 -07003851// Test creating a session, request multiple offers, destroy the session
3852// and make sure we got success/failure callbacks for all of the requests.
3853// Background: crbug.com/507307
3854TEST_F(WebRtcSessionTest, CreateOffersAndShutdown) {
3855 Init();
3856
3857 rtc::scoped_refptr<WebRtcSessionCreateSDPObserverForTest> observers[100];
3858 PeerConnectionInterface::RTCOfferAnswerOptions options;
3859 options.offer_to_receive_audio =
3860 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
3861
3862 for (auto& o : observers) {
3863 o = new WebRtcSessionCreateSDPObserverForTest();
3864 session_->CreateOffer(o, options);
3865 }
3866
3867 session_.reset();
3868
3869 // Make sure we process pending messages on the current (signaling) thread
3870 // before checking we we got our callbacks. Quit() will do this and then
3871 // immediately exit. We won't need the queue after this point anyway.
3872 rtc::Thread::Current()->Quit();
3873
3874 for (auto& o : observers) {
3875 // We expect to have received a notification now even if the session was
3876 // terminated. The offer creation may or may not have succeeded, but we
3877 // must have received a notification which, so the only invalid state
3878 // is kInit.
3879 EXPECT_NE(WebRtcSessionCreateSDPObserverForTest::kInit, o->state());
3880 }
3881}
3882
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003883// TODO(bemasc): Add a TestIceStatesBundle with BUNDLE enabled. That test
3884// currently fails because upon disconnection and reconnection OnIceComplete is
3885// called more than once without returning to IceGatheringGathering.