blob: 8bd97e59ce5f6b67a681ada2454cefada0065e21 [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
Henrik Boström87713d02015-08-25 09:53:21 +0200159enum RTCCertificateGenerationMethod { ALREADY_GENERATED, DTLS_IDENTITY_STORE };
160
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000161// Add some extra |newlines| to the |message| after |line|.
162static void InjectAfter(const std::string& line,
163 const std::string& newlines,
164 std::string* message) {
165 const std::string tmp = line + newlines;
torbjornga81a42f2015-09-23 02:16:58 -0700166 rtc::replace_substrs(line.c_str(), line.length(),
167 tmp.c_str(), tmp.length(), message);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000168}
169
170class MockIceObserver : public webrtc::IceObserver {
171 public:
172 MockIceObserver()
173 : oncandidatesready_(false),
174 ice_connection_state_(PeerConnectionInterface::kIceConnectionNew),
175 ice_gathering_state_(PeerConnectionInterface::kIceGatheringNew) {
176 }
177
178 virtual void OnIceConnectionChange(
179 PeerConnectionInterface::IceConnectionState new_state) {
180 ice_connection_state_ = new_state;
181 }
182 virtual void OnIceGatheringChange(
183 PeerConnectionInterface::IceGatheringState new_state) {
184 // We can never transition back to "new".
185 EXPECT_NE(PeerConnectionInterface::kIceGatheringNew, new_state);
186 ice_gathering_state_ = new_state;
187
188 // oncandidatesready_ really means "ICE gathering is complete".
189 // This if statement ensures that this value remains correct when we
190 // transition from kIceGatheringComplete to kIceGatheringGathering.
191 if (new_state == PeerConnectionInterface::kIceGatheringGathering) {
192 oncandidatesready_ = false;
193 }
194 }
195
196 // Found a new candidate.
197 virtual void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) {
wu@webrtc.org364f2042013-11-20 21:49:41 +0000198 switch (candidate->sdp_mline_index()) {
199 case kMediaContentIndex0:
200 mline_0_candidates_.push_back(candidate->candidate());
201 break;
202 case kMediaContentIndex1:
203 mline_1_candidates_.push_back(candidate->candidate());
204 break;
205 default:
206 ASSERT(false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000207 }
wu@webrtc.org364f2042013-11-20 21:49:41 +0000208
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000209 // The ICE gathering state should always be Gathering when a candidate is
210 // received (or possibly Completed in the case of the final candidate).
211 EXPECT_NE(PeerConnectionInterface::kIceGatheringNew, ice_gathering_state_);
212 }
213
214 // TODO(bemasc): Remove this once callers transition to OnIceGatheringChange.
215 virtual void OnIceComplete() {
216 EXPECT_FALSE(oncandidatesready_);
217 oncandidatesready_ = true;
218
219 // OnIceGatheringChange(IceGatheringCompleted) and OnIceComplete() should
220 // be called approximately simultaneously. For ease of testing, this
221 // check additionally requires that they be called in the above order.
222 EXPECT_EQ(PeerConnectionInterface::kIceGatheringComplete,
223 ice_gathering_state_);
224 }
225
226 bool oncandidatesready_;
227 std::vector<cricket::Candidate> mline_0_candidates_;
228 std::vector<cricket::Candidate> mline_1_candidates_;
229 PeerConnectionInterface::IceConnectionState ice_connection_state_;
230 PeerConnectionInterface::IceGatheringState ice_gathering_state_;
231};
232
233class WebRtcSessionForTest : public webrtc::WebRtcSession {
234 public:
235 WebRtcSessionForTest(cricket::ChannelManager* cmgr,
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000236 rtc::Thread* signaling_thread,
237 rtc::Thread* worker_thread,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000238 cricket::PortAllocator* port_allocator,
239 webrtc::IceObserver* ice_observer,
240 webrtc::MediaStreamSignaling* mediastream_signaling)
241 : WebRtcSession(cmgr, signaling_thread, worker_thread, port_allocator,
242 mediastream_signaling) {
243 RegisterIceObserver(ice_observer);
244 }
245 virtual ~WebRtcSessionForTest() {}
246
torbjornga81a42f2015-09-23 02:16:58 -0700247 using cricket::BaseSession::GetTransportProxy;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000248 using webrtc::WebRtcSession::SetAudioPlayout;
249 using webrtc::WebRtcSession::SetAudioSend;
250 using webrtc::WebRtcSession::SetCaptureDevice;
251 using webrtc::WebRtcSession::SetVideoPlayout;
252 using webrtc::WebRtcSession::SetVideoSend;
253};
254
wu@webrtc.org91053e72013-08-10 07:18:04 +0000255class WebRtcSessionCreateSDPObserverForTest
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000256 : public rtc::RefCountedObject<CreateSessionDescriptionObserver> {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000257 public:
wu@webrtc.org91053e72013-08-10 07:18:04 +0000258 enum State {
259 kInit,
260 kFailed,
261 kSucceeded,
262 };
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000263 WebRtcSessionCreateSDPObserverForTest() : state_(kInit) {}
wu@webrtc.org91053e72013-08-10 07:18:04 +0000264
265 // CreateSessionDescriptionObserver implementation.
266 virtual void OnSuccess(SessionDescriptionInterface* desc) {
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000267 description_.reset(desc);
wu@webrtc.org91053e72013-08-10 07:18:04 +0000268 state_ = kSucceeded;
269 }
270 virtual void OnFailure(const std::string& error) {
271 state_ = kFailed;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000272 }
273
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000274 SessionDescriptionInterface* description() { return description_.get(); }
275
276 SessionDescriptionInterface* ReleaseDescription() {
277 return description_.release();
278 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000279
wu@webrtc.org91053e72013-08-10 07:18:04 +0000280 State state() const { return state_; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000281
wu@webrtc.org91053e72013-08-10 07:18:04 +0000282 protected:
283 ~WebRtcSessionCreateSDPObserverForTest() {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000284
285 private:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000286 rtc::scoped_ptr<SessionDescriptionInterface> description_;
wu@webrtc.org91053e72013-08-10 07:18:04 +0000287 State state_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000288};
289
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000290class FakeAudioRenderer : public cricket::AudioRenderer {
291 public:
henrike@webrtc.orga7b98182014-02-21 15:51:43 +0000292 FakeAudioRenderer() : channel_id_(-1), sink_(NULL) {}
293 virtual ~FakeAudioRenderer() {
294 if (sink_)
295 sink_->OnClose();
296 }
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000297
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000298 void AddChannel(int channel_id) override {
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000299 ASSERT(channel_id_ == -1);
300 channel_id_ = channel_id;
301 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000302 void RemoveChannel(int channel_id) override {
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000303 ASSERT(channel_id == channel_id_);
304 channel_id_ = -1;
305 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000306 void SetSink(Sink* sink) override { sink_ = sink; }
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000307
308 int channel_id() const { return channel_id_; }
henrike@webrtc.orga7b98182014-02-21 15:51:43 +0000309 cricket::AudioRenderer::Sink* sink() const { return sink_; }
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000310 private:
311 int channel_id_;
henrike@webrtc.orga7b98182014-02-21 15:51:43 +0000312 cricket::AudioRenderer::Sink* sink_;
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000313};
314
Henrik Boström87713d02015-08-25 09:53:21 +0200315class WebRtcSessionTest
316 : public testing::TestWithParam<RTCCertificateGenerationMethod> {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000317 protected:
318 // TODO Investigate why ChannelManager crashes, if it's created
319 // after stun_server.
320 WebRtcSessionTest()
321 : media_engine_(new cricket::FakeMediaEngine()),
322 data_engine_(new cricket::FakeDataEngine()),
323 device_manager_(new cricket::FakeDeviceManager()),
324 channel_manager_(new cricket::ChannelManager(
325 media_engine_, data_engine_, device_manager_,
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000326 new cricket::CaptureManager(), rtc::Thread::Current())),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000327 tdesc_factory_(new cricket::TransportDescriptionFactory()),
328 desc_factory_(new cricket::MediaSessionDescriptionFactory(
329 channel_manager_.get(), tdesc_factory_.get())),
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000330 pss_(new rtc::PhysicalSocketServer),
331 vss_(new rtc::VirtualSocketServer(pss_.get())),
332 fss_(new rtc::FirewallSocketServer(vss_.get())),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000333 ss_scope_(fss_.get()),
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000334 stun_socket_addr_(rtc::SocketAddress(kStunAddrHost,
wu@webrtc.org364f2042013-11-20 21:49:41 +0000335 cricket::STUN_SERVER_PORT)),
jiayl@webrtc.orgbebc75e2014-09-26 23:01:11 +0000336 stun_server_(cricket::TestStunServer::Create(Thread::Current(),
337 stun_socket_addr_)),
buildbot@webrtc.org41451d42014-05-03 05:39:45 +0000338 turn_server_(Thread::Current(), kTurnUdpIntAddr, kTurnUdpExtAddr),
jbauchac8869e2015-07-03 01:36:14 -0700339 mediastream_signaling_(channel_manager_.get()),
340 metrics_observer_(new rtc::RefCountedObject<FakeMetricsObserver>()) {
buildbot@webrtc.org51c55082014-07-28 22:26:15 +0000341 cricket::ServerAddresses stun_servers;
342 stun_servers.insert(stun_socket_addr_);
343 allocator_.reset(new cricket::BasicPortAllocator(
344 &network_manager_,
345 stun_servers,
346 SocketAddress(), SocketAddress(), SocketAddress()));
buildbot@webrtc.org41451d42014-05-03 05:39:45 +0000347 allocator_->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700348 cricket::PORTALLOCATOR_DISABLE_RELAY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000349 EXPECT_TRUE(channel_manager_->Init());
350 desc_factory_->set_add_legacy_streams(false);
buildbot@webrtc.org41451d42014-05-03 05:39:45 +0000351 allocator_->set_step_delay(cricket::kMinimumStepDelay);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000352 }
353
354 void AddInterface(const SocketAddress& addr) {
355 network_manager_.AddInterface(addr);
356 }
357
Henrik Boström87713d02015-08-25 09:53:21 +0200358 // If |dtls_identity_store| != null or |rtc_configuration| contains
359 // |certificates| then DTLS will be enabled unless explicitly disabled by
360 // |rtc_configuration| options. When DTLS is enabled a certificate will be
361 // used if provided, otherwise one will be generated using the
362 // |dtls_identity_store|.
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000363 void Init(
Henrik Boström5e56c592015-08-11 10:33:13 +0200364 rtc::scoped_ptr<webrtc::DtlsIdentityStoreInterface> dtls_identity_store,
Henrik Lundin64dad832015-05-11 12:44:23 +0200365 const PeerConnectionInterface::RTCConfiguration& rtc_configuration) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000366 ASSERT_TRUE(session_.get() == NULL);
367 session_.reset(new WebRtcSessionForTest(
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000368 channel_manager_.get(), rtc::Thread::Current(),
369 rtc::Thread::Current(), allocator_.get(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000370 &observer_,
371 &mediastream_signaling_));
372
373 EXPECT_EQ(PeerConnectionInterface::kIceConnectionNew,
374 observer_.ice_connection_state_);
375 EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
376 observer_.ice_gathering_state_);
377
torbjornga81a42f2015-09-23 02:16:58 -0700378 EXPECT_TRUE(session_->Initialize(
379 options_, constraints_.get(), dtls_identity_store.Pass(),
380 rtc_configuration));
jbauchac8869e2015-07-03 01:36:14 -0700381 session_->set_metrics_observer(metrics_observer_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000382 }
383
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000384 void Init() {
Henrik Lundin64dad832015-05-11 12:44:23 +0200385 PeerConnectionInterface::RTCConfiguration configuration;
Henrik Boström5e56c592015-08-11 10:33:13 +0200386 Init(nullptr, configuration);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000387 }
388
389 void InitWithIceTransport(
390 PeerConnectionInterface::IceTransportsType ice_transport_type) {
Henrik Lundin64dad832015-05-11 12:44:23 +0200391 PeerConnectionInterface::RTCConfiguration configuration;
392 configuration.type = ice_transport_type;
Henrik Boström5e56c592015-08-11 10:33:13 +0200393 Init(nullptr, configuration);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000394 }
395
396 void InitWithBundlePolicy(
397 PeerConnectionInterface::BundlePolicy bundle_policy) {
Henrik Lundin64dad832015-05-11 12:44:23 +0200398 PeerConnectionInterface::RTCConfiguration configuration;
Henrik Lundin64dad832015-05-11 12:44:23 +0200399 configuration.bundle_policy = bundle_policy;
Henrik Boström5e56c592015-08-11 10:33:13 +0200400 Init(nullptr, configuration);
Peter Thatcheraf55ccc2015-05-21 07:48:41 -0700401 }
402
403 void InitWithRtcpMuxPolicy(
404 PeerConnectionInterface::RtcpMuxPolicy rtcp_mux_policy) {
405 PeerConnectionInterface::RTCConfiguration configuration;
406 configuration.rtcp_mux_policy = rtcp_mux_policy;
Henrik Boström5e56c592015-08-11 10:33:13 +0200407 Init(nullptr, configuration);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000408 }
409
Henrik Boström87713d02015-08-25 09:53:21 +0200410 // Successfully init with DTLS; with a certificate generated and supplied or
411 // with a store that generates it for us.
412 void InitWithDtls(RTCCertificateGenerationMethod cert_gen_method) {
413 rtc::scoped_ptr<FakeDtlsIdentityStore> dtls_identity_store;
414 PeerConnectionInterface::RTCConfiguration configuration;
415 if (cert_gen_method == ALREADY_GENERATED) {
416 configuration.certificates.push_back(
417 FakeDtlsIdentityStore::GenerateCertificate());
418 } else if (cert_gen_method == DTLS_IDENTITY_STORE) {
419 dtls_identity_store.reset(new FakeDtlsIdentityStore());
420 dtls_identity_store->set_should_fail(false);
421 } else {
henrikg91d6ede2015-09-17 00:24:34 -0700422 RTC_CHECK(false);
Henrik Boström87713d02015-08-25 09:53:21 +0200423 }
424 Init(dtls_identity_store.Pass(), configuration);
425 }
426
427 // Init with DTLS with a store that will fail to generate a certificate.
428 void InitWithDtlsIdentityGenFail() {
Henrik Boström5e56c592015-08-11 10:33:13 +0200429 rtc::scoped_ptr<FakeDtlsIdentityStore> dtls_identity_store(
430 new FakeDtlsIdentityStore());
Henrik Boström87713d02015-08-25 09:53:21 +0200431 dtls_identity_store->set_should_fail(true);
Henrik Lundin64dad832015-05-11 12:44:23 +0200432 PeerConnectionInterface::RTCConfiguration configuration;
Henrik Boström5e56c592015-08-11 10:33:13 +0200433 Init(dtls_identity_store.Pass(), configuration);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000434 }
435
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000436 void InitWithDtmfCodec() {
437 // Add kTelephoneEventCodec for dtmf test.
wu@webrtc.org364f2042013-11-20 21:49:41 +0000438 const cricket::AudioCodec kTelephoneEventCodec(
439 106, "telephone-event", 8000, 0, 1, 0);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000440 std::vector<cricket::AudioCodec> codecs;
441 codecs.push_back(kTelephoneEventCodec);
442 media_engine_->SetAudioCodecs(codecs);
443 desc_factory_->set_audio_codecs(codecs);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000444 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000445 }
446
447 // Creates a local offer and applies it. Starts ice.
448 // Call mediastream_signaling_.UseOptionsWithStreamX() before this function
449 // to decide which streams to create.
450 void InitiateCall() {
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +0000451 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000452 SetLocalDescriptionWithoutError(offer);
453 EXPECT_TRUE_WAIT(PeerConnectionInterface::kIceGatheringNew !=
454 observer_.ice_gathering_state_,
455 kIceCandidatesTimeout);
456 }
457
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +0000458 SessionDescriptionInterface* CreateOffer() {
459 PeerConnectionInterface::RTCOfferAnswerOptions options;
460 options.offer_to_receive_audio =
461 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
462
463 return CreateOffer(options);
464 }
465
wu@webrtc.org91053e72013-08-10 07:18:04 +0000466 SessionDescriptionInterface* CreateOffer(
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +0000467 const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000468 rtc::scoped_refptr<WebRtcSessionCreateSDPObserverForTest>
wu@webrtc.org91053e72013-08-10 07:18:04 +0000469 observer = new WebRtcSessionCreateSDPObserverForTest();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +0000470 session_->CreateOffer(observer, options);
wu@webrtc.org91053e72013-08-10 07:18:04 +0000471 EXPECT_TRUE_WAIT(
472 observer->state() != WebRtcSessionCreateSDPObserverForTest::kInit,
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000473 2000);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000474 return observer->ReleaseDescription();
wu@webrtc.org91053e72013-08-10 07:18:04 +0000475 }
476
477 SessionDescriptionInterface* CreateAnswer(
478 const webrtc::MediaConstraintsInterface* constraints) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000479 rtc::scoped_refptr<WebRtcSessionCreateSDPObserverForTest> observer
wu@webrtc.org91053e72013-08-10 07:18:04 +0000480 = new WebRtcSessionCreateSDPObserverForTest();
481 session_->CreateAnswer(observer, constraints);
482 EXPECT_TRUE_WAIT(
483 observer->state() != WebRtcSessionCreateSDPObserverForTest::kInit,
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000484 2000);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000485 return observer->ReleaseDescription();
wu@webrtc.org91053e72013-08-10 07:18:04 +0000486 }
487
wu@webrtc.org364f2042013-11-20 21:49:41 +0000488 bool ChannelsExist() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000489 return (session_->voice_channel() != NULL &&
490 session_->video_channel() != NULL);
491 }
492
torbjornga81a42f2015-09-23 02:16:58 -0700493 void CheckTransportChannels() const {
494 EXPECT_TRUE(session_->GetChannel(cricket::CN_AUDIO, 1) != NULL);
495 EXPECT_TRUE(session_->GetChannel(cricket::CN_AUDIO, 2) != NULL);
496 EXPECT_TRUE(session_->GetChannel(cricket::CN_VIDEO, 1) != NULL);
497 EXPECT_TRUE(session_->GetChannel(cricket::CN_VIDEO, 2) != NULL);
498 }
499
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000500 void VerifyCryptoParams(const cricket::SessionDescription* sdp) {
501 ASSERT_TRUE(session_.get() != NULL);
502 const cricket::ContentInfo* content = cricket::GetFirstAudioContent(sdp);
503 ASSERT_TRUE(content != NULL);
504 const cricket::AudioContentDescription* audio_content =
505 static_cast<const cricket::AudioContentDescription*>(
506 content->description);
507 ASSERT_TRUE(audio_content != NULL);
508 ASSERT_EQ(1U, audio_content->cryptos().size());
509 ASSERT_EQ(47U, audio_content->cryptos()[0].key_params.size());
510 ASSERT_EQ("AES_CM_128_HMAC_SHA1_80",
511 audio_content->cryptos()[0].cipher_suite);
512 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf),
513 audio_content->protocol());
514
515 content = cricket::GetFirstVideoContent(sdp);
516 ASSERT_TRUE(content != NULL);
517 const cricket::VideoContentDescription* video_content =
518 static_cast<const cricket::VideoContentDescription*>(
519 content->description);
520 ASSERT_TRUE(video_content != NULL);
521 ASSERT_EQ(1U, video_content->cryptos().size());
522 ASSERT_EQ("AES_CM_128_HMAC_SHA1_80",
523 video_content->cryptos()[0].cipher_suite);
524 ASSERT_EQ(47U, video_content->cryptos()[0].key_params.size());
525 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf),
526 video_content->protocol());
527 }
528
529 void VerifyNoCryptoParams(const cricket::SessionDescription* sdp, bool dtls) {
530 const cricket::ContentInfo* content = cricket::GetFirstAudioContent(sdp);
531 ASSERT_TRUE(content != NULL);
532 const cricket::AudioContentDescription* audio_content =
533 static_cast<const cricket::AudioContentDescription*>(
534 content->description);
535 ASSERT_TRUE(audio_content != NULL);
536 ASSERT_EQ(0U, audio_content->cryptos().size());
537
538 content = cricket::GetFirstVideoContent(sdp);
539 ASSERT_TRUE(content != NULL);
540 const cricket::VideoContentDescription* video_content =
541 static_cast<const cricket::VideoContentDescription*>(
542 content->description);
543 ASSERT_TRUE(video_content != NULL);
544 ASSERT_EQ(0U, video_content->cryptos().size());
545
546 if (dtls) {
deadbeeff3938292015-07-15 12:20:53 -0700547 EXPECT_EQ(std::string(cricket::kMediaProtocolDtlsSavpf),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000548 audio_content->protocol());
deadbeeff3938292015-07-15 12:20:53 -0700549 EXPECT_EQ(std::string(cricket::kMediaProtocolDtlsSavpf),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000550 video_content->protocol());
551 } else {
552 EXPECT_EQ(std::string(cricket::kMediaProtocolAvpf),
553 audio_content->protocol());
554 EXPECT_EQ(std::string(cricket::kMediaProtocolAvpf),
555 video_content->protocol());
556 }
557 }
558
559 // Set the internal fake description factories to do DTLS-SRTP.
560 void SetFactoryDtlsSrtp() {
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000561 desc_factory_->set_secure(cricket::SEC_DISABLED);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000562 std::string identity_name = "WebRTC" +
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000563 rtc::ToString(rtc::CreateRandomId());
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200564 // Confirmed to work with KT_RSA and KT_ECDSA.
Henrik Boström3a14bf32015-08-31 09:27:58 +0200565 tdesc_factory_->set_certificate(rtc::RTCCertificate::Create(
566 rtc::scoped_ptr<rtc::SSLIdentity>(rtc::SSLIdentity::Generate(
567 identity_name, rtc::KT_DEFAULT)).Pass()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000568 tdesc_factory_->set_secure(cricket::SEC_REQUIRED);
569 }
570
571 void VerifyFingerprintStatus(const cricket::SessionDescription* sdp,
572 bool expected) {
573 const TransportInfo* audio = sdp->GetTransportInfoByName("audio");
574 ASSERT_TRUE(audio != NULL);
575 ASSERT_EQ(expected, audio->description.identity_fingerprint.get() != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000576 const TransportInfo* video = sdp->GetTransportInfoByName("video");
577 ASSERT_TRUE(video != NULL);
578 ASSERT_EQ(expected, video->description.identity_fingerprint.get() != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000579 }
580
581 void VerifyAnswerFromNonCryptoOffer() {
jiayl@webrtc.org7d4891d2014-09-09 21:43:15 +0000582 // Create an SDP without Crypto.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000583 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +0000584 options.recv_video = true;
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000585 JsepSessionDescription* offer(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000586 CreateRemoteOffer(options, cricket::SEC_DISABLED));
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000587 ASSERT_TRUE(offer != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000588 VerifyNoCryptoParams(offer->description(), false);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000589 SetRemoteDescriptionOfferExpectError(kSdpWithoutSdesCrypto,
590 offer);
wu@webrtc.org91053e72013-08-10 07:18:04 +0000591 const webrtc::SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000592 // Answer should be NULL as no crypto params in offer.
593 ASSERT_TRUE(answer == NULL);
594 }
595
596 void VerifyAnswerFromCryptoOffer() {
597 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +0000598 options.recv_video = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000599 options.bundle_enabled = true;
600 scoped_ptr<JsepSessionDescription> offer(
601 CreateRemoteOffer(options, cricket::SEC_REQUIRED));
602 ASSERT_TRUE(offer.get() != NULL);
603 VerifyCryptoParams(offer->description());
604 SetRemoteDescriptionWithoutError(offer.release());
wu@webrtc.org91053e72013-08-10 07:18:04 +0000605 scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000606 ASSERT_TRUE(answer.get() != NULL);
607 VerifyCryptoParams(answer->description());
608 }
609
buildbot@webrtc.org53df88c2014-08-07 22:46:01 +0000610 void SetAndVerifyNumUnsignalledRecvStreams(
611 int value_set, int value_expected) {
612 constraints_.reset(new FakeConstraints());
613 constraints_->AddOptional(
614 webrtc::MediaConstraintsInterface::kNumUnsignalledRecvStreams,
615 value_set);
616 session_.reset();
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000617 Init();
buildbot@webrtc.org53df88c2014-08-07 22:46:01 +0000618 mediastream_signaling_.SendAudioVideoStream1();
619 SessionDescriptionInterface* offer = CreateOffer();
620
621 SetLocalDescriptionWithoutError(offer);
622
623 video_channel_ = media_engine_->GetVideoChannel(0);
624
625 ASSERT_TRUE(video_channel_ != NULL);
solenberg66f43392015-09-09 01:36:22 -0700626 const cricket::VideoOptions& video_options = video_channel_->options();
buildbot@webrtc.org53df88c2014-08-07 22:46:01 +0000627 EXPECT_EQ(value_expected,
628 video_options.unsignalled_recv_stream_limit.GetWithDefaultIfUnset(-1));
629 }
630
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000631 void CompareIceUfragAndPassword(const cricket::SessionDescription* desc1,
632 const cricket::SessionDescription* desc2,
633 bool expect_equal) {
634 if (desc1->contents().size() != desc2->contents().size()) {
635 EXPECT_FALSE(expect_equal);
636 return;
637 }
638
639 const cricket::ContentInfos& contents = desc1->contents();
640 cricket::ContentInfos::const_iterator it = contents.begin();
641
642 for (; it != contents.end(); ++it) {
643 const cricket::TransportDescription* transport_desc1 =
644 desc1->GetTransportDescriptionByName(it->name);
645 const cricket::TransportDescription* transport_desc2 =
646 desc2->GetTransportDescriptionByName(it->name);
647 if (!transport_desc1 || !transport_desc2) {
648 EXPECT_FALSE(expect_equal);
649 return;
650 }
651 if (transport_desc1->ice_pwd != transport_desc2->ice_pwd ||
652 transport_desc1->ice_ufrag != transport_desc2->ice_ufrag) {
653 EXPECT_FALSE(expect_equal);
654 return;
655 }
656 }
657 EXPECT_TRUE(expect_equal);
658 }
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000659
660 void RemoveIceUfragPwdLines(const SessionDescriptionInterface* current_desc,
661 std::string *sdp) {
662 const cricket::SessionDescription* desc = current_desc->description();
663 EXPECT_TRUE(current_desc->ToString(sdp));
664
665 const cricket::ContentInfos& contents = desc->contents();
666 cricket::ContentInfos::const_iterator it = contents.begin();
667 // Replace ufrag and pwd lines with empty 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";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000675 rtc::replace_substrs(ufrag_line.c_str(), ufrag_line.length(),
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000676 "", 0,
677 sdp);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000678 rtc::replace_substrs(pwd_line.c_str(), pwd_line.length(),
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000679 "", 0,
680 sdp);
681 }
682 }
683
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +0000684 void ModifyIceUfragPwdLines(const SessionDescriptionInterface* current_desc,
685 const std::string& modified_ice_ufrag,
686 const std::string& modified_ice_pwd,
687 std::string* sdp) {
688 const cricket::SessionDescription* desc = current_desc->description();
689 EXPECT_TRUE(current_desc->ToString(sdp));
690
691 const cricket::ContentInfos& contents = desc->contents();
692 cricket::ContentInfos::const_iterator it = contents.begin();
693 // Replace ufrag and pwd lines with |modified_ice_ufrag| and
694 // |modified_ice_pwd| strings.
695 for (; it != contents.end(); ++it) {
696 const cricket::TransportDescription* transport_desc =
697 desc->GetTransportDescriptionByName(it->name);
698 std::string ufrag_line = "a=ice-ufrag:" + transport_desc->ice_ufrag
699 + "\r\n";
700 std::string pwd_line = "a=ice-pwd:" + transport_desc->ice_pwd
701 + "\r\n";
702 std::string mod_ufrag = "a=ice-ufrag:" + modified_ice_ufrag + "\r\n";
703 std::string mod_pwd = "a=ice-pwd:" + modified_ice_pwd + "\r\n";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000704 rtc::replace_substrs(ufrag_line.c_str(), ufrag_line.length(),
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +0000705 mod_ufrag.c_str(), mod_ufrag.length(),
706 sdp);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000707 rtc::replace_substrs(pwd_line.c_str(), pwd_line.length(),
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +0000708 mod_pwd.c_str(), mod_pwd.length(),
709 sdp);
710 }
711 }
712
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000713 // Creates a remote offer and and applies it as a remote description,
714 // creates a local answer and applies is as a local description.
715 // Call mediastream_signaling_.UseOptionsWithStreamX() before this function
716 // to decide which local and remote streams to create.
717 void CreateAndSetRemoteOfferAndLocalAnswer() {
718 SessionDescriptionInterface* offer = CreateRemoteOffer();
719 SetRemoteDescriptionWithoutError(offer);
wu@webrtc.org91053e72013-08-10 07:18:04 +0000720 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000721 SetLocalDescriptionWithoutError(answer);
722 }
723 void SetLocalDescriptionWithoutError(SessionDescriptionInterface* desc) {
724 EXPECT_TRUE(session_->SetLocalDescription(desc, NULL));
725 }
726 void SetLocalDescriptionExpectState(SessionDescriptionInterface* desc,
727 BaseSession::State expected_state) {
728 SetLocalDescriptionWithoutError(desc);
729 EXPECT_EQ(expected_state, session_->state());
730 }
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000731 void SetLocalDescriptionExpectError(const std::string& action,
732 const std::string& expected_error,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000733 SessionDescriptionInterface* desc) {
734 std::string error;
735 EXPECT_FALSE(session_->SetLocalDescription(desc, &error));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000736 std::string sdp_type = "local ";
737 sdp_type.append(action);
738 EXPECT_NE(std::string::npos, error.find(sdp_type));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000739 EXPECT_NE(std::string::npos, error.find(expected_error));
740 }
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000741 void SetLocalDescriptionOfferExpectError(const std::string& expected_error,
742 SessionDescriptionInterface* desc) {
743 SetLocalDescriptionExpectError(SessionDescriptionInterface::kOffer,
744 expected_error, desc);
745 }
746 void SetLocalDescriptionAnswerExpectError(const std::string& expected_error,
747 SessionDescriptionInterface* desc) {
748 SetLocalDescriptionExpectError(SessionDescriptionInterface::kAnswer,
749 expected_error, desc);
750 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000751 void SetRemoteDescriptionWithoutError(SessionDescriptionInterface* desc) {
752 EXPECT_TRUE(session_->SetRemoteDescription(desc, NULL));
753 }
754 void SetRemoteDescriptionExpectState(SessionDescriptionInterface* desc,
755 BaseSession::State expected_state) {
756 SetRemoteDescriptionWithoutError(desc);
757 EXPECT_EQ(expected_state, session_->state());
758 }
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000759 void SetRemoteDescriptionExpectError(const std::string& action,
760 const std::string& expected_error,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000761 SessionDescriptionInterface* desc) {
762 std::string error;
763 EXPECT_FALSE(session_->SetRemoteDescription(desc, &error));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000764 std::string sdp_type = "remote ";
765 sdp_type.append(action);
766 EXPECT_NE(std::string::npos, error.find(sdp_type));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000767 EXPECT_NE(std::string::npos, error.find(expected_error));
768 }
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000769 void SetRemoteDescriptionOfferExpectError(
770 const std::string& expected_error, SessionDescriptionInterface* desc) {
771 SetRemoteDescriptionExpectError(SessionDescriptionInterface::kOffer,
772 expected_error, desc);
773 }
774 void SetRemoteDescriptionPranswerExpectError(
775 const std::string& expected_error, SessionDescriptionInterface* desc) {
776 SetRemoteDescriptionExpectError(SessionDescriptionInterface::kPrAnswer,
777 expected_error, desc);
778 }
779 void SetRemoteDescriptionAnswerExpectError(
780 const std::string& expected_error, SessionDescriptionInterface* desc) {
781 SetRemoteDescriptionExpectError(SessionDescriptionInterface::kAnswer,
782 expected_error, desc);
783 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000784
785 void CreateCryptoOfferAndNonCryptoAnswer(SessionDescriptionInterface** offer,
786 SessionDescriptionInterface** nocrypto_answer) {
787 // Create a SDP without Crypto.
788 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +0000789 options.recv_video = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000790 options.bundle_enabled = true;
791 *offer = CreateRemoteOffer(options, cricket::SEC_ENABLED);
792 ASSERT_TRUE(*offer != NULL);
793 VerifyCryptoParams((*offer)->description());
794
795 *nocrypto_answer = CreateRemoteAnswer(*offer, options,
796 cricket::SEC_DISABLED);
797 EXPECT_TRUE(*nocrypto_answer != NULL);
798 }
799
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000800 void CreateDtlsOfferAndNonDtlsAnswer(SessionDescriptionInterface** offer,
801 SessionDescriptionInterface** nodtls_answer) {
802 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +0000803 options.recv_video = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000804 options.bundle_enabled = true;
805
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000806 rtc::scoped_ptr<SessionDescriptionInterface> temp_offer(
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000807 CreateRemoteOffer(options, cricket::SEC_ENABLED));
808
809 *nodtls_answer =
810 CreateRemoteAnswer(temp_offer.get(), options, cricket::SEC_ENABLED);
811 EXPECT_TRUE(*nodtls_answer != NULL);
812 VerifyFingerprintStatus((*nodtls_answer)->description(), false);
813 VerifyCryptoParams((*nodtls_answer)->description());
814
815 SetFactoryDtlsSrtp();
816 *offer = CreateRemoteOffer(options, cricket::SEC_ENABLED);
817 ASSERT_TRUE(*offer != NULL);
818 VerifyFingerprintStatus((*offer)->description(), true);
819 VerifyCryptoParams((*offer)->description());
820 }
821
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000822 JsepSessionDescription* CreateRemoteOfferWithVersion(
823 cricket::MediaSessionOptions options,
824 cricket::SecurePolicy secure_policy,
825 const std::string& session_version,
826 const SessionDescriptionInterface* current_desc) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000827 std::string session_id = rtc::ToString(rtc::CreateRandomId64());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000828 const cricket::SessionDescription* cricket_desc = NULL;
829 if (current_desc) {
830 cricket_desc = current_desc->description();
831 session_id = current_desc->session_id();
832 }
833
834 desc_factory_->set_secure(secure_policy);
835 JsepSessionDescription* offer(
836 new JsepSessionDescription(JsepSessionDescription::kOffer));
837 if (!offer->Initialize(desc_factory_->CreateOffer(options, cricket_desc),
838 session_id, session_version)) {
839 delete offer;
840 offer = NULL;
841 }
842 return offer;
843 }
844 JsepSessionDescription* CreateRemoteOffer(
845 cricket::MediaSessionOptions options) {
846 return CreateRemoteOfferWithVersion(options, cricket::SEC_ENABLED,
847 kSessionVersion, NULL);
848 }
849 JsepSessionDescription* CreateRemoteOffer(
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000850 cricket::MediaSessionOptions options, cricket::SecurePolicy sdes_policy) {
851 return CreateRemoteOfferWithVersion(
852 options, sdes_policy, kSessionVersion, NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000853 }
854 JsepSessionDescription* CreateRemoteOffer(
855 cricket::MediaSessionOptions options,
856 const SessionDescriptionInterface* current_desc) {
857 return CreateRemoteOfferWithVersion(options, cricket::SEC_ENABLED,
858 kSessionVersion, current_desc);
859 }
860
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000861 JsepSessionDescription* CreateRemoteOfferWithSctpPort(
862 const char* sctp_stream_name, int new_port,
863 cricket::MediaSessionOptions options) {
864 options.data_channel_type = cricket::DCT_SCTP;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +0000865 options.AddSendStream(cricket::MEDIA_TYPE_DATA, "datachannel",
866 sctp_stream_name);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000867 return ChangeSDPSctpPort(new_port, CreateRemoteOffer(options));
868 }
869
870 // Takes ownership of offer_basis (and deletes it).
871 JsepSessionDescription* ChangeSDPSctpPort(
872 int new_port, webrtc::SessionDescriptionInterface *offer_basis) {
873 // Stringify the input SDP, swap the 5000 for 'new_port' and create a new
874 // SessionDescription from the mutated string.
875 const char* default_port_str = "5000";
876 char new_port_str[16];
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000877 rtc::sprintfn(new_port_str, sizeof(new_port_str), "%d", new_port);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000878 std::string offer_str;
879 offer_basis->ToString(&offer_str);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000880 rtc::replace_substrs(default_port_str, strlen(default_port_str),
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000881 new_port_str, strlen(new_port_str),
882 &offer_str);
883 JsepSessionDescription* offer = new JsepSessionDescription(
884 offer_basis->type());
885 delete offer_basis;
886 offer->Initialize(offer_str, NULL);
887 return offer;
888 }
889
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000890 // Create a remote offer. Call mediastream_signaling_.UseOptionsWithStreamX()
891 // before this function to decide which streams to create.
892 JsepSessionDescription* CreateRemoteOffer() {
893 cricket::MediaSessionOptions options;
894 mediastream_signaling_.GetOptionsForAnswer(NULL, &options);
895 return CreateRemoteOffer(options, session_->remote_description());
896 }
897
898 JsepSessionDescription* CreateRemoteAnswer(
899 const SessionDescriptionInterface* offer,
900 cricket::MediaSessionOptions options,
901 cricket::SecurePolicy policy) {
902 desc_factory_->set_secure(policy);
903 const std::string session_id =
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000904 rtc::ToString(rtc::CreateRandomId64());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000905 JsepSessionDescription* answer(
906 new JsepSessionDescription(JsepSessionDescription::kAnswer));
907 if (!answer->Initialize(desc_factory_->CreateAnswer(offer->description(),
908 options, NULL),
909 session_id, kSessionVersion)) {
910 delete answer;
911 answer = NULL;
912 }
913 return answer;
914 }
915
916 JsepSessionDescription* CreateRemoteAnswer(
917 const SessionDescriptionInterface* offer,
918 cricket::MediaSessionOptions options) {
919 return CreateRemoteAnswer(offer, options, cricket::SEC_REQUIRED);
920 }
921
922 // Creates an answer session description with streams based on
923 // |mediastream_signaling_|. Call
924 // mediastream_signaling_.UseOptionsWithStreamX() before this function
925 // to decide which streams to create.
926 JsepSessionDescription* CreateRemoteAnswer(
927 const SessionDescriptionInterface* offer) {
928 cricket::MediaSessionOptions options;
929 mediastream_signaling_.GetOptionsForAnswer(NULL, &options);
930 return CreateRemoteAnswer(offer, options, cricket::SEC_REQUIRED);
931 }
932
933 void TestSessionCandidatesWithBundleRtcpMux(bool bundle, bool rtcp_mux) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000934 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000935 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000936 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +0000937
938 PeerConnectionInterface::RTCOfferAnswerOptions options;
939 options.use_rtp_mux = bundle;
940
941 SessionDescriptionInterface* offer = CreateOffer(options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000942 // SetLocalDescription and SetRemoteDescriptions takes ownership of offer
943 // and answer.
944 SetLocalDescriptionWithoutError(offer);
945
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000946 rtc::scoped_ptr<SessionDescriptionInterface> answer(
henrike@webrtc.org723d6832013-07-12 16:04:50 +0000947 CreateRemoteAnswer(session_->local_description()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000948 std::string sdp;
949 EXPECT_TRUE(answer->ToString(&sdp));
950
951 size_t expected_candidate_num = 2;
952 if (!rtcp_mux) {
953 // If rtcp_mux is enabled we should expect 4 candidates - host and srflex
954 // for rtp and rtcp.
955 expected_candidate_num = 4;
956 // Disable rtcp-mux from the answer
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000957 const std::string kRtcpMux = "a=rtcp-mux";
958 const std::string kXRtcpMux = "a=xrtcp-mux";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000959 rtc::replace_substrs(kRtcpMux.c_str(), kRtcpMux.length(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000960 kXRtcpMux.c_str(), kXRtcpMux.length(),
961 &sdp);
962 }
963
964 SessionDescriptionInterface* new_answer = CreateSessionDescription(
965 JsepSessionDescription::kAnswer, sdp, NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000966
967 // SetRemoteDescription to enable rtcp mux.
henrike@webrtc.org723d6832013-07-12 16:04:50 +0000968 SetRemoteDescriptionWithoutError(new_answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000969 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
970 EXPECT_EQ(expected_candidate_num, observer_.mline_0_candidates_.size());
torbjornga81a42f2015-09-23 02:16:58 -0700971 EXPECT_EQ(expected_candidate_num, observer_.mline_1_candidates_.size());
972 for (size_t i = 0; i < observer_.mline_0_candidates_.size(); ++i) {
973 cricket::Candidate c0 = observer_.mline_0_candidates_[i];
974 cricket::Candidate c1 = observer_.mline_1_candidates_[i];
975 if (bundle) {
976 EXPECT_TRUE(c0.IsEquivalent(c1));
977 } else {
978 EXPECT_FALSE(c0.IsEquivalent(c1));
979 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000980 }
981 }
982 // Tests that we can only send DTMF when the dtmf codec is supported.
983 void TestCanInsertDtmf(bool can) {
984 if (can) {
985 InitWithDtmfCodec();
986 } else {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000987 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000988 }
989 mediastream_signaling_.SendAudioVideoStream1();
990 CreateAndSetRemoteOfferAndLocalAnswer();
991 EXPECT_FALSE(session_->CanInsertDtmf(""));
992 EXPECT_EQ(can, session_->CanInsertDtmf(kAudioTrack1));
993 }
994
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +0000995 // Helper class to configure loopback network and verify Best
996 // Connection using right IP protocol for TestLoopbackCall
997 // method. LoopbackNetworkManager applies firewall rules to block
998 // all ping traffic once ICE completed, and remove them to observe
999 // ICE reconnected again. This LoopbackNetworkConfiguration struct
1000 // verifies the best connection is using the right IP protocol after
1001 // initial ICE convergences.
1002
1003 class LoopbackNetworkConfiguration {
torbjornga81a42f2015-09-23 02:16:58 -07001004 public:
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001005 LoopbackNetworkConfiguration()
1006 : test_ipv6_network_(false),
1007 test_extra_ipv4_network_(false),
1008 best_connection_after_initial_ice_converged_(1, 0) {}
1009
1010 // Used to track the expected best connection count in each IP protocol.
1011 struct ExpectedBestConnection {
1012 ExpectedBestConnection(int ipv4_count, int ipv6_count)
1013 : ipv4_count_(ipv4_count),
1014 ipv6_count_(ipv6_count) {}
1015
1016 int ipv4_count_;
1017 int ipv6_count_;
1018 };
1019
1020 bool test_ipv6_network_;
1021 bool test_extra_ipv4_network_;
1022 ExpectedBestConnection best_connection_after_initial_ice_converged_;
1023
1024 void VerifyBestConnectionAfterIceConverge(
jbauchac8869e2015-07-03 01:36:14 -07001025 const rtc::scoped_refptr<FakeMetricsObserver> metrics_observer) const {
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001026 Verify(metrics_observer, best_connection_after_initial_ice_converged_);
1027 }
1028
1029 private:
jbauchac8869e2015-07-03 01:36:14 -07001030 void Verify(const rtc::scoped_refptr<FakeMetricsObserver> metrics_observer,
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001031 const ExpectedBestConnection& expected) const {
1032 EXPECT_EQ(
Guo-wei Shieh3d564c12015-08-19 16:51:15 -07001033 metrics_observer->GetEnumCounter(webrtc::kEnumCounterAddressFamily,
1034 webrtc::kBestConnections_IPv4),
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001035 expected.ipv4_count_);
1036 EXPECT_EQ(
Guo-wei Shieh3d564c12015-08-19 16:51:15 -07001037 metrics_observer->GetEnumCounter(webrtc::kEnumCounterAddressFamily,
1038 webrtc::kBestConnections_IPv6),
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001039 expected.ipv6_count_);
Guo-wei Shieh3d564c12015-08-19 16:51:15 -07001040 // This is used in the loopback call so there is only single host to host
1041 // candidate pair.
1042 EXPECT_EQ(metrics_observer->GetEnumCounter(
1043 webrtc::kEnumCounterIceCandidatePairTypeUdp,
1044 webrtc::kIceCandidatePairHostHost),
Guo-wei Shieh3cc834a2015-09-04 15:52:14 -07001045 0);
1046 EXPECT_EQ(metrics_observer->GetEnumCounter(
1047 webrtc::kEnumCounterIceCandidatePairTypeUdp,
1048 webrtc::kIceCandidatePairHostPublicHostPublic),
Guo-wei Shieh3d564c12015-08-19 16:51:15 -07001049 1);
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001050 }
1051 };
1052
1053 class LoopbackNetworkManager {
1054 public:
1055 LoopbackNetworkManager(WebRtcSessionTest* session,
1056 const LoopbackNetworkConfiguration& config)
1057 : config_(config) {
1058 session->AddInterface(
1059 rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
1060 if (config_.test_extra_ipv4_network_) {
1061 session->AddInterface(
1062 rtc::SocketAddress(kClientAddrHost2, kClientAddrPort));
1063 }
1064 if (config_.test_ipv6_network_) {
1065 session->AddInterface(
1066 rtc::SocketAddress(kClientIPv6AddrHost1, kClientAddrPort));
1067 }
1068 }
1069
1070 void ApplyFirewallRules(rtc::FirewallSocketServer* fss) {
1071 fss->AddRule(false, rtc::FP_ANY, rtc::FD_ANY,
1072 rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
1073 if (config_.test_extra_ipv4_network_) {
1074 fss->AddRule(false, rtc::FP_ANY, rtc::FD_ANY,
1075 rtc::SocketAddress(kClientAddrHost2, kClientAddrPort));
1076 }
1077 if (config_.test_ipv6_network_) {
1078 fss->AddRule(false, rtc::FP_ANY, rtc::FD_ANY,
1079 rtc::SocketAddress(kClientIPv6AddrHost1, kClientAddrPort));
1080 }
1081 }
1082
1083 void ClearRules(rtc::FirewallSocketServer* fss) { fss->ClearRules(); }
1084
1085 private:
1086 LoopbackNetworkConfiguration config_;
1087 };
1088
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001089 // The method sets up a call from the session to itself, in a loopback
1090 // arrangement. It also uses a firewall rule to create a temporary
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00001091 // disconnection, and then a permanent disconnection.
1092 // This code is placed in a method so that it can be invoked
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001093 // by multiple tests with different allocators (e.g. with and without BUNDLE).
1094 // While running the call, this method also checks if the session goes through
1095 // the correct sequence of ICE states when a connection is established,
1096 // broken, and re-established.
1097 // The Connection state should go:
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00001098 // New -> Checking -> (Connected) -> Completed -> Disconnected -> Completed
1099 // -> Failed.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001100 // The Gathering state should go: New -> Gathering -> Completed.
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001101
1102 void TestLoopbackCall(const LoopbackNetworkConfiguration& config) {
1103 LoopbackNetworkManager loopback_network_manager(this, config);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001104 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001105 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001106 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001107
1108 EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
1109 observer_.ice_gathering_state_);
1110 SetLocalDescriptionWithoutError(offer);
1111 EXPECT_EQ(PeerConnectionInterface::kIceConnectionNew,
1112 observer_.ice_connection_state_);
1113 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceGatheringGathering,
1114 observer_.ice_gathering_state_,
1115 kIceCandidatesTimeout);
1116 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1117 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
1118 observer_.ice_gathering_state_,
1119 kIceCandidatesTimeout);
1120
1121 std::string sdp;
1122 offer->ToString(&sdp);
1123 SessionDescriptionInterface* desc =
jbauchfabe2c92015-07-16 13:43:14 -07001124 webrtc::CreateSessionDescription(
1125 JsepSessionDescription::kAnswer, sdp, nullptr);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001126 ASSERT_TRUE(desc != NULL);
1127 SetRemoteDescriptionWithoutError(desc);
1128
1129 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionChecking,
1130 observer_.ice_connection_state_,
1131 kIceCandidatesTimeout);
mallinath@webrtc.orgd3dc4242014-03-01 00:05:52 +00001132
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00001133 // The ice connection state is "Connected" too briefly to catch in a test.
1134 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001135 observer_.ice_connection_state_,
1136 kIceCandidatesTimeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001137
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001138 config.VerifyBestConnectionAfterIceConverge(metrics_observer_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001139 // Adding firewall rule to block ping requests, which should cause
1140 // transport channel failure.
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001141
1142 loopback_network_manager.ApplyFirewallRules(fss_.get());
1143
1144 LOG(LS_INFO) << "Firewall Rules applied";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001145 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
1146 observer_.ice_connection_state_,
1147 kIceCandidatesTimeout);
1148
jbauchac8869e2015-07-03 01:36:14 -07001149 metrics_observer_->Reset();
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001150
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001151 // Clearing the rules, session should move back to completed state.
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001152 loopback_network_manager.ClearRules(fss_.get());
torbjornga81a42f2015-09-23 02:16:58 -07001153 // Session is automatically calling OnSignalingReady after creation of
1154 // new portallocator session which will allocate new set of candidates.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001155
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001156 LOG(LS_INFO) << "Firewall Rules cleared";
torbjornga81a42f2015-09-23 02:16:58 -07001157
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00001158 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001159 observer_.ice_connection_state_,
1160 kIceCandidatesTimeout);
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00001161
1162 // Now we block ping requests and wait until the ICE connection transitions
1163 // to the Failed state. This will take at least 30 seconds because it must
1164 // wait for the Port to timeout.
1165 int port_timeout = 30000;
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001166
1167 loopback_network_manager.ApplyFirewallRules(fss_.get());
1168 LOG(LS_INFO) << "Firewall Rules applied again";
jlmiller@webrtc.org804eb462015-02-20 02:20:03 +00001169 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00001170 observer_.ice_connection_state_,
1171 kIceCandidatesTimeout + port_timeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001172 }
1173
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001174 void TestLoopbackCall() {
1175 LoopbackNetworkConfiguration config;
1176 TestLoopbackCall(config);
1177 }
1178
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001179 // Adds CN codecs to FakeMediaEngine and MediaDescriptionFactory.
1180 void AddCNCodecs() {
wu@webrtc.org364f2042013-11-20 21:49:41 +00001181 const cricket::AudioCodec kCNCodec1(102, "CN", 8000, 0, 1, 0);
1182 const cricket::AudioCodec kCNCodec2(103, "CN", 16000, 0, 1, 0);
1183
1184 // Add kCNCodec for dtmf test.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001185 std::vector<cricket::AudioCodec> codecs = media_engine_->audio_codecs();;
1186 codecs.push_back(kCNCodec1);
1187 codecs.push_back(kCNCodec2);
1188 media_engine_->SetAudioCodecs(codecs);
1189 desc_factory_->set_audio_codecs(codecs);
1190 }
1191
1192 bool VerifyNoCNCodecs(const cricket::ContentInfo* content) {
1193 const cricket::ContentDescription* description = content->description;
1194 ASSERT(description != NULL);
1195 const cricket::AudioContentDescription* audio_content_desc =
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00001196 static_cast<const cricket::AudioContentDescription*>(description);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001197 ASSERT(audio_content_desc != NULL);
1198 for (size_t i = 0; i < audio_content_desc->codecs().size(); ++i) {
1199 if (audio_content_desc->codecs()[i].name == "CN")
1200 return false;
1201 }
1202 return true;
1203 }
1204
1205 void SetLocalDescriptionWithDataChannel() {
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +00001206 webrtc::InternalDataChannelInit dci;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001207 dci.reliable = false;
1208 session_->CreateDataChannel("datachannel", &dci);
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001209 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001210 SetLocalDescriptionWithoutError(offer);
1211 }
1212
wu@webrtc.org91053e72013-08-10 07:18:04 +00001213 void VerifyMultipleAsyncCreateDescription(
Henrik Boström87713d02015-08-25 09:53:21 +02001214 RTCCertificateGenerationMethod cert_gen_method,
1215 CreateSessionDescriptionRequest::Type type) {
1216 InitWithDtls(cert_gen_method);
1217 VerifyMultipleAsyncCreateDescriptionAfterInit(true, type);
1218 }
1219
1220 void VerifyMultipleAsyncCreateDescriptionIdentityGenFailure(
1221 CreateSessionDescriptionRequest::Type type) {
1222 InitWithDtlsIdentityGenFail();
1223 VerifyMultipleAsyncCreateDescriptionAfterInit(false, type);
1224 }
1225
1226 void VerifyMultipleAsyncCreateDescriptionAfterInit(
wu@webrtc.org91053e72013-08-10 07:18:04 +00001227 bool success, CreateSessionDescriptionRequest::Type type) {
henrikg91d6ede2015-09-17 00:24:34 -07001228 RTC_CHECK(session_);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001229 SetFactoryDtlsSrtp();
wu@webrtc.org91053e72013-08-10 07:18:04 +00001230 if (type == CreateSessionDescriptionRequest::kAnswer) {
1231 cricket::MediaSessionOptions options;
1232 scoped_ptr<JsepSessionDescription> offer(
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001233 CreateRemoteOffer(options, cricket::SEC_DISABLED));
wu@webrtc.org91053e72013-08-10 07:18:04 +00001234 ASSERT_TRUE(offer.get() != NULL);
1235 SetRemoteDescriptionWithoutError(offer.release());
1236 }
1237
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001238 PeerConnectionInterface::RTCOfferAnswerOptions options;
wu@webrtc.org91053e72013-08-10 07:18:04 +00001239 const int kNumber = 3;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001240 rtc::scoped_refptr<WebRtcSessionCreateSDPObserverForTest>
wu@webrtc.org91053e72013-08-10 07:18:04 +00001241 observers[kNumber];
1242 for (int i = 0; i < kNumber; ++i) {
1243 observers[i] = new WebRtcSessionCreateSDPObserverForTest();
1244 if (type == CreateSessionDescriptionRequest::kOffer) {
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001245 session_->CreateOffer(observers[i], options);
wu@webrtc.org91053e72013-08-10 07:18:04 +00001246 } else {
1247 session_->CreateAnswer(observers[i], NULL);
1248 }
1249 }
1250
1251 WebRtcSessionCreateSDPObserverForTest::State expected_state =
1252 success ? WebRtcSessionCreateSDPObserverForTest::kSucceeded :
1253 WebRtcSessionCreateSDPObserverForTest::kFailed;
1254
1255 for (int i = 0; i < kNumber; ++i) {
1256 EXPECT_EQ_WAIT(expected_state, observers[i]->state(), 1000);
1257 if (success) {
1258 EXPECT_TRUE(observers[i]->description() != NULL);
1259 } else {
1260 EXPECT_TRUE(observers[i]->description() == NULL);
1261 }
1262 }
1263 }
1264
mallinath@webrtc.org3d81b1b2014-09-09 14:38:10 +00001265 void ConfigureAllocatorWithTurn() {
1266 cricket::RelayServerConfig relay_server(cricket::RELAY_TURN);
1267 cricket::RelayCredentials credentials(kTurnUsername, kTurnPassword);
1268 relay_server.credentials = credentials;
1269 relay_server.ports.push_back(cricket::ProtocolAddress(
1270 kTurnUdpIntAddr, cricket::PROTO_UDP, false));
1271 allocator_->AddRelay(relay_server);
1272 allocator_->set_step_delay(cricket::kMinimumStepDelay);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001273 allocator_->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP);
mallinath@webrtc.org3d81b1b2014-09-09 14:38:10 +00001274 }
1275
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001276 cricket::FakeMediaEngine* media_engine_;
1277 cricket::FakeDataEngine* data_engine_;
1278 cricket::FakeDeviceManager* device_manager_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001279 rtc::scoped_ptr<cricket::ChannelManager> channel_manager_;
1280 rtc::scoped_ptr<cricket::TransportDescriptionFactory> tdesc_factory_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001281 rtc::scoped_ptr<cricket::MediaSessionDescriptionFactory> desc_factory_;
1282 rtc::scoped_ptr<rtc::PhysicalSocketServer> pss_;
1283 rtc::scoped_ptr<rtc::VirtualSocketServer> vss_;
1284 rtc::scoped_ptr<rtc::FirewallSocketServer> fss_;
1285 rtc::SocketServerScope ss_scope_;
1286 rtc::SocketAddress stun_socket_addr_;
jiayl@webrtc.orgbebc75e2014-09-26 23:01:11 +00001287 rtc::scoped_ptr<cricket::TestStunServer> stun_server_;
buildbot@webrtc.org41451d42014-05-03 05:39:45 +00001288 cricket::TestTurnServer turn_server_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001289 rtc::FakeNetworkManager network_manager_;
1290 rtc::scoped_ptr<cricket::BasicPortAllocator> allocator_;
wu@webrtc.org97077a32013-10-25 21:18:33 +00001291 PeerConnectionFactoryInterface::Options options_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001292 rtc::scoped_ptr<FakeConstraints> constraints_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001293 FakeMediaStreamSignaling mediastream_signaling_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001294 rtc::scoped_ptr<WebRtcSessionForTest> session_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001295 MockIceObserver observer_;
1296 cricket::FakeVideoMediaChannel* video_channel_;
1297 cricket::FakeVoiceMediaChannel* voice_channel_;
jbauchac8869e2015-07-03 01:36:14 -07001298 rtc::scoped_refptr<FakeMetricsObserver> metrics_observer_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001299};
1300
Henrik Boström87713d02015-08-25 09:53:21 +02001301TEST_P(WebRtcSessionTest, TestInitializeWithDtls) {
1302 InitWithDtls(GetParam());
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001303 // SDES is disabled when DTLS is on.
1304 EXPECT_EQ(cricket::SEC_DISABLED, session_->SdesPolicy());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001305}
1306
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001307TEST_F(WebRtcSessionTest, TestInitializeWithoutDtls) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001308 Init();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001309 // SDES is required if DTLS is off.
1310 EXPECT_EQ(cricket::SEC_REQUIRED, session_->SdesPolicy());
wu@webrtc.org91053e72013-08-10 07:18:04 +00001311}
1312
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001313TEST_F(WebRtcSessionTest, TestSessionCandidates) {
1314 TestSessionCandidatesWithBundleRtcpMux(false, false);
1315}
1316
1317// Below test cases (TestSessionCandidatesWith*) verify the candidates gathered
1318// with rtcp-mux and/or bundle.
1319TEST_F(WebRtcSessionTest, TestSessionCandidatesWithRtcpMux) {
1320 TestSessionCandidatesWithBundleRtcpMux(false, true);
1321}
1322
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001323TEST_F(WebRtcSessionTest, TestSessionCandidatesWithBundleRtcpMux) {
1324 TestSessionCandidatesWithBundleRtcpMux(true, true);
1325}
1326
1327TEST_F(WebRtcSessionTest, TestMultihomeCandidates) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001328 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
1329 AddInterface(rtc::SocketAddress(kClientAddrHost2, kClientAddrPort));
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001330 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001331 mediastream_signaling_.SendAudioVideoStream1();
1332 InitiateCall();
1333 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1334 EXPECT_EQ(8u, observer_.mline_0_candidates_.size());
1335 EXPECT_EQ(8u, observer_.mline_1_candidates_.size());
1336}
1337
1338TEST_F(WebRtcSessionTest, TestStunError) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001339 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
1340 AddInterface(rtc::SocketAddress(kClientAddrHost2, kClientAddrPort));
wu@webrtc.org364f2042013-11-20 21:49:41 +00001341 fss_->AddRule(false,
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001342 rtc::FP_UDP,
1343 rtc::FD_ANY,
1344 rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001345 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001346 mediastream_signaling_.SendAudioVideoStream1();
1347 InitiateCall();
wu@webrtc.org364f2042013-11-20 21:49:41 +00001348 // Since kClientAddrHost1 is blocked, not expecting stun candidates for it.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001349 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1350 EXPECT_EQ(6u, observer_.mline_0_candidates_.size());
1351 EXPECT_EQ(6u, observer_.mline_1_candidates_.size());
1352}
1353
mallinath@webrtc.org3d81b1b2014-09-09 14:38:10 +00001354// Test session delivers no candidates gathered when constraint set to "none".
1355TEST_F(WebRtcSessionTest, TestIceTransportsNone) {
1356 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001357 InitWithIceTransport(PeerConnectionInterface::kNone);
mallinath@webrtc.org3d81b1b2014-09-09 14:38:10 +00001358 mediastream_signaling_.SendAudioVideoStream1();
1359 InitiateCall();
1360 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1361 EXPECT_EQ(0u, observer_.mline_0_candidates_.size());
1362 EXPECT_EQ(0u, observer_.mline_1_candidates_.size());
1363}
1364
1365// Test session delivers only relay candidates gathered when constaint set to
1366// "relay".
1367TEST_F(WebRtcSessionTest, TestIceTransportsRelay) {
1368 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
1369 ConfigureAllocatorWithTurn();
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001370 InitWithIceTransport(PeerConnectionInterface::kRelay);
mallinath@webrtc.org3d81b1b2014-09-09 14:38:10 +00001371 mediastream_signaling_.SendAudioVideoStream1();
1372 InitiateCall();
1373 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1374 EXPECT_EQ(2u, observer_.mline_0_candidates_.size());
1375 EXPECT_EQ(2u, observer_.mline_1_candidates_.size());
1376 for (size_t i = 0; i < observer_.mline_0_candidates_.size(); ++i) {
1377 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
1378 observer_.mline_0_candidates_[i].type());
1379 }
1380 for (size_t i = 0; i < observer_.mline_1_candidates_.size(); ++i) {
1381 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
1382 observer_.mline_1_candidates_[i].type());
1383 }
1384}
1385
1386// Test session delivers all candidates gathered when constaint set to "all".
1387TEST_F(WebRtcSessionTest, TestIceTransportsAll) {
1388 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001389 InitWithIceTransport(PeerConnectionInterface::kAll);
mallinath@webrtc.org3d81b1b2014-09-09 14:38:10 +00001390 mediastream_signaling_.SendAudioVideoStream1();
1391 InitiateCall();
1392 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1393 // Host + STUN. By default allocator is disabled to gather relay candidates.
1394 EXPECT_EQ(4u, observer_.mline_0_candidates_.size());
1395 EXPECT_EQ(4u, observer_.mline_1_candidates_.size());
1396}
1397
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001398TEST_F(WebRtcSessionTest, SetSdpFailedOnInvalidSdp) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001399 Init();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001400 SessionDescriptionInterface* offer = NULL;
1401 // Since |offer| is NULL, there's no way to tell if it's an offer or answer.
1402 std::string unknown_action;
1403 SetLocalDescriptionExpectError(unknown_action, kInvalidSdp, offer);
1404 SetRemoteDescriptionExpectError(unknown_action, kInvalidSdp, offer);
1405}
1406
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001407// Test creating offers and receive answers and make sure the
1408// media engine creates the expected send and receive streams.
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001409TEST_F(WebRtcSessionTest, TestCreateSdesOfferReceiveSdesAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001410 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001411 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001412 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001413 const std::string session_id_orig = offer->session_id();
1414 const std::string session_version_orig = offer->session_version();
1415 SetLocalDescriptionWithoutError(offer);
1416
1417 mediastream_signaling_.SendAudioVideoStream2();
1418 SessionDescriptionInterface* answer =
1419 CreateRemoteAnswer(session_->local_description());
1420 SetRemoteDescriptionWithoutError(answer);
1421
1422 video_channel_ = media_engine_->GetVideoChannel(0);
1423 voice_channel_ = media_engine_->GetVoiceChannel(0);
1424
1425 ASSERT_EQ(1u, video_channel_->recv_streams().size());
1426 EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].id);
1427
1428 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
1429 EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].id);
1430
1431 ASSERT_EQ(1u, video_channel_->send_streams().size());
1432 EXPECT_TRUE(kVideoTrack1 == video_channel_->send_streams()[0].id);
1433 ASSERT_EQ(1u, voice_channel_->send_streams().size());
1434 EXPECT_TRUE(kAudioTrack1 == voice_channel_->send_streams()[0].id);
1435
1436 // Create new offer without send streams.
1437 mediastream_signaling_.SendNothing();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001438 offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001439
1440 // Verify the session id is the same and the session version is
1441 // increased.
1442 EXPECT_EQ(session_id_orig, offer->session_id());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001443 EXPECT_LT(rtc::FromString<uint64>(session_version_orig),
1444 rtc::FromString<uint64>(offer->session_version()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001445
1446 SetLocalDescriptionWithoutError(offer);
jiayl@webrtc.org7d4891d2014-09-09 21:43:15 +00001447 EXPECT_EQ(0u, video_channel_->send_streams().size());
1448 EXPECT_EQ(0u, voice_channel_->send_streams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001449
1450 mediastream_signaling_.SendAudioVideoStream2();
1451 answer = CreateRemoteAnswer(session_->local_description());
1452 SetRemoteDescriptionWithoutError(answer);
1453
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001454 // Make sure the receive streams have not changed.
1455 ASSERT_EQ(1u, video_channel_->recv_streams().size());
1456 EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].id);
1457 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
1458 EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].id);
1459}
1460
1461// Test receiving offers and creating answers and make sure the
1462// media engine creates the expected send and receive streams.
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001463TEST_F(WebRtcSessionTest, TestReceiveSdesOfferCreateSdesAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001464 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001465 mediastream_signaling_.SendAudioVideoStream2();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001466 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001467 VerifyCryptoParams(offer->description());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001468 SetRemoteDescriptionWithoutError(offer);
1469
1470 mediastream_signaling_.SendAudioVideoStream1();
wu@webrtc.org91053e72013-08-10 07:18:04 +00001471 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001472 VerifyCryptoParams(answer->description());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001473 SetLocalDescriptionWithoutError(answer);
1474
1475 const std::string session_id_orig = answer->session_id();
1476 const std::string session_version_orig = answer->session_version();
1477
1478 video_channel_ = media_engine_->GetVideoChannel(0);
1479 voice_channel_ = media_engine_->GetVoiceChannel(0);
1480
1481 ASSERT_EQ(1u, video_channel_->recv_streams().size());
1482 EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].id);
1483
1484 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
1485 EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].id);
1486
1487 ASSERT_EQ(1u, video_channel_->send_streams().size());
1488 EXPECT_TRUE(kVideoTrack1 == video_channel_->send_streams()[0].id);
1489 ASSERT_EQ(1u, voice_channel_->send_streams().size());
1490 EXPECT_TRUE(kAudioTrack1 == voice_channel_->send_streams()[0].id);
1491
1492 mediastream_signaling_.SendAudioVideoStream1And2();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001493 offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001494 SetRemoteDescriptionWithoutError(offer);
1495
1496 // Answer by turning off all send streams.
1497 mediastream_signaling_.SendNothing();
wu@webrtc.org91053e72013-08-10 07:18:04 +00001498 answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001499
1500 // Verify the session id is the same and the session version is
1501 // increased.
1502 EXPECT_EQ(session_id_orig, answer->session_id());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001503 EXPECT_LT(rtc::FromString<uint64>(session_version_orig),
1504 rtc::FromString<uint64>(answer->session_version()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001505 SetLocalDescriptionWithoutError(answer);
1506
1507 ASSERT_EQ(2u, video_channel_->recv_streams().size());
1508 EXPECT_TRUE(kVideoTrack1 == video_channel_->recv_streams()[0].id);
1509 EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[1].id);
1510 ASSERT_EQ(2u, voice_channel_->recv_streams().size());
1511 EXPECT_TRUE(kAudioTrack1 == voice_channel_->recv_streams()[0].id);
1512 EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[1].id);
1513
1514 // Make sure we have no send streams.
1515 EXPECT_EQ(0u, video_channel_->send_streams().size());
1516 EXPECT_EQ(0u, voice_channel_->send_streams().size());
1517}
1518
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001519TEST_F(WebRtcSessionTest, SetLocalSdpFailedOnCreateChannel) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001520 Init();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001521 media_engine_->set_fail_create_channel(true);
1522
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001523 SessionDescriptionInterface* offer = CreateOffer();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001524 ASSERT_TRUE(offer != NULL);
1525 // SetRemoteDescription and SetLocalDescription will take the ownership of
1526 // the offer.
1527 SetRemoteDescriptionOfferExpectError(kCreateChannelFailed, offer);
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001528 offer = CreateOffer();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001529 ASSERT_TRUE(offer != NULL);
1530 SetLocalDescriptionOfferExpectError(kCreateChannelFailed, offer);
1531}
1532
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001533//
1534// Tests for creating/setting SDP under different SDES/DTLS polices:
1535//
1536// --DTLS off and SDES on
1537// TestCreateSdesOfferReceiveSdesAnswer/TestReceiveSdesOfferCreateSdesAnswer:
1538// set local/remote offer/answer with crypto --> success
1539// TestSetNonSdesOfferWhenSdesOn: set local/remote offer without crypto --->
1540// failure
1541// TestSetLocalNonSdesAnswerWhenSdesOn: set local answer without crypto -->
1542// failure
1543// TestSetRemoteNonSdesAnswerWhenSdesOn: set remote answer without crypto -->
1544// failure
1545//
1546// --DTLS on and SDES off
1547// TestCreateDtlsOfferReceiveDtlsAnswer/TestReceiveDtlsOfferCreateDtlsAnswer:
1548// set local/remote offer/answer with DTLS fingerprint --> success
1549// TestReceiveNonDtlsOfferWhenDtlsOn: set local/remote offer without DTLS
1550// fingerprint --> failure
1551// TestSetLocalNonDtlsAnswerWhenDtlsOn: set local answer without fingerprint
1552// --> failure
1553// TestSetRemoteNonDtlsAnswerWhenDtlsOn: set remote answer without fingerprint
1554// --> failure
1555//
1556// --Encryption disabled: DTLS off and SDES off
1557// TestCreateOfferReceiveAnswerWithoutEncryption: set local offer and remote
1558// answer without SDES or DTLS --> success
1559// TestCreateAnswerReceiveOfferWithoutEncryption: set remote offer and local
1560// answer without SDES or DTLS --> success
1561//
1562
1563// Test that we return a failure when applying a remote/local offer that doesn't
1564// have cryptos enabled when DTLS is off.
1565TEST_F(WebRtcSessionTest, TestSetNonSdesOfferWhenSdesOn) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001566 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001567 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001568 options.recv_video = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001569 JsepSessionDescription* offer = CreateRemoteOffer(
1570 options, cricket::SEC_DISABLED);
1571 ASSERT_TRUE(offer != NULL);
1572 VerifyNoCryptoParams(offer->description(), false);
1573 // SetRemoteDescription and SetLocalDescription will take the ownership of
1574 // the offer.
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001575 SetRemoteDescriptionOfferExpectError(kSdpWithoutSdesCrypto, offer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001576 offer = CreateRemoteOffer(options, cricket::SEC_DISABLED);
1577 ASSERT_TRUE(offer != NULL);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001578 SetLocalDescriptionOfferExpectError(kSdpWithoutSdesCrypto, offer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001579}
1580
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001581// Test that we return a failure when applying a local answer that doesn't have
1582// cryptos enabled when DTLS is off.
1583TEST_F(WebRtcSessionTest, TestSetLocalNonSdesAnswerWhenSdesOn) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001584 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001585 SessionDescriptionInterface* offer = NULL;
1586 SessionDescriptionInterface* answer = NULL;
1587 CreateCryptoOfferAndNonCryptoAnswer(&offer, &answer);
1588 // SetRemoteDescription and SetLocalDescription will take the ownership of
1589 // the offer.
1590 SetRemoteDescriptionWithoutError(offer);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001591 SetLocalDescriptionAnswerExpectError(kSdpWithoutSdesCrypto, answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001592}
1593
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001594// Test we will return fail when apply an remote answer that doesn't have
1595// crypto enabled when DTLS is off.
1596TEST_F(WebRtcSessionTest, TestSetRemoteNonSdesAnswerWhenSdesOn) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001597 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001598 SessionDescriptionInterface* offer = NULL;
1599 SessionDescriptionInterface* answer = NULL;
1600 CreateCryptoOfferAndNonCryptoAnswer(&offer, &answer);
1601 // SetRemoteDescription and SetLocalDescription will take the ownership of
1602 // the offer.
1603 SetLocalDescriptionWithoutError(offer);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001604 SetRemoteDescriptionAnswerExpectError(kSdpWithoutSdesCrypto, answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001605}
1606
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001607// Test that we accept an offer with a DTLS fingerprint when DTLS is on
1608// and that we return an answer with a DTLS fingerprint.
Henrik Boström87713d02015-08-25 09:53:21 +02001609TEST_P(WebRtcSessionTest, TestReceiveDtlsOfferCreateDtlsAnswer) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001610 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001611 mediastream_signaling_.SendAudioVideoStream1();
Henrik Boström87713d02015-08-25 09:53:21 +02001612 InitWithDtls(GetParam());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001613 SetFactoryDtlsSrtp();
1614 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001615 options.recv_video = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001616 JsepSessionDescription* offer =
1617 CreateRemoteOffer(options, cricket::SEC_DISABLED);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001618 ASSERT_TRUE(offer != NULL);
1619 VerifyFingerprintStatus(offer->description(), true);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001620 VerifyNoCryptoParams(offer->description(), true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001621
1622 // SetRemoteDescription will take the ownership of the offer.
1623 SetRemoteDescriptionWithoutError(offer);
1624
1625 // Verify that we get a crypto fingerprint in the answer.
wu@webrtc.org91053e72013-08-10 07:18:04 +00001626 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001627 ASSERT_TRUE(answer != NULL);
1628 VerifyFingerprintStatus(answer->description(), true);
1629 // Check that we don't have an a=crypto line in the answer.
1630 VerifyNoCryptoParams(answer->description(), true);
1631
1632 // Now set the local description, which should work, even without a=crypto.
1633 SetLocalDescriptionWithoutError(answer);
1634}
1635
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001636// Test that we set a local offer with a DTLS fingerprint when DTLS is on
1637// and then we accept a remote answer with a DTLS fingerprint successfully.
Henrik Boström87713d02015-08-25 09:53:21 +02001638TEST_P(WebRtcSessionTest, TestCreateDtlsOfferReceiveDtlsAnswer) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001639 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001640 mediastream_signaling_.SendAudioVideoStream1();
Henrik Boström87713d02015-08-25 09:53:21 +02001641 InitWithDtls(GetParam());
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001642 SetFactoryDtlsSrtp();
1643
1644 // Verify that we get a crypto fingerprint in the answer.
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001645 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001646 ASSERT_TRUE(offer != NULL);
1647 VerifyFingerprintStatus(offer->description(), true);
1648 // Check that we don't have an a=crypto line in the offer.
1649 VerifyNoCryptoParams(offer->description(), true);
1650
1651 // Now set the local description, which should work, even without a=crypto.
1652 SetLocalDescriptionWithoutError(offer);
1653
1654 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001655 options.recv_video = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001656 JsepSessionDescription* answer =
1657 CreateRemoteAnswer(offer, options, cricket::SEC_DISABLED);
1658 ASSERT_TRUE(answer != NULL);
1659 VerifyFingerprintStatus(answer->description(), true);
1660 VerifyNoCryptoParams(answer->description(), true);
1661
1662 // SetRemoteDescription will take the ownership of the answer.
1663 SetRemoteDescriptionWithoutError(answer);
1664}
1665
1666// Test that if we support DTLS and the other side didn't offer a fingerprint,
1667// we will fail to set the remote description.
Henrik Boström87713d02015-08-25 09:53:21 +02001668TEST_P(WebRtcSessionTest, TestReceiveNonDtlsOfferWhenDtlsOn) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001669 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
Henrik Boström87713d02015-08-25 09:53:21 +02001670 InitWithDtls(GetParam());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001671 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001672 options.recv_video = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001673 options.bundle_enabled = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001674 JsepSessionDescription* offer = CreateRemoteOffer(
1675 options, cricket::SEC_REQUIRED);
1676 ASSERT_TRUE(offer != NULL);
1677 VerifyFingerprintStatus(offer->description(), false);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001678 VerifyCryptoParams(offer->description());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001679
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001680 // SetRemoteDescription will take the ownership of the offer.
1681 SetRemoteDescriptionOfferExpectError(
1682 kSdpWithoutDtlsFingerprint, offer);
1683
1684 offer = CreateRemoteOffer(options, cricket::SEC_REQUIRED);
1685 // SetLocalDescription will take the ownership of the offer.
1686 SetLocalDescriptionOfferExpectError(
1687 kSdpWithoutDtlsFingerprint, offer);
1688}
1689
1690// Test that we return a failure when applying a local answer that doesn't have
1691// a DTLS fingerprint when DTLS is required.
Henrik Boström87713d02015-08-25 09:53:21 +02001692TEST_P(WebRtcSessionTest, TestSetLocalNonDtlsAnswerWhenDtlsOn) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001693 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
Henrik Boström87713d02015-08-25 09:53:21 +02001694 InitWithDtls(GetParam());
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001695 SessionDescriptionInterface* offer = NULL;
1696 SessionDescriptionInterface* answer = NULL;
1697 CreateDtlsOfferAndNonDtlsAnswer(&offer, &answer);
1698
1699 // SetRemoteDescription and SetLocalDescription will take the ownership of
1700 // the offer and answer.
1701 SetRemoteDescriptionWithoutError(offer);
1702 SetLocalDescriptionAnswerExpectError(
1703 kSdpWithoutDtlsFingerprint, answer);
1704}
1705
1706// Test that we return a failure when applying a remote answer that doesn't have
1707// a DTLS fingerprint when DTLS is required.
Henrik Boström87713d02015-08-25 09:53:21 +02001708TEST_P(WebRtcSessionTest, TestSetRemoteNonDtlsAnswerWhenDtlsOn) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001709 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
torbjornga81a42f2015-09-23 02:16:58 -07001710 // Enable both SDES and DTLS, so that offer won't be outright rejected as a
1711 // result of using the "UDP/TLS/RTP/SAVPF" profile.
Henrik Boström87713d02015-08-25 09:53:21 +02001712 InitWithDtls(GetParam());
torbjornga81a42f2015-09-23 02:16:58 -07001713 session_->SetSdesPolicy(cricket::SEC_ENABLED);
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001714 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001715 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001716 options.recv_video = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001717 JsepSessionDescription* answer =
torbjornga81a42f2015-09-23 02:16:58 -07001718 CreateRemoteAnswer(offer, options, cricket::SEC_ENABLED);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001719
1720 // SetRemoteDescription and SetLocalDescription will take the ownership of
1721 // the offer and answer.
1722 SetLocalDescriptionWithoutError(offer);
1723 SetRemoteDescriptionAnswerExpectError(
1724 kSdpWithoutDtlsFingerprint, answer);
1725}
1726
1727// Test that we create a local offer without SDES or DTLS and accept a remote
1728// answer without SDES or DTLS when encryption is disabled.
Henrik Boström87713d02015-08-25 09:53:21 +02001729TEST_P(WebRtcSessionTest, TestCreateOfferReceiveAnswerWithoutEncryption) {
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001730 mediastream_signaling_.SendAudioVideoStream1();
1731 options_.disable_encryption = true;
Henrik Boström87713d02015-08-25 09:53:21 +02001732 InitWithDtls(GetParam());
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001733
1734 // Verify that we get a crypto fingerprint in the answer.
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001735 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001736 ASSERT_TRUE(offer != NULL);
1737 VerifyFingerprintStatus(offer->description(), false);
1738 // Check that we don't have an a=crypto line in the offer.
1739 VerifyNoCryptoParams(offer->description(), false);
1740
1741 // Now set the local description, which should work, even without a=crypto.
1742 SetLocalDescriptionWithoutError(offer);
1743
1744 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001745 options.recv_video = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001746 JsepSessionDescription* answer =
1747 CreateRemoteAnswer(offer, options, cricket::SEC_DISABLED);
1748 ASSERT_TRUE(answer != NULL);
1749 VerifyFingerprintStatus(answer->description(), false);
1750 VerifyNoCryptoParams(answer->description(), false);
1751
1752 // SetRemoteDescription will take the ownership of the answer.
1753 SetRemoteDescriptionWithoutError(answer);
1754}
1755
1756// Test that we create a local answer without SDES or DTLS and accept a remote
1757// offer without SDES or DTLS when encryption is disabled.
Henrik Boström87713d02015-08-25 09:53:21 +02001758TEST_P(WebRtcSessionTest, TestCreateAnswerReceiveOfferWithoutEncryption) {
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001759 options_.disable_encryption = true;
Henrik Boström87713d02015-08-25 09:53:21 +02001760 InitWithDtls(GetParam());
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001761
1762 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001763 options.recv_video = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001764 JsepSessionDescription* offer =
1765 CreateRemoteOffer(options, cricket::SEC_DISABLED);
1766 ASSERT_TRUE(offer != NULL);
1767 VerifyFingerprintStatus(offer->description(), false);
1768 VerifyNoCryptoParams(offer->description(), false);
1769
1770 // SetRemoteDescription will take the ownership of the offer.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001771 SetRemoteDescriptionWithoutError(offer);
1772
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001773 // Verify that we get a crypto fingerprint in the answer.
wu@webrtc.org91053e72013-08-10 07:18:04 +00001774 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001775 ASSERT_TRUE(answer != NULL);
1776 VerifyFingerprintStatus(answer->description(), false);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001777 // Check that we don't have an a=crypto line in the answer.
1778 VerifyNoCryptoParams(answer->description(), false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001779
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001780 // Now set the local description, which should work, even without a=crypto.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001781 SetLocalDescriptionWithoutError(answer);
1782}
1783
1784TEST_F(WebRtcSessionTest, TestSetLocalOfferTwice) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001785 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001786 mediastream_signaling_.SendNothing();
1787 // SetLocalDescription take ownership of offer.
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001788 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001789 SetLocalDescriptionWithoutError(offer);
1790
1791 // SetLocalDescription take ownership of offer.
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001792 SessionDescriptionInterface* offer2 = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001793 SetLocalDescriptionWithoutError(offer2);
1794}
1795
1796TEST_F(WebRtcSessionTest, TestSetRemoteOfferTwice) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001797 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001798 mediastream_signaling_.SendNothing();
1799 // SetLocalDescription take ownership of offer.
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001800 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001801 SetRemoteDescriptionWithoutError(offer);
1802
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001803 SessionDescriptionInterface* offer2 = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001804 SetRemoteDescriptionWithoutError(offer2);
1805}
1806
1807TEST_F(WebRtcSessionTest, TestSetLocalAndRemoteOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001808 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001809 mediastream_signaling_.SendNothing();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001810 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001811 SetLocalDescriptionWithoutError(offer);
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001812 offer = CreateOffer();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001813 SetRemoteDescriptionOfferExpectError(
1814 "Called in wrong state: STATE_SENTINITIATE", offer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001815}
1816
1817TEST_F(WebRtcSessionTest, TestSetRemoteAndLocalOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001818 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001819 mediastream_signaling_.SendNothing();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001820 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001821 SetRemoteDescriptionWithoutError(offer);
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001822 offer = CreateOffer();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001823 SetLocalDescriptionOfferExpectError(
1824 "Called in wrong state: STATE_RECEIVEDINITIATE", offer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001825}
1826
1827TEST_F(WebRtcSessionTest, TestSetLocalPrAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001828 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001829 mediastream_signaling_.SendNothing();
1830 SessionDescriptionInterface* offer = CreateRemoteOffer();
1831 SetRemoteDescriptionExpectState(offer, BaseSession::STATE_RECEIVEDINITIATE);
1832
1833 JsepSessionDescription* pranswer = static_cast<JsepSessionDescription*>(
wu@webrtc.org91053e72013-08-10 07:18:04 +00001834 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001835 pranswer->set_type(SessionDescriptionInterface::kPrAnswer);
1836 SetLocalDescriptionExpectState(pranswer, BaseSession::STATE_SENTPRACCEPT);
1837
1838 mediastream_signaling_.SendAudioVideoStream1();
1839 JsepSessionDescription* pranswer2 = static_cast<JsepSessionDescription*>(
wu@webrtc.org91053e72013-08-10 07:18:04 +00001840 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001841 pranswer2->set_type(SessionDescriptionInterface::kPrAnswer);
1842
1843 SetLocalDescriptionExpectState(pranswer2, BaseSession::STATE_SENTPRACCEPT);
1844
1845 mediastream_signaling_.SendAudioVideoStream2();
wu@webrtc.org91053e72013-08-10 07:18:04 +00001846 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001847 SetLocalDescriptionExpectState(answer, BaseSession::STATE_SENTACCEPT);
1848}
1849
1850TEST_F(WebRtcSessionTest, TestSetRemotePrAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001851 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001852 mediastream_signaling_.SendNothing();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001853 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001854 SetLocalDescriptionExpectState(offer, BaseSession::STATE_SENTINITIATE);
1855
1856 JsepSessionDescription* pranswer =
1857 CreateRemoteAnswer(session_->local_description());
1858 pranswer->set_type(SessionDescriptionInterface::kPrAnswer);
1859
1860 SetRemoteDescriptionExpectState(pranswer,
1861 BaseSession::STATE_RECEIVEDPRACCEPT);
1862
1863 mediastream_signaling_.SendAudioVideoStream1();
1864 JsepSessionDescription* pranswer2 =
1865 CreateRemoteAnswer(session_->local_description());
1866 pranswer2->set_type(SessionDescriptionInterface::kPrAnswer);
1867
1868 SetRemoteDescriptionExpectState(pranswer2,
1869 BaseSession::STATE_RECEIVEDPRACCEPT);
1870
1871 mediastream_signaling_.SendAudioVideoStream2();
1872 SessionDescriptionInterface* answer =
1873 CreateRemoteAnswer(session_->local_description());
1874 SetRemoteDescriptionExpectState(answer, BaseSession::STATE_RECEIVEDACCEPT);
1875}
1876
1877TEST_F(WebRtcSessionTest, TestSetLocalAnswerWithoutOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001878 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001879 mediastream_signaling_.SendNothing();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001880 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
1881
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001882 SessionDescriptionInterface* answer =
1883 CreateRemoteAnswer(offer.get());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001884 SetLocalDescriptionAnswerExpectError("Called in wrong state: STATE_INIT",
1885 answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001886}
1887
1888TEST_F(WebRtcSessionTest, TestSetRemoteAnswerWithoutOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001889 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001890 mediastream_signaling_.SendNothing();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001891 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
1892
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001893 SessionDescriptionInterface* answer =
1894 CreateRemoteAnswer(offer.get());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001895 SetRemoteDescriptionAnswerExpectError(
1896 "Called in wrong state: STATE_INIT", answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001897}
1898
1899TEST_F(WebRtcSessionTest, TestAddRemoteCandidate) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001900 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001901 mediastream_signaling_.SendAudioVideoStream1();
1902
1903 cricket::Candidate candidate;
1904 candidate.set_component(1);
1905 JsepIceCandidate ice_candidate1(kMediaContentName0, 0, candidate);
1906
1907 // Fail since we have not set a offer description.
1908 EXPECT_FALSE(session_->ProcessIceMessage(&ice_candidate1));
1909
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001910 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001911 SetLocalDescriptionWithoutError(offer);
1912 // Candidate should be allowed to add before remote description.
1913 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate1));
1914 candidate.set_component(2);
1915 JsepIceCandidate ice_candidate2(kMediaContentName0, 0, candidate);
1916 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate2));
1917
1918 SessionDescriptionInterface* answer = CreateRemoteAnswer(
1919 session_->local_description());
1920 SetRemoteDescriptionWithoutError(answer);
1921
1922 // Verifying the candidates are copied properly from internal vector.
1923 const SessionDescriptionInterface* remote_desc =
1924 session_->remote_description();
1925 ASSERT_TRUE(remote_desc != NULL);
1926 ASSERT_EQ(2u, remote_desc->number_of_mediasections());
1927 const IceCandidateCollection* candidates =
1928 remote_desc->candidates(kMediaContentIndex0);
1929 ASSERT_EQ(2u, candidates->count());
1930 EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
1931 EXPECT_EQ(kMediaContentName0, candidates->at(0)->sdp_mid());
1932 EXPECT_EQ(1, candidates->at(0)->candidate().component());
1933 EXPECT_EQ(2, candidates->at(1)->candidate().component());
1934
mallinath@webrtc.org67ee6b92014-02-03 16:57:16 +00001935 // |ice_candidate3| is identical to |ice_candidate2|. It can be added
1936 // successfully, but the total count of candidates will not increase.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001937 candidate.set_component(2);
1938 JsepIceCandidate ice_candidate3(kMediaContentName0, 0, candidate);
1939 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate3));
mallinath@webrtc.org67ee6b92014-02-03 16:57:16 +00001940 ASSERT_EQ(2u, candidates->count());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001941
1942 JsepIceCandidate bad_ice_candidate("bad content name", 99, candidate);
1943 EXPECT_FALSE(session_->ProcessIceMessage(&bad_ice_candidate));
1944}
1945
1946// Test that a remote candidate is added to the remote session description and
1947// that it is retained if the remote session description is changed.
1948TEST_F(WebRtcSessionTest, TestRemoteCandidatesAddedToSessionDescription) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001949 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001950 cricket::Candidate candidate1;
1951 candidate1.set_component(1);
1952 JsepIceCandidate ice_candidate1(kMediaContentName0, kMediaContentIndex0,
1953 candidate1);
1954 mediastream_signaling_.SendAudioVideoStream1();
1955 CreateAndSetRemoteOfferAndLocalAnswer();
1956
1957 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate1));
1958 const SessionDescriptionInterface* remote_desc =
1959 session_->remote_description();
1960 ASSERT_TRUE(remote_desc != NULL);
1961 ASSERT_EQ(2u, remote_desc->number_of_mediasections());
1962 const IceCandidateCollection* candidates =
1963 remote_desc->candidates(kMediaContentIndex0);
1964 ASSERT_EQ(1u, candidates->count());
1965 EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
1966
1967 // Update the RemoteSessionDescription with a new session description and
1968 // a candidate and check that the new remote session description contains both
1969 // candidates.
1970 SessionDescriptionInterface* offer = CreateRemoteOffer();
1971 cricket::Candidate candidate2;
1972 JsepIceCandidate ice_candidate2(kMediaContentName0, kMediaContentIndex0,
1973 candidate2);
1974 EXPECT_TRUE(offer->AddCandidate(&ice_candidate2));
1975 SetRemoteDescriptionWithoutError(offer);
1976
1977 remote_desc = session_->remote_description();
1978 ASSERT_TRUE(remote_desc != NULL);
1979 ASSERT_EQ(2u, remote_desc->number_of_mediasections());
1980 candidates = remote_desc->candidates(kMediaContentIndex0);
1981 ASSERT_EQ(2u, candidates->count());
1982 EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
1983 // Username and password have be updated with the TransportInfo of the
1984 // SessionDescription, won't be equal to the original one.
1985 candidate2.set_username(candidates->at(0)->candidate().username());
1986 candidate2.set_password(candidates->at(0)->candidate().password());
1987 EXPECT_TRUE(candidate2.IsEquivalent(candidates->at(0)->candidate()));
1988 EXPECT_EQ(kMediaContentIndex0, candidates->at(1)->sdp_mline_index());
1989 // No need to verify the username and password.
1990 candidate1.set_username(candidates->at(1)->candidate().username());
1991 candidate1.set_password(candidates->at(1)->candidate().password());
1992 EXPECT_TRUE(candidate1.IsEquivalent(candidates->at(1)->candidate()));
1993
1994 // Test that the candidate is ignored if we can add the same candidate again.
1995 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate2));
1996}
1997
1998// Test that local candidates are added to the local session description and
1999// that they are retained if the local session description is changed.
2000TEST_F(WebRtcSessionTest, TestLocalCandidatesAddedToSessionDescription) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002001 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002002 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002003 mediastream_signaling_.SendAudioVideoStream1();
2004 CreateAndSetRemoteOfferAndLocalAnswer();
2005
2006 const SessionDescriptionInterface* local_desc = session_->local_description();
2007 const IceCandidateCollection* candidates =
2008 local_desc->candidates(kMediaContentIndex0);
2009 ASSERT_TRUE(candidates != NULL);
2010 EXPECT_EQ(0u, candidates->count());
2011
2012 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
2013
2014 local_desc = session_->local_description();
2015 candidates = local_desc->candidates(kMediaContentIndex0);
2016 ASSERT_TRUE(candidates != NULL);
2017 EXPECT_LT(0u, candidates->count());
2018 candidates = local_desc->candidates(1);
2019 ASSERT_TRUE(candidates != NULL);
torbjornga81a42f2015-09-23 02:16:58 -07002020 EXPECT_LT(0u, candidates->count());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002021
2022 // Update the session descriptions.
2023 mediastream_signaling_.SendAudioVideoStream1();
2024 CreateAndSetRemoteOfferAndLocalAnswer();
2025
2026 local_desc = session_->local_description();
2027 candidates = local_desc->candidates(kMediaContentIndex0);
2028 ASSERT_TRUE(candidates != NULL);
2029 EXPECT_LT(0u, candidates->count());
2030 candidates = local_desc->candidates(1);
2031 ASSERT_TRUE(candidates != NULL);
torbjornga81a42f2015-09-23 02:16:58 -07002032 EXPECT_LT(0u, candidates->count());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002033}
2034
2035// Test that we can set a remote session description with remote candidates.
2036TEST_F(WebRtcSessionTest, TestSetRemoteSessionDescriptionWithCandidates) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002037 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002038
2039 cricket::Candidate candidate1;
2040 candidate1.set_component(1);
2041 JsepIceCandidate ice_candidate(kMediaContentName0, kMediaContentIndex0,
2042 candidate1);
2043 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002044 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002045
2046 EXPECT_TRUE(offer->AddCandidate(&ice_candidate));
2047 SetRemoteDescriptionWithoutError(offer);
2048
2049 const SessionDescriptionInterface* remote_desc =
2050 session_->remote_description();
2051 ASSERT_TRUE(remote_desc != NULL);
2052 ASSERT_EQ(2u, remote_desc->number_of_mediasections());
2053 const IceCandidateCollection* candidates =
2054 remote_desc->candidates(kMediaContentIndex0);
2055 ASSERT_EQ(1u, candidates->count());
2056 EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
2057
wu@webrtc.org91053e72013-08-10 07:18:04 +00002058 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002059 SetLocalDescriptionWithoutError(answer);
2060}
2061
2062// Test that offers and answers contains ice candidates when Ice candidates have
2063// been gathered.
2064TEST_F(WebRtcSessionTest, TestSetLocalAndRemoteDescriptionWithCandidates) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002065 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002066 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002067 mediastream_signaling_.SendAudioVideoStream1();
2068 // Ice is started but candidates are not provided until SetLocalDescription
2069 // is called.
2070 EXPECT_EQ(0u, observer_.mline_0_candidates_.size());
2071 EXPECT_EQ(0u, observer_.mline_1_candidates_.size());
2072 CreateAndSetRemoteOfferAndLocalAnswer();
2073 // Wait until at least one local candidate has been collected.
2074 EXPECT_TRUE_WAIT(0u < observer_.mline_0_candidates_.size(),
2075 kIceCandidatesTimeout);
torbjornga81a42f2015-09-23 02:16:58 -07002076 EXPECT_TRUE_WAIT(0u < observer_.mline_1_candidates_.size(),
2077 kIceCandidatesTimeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002078
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002079 rtc::scoped_ptr<SessionDescriptionInterface> local_offer(CreateOffer());
2080
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002081 ASSERT_TRUE(local_offer->candidates(kMediaContentIndex0) != NULL);
2082 EXPECT_LT(0u, local_offer->candidates(kMediaContentIndex0)->count());
torbjornga81a42f2015-09-23 02:16:58 -07002083 ASSERT_TRUE(local_offer->candidates(kMediaContentIndex1) != NULL);
2084 EXPECT_LT(0u, local_offer->candidates(kMediaContentIndex1)->count());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002085
2086 SessionDescriptionInterface* remote_offer(CreateRemoteOffer());
2087 SetRemoteDescriptionWithoutError(remote_offer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00002088 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002089 ASSERT_TRUE(answer->candidates(kMediaContentIndex0) != NULL);
2090 EXPECT_LT(0u, answer->candidates(kMediaContentIndex0)->count());
torbjornga81a42f2015-09-23 02:16:58 -07002091 ASSERT_TRUE(answer->candidates(kMediaContentIndex1) != NULL);
2092 EXPECT_LT(0u, answer->candidates(kMediaContentIndex1)->count());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002093 SetLocalDescriptionWithoutError(answer);
2094}
2095
2096// Verifies TransportProxy and media channels are created with content names
2097// present in the SessionDescription.
2098TEST_F(WebRtcSessionTest, TestChannelCreationsWithContentNames) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002099 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002100 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002101 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002102
2103 // CreateOffer creates session description with the content names "audio" and
2104 // "video". Goal is to modify these content names and verify transport channel
2105 // proxy in the BaseSession, as proxies are created with the content names
2106 // present in SDP.
2107 std::string sdp;
2108 EXPECT_TRUE(offer->ToString(&sdp));
2109 const std::string kAudioMid = "a=mid:audio";
2110 const std::string kAudioMidReplaceStr = "a=mid:audio_content_name";
2111 const std::string kVideoMid = "a=mid:video";
2112 const std::string kVideoMidReplaceStr = "a=mid:video_content_name";
2113
2114 // Replacing |audio| with |audio_content_name|.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002115 rtc::replace_substrs(kAudioMid.c_str(), kAudioMid.length(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002116 kAudioMidReplaceStr.c_str(),
2117 kAudioMidReplaceStr.length(),
2118 &sdp);
2119 // Replacing |video| with |video_content_name|.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002120 rtc::replace_substrs(kVideoMid.c_str(), kVideoMid.length(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002121 kVideoMidReplaceStr.c_str(),
2122 kVideoMidReplaceStr.length(),
2123 &sdp);
2124
2125 SessionDescriptionInterface* modified_offer =
2126 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
2127
2128 SetRemoteDescriptionWithoutError(modified_offer);
2129
2130 SessionDescriptionInterface* answer =
wu@webrtc.org91053e72013-08-10 07:18:04 +00002131 CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002132 SetLocalDescriptionWithoutError(answer);
2133
torbjornga81a42f2015-09-23 02:16:58 -07002134 EXPECT_TRUE(session_->GetTransportProxy("audio_content_name") != NULL);
2135 EXPECT_TRUE(session_->GetTransportProxy("video_content_name") != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002136 EXPECT_TRUE((video_channel_ = media_engine_->GetVideoChannel(0)) != NULL);
2137 EXPECT_TRUE((voice_channel_ = media_engine_->GetVoiceChannel(0)) != NULL);
2138}
2139
2140// Test that an offer contains the correct media content descriptions based on
2141// the send streams when no constraints have been set.
2142TEST_F(WebRtcSessionTest, CreateOfferWithoutConstraintsOrStreams) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002143 Init();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002144 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
2145
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002146 ASSERT_TRUE(offer != NULL);
2147 const cricket::ContentInfo* content =
2148 cricket::GetFirstAudioContent(offer->description());
2149 EXPECT_TRUE(content != NULL);
2150 content = cricket::GetFirstVideoContent(offer->description());
2151 EXPECT_TRUE(content == NULL);
2152}
2153
2154// Test that an offer contains the correct media content descriptions based on
2155// the send streams when no constraints have been set.
2156TEST_F(WebRtcSessionTest, CreateOfferWithoutConstraints) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002157 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002158 // Test Audio only offer.
2159 mediastream_signaling_.UseOptionsAudioOnly();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002160 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
2161
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002162 const cricket::ContentInfo* content =
2163 cricket::GetFirstAudioContent(offer->description());
2164 EXPECT_TRUE(content != NULL);
2165 content = cricket::GetFirstVideoContent(offer->description());
2166 EXPECT_TRUE(content == NULL);
2167
2168 // Test Audio / Video offer.
2169 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002170 offer.reset(CreateOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002171 content = cricket::GetFirstAudioContent(offer->description());
2172 EXPECT_TRUE(content != NULL);
2173 content = cricket::GetFirstVideoContent(offer->description());
2174 EXPECT_TRUE(content != NULL);
2175}
2176
2177// Test that an offer contains no media content descriptions if
2178// kOfferToReceiveVideo and kOfferToReceiveAudio constraints are set to false.
2179TEST_F(WebRtcSessionTest, CreateOfferWithConstraintsWithoutStreams) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002180 Init();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002181 PeerConnectionInterface::RTCOfferAnswerOptions options;
2182 options.offer_to_receive_audio = 0;
2183 options.offer_to_receive_video = 0;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002184
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002185 rtc::scoped_ptr<SessionDescriptionInterface> offer(
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002186 CreateOffer(options));
2187
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002188 ASSERT_TRUE(offer != NULL);
2189 const cricket::ContentInfo* content =
2190 cricket::GetFirstAudioContent(offer->description());
2191 EXPECT_TRUE(content == NULL);
2192 content = cricket::GetFirstVideoContent(offer->description());
2193 EXPECT_TRUE(content == NULL);
2194}
2195
2196// Test that an offer contains only audio media content descriptions if
2197// kOfferToReceiveAudio constraints are set to true.
2198TEST_F(WebRtcSessionTest, CreateAudioOnlyOfferWithConstraints) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002199 Init();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002200 PeerConnectionInterface::RTCOfferAnswerOptions options;
2201 options.offer_to_receive_audio =
2202 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
2203
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002204 rtc::scoped_ptr<SessionDescriptionInterface> offer(
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002205 CreateOffer(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002206
2207 const cricket::ContentInfo* content =
2208 cricket::GetFirstAudioContent(offer->description());
2209 EXPECT_TRUE(content != NULL);
2210 content = cricket::GetFirstVideoContent(offer->description());
2211 EXPECT_TRUE(content == NULL);
2212}
2213
2214// Test that an offer contains audio and video media content descriptions if
2215// kOfferToReceiveAudio and kOfferToReceiveVideo constraints are set to true.
2216TEST_F(WebRtcSessionTest, CreateOfferWithConstraints) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002217 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002218 // Test Audio / Video offer.
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002219 PeerConnectionInterface::RTCOfferAnswerOptions options;
2220 options.offer_to_receive_audio =
2221 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
2222 options.offer_to_receive_video =
2223 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
2224
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002225 rtc::scoped_ptr<SessionDescriptionInterface> offer(
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002226 CreateOffer(options));
2227
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002228 const cricket::ContentInfo* content =
2229 cricket::GetFirstAudioContent(offer->description());
jiayl@webrtc.orgc1723202014-09-08 20:44:36 +00002230 EXPECT_TRUE(content != NULL);
jiayl@webrtc.org7d4891d2014-09-09 21:43:15 +00002231
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002232 content = cricket::GetFirstVideoContent(offer->description());
2233 EXPECT_TRUE(content != NULL);
2234
jiayl@webrtc.org7d4891d2014-09-09 21:43:15 +00002235 // Sets constraints to false and verifies that audio/video contents are
2236 // removed.
2237 options.offer_to_receive_audio = 0;
2238 options.offer_to_receive_video = 0;
2239 offer.reset(CreateOffer(options));
2240
2241 content = cricket::GetFirstAudioContent(offer->description());
2242 EXPECT_TRUE(content == NULL);
2243 content = cricket::GetFirstVideoContent(offer->description());
2244 EXPECT_TRUE(content == NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002245}
2246
2247// Test that an answer can not be created if the last remote description is not
2248// an offer.
2249TEST_F(WebRtcSessionTest, CreateAnswerWithoutAnOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002250 Init();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002251 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002252 SetLocalDescriptionWithoutError(offer);
2253 SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
2254 SetRemoteDescriptionWithoutError(answer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00002255 EXPECT_TRUE(CreateAnswer(NULL) == NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002256}
2257
2258// Test that an answer contains the correct media content descriptions when no
2259// constraints have been set.
2260TEST_F(WebRtcSessionTest, CreateAnswerWithoutConstraintsOrStreams) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002261 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002262 // Create a remote offer with audio and video content.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002263 rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002264 SetRemoteDescriptionWithoutError(offer.release());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002265 rtc::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002266 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002267 const cricket::ContentInfo* content =
2268 cricket::GetFirstAudioContent(answer->description());
2269 ASSERT_TRUE(content != NULL);
2270 EXPECT_FALSE(content->rejected);
2271
2272 content = cricket::GetFirstVideoContent(answer->description());
2273 ASSERT_TRUE(content != NULL);
2274 EXPECT_FALSE(content->rejected);
2275}
2276
2277// Test that an answer contains the correct media content descriptions when no
2278// constraints have been set and the offer only contain audio.
2279TEST_F(WebRtcSessionTest, CreateAudioAnswerWithoutConstraintsOrStreams) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002280 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002281 // Create a remote offer with audio only.
2282 cricket::MediaSessionOptions options;
jiayl@webrtc.org7d4891d2014-09-09 21:43:15 +00002283
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002284 rtc::scoped_ptr<JsepSessionDescription> offer(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002285 CreateRemoteOffer(options));
2286 ASSERT_TRUE(cricket::GetFirstVideoContent(offer->description()) == NULL);
2287 ASSERT_TRUE(cricket::GetFirstAudioContent(offer->description()) != NULL);
2288
2289 SetRemoteDescriptionWithoutError(offer.release());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002290 rtc::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002291 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002292 const cricket::ContentInfo* content =
2293 cricket::GetFirstAudioContent(answer->description());
2294 ASSERT_TRUE(content != NULL);
2295 EXPECT_FALSE(content->rejected);
2296
2297 EXPECT_TRUE(cricket::GetFirstVideoContent(answer->description()) == NULL);
2298}
2299
2300// Test that an answer contains the correct media content descriptions when no
2301// constraints have been set.
2302TEST_F(WebRtcSessionTest, CreateAnswerWithoutConstraints) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002303 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002304 // Create a remote offer with audio and video content.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002305 rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002306 SetRemoteDescriptionWithoutError(offer.release());
2307 // Test with a stream with tracks.
2308 mediastream_signaling_.SendAudioVideoStream1();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002309 rtc::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002310 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002311 const cricket::ContentInfo* content =
2312 cricket::GetFirstAudioContent(answer->description());
2313 ASSERT_TRUE(content != NULL);
2314 EXPECT_FALSE(content->rejected);
2315
2316 content = cricket::GetFirstVideoContent(answer->description());
2317 ASSERT_TRUE(content != NULL);
2318 EXPECT_FALSE(content->rejected);
2319}
2320
2321// Test that an answer contains the correct media content descriptions when
2322// constraints have been set but no stream is sent.
2323TEST_F(WebRtcSessionTest, CreateAnswerWithConstraintsWithoutStreams) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002324 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002325 // Create a remote offer with audio and video content.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002326 rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002327 SetRemoteDescriptionWithoutError(offer.release());
2328
2329 webrtc::FakeConstraints constraints_no_receive;
2330 constraints_no_receive.SetMandatoryReceiveAudio(false);
2331 constraints_no_receive.SetMandatoryReceiveVideo(false);
2332
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002333 rtc::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002334 CreateAnswer(&constraints_no_receive));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002335 const cricket::ContentInfo* content =
2336 cricket::GetFirstAudioContent(answer->description());
2337 ASSERT_TRUE(content != NULL);
2338 EXPECT_TRUE(content->rejected);
2339
2340 content = cricket::GetFirstVideoContent(answer->description());
2341 ASSERT_TRUE(content != NULL);
2342 EXPECT_TRUE(content->rejected);
2343}
2344
2345// Test that an answer contains the correct media content descriptions when
2346// constraints have been set and streams are sent.
2347TEST_F(WebRtcSessionTest, CreateAnswerWithConstraints) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002348 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002349 // Create a remote offer with audio and video content.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002350 rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002351 SetRemoteDescriptionWithoutError(offer.release());
2352
2353 webrtc::FakeConstraints constraints_no_receive;
2354 constraints_no_receive.SetMandatoryReceiveAudio(false);
2355 constraints_no_receive.SetMandatoryReceiveVideo(false);
2356
2357 // Test with a stream with tracks.
2358 mediastream_signaling_.SendAudioVideoStream1();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002359 rtc::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002360 CreateAnswer(&constraints_no_receive));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002361
2362 // TODO(perkj): Should the direction be set to SEND_ONLY?
2363 const cricket::ContentInfo* content =
2364 cricket::GetFirstAudioContent(answer->description());
2365 ASSERT_TRUE(content != NULL);
2366 EXPECT_FALSE(content->rejected);
2367
2368 // TODO(perkj): Should the direction be set to SEND_ONLY?
2369 content = cricket::GetFirstVideoContent(answer->description());
2370 ASSERT_TRUE(content != NULL);
2371 EXPECT_FALSE(content->rejected);
2372}
2373
2374TEST_F(WebRtcSessionTest, CreateOfferWithoutCNCodecs) {
2375 AddCNCodecs();
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002376 Init();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002377 PeerConnectionInterface::RTCOfferAnswerOptions options;
2378 options.offer_to_receive_audio =
2379 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
2380 options.voice_activity_detection = false;
2381
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002382 rtc::scoped_ptr<SessionDescriptionInterface> offer(
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002383 CreateOffer(options));
2384
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002385 const cricket::ContentInfo* content =
2386 cricket::GetFirstAudioContent(offer->description());
2387 EXPECT_TRUE(content != NULL);
2388 EXPECT_TRUE(VerifyNoCNCodecs(content));
2389}
2390
2391TEST_F(WebRtcSessionTest, CreateAnswerWithoutCNCodecs) {
2392 AddCNCodecs();
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002393 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002394 // Create a remote offer with audio and video content.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002395 rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002396 SetRemoteDescriptionWithoutError(offer.release());
2397
2398 webrtc::FakeConstraints constraints;
2399 constraints.SetOptionalVAD(false);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002400 rtc::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002401 CreateAnswer(&constraints));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002402 const cricket::ContentInfo* content =
2403 cricket::GetFirstAudioContent(answer->description());
2404 ASSERT_TRUE(content != NULL);
2405 EXPECT_TRUE(VerifyNoCNCodecs(content));
2406}
2407
2408// This test verifies the call setup when remote answer with audio only and
2409// later updates with video.
2410TEST_F(WebRtcSessionTest, TestAVOfferWithAudioOnlyAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002411 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002412 EXPECT_TRUE(media_engine_->GetVideoChannel(0) == NULL);
2413 EXPECT_TRUE(media_engine_->GetVoiceChannel(0) == NULL);
2414
2415 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002416 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002417
2418 cricket::MediaSessionOptions options;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002419 SessionDescriptionInterface* answer = CreateRemoteAnswer(offer, options);
2420
2421 // SetLocalDescription and SetRemoteDescriptions takes ownership of offer
2422 // and answer;
2423 SetLocalDescriptionWithoutError(offer);
2424 SetRemoteDescriptionWithoutError(answer);
2425
2426 video_channel_ = media_engine_->GetVideoChannel(0);
2427 voice_channel_ = media_engine_->GetVoiceChannel(0);
2428
2429 ASSERT_TRUE(video_channel_ == NULL);
2430
2431 ASSERT_EQ(0u, voice_channel_->recv_streams().size());
2432 ASSERT_EQ(1u, voice_channel_->send_streams().size());
2433 EXPECT_EQ(kAudioTrack1, voice_channel_->send_streams()[0].id);
2434
2435 // Let the remote end update the session descriptions, with Audio and Video.
2436 mediastream_signaling_.SendAudioVideoStream2();
2437 CreateAndSetRemoteOfferAndLocalAnswer();
2438
2439 video_channel_ = media_engine_->GetVideoChannel(0);
2440 voice_channel_ = media_engine_->GetVoiceChannel(0);
2441
2442 ASSERT_TRUE(video_channel_ != NULL);
2443 ASSERT_TRUE(voice_channel_ != NULL);
2444
2445 ASSERT_EQ(1u, video_channel_->recv_streams().size());
2446 ASSERT_EQ(1u, video_channel_->send_streams().size());
2447 EXPECT_EQ(kVideoTrack2, video_channel_->recv_streams()[0].id);
2448 EXPECT_EQ(kVideoTrack2, video_channel_->send_streams()[0].id);
2449 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
2450 ASSERT_EQ(1u, voice_channel_->send_streams().size());
2451 EXPECT_EQ(kAudioTrack2, voice_channel_->recv_streams()[0].id);
2452 EXPECT_EQ(kAudioTrack2, voice_channel_->send_streams()[0].id);
2453
2454 // Change session back to audio only.
2455 mediastream_signaling_.UseOptionsAudioOnly();
2456 CreateAndSetRemoteOfferAndLocalAnswer();
2457
2458 EXPECT_EQ(0u, video_channel_->recv_streams().size());
2459 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
2460 EXPECT_EQ(kAudioTrack2, voice_channel_->recv_streams()[0].id);
2461 ASSERT_EQ(1u, voice_channel_->send_streams().size());
2462 EXPECT_EQ(kAudioTrack2, voice_channel_->send_streams()[0].id);
2463}
2464
2465// This test verifies the call setup when remote answer with video only and
2466// later updates with audio.
2467TEST_F(WebRtcSessionTest, TestAVOfferWithVideoOnlyAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002468 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002469 EXPECT_TRUE(media_engine_->GetVideoChannel(0) == NULL);
2470 EXPECT_TRUE(media_engine_->GetVoiceChannel(0) == NULL);
2471 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002472 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002473
2474 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00002475 options.recv_audio = false;
2476 options.recv_video = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002477 SessionDescriptionInterface* answer = CreateRemoteAnswer(
2478 offer, options, cricket::SEC_ENABLED);
2479
2480 // SetLocalDescription and SetRemoteDescriptions takes ownership of offer
2481 // and answer.
2482 SetLocalDescriptionWithoutError(offer);
2483 SetRemoteDescriptionWithoutError(answer);
2484
2485 video_channel_ = media_engine_->GetVideoChannel(0);
2486 voice_channel_ = media_engine_->GetVoiceChannel(0);
2487
2488 ASSERT_TRUE(voice_channel_ == NULL);
2489 ASSERT_TRUE(video_channel_ != NULL);
2490
2491 EXPECT_EQ(0u, video_channel_->recv_streams().size());
2492 ASSERT_EQ(1u, video_channel_->send_streams().size());
2493 EXPECT_EQ(kVideoTrack1, video_channel_->send_streams()[0].id);
2494
2495 // Update the session descriptions, with Audio and Video.
2496 mediastream_signaling_.SendAudioVideoStream2();
2497 CreateAndSetRemoteOfferAndLocalAnswer();
2498
2499 voice_channel_ = media_engine_->GetVoiceChannel(0);
2500 ASSERT_TRUE(voice_channel_ != NULL);
2501
2502 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
2503 ASSERT_EQ(1u, voice_channel_->send_streams().size());
2504 EXPECT_EQ(kAudioTrack2, voice_channel_->recv_streams()[0].id);
2505 EXPECT_EQ(kAudioTrack2, voice_channel_->send_streams()[0].id);
2506
2507 // Change session back to video only.
2508 mediastream_signaling_.UseOptionsVideoOnly();
2509 CreateAndSetRemoteOfferAndLocalAnswer();
2510
2511 video_channel_ = media_engine_->GetVideoChannel(0);
2512 voice_channel_ = media_engine_->GetVoiceChannel(0);
2513
2514 ASSERT_EQ(1u, video_channel_->recv_streams().size());
2515 EXPECT_EQ(kVideoTrack2, video_channel_->recv_streams()[0].id);
2516 ASSERT_EQ(1u, video_channel_->send_streams().size());
2517 EXPECT_EQ(kVideoTrack2, video_channel_->send_streams()[0].id);
2518}
2519
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002520TEST_F(WebRtcSessionTest, VerifyCryptoParamsInSDP) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002521 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002522 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002523 scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002524 VerifyCryptoParams(offer->description());
2525 SetRemoteDescriptionWithoutError(offer.release());
wu@webrtc.org91053e72013-08-10 07:18:04 +00002526 scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002527 VerifyCryptoParams(answer->description());
2528}
2529
2530TEST_F(WebRtcSessionTest, VerifyNoCryptoParamsInSDP) {
wu@webrtc.org97077a32013-10-25 21:18:33 +00002531 options_.disable_encryption = true;
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002532 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002533 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002534 scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002535 VerifyNoCryptoParams(offer->description(), false);
2536}
2537
2538TEST_F(WebRtcSessionTest, VerifyAnswerFromNonCryptoOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002539 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002540 VerifyAnswerFromNonCryptoOffer();
2541}
2542
2543TEST_F(WebRtcSessionTest, VerifyAnswerFromCryptoOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002544 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002545 VerifyAnswerFromCryptoOffer();
2546}
2547
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002548// This test verifies that setLocalDescription fails if
2549// no a=ice-ufrag and a=ice-pwd lines are present in the SDP.
2550TEST_F(WebRtcSessionTest, TestSetLocalDescriptionWithoutIce) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002551 Init();
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002552 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002553 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
2554
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002555 std::string sdp;
2556 RemoveIceUfragPwdLines(offer.get(), &sdp);
2557 SessionDescriptionInterface* modified_offer =
2558 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00002559 SetLocalDescriptionOfferExpectError(kSdpWithoutIceUfragPwd, modified_offer);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002560}
2561
2562// This test verifies that setRemoteDescription fails if
2563// no a=ice-ufrag and a=ice-pwd lines are present in the SDP.
2564TEST_F(WebRtcSessionTest, TestSetRemoteDescriptionWithoutIce) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002565 Init();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002566 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateRemoteOffer());
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002567 std::string sdp;
2568 RemoveIceUfragPwdLines(offer.get(), &sdp);
2569 SessionDescriptionInterface* modified_offer =
2570 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00002571 SetRemoteDescriptionOfferExpectError(kSdpWithoutIceUfragPwd, modified_offer);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002572}
2573
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +00002574// This test verifies that setLocalDescription fails if local offer has
2575// too short ice ufrag and pwd strings.
2576TEST_F(WebRtcSessionTest, TestSetLocalDescriptionInvalidIceCredentials) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002577 Init();
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +00002578 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002579 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
2580
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +00002581 std::string sdp;
2582 // Modifying ice ufrag and pwd in local offer with strings smaller than the
2583 // recommended values of 4 and 22 bytes respectively.
2584 ModifyIceUfragPwdLines(offer.get(), "ice", "icepwd", &sdp);
2585 SessionDescriptionInterface* modified_offer =
2586 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
2587 std::string error;
2588 EXPECT_FALSE(session_->SetLocalDescription(modified_offer, &error));
2589
2590 // Test with string greater than 256.
2591 sdp.clear();
2592 ModifyIceUfragPwdLines(offer.get(), kTooLongIceUfragPwd, kTooLongIceUfragPwd,
2593 &sdp);
2594 modified_offer = CreateSessionDescription(JsepSessionDescription::kOffer, sdp,
2595 NULL);
2596 EXPECT_FALSE(session_->SetLocalDescription(modified_offer, &error));
2597}
2598
2599// This test verifies that setRemoteDescription fails if remote offer has
2600// too short ice ufrag and pwd strings.
2601TEST_F(WebRtcSessionTest, TestSetRemoteDescriptionInvalidIceCredentials) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002602 Init();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002603 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateRemoteOffer());
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +00002604 std::string sdp;
2605 // Modifying ice ufrag and pwd in remote offer with strings smaller than the
2606 // recommended values of 4 and 22 bytes respectively.
2607 ModifyIceUfragPwdLines(offer.get(), "ice", "icepwd", &sdp);
2608 SessionDescriptionInterface* modified_offer =
2609 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
2610 std::string error;
2611 EXPECT_FALSE(session_->SetRemoteDescription(modified_offer, &error));
2612
2613 sdp.clear();
2614 ModifyIceUfragPwdLines(offer.get(), kTooLongIceUfragPwd, kTooLongIceUfragPwd,
2615 &sdp);
2616 modified_offer = CreateSessionDescription(JsepSessionDescription::kOffer, sdp,
2617 NULL);
2618 EXPECT_FALSE(session_->SetRemoteDescription(modified_offer, &error));
2619}
2620
honghaiz503726c2015-07-31 12:37:38 -07002621// Test that if the remote description indicates the peer requested ICE restart
2622// (via a new ufrag or pwd), the old ICE candidates are not copied,
2623// and vice versa.
2624TEST_F(WebRtcSessionTest, TestSetRemoteDescriptionWithIceRestart) {
2625 Init();
2626 scoped_ptr<SessionDescriptionInterface> offer(CreateRemoteOffer());
2627
2628 // Create the first offer.
2629 std::string sdp;
2630 ModifyIceUfragPwdLines(offer.get(), "0123456789012345",
2631 "abcdefghijklmnopqrstuvwx", &sdp);
2632 SessionDescriptionInterface* offer1 =
2633 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
2634 cricket::Candidate candidate1(1, "udp", rtc::SocketAddress("1.1.1.1", 5000),
2635 0, "", "", "relay", 0, "");
2636 JsepIceCandidate ice_candidate1(kMediaContentName0, kMediaContentIndex0,
2637 candidate1);
2638 EXPECT_TRUE(offer1->AddCandidate(&ice_candidate1));
2639 SetRemoteDescriptionWithoutError(offer1);
2640 EXPECT_EQ(1, session_->remote_description()->candidates(0)->count());
2641
2642 // The second offer has the same ufrag and pwd but different address.
2643 sdp.clear();
2644 ModifyIceUfragPwdLines(offer.get(), "0123456789012345",
2645 "abcdefghijklmnopqrstuvwx", &sdp);
2646 SessionDescriptionInterface* offer2 =
2647 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
2648 candidate1.set_address(rtc::SocketAddress("1.1.1.1", 6000));
2649 JsepIceCandidate ice_candidate2(kMediaContentName0, kMediaContentIndex0,
2650 candidate1);
2651 EXPECT_TRUE(offer2->AddCandidate(&ice_candidate2));
2652 SetRemoteDescriptionWithoutError(offer2);
2653 EXPECT_EQ(2, session_->remote_description()->candidates(0)->count());
2654
2655 // The third offer has a different ufrag and different address.
2656 sdp.clear();
2657 ModifyIceUfragPwdLines(offer.get(), "0123456789012333",
2658 "abcdefghijklmnopqrstuvwx", &sdp);
2659 SessionDescriptionInterface* offer3 =
2660 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
2661 candidate1.set_address(rtc::SocketAddress("1.1.1.1", 7000));
2662 JsepIceCandidate ice_candidate3(kMediaContentName0, kMediaContentIndex0,
2663 candidate1);
2664 EXPECT_TRUE(offer3->AddCandidate(&ice_candidate3));
2665 SetRemoteDescriptionWithoutError(offer3);
2666 EXPECT_EQ(1, session_->remote_description()->candidates(0)->count());
2667
2668 // The fourth offer has no candidate but a different ufrag/pwd.
2669 sdp.clear();
2670 ModifyIceUfragPwdLines(offer.get(), "0123456789012444",
2671 "abcdefghijklmnopqrstuvyz", &sdp);
2672 SessionDescriptionInterface* offer4 =
2673 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
2674 SetRemoteDescriptionWithoutError(offer4);
2675 EXPECT_EQ(0, session_->remote_description()->candidates(0)->count());
2676}
2677
Donald Curtisd4f769d2015-05-28 09:48:21 -07002678// Test that candidates sent to the "video" transport do not get pushed down to
2679// the "audio" transport channel when bundling using TransportProxy.
2680TEST_F(WebRtcSessionTest, TestIgnoreCandidatesForUnusedTransportWhenBundling) {
2681 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
2682
2683 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyBalanced);
2684 mediastream_signaling_.SendAudioVideoStream1();
2685
2686 PeerConnectionInterface::RTCOfferAnswerOptions options;
2687 options.use_rtp_mux = true;
2688
2689 SessionDescriptionInterface* offer = CreateRemoteOffer();
2690 SetRemoteDescriptionWithoutError(offer);
2691
2692 SessionDescriptionInterface* answer = CreateAnswer(NULL);
2693 SetLocalDescriptionWithoutError(answer);
2694
torbjornga81a42f2015-09-23 02:16:58 -07002695 EXPECT_EQ(session_->GetTransportProxy("audio")->impl(),
2696 session_->GetTransportProxy("video")->impl());
Donald Curtisd4f769d2015-05-28 09:48:21 -07002697
torbjornga81a42f2015-09-23 02:16:58 -07002698 cricket::Transport* t = session_->GetTransport("audio");
Donald Curtisd4f769d2015-05-28 09:48:21 -07002699
2700 // Checks if one of the transport channels contains a connection using a given
2701 // port.
torbjornga81a42f2015-09-23 02:16:58 -07002702 auto connection_with_remote_port = [t](int port) {
2703 cricket::TransportStats stats;
2704 t->GetStats(&stats);
2705 for (auto& chan_stat : stats.channel_stats) {
2706 for (auto& conn_info : chan_stat.connection_infos) {
2707 if (conn_info.remote_candidate.address().port() == port) {
2708 return true;
Donald Curtisd4f769d2015-05-28 09:48:21 -07002709 }
2710 }
2711 }
2712 return false;
2713 };
2714
2715 EXPECT_FALSE(connection_with_remote_port(5000));
2716 EXPECT_FALSE(connection_with_remote_port(5001));
2717 EXPECT_FALSE(connection_with_remote_port(6000));
2718
2719 // The way the *_WAIT checks work is they only wait if the condition fails,
2720 // which does not help in the case where state is not changing. This is
2721 // problematic in this test since we want to verify that adding a video
2722 // candidate does _not_ change state. So we interleave candidates and assume
2723 // that messages are executed in the order they were posted.
2724
2725 // First audio candidate.
2726 cricket::Candidate candidate0;
2727 candidate0.set_address(rtc::SocketAddress("1.1.1.1", 5000));
2728 candidate0.set_component(1);
2729 candidate0.set_protocol("udp");
2730 JsepIceCandidate ice_candidate0(kMediaContentName0, kMediaContentIndex0,
2731 candidate0);
2732 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate0));
2733
2734 // Video candidate.
2735 cricket::Candidate candidate1;
2736 candidate1.set_address(rtc::SocketAddress("1.1.1.1", 6000));
2737 candidate1.set_component(1);
2738 candidate1.set_protocol("udp");
2739 JsepIceCandidate ice_candidate1(kMediaContentName1, kMediaContentIndex1,
2740 candidate1);
2741 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate1));
2742
2743 // Second audio candidate.
2744 cricket::Candidate candidate2;
2745 candidate2.set_address(rtc::SocketAddress("1.1.1.1", 5001));
2746 candidate2.set_component(1);
2747 candidate2.set_protocol("udp");
2748 JsepIceCandidate ice_candidate2(kMediaContentName0, kMediaContentIndex0,
2749 candidate2);
2750 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate2));
2751
2752 EXPECT_TRUE_WAIT(connection_with_remote_port(5000), 1000);
2753 EXPECT_TRUE_WAIT(connection_with_remote_port(5001), 1000);
2754
2755 // No need here for a _WAIT check since we are checking that state hasn't
2756 // changed: if this is false we would be doing waits for nothing and if this
2757 // is true then there will be no messages processed anyways.
2758 EXPECT_FALSE(connection_with_remote_port(6000));
2759}
2760
torbjornga81a42f2015-09-23 02:16:58 -07002761// kBundlePolicyBalanced bundle policy and answer contains BUNDLE.
Donald Curtis0e209b02015-03-24 09:29:54 -07002762TEST_F(WebRtcSessionTest, TestBalancedBundleInAnswer) {
2763 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyBalanced);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002764 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002765
2766 PeerConnectionInterface::RTCOfferAnswerOptions options;
2767 options.use_rtp_mux = true;
2768
2769 SessionDescriptionInterface* offer = CreateOffer(options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002770 SetLocalDescriptionWithoutError(offer);
Donald Curtis0e209b02015-03-24 09:29:54 -07002771
torbjornga81a42f2015-09-23 02:16:58 -07002772 EXPECT_NE(session_->GetTransportProxy("audio")->impl(),
2773 session_->GetTransportProxy("video")->impl());
Donald Curtis0e209b02015-03-24 09:29:54 -07002774
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002775 mediastream_signaling_.SendAudioVideoStream2();
Donald Curtis0e209b02015-03-24 09:29:54 -07002776 SessionDescriptionInterface* answer =
2777 CreateRemoteAnswer(session_->local_description());
2778 SetRemoteDescriptionWithoutError(answer);
2779
torbjornga81a42f2015-09-23 02:16:58 -07002780 EXPECT_EQ(session_->GetTransportProxy("audio")->impl(),
2781 session_->GetTransportProxy("video")->impl());
Donald Curtis0e209b02015-03-24 09:29:54 -07002782}
2783
torbjornga81a42f2015-09-23 02:16:58 -07002784// kBundlePolicyBalanced bundle policy but no BUNDLE in the answer.
Donald Curtis0e209b02015-03-24 09:29:54 -07002785TEST_F(WebRtcSessionTest, TestBalancedNoBundleInAnswer) {
2786 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyBalanced);
2787 mediastream_signaling_.SendAudioVideoStream1();
Peter Thatcher4eddf182015-04-30 10:55:59 -07002788
Donald Curtis0e209b02015-03-24 09:29:54 -07002789 PeerConnectionInterface::RTCOfferAnswerOptions options;
2790 options.use_rtp_mux = true;
2791
2792 SessionDescriptionInterface* offer = CreateOffer(options);
2793 SetLocalDescriptionWithoutError(offer);
2794
torbjornga81a42f2015-09-23 02:16:58 -07002795 EXPECT_NE(session_->GetTransportProxy("audio")->impl(),
2796 session_->GetTransportProxy("video")->impl());
Donald Curtis0e209b02015-03-24 09:29:54 -07002797
2798 mediastream_signaling_.SendAudioVideoStream2();
2799
2800 // Remove BUNDLE from the answer.
2801 rtc::scoped_ptr<SessionDescriptionInterface> answer(
2802 CreateRemoteAnswer(session_->local_description()));
2803 cricket::SessionDescription* answer_copy = answer->description()->Copy();
2804 answer_copy->RemoveGroupByName(cricket::GROUP_TYPE_BUNDLE);
2805 JsepSessionDescription* modified_answer =
2806 new JsepSessionDescription(JsepSessionDescription::kAnswer);
2807 modified_answer->Initialize(answer_copy, "1", "1");
2808 SetRemoteDescriptionWithoutError(modified_answer); //
2809
torbjornga81a42f2015-09-23 02:16:58 -07002810 EXPECT_NE(session_->GetTransportProxy("audio")->impl(),
2811 session_->GetTransportProxy("video")->impl());
Donald Curtis0e209b02015-03-24 09:29:54 -07002812}
2813
2814// kBundlePolicyMaxBundle policy with BUNDLE in the answer.
2815TEST_F(WebRtcSessionTest, TestMaxBundleBundleInAnswer) {
2816 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxBundle);
2817 mediastream_signaling_.SendAudioVideoStream1();
2818
2819 PeerConnectionInterface::RTCOfferAnswerOptions options;
2820 options.use_rtp_mux = true;
2821
2822 SessionDescriptionInterface* offer = CreateOffer(options);
2823 SetLocalDescriptionWithoutError(offer);
2824
torbjornga81a42f2015-09-23 02:16:58 -07002825 EXPECT_EQ(session_->GetTransportProxy("audio")->impl(),
2826 session_->GetTransportProxy("video")->impl());
Donald Curtis0e209b02015-03-24 09:29:54 -07002827
2828 mediastream_signaling_.SendAudioVideoStream2();
2829 SessionDescriptionInterface* answer =
2830 CreateRemoteAnswer(session_->local_description());
2831 SetRemoteDescriptionWithoutError(answer);
2832
torbjornga81a42f2015-09-23 02:16:58 -07002833 EXPECT_EQ(session_->GetTransportProxy("audio")->impl(),
2834 session_->GetTransportProxy("video")->impl());
Donald Curtis0e209b02015-03-24 09:29:54 -07002835}
2836
2837// kBundlePolicyMaxBundle policy but no BUNDLE in the answer.
2838TEST_F(WebRtcSessionTest, TestMaxBundleNoBundleInAnswer) {
2839 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxBundle);
2840 mediastream_signaling_.SendAudioVideoStream1();
Peter Thatcher4eddf182015-04-30 10:55:59 -07002841
Donald Curtis0e209b02015-03-24 09:29:54 -07002842 PeerConnectionInterface::RTCOfferAnswerOptions options;
2843 options.use_rtp_mux = true;
2844
2845 SessionDescriptionInterface* offer = CreateOffer(options);
2846 SetLocalDescriptionWithoutError(offer);
2847
torbjornga81a42f2015-09-23 02:16:58 -07002848 EXPECT_EQ(session_->GetTransportProxy("audio")->impl(),
2849 session_->GetTransportProxy("video")->impl());
Donald Curtis0e209b02015-03-24 09:29:54 -07002850
2851 mediastream_signaling_.SendAudioVideoStream2();
2852
2853 // Remove BUNDLE from the answer.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002854 rtc::scoped_ptr<SessionDescriptionInterface> answer(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002855 CreateRemoteAnswer(session_->local_description()));
2856 cricket::SessionDescription* answer_copy = answer->description()->Copy();
2857 answer_copy->RemoveGroupByName(cricket::GROUP_TYPE_BUNDLE);
2858 JsepSessionDescription* modified_answer =
2859 new JsepSessionDescription(JsepSessionDescription::kAnswer);
2860 modified_answer->Initialize(answer_copy, "1", "1");
2861 SetRemoteDescriptionWithoutError(modified_answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002862
torbjornga81a42f2015-09-23 02:16:58 -07002863 EXPECT_EQ(session_->GetTransportProxy("audio")->impl(),
2864 session_->GetTransportProxy("video")->impl());
Donald Curtis0e209b02015-03-24 09:29:54 -07002865}
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002866
Peter Thatcher4eddf182015-04-30 10:55:59 -07002867// kBundlePolicyMaxCompat bundle policy and answer contains BUNDLE.
Donald Curtis0e209b02015-03-24 09:29:54 -07002868TEST_F(WebRtcSessionTest, TestMaxCompatBundleInAnswer) {
2869 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxCompat);
2870 mediastream_signaling_.SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002871
Donald Curtis0e209b02015-03-24 09:29:54 -07002872 PeerConnectionInterface::RTCOfferAnswerOptions options;
2873 options.use_rtp_mux = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002874
Donald Curtis0e209b02015-03-24 09:29:54 -07002875 SessionDescriptionInterface* offer = CreateOffer(options);
2876 SetLocalDescriptionWithoutError(offer);
2877
torbjornga81a42f2015-09-23 02:16:58 -07002878 EXPECT_NE(session_->GetTransportProxy("audio")->impl(),
2879 session_->GetTransportProxy("video")->impl());
Donald Curtis0e209b02015-03-24 09:29:54 -07002880
2881 mediastream_signaling_.SendAudioVideoStream2();
2882 SessionDescriptionInterface* answer =
2883 CreateRemoteAnswer(session_->local_description());
2884 SetRemoteDescriptionWithoutError(answer);
2885
2886 // This should lead to an audio-only call but isn't implemented
2887 // correctly yet.
torbjornga81a42f2015-09-23 02:16:58 -07002888 EXPECT_EQ(session_->GetTransportProxy("audio")->impl(),
2889 session_->GetTransportProxy("video")->impl());
Donald Curtis0e209b02015-03-24 09:29:54 -07002890}
2891
torbjornga81a42f2015-09-23 02:16:58 -07002892// kBundlePolicyMaxCompat bundle policy but no BUNDLE in the answer.
Donald Curtis0e209b02015-03-24 09:29:54 -07002893TEST_F(WebRtcSessionTest, TestMaxCompatNoBundleInAnswer) {
2894 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxCompat);
2895 mediastream_signaling_.SendAudioVideoStream1();
2896 PeerConnectionInterface::RTCOfferAnswerOptions options;
2897 options.use_rtp_mux = true;
2898
2899 SessionDescriptionInterface* offer = CreateOffer(options);
2900 SetLocalDescriptionWithoutError(offer);
2901
torbjornga81a42f2015-09-23 02:16:58 -07002902 EXPECT_NE(session_->GetTransportProxy("audio")->impl(),
2903 session_->GetTransportProxy("video")->impl());
Donald Curtis0e209b02015-03-24 09:29:54 -07002904
2905 mediastream_signaling_.SendAudioVideoStream2();
2906
2907 // Remove BUNDLE from the answer.
2908 rtc::scoped_ptr<SessionDescriptionInterface> answer(
2909 CreateRemoteAnswer(session_->local_description()));
2910 cricket::SessionDescription* answer_copy = answer->description()->Copy();
2911 answer_copy->RemoveGroupByName(cricket::GROUP_TYPE_BUNDLE);
2912 JsepSessionDescription* modified_answer =
2913 new JsepSessionDescription(JsepSessionDescription::kAnswer);
2914 modified_answer->Initialize(answer_copy, "1", "1");
2915 SetRemoteDescriptionWithoutError(modified_answer); //
2916
torbjornga81a42f2015-09-23 02:16:58 -07002917 EXPECT_NE(session_->GetTransportProxy("audio")->impl(),
2918 session_->GetTransportProxy("video")->impl());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002919}
2920
Peter Thatcher4eddf182015-04-30 10:55:59 -07002921// kBundlePolicyMaxbundle and then we call SetRemoteDescription first.
2922TEST_F(WebRtcSessionTest, TestMaxBundleWithSetRemoteDescriptionFirst) {
2923 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxBundle);
2924 mediastream_signaling_.SendAudioVideoStream1();
2925
2926 PeerConnectionInterface::RTCOfferAnswerOptions options;
2927 options.use_rtp_mux = true;
2928
2929 SessionDescriptionInterface* offer = CreateOffer(options);
2930 SetRemoteDescriptionWithoutError(offer);
2931
torbjornga81a42f2015-09-23 02:16:58 -07002932 EXPECT_EQ(session_->GetTransportProxy("audio")->impl(),
2933 session_->GetTransportProxy("video")->impl());
Peter Thatcher4eddf182015-04-30 10:55:59 -07002934}
2935
Peter Thatcheraf55ccc2015-05-21 07:48:41 -07002936TEST_F(WebRtcSessionTest, TestRequireRtcpMux) {
2937 InitWithRtcpMuxPolicy(PeerConnectionInterface::kRtcpMuxPolicyRequire);
2938 mediastream_signaling_.SendAudioVideoStream1();
2939
2940 PeerConnectionInterface::RTCOfferAnswerOptions options;
2941 SessionDescriptionInterface* offer = CreateOffer(options);
2942 SetLocalDescriptionWithoutError(offer);
2943
torbjornga81a42f2015-09-23 02:16:58 -07002944 EXPECT_FALSE(session_->GetTransportProxy("audio")->impl()->HasChannel(2));
2945 EXPECT_FALSE(session_->GetTransportProxy("video")->impl()->HasChannel(2));
Peter Thatcheraf55ccc2015-05-21 07:48:41 -07002946
2947 mediastream_signaling_.SendAudioVideoStream2();
2948 SessionDescriptionInterface* answer =
2949 CreateRemoteAnswer(session_->local_description());
2950 SetRemoteDescriptionWithoutError(answer);
2951
torbjornga81a42f2015-09-23 02:16:58 -07002952 EXPECT_FALSE(session_->GetTransportProxy("audio")->impl()->HasChannel(2));
2953 EXPECT_FALSE(session_->GetTransportProxy("video")->impl()->HasChannel(2));
Peter Thatcheraf55ccc2015-05-21 07:48:41 -07002954}
2955
2956TEST_F(WebRtcSessionTest, TestNegotiateRtcpMux) {
2957 InitWithRtcpMuxPolicy(PeerConnectionInterface::kRtcpMuxPolicyNegotiate);
2958 mediastream_signaling_.SendAudioVideoStream1();
2959
2960 PeerConnectionInterface::RTCOfferAnswerOptions options;
2961 SessionDescriptionInterface* offer = CreateOffer(options);
2962 SetLocalDescriptionWithoutError(offer);
2963
torbjornga81a42f2015-09-23 02:16:58 -07002964 EXPECT_TRUE(session_->GetTransportProxy("audio")->impl()->HasChannel(2));
2965 EXPECT_TRUE(session_->GetTransportProxy("video")->impl()->HasChannel(2));
Peter Thatcheraf55ccc2015-05-21 07:48:41 -07002966
2967 mediastream_signaling_.SendAudioVideoStream2();
2968 SessionDescriptionInterface* answer =
2969 CreateRemoteAnswer(session_->local_description());
2970 SetRemoteDescriptionWithoutError(answer);
2971
torbjornga81a42f2015-09-23 02:16:58 -07002972 EXPECT_FALSE(session_->GetTransportProxy("audio")->impl()->HasChannel(2));
2973 EXPECT_FALSE(session_->GetTransportProxy("video")->impl()->HasChannel(2));
Peter Thatcheraf55ccc2015-05-21 07:48:41 -07002974}
2975
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002976// This test verifies that SetLocalDescription and SetRemoteDescription fails
2977// if BUNDLE is enabled but rtcp-mux is disabled in m-lines.
2978TEST_F(WebRtcSessionTest, TestDisabledRtcpMuxWithBundleEnabled) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002979 Init();
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002980 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002981
2982 PeerConnectionInterface::RTCOfferAnswerOptions options;
2983 options.use_rtp_mux = true;
2984
2985 SessionDescriptionInterface* offer = CreateOffer(options);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002986 std::string offer_str;
2987 offer->ToString(&offer_str);
2988 // Disable rtcp-mux
2989 const std::string rtcp_mux = "rtcp-mux";
2990 const std::string xrtcp_mux = "xrtcp-mux";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002991 rtc::replace_substrs(rtcp_mux.c_str(), rtcp_mux.length(),
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002992 xrtcp_mux.c_str(), xrtcp_mux.length(),
2993 &offer_str);
torbjornga81a42f2015-09-23 02:16:58 -07002994 JsepSessionDescription *local_offer =
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002995 new JsepSessionDescription(JsepSessionDescription::kOffer);
2996 EXPECT_TRUE((local_offer)->Initialize(offer_str, NULL));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00002997 SetLocalDescriptionOfferExpectError(kBundleWithoutRtcpMux, local_offer);
torbjornga81a42f2015-09-23 02:16:58 -07002998 JsepSessionDescription *remote_offer =
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002999 new JsepSessionDescription(JsepSessionDescription::kOffer);
3000 EXPECT_TRUE((remote_offer)->Initialize(offer_str, NULL));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003001 SetRemoteDescriptionOfferExpectError(kBundleWithoutRtcpMux, remote_offer);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00003002 // Trying unmodified SDP.
3003 SetLocalDescriptionWithoutError(offer);
3004}
3005
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003006TEST_F(WebRtcSessionTest, SetAudioPlayout) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003007 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003008 mediastream_signaling_.SendAudioVideoStream1();
3009 CreateAndSetRemoteOfferAndLocalAnswer();
3010 cricket::FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0);
3011 ASSERT_TRUE(channel != NULL);
3012 ASSERT_EQ(1u, channel->recv_streams().size());
3013 uint32 receive_ssrc = channel->recv_streams()[0].first_ssrc();
3014 double left_vol, right_vol;
3015 EXPECT_TRUE(channel->GetOutputScaling(receive_ssrc, &left_vol, &right_vol));
3016 EXPECT_EQ(1, left_vol);
3017 EXPECT_EQ(1, right_vol);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003018 rtc::scoped_ptr<FakeAudioRenderer> renderer(new FakeAudioRenderer());
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00003019 session_->SetAudioPlayout(receive_ssrc, false, renderer.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003020 EXPECT_TRUE(channel->GetOutputScaling(receive_ssrc, &left_vol, &right_vol));
3021 EXPECT_EQ(0, left_vol);
3022 EXPECT_EQ(0, right_vol);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00003023 EXPECT_EQ(0, renderer->channel_id());
3024 session_->SetAudioPlayout(receive_ssrc, true, NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003025 EXPECT_TRUE(channel->GetOutputScaling(receive_ssrc, &left_vol, &right_vol));
3026 EXPECT_EQ(1, left_vol);
3027 EXPECT_EQ(1, right_vol);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00003028 EXPECT_EQ(-1, renderer->channel_id());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003029}
3030
3031TEST_F(WebRtcSessionTest, SetAudioSend) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003032 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003033 mediastream_signaling_.SendAudioVideoStream1();
3034 CreateAndSetRemoteOfferAndLocalAnswer();
3035 cricket::FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0);
3036 ASSERT_TRUE(channel != NULL);
3037 ASSERT_EQ(1u, channel->send_streams().size());
3038 uint32 send_ssrc = channel->send_streams()[0].first_ssrc();
3039 EXPECT_FALSE(channel->IsStreamMuted(send_ssrc));
3040
3041 cricket::AudioOptions options;
3042 options.echo_cancellation.Set(true);
3043
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003044 rtc::scoped_ptr<FakeAudioRenderer> renderer(new FakeAudioRenderer());
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00003045 session_->SetAudioSend(send_ssrc, false, options, renderer.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003046 EXPECT_TRUE(channel->IsStreamMuted(send_ssrc));
3047 EXPECT_FALSE(channel->options().echo_cancellation.IsSet());
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00003048 EXPECT_EQ(0, renderer->channel_id());
henrike@webrtc.orga7b98182014-02-21 15:51:43 +00003049 EXPECT_TRUE(renderer->sink() != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003050
henrike@webrtc.orga7b98182014-02-21 15:51:43 +00003051 // This will trigger SetSink(NULL) to the |renderer|.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00003052 session_->SetAudioSend(send_ssrc, true, options, NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003053 EXPECT_FALSE(channel->IsStreamMuted(send_ssrc));
3054 bool value;
3055 EXPECT_TRUE(channel->options().echo_cancellation.Get(&value));
3056 EXPECT_TRUE(value);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00003057 EXPECT_EQ(-1, renderer->channel_id());
henrike@webrtc.orga7b98182014-02-21 15:51:43 +00003058 EXPECT_TRUE(renderer->sink() == NULL);
3059}
3060
3061TEST_F(WebRtcSessionTest, AudioRendererForLocalStream) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003062 Init();
henrike@webrtc.orga7b98182014-02-21 15:51:43 +00003063 mediastream_signaling_.SendAudioVideoStream1();
3064 CreateAndSetRemoteOfferAndLocalAnswer();
3065 cricket::FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0);
3066 ASSERT_TRUE(channel != NULL);
3067 ASSERT_EQ(1u, channel->send_streams().size());
3068 uint32 send_ssrc = channel->send_streams()[0].first_ssrc();
3069
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003070 rtc::scoped_ptr<FakeAudioRenderer> renderer(new FakeAudioRenderer());
henrike@webrtc.orga7b98182014-02-21 15:51:43 +00003071 cricket::AudioOptions options;
3072 session_->SetAudioSend(send_ssrc, true, options, renderer.get());
3073 EXPECT_TRUE(renderer->sink() != NULL);
3074
3075 // Delete the |renderer| and it will trigger OnClose() to the sink, and this
3076 // will invalidate the |renderer_| pointer in the sink and prevent getting a
3077 // SetSink(NULL) callback afterwards.
3078 renderer.reset();
3079
3080 // This will trigger SetSink(NULL) if no OnClose() callback.
3081 session_->SetAudioSend(send_ssrc, true, options, NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003082}
3083
3084TEST_F(WebRtcSessionTest, SetVideoPlayout) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003085 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003086 mediastream_signaling_.SendAudioVideoStream1();
3087 CreateAndSetRemoteOfferAndLocalAnswer();
3088 cricket::FakeVideoMediaChannel* channel = media_engine_->GetVideoChannel(0);
3089 ASSERT_TRUE(channel != NULL);
3090 ASSERT_LT(0u, channel->renderers().size());
3091 EXPECT_TRUE(channel->renderers().begin()->second == NULL);
3092 ASSERT_EQ(1u, channel->recv_streams().size());
3093 uint32 receive_ssrc = channel->recv_streams()[0].first_ssrc();
3094 cricket::FakeVideoRenderer renderer;
3095 session_->SetVideoPlayout(receive_ssrc, true, &renderer);
3096 EXPECT_TRUE(channel->renderers().begin()->second == &renderer);
3097 session_->SetVideoPlayout(receive_ssrc, false, &renderer);
3098 EXPECT_TRUE(channel->renderers().begin()->second == NULL);
3099}
3100
3101TEST_F(WebRtcSessionTest, SetVideoSend) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003102 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003103 mediastream_signaling_.SendAudioVideoStream1();
3104 CreateAndSetRemoteOfferAndLocalAnswer();
3105 cricket::FakeVideoMediaChannel* channel = media_engine_->GetVideoChannel(0);
3106 ASSERT_TRUE(channel != NULL);
3107 ASSERT_EQ(1u, channel->send_streams().size());
3108 uint32 send_ssrc = channel->send_streams()[0].first_ssrc();
3109 EXPECT_FALSE(channel->IsStreamMuted(send_ssrc));
3110 cricket::VideoOptions* options = NULL;
3111 session_->SetVideoSend(send_ssrc, false, options);
3112 EXPECT_TRUE(channel->IsStreamMuted(send_ssrc));
3113 session_->SetVideoSend(send_ssrc, true, options);
3114 EXPECT_FALSE(channel->IsStreamMuted(send_ssrc));
3115}
3116
3117TEST_F(WebRtcSessionTest, CanNotInsertDtmf) {
3118 TestCanInsertDtmf(false);
3119}
3120
3121TEST_F(WebRtcSessionTest, CanInsertDtmf) {
3122 TestCanInsertDtmf(true);
3123}
3124
3125TEST_F(WebRtcSessionTest, InsertDtmf) {
3126 // Setup
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003127 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003128 mediastream_signaling_.SendAudioVideoStream1();
3129 CreateAndSetRemoteOfferAndLocalAnswer();
3130 FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0);
3131 EXPECT_EQ(0U, channel->dtmf_info_queue().size());
3132
3133 // Insert DTMF
3134 const int expected_flags = DF_SEND;
3135 const int expected_duration = 90;
3136 session_->InsertDtmf(kAudioTrack1, 0, expected_duration);
3137 session_->InsertDtmf(kAudioTrack1, 1, expected_duration);
3138 session_->InsertDtmf(kAudioTrack1, 2, expected_duration);
3139
3140 // Verify
3141 ASSERT_EQ(3U, channel->dtmf_info_queue().size());
3142 const uint32 send_ssrc = channel->send_streams()[0].first_ssrc();
3143 EXPECT_TRUE(CompareDtmfInfo(channel->dtmf_info_queue()[0], send_ssrc, 0,
3144 expected_duration, expected_flags));
3145 EXPECT_TRUE(CompareDtmfInfo(channel->dtmf_info_queue()[1], send_ssrc, 1,
3146 expected_duration, expected_flags));
3147 EXPECT_TRUE(CompareDtmfInfo(channel->dtmf_info_queue()[2], send_ssrc, 2,
3148 expected_duration, expected_flags));
3149}
3150
3151// This test verifies the |initiator| flag when session initiates the call.
3152TEST_F(WebRtcSessionTest, TestInitiatorFlagAsOriginator) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003153 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003154 EXPECT_FALSE(session_->initiator());
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003155 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003156 SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
3157 SetLocalDescriptionWithoutError(offer);
3158 EXPECT_TRUE(session_->initiator());
3159 SetRemoteDescriptionWithoutError(answer);
3160 EXPECT_TRUE(session_->initiator());
3161}
3162
3163// This test verifies the |initiator| flag when session receives the call.
3164TEST_F(WebRtcSessionTest, TestInitiatorFlagAsReceiver) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003165 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003166 EXPECT_FALSE(session_->initiator());
3167 SessionDescriptionInterface* offer = CreateRemoteOffer();
3168 SetRemoteDescriptionWithoutError(offer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003169 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003170
3171 EXPECT_FALSE(session_->initiator());
3172 SetLocalDescriptionWithoutError(answer);
3173 EXPECT_FALSE(session_->initiator());
3174}
3175
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003176// Verifing local offer and remote answer have matching m-lines as per RFC 3264.
3177TEST_F(WebRtcSessionTest, TestIncorrectMLinesInRemoteAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003178 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003179 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003180 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003181 SetLocalDescriptionWithoutError(offer);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003182 rtc::scoped_ptr<SessionDescriptionInterface> answer(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003183 CreateRemoteAnswer(session_->local_description()));
3184
3185 cricket::SessionDescription* answer_copy = answer->description()->Copy();
3186 answer_copy->RemoveContentByName("video");
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00003187 JsepSessionDescription* modified_answer =
3188 new JsepSessionDescription(JsepSessionDescription::kAnswer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003189
3190 EXPECT_TRUE(modified_answer->Initialize(answer_copy,
3191 answer->session_id(),
3192 answer->session_version()));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003193 SetRemoteDescriptionAnswerExpectError(kMlineMismatch, modified_answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003194
wu@webrtc.org4e393072014-04-07 17:04:35 +00003195 // Different content names.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003196 std::string sdp;
3197 EXPECT_TRUE(answer->ToString(&sdp));
3198 const std::string kAudioMid = "a=mid:audio";
3199 const std::string kAudioMidReplaceStr = "a=mid:audio_content_name";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003200 rtc::replace_substrs(kAudioMid.c_str(), kAudioMid.length(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003201 kAudioMidReplaceStr.c_str(),
3202 kAudioMidReplaceStr.length(),
3203 &sdp);
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00003204 SessionDescriptionInterface* modified_answer1 =
3205 CreateSessionDescription(JsepSessionDescription::kAnswer, sdp, NULL);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003206 SetRemoteDescriptionAnswerExpectError(kMlineMismatch, modified_answer1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003207
wu@webrtc.org4e393072014-04-07 17:04:35 +00003208 // Different media types.
3209 EXPECT_TRUE(answer->ToString(&sdp));
3210 const std::string kAudioMline = "m=audio";
3211 const std::string kAudioMlineReplaceStr = "m=video";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003212 rtc::replace_substrs(kAudioMline.c_str(), kAudioMline.length(),
wu@webrtc.org4e393072014-04-07 17:04:35 +00003213 kAudioMlineReplaceStr.c_str(),
3214 kAudioMlineReplaceStr.length(),
3215 &sdp);
3216 SessionDescriptionInterface* modified_answer2 =
3217 CreateSessionDescription(JsepSessionDescription::kAnswer, sdp, NULL);
3218 SetRemoteDescriptionAnswerExpectError(kMlineMismatch, modified_answer2);
3219
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003220 SetRemoteDescriptionWithoutError(answer.release());
3221}
3222
3223// Verifying remote offer and local answer have matching m-lines as per
3224// RFC 3264.
3225TEST_F(WebRtcSessionTest, TestIncorrectMLinesInLocalAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003226 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003227 mediastream_signaling_.SendAudioVideoStream1();
3228 SessionDescriptionInterface* offer = CreateRemoteOffer();
3229 SetRemoteDescriptionWithoutError(offer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003230 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003231
3232 cricket::SessionDescription* answer_copy = answer->description()->Copy();
3233 answer_copy->RemoveContentByName("video");
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00003234 JsepSessionDescription* modified_answer =
3235 new JsepSessionDescription(JsepSessionDescription::kAnswer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003236
3237 EXPECT_TRUE(modified_answer->Initialize(answer_copy,
3238 answer->session_id(),
3239 answer->session_version()));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003240 SetLocalDescriptionAnswerExpectError(kMlineMismatch, modified_answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003241 SetLocalDescriptionWithoutError(answer);
3242}
3243
3244// This test verifies that WebRtcSession does not start candidate allocation
3245// before SetLocalDescription is called.
3246TEST_F(WebRtcSessionTest, TestIceStartAfterSetLocalDescriptionOnly) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003247 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003248 mediastream_signaling_.SendAudioVideoStream1();
3249 SessionDescriptionInterface* offer = CreateRemoteOffer();
3250 cricket::Candidate candidate;
3251 candidate.set_component(1);
3252 JsepIceCandidate ice_candidate(kMediaContentName0, kMediaContentIndex0,
3253 candidate);
3254 EXPECT_TRUE(offer->AddCandidate(&ice_candidate));
3255 cricket::Candidate candidate1;
3256 candidate1.set_component(1);
3257 JsepIceCandidate ice_candidate1(kMediaContentName1, kMediaContentIndex1,
3258 candidate1);
3259 EXPECT_TRUE(offer->AddCandidate(&ice_candidate1));
3260 SetRemoteDescriptionWithoutError(offer);
torbjornga81a42f2015-09-23 02:16:58 -07003261 ASSERT_TRUE(session_->GetTransportProxy("audio") != NULL);
3262 ASSERT_TRUE(session_->GetTransportProxy("video") != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003263
3264 // Pump for 1 second and verify that no candidates are generated.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003265 rtc::Thread::Current()->ProcessMessages(1000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003266 EXPECT_TRUE(observer_.mline_0_candidates_.empty());
3267 EXPECT_TRUE(observer_.mline_1_candidates_.empty());
3268
wu@webrtc.org91053e72013-08-10 07:18:04 +00003269 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003270 SetLocalDescriptionWithoutError(answer);
torbjornga81a42f2015-09-23 02:16:58 -07003271 EXPECT_TRUE(session_->GetTransportProxy("audio")->negotiated());
3272 EXPECT_TRUE(session_->GetTransportProxy("video")->negotiated());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003273 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
3274}
3275
3276// This test verifies that crypto parameter is updated in local session
3277// description as per security policy set in MediaSessionDescriptionFactory.
3278TEST_F(WebRtcSessionTest, TestCryptoAfterSetLocalDescription) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003279 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003280 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003281 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003282
3283 // Making sure SetLocalDescription correctly sets crypto value in
3284 // SessionDescription object after de-serialization of sdp string. The value
3285 // will be set as per MediaSessionDescriptionFactory.
3286 std::string offer_str;
3287 offer->ToString(&offer_str);
3288 SessionDescriptionInterface* jsep_offer_str =
3289 CreateSessionDescription(JsepSessionDescription::kOffer, offer_str, NULL);
3290 SetLocalDescriptionWithoutError(jsep_offer_str);
3291 EXPECT_TRUE(session_->voice_channel()->secure_required());
3292 EXPECT_TRUE(session_->video_channel()->secure_required());
3293}
3294
3295// This test verifies the crypto parameter when security is disabled.
3296TEST_F(WebRtcSessionTest, TestCryptoAfterSetLocalDescriptionWithDisabled) {
wu@webrtc.org97077a32013-10-25 21:18:33 +00003297 options_.disable_encryption = true;
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003298 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003299 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003300 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003301
3302 // Making sure SetLocalDescription correctly sets crypto value in
3303 // SessionDescription object after de-serialization of sdp string. The value
3304 // will be set as per MediaSessionDescriptionFactory.
3305 std::string offer_str;
3306 offer->ToString(&offer_str);
torbjornga81a42f2015-09-23 02:16:58 -07003307 SessionDescriptionInterface *jsep_offer_str =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003308 CreateSessionDescription(JsepSessionDescription::kOffer, offer_str, NULL);
3309 SetLocalDescriptionWithoutError(jsep_offer_str);
3310 EXPECT_FALSE(session_->voice_channel()->secure_required());
3311 EXPECT_FALSE(session_->video_channel()->secure_required());
3312}
3313
3314// This test verifies that an answer contains new ufrag and password if an offer
3315// with new ufrag and password is received.
3316TEST_F(WebRtcSessionTest, TestCreateAnswerWithNewUfragAndPassword) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003317 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003318 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00003319 options.recv_video = true;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003320 rtc::scoped_ptr<JsepSessionDescription> offer(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003321 CreateRemoteOffer(options));
3322 SetRemoteDescriptionWithoutError(offer.release());
3323
3324 mediastream_signaling_.SendAudioVideoStream1();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003325 rtc::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00003326 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003327 SetLocalDescriptionWithoutError(answer.release());
3328
3329 // Receive an offer with new ufrag and password.
3330 options.transport_options.ice_restart = true;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003331 rtc::scoped_ptr<JsepSessionDescription> updated_offer1(
wu@webrtc.org91053e72013-08-10 07:18:04 +00003332 CreateRemoteOffer(options, session_->remote_description()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003333 SetRemoteDescriptionWithoutError(updated_offer1.release());
3334
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003335 rtc::scoped_ptr<SessionDescriptionInterface> updated_answer1(
wu@webrtc.org91053e72013-08-10 07:18:04 +00003336 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003337
3338 CompareIceUfragAndPassword(updated_answer1->description(),
3339 session_->local_description()->description(),
3340 false);
3341
3342 SetLocalDescriptionWithoutError(updated_answer1.release());
wu@webrtc.org91053e72013-08-10 07:18:04 +00003343}
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003344
wu@webrtc.org91053e72013-08-10 07:18:04 +00003345// This test verifies that an answer contains old ufrag and password if an offer
3346// with old ufrag and password is received.
3347TEST_F(WebRtcSessionTest, TestCreateAnswerWithOldUfragAndPassword) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003348 Init();
wu@webrtc.org91053e72013-08-10 07:18:04 +00003349 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00003350 options.recv_video = true;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003351 rtc::scoped_ptr<JsepSessionDescription> offer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00003352 CreateRemoteOffer(options));
3353 SetRemoteDescriptionWithoutError(offer.release());
3354
3355 mediastream_signaling_.SendAudioVideoStream1();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003356 rtc::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00003357 CreateAnswer(NULL));
3358 SetLocalDescriptionWithoutError(answer.release());
3359
3360 // Receive an offer without changed ufrag or password.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003361 options.transport_options.ice_restart = false;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003362 rtc::scoped_ptr<JsepSessionDescription> updated_offer2(
wu@webrtc.org91053e72013-08-10 07:18:04 +00003363 CreateRemoteOffer(options, session_->remote_description()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003364 SetRemoteDescriptionWithoutError(updated_offer2.release());
3365
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003366 rtc::scoped_ptr<SessionDescriptionInterface> updated_answer2(
wu@webrtc.org91053e72013-08-10 07:18:04 +00003367 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003368
3369 CompareIceUfragAndPassword(updated_answer2->description(),
3370 session_->local_description()->description(),
3371 true);
3372
3373 SetLocalDescriptionWithoutError(updated_answer2.release());
3374}
3375
3376TEST_F(WebRtcSessionTest, TestSessionContentError) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003377 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003378 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003379 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003380 const std::string session_id_orig = offer->session_id();
3381 const std::string session_version_orig = offer->session_version();
3382 SetLocalDescriptionWithoutError(offer);
3383
3384 video_channel_ = media_engine_->GetVideoChannel(0);
3385 video_channel_->set_fail_set_send_codecs(true);
3386
3387 mediastream_signaling_.SendAudioVideoStream2();
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00003388 SessionDescriptionInterface* answer =
3389 CreateRemoteAnswer(session_->local_description());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003390 SetRemoteDescriptionAnswerExpectError("ERROR_CONTENT", answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003391}
3392
3393// Runs the loopback call test with BUNDLE and STUN disabled.
3394TEST_F(WebRtcSessionTest, TestIceStatesBasic) {
3395 // Lets try with only UDP ports.
Peter Thatcher7cbd1882015-09-17 18:54:52 -07003396 allocator_->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00003397 cricket::PORTALLOCATOR_DISABLE_STUN |
3398 cricket::PORTALLOCATOR_DISABLE_RELAY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003399 TestLoopbackCall();
3400}
3401
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00003402TEST_F(WebRtcSessionTest, TestIceStatesBasicIPv6) {
Peter Thatcher7cbd1882015-09-17 18:54:52 -07003403 allocator_->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00003404 cricket::PORTALLOCATOR_DISABLE_STUN |
3405 cricket::PORTALLOCATOR_ENABLE_IPV6 |
3406 cricket::PORTALLOCATOR_DISABLE_RELAY);
3407
3408 // best connection is IPv6 since it has higher network preference.
3409 LoopbackNetworkConfiguration config;
3410 config.test_ipv6_network_ = true;
3411 config.best_connection_after_initial_ice_converged_ =
3412 LoopbackNetworkConfiguration::ExpectedBestConnection(0, 1);
3413
3414 TestLoopbackCall(config);
3415}
3416
mallinath@webrtc.orgd3dc4242014-03-01 00:05:52 +00003417// Runs the loopback call test with BUNDLE and STUN enabled.
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00003418TEST_F(WebRtcSessionTest, TestIceStatesBundle) {
Peter Thatcher7cbd1882015-09-17 18:54:52 -07003419 allocator_->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
3420 cricket::PORTALLOCATOR_DISABLE_RELAY);
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00003421 TestLoopbackCall();
3422}
3423
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003424TEST_F(WebRtcSessionTest, SetSdpFailedOnSessionError) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003425 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003426 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00003427 options.recv_video = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003428
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003429 cricket::BaseSession::Error error_code = cricket::BaseSession::ERROR_CONTENT;
3430 std::string error_code_str = "ERROR_CONTENT";
3431 std::string error_desc = "Fake session error description.";
3432 session_->SetError(error_code, error_desc);
3433
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003434 SessionDescriptionInterface* offer = CreateRemoteOffer(options);
3435 SessionDescriptionInterface* answer =
3436 CreateRemoteAnswer(offer, options);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003437
3438 std::string action;
3439 std::ostringstream session_error_msg;
3440 session_error_msg << kSessionError << error_code_str << ". ";
3441 session_error_msg << kSessionErrorDesc << error_desc << ".";
3442 SetRemoteDescriptionExpectError(action, session_error_msg.str(), offer);
3443 SetLocalDescriptionExpectError(action, session_error_msg.str(), answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003444}
3445
3446TEST_F(WebRtcSessionTest, TestRtpDataChannel) {
3447 constraints_.reset(new FakeConstraints());
3448 constraints_->AddOptional(
3449 webrtc::MediaConstraintsInterface::kEnableRtpDataChannels, true);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003450 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003451
3452 SetLocalDescriptionWithDataChannel();
3453 EXPECT_EQ(cricket::DCT_RTP, data_engine_->last_channel_type());
3454}
3455
Henrik Boström87713d02015-08-25 09:53:21 +02003456TEST_P(WebRtcSessionTest, TestRtpDataChannelConstraintTakesPrecedence) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003457 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003458
3459 constraints_.reset(new FakeConstraints());
3460 constraints_->AddOptional(
3461 webrtc::MediaConstraintsInterface::kEnableRtpDataChannels, true);
wu@webrtc.org97077a32013-10-25 21:18:33 +00003462 options_.disable_sctp_data_channels = false;
3463
Henrik Boström87713d02015-08-25 09:53:21 +02003464 InitWithDtls(GetParam());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003465
3466 SetLocalDescriptionWithDataChannel();
3467 EXPECT_EQ(cricket::DCT_RTP, data_engine_->last_channel_type());
3468}
3469
Henrik Boström87713d02015-08-25 09:53:21 +02003470TEST_P(WebRtcSessionTest, TestCreateOfferWithSctpEnabledWithoutStreams) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003471 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
wu@webrtc.org967bfff2013-09-19 05:49:50 +00003472
Henrik Boström87713d02015-08-25 09:53:21 +02003473 InitWithDtls(GetParam());
sergeyu@chromium.orga59696b2013-09-13 23:48:58 +00003474
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003475 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
sergeyu@chromium.orga59696b2013-09-13 23:48:58 +00003476 EXPECT_TRUE(offer->description()->GetContentByName("data") == NULL);
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00003477 EXPECT_TRUE(offer->description()->GetTransportInfoByName("data") == NULL);
3478}
3479
Henrik Boström87713d02015-08-25 09:53:21 +02003480TEST_P(WebRtcSessionTest, TestCreateAnswerWithSctpInOfferAndNoStreams) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003481 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00003482 SetFactoryDtlsSrtp();
Henrik Boström87713d02015-08-25 09:53:21 +02003483 InitWithDtls(GetParam());
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00003484
3485 // Create remote offer with SCTP.
3486 cricket::MediaSessionOptions options;
3487 options.data_channel_type = cricket::DCT_SCTP;
3488 JsepSessionDescription* offer =
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003489 CreateRemoteOffer(options, cricket::SEC_DISABLED);
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00003490 SetRemoteDescriptionWithoutError(offer);
3491
3492 // Verifies the answer contains SCTP.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003493 rtc::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00003494 EXPECT_TRUE(answer != NULL);
3495 EXPECT_TRUE(answer->description()->GetContentByName("data") != NULL);
3496 EXPECT_TRUE(answer->description()->GetTransportInfoByName("data") != NULL);
sergeyu@chromium.orga59696b2013-09-13 23:48:58 +00003497}
3498
Henrik Boström87713d02015-08-25 09:53:21 +02003499TEST_P(WebRtcSessionTest, TestSctpDataChannelWithoutDtls) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003500 constraints_.reset(new FakeConstraints());
3501 constraints_->AddOptional(
sergeyu@chromium.orga59696b2013-09-13 23:48:58 +00003502 webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, false);
Henrik Boström87713d02015-08-25 09:53:21 +02003503 InitWithDtls(GetParam());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003504
3505 SetLocalDescriptionWithDataChannel();
3506 EXPECT_EQ(cricket::DCT_NONE, data_engine_->last_channel_type());
3507}
3508
Henrik Boström87713d02015-08-25 09:53:21 +02003509TEST_P(WebRtcSessionTest, TestSctpDataChannelWithDtls) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003510 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003511
Henrik Boström87713d02015-08-25 09:53:21 +02003512 InitWithDtls(GetParam());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003513
3514 SetLocalDescriptionWithDataChannel();
3515 EXPECT_EQ(cricket::DCT_SCTP, data_engine_->last_channel_type());
3516}
wu@webrtc.org91053e72013-08-10 07:18:04 +00003517
Henrik Boström87713d02015-08-25 09:53:21 +02003518TEST_P(WebRtcSessionTest, TestDisableSctpDataChannels) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003519 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
wu@webrtc.org97077a32013-10-25 21:18:33 +00003520 options_.disable_sctp_data_channels = true;
Henrik Boström87713d02015-08-25 09:53:21 +02003521 InitWithDtls(GetParam());
wu@webrtc.org97077a32013-10-25 21:18:33 +00003522
3523 SetLocalDescriptionWithDataChannel();
3524 EXPECT_EQ(cricket::DCT_NONE, data_engine_->last_channel_type());
3525}
3526
Henrik Boström87713d02015-08-25 09:53:21 +02003527TEST_P(WebRtcSessionTest, TestSctpDataChannelSendPortParsing) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003528 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00003529 const int new_send_port = 9998;
3530 const int new_recv_port = 7775;
3531
Henrik Boström87713d02015-08-25 09:53:21 +02003532 InitWithDtls(GetParam());
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00003533 SetFactoryDtlsSrtp();
3534
3535 // By default, don't actually add the codecs to desc_factory_; they don't
3536 // actually get serialized for SCTP in BuildMediaDescription(). Instead,
3537 // let the session description get parsed. That'll get the proper codecs
3538 // into the stream.
3539 cricket::MediaSessionOptions options;
3540 JsepSessionDescription* offer = CreateRemoteOfferWithSctpPort(
3541 "stream1", new_send_port, options);
3542
3543 // SetRemoteDescription will take the ownership of the offer.
3544 SetRemoteDescriptionWithoutError(offer);
3545
3546 SessionDescriptionInterface* answer = ChangeSDPSctpPort(
3547 new_recv_port, CreateAnswer(NULL));
3548 ASSERT_TRUE(answer != NULL);
3549
3550 // Now set the local description, which'll take ownership of the answer.
3551 SetLocalDescriptionWithoutError(answer);
3552
3553 // TEST PLAN: Set the port number to something new, set it in the SDP,
3554 // and pass it all the way down.
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +00003555 webrtc::InternalDataChannelInit dci;
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00003556 dci.reliable = true;
3557 EXPECT_EQ(cricket::DCT_SCTP, data_engine_->last_channel_type());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003558 rtc::scoped_refptr<webrtc::DataChannel> dc =
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00003559 session_->CreateDataChannel("datachannel", &dci);
3560
3561 cricket::FakeDataMediaChannel* ch = data_engine_->GetChannel(0);
3562 int portnum = -1;
3563 ASSERT_TRUE(ch != NULL);
3564 ASSERT_EQ(1UL, ch->send_codecs().size());
3565 EXPECT_EQ(cricket::kGoogleSctpDataCodecId, ch->send_codecs()[0].id);
Donald Curtisd4f769d2015-05-28 09:48:21 -07003566 EXPECT_EQ(0, strcmp(cricket::kGoogleSctpDataCodecName,
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00003567 ch->send_codecs()[0].name.c_str()));
3568 EXPECT_TRUE(ch->send_codecs()[0].GetParam(cricket::kCodecParamPort,
3569 &portnum));
3570 EXPECT_EQ(new_send_port, portnum);
3571
3572 ASSERT_EQ(1UL, ch->recv_codecs().size());
3573 EXPECT_EQ(cricket::kGoogleSctpDataCodecId, ch->recv_codecs()[0].id);
Donald Curtisd4f769d2015-05-28 09:48:21 -07003574 EXPECT_EQ(0, strcmp(cricket::kGoogleSctpDataCodecName,
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00003575 ch->recv_codecs()[0].name.c_str()));
3576 EXPECT_TRUE(ch->recv_codecs()[0].GetParam(cricket::kCodecParamPort,
3577 &portnum));
3578 EXPECT_EQ(new_recv_port, portnum);
3579}
3580
Henrik Boströmd8281982015-08-27 10:12:24 +02003581TEST_F(WebRtcSessionTest, TestUsesProvidedCertificate) {
3582 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
3583 FakeDtlsIdentityStore::GenerateCertificate();
3584
3585 PeerConnectionInterface::RTCConfiguration configuration;
3586 configuration.certificates.push_back(certificate);
3587 Init(nullptr, configuration);
3588 EXPECT_TRUE_WAIT(!session_->waiting_for_certificate_for_testing(), 1000);
3589
3590 EXPECT_EQ(session_->certificate_for_testing(), certificate);
3591}
wu@webrtc.org91053e72013-08-10 07:18:04 +00003592
Henrik Boström87713d02015-08-25 09:53:21 +02003593// Verifies that CreateOffer succeeds when CreateOffer is called before async
3594// identity generation is finished (even if a certificate is provided this is
3595// an async op).
3596TEST_P(WebRtcSessionTest, TestCreateOfferBeforeIdentityRequestReturnSuccess) {
3597 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
3598 InitWithDtls(GetParam());
3599
Henrik Boströmd8281982015-08-27 10:12:24 +02003600 EXPECT_TRUE(session_->waiting_for_certificate_for_testing());
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003601 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003602 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
3603
wu@webrtc.org91053e72013-08-10 07:18:04 +00003604 EXPECT_TRUE(offer != NULL);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003605 VerifyNoCryptoParams(offer->description(), true);
3606 VerifyFingerprintStatus(offer->description(), true);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003607}
3608
3609// Verifies that CreateAnswer succeeds when CreateOffer is called before async
Henrik Boström87713d02015-08-25 09:53:21 +02003610// identity generation is finished (even if a certificate is provided this is
3611// an async op).
3612TEST_P(WebRtcSessionTest, TestCreateAnswerBeforeIdentityRequestReturnSuccess) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003613 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
Henrik Boström87713d02015-08-25 09:53:21 +02003614 InitWithDtls(GetParam());
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003615 SetFactoryDtlsSrtp();
wu@webrtc.org91053e72013-08-10 07:18:04 +00003616
3617 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00003618 options.recv_video = true;
wu@webrtc.org91053e72013-08-10 07:18:04 +00003619 scoped_ptr<JsepSessionDescription> offer(
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003620 CreateRemoteOffer(options, cricket::SEC_DISABLED));
wu@webrtc.org91053e72013-08-10 07:18:04 +00003621 ASSERT_TRUE(offer.get() != NULL);
3622 SetRemoteDescriptionWithoutError(offer.release());
3623
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003624 rtc::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
wu@webrtc.org91053e72013-08-10 07:18:04 +00003625 EXPECT_TRUE(answer != NULL);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003626 VerifyNoCryptoParams(answer->description(), true);
3627 VerifyFingerprintStatus(answer->description(), true);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003628}
3629
3630// Verifies that CreateOffer succeeds when CreateOffer is called after async
Henrik Boström87713d02015-08-25 09:53:21 +02003631// identity generation is finished (even if a certificate is provided this is
3632// an async op).
3633TEST_P(WebRtcSessionTest, TestCreateOfferAfterIdentityRequestReturnSuccess) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003634 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
Henrik Boström87713d02015-08-25 09:53:21 +02003635 InitWithDtls(GetParam());
wu@webrtc.org91053e72013-08-10 07:18:04 +00003636
Henrik Boströmd8281982015-08-27 10:12:24 +02003637 EXPECT_TRUE_WAIT(!session_->waiting_for_certificate_for_testing(), 1000);
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003638
3639 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
wu@webrtc.org91053e72013-08-10 07:18:04 +00003640 EXPECT_TRUE(offer != NULL);
3641}
3642
3643// Verifies that CreateOffer fails when CreateOffer is called after async
3644// identity generation fails.
3645TEST_F(WebRtcSessionTest, TestCreateOfferAfterIdentityRequestReturnFailure) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003646 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
Henrik Boström87713d02015-08-25 09:53:21 +02003647 InitWithDtlsIdentityGenFail();
wu@webrtc.org91053e72013-08-10 07:18:04 +00003648
Henrik Boströmd8281982015-08-27 10:12:24 +02003649 EXPECT_TRUE_WAIT(!session_->waiting_for_certificate_for_testing(), 1000);
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003650
3651 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
wu@webrtc.org91053e72013-08-10 07:18:04 +00003652 EXPECT_TRUE(offer == NULL);
3653}
3654
3655// Verifies that CreateOffer succeeds when Multiple CreateOffer calls are made
3656// before async identity generation is finished.
Henrik Boström87713d02015-08-25 09:53:21 +02003657TEST_P(WebRtcSessionTest,
wu@webrtc.org91053e72013-08-10 07:18:04 +00003658 TestMultipleCreateOfferBeforeIdentityRequestReturnSuccess) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003659 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
torbjornga81a42f2015-09-23 02:16:58 -07003660 VerifyMultipleAsyncCreateDescription(
3661 GetParam(), CreateSessionDescriptionRequest::kOffer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003662}
3663
3664// Verifies that CreateOffer fails when Multiple CreateOffer calls are made
3665// before async identity generation fails.
3666TEST_F(WebRtcSessionTest,
3667 TestMultipleCreateOfferBeforeIdentityRequestReturnFailure) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003668 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
Henrik Boström87713d02015-08-25 09:53:21 +02003669 VerifyMultipleAsyncCreateDescriptionIdentityGenFailure(
3670 CreateSessionDescriptionRequest::kOffer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003671}
3672
3673// Verifies that CreateAnswer succeeds when Multiple CreateAnswer calls are made
3674// before async identity generation is finished.
Henrik Boström87713d02015-08-25 09:53:21 +02003675TEST_P(WebRtcSessionTest,
wu@webrtc.org91053e72013-08-10 07:18:04 +00003676 TestMultipleCreateAnswerBeforeIdentityRequestReturnSuccess) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003677 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003678 VerifyMultipleAsyncCreateDescription(
Henrik Boström87713d02015-08-25 09:53:21 +02003679 GetParam(), CreateSessionDescriptionRequest::kAnswer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003680}
3681
3682// Verifies that CreateAnswer fails when Multiple CreateAnswer calls are made
3683// before async identity generation fails.
3684TEST_F(WebRtcSessionTest,
3685 TestMultipleCreateAnswerBeforeIdentityRequestReturnFailure) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003686 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
Henrik Boström87713d02015-08-25 09:53:21 +02003687 VerifyMultipleAsyncCreateDescriptionIdentityGenFailure(
3688 CreateSessionDescriptionRequest::kAnswer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003689}
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00003690
3691// Verifies that setRemoteDescription fails when DTLS is disabled and the remote
3692// offer has no SDES crypto but only DTLS fingerprint.
3693TEST_F(WebRtcSessionTest, TestSetRemoteOfferFailIfDtlsDisabledAndNoCrypto) {
3694 // Init without DTLS.
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003695 Init();
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00003696 // Create a remote offer with secured transport disabled.
3697 cricket::MediaSessionOptions options;
3698 JsepSessionDescription* offer(CreateRemoteOffer(
3699 options, cricket::SEC_DISABLED));
3700 // Adds a DTLS fingerprint to the remote offer.
3701 cricket::SessionDescription* sdp = offer->description();
3702 TransportInfo* audio = sdp->GetTransportInfoByName("audio");
3703 ASSERT_TRUE(audio != NULL);
3704 ASSERT_TRUE(audio->description.identity_fingerprint.get() == NULL);
3705 audio->description.identity_fingerprint.reset(
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003706 rtc::SSLFingerprint::CreateFromRfc4572(
3707 rtc::DIGEST_SHA_256, kFakeDtlsFingerprint));
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003708 SetRemoteDescriptionOfferExpectError(kSdpWithoutSdesCrypto,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003709 offer);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00003710}
3711
wu@webrtc.orgde305012013-10-31 15:40:38 +00003712// This test verifies DSCP is properly applied on the media channels.
3713TEST_F(WebRtcSessionTest, TestDscpConstraint) {
3714 constraints_.reset(new FakeConstraints());
3715 constraints_->AddOptional(
3716 webrtc::MediaConstraintsInterface::kEnableDscp, true);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003717 Init();
wu@webrtc.orgde305012013-10-31 15:40:38 +00003718 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003719 SessionDescriptionInterface* offer = CreateOffer();
wu@webrtc.orgde305012013-10-31 15:40:38 +00003720
3721 SetLocalDescriptionWithoutError(offer);
3722
3723 video_channel_ = media_engine_->GetVideoChannel(0);
3724 voice_channel_ = media_engine_->GetVoiceChannel(0);
3725
3726 ASSERT_TRUE(video_channel_ != NULL);
3727 ASSERT_TRUE(voice_channel_ != NULL);
solenberg66f43392015-09-09 01:36:22 -07003728 const cricket::AudioOptions& audio_options = voice_channel_->options();
3729 const cricket::VideoOptions& video_options = video_channel_->options();
wu@webrtc.orgde305012013-10-31 15:40:38 +00003730 EXPECT_TRUE(audio_options.dscp.IsSet());
3731 EXPECT_TRUE(audio_options.dscp.GetWithDefaultIfUnset(false));
3732 EXPECT_TRUE(video_options.dscp.IsSet());
3733 EXPECT_TRUE(video_options.dscp.GetWithDefaultIfUnset(false));
3734}
3735
henrike@webrtc.org6e3dbc22014-03-25 17:09:47 +00003736TEST_F(WebRtcSessionTest, TestSuspendBelowMinBitrateConstraint) {
3737 constraints_.reset(new FakeConstraints());
3738 constraints_->AddOptional(
3739 webrtc::MediaConstraintsInterface::kEnableVideoSuspendBelowMinBitrate,
3740 true);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003741 Init();
henrike@webrtc.org6e3dbc22014-03-25 17:09:47 +00003742 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003743 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org6e3dbc22014-03-25 17:09:47 +00003744
3745 SetLocalDescriptionWithoutError(offer);
3746
3747 video_channel_ = media_engine_->GetVideoChannel(0);
3748
3749 ASSERT_TRUE(video_channel_ != NULL);
solenberg66f43392015-09-09 01:36:22 -07003750 const cricket::VideoOptions& video_options = video_channel_->options();
henrike@webrtc.org6e3dbc22014-03-25 17:09:47 +00003751 EXPECT_TRUE(
3752 video_options.suspend_below_min_bitrate.GetWithDefaultIfUnset(false));
3753}
3754
buildbot@webrtc.org53df88c2014-08-07 22:46:01 +00003755TEST_F(WebRtcSessionTest, TestNumUnsignalledRecvStreamsConstraint) {
3756 // Number of unsignalled receiving streams should be between 0 and
3757 // kMaxUnsignalledRecvStreams.
3758 SetAndVerifyNumUnsignalledRecvStreams(10, 10);
3759 SetAndVerifyNumUnsignalledRecvStreams(kMaxUnsignalledRecvStreams + 1,
3760 kMaxUnsignalledRecvStreams);
3761 SetAndVerifyNumUnsignalledRecvStreams(-1, 0);
3762}
3763
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +00003764TEST_F(WebRtcSessionTest, TestCombinedAudioVideoBweConstraint) {
3765 constraints_.reset(new FakeConstraints());
3766 constraints_->AddOptional(
3767 webrtc::MediaConstraintsInterface::kCombinedAudioVideoBwe,
3768 true);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003769 Init();
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +00003770 mediastream_signaling_.SendAudioVideoStream1();
3771 SessionDescriptionInterface* offer = CreateOffer();
3772
3773 SetLocalDescriptionWithoutError(offer);
3774
3775 voice_channel_ = media_engine_->GetVoiceChannel(0);
3776
3777 ASSERT_TRUE(voice_channel_ != NULL);
solenberg66f43392015-09-09 01:36:22 -07003778 const cricket::AudioOptions& audio_options = voice_channel_->options();
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +00003779 EXPECT_TRUE(
3780 audio_options.combined_audio_video_bwe.GetWithDefaultIfUnset(false));
3781}
3782
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00003783// Tests that we can renegotiate new media content with ICE candidates in the
3784// new remote SDP.
Henrik Boström87713d02015-08-25 09:53:21 +02003785TEST_P(WebRtcSessionTest, TestRenegotiateNewMediaWithCandidatesInSdp) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003786 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
Henrik Boström87713d02015-08-25 09:53:21 +02003787 InitWithDtls(GetParam());
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00003788 SetFactoryDtlsSrtp();
3789
3790 mediastream_signaling_.UseOptionsAudioOnly();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003791 SessionDescriptionInterface* offer = CreateOffer();
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00003792 SetLocalDescriptionWithoutError(offer);
3793
3794 SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
3795 SetRemoteDescriptionWithoutError(answer);
3796
3797 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00003798 options.recv_video = true;
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00003799 offer = CreateRemoteOffer(options, cricket::SEC_DISABLED);
3800
3801 cricket::Candidate candidate1;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003802 candidate1.set_address(rtc::SocketAddress("1.1.1.1", 5000));
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00003803 candidate1.set_component(1);
3804 JsepIceCandidate ice_candidate(kMediaContentName1, kMediaContentIndex1,
3805 candidate1);
3806 EXPECT_TRUE(offer->AddCandidate(&ice_candidate));
3807 SetRemoteDescriptionWithoutError(offer);
3808
3809 answer = CreateAnswer(NULL);
3810 SetLocalDescriptionWithoutError(answer);
3811}
3812
3813// Tests that we can renegotiate new media content with ICE candidates separated
3814// from the remote SDP.
Henrik Boström87713d02015-08-25 09:53:21 +02003815TEST_P(WebRtcSessionTest, TestRenegotiateNewMediaWithCandidatesSeparated) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003816 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
Henrik Boström87713d02015-08-25 09:53:21 +02003817 InitWithDtls(GetParam());
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00003818 SetFactoryDtlsSrtp();
3819
3820 mediastream_signaling_.UseOptionsAudioOnly();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003821 SessionDescriptionInterface* offer = CreateOffer();
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00003822 SetLocalDescriptionWithoutError(offer);
3823
3824 SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
3825 SetRemoteDescriptionWithoutError(answer);
3826
3827 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00003828 options.recv_video = true;
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00003829 offer = CreateRemoteOffer(options, cricket::SEC_DISABLED);
3830 SetRemoteDescriptionWithoutError(offer);
3831
3832 cricket::Candidate candidate1;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003833 candidate1.set_address(rtc::SocketAddress("1.1.1.1", 5000));
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00003834 candidate1.set_component(1);
3835 JsepIceCandidate ice_candidate(kMediaContentName1, kMediaContentIndex1,
3836 candidate1);
3837 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate));
3838
3839 answer = CreateAnswer(NULL);
3840 SetLocalDescriptionWithoutError(answer);
3841}
changbin.shao@webrtc.org2d25b442015-03-16 04:14:34 +00003842// Tests that RTX codec is removed from the answer when it isn't supported
3843// by local side.
3844TEST_F(WebRtcSessionTest, TestRtxRemovedByCreateAnswer) {
3845 Init();
3846 mediastream_signaling_.SendAudioVideoStream1();
3847 std::string offer_sdp(kSdpWithRtx);
3848
3849 SessionDescriptionInterface* offer =
3850 CreateSessionDescription(JsepSessionDescription::kOffer, offer_sdp, NULL);
3851 EXPECT_TRUE(offer->ToString(&offer_sdp));
3852
3853 // Offer SDP contains the RTX codec.
3854 EXPECT_TRUE(offer_sdp.find("rtx") != std::string::npos);
3855 SetRemoteDescriptionWithoutError(offer);
3856
3857 SessionDescriptionInterface* answer = CreateAnswer(NULL);
3858 std::string answer_sdp;
3859 answer->ToString(&answer_sdp);
3860 // Answer SDP removes the unsupported RTX codec.
3861 EXPECT_TRUE(answer_sdp.find("rtx") == std::string::npos);
3862 SetLocalDescriptionWithoutError(answer);
3863}
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00003864
guoweis@webrtc.org4f852882015-03-12 20:09:44 +00003865// This verifies that the voice channel after bundle has both options from video
3866// and voice channels.
3867TEST_F(WebRtcSessionTest, TestSetSocketOptionBeforeBundle) {
3868 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyBalanced);
3869 mediastream_signaling_.SendAudioVideoStream1();
3870
3871 PeerConnectionInterface::RTCOfferAnswerOptions options;
3872 options.use_rtp_mux = true;
3873
3874 SessionDescriptionInterface* offer = CreateOffer(options);
3875 SetLocalDescriptionWithoutError(offer);
3876
3877 session_->video_channel()->SetOption(cricket::BaseChannel::ST_RTP,
3878 rtc::Socket::Option::OPT_SNDBUF, 4000);
3879
3880 session_->voice_channel()->SetOption(cricket::BaseChannel::ST_RTP,
3881 rtc::Socket::Option::OPT_RCVBUF, 8000);
3882
3883 int option_val;
torbjornga81a42f2015-09-23 02:16:58 -07003884 EXPECT_TRUE(session_->video_channel()->transport_channel()->GetOption(
guoweis@webrtc.org4f852882015-03-12 20:09:44 +00003885 rtc::Socket::Option::OPT_SNDBUF, &option_val));
3886 EXPECT_EQ(4000, option_val);
torbjornga81a42f2015-09-23 02:16:58 -07003887 EXPECT_FALSE(session_->voice_channel()->transport_channel()->GetOption(
guoweis@webrtc.org4f852882015-03-12 20:09:44 +00003888 rtc::Socket::Option::OPT_SNDBUF, &option_val));
3889
torbjornga81a42f2015-09-23 02:16:58 -07003890 EXPECT_TRUE(session_->voice_channel()->transport_channel()->GetOption(
guoweis@webrtc.org4f852882015-03-12 20:09:44 +00003891 rtc::Socket::Option::OPT_RCVBUF, &option_val));
3892 EXPECT_EQ(8000, option_val);
torbjornga81a42f2015-09-23 02:16:58 -07003893 EXPECT_FALSE(session_->video_channel()->transport_channel()->GetOption(
guoweis@webrtc.org4f852882015-03-12 20:09:44 +00003894 rtc::Socket::Option::OPT_RCVBUF, &option_val));
3895
torbjornga81a42f2015-09-23 02:16:58 -07003896 EXPECT_NE(session_->voice_channel()->transport_channel(),
3897 session_->video_channel()->transport_channel());
guoweis@webrtc.org4f852882015-03-12 20:09:44 +00003898
3899 mediastream_signaling_.SendAudioVideoStream2();
3900 SessionDescriptionInterface* answer =
3901 CreateRemoteAnswer(session_->local_description());
3902 SetRemoteDescriptionWithoutError(answer);
3903
torbjornga81a42f2015-09-23 02:16:58 -07003904 EXPECT_TRUE(session_->voice_channel()->transport_channel()->GetOption(
guoweis@webrtc.org4f852882015-03-12 20:09:44 +00003905 rtc::Socket::Option::OPT_SNDBUF, &option_val));
3906 EXPECT_EQ(4000, option_val);
3907
torbjornga81a42f2015-09-23 02:16:58 -07003908 EXPECT_TRUE(session_->voice_channel()->transport_channel()->GetOption(
guoweis@webrtc.org4f852882015-03-12 20:09:44 +00003909 rtc::Socket::Option::OPT_RCVBUF, &option_val));
3910 EXPECT_EQ(8000, option_val);
3911}
3912
tommi0f620f42015-07-09 03:25:02 -07003913// Test creating a session, request multiple offers, destroy the session
3914// and make sure we got success/failure callbacks for all of the requests.
3915// Background: crbug.com/507307
3916TEST_F(WebRtcSessionTest, CreateOffersAndShutdown) {
3917 Init();
3918
3919 rtc::scoped_refptr<WebRtcSessionCreateSDPObserverForTest> observers[100];
3920 PeerConnectionInterface::RTCOfferAnswerOptions options;
3921 options.offer_to_receive_audio =
3922 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
3923
3924 for (auto& o : observers) {
3925 o = new WebRtcSessionCreateSDPObserverForTest();
3926 session_->CreateOffer(o, options);
3927 }
3928
3929 session_.reset();
3930
tommi0f620f42015-07-09 03:25:02 -07003931 for (auto& o : observers) {
3932 // We expect to have received a notification now even if the session was
3933 // terminated. The offer creation may or may not have succeeded, but we
3934 // must have received a notification which, so the only invalid state
3935 // is kInit.
3936 EXPECT_NE(WebRtcSessionCreateSDPObserverForTest::kInit, o->state());
3937 }
3938}
3939
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003940// TODO(bemasc): Add a TestIceStatesBundle with BUNDLE enabled. That test
3941// currently fails because upon disconnection and reconnection OnIceComplete is
3942// called more than once without returning to IceGatheringGathering.
Henrik Boström87713d02015-08-25 09:53:21 +02003943
torbjornga81a42f2015-09-23 02:16:58 -07003944INSTANTIATE_TEST_CASE_P(
3945 WebRtcSessionTests, WebRtcSessionTest,
3946 testing::Values(ALREADY_GENERATED, DTLS_IDENTITY_STORE));