blob: 2b6f207e29cf345d82eb6d5a81ade3a0eb0f7d1b [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"
29#include "talk/app/webrtc/jsepicecandidate.h"
30#include "talk/app/webrtc/jsepsessiondescription.h"
31#include "talk/app/webrtc/mediastreamsignaling.h"
32#include "talk/app/webrtc/streamcollection.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000033#include "talk/app/webrtc/test/fakeconstraints.h"
wu@webrtc.org91053e72013-08-10 07:18:04 +000034#include "talk/app/webrtc/test/fakedtlsidentityservice.h"
35#include "talk/app/webrtc/test/fakemediastreamsignaling.h"
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000036#include "talk/app/webrtc/videotrack.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000037#include "talk/app/webrtc/webrtcsession.h"
wu@webrtc.org91053e72013-08-10 07:18:04 +000038#include "talk/app/webrtc/webrtcsessiondescriptionfactory.h"
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000039#include "talk/media/base/fakemediaengine.h"
40#include "talk/media/base/fakevideorenderer.h"
41#include "talk/media/base/mediachannel.h"
42#include "talk/media/devices/fakedevicemanager.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000043#include "webrtc/p2p/base/stunserver.h"
44#include "webrtc/p2p/base/teststunserver.h"
45#include "webrtc/p2p/base/testturnserver.h"
pthatcher@webrtc.orgb4aac132015-03-13 18:25:21 +000046#include "webrtc/p2p/base/transportchannel.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000047#include "webrtc/p2p/client/basicportallocator.h"
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000048#include "talk/session/media/channelmanager.h"
49#include "talk/session/media/mediasession.h"
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000050#include "webrtc/base/fakenetwork.h"
51#include "webrtc/base/firewallsocketserver.h"
52#include "webrtc/base/gunit.h"
53#include "webrtc/base/logging.h"
54#include "webrtc/base/network.h"
55#include "webrtc/base/physicalsocketserver.h"
56#include "webrtc/base/ssladapter.h"
57#include "webrtc/base/sslstreamadapter.h"
58#include "webrtc/base/stringutils.h"
59#include "webrtc/base/thread.h"
60#include "webrtc/base/virtualsocketserver.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000061
62#define MAYBE_SKIP_TEST(feature) \
63 if (!(feature())) { \
64 LOG(LS_INFO) << "Feature disabled... skipping"; \
65 return; \
66 }
67
68using cricket::BaseSession;
69using cricket::DF_PLAY;
70using cricket::DF_SEND;
71using cricket::FakeVoiceMediaChannel;
72using cricket::NS_GINGLE_P2P;
73using cricket::NS_JINGLE_ICE_UDP;
74using 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;
81using webrtc::DTLSIdentityRequestObserver;
82using webrtc::DTLSIdentityServiceInterface;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000083using webrtc::FakeConstraints;
84using webrtc::IceCandidateCollection;
85using webrtc::JsepIceCandidate;
86using webrtc::JsepSessionDescription;
wu@webrtc.org97077a32013-10-25 21:18:33 +000087using webrtc::PeerConnectionFactoryInterface;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000088using webrtc::PeerConnectionInterface;
89using webrtc::SessionDescriptionInterface;
90using webrtc::StreamCollection;
wu@webrtc.org91053e72013-08-10 07:18:04 +000091using webrtc::WebRtcSession;
wu@webrtc.org364f2042013-11-20 21:49:41 +000092using webrtc::kBundleWithoutRtcpMux;
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +000093using webrtc::kCreateChannelFailed;
94using webrtc::kInvalidSdp;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000095using webrtc::kMlineMismatch;
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +000096using webrtc::kPushDownTDFailed;
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +000097using webrtc::kSdpWithoutIceUfragPwd;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +000098using webrtc::kSdpWithoutDtlsFingerprint;
99using webrtc::kSdpWithoutSdesCrypto;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000100using webrtc::kSessionError;
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000101using webrtc::kSessionErrorDesc;
buildbot@webrtc.org53df88c2014-08-07 22:46:01 +0000102using webrtc::kMaxUnsignalledRecvStreams;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000103
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +0000104typedef PeerConnectionInterface::RTCOfferAnswerOptions RTCOfferAnswerOptions;
105
wu@webrtc.org364f2042013-11-20 21:49:41 +0000106static const int kClientAddrPort = 0;
107static const char kClientAddrHost1[] = "11.11.11.11";
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +0000108static const char kClientIPv6AddrHost1[] =
109 "2620:0:aaaa:bbbb:cccc:dddd:eeee:ffff";
wu@webrtc.org364f2042013-11-20 21:49:41 +0000110static const char kClientAddrHost2[] = "22.22.22.22";
111static const char kStunAddrHost[] = "99.99.99.1";
buildbot@webrtc.org41451d42014-05-03 05:39:45 +0000112static const SocketAddress kTurnUdpIntAddr("99.99.99.4", 3478);
113static const SocketAddress kTurnUdpExtAddr("99.99.99.6", 0);
mallinath@webrtc.org3d81b1b2014-09-09 14:38:10 +0000114static const char kTurnUsername[] = "test";
115static const char kTurnPassword[] = "test";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000116
117static const char kSessionVersion[] = "1";
118
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000119// Media index of candidates belonging to the first media content.
120static const int kMediaContentIndex0 = 0;
121static const char kMediaContentName0[] = "audio";
122
123// Media index of candidates belonging to the second media content.
124static const int kMediaContentIndex1 = 1;
125static const char kMediaContentName1[] = "video";
126
127static const int kIceCandidatesTimeout = 10000;
128
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +0000129static const char kFakeDtlsFingerprint[] =
130 "BB:CD:72:F7:2F:D0:BA:43:F3:68:B1:0C:23:72:B6:4A:"
131 "0F:DE:34:06:BC:E0:FE:01:BC:73:C8:6D:F4:65:D5:24";
132
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +0000133static const char kTooLongIceUfragPwd[] =
134 "IceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfrag"
135 "IceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfrag"
136 "IceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfrag"
137 "IceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfrag";
138
changbin.shao@webrtc.org2d25b442015-03-16 04:14:34 +0000139static const char kSdpWithRtx[] =
140 "v=0\r\n"
141 "o=- 4104004319237231850 2 IN IP4 127.0.0.1\r\n"
142 "s=-\r\n"
143 "t=0 0\r\n"
144 "a=msid-semantic: WMS stream1\r\n"
145 "m=video 9 RTP/SAVPF 0 96\r\n"
146 "c=IN IP4 0.0.0.0\r\n"
147 "a=rtcp:9 IN IP4 0.0.0.0\r\n"
148 "a=ice-ufrag:CerjGp19G7wpXwl7\r\n"
149 "a=ice-pwd:cMvOlFvQ6ochez1ZOoC2uBEC\r\n"
150 "a=mid:video\r\n"
151 "a=sendrecv\r\n"
152 "a=rtcp-mux\r\n"
153 "a=crypto:1 AES_CM_128_HMAC_SHA1_80 "
154 "inline:5/4N5CDvMiyDArHtBByUM71VIkguH17ZNoX60GrA\r\n"
155 "a=rtpmap:0 fake_video_codec/90000\r\n"
156 "a=rtpmap:96 rtx/90000\r\n"
157 "a=fmtp:96 apt=0\r\n";
158
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000159// Add some extra |newlines| to the |message| after |line|.
160static void InjectAfter(const std::string& line,
161 const std::string& newlines,
162 std::string* message) {
163 const std::string tmp = line + newlines;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000164 rtc::replace_substrs(line.c_str(), line.length(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000165 tmp.c_str(), tmp.length(), message);
166}
167
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +0000168class FakeMetricsObserver : public webrtc::MetricsObserverInterface {
169 public:
170 FakeMetricsObserver() { Reset(); }
171 void Reset() {
172 memset(peer_connection_metrics_counters_, 0,
173 sizeof(peer_connection_metrics_counters_));
174 memset(peer_connection_metrics_name_, 0,
175 sizeof(peer_connection_metrics_name_));
176 }
177
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000178 void IncrementCounter(webrtc::PeerConnectionMetricsCounter type) override {
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +0000179 peer_connection_metrics_counters_[type]++;
180 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000181 void AddHistogramSample(webrtc::PeerConnectionMetricsName type,
182 int value) override {
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +0000183 ASSERT(peer_connection_metrics_name_[type] == 0);
184 peer_connection_metrics_name_[type] = value;
185 }
186
187 int peer_connection_metrics_counters_
188 [webrtc::kPeerConnectionMetricsCounter_Max];
189 int peer_connection_metrics_name_[webrtc::kPeerConnectionMetricsCounter_Max];
190
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000191 int AddRef() override { return 1; }
192 int Release() override { return 1; }
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +0000193};
194
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000195class MockIceObserver : public webrtc::IceObserver {
196 public:
197 MockIceObserver()
198 : oncandidatesready_(false),
199 ice_connection_state_(PeerConnectionInterface::kIceConnectionNew),
200 ice_gathering_state_(PeerConnectionInterface::kIceGatheringNew) {
201 }
202
203 virtual void OnIceConnectionChange(
204 PeerConnectionInterface::IceConnectionState new_state) {
205 ice_connection_state_ = new_state;
206 }
207 virtual void OnIceGatheringChange(
208 PeerConnectionInterface::IceGatheringState new_state) {
209 // We can never transition back to "new".
210 EXPECT_NE(PeerConnectionInterface::kIceGatheringNew, new_state);
211 ice_gathering_state_ = new_state;
212
213 // oncandidatesready_ really means "ICE gathering is complete".
214 // This if statement ensures that this value remains correct when we
215 // transition from kIceGatheringComplete to kIceGatheringGathering.
216 if (new_state == PeerConnectionInterface::kIceGatheringGathering) {
217 oncandidatesready_ = false;
218 }
219 }
220
221 // Found a new candidate.
222 virtual void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) {
wu@webrtc.org364f2042013-11-20 21:49:41 +0000223 switch (candidate->sdp_mline_index()) {
224 case kMediaContentIndex0:
225 mline_0_candidates_.push_back(candidate->candidate());
226 break;
227 case kMediaContentIndex1:
228 mline_1_candidates_.push_back(candidate->candidate());
229 break;
230 default:
231 ASSERT(false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000232 }
wu@webrtc.org364f2042013-11-20 21:49:41 +0000233
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000234 // The ICE gathering state should always be Gathering when a candidate is
235 // received (or possibly Completed in the case of the final candidate).
236 EXPECT_NE(PeerConnectionInterface::kIceGatheringNew, ice_gathering_state_);
237 }
238
239 // TODO(bemasc): Remove this once callers transition to OnIceGatheringChange.
240 virtual void OnIceComplete() {
241 EXPECT_FALSE(oncandidatesready_);
242 oncandidatesready_ = true;
243
244 // OnIceGatheringChange(IceGatheringCompleted) and OnIceComplete() should
245 // be called approximately simultaneously. For ease of testing, this
246 // check additionally requires that they be called in the above order.
247 EXPECT_EQ(PeerConnectionInterface::kIceGatheringComplete,
248 ice_gathering_state_);
249 }
250
251 bool oncandidatesready_;
252 std::vector<cricket::Candidate> mline_0_candidates_;
253 std::vector<cricket::Candidate> mline_1_candidates_;
254 PeerConnectionInterface::IceConnectionState ice_connection_state_;
255 PeerConnectionInterface::IceGatheringState ice_gathering_state_;
256};
257
258class WebRtcSessionForTest : public webrtc::WebRtcSession {
259 public:
260 WebRtcSessionForTest(cricket::ChannelManager* cmgr,
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000261 rtc::Thread* signaling_thread,
262 rtc::Thread* worker_thread,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000263 cricket::PortAllocator* port_allocator,
264 webrtc::IceObserver* ice_observer,
265 webrtc::MediaStreamSignaling* mediastream_signaling)
266 : WebRtcSession(cmgr, signaling_thread, worker_thread, port_allocator,
267 mediastream_signaling) {
268 RegisterIceObserver(ice_observer);
269 }
270 virtual ~WebRtcSessionForTest() {}
271
272 using cricket::BaseSession::GetTransportProxy;
273 using webrtc::WebRtcSession::SetAudioPlayout;
274 using webrtc::WebRtcSession::SetAudioSend;
275 using webrtc::WebRtcSession::SetCaptureDevice;
276 using webrtc::WebRtcSession::SetVideoPlayout;
277 using webrtc::WebRtcSession::SetVideoSend;
278};
279
wu@webrtc.org91053e72013-08-10 07:18:04 +0000280class WebRtcSessionCreateSDPObserverForTest
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000281 : public rtc::RefCountedObject<CreateSessionDescriptionObserver> {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000282 public:
wu@webrtc.org91053e72013-08-10 07:18:04 +0000283 enum State {
284 kInit,
285 kFailed,
286 kSucceeded,
287 };
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000288 WebRtcSessionCreateSDPObserverForTest() : state_(kInit) {}
wu@webrtc.org91053e72013-08-10 07:18:04 +0000289
290 // CreateSessionDescriptionObserver implementation.
291 virtual void OnSuccess(SessionDescriptionInterface* desc) {
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000292 description_.reset(desc);
wu@webrtc.org91053e72013-08-10 07:18:04 +0000293 state_ = kSucceeded;
294 }
295 virtual void OnFailure(const std::string& error) {
296 state_ = kFailed;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000297 }
298
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000299 SessionDescriptionInterface* description() { return description_.get(); }
300
301 SessionDescriptionInterface* ReleaseDescription() {
302 return description_.release();
303 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000304
wu@webrtc.org91053e72013-08-10 07:18:04 +0000305 State state() const { return state_; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000306
wu@webrtc.org91053e72013-08-10 07:18:04 +0000307 protected:
308 ~WebRtcSessionCreateSDPObserverForTest() {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000309
310 private:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000311 rtc::scoped_ptr<SessionDescriptionInterface> description_;
wu@webrtc.org91053e72013-08-10 07:18:04 +0000312 State state_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000313};
314
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000315class FakeAudioRenderer : public cricket::AudioRenderer {
316 public:
henrike@webrtc.orga7b98182014-02-21 15:51:43 +0000317 FakeAudioRenderer() : channel_id_(-1), sink_(NULL) {}
318 virtual ~FakeAudioRenderer() {
319 if (sink_)
320 sink_->OnClose();
321 }
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000322
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000323 void AddChannel(int channel_id) override {
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000324 ASSERT(channel_id_ == -1);
325 channel_id_ = channel_id;
326 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000327 void RemoveChannel(int channel_id) override {
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000328 ASSERT(channel_id == channel_id_);
329 channel_id_ = -1;
330 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000331 void SetSink(Sink* sink) override { sink_ = sink; }
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000332
333 int channel_id() const { return channel_id_; }
henrike@webrtc.orga7b98182014-02-21 15:51:43 +0000334 cricket::AudioRenderer::Sink* sink() const { return sink_; }
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000335 private:
336 int channel_id_;
henrike@webrtc.orga7b98182014-02-21 15:51:43 +0000337 cricket::AudioRenderer::Sink* sink_;
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000338};
339
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000340class WebRtcSessionTest : public testing::Test {
341 protected:
342 // TODO Investigate why ChannelManager crashes, if it's created
343 // after stun_server.
344 WebRtcSessionTest()
345 : media_engine_(new cricket::FakeMediaEngine()),
346 data_engine_(new cricket::FakeDataEngine()),
347 device_manager_(new cricket::FakeDeviceManager()),
348 channel_manager_(new cricket::ChannelManager(
349 media_engine_, data_engine_, device_manager_,
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000350 new cricket::CaptureManager(), rtc::Thread::Current())),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000351 tdesc_factory_(new cricket::TransportDescriptionFactory()),
352 desc_factory_(new cricket::MediaSessionDescriptionFactory(
353 channel_manager_.get(), tdesc_factory_.get())),
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000354 pss_(new rtc::PhysicalSocketServer),
355 vss_(new rtc::VirtualSocketServer(pss_.get())),
356 fss_(new rtc::FirewallSocketServer(vss_.get())),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000357 ss_scope_(fss_.get()),
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000358 stun_socket_addr_(rtc::SocketAddress(kStunAddrHost,
wu@webrtc.org364f2042013-11-20 21:49:41 +0000359 cricket::STUN_SERVER_PORT)),
jiayl@webrtc.orgbebc75e2014-09-26 23:01:11 +0000360 stun_server_(cricket::TestStunServer::Create(Thread::Current(),
361 stun_socket_addr_)),
buildbot@webrtc.org41451d42014-05-03 05:39:45 +0000362 turn_server_(Thread::Current(), kTurnUdpIntAddr, kTurnUdpExtAddr),
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000363 mediastream_signaling_(channel_manager_.get()) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000364 tdesc_factory_->set_protocol(cricket::ICEPROTO_HYBRID);
buildbot@webrtc.org51c55082014-07-28 22:26:15 +0000365
366 cricket::ServerAddresses stun_servers;
367 stun_servers.insert(stun_socket_addr_);
368 allocator_.reset(new cricket::BasicPortAllocator(
369 &network_manager_,
370 stun_servers,
371 SocketAddress(), SocketAddress(), SocketAddress()));
buildbot@webrtc.org41451d42014-05-03 05:39:45 +0000372 allocator_->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000373 cricket::PORTALLOCATOR_DISABLE_RELAY |
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +0000374 cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000375 EXPECT_TRUE(channel_manager_->Init());
376 desc_factory_->set_add_legacy_streams(false);
buildbot@webrtc.org41451d42014-05-03 05:39:45 +0000377 allocator_->set_step_delay(cricket::kMinimumStepDelay);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000378 }
379
380 void AddInterface(const SocketAddress& addr) {
381 network_manager_.AddInterface(addr);
382 }
383
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000384 void Init(
385 DTLSIdentityServiceInterface* identity_service,
Henrik Lundin64dad832015-05-11 12:44:23 +0200386 const PeerConnectionInterface::RTCConfiguration& rtc_configuration) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000387 ASSERT_TRUE(session_.get() == NULL);
388 session_.reset(new WebRtcSessionForTest(
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000389 channel_manager_.get(), rtc::Thread::Current(),
390 rtc::Thread::Current(), allocator_.get(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000391 &observer_,
392 &mediastream_signaling_));
393
394 EXPECT_EQ(PeerConnectionInterface::kIceConnectionNew,
395 observer_.ice_connection_state_);
396 EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
397 observer_.ice_gathering_state_);
398
wu@webrtc.org97077a32013-10-25 21:18:33 +0000399 EXPECT_TRUE(session_->Initialize(options_, constraints_.get(),
Henrik Lundin64dad832015-05-11 12:44:23 +0200400 identity_service, rtc_configuration));
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +0000401 session_->set_metrics_observer(&metrics_observer_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000402 }
403
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000404 void Init() {
Henrik Lundin64dad832015-05-11 12:44:23 +0200405 PeerConnectionInterface::RTCConfiguration configuration;
Henrik Lundin64dad832015-05-11 12:44:23 +0200406 Init(NULL, configuration);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000407 }
408
409 void InitWithIceTransport(
410 PeerConnectionInterface::IceTransportsType ice_transport_type) {
Henrik Lundin64dad832015-05-11 12:44:23 +0200411 PeerConnectionInterface::RTCConfiguration configuration;
412 configuration.type = ice_transport_type;
Henrik Lundin64dad832015-05-11 12:44:23 +0200413 Init(NULL, configuration);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000414 }
415
416 void InitWithBundlePolicy(
417 PeerConnectionInterface::BundlePolicy bundle_policy) {
Henrik Lundin64dad832015-05-11 12:44:23 +0200418 PeerConnectionInterface::RTCConfiguration configuration;
Henrik Lundin64dad832015-05-11 12:44:23 +0200419 configuration.bundle_policy = bundle_policy;
Peter Thatcheraf55ccc2015-05-21 07:48:41 -0700420 Init(NULL, configuration);
421 }
422
423 void InitWithRtcpMuxPolicy(
424 PeerConnectionInterface::RtcpMuxPolicy rtcp_mux_policy) {
425 PeerConnectionInterface::RTCConfiguration configuration;
426 configuration.rtcp_mux_policy = rtcp_mux_policy;
Henrik Lundin64dad832015-05-11 12:44:23 +0200427 Init(NULL, configuration);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000428 }
429
430 void InitWithDtls(bool identity_request_should_fail = false) {
431 FakeIdentityService* identity_service = new FakeIdentityService();
432 identity_service->set_should_fail(identity_request_should_fail);
Henrik Lundin64dad832015-05-11 12:44:23 +0200433 PeerConnectionInterface::RTCConfiguration configuration;
Henrik Lundin64dad832015-05-11 12:44:23 +0200434 Init(identity_service, configuration);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000435 }
436
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000437 void InitWithDtmfCodec() {
438 // Add kTelephoneEventCodec for dtmf test.
wu@webrtc.org364f2042013-11-20 21:49:41 +0000439 const cricket::AudioCodec kTelephoneEventCodec(
440 106, "telephone-event", 8000, 0, 1, 0);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000441 std::vector<cricket::AudioCodec> codecs;
442 codecs.push_back(kTelephoneEventCodec);
443 media_engine_->SetAudioCodecs(codecs);
444 desc_factory_->set_audio_codecs(codecs);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000445 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000446 }
447
448 // Creates a local offer and applies it. Starts ice.
449 // Call mediastream_signaling_.UseOptionsWithStreamX() before this function
450 // to decide which streams to create.
451 void InitiateCall() {
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +0000452 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000453 SetLocalDescriptionWithoutError(offer);
454 EXPECT_TRUE_WAIT(PeerConnectionInterface::kIceGatheringNew !=
455 observer_.ice_gathering_state_,
456 kIceCandidatesTimeout);
457 }
458
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +0000459 SessionDescriptionInterface* CreateOffer() {
460 PeerConnectionInterface::RTCOfferAnswerOptions options;
461 options.offer_to_receive_audio =
462 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
463
464 return CreateOffer(options);
465 }
466
wu@webrtc.org91053e72013-08-10 07:18:04 +0000467 SessionDescriptionInterface* CreateOffer(
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +0000468 const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000469 rtc::scoped_refptr<WebRtcSessionCreateSDPObserverForTest>
wu@webrtc.org91053e72013-08-10 07:18:04 +0000470 observer = new WebRtcSessionCreateSDPObserverForTest();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +0000471 session_->CreateOffer(observer, options);
wu@webrtc.org91053e72013-08-10 07:18:04 +0000472 EXPECT_TRUE_WAIT(
473 observer->state() != WebRtcSessionCreateSDPObserverForTest::kInit,
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000474 2000);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000475 return observer->ReleaseDescription();
wu@webrtc.org91053e72013-08-10 07:18:04 +0000476 }
477
478 SessionDescriptionInterface* CreateAnswer(
479 const webrtc::MediaConstraintsInterface* constraints) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000480 rtc::scoped_refptr<WebRtcSessionCreateSDPObserverForTest> observer
wu@webrtc.org91053e72013-08-10 07:18:04 +0000481 = new WebRtcSessionCreateSDPObserverForTest();
482 session_->CreateAnswer(observer, constraints);
483 EXPECT_TRUE_WAIT(
484 observer->state() != WebRtcSessionCreateSDPObserverForTest::kInit,
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000485 2000);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000486 return observer->ReleaseDescription();
wu@webrtc.org91053e72013-08-10 07:18:04 +0000487 }
488
wu@webrtc.org364f2042013-11-20 21:49:41 +0000489 bool ChannelsExist() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000490 return (session_->voice_channel() != NULL &&
491 session_->video_channel() != NULL);
492 }
493
wu@webrtc.org364f2042013-11-20 21:49:41 +0000494 void CheckTransportChannels() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000495 EXPECT_TRUE(session_->GetChannel(cricket::CN_AUDIO, 1) != NULL);
496 EXPECT_TRUE(session_->GetChannel(cricket::CN_AUDIO, 2) != NULL);
497 EXPECT_TRUE(session_->GetChannel(cricket::CN_VIDEO, 1) != NULL);
498 EXPECT_TRUE(session_->GetChannel(cricket::CN_VIDEO, 2) != NULL);
499 }
500
501 void VerifyCryptoParams(const cricket::SessionDescription* sdp) {
502 ASSERT_TRUE(session_.get() != NULL);
503 const cricket::ContentInfo* content = cricket::GetFirstAudioContent(sdp);
504 ASSERT_TRUE(content != NULL);
505 const cricket::AudioContentDescription* audio_content =
506 static_cast<const cricket::AudioContentDescription*>(
507 content->description);
508 ASSERT_TRUE(audio_content != NULL);
509 ASSERT_EQ(1U, audio_content->cryptos().size());
510 ASSERT_EQ(47U, audio_content->cryptos()[0].key_params.size());
511 ASSERT_EQ("AES_CM_128_HMAC_SHA1_80",
512 audio_content->cryptos()[0].cipher_suite);
513 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf),
514 audio_content->protocol());
515
516 content = cricket::GetFirstVideoContent(sdp);
517 ASSERT_TRUE(content != NULL);
518 const cricket::VideoContentDescription* video_content =
519 static_cast<const cricket::VideoContentDescription*>(
520 content->description);
521 ASSERT_TRUE(video_content != NULL);
522 ASSERT_EQ(1U, video_content->cryptos().size());
523 ASSERT_EQ("AES_CM_128_HMAC_SHA1_80",
524 video_content->cryptos()[0].cipher_suite);
525 ASSERT_EQ(47U, video_content->cryptos()[0].key_params.size());
526 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf),
527 video_content->protocol());
528 }
529
530 void VerifyNoCryptoParams(const cricket::SessionDescription* sdp, bool dtls) {
531 const cricket::ContentInfo* content = cricket::GetFirstAudioContent(sdp);
532 ASSERT_TRUE(content != NULL);
533 const cricket::AudioContentDescription* audio_content =
534 static_cast<const cricket::AudioContentDescription*>(
535 content->description);
536 ASSERT_TRUE(audio_content != NULL);
537 ASSERT_EQ(0U, audio_content->cryptos().size());
538
539 content = cricket::GetFirstVideoContent(sdp);
540 ASSERT_TRUE(content != NULL);
541 const cricket::VideoContentDescription* video_content =
542 static_cast<const cricket::VideoContentDescription*>(
543 content->description);
544 ASSERT_TRUE(video_content != NULL);
545 ASSERT_EQ(0U, video_content->cryptos().size());
546
547 if (dtls) {
548 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf),
549 audio_content->protocol());
550 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf),
551 video_content->protocol());
552 } else {
553 EXPECT_EQ(std::string(cricket::kMediaProtocolAvpf),
554 audio_content->protocol());
555 EXPECT_EQ(std::string(cricket::kMediaProtocolAvpf),
556 video_content->protocol());
557 }
558 }
559
560 // Set the internal fake description factories to do DTLS-SRTP.
561 void SetFactoryDtlsSrtp() {
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000562 desc_factory_->set_secure(cricket::SEC_DISABLED);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000563 std::string identity_name = "WebRTC" +
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000564 rtc::ToString(rtc::CreateRandomId());
565 identity_.reset(rtc::SSLIdentity::Generate(identity_name));
henrike@webrtc.org723d6832013-07-12 16:04:50 +0000566 tdesc_factory_->set_identity(identity_.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000567 tdesc_factory_->set_secure(cricket::SEC_REQUIRED);
568 }
569
570 void VerifyFingerprintStatus(const cricket::SessionDescription* sdp,
571 bool expected) {
572 const TransportInfo* audio = sdp->GetTransportInfoByName("audio");
573 ASSERT_TRUE(audio != NULL);
574 ASSERT_EQ(expected, audio->description.identity_fingerprint.get() != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000575 const TransportInfo* video = sdp->GetTransportInfoByName("video");
576 ASSERT_TRUE(video != NULL);
577 ASSERT_EQ(expected, video->description.identity_fingerprint.get() != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000578 }
579
580 void VerifyAnswerFromNonCryptoOffer() {
jiayl@webrtc.org7d4891d2014-09-09 21:43:15 +0000581 // Create an SDP without Crypto.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000582 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +0000583 options.recv_video = true;
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000584 JsepSessionDescription* offer(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000585 CreateRemoteOffer(options, cricket::SEC_DISABLED));
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000586 ASSERT_TRUE(offer != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000587 VerifyNoCryptoParams(offer->description(), false);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000588 SetRemoteDescriptionOfferExpectError(kSdpWithoutSdesCrypto,
589 offer);
wu@webrtc.org91053e72013-08-10 07:18:04 +0000590 const webrtc::SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000591 // Answer should be NULL as no crypto params in offer.
592 ASSERT_TRUE(answer == NULL);
593 }
594
595 void VerifyAnswerFromCryptoOffer() {
596 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +0000597 options.recv_video = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000598 options.bundle_enabled = true;
599 scoped_ptr<JsepSessionDescription> offer(
600 CreateRemoteOffer(options, cricket::SEC_REQUIRED));
601 ASSERT_TRUE(offer.get() != NULL);
602 VerifyCryptoParams(offer->description());
603 SetRemoteDescriptionWithoutError(offer.release());
wu@webrtc.org91053e72013-08-10 07:18:04 +0000604 scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000605 ASSERT_TRUE(answer.get() != NULL);
606 VerifyCryptoParams(answer->description());
607 }
608
buildbot@webrtc.org53df88c2014-08-07 22:46:01 +0000609 void SetAndVerifyNumUnsignalledRecvStreams(
610 int value_set, int value_expected) {
611 constraints_.reset(new FakeConstraints());
612 constraints_->AddOptional(
613 webrtc::MediaConstraintsInterface::kNumUnsignalledRecvStreams,
614 value_set);
615 session_.reset();
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000616 Init();
buildbot@webrtc.org53df88c2014-08-07 22:46:01 +0000617 mediastream_signaling_.SendAudioVideoStream1();
618 SessionDescriptionInterface* offer = CreateOffer();
619
620 SetLocalDescriptionWithoutError(offer);
621
622 video_channel_ = media_engine_->GetVideoChannel(0);
623
624 ASSERT_TRUE(video_channel_ != NULL);
625 cricket::VideoOptions video_options;
626 EXPECT_TRUE(video_channel_->GetOptions(&video_options));
627 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());
971 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 }
980 }
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 {
1004 public:
1005 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(
1025 const FakeMetricsObserver& metrics_observer) const {
1026 Verify(metrics_observer, best_connection_after_initial_ice_converged_);
1027 }
1028
1029 private:
1030 void Verify(const FakeMetricsObserver& metrics_observer,
1031 const ExpectedBestConnection& expected) const {
1032 EXPECT_EQ(
1033 metrics_observer
1034 .peer_connection_metrics_counters_[webrtc::kBestConnections_IPv4],
1035 expected.ipv4_count_);
1036 EXPECT_EQ(
1037 metrics_observer
1038 .peer_connection_metrics_counters_[webrtc::kBestConnections_IPv6],
1039 expected.ipv6_count_);
1040 }
1041 };
1042
1043 class LoopbackNetworkManager {
1044 public:
1045 LoopbackNetworkManager(WebRtcSessionTest* session,
1046 const LoopbackNetworkConfiguration& config)
1047 : config_(config) {
1048 session->AddInterface(
1049 rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
1050 if (config_.test_extra_ipv4_network_) {
1051 session->AddInterface(
1052 rtc::SocketAddress(kClientAddrHost2, kClientAddrPort));
1053 }
1054 if (config_.test_ipv6_network_) {
1055 session->AddInterface(
1056 rtc::SocketAddress(kClientIPv6AddrHost1, kClientAddrPort));
1057 }
1058 }
1059
1060 void ApplyFirewallRules(rtc::FirewallSocketServer* fss) {
1061 fss->AddRule(false, rtc::FP_ANY, rtc::FD_ANY,
1062 rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
1063 if (config_.test_extra_ipv4_network_) {
1064 fss->AddRule(false, rtc::FP_ANY, rtc::FD_ANY,
1065 rtc::SocketAddress(kClientAddrHost2, kClientAddrPort));
1066 }
1067 if (config_.test_ipv6_network_) {
1068 fss->AddRule(false, rtc::FP_ANY, rtc::FD_ANY,
1069 rtc::SocketAddress(kClientIPv6AddrHost1, kClientAddrPort));
1070 }
1071 }
1072
1073 void ClearRules(rtc::FirewallSocketServer* fss) { fss->ClearRules(); }
1074
1075 private:
1076 LoopbackNetworkConfiguration config_;
1077 };
1078
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001079 // The method sets up a call from the session to itself, in a loopback
1080 // arrangement. It also uses a firewall rule to create a temporary
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00001081 // disconnection, and then a permanent disconnection.
1082 // This code is placed in a method so that it can be invoked
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001083 // by multiple tests with different allocators (e.g. with and without BUNDLE).
1084 // While running the call, this method also checks if the session goes through
1085 // the correct sequence of ICE states when a connection is established,
1086 // broken, and re-established.
1087 // The Connection state should go:
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00001088 // New -> Checking -> (Connected) -> Completed -> Disconnected -> Completed
1089 // -> Failed.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001090 // The Gathering state should go: New -> Gathering -> Completed.
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001091
1092 void TestLoopbackCall(const LoopbackNetworkConfiguration& config) {
1093 LoopbackNetworkManager loopback_network_manager(this, config);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001094 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001095 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001096 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001097
1098 EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
1099 observer_.ice_gathering_state_);
1100 SetLocalDescriptionWithoutError(offer);
1101 EXPECT_EQ(PeerConnectionInterface::kIceConnectionNew,
1102 observer_.ice_connection_state_);
1103 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceGatheringGathering,
1104 observer_.ice_gathering_state_,
1105 kIceCandidatesTimeout);
1106 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1107 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
1108 observer_.ice_gathering_state_,
1109 kIceCandidatesTimeout);
1110
1111 std::string sdp;
1112 offer->ToString(&sdp);
1113 SessionDescriptionInterface* desc =
1114 webrtc::CreateSessionDescription(JsepSessionDescription::kAnswer, sdp);
1115 ASSERT_TRUE(desc != NULL);
1116 SetRemoteDescriptionWithoutError(desc);
1117
1118 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionChecking,
1119 observer_.ice_connection_state_,
1120 kIceCandidatesTimeout);
mallinath@webrtc.orgd3dc4242014-03-01 00:05:52 +00001121
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00001122 // The ice connection state is "Connected" too briefly to catch in a test.
1123 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001124 observer_.ice_connection_state_,
1125 kIceCandidatesTimeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001126
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001127 config.VerifyBestConnectionAfterIceConverge(metrics_observer_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001128 // Adding firewall rule to block ping requests, which should cause
1129 // transport channel failure.
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001130
1131 loopback_network_manager.ApplyFirewallRules(fss_.get());
1132
1133 LOG(LS_INFO) << "Firewall Rules applied";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001134 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
1135 observer_.ice_connection_state_,
1136 kIceCandidatesTimeout);
1137
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001138 metrics_observer_.Reset();
1139
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001140 // Clearing the rules, session should move back to completed state.
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001141 loopback_network_manager.ClearRules(fss_.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001142 // Session is automatically calling OnSignalingReady after creation of
1143 // new portallocator session which will allocate new set of candidates.
1144
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001145 LOG(LS_INFO) << "Firewall Rules cleared";
1146
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00001147 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001148 observer_.ice_connection_state_,
1149 kIceCandidatesTimeout);
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00001150
1151 // Now we block ping requests and wait until the ICE connection transitions
1152 // to the Failed state. This will take at least 30 seconds because it must
1153 // wait for the Port to timeout.
1154 int port_timeout = 30000;
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001155
1156 loopback_network_manager.ApplyFirewallRules(fss_.get());
1157 LOG(LS_INFO) << "Firewall Rules applied again";
jlmiller@webrtc.org804eb462015-02-20 02:20:03 +00001158 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00001159 observer_.ice_connection_state_,
1160 kIceCandidatesTimeout + port_timeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001161 }
1162
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001163 void TestLoopbackCall() {
1164 LoopbackNetworkConfiguration config;
1165 TestLoopbackCall(config);
1166 }
1167
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001168 void VerifyTransportType(const std::string& content_name,
1169 cricket::TransportProtocol protocol) {
1170 const cricket::Transport* transport = session_->GetTransport(content_name);
1171 ASSERT_TRUE(transport != NULL);
1172 EXPECT_EQ(protocol, transport->protocol());
1173 }
1174
1175 // Adds CN codecs to FakeMediaEngine and MediaDescriptionFactory.
1176 void AddCNCodecs() {
wu@webrtc.org364f2042013-11-20 21:49:41 +00001177 const cricket::AudioCodec kCNCodec1(102, "CN", 8000, 0, 1, 0);
1178 const cricket::AudioCodec kCNCodec2(103, "CN", 16000, 0, 1, 0);
1179
1180 // Add kCNCodec for dtmf test.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001181 std::vector<cricket::AudioCodec> codecs = media_engine_->audio_codecs();;
1182 codecs.push_back(kCNCodec1);
1183 codecs.push_back(kCNCodec2);
1184 media_engine_->SetAudioCodecs(codecs);
1185 desc_factory_->set_audio_codecs(codecs);
1186 }
1187
1188 bool VerifyNoCNCodecs(const cricket::ContentInfo* content) {
1189 const cricket::ContentDescription* description = content->description;
1190 ASSERT(description != NULL);
1191 const cricket::AudioContentDescription* audio_content_desc =
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00001192 static_cast<const cricket::AudioContentDescription*>(description);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001193 ASSERT(audio_content_desc != NULL);
1194 for (size_t i = 0; i < audio_content_desc->codecs().size(); ++i) {
1195 if (audio_content_desc->codecs()[i].name == "CN")
1196 return false;
1197 }
1198 return true;
1199 }
1200
1201 void SetLocalDescriptionWithDataChannel() {
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +00001202 webrtc::InternalDataChannelInit dci;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001203 dci.reliable = false;
1204 session_->CreateDataChannel("datachannel", &dci);
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001205 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001206 SetLocalDescriptionWithoutError(offer);
1207 }
1208
wu@webrtc.org91053e72013-08-10 07:18:04 +00001209 void VerifyMultipleAsyncCreateDescription(
1210 bool success, CreateSessionDescriptionRequest::Type type) {
henrike@webrtc.org7666db72013-08-22 14:45:42 +00001211 InitWithDtls(!success);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001212 SetFactoryDtlsSrtp();
wu@webrtc.org91053e72013-08-10 07:18:04 +00001213 if (type == CreateSessionDescriptionRequest::kAnswer) {
1214 cricket::MediaSessionOptions options;
1215 scoped_ptr<JsepSessionDescription> offer(
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001216 CreateRemoteOffer(options, cricket::SEC_DISABLED));
wu@webrtc.org91053e72013-08-10 07:18:04 +00001217 ASSERT_TRUE(offer.get() != NULL);
1218 SetRemoteDescriptionWithoutError(offer.release());
1219 }
1220
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001221 PeerConnectionInterface::RTCOfferAnswerOptions options;
wu@webrtc.org91053e72013-08-10 07:18:04 +00001222 const int kNumber = 3;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001223 rtc::scoped_refptr<WebRtcSessionCreateSDPObserverForTest>
wu@webrtc.org91053e72013-08-10 07:18:04 +00001224 observers[kNumber];
1225 for (int i = 0; i < kNumber; ++i) {
1226 observers[i] = new WebRtcSessionCreateSDPObserverForTest();
1227 if (type == CreateSessionDescriptionRequest::kOffer) {
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001228 session_->CreateOffer(observers[i], options);
wu@webrtc.org91053e72013-08-10 07:18:04 +00001229 } else {
1230 session_->CreateAnswer(observers[i], NULL);
1231 }
1232 }
1233
1234 WebRtcSessionCreateSDPObserverForTest::State expected_state =
1235 success ? WebRtcSessionCreateSDPObserverForTest::kSucceeded :
1236 WebRtcSessionCreateSDPObserverForTest::kFailed;
1237
1238 for (int i = 0; i < kNumber; ++i) {
1239 EXPECT_EQ_WAIT(expected_state, observers[i]->state(), 1000);
1240 if (success) {
1241 EXPECT_TRUE(observers[i]->description() != NULL);
1242 } else {
1243 EXPECT_TRUE(observers[i]->description() == NULL);
1244 }
1245 }
1246 }
1247
mallinath@webrtc.org3d81b1b2014-09-09 14:38:10 +00001248 void ConfigureAllocatorWithTurn() {
1249 cricket::RelayServerConfig relay_server(cricket::RELAY_TURN);
1250 cricket::RelayCredentials credentials(kTurnUsername, kTurnPassword);
1251 relay_server.credentials = credentials;
1252 relay_server.ports.push_back(cricket::ProtocolAddress(
1253 kTurnUdpIntAddr, cricket::PROTO_UDP, false));
1254 allocator_->AddRelay(relay_server);
1255 allocator_->set_step_delay(cricket::kMinimumStepDelay);
1256 allocator_->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
jiayl@webrtc.orgdacdd942015-01-23 17:33:34 +00001257 cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG);
mallinath@webrtc.org3d81b1b2014-09-09 14:38:10 +00001258 }
1259
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001260 cricket::FakeMediaEngine* media_engine_;
1261 cricket::FakeDataEngine* data_engine_;
1262 cricket::FakeDeviceManager* device_manager_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001263 rtc::scoped_ptr<cricket::ChannelManager> channel_manager_;
1264 rtc::scoped_ptr<cricket::TransportDescriptionFactory> tdesc_factory_;
1265 rtc::scoped_ptr<rtc::SSLIdentity> identity_;
1266 rtc::scoped_ptr<cricket::MediaSessionDescriptionFactory> desc_factory_;
1267 rtc::scoped_ptr<rtc::PhysicalSocketServer> pss_;
1268 rtc::scoped_ptr<rtc::VirtualSocketServer> vss_;
1269 rtc::scoped_ptr<rtc::FirewallSocketServer> fss_;
1270 rtc::SocketServerScope ss_scope_;
1271 rtc::SocketAddress stun_socket_addr_;
jiayl@webrtc.orgbebc75e2014-09-26 23:01:11 +00001272 rtc::scoped_ptr<cricket::TestStunServer> stun_server_;
buildbot@webrtc.org41451d42014-05-03 05:39:45 +00001273 cricket::TestTurnServer turn_server_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001274 rtc::FakeNetworkManager network_manager_;
1275 rtc::scoped_ptr<cricket::BasicPortAllocator> allocator_;
wu@webrtc.org97077a32013-10-25 21:18:33 +00001276 PeerConnectionFactoryInterface::Options options_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001277 rtc::scoped_ptr<FakeConstraints> constraints_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001278 FakeMediaStreamSignaling mediastream_signaling_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001279 rtc::scoped_ptr<WebRtcSessionForTest> session_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001280 MockIceObserver observer_;
1281 cricket::FakeVideoMediaChannel* video_channel_;
1282 cricket::FakeVoiceMediaChannel* voice_channel_;
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001283 FakeMetricsObserver metrics_observer_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001284};
1285
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001286TEST_F(WebRtcSessionTest, TestInitializeWithDtls) {
1287 InitWithDtls();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001288 // SDES is disabled when DTLS is on.
1289 EXPECT_EQ(cricket::SEC_DISABLED, session_->SdesPolicy());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001290}
1291
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001292TEST_F(WebRtcSessionTest, TestInitializeWithoutDtls) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001293 Init();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001294 // SDES is required if DTLS is off.
1295 EXPECT_EQ(cricket::SEC_REQUIRED, session_->SdesPolicy());
wu@webrtc.org91053e72013-08-10 07:18:04 +00001296}
1297
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001298TEST_F(WebRtcSessionTest, TestSessionCandidates) {
1299 TestSessionCandidatesWithBundleRtcpMux(false, false);
1300}
1301
1302// Below test cases (TestSessionCandidatesWith*) verify the candidates gathered
1303// with rtcp-mux and/or bundle.
1304TEST_F(WebRtcSessionTest, TestSessionCandidatesWithRtcpMux) {
1305 TestSessionCandidatesWithBundleRtcpMux(false, true);
1306}
1307
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001308TEST_F(WebRtcSessionTest, TestSessionCandidatesWithBundleRtcpMux) {
1309 TestSessionCandidatesWithBundleRtcpMux(true, true);
1310}
1311
1312TEST_F(WebRtcSessionTest, TestMultihomeCandidates) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001313 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
1314 AddInterface(rtc::SocketAddress(kClientAddrHost2, kClientAddrPort));
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001315 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001316 mediastream_signaling_.SendAudioVideoStream1();
1317 InitiateCall();
1318 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1319 EXPECT_EQ(8u, observer_.mline_0_candidates_.size());
1320 EXPECT_EQ(8u, observer_.mline_1_candidates_.size());
1321}
1322
1323TEST_F(WebRtcSessionTest, TestStunError) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001324 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
1325 AddInterface(rtc::SocketAddress(kClientAddrHost2, kClientAddrPort));
wu@webrtc.org364f2042013-11-20 21:49:41 +00001326 fss_->AddRule(false,
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001327 rtc::FP_UDP,
1328 rtc::FD_ANY,
1329 rtc::SocketAddress(kClientAddrHost1, 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();
wu@webrtc.org364f2042013-11-20 21:49:41 +00001333 // Since kClientAddrHost1 is blocked, not expecting stun candidates for it.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001334 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1335 EXPECT_EQ(6u, observer_.mline_0_candidates_.size());
1336 EXPECT_EQ(6u, observer_.mline_1_candidates_.size());
1337}
1338
mallinath@webrtc.org3d81b1b2014-09-09 14:38:10 +00001339// Test session delivers no candidates gathered when constraint set to "none".
1340TEST_F(WebRtcSessionTest, TestIceTransportsNone) {
1341 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001342 InitWithIceTransport(PeerConnectionInterface::kNone);
mallinath@webrtc.org3d81b1b2014-09-09 14:38:10 +00001343 mediastream_signaling_.SendAudioVideoStream1();
1344 InitiateCall();
1345 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1346 EXPECT_EQ(0u, observer_.mline_0_candidates_.size());
1347 EXPECT_EQ(0u, observer_.mline_1_candidates_.size());
1348}
1349
1350// Test session delivers only relay candidates gathered when constaint set to
1351// "relay".
1352TEST_F(WebRtcSessionTest, TestIceTransportsRelay) {
1353 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
1354 ConfigureAllocatorWithTurn();
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001355 InitWithIceTransport(PeerConnectionInterface::kRelay);
mallinath@webrtc.org3d81b1b2014-09-09 14:38:10 +00001356 mediastream_signaling_.SendAudioVideoStream1();
1357 InitiateCall();
1358 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1359 EXPECT_EQ(2u, observer_.mline_0_candidates_.size());
1360 EXPECT_EQ(2u, observer_.mline_1_candidates_.size());
1361 for (size_t i = 0; i < observer_.mline_0_candidates_.size(); ++i) {
1362 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
1363 observer_.mline_0_candidates_[i].type());
1364 }
1365 for (size_t i = 0; i < observer_.mline_1_candidates_.size(); ++i) {
1366 EXPECT_EQ(cricket::RELAY_PORT_TYPE,
1367 observer_.mline_1_candidates_[i].type());
1368 }
1369}
1370
1371// Test session delivers all candidates gathered when constaint set to "all".
1372TEST_F(WebRtcSessionTest, TestIceTransportsAll) {
1373 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001374 InitWithIceTransport(PeerConnectionInterface::kAll);
mallinath@webrtc.org3d81b1b2014-09-09 14:38:10 +00001375 mediastream_signaling_.SendAudioVideoStream1();
1376 InitiateCall();
1377 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1378 // Host + STUN. By default allocator is disabled to gather relay candidates.
1379 EXPECT_EQ(4u, observer_.mline_0_candidates_.size());
1380 EXPECT_EQ(4u, observer_.mline_1_candidates_.size());
1381}
1382
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001383TEST_F(WebRtcSessionTest, SetSdpFailedOnInvalidSdp) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001384 Init();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001385 SessionDescriptionInterface* offer = NULL;
1386 // Since |offer| is NULL, there's no way to tell if it's an offer or answer.
1387 std::string unknown_action;
1388 SetLocalDescriptionExpectError(unknown_action, kInvalidSdp, offer);
1389 SetRemoteDescriptionExpectError(unknown_action, kInvalidSdp, offer);
1390}
1391
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001392// Test creating offers and receive answers and make sure the
1393// media engine creates the expected send and receive streams.
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001394TEST_F(WebRtcSessionTest, TestCreateSdesOfferReceiveSdesAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001395 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001396 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001397 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001398 const std::string session_id_orig = offer->session_id();
1399 const std::string session_version_orig = offer->session_version();
1400 SetLocalDescriptionWithoutError(offer);
1401
1402 mediastream_signaling_.SendAudioVideoStream2();
1403 SessionDescriptionInterface* answer =
1404 CreateRemoteAnswer(session_->local_description());
1405 SetRemoteDescriptionWithoutError(answer);
1406
1407 video_channel_ = media_engine_->GetVideoChannel(0);
1408 voice_channel_ = media_engine_->GetVoiceChannel(0);
1409
1410 ASSERT_EQ(1u, video_channel_->recv_streams().size());
1411 EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].id);
1412
1413 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
1414 EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].id);
1415
1416 ASSERT_EQ(1u, video_channel_->send_streams().size());
1417 EXPECT_TRUE(kVideoTrack1 == video_channel_->send_streams()[0].id);
1418 ASSERT_EQ(1u, voice_channel_->send_streams().size());
1419 EXPECT_TRUE(kAudioTrack1 == voice_channel_->send_streams()[0].id);
1420
1421 // Create new offer without send streams.
1422 mediastream_signaling_.SendNothing();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001423 offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001424
1425 // Verify the session id is the same and the session version is
1426 // increased.
1427 EXPECT_EQ(session_id_orig, offer->session_id());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001428 EXPECT_LT(rtc::FromString<uint64>(session_version_orig),
1429 rtc::FromString<uint64>(offer->session_version()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001430
1431 SetLocalDescriptionWithoutError(offer);
jiayl@webrtc.org7d4891d2014-09-09 21:43:15 +00001432 EXPECT_EQ(0u, video_channel_->send_streams().size());
1433 EXPECT_EQ(0u, voice_channel_->send_streams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001434
1435 mediastream_signaling_.SendAudioVideoStream2();
1436 answer = CreateRemoteAnswer(session_->local_description());
1437 SetRemoteDescriptionWithoutError(answer);
1438
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001439 // Make sure the receive streams have not changed.
1440 ASSERT_EQ(1u, video_channel_->recv_streams().size());
1441 EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].id);
1442 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
1443 EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].id);
1444}
1445
1446// Test receiving offers and creating answers and make sure the
1447// media engine creates the expected send and receive streams.
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001448TEST_F(WebRtcSessionTest, TestReceiveSdesOfferCreateSdesAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001449 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001450 mediastream_signaling_.SendAudioVideoStream2();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001451 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001452 VerifyCryptoParams(offer->description());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001453 SetRemoteDescriptionWithoutError(offer);
1454
1455 mediastream_signaling_.SendAudioVideoStream1();
wu@webrtc.org91053e72013-08-10 07:18:04 +00001456 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001457 VerifyCryptoParams(answer->description());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001458 SetLocalDescriptionWithoutError(answer);
1459
1460 const std::string session_id_orig = answer->session_id();
1461 const std::string session_version_orig = answer->session_version();
1462
1463 video_channel_ = media_engine_->GetVideoChannel(0);
1464 voice_channel_ = media_engine_->GetVoiceChannel(0);
1465
1466 ASSERT_EQ(1u, video_channel_->recv_streams().size());
1467 EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].id);
1468
1469 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
1470 EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].id);
1471
1472 ASSERT_EQ(1u, video_channel_->send_streams().size());
1473 EXPECT_TRUE(kVideoTrack1 == video_channel_->send_streams()[0].id);
1474 ASSERT_EQ(1u, voice_channel_->send_streams().size());
1475 EXPECT_TRUE(kAudioTrack1 == voice_channel_->send_streams()[0].id);
1476
1477 mediastream_signaling_.SendAudioVideoStream1And2();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001478 offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001479 SetRemoteDescriptionWithoutError(offer);
1480
1481 // Answer by turning off all send streams.
1482 mediastream_signaling_.SendNothing();
wu@webrtc.org91053e72013-08-10 07:18:04 +00001483 answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001484
1485 // Verify the session id is the same and the session version is
1486 // increased.
1487 EXPECT_EQ(session_id_orig, answer->session_id());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001488 EXPECT_LT(rtc::FromString<uint64>(session_version_orig),
1489 rtc::FromString<uint64>(answer->session_version()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001490 SetLocalDescriptionWithoutError(answer);
1491
1492 ASSERT_EQ(2u, video_channel_->recv_streams().size());
1493 EXPECT_TRUE(kVideoTrack1 == video_channel_->recv_streams()[0].id);
1494 EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[1].id);
1495 ASSERT_EQ(2u, voice_channel_->recv_streams().size());
1496 EXPECT_TRUE(kAudioTrack1 == voice_channel_->recv_streams()[0].id);
1497 EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[1].id);
1498
1499 // Make sure we have no send streams.
1500 EXPECT_EQ(0u, video_channel_->send_streams().size());
1501 EXPECT_EQ(0u, voice_channel_->send_streams().size());
1502}
1503
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001504TEST_F(WebRtcSessionTest, SetLocalSdpFailedOnCreateChannel) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001505 Init();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001506 media_engine_->set_fail_create_channel(true);
1507
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001508 SessionDescriptionInterface* offer = CreateOffer();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001509 ASSERT_TRUE(offer != NULL);
1510 // SetRemoteDescription and SetLocalDescription will take the ownership of
1511 // the offer.
1512 SetRemoteDescriptionOfferExpectError(kCreateChannelFailed, offer);
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001513 offer = CreateOffer();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001514 ASSERT_TRUE(offer != NULL);
1515 SetLocalDescriptionOfferExpectError(kCreateChannelFailed, offer);
1516}
1517
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001518//
1519// Tests for creating/setting SDP under different SDES/DTLS polices:
1520//
1521// --DTLS off and SDES on
1522// TestCreateSdesOfferReceiveSdesAnswer/TestReceiveSdesOfferCreateSdesAnswer:
1523// set local/remote offer/answer with crypto --> success
1524// TestSetNonSdesOfferWhenSdesOn: set local/remote offer without crypto --->
1525// failure
1526// TestSetLocalNonSdesAnswerWhenSdesOn: set local answer without crypto -->
1527// failure
1528// TestSetRemoteNonSdesAnswerWhenSdesOn: set remote answer without crypto -->
1529// failure
1530//
1531// --DTLS on and SDES off
1532// TestCreateDtlsOfferReceiveDtlsAnswer/TestReceiveDtlsOfferCreateDtlsAnswer:
1533// set local/remote offer/answer with DTLS fingerprint --> success
1534// TestReceiveNonDtlsOfferWhenDtlsOn: set local/remote offer without DTLS
1535// fingerprint --> failure
1536// TestSetLocalNonDtlsAnswerWhenDtlsOn: set local answer without fingerprint
1537// --> failure
1538// TestSetRemoteNonDtlsAnswerWhenDtlsOn: set remote answer without fingerprint
1539// --> failure
1540//
1541// --Encryption disabled: DTLS off and SDES off
1542// TestCreateOfferReceiveAnswerWithoutEncryption: set local offer and remote
1543// answer without SDES or DTLS --> success
1544// TestCreateAnswerReceiveOfferWithoutEncryption: set remote offer and local
1545// answer without SDES or DTLS --> success
1546//
1547
1548// Test that we return a failure when applying a remote/local offer that doesn't
1549// have cryptos enabled when DTLS is off.
1550TEST_F(WebRtcSessionTest, TestSetNonSdesOfferWhenSdesOn) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001551 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001552 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001553 options.recv_video = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001554 JsepSessionDescription* offer = CreateRemoteOffer(
1555 options, cricket::SEC_DISABLED);
1556 ASSERT_TRUE(offer != NULL);
1557 VerifyNoCryptoParams(offer->description(), false);
1558 // SetRemoteDescription and SetLocalDescription will take the ownership of
1559 // the offer.
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001560 SetRemoteDescriptionOfferExpectError(kSdpWithoutSdesCrypto, offer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001561 offer = CreateRemoteOffer(options, cricket::SEC_DISABLED);
1562 ASSERT_TRUE(offer != NULL);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001563 SetLocalDescriptionOfferExpectError(kSdpWithoutSdesCrypto, offer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001564}
1565
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001566// Test that we return a failure when applying a local answer that doesn't have
1567// cryptos enabled when DTLS is off.
1568TEST_F(WebRtcSessionTest, TestSetLocalNonSdesAnswerWhenSdesOn) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001569 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001570 SessionDescriptionInterface* offer = NULL;
1571 SessionDescriptionInterface* answer = NULL;
1572 CreateCryptoOfferAndNonCryptoAnswer(&offer, &answer);
1573 // SetRemoteDescription and SetLocalDescription will take the ownership of
1574 // the offer.
1575 SetRemoteDescriptionWithoutError(offer);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001576 SetLocalDescriptionAnswerExpectError(kSdpWithoutSdesCrypto, answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001577}
1578
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001579// Test we will return fail when apply an remote answer that doesn't have
1580// crypto enabled when DTLS is off.
1581TEST_F(WebRtcSessionTest, TestSetRemoteNonSdesAnswerWhenSdesOn) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001582 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001583 SessionDescriptionInterface* offer = NULL;
1584 SessionDescriptionInterface* answer = NULL;
1585 CreateCryptoOfferAndNonCryptoAnswer(&offer, &answer);
1586 // SetRemoteDescription and SetLocalDescription will take the ownership of
1587 // the offer.
1588 SetLocalDescriptionWithoutError(offer);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001589 SetRemoteDescriptionAnswerExpectError(kSdpWithoutSdesCrypto, answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001590}
1591
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001592// Test that we accept an offer with a DTLS fingerprint when DTLS is on
1593// and that we return an answer with a DTLS fingerprint.
1594TEST_F(WebRtcSessionTest, TestReceiveDtlsOfferCreateDtlsAnswer) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001595 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001596 mediastream_signaling_.SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001597 InitWithDtls();
1598 SetFactoryDtlsSrtp();
1599 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001600 options.recv_video = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001601 JsepSessionDescription* offer =
1602 CreateRemoteOffer(options, cricket::SEC_DISABLED);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001603 ASSERT_TRUE(offer != NULL);
1604 VerifyFingerprintStatus(offer->description(), true);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001605 VerifyNoCryptoParams(offer->description(), true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001606
1607 // SetRemoteDescription will take the ownership of the offer.
1608 SetRemoteDescriptionWithoutError(offer);
1609
1610 // Verify that we get a crypto fingerprint in the answer.
wu@webrtc.org91053e72013-08-10 07:18:04 +00001611 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001612 ASSERT_TRUE(answer != NULL);
1613 VerifyFingerprintStatus(answer->description(), true);
1614 // Check that we don't have an a=crypto line in the answer.
1615 VerifyNoCryptoParams(answer->description(), true);
1616
1617 // Now set the local description, which should work, even without a=crypto.
1618 SetLocalDescriptionWithoutError(answer);
1619}
1620
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001621// Test that we set a local offer with a DTLS fingerprint when DTLS is on
1622// and then we accept a remote answer with a DTLS fingerprint successfully.
1623TEST_F(WebRtcSessionTest, TestCreateDtlsOfferReceiveDtlsAnswer) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001624 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001625 mediastream_signaling_.SendAudioVideoStream1();
1626 InitWithDtls();
1627 SetFactoryDtlsSrtp();
1628
1629 // Verify that we get a crypto fingerprint in the answer.
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001630 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001631 ASSERT_TRUE(offer != NULL);
1632 VerifyFingerprintStatus(offer->description(), true);
1633 // Check that we don't have an a=crypto line in the offer.
1634 VerifyNoCryptoParams(offer->description(), true);
1635
1636 // Now set the local description, which should work, even without a=crypto.
1637 SetLocalDescriptionWithoutError(offer);
1638
1639 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001640 options.recv_video = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001641 JsepSessionDescription* answer =
1642 CreateRemoteAnswer(offer, options, cricket::SEC_DISABLED);
1643 ASSERT_TRUE(answer != NULL);
1644 VerifyFingerprintStatus(answer->description(), true);
1645 VerifyNoCryptoParams(answer->description(), true);
1646
1647 // SetRemoteDescription will take the ownership of the answer.
1648 SetRemoteDescriptionWithoutError(answer);
1649}
1650
1651// Test that if we support DTLS and the other side didn't offer a fingerprint,
1652// we will fail to set the remote description.
1653TEST_F(WebRtcSessionTest, TestReceiveNonDtlsOfferWhenDtlsOn) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001654 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001655 InitWithDtls();
1656 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001657 options.recv_video = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001658 options.bundle_enabled = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001659 JsepSessionDescription* offer = CreateRemoteOffer(
1660 options, cricket::SEC_REQUIRED);
1661 ASSERT_TRUE(offer != NULL);
1662 VerifyFingerprintStatus(offer->description(), false);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001663 VerifyCryptoParams(offer->description());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001664
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001665 // SetRemoteDescription will take the ownership of the offer.
1666 SetRemoteDescriptionOfferExpectError(
1667 kSdpWithoutDtlsFingerprint, offer);
1668
1669 offer = CreateRemoteOffer(options, cricket::SEC_REQUIRED);
1670 // SetLocalDescription will take the ownership of the offer.
1671 SetLocalDescriptionOfferExpectError(
1672 kSdpWithoutDtlsFingerprint, offer);
1673}
1674
1675// Test that we return a failure when applying a local answer that doesn't have
1676// a DTLS fingerprint when DTLS is required.
1677TEST_F(WebRtcSessionTest, TestSetLocalNonDtlsAnswerWhenDtlsOn) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001678 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001679 InitWithDtls();
1680 SessionDescriptionInterface* offer = NULL;
1681 SessionDescriptionInterface* answer = NULL;
1682 CreateDtlsOfferAndNonDtlsAnswer(&offer, &answer);
1683
1684 // SetRemoteDescription and SetLocalDescription will take the ownership of
1685 // the offer and answer.
1686 SetRemoteDescriptionWithoutError(offer);
1687 SetLocalDescriptionAnswerExpectError(
1688 kSdpWithoutDtlsFingerprint, answer);
1689}
1690
1691// Test that we return a failure when applying a remote answer that doesn't have
1692// a DTLS fingerprint when DTLS is required.
1693TEST_F(WebRtcSessionTest, TestSetRemoteNonDtlsAnswerWhenDtlsOn) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001694 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001695 InitWithDtls();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001696 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001697 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001698 options.recv_video = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001699 JsepSessionDescription* answer =
1700 CreateRemoteAnswer(offer, options, cricket::SEC_ENABLED);
1701
1702 // SetRemoteDescription and SetLocalDescription will take the ownership of
1703 // the offer and answer.
1704 SetLocalDescriptionWithoutError(offer);
1705 SetRemoteDescriptionAnswerExpectError(
1706 kSdpWithoutDtlsFingerprint, answer);
1707}
1708
1709// Test that we create a local offer without SDES or DTLS and accept a remote
1710// answer without SDES or DTLS when encryption is disabled.
1711TEST_F(WebRtcSessionTest, TestCreateOfferReceiveAnswerWithoutEncryption) {
1712 mediastream_signaling_.SendAudioVideoStream1();
1713 options_.disable_encryption = true;
1714 InitWithDtls();
1715
1716 // Verify that we get a crypto fingerprint in the answer.
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001717 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001718 ASSERT_TRUE(offer != NULL);
1719 VerifyFingerprintStatus(offer->description(), false);
1720 // Check that we don't have an a=crypto line in the offer.
1721 VerifyNoCryptoParams(offer->description(), false);
1722
1723 // Now set the local description, which should work, even without a=crypto.
1724 SetLocalDescriptionWithoutError(offer);
1725
1726 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001727 options.recv_video = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001728 JsepSessionDescription* answer =
1729 CreateRemoteAnswer(offer, options, cricket::SEC_DISABLED);
1730 ASSERT_TRUE(answer != NULL);
1731 VerifyFingerprintStatus(answer->description(), false);
1732 VerifyNoCryptoParams(answer->description(), false);
1733
1734 // SetRemoteDescription will take the ownership of the answer.
1735 SetRemoteDescriptionWithoutError(answer);
1736}
1737
1738// Test that we create a local answer without SDES or DTLS and accept a remote
1739// offer without SDES or DTLS when encryption is disabled.
1740TEST_F(WebRtcSessionTest, TestCreateAnswerReceiveOfferWithoutEncryption) {
1741 options_.disable_encryption = true;
1742 InitWithDtls();
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* offer =
1747 CreateRemoteOffer(options, cricket::SEC_DISABLED);
1748 ASSERT_TRUE(offer != NULL);
1749 VerifyFingerprintStatus(offer->description(), false);
1750 VerifyNoCryptoParams(offer->description(), false);
1751
1752 // SetRemoteDescription will take the ownership of the offer.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001753 SetRemoteDescriptionWithoutError(offer);
1754
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001755 // Verify that we get a crypto fingerprint in the answer.
wu@webrtc.org91053e72013-08-10 07:18:04 +00001756 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001757 ASSERT_TRUE(answer != NULL);
1758 VerifyFingerprintStatus(answer->description(), false);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001759 // Check that we don't have an a=crypto line in the answer.
1760 VerifyNoCryptoParams(answer->description(), false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001761
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001762 // Now set the local description, which should work, even without a=crypto.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001763 SetLocalDescriptionWithoutError(answer);
1764}
1765
1766TEST_F(WebRtcSessionTest, TestSetLocalOfferTwice) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001767 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001768 mediastream_signaling_.SendNothing();
1769 // SetLocalDescription take ownership of offer.
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001770 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001771 SetLocalDescriptionWithoutError(offer);
1772
1773 // SetLocalDescription take ownership of offer.
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001774 SessionDescriptionInterface* offer2 = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001775 SetLocalDescriptionWithoutError(offer2);
1776}
1777
1778TEST_F(WebRtcSessionTest, TestSetRemoteOfferTwice) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001779 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001780 mediastream_signaling_.SendNothing();
1781 // SetLocalDescription take ownership of offer.
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001782 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001783 SetRemoteDescriptionWithoutError(offer);
1784
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001785 SessionDescriptionInterface* offer2 = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001786 SetRemoteDescriptionWithoutError(offer2);
1787}
1788
1789TEST_F(WebRtcSessionTest, TestSetLocalAndRemoteOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001790 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001791 mediastream_signaling_.SendNothing();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001792 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001793 SetLocalDescriptionWithoutError(offer);
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001794 offer = CreateOffer();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001795 SetRemoteDescriptionOfferExpectError(
1796 "Called in wrong state: STATE_SENTINITIATE", offer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001797}
1798
1799TEST_F(WebRtcSessionTest, TestSetRemoteAndLocalOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001800 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001801 mediastream_signaling_.SendNothing();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001802 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001803 SetRemoteDescriptionWithoutError(offer);
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001804 offer = CreateOffer();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001805 SetLocalDescriptionOfferExpectError(
1806 "Called in wrong state: STATE_RECEIVEDINITIATE", offer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001807}
1808
1809TEST_F(WebRtcSessionTest, TestSetLocalPrAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001810 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001811 mediastream_signaling_.SendNothing();
1812 SessionDescriptionInterface* offer = CreateRemoteOffer();
1813 SetRemoteDescriptionExpectState(offer, BaseSession::STATE_RECEIVEDINITIATE);
1814
1815 JsepSessionDescription* pranswer = static_cast<JsepSessionDescription*>(
wu@webrtc.org91053e72013-08-10 07:18:04 +00001816 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001817 pranswer->set_type(SessionDescriptionInterface::kPrAnswer);
1818 SetLocalDescriptionExpectState(pranswer, BaseSession::STATE_SENTPRACCEPT);
1819
1820 mediastream_signaling_.SendAudioVideoStream1();
1821 JsepSessionDescription* pranswer2 = static_cast<JsepSessionDescription*>(
wu@webrtc.org91053e72013-08-10 07:18:04 +00001822 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001823 pranswer2->set_type(SessionDescriptionInterface::kPrAnswer);
1824
1825 SetLocalDescriptionExpectState(pranswer2, BaseSession::STATE_SENTPRACCEPT);
1826
1827 mediastream_signaling_.SendAudioVideoStream2();
wu@webrtc.org91053e72013-08-10 07:18:04 +00001828 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001829 SetLocalDescriptionExpectState(answer, BaseSession::STATE_SENTACCEPT);
1830}
1831
1832TEST_F(WebRtcSessionTest, TestSetRemotePrAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001833 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001834 mediastream_signaling_.SendNothing();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001835 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001836 SetLocalDescriptionExpectState(offer, BaseSession::STATE_SENTINITIATE);
1837
1838 JsepSessionDescription* pranswer =
1839 CreateRemoteAnswer(session_->local_description());
1840 pranswer->set_type(SessionDescriptionInterface::kPrAnswer);
1841
1842 SetRemoteDescriptionExpectState(pranswer,
1843 BaseSession::STATE_RECEIVEDPRACCEPT);
1844
1845 mediastream_signaling_.SendAudioVideoStream1();
1846 JsepSessionDescription* pranswer2 =
1847 CreateRemoteAnswer(session_->local_description());
1848 pranswer2->set_type(SessionDescriptionInterface::kPrAnswer);
1849
1850 SetRemoteDescriptionExpectState(pranswer2,
1851 BaseSession::STATE_RECEIVEDPRACCEPT);
1852
1853 mediastream_signaling_.SendAudioVideoStream2();
1854 SessionDescriptionInterface* answer =
1855 CreateRemoteAnswer(session_->local_description());
1856 SetRemoteDescriptionExpectState(answer, BaseSession::STATE_RECEIVEDACCEPT);
1857}
1858
1859TEST_F(WebRtcSessionTest, TestSetLocalAnswerWithoutOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001860 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001861 mediastream_signaling_.SendNothing();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001862 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
1863
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001864 SessionDescriptionInterface* answer =
1865 CreateRemoteAnswer(offer.get());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001866 SetLocalDescriptionAnswerExpectError("Called in wrong state: STATE_INIT",
1867 answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001868}
1869
1870TEST_F(WebRtcSessionTest, TestSetRemoteAnswerWithoutOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001871 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001872 mediastream_signaling_.SendNothing();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001873 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
1874
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001875 SessionDescriptionInterface* answer =
1876 CreateRemoteAnswer(offer.get());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001877 SetRemoteDescriptionAnswerExpectError(
1878 "Called in wrong state: STATE_INIT", answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001879}
1880
1881TEST_F(WebRtcSessionTest, TestAddRemoteCandidate) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001882 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001883 mediastream_signaling_.SendAudioVideoStream1();
1884
1885 cricket::Candidate candidate;
1886 candidate.set_component(1);
1887 JsepIceCandidate ice_candidate1(kMediaContentName0, 0, candidate);
1888
1889 // Fail since we have not set a offer description.
1890 EXPECT_FALSE(session_->ProcessIceMessage(&ice_candidate1));
1891
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001892 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001893 SetLocalDescriptionWithoutError(offer);
1894 // Candidate should be allowed to add before remote description.
1895 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate1));
1896 candidate.set_component(2);
1897 JsepIceCandidate ice_candidate2(kMediaContentName0, 0, candidate);
1898 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate2));
1899
1900 SessionDescriptionInterface* answer = CreateRemoteAnswer(
1901 session_->local_description());
1902 SetRemoteDescriptionWithoutError(answer);
1903
1904 // Verifying the candidates are copied properly from internal vector.
1905 const SessionDescriptionInterface* remote_desc =
1906 session_->remote_description();
1907 ASSERT_TRUE(remote_desc != NULL);
1908 ASSERT_EQ(2u, remote_desc->number_of_mediasections());
1909 const IceCandidateCollection* candidates =
1910 remote_desc->candidates(kMediaContentIndex0);
1911 ASSERT_EQ(2u, candidates->count());
1912 EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
1913 EXPECT_EQ(kMediaContentName0, candidates->at(0)->sdp_mid());
1914 EXPECT_EQ(1, candidates->at(0)->candidate().component());
1915 EXPECT_EQ(2, candidates->at(1)->candidate().component());
1916
mallinath@webrtc.org67ee6b92014-02-03 16:57:16 +00001917 // |ice_candidate3| is identical to |ice_candidate2|. It can be added
1918 // successfully, but the total count of candidates will not increase.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001919 candidate.set_component(2);
1920 JsepIceCandidate ice_candidate3(kMediaContentName0, 0, candidate);
1921 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate3));
mallinath@webrtc.org67ee6b92014-02-03 16:57:16 +00001922 ASSERT_EQ(2u, candidates->count());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001923
1924 JsepIceCandidate bad_ice_candidate("bad content name", 99, candidate);
1925 EXPECT_FALSE(session_->ProcessIceMessage(&bad_ice_candidate));
1926}
1927
1928// Test that a remote candidate is added to the remote session description and
1929// that it is retained if the remote session description is changed.
1930TEST_F(WebRtcSessionTest, TestRemoteCandidatesAddedToSessionDescription) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001931 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001932 cricket::Candidate candidate1;
1933 candidate1.set_component(1);
1934 JsepIceCandidate ice_candidate1(kMediaContentName0, kMediaContentIndex0,
1935 candidate1);
1936 mediastream_signaling_.SendAudioVideoStream1();
1937 CreateAndSetRemoteOfferAndLocalAnswer();
1938
1939 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate1));
1940 const SessionDescriptionInterface* remote_desc =
1941 session_->remote_description();
1942 ASSERT_TRUE(remote_desc != NULL);
1943 ASSERT_EQ(2u, remote_desc->number_of_mediasections());
1944 const IceCandidateCollection* candidates =
1945 remote_desc->candidates(kMediaContentIndex0);
1946 ASSERT_EQ(1u, candidates->count());
1947 EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
1948
1949 // Update the RemoteSessionDescription with a new session description and
1950 // a candidate and check that the new remote session description contains both
1951 // candidates.
1952 SessionDescriptionInterface* offer = CreateRemoteOffer();
1953 cricket::Candidate candidate2;
1954 JsepIceCandidate ice_candidate2(kMediaContentName0, kMediaContentIndex0,
1955 candidate2);
1956 EXPECT_TRUE(offer->AddCandidate(&ice_candidate2));
1957 SetRemoteDescriptionWithoutError(offer);
1958
1959 remote_desc = session_->remote_description();
1960 ASSERT_TRUE(remote_desc != NULL);
1961 ASSERT_EQ(2u, remote_desc->number_of_mediasections());
1962 candidates = remote_desc->candidates(kMediaContentIndex0);
1963 ASSERT_EQ(2u, candidates->count());
1964 EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
1965 // Username and password have be updated with the TransportInfo of the
1966 // SessionDescription, won't be equal to the original one.
1967 candidate2.set_username(candidates->at(0)->candidate().username());
1968 candidate2.set_password(candidates->at(0)->candidate().password());
1969 EXPECT_TRUE(candidate2.IsEquivalent(candidates->at(0)->candidate()));
1970 EXPECT_EQ(kMediaContentIndex0, candidates->at(1)->sdp_mline_index());
1971 // No need to verify the username and password.
1972 candidate1.set_username(candidates->at(1)->candidate().username());
1973 candidate1.set_password(candidates->at(1)->candidate().password());
1974 EXPECT_TRUE(candidate1.IsEquivalent(candidates->at(1)->candidate()));
1975
1976 // Test that the candidate is ignored if we can add the same candidate again.
1977 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate2));
1978}
1979
1980// Test that local candidates are added to the local session description and
1981// that they are retained if the local session description is changed.
1982TEST_F(WebRtcSessionTest, TestLocalCandidatesAddedToSessionDescription) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001983 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001984 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001985 mediastream_signaling_.SendAudioVideoStream1();
1986 CreateAndSetRemoteOfferAndLocalAnswer();
1987
1988 const SessionDescriptionInterface* local_desc = session_->local_description();
1989 const IceCandidateCollection* candidates =
1990 local_desc->candidates(kMediaContentIndex0);
1991 ASSERT_TRUE(candidates != NULL);
1992 EXPECT_EQ(0u, candidates->count());
1993
1994 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1995
1996 local_desc = session_->local_description();
1997 candidates = local_desc->candidates(kMediaContentIndex0);
1998 ASSERT_TRUE(candidates != NULL);
1999 EXPECT_LT(0u, candidates->count());
2000 candidates = local_desc->candidates(1);
2001 ASSERT_TRUE(candidates != NULL);
2002 EXPECT_LT(0u, candidates->count());
2003
2004 // Update the session descriptions.
2005 mediastream_signaling_.SendAudioVideoStream1();
2006 CreateAndSetRemoteOfferAndLocalAnswer();
2007
2008 local_desc = session_->local_description();
2009 candidates = local_desc->candidates(kMediaContentIndex0);
2010 ASSERT_TRUE(candidates != NULL);
2011 EXPECT_LT(0u, candidates->count());
2012 candidates = local_desc->candidates(1);
2013 ASSERT_TRUE(candidates != NULL);
2014 EXPECT_LT(0u, candidates->count());
2015}
2016
2017// Test that we can set a remote session description with remote candidates.
2018TEST_F(WebRtcSessionTest, TestSetRemoteSessionDescriptionWithCandidates) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002019 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002020
2021 cricket::Candidate candidate1;
2022 candidate1.set_component(1);
2023 JsepIceCandidate ice_candidate(kMediaContentName0, kMediaContentIndex0,
2024 candidate1);
2025 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002026 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002027
2028 EXPECT_TRUE(offer->AddCandidate(&ice_candidate));
2029 SetRemoteDescriptionWithoutError(offer);
2030
2031 const SessionDescriptionInterface* remote_desc =
2032 session_->remote_description();
2033 ASSERT_TRUE(remote_desc != NULL);
2034 ASSERT_EQ(2u, remote_desc->number_of_mediasections());
2035 const IceCandidateCollection* candidates =
2036 remote_desc->candidates(kMediaContentIndex0);
2037 ASSERT_EQ(1u, candidates->count());
2038 EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
2039
wu@webrtc.org91053e72013-08-10 07:18:04 +00002040 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002041 SetLocalDescriptionWithoutError(answer);
2042}
2043
2044// Test that offers and answers contains ice candidates when Ice candidates have
2045// been gathered.
2046TEST_F(WebRtcSessionTest, TestSetLocalAndRemoteDescriptionWithCandidates) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002047 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002048 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002049 mediastream_signaling_.SendAudioVideoStream1();
2050 // Ice is started but candidates are not provided until SetLocalDescription
2051 // is called.
2052 EXPECT_EQ(0u, observer_.mline_0_candidates_.size());
2053 EXPECT_EQ(0u, observer_.mline_1_candidates_.size());
2054 CreateAndSetRemoteOfferAndLocalAnswer();
2055 // Wait until at least one local candidate has been collected.
2056 EXPECT_TRUE_WAIT(0u < observer_.mline_0_candidates_.size(),
2057 kIceCandidatesTimeout);
2058 EXPECT_TRUE_WAIT(0u < observer_.mline_1_candidates_.size(),
2059 kIceCandidatesTimeout);
2060
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002061 rtc::scoped_ptr<SessionDescriptionInterface> local_offer(CreateOffer());
2062
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002063 ASSERT_TRUE(local_offer->candidates(kMediaContentIndex0) != NULL);
2064 EXPECT_LT(0u, local_offer->candidates(kMediaContentIndex0)->count());
2065 ASSERT_TRUE(local_offer->candidates(kMediaContentIndex1) != NULL);
2066 EXPECT_LT(0u, local_offer->candidates(kMediaContentIndex1)->count());
2067
2068 SessionDescriptionInterface* remote_offer(CreateRemoteOffer());
2069 SetRemoteDescriptionWithoutError(remote_offer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00002070 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002071 ASSERT_TRUE(answer->candidates(kMediaContentIndex0) != NULL);
2072 EXPECT_LT(0u, answer->candidates(kMediaContentIndex0)->count());
2073 ASSERT_TRUE(answer->candidates(kMediaContentIndex1) != NULL);
2074 EXPECT_LT(0u, answer->candidates(kMediaContentIndex1)->count());
2075 SetLocalDescriptionWithoutError(answer);
2076}
2077
2078// Verifies TransportProxy and media channels are created with content names
2079// present in the SessionDescription.
2080TEST_F(WebRtcSessionTest, TestChannelCreationsWithContentNames) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002081 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002082 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002083 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002084
2085 // CreateOffer creates session description with the content names "audio" and
2086 // "video". Goal is to modify these content names and verify transport channel
2087 // proxy in the BaseSession, as proxies are created with the content names
2088 // present in SDP.
2089 std::string sdp;
2090 EXPECT_TRUE(offer->ToString(&sdp));
2091 const std::string kAudioMid = "a=mid:audio";
2092 const std::string kAudioMidReplaceStr = "a=mid:audio_content_name";
2093 const std::string kVideoMid = "a=mid:video";
2094 const std::string kVideoMidReplaceStr = "a=mid:video_content_name";
2095
2096 // Replacing |audio| with |audio_content_name|.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002097 rtc::replace_substrs(kAudioMid.c_str(), kAudioMid.length(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002098 kAudioMidReplaceStr.c_str(),
2099 kAudioMidReplaceStr.length(),
2100 &sdp);
2101 // Replacing |video| with |video_content_name|.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002102 rtc::replace_substrs(kVideoMid.c_str(), kVideoMid.length(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002103 kVideoMidReplaceStr.c_str(),
2104 kVideoMidReplaceStr.length(),
2105 &sdp);
2106
2107 SessionDescriptionInterface* modified_offer =
2108 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
2109
2110 SetRemoteDescriptionWithoutError(modified_offer);
2111
2112 SessionDescriptionInterface* answer =
wu@webrtc.org91053e72013-08-10 07:18:04 +00002113 CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002114 SetLocalDescriptionWithoutError(answer);
2115
2116 EXPECT_TRUE(session_->GetTransportProxy("audio_content_name") != NULL);
2117 EXPECT_TRUE(session_->GetTransportProxy("video_content_name") != NULL);
2118 EXPECT_TRUE((video_channel_ = media_engine_->GetVideoChannel(0)) != NULL);
2119 EXPECT_TRUE((voice_channel_ = media_engine_->GetVoiceChannel(0)) != NULL);
2120}
2121
2122// Test that an offer contains the correct media content descriptions based on
2123// the send streams when no constraints have been set.
2124TEST_F(WebRtcSessionTest, CreateOfferWithoutConstraintsOrStreams) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002125 Init();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002126 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
2127
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002128 ASSERT_TRUE(offer != NULL);
2129 const cricket::ContentInfo* content =
2130 cricket::GetFirstAudioContent(offer->description());
2131 EXPECT_TRUE(content != NULL);
2132 content = cricket::GetFirstVideoContent(offer->description());
2133 EXPECT_TRUE(content == NULL);
2134}
2135
2136// Test that an offer contains the correct media content descriptions based on
2137// the send streams when no constraints have been set.
2138TEST_F(WebRtcSessionTest, CreateOfferWithoutConstraints) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002139 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002140 // Test Audio only offer.
2141 mediastream_signaling_.UseOptionsAudioOnly();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002142 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
2143
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002144 const cricket::ContentInfo* content =
2145 cricket::GetFirstAudioContent(offer->description());
2146 EXPECT_TRUE(content != NULL);
2147 content = cricket::GetFirstVideoContent(offer->description());
2148 EXPECT_TRUE(content == NULL);
2149
2150 // Test Audio / Video offer.
2151 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002152 offer.reset(CreateOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002153 content = cricket::GetFirstAudioContent(offer->description());
2154 EXPECT_TRUE(content != NULL);
2155 content = cricket::GetFirstVideoContent(offer->description());
2156 EXPECT_TRUE(content != NULL);
2157}
2158
2159// Test that an offer contains no media content descriptions if
2160// kOfferToReceiveVideo and kOfferToReceiveAudio constraints are set to false.
2161TEST_F(WebRtcSessionTest, CreateOfferWithConstraintsWithoutStreams) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002162 Init();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002163 PeerConnectionInterface::RTCOfferAnswerOptions options;
2164 options.offer_to_receive_audio = 0;
2165 options.offer_to_receive_video = 0;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002166
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002167 rtc::scoped_ptr<SessionDescriptionInterface> offer(
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002168 CreateOffer(options));
2169
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002170 ASSERT_TRUE(offer != NULL);
2171 const cricket::ContentInfo* content =
2172 cricket::GetFirstAudioContent(offer->description());
2173 EXPECT_TRUE(content == NULL);
2174 content = cricket::GetFirstVideoContent(offer->description());
2175 EXPECT_TRUE(content == NULL);
2176}
2177
2178// Test that an offer contains only audio media content descriptions if
2179// kOfferToReceiveAudio constraints are set to true.
2180TEST_F(WebRtcSessionTest, CreateAudioOnlyOfferWithConstraints) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002181 Init();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002182 PeerConnectionInterface::RTCOfferAnswerOptions options;
2183 options.offer_to_receive_audio =
2184 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
2185
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002186 rtc::scoped_ptr<SessionDescriptionInterface> offer(
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002187 CreateOffer(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002188
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 audio and video media content descriptions if
2197// kOfferToReceiveAudio and kOfferToReceiveVideo constraints are set to true.
2198TEST_F(WebRtcSessionTest, CreateOfferWithConstraints) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002199 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002200 // Test Audio / Video offer.
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002201 PeerConnectionInterface::RTCOfferAnswerOptions options;
2202 options.offer_to_receive_audio =
2203 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
2204 options.offer_to_receive_video =
2205 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
2206
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002207 rtc::scoped_ptr<SessionDescriptionInterface> offer(
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002208 CreateOffer(options));
2209
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002210 const cricket::ContentInfo* content =
2211 cricket::GetFirstAudioContent(offer->description());
jiayl@webrtc.orgc1723202014-09-08 20:44:36 +00002212 EXPECT_TRUE(content != NULL);
jiayl@webrtc.org7d4891d2014-09-09 21:43:15 +00002213
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002214 content = cricket::GetFirstVideoContent(offer->description());
2215 EXPECT_TRUE(content != NULL);
2216
jiayl@webrtc.org7d4891d2014-09-09 21:43:15 +00002217 // Sets constraints to false and verifies that audio/video contents are
2218 // removed.
2219 options.offer_to_receive_audio = 0;
2220 options.offer_to_receive_video = 0;
2221 offer.reset(CreateOffer(options));
2222
2223 content = cricket::GetFirstAudioContent(offer->description());
2224 EXPECT_TRUE(content == NULL);
2225 content = cricket::GetFirstVideoContent(offer->description());
2226 EXPECT_TRUE(content == NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002227}
2228
2229// Test that an answer can not be created if the last remote description is not
2230// an offer.
2231TEST_F(WebRtcSessionTest, CreateAnswerWithoutAnOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002232 Init();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002233 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002234 SetLocalDescriptionWithoutError(offer);
2235 SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
2236 SetRemoteDescriptionWithoutError(answer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00002237 EXPECT_TRUE(CreateAnswer(NULL) == NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002238}
2239
2240// Test that an answer contains the correct media content descriptions when no
2241// constraints have been set.
2242TEST_F(WebRtcSessionTest, CreateAnswerWithoutConstraintsOrStreams) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002243 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002244 // Create a remote offer with audio and video content.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002245 rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002246 SetRemoteDescriptionWithoutError(offer.release());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002247 rtc::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002248 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002249 const cricket::ContentInfo* content =
2250 cricket::GetFirstAudioContent(answer->description());
2251 ASSERT_TRUE(content != NULL);
2252 EXPECT_FALSE(content->rejected);
2253
2254 content = cricket::GetFirstVideoContent(answer->description());
2255 ASSERT_TRUE(content != NULL);
2256 EXPECT_FALSE(content->rejected);
2257}
2258
2259// Test that an answer contains the correct media content descriptions when no
2260// constraints have been set and the offer only contain audio.
2261TEST_F(WebRtcSessionTest, CreateAudioAnswerWithoutConstraintsOrStreams) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002262 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002263 // Create a remote offer with audio only.
2264 cricket::MediaSessionOptions options;
jiayl@webrtc.org7d4891d2014-09-09 21:43:15 +00002265
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002266 rtc::scoped_ptr<JsepSessionDescription> offer(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002267 CreateRemoteOffer(options));
2268 ASSERT_TRUE(cricket::GetFirstVideoContent(offer->description()) == NULL);
2269 ASSERT_TRUE(cricket::GetFirstAudioContent(offer->description()) != NULL);
2270
2271 SetRemoteDescriptionWithoutError(offer.release());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002272 rtc::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002273 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002274 const cricket::ContentInfo* content =
2275 cricket::GetFirstAudioContent(answer->description());
2276 ASSERT_TRUE(content != NULL);
2277 EXPECT_FALSE(content->rejected);
2278
2279 EXPECT_TRUE(cricket::GetFirstVideoContent(answer->description()) == NULL);
2280}
2281
2282// Test that an answer contains the correct media content descriptions when no
2283// constraints have been set.
2284TEST_F(WebRtcSessionTest, CreateAnswerWithoutConstraints) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002285 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002286 // Create a remote offer with audio and video content.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002287 rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002288 SetRemoteDescriptionWithoutError(offer.release());
2289 // Test with a stream with tracks.
2290 mediastream_signaling_.SendAudioVideoStream1();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002291 rtc::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002292 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002293 const cricket::ContentInfo* content =
2294 cricket::GetFirstAudioContent(answer->description());
2295 ASSERT_TRUE(content != NULL);
2296 EXPECT_FALSE(content->rejected);
2297
2298 content = cricket::GetFirstVideoContent(answer->description());
2299 ASSERT_TRUE(content != NULL);
2300 EXPECT_FALSE(content->rejected);
2301}
2302
2303// Test that an answer contains the correct media content descriptions when
2304// constraints have been set but no stream is sent.
2305TEST_F(WebRtcSessionTest, CreateAnswerWithConstraintsWithoutStreams) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002306 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002307 // Create a remote offer with audio and video content.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002308 rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002309 SetRemoteDescriptionWithoutError(offer.release());
2310
2311 webrtc::FakeConstraints constraints_no_receive;
2312 constraints_no_receive.SetMandatoryReceiveAudio(false);
2313 constraints_no_receive.SetMandatoryReceiveVideo(false);
2314
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002315 rtc::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002316 CreateAnswer(&constraints_no_receive));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002317 const cricket::ContentInfo* content =
2318 cricket::GetFirstAudioContent(answer->description());
2319 ASSERT_TRUE(content != NULL);
2320 EXPECT_TRUE(content->rejected);
2321
2322 content = cricket::GetFirstVideoContent(answer->description());
2323 ASSERT_TRUE(content != NULL);
2324 EXPECT_TRUE(content->rejected);
2325}
2326
2327// Test that an answer contains the correct media content descriptions when
2328// constraints have been set and streams are sent.
2329TEST_F(WebRtcSessionTest, CreateAnswerWithConstraints) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002330 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002331 // Create a remote offer with audio and video content.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002332 rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002333 SetRemoteDescriptionWithoutError(offer.release());
2334
2335 webrtc::FakeConstraints constraints_no_receive;
2336 constraints_no_receive.SetMandatoryReceiveAudio(false);
2337 constraints_no_receive.SetMandatoryReceiveVideo(false);
2338
2339 // Test with a stream with tracks.
2340 mediastream_signaling_.SendAudioVideoStream1();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002341 rtc::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002342 CreateAnswer(&constraints_no_receive));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002343
2344 // TODO(perkj): Should the direction be set to SEND_ONLY?
2345 const cricket::ContentInfo* content =
2346 cricket::GetFirstAudioContent(answer->description());
2347 ASSERT_TRUE(content != NULL);
2348 EXPECT_FALSE(content->rejected);
2349
2350 // TODO(perkj): Should the direction be set to SEND_ONLY?
2351 content = cricket::GetFirstVideoContent(answer->description());
2352 ASSERT_TRUE(content != NULL);
2353 EXPECT_FALSE(content->rejected);
2354}
2355
2356TEST_F(WebRtcSessionTest, CreateOfferWithoutCNCodecs) {
2357 AddCNCodecs();
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002358 Init();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002359 PeerConnectionInterface::RTCOfferAnswerOptions options;
2360 options.offer_to_receive_audio =
2361 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
2362 options.voice_activity_detection = false;
2363
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002364 rtc::scoped_ptr<SessionDescriptionInterface> offer(
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002365 CreateOffer(options));
2366
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002367 const cricket::ContentInfo* content =
2368 cricket::GetFirstAudioContent(offer->description());
2369 EXPECT_TRUE(content != NULL);
2370 EXPECT_TRUE(VerifyNoCNCodecs(content));
2371}
2372
2373TEST_F(WebRtcSessionTest, CreateAnswerWithoutCNCodecs) {
2374 AddCNCodecs();
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002375 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002376 // Create a remote offer with audio and video content.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002377 rtc::scoped_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002378 SetRemoteDescriptionWithoutError(offer.release());
2379
2380 webrtc::FakeConstraints constraints;
2381 constraints.SetOptionalVAD(false);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002382 rtc::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00002383 CreateAnswer(&constraints));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002384 const cricket::ContentInfo* content =
2385 cricket::GetFirstAudioContent(answer->description());
2386 ASSERT_TRUE(content != NULL);
2387 EXPECT_TRUE(VerifyNoCNCodecs(content));
2388}
2389
2390// This test verifies the call setup when remote answer with audio only and
2391// later updates with video.
2392TEST_F(WebRtcSessionTest, TestAVOfferWithAudioOnlyAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002393 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002394 EXPECT_TRUE(media_engine_->GetVideoChannel(0) == NULL);
2395 EXPECT_TRUE(media_engine_->GetVoiceChannel(0) == NULL);
2396
2397 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002398 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002399
2400 cricket::MediaSessionOptions options;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002401 SessionDescriptionInterface* answer = CreateRemoteAnswer(offer, options);
2402
2403 // SetLocalDescription and SetRemoteDescriptions takes ownership of offer
2404 // and answer;
2405 SetLocalDescriptionWithoutError(offer);
2406 SetRemoteDescriptionWithoutError(answer);
2407
2408 video_channel_ = media_engine_->GetVideoChannel(0);
2409 voice_channel_ = media_engine_->GetVoiceChannel(0);
2410
2411 ASSERT_TRUE(video_channel_ == NULL);
2412
2413 ASSERT_EQ(0u, voice_channel_->recv_streams().size());
2414 ASSERT_EQ(1u, voice_channel_->send_streams().size());
2415 EXPECT_EQ(kAudioTrack1, voice_channel_->send_streams()[0].id);
2416
2417 // Let the remote end update the session descriptions, with Audio and Video.
2418 mediastream_signaling_.SendAudioVideoStream2();
2419 CreateAndSetRemoteOfferAndLocalAnswer();
2420
2421 video_channel_ = media_engine_->GetVideoChannel(0);
2422 voice_channel_ = media_engine_->GetVoiceChannel(0);
2423
2424 ASSERT_TRUE(video_channel_ != NULL);
2425 ASSERT_TRUE(voice_channel_ != NULL);
2426
2427 ASSERT_EQ(1u, video_channel_->recv_streams().size());
2428 ASSERT_EQ(1u, video_channel_->send_streams().size());
2429 EXPECT_EQ(kVideoTrack2, video_channel_->recv_streams()[0].id);
2430 EXPECT_EQ(kVideoTrack2, video_channel_->send_streams()[0].id);
2431 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
2432 ASSERT_EQ(1u, voice_channel_->send_streams().size());
2433 EXPECT_EQ(kAudioTrack2, voice_channel_->recv_streams()[0].id);
2434 EXPECT_EQ(kAudioTrack2, voice_channel_->send_streams()[0].id);
2435
2436 // Change session back to audio only.
2437 mediastream_signaling_.UseOptionsAudioOnly();
2438 CreateAndSetRemoteOfferAndLocalAnswer();
2439
2440 EXPECT_EQ(0u, video_channel_->recv_streams().size());
2441 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
2442 EXPECT_EQ(kAudioTrack2, voice_channel_->recv_streams()[0].id);
2443 ASSERT_EQ(1u, voice_channel_->send_streams().size());
2444 EXPECT_EQ(kAudioTrack2, voice_channel_->send_streams()[0].id);
2445}
2446
2447// This test verifies the call setup when remote answer with video only and
2448// later updates with audio.
2449TEST_F(WebRtcSessionTest, TestAVOfferWithVideoOnlyAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002450 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002451 EXPECT_TRUE(media_engine_->GetVideoChannel(0) == NULL);
2452 EXPECT_TRUE(media_engine_->GetVoiceChannel(0) == NULL);
2453 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002454 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002455
2456 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00002457 options.recv_audio = false;
2458 options.recv_video = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002459 SessionDescriptionInterface* answer = CreateRemoteAnswer(
2460 offer, options, cricket::SEC_ENABLED);
2461
2462 // SetLocalDescription and SetRemoteDescriptions takes ownership of offer
2463 // and answer.
2464 SetLocalDescriptionWithoutError(offer);
2465 SetRemoteDescriptionWithoutError(answer);
2466
2467 video_channel_ = media_engine_->GetVideoChannel(0);
2468 voice_channel_ = media_engine_->GetVoiceChannel(0);
2469
2470 ASSERT_TRUE(voice_channel_ == NULL);
2471 ASSERT_TRUE(video_channel_ != NULL);
2472
2473 EXPECT_EQ(0u, video_channel_->recv_streams().size());
2474 ASSERT_EQ(1u, video_channel_->send_streams().size());
2475 EXPECT_EQ(kVideoTrack1, video_channel_->send_streams()[0].id);
2476
2477 // Update the session descriptions, with Audio and Video.
2478 mediastream_signaling_.SendAudioVideoStream2();
2479 CreateAndSetRemoteOfferAndLocalAnswer();
2480
2481 voice_channel_ = media_engine_->GetVoiceChannel(0);
2482 ASSERT_TRUE(voice_channel_ != NULL);
2483
2484 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
2485 ASSERT_EQ(1u, voice_channel_->send_streams().size());
2486 EXPECT_EQ(kAudioTrack2, voice_channel_->recv_streams()[0].id);
2487 EXPECT_EQ(kAudioTrack2, voice_channel_->send_streams()[0].id);
2488
2489 // Change session back to video only.
2490 mediastream_signaling_.UseOptionsVideoOnly();
2491 CreateAndSetRemoteOfferAndLocalAnswer();
2492
2493 video_channel_ = media_engine_->GetVideoChannel(0);
2494 voice_channel_ = media_engine_->GetVoiceChannel(0);
2495
2496 ASSERT_EQ(1u, video_channel_->recv_streams().size());
2497 EXPECT_EQ(kVideoTrack2, video_channel_->recv_streams()[0].id);
2498 ASSERT_EQ(1u, video_channel_->send_streams().size());
2499 EXPECT_EQ(kVideoTrack2, video_channel_->send_streams()[0].id);
2500}
2501
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002502TEST_F(WebRtcSessionTest, VerifyCryptoParamsInSDP) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002503 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002504 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002505 scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002506 VerifyCryptoParams(offer->description());
2507 SetRemoteDescriptionWithoutError(offer.release());
wu@webrtc.org91053e72013-08-10 07:18:04 +00002508 scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002509 VerifyCryptoParams(answer->description());
2510}
2511
2512TEST_F(WebRtcSessionTest, VerifyNoCryptoParamsInSDP) {
wu@webrtc.org97077a32013-10-25 21:18:33 +00002513 options_.disable_encryption = true;
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002514 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002515 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002516 scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002517 VerifyNoCryptoParams(offer->description(), false);
2518}
2519
2520TEST_F(WebRtcSessionTest, VerifyAnswerFromNonCryptoOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002521 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002522 VerifyAnswerFromNonCryptoOffer();
2523}
2524
2525TEST_F(WebRtcSessionTest, VerifyAnswerFromCryptoOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002526 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002527 VerifyAnswerFromCryptoOffer();
2528}
2529
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002530// This test verifies that setLocalDescription fails if
2531// no a=ice-ufrag and a=ice-pwd lines are present in the SDP.
2532TEST_F(WebRtcSessionTest, TestSetLocalDescriptionWithoutIce) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002533 Init();
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002534 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002535 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
2536
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002537 std::string sdp;
2538 RemoveIceUfragPwdLines(offer.get(), &sdp);
2539 SessionDescriptionInterface* modified_offer =
2540 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00002541 SetLocalDescriptionOfferExpectError(kSdpWithoutIceUfragPwd, modified_offer);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002542}
2543
2544// This test verifies that setRemoteDescription fails if
2545// no a=ice-ufrag and a=ice-pwd lines are present in the SDP.
2546TEST_F(WebRtcSessionTest, TestSetRemoteDescriptionWithoutIce) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002547 Init();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002548 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateRemoteOffer());
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002549 std::string sdp;
2550 RemoveIceUfragPwdLines(offer.get(), &sdp);
2551 SessionDescriptionInterface* modified_offer =
2552 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00002553 SetRemoteDescriptionOfferExpectError(kSdpWithoutIceUfragPwd, modified_offer);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002554}
2555
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +00002556// This test verifies that setLocalDescription fails if local offer has
2557// too short ice ufrag and pwd strings.
2558TEST_F(WebRtcSessionTest, TestSetLocalDescriptionInvalidIceCredentials) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002559 Init();
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +00002560 tdesc_factory_->set_protocol(cricket::ICEPROTO_RFC5245);
2561 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002562 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
2563
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +00002564 std::string sdp;
2565 // Modifying ice ufrag and pwd in local offer with strings smaller than the
2566 // recommended values of 4 and 22 bytes respectively.
2567 ModifyIceUfragPwdLines(offer.get(), "ice", "icepwd", &sdp);
2568 SessionDescriptionInterface* modified_offer =
2569 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
2570 std::string error;
2571 EXPECT_FALSE(session_->SetLocalDescription(modified_offer, &error));
2572
2573 // Test with string greater than 256.
2574 sdp.clear();
2575 ModifyIceUfragPwdLines(offer.get(), kTooLongIceUfragPwd, kTooLongIceUfragPwd,
2576 &sdp);
2577 modified_offer = CreateSessionDescription(JsepSessionDescription::kOffer, sdp,
2578 NULL);
2579 EXPECT_FALSE(session_->SetLocalDescription(modified_offer, &error));
2580}
2581
2582// This test verifies that setRemoteDescription fails if remote offer has
2583// too short ice ufrag and pwd strings.
2584TEST_F(WebRtcSessionTest, TestSetRemoteDescriptionInvalidIceCredentials) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002585 Init();
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +00002586 tdesc_factory_->set_protocol(cricket::ICEPROTO_RFC5245);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002587 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateRemoteOffer());
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +00002588 std::string sdp;
2589 // Modifying ice ufrag and pwd in remote offer with strings smaller than the
2590 // recommended values of 4 and 22 bytes respectively.
2591 ModifyIceUfragPwdLines(offer.get(), "ice", "icepwd", &sdp);
2592 SessionDescriptionInterface* modified_offer =
2593 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
2594 std::string error;
2595 EXPECT_FALSE(session_->SetRemoteDescription(modified_offer, &error));
2596
2597 sdp.clear();
2598 ModifyIceUfragPwdLines(offer.get(), kTooLongIceUfragPwd, kTooLongIceUfragPwd,
2599 &sdp);
2600 modified_offer = CreateSessionDescription(JsepSessionDescription::kOffer, sdp,
2601 NULL);
2602 EXPECT_FALSE(session_->SetRemoteDescription(modified_offer, &error));
2603}
2604
Peter Thatcher4eddf182015-04-30 10:55:59 -07002605// kBundlePolicyBalanced bundle policy and answer contains BUNDLE.
Donald Curtis0e209b02015-03-24 09:29:54 -07002606TEST_F(WebRtcSessionTest, TestBalancedBundleInAnswer) {
2607 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyBalanced);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002608 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002609
2610 PeerConnectionInterface::RTCOfferAnswerOptions options;
2611 options.use_rtp_mux = true;
2612
2613 SessionDescriptionInterface* offer = CreateOffer(options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002614 SetLocalDescriptionWithoutError(offer);
Donald Curtis0e209b02015-03-24 09:29:54 -07002615
2616 EXPECT_NE(session_->GetTransportProxy("audio")->impl(),
2617 session_->GetTransportProxy("video")->impl());
2618
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002619 mediastream_signaling_.SendAudioVideoStream2();
Donald Curtis0e209b02015-03-24 09:29:54 -07002620 SessionDescriptionInterface* answer =
2621 CreateRemoteAnswer(session_->local_description());
2622 SetRemoteDescriptionWithoutError(answer);
2623
2624 EXPECT_EQ(session_->GetTransportProxy("audio")->impl(),
2625 session_->GetTransportProxy("video")->impl());
2626}
2627
2628// kBundlePolicyBalanced bundle policy but no BUNDLE in the answer.
2629TEST_F(WebRtcSessionTest, TestBalancedNoBundleInAnswer) {
2630 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyBalanced);
2631 mediastream_signaling_.SendAudioVideoStream1();
Peter Thatcher4eddf182015-04-30 10:55:59 -07002632
Donald Curtis0e209b02015-03-24 09:29:54 -07002633 PeerConnectionInterface::RTCOfferAnswerOptions options;
2634 options.use_rtp_mux = true;
2635
2636 SessionDescriptionInterface* offer = CreateOffer(options);
2637 SetLocalDescriptionWithoutError(offer);
2638
2639 EXPECT_NE(session_->GetTransportProxy("audio")->impl(),
2640 session_->GetTransportProxy("video")->impl());
2641
2642 mediastream_signaling_.SendAudioVideoStream2();
2643
2644 // Remove BUNDLE from the answer.
2645 rtc::scoped_ptr<SessionDescriptionInterface> answer(
2646 CreateRemoteAnswer(session_->local_description()));
2647 cricket::SessionDescription* answer_copy = answer->description()->Copy();
2648 answer_copy->RemoveGroupByName(cricket::GROUP_TYPE_BUNDLE);
2649 JsepSessionDescription* modified_answer =
2650 new JsepSessionDescription(JsepSessionDescription::kAnswer);
2651 modified_answer->Initialize(answer_copy, "1", "1");
2652 SetRemoteDescriptionWithoutError(modified_answer); //
2653
2654 EXPECT_NE(session_->GetTransportProxy("audio")->impl(),
2655 session_->GetTransportProxy("video")->impl());
2656}
2657
2658// kBundlePolicyMaxBundle policy with BUNDLE in the answer.
2659TEST_F(WebRtcSessionTest, TestMaxBundleBundleInAnswer) {
2660 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxBundle);
2661 mediastream_signaling_.SendAudioVideoStream1();
2662
2663 PeerConnectionInterface::RTCOfferAnswerOptions options;
2664 options.use_rtp_mux = true;
2665
2666 SessionDescriptionInterface* offer = CreateOffer(options);
2667 SetLocalDescriptionWithoutError(offer);
2668
2669 EXPECT_EQ(session_->GetTransportProxy("audio")->impl(),
2670 session_->GetTransportProxy("video")->impl());
2671
2672 mediastream_signaling_.SendAudioVideoStream2();
2673 SessionDescriptionInterface* answer =
2674 CreateRemoteAnswer(session_->local_description());
2675 SetRemoteDescriptionWithoutError(answer);
2676
2677 EXPECT_EQ(session_->GetTransportProxy("audio")->impl(),
2678 session_->GetTransportProxy("video")->impl());
2679}
2680
2681// kBundlePolicyMaxBundle policy but no BUNDLE in the answer.
2682TEST_F(WebRtcSessionTest, TestMaxBundleNoBundleInAnswer) {
2683 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxBundle);
2684 mediastream_signaling_.SendAudioVideoStream1();
Peter Thatcher4eddf182015-04-30 10:55:59 -07002685
Donald Curtis0e209b02015-03-24 09:29:54 -07002686 PeerConnectionInterface::RTCOfferAnswerOptions options;
2687 options.use_rtp_mux = true;
2688
2689 SessionDescriptionInterface* offer = CreateOffer(options);
2690 SetLocalDescriptionWithoutError(offer);
2691
2692 EXPECT_EQ(session_->GetTransportProxy("audio")->impl(),
2693 session_->GetTransportProxy("video")->impl());
2694
2695 mediastream_signaling_.SendAudioVideoStream2();
2696
2697 // Remove BUNDLE from the answer.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002698 rtc::scoped_ptr<SessionDescriptionInterface> answer(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002699 CreateRemoteAnswer(session_->local_description()));
2700 cricket::SessionDescription* answer_copy = answer->description()->Copy();
2701 answer_copy->RemoveGroupByName(cricket::GROUP_TYPE_BUNDLE);
2702 JsepSessionDescription* modified_answer =
2703 new JsepSessionDescription(JsepSessionDescription::kAnswer);
2704 modified_answer->Initialize(answer_copy, "1", "1");
2705 SetRemoteDescriptionWithoutError(modified_answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002706
Donald Curtis0e209b02015-03-24 09:29:54 -07002707 EXPECT_EQ(session_->GetTransportProxy("audio")->impl(),
2708 session_->GetTransportProxy("video")->impl());
2709}
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002710
Peter Thatcher4eddf182015-04-30 10:55:59 -07002711// kBundlePolicyMaxCompat bundle policy and answer contains BUNDLE.
Donald Curtis0e209b02015-03-24 09:29:54 -07002712TEST_F(WebRtcSessionTest, TestMaxCompatBundleInAnswer) {
2713 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxCompat);
2714 mediastream_signaling_.SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002715
Donald Curtis0e209b02015-03-24 09:29:54 -07002716 PeerConnectionInterface::RTCOfferAnswerOptions options;
2717 options.use_rtp_mux = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002718
Donald Curtis0e209b02015-03-24 09:29:54 -07002719 SessionDescriptionInterface* offer = CreateOffer(options);
2720 SetLocalDescriptionWithoutError(offer);
2721
2722 EXPECT_NE(session_->GetTransportProxy("audio")->impl(),
2723 session_->GetTransportProxy("video")->impl());
2724
2725 mediastream_signaling_.SendAudioVideoStream2();
2726 SessionDescriptionInterface* answer =
2727 CreateRemoteAnswer(session_->local_description());
2728 SetRemoteDescriptionWithoutError(answer);
2729
2730 // This should lead to an audio-only call but isn't implemented
2731 // correctly yet.
2732 EXPECT_EQ(session_->GetTransportProxy("audio")->impl(),
2733 session_->GetTransportProxy("video")->impl());
2734}
2735
2736// kBundlePolicyMaxCompat bundle policy but no BUNDLE in the answer.
2737TEST_F(WebRtcSessionTest, TestMaxCompatNoBundleInAnswer) {
2738 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxCompat);
2739 mediastream_signaling_.SendAudioVideoStream1();
2740 PeerConnectionInterface::RTCOfferAnswerOptions options;
2741 options.use_rtp_mux = true;
2742
2743 SessionDescriptionInterface* offer = CreateOffer(options);
2744 SetLocalDescriptionWithoutError(offer);
2745
2746 EXPECT_NE(session_->GetTransportProxy("audio")->impl(),
2747 session_->GetTransportProxy("video")->impl());
2748
2749 mediastream_signaling_.SendAudioVideoStream2();
2750
2751 // Remove BUNDLE from the answer.
2752 rtc::scoped_ptr<SessionDescriptionInterface> answer(
2753 CreateRemoteAnswer(session_->local_description()));
2754 cricket::SessionDescription* answer_copy = answer->description()->Copy();
2755 answer_copy->RemoveGroupByName(cricket::GROUP_TYPE_BUNDLE);
2756 JsepSessionDescription* modified_answer =
2757 new JsepSessionDescription(JsepSessionDescription::kAnswer);
2758 modified_answer->Initialize(answer_copy, "1", "1");
2759 SetRemoteDescriptionWithoutError(modified_answer); //
2760
2761 EXPECT_NE(session_->GetTransportProxy("audio")->impl(),
2762 session_->GetTransportProxy("video")->impl());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002763}
2764
Peter Thatcher4eddf182015-04-30 10:55:59 -07002765// kBundlePolicyMaxbundle and then we call SetRemoteDescription first.
2766TEST_F(WebRtcSessionTest, TestMaxBundleWithSetRemoteDescriptionFirst) {
2767 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxBundle);
2768 mediastream_signaling_.SendAudioVideoStream1();
2769
2770 PeerConnectionInterface::RTCOfferAnswerOptions options;
2771 options.use_rtp_mux = true;
2772
2773 SessionDescriptionInterface* offer = CreateOffer(options);
2774 SetRemoteDescriptionWithoutError(offer);
2775
2776 EXPECT_EQ(session_->GetTransportProxy("audio")->impl(),
2777 session_->GetTransportProxy("video")->impl());
2778}
2779
Peter Thatcheraf55ccc2015-05-21 07:48:41 -07002780TEST_F(WebRtcSessionTest, TestRequireRtcpMux) {
2781 InitWithRtcpMuxPolicy(PeerConnectionInterface::kRtcpMuxPolicyRequire);
2782 mediastream_signaling_.SendAudioVideoStream1();
2783
2784 PeerConnectionInterface::RTCOfferAnswerOptions options;
2785 SessionDescriptionInterface* offer = CreateOffer(options);
2786 SetLocalDescriptionWithoutError(offer);
2787
2788 EXPECT_FALSE(session_->GetTransportProxy("audio")->impl()->HasChannel(2));
2789 EXPECT_FALSE(session_->GetTransportProxy("video")->impl()->HasChannel(2));
2790
2791 mediastream_signaling_.SendAudioVideoStream2();
2792 SessionDescriptionInterface* answer =
2793 CreateRemoteAnswer(session_->local_description());
2794 SetRemoteDescriptionWithoutError(answer);
2795
2796 EXPECT_FALSE(session_->GetTransportProxy("audio")->impl()->HasChannel(2));
2797 EXPECT_FALSE(session_->GetTransportProxy("video")->impl()->HasChannel(2));
2798}
2799
2800TEST_F(WebRtcSessionTest, TestNegotiateRtcpMux) {
2801 InitWithRtcpMuxPolicy(PeerConnectionInterface::kRtcpMuxPolicyNegotiate);
2802 mediastream_signaling_.SendAudioVideoStream1();
2803
2804 PeerConnectionInterface::RTCOfferAnswerOptions options;
2805 SessionDescriptionInterface* offer = CreateOffer(options);
2806 SetLocalDescriptionWithoutError(offer);
2807
2808 EXPECT_TRUE(session_->GetTransportProxy("audio")->impl()->HasChannel(2));
2809 EXPECT_TRUE(session_->GetTransportProxy("video")->impl()->HasChannel(2));
2810
2811 mediastream_signaling_.SendAudioVideoStream2();
2812 SessionDescriptionInterface* answer =
2813 CreateRemoteAnswer(session_->local_description());
2814 SetRemoteDescriptionWithoutError(answer);
2815
2816 EXPECT_FALSE(session_->GetTransportProxy("audio")->impl()->HasChannel(2));
2817 EXPECT_FALSE(session_->GetTransportProxy("video")->impl()->HasChannel(2));
2818}
2819
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002820// This test verifies that SetLocalDescription and SetRemoteDescription fails
2821// if BUNDLE is enabled but rtcp-mux is disabled in m-lines.
2822TEST_F(WebRtcSessionTest, TestDisabledRtcpMuxWithBundleEnabled) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002823 Init();
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002824 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002825
2826 PeerConnectionInterface::RTCOfferAnswerOptions options;
2827 options.use_rtp_mux = true;
2828
2829 SessionDescriptionInterface* offer = CreateOffer(options);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002830 std::string offer_str;
2831 offer->ToString(&offer_str);
2832 // Disable rtcp-mux
2833 const std::string rtcp_mux = "rtcp-mux";
2834 const std::string xrtcp_mux = "xrtcp-mux";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002835 rtc::replace_substrs(rtcp_mux.c_str(), rtcp_mux.length(),
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002836 xrtcp_mux.c_str(), xrtcp_mux.length(),
2837 &offer_str);
2838 JsepSessionDescription *local_offer =
2839 new JsepSessionDescription(JsepSessionDescription::kOffer);
2840 EXPECT_TRUE((local_offer)->Initialize(offer_str, NULL));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00002841 SetLocalDescriptionOfferExpectError(kBundleWithoutRtcpMux, local_offer);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002842 JsepSessionDescription *remote_offer =
2843 new JsepSessionDescription(JsepSessionDescription::kOffer);
2844 EXPECT_TRUE((remote_offer)->Initialize(offer_str, NULL));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00002845 SetRemoteDescriptionOfferExpectError(kBundleWithoutRtcpMux, remote_offer);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002846 // Trying unmodified SDP.
2847 SetLocalDescriptionWithoutError(offer);
2848}
2849
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002850TEST_F(WebRtcSessionTest, SetAudioPlayout) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002851 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002852 mediastream_signaling_.SendAudioVideoStream1();
2853 CreateAndSetRemoteOfferAndLocalAnswer();
2854 cricket::FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0);
2855 ASSERT_TRUE(channel != NULL);
2856 ASSERT_EQ(1u, channel->recv_streams().size());
2857 uint32 receive_ssrc = channel->recv_streams()[0].first_ssrc();
2858 double left_vol, right_vol;
2859 EXPECT_TRUE(channel->GetOutputScaling(receive_ssrc, &left_vol, &right_vol));
2860 EXPECT_EQ(1, left_vol);
2861 EXPECT_EQ(1, right_vol);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002862 rtc::scoped_ptr<FakeAudioRenderer> renderer(new FakeAudioRenderer());
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002863 session_->SetAudioPlayout(receive_ssrc, false, renderer.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002864 EXPECT_TRUE(channel->GetOutputScaling(receive_ssrc, &left_vol, &right_vol));
2865 EXPECT_EQ(0, left_vol);
2866 EXPECT_EQ(0, right_vol);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002867 EXPECT_EQ(0, renderer->channel_id());
2868 session_->SetAudioPlayout(receive_ssrc, true, NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002869 EXPECT_TRUE(channel->GetOutputScaling(receive_ssrc, &left_vol, &right_vol));
2870 EXPECT_EQ(1, left_vol);
2871 EXPECT_EQ(1, right_vol);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002872 EXPECT_EQ(-1, renderer->channel_id());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002873}
2874
2875TEST_F(WebRtcSessionTest, SetAudioSend) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002876 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002877 mediastream_signaling_.SendAudioVideoStream1();
2878 CreateAndSetRemoteOfferAndLocalAnswer();
2879 cricket::FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0);
2880 ASSERT_TRUE(channel != NULL);
2881 ASSERT_EQ(1u, channel->send_streams().size());
2882 uint32 send_ssrc = channel->send_streams()[0].first_ssrc();
2883 EXPECT_FALSE(channel->IsStreamMuted(send_ssrc));
2884
2885 cricket::AudioOptions options;
2886 options.echo_cancellation.Set(true);
2887
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002888 rtc::scoped_ptr<FakeAudioRenderer> renderer(new FakeAudioRenderer());
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002889 session_->SetAudioSend(send_ssrc, false, options, renderer.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002890 EXPECT_TRUE(channel->IsStreamMuted(send_ssrc));
2891 EXPECT_FALSE(channel->options().echo_cancellation.IsSet());
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002892 EXPECT_EQ(0, renderer->channel_id());
henrike@webrtc.orga7b98182014-02-21 15:51:43 +00002893 EXPECT_TRUE(renderer->sink() != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002894
henrike@webrtc.orga7b98182014-02-21 15:51:43 +00002895 // This will trigger SetSink(NULL) to the |renderer|.
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002896 session_->SetAudioSend(send_ssrc, true, options, NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002897 EXPECT_FALSE(channel->IsStreamMuted(send_ssrc));
2898 bool value;
2899 EXPECT_TRUE(channel->options().echo_cancellation.Get(&value));
2900 EXPECT_TRUE(value);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00002901 EXPECT_EQ(-1, renderer->channel_id());
henrike@webrtc.orga7b98182014-02-21 15:51:43 +00002902 EXPECT_TRUE(renderer->sink() == NULL);
2903}
2904
2905TEST_F(WebRtcSessionTest, AudioRendererForLocalStream) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002906 Init();
henrike@webrtc.orga7b98182014-02-21 15:51:43 +00002907 mediastream_signaling_.SendAudioVideoStream1();
2908 CreateAndSetRemoteOfferAndLocalAnswer();
2909 cricket::FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0);
2910 ASSERT_TRUE(channel != NULL);
2911 ASSERT_EQ(1u, channel->send_streams().size());
2912 uint32 send_ssrc = channel->send_streams()[0].first_ssrc();
2913
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002914 rtc::scoped_ptr<FakeAudioRenderer> renderer(new FakeAudioRenderer());
henrike@webrtc.orga7b98182014-02-21 15:51:43 +00002915 cricket::AudioOptions options;
2916 session_->SetAudioSend(send_ssrc, true, options, renderer.get());
2917 EXPECT_TRUE(renderer->sink() != NULL);
2918
2919 // Delete the |renderer| and it will trigger OnClose() to the sink, and this
2920 // will invalidate the |renderer_| pointer in the sink and prevent getting a
2921 // SetSink(NULL) callback afterwards.
2922 renderer.reset();
2923
2924 // This will trigger SetSink(NULL) if no OnClose() callback.
2925 session_->SetAudioSend(send_ssrc, true, options, NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002926}
2927
2928TEST_F(WebRtcSessionTest, SetVideoPlayout) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002929 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002930 mediastream_signaling_.SendAudioVideoStream1();
2931 CreateAndSetRemoteOfferAndLocalAnswer();
2932 cricket::FakeVideoMediaChannel* channel = media_engine_->GetVideoChannel(0);
2933 ASSERT_TRUE(channel != NULL);
2934 ASSERT_LT(0u, channel->renderers().size());
2935 EXPECT_TRUE(channel->renderers().begin()->second == NULL);
2936 ASSERT_EQ(1u, channel->recv_streams().size());
2937 uint32 receive_ssrc = channel->recv_streams()[0].first_ssrc();
2938 cricket::FakeVideoRenderer renderer;
2939 session_->SetVideoPlayout(receive_ssrc, true, &renderer);
2940 EXPECT_TRUE(channel->renderers().begin()->second == &renderer);
2941 session_->SetVideoPlayout(receive_ssrc, false, &renderer);
2942 EXPECT_TRUE(channel->renderers().begin()->second == NULL);
2943}
2944
2945TEST_F(WebRtcSessionTest, SetVideoSend) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002946 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002947 mediastream_signaling_.SendAudioVideoStream1();
2948 CreateAndSetRemoteOfferAndLocalAnswer();
2949 cricket::FakeVideoMediaChannel* channel = media_engine_->GetVideoChannel(0);
2950 ASSERT_TRUE(channel != NULL);
2951 ASSERT_EQ(1u, channel->send_streams().size());
2952 uint32 send_ssrc = channel->send_streams()[0].first_ssrc();
2953 EXPECT_FALSE(channel->IsStreamMuted(send_ssrc));
2954 cricket::VideoOptions* options = NULL;
2955 session_->SetVideoSend(send_ssrc, false, options);
2956 EXPECT_TRUE(channel->IsStreamMuted(send_ssrc));
2957 session_->SetVideoSend(send_ssrc, true, options);
2958 EXPECT_FALSE(channel->IsStreamMuted(send_ssrc));
2959}
2960
2961TEST_F(WebRtcSessionTest, CanNotInsertDtmf) {
2962 TestCanInsertDtmf(false);
2963}
2964
2965TEST_F(WebRtcSessionTest, CanInsertDtmf) {
2966 TestCanInsertDtmf(true);
2967}
2968
2969TEST_F(WebRtcSessionTest, InsertDtmf) {
2970 // Setup
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002971 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002972 mediastream_signaling_.SendAudioVideoStream1();
2973 CreateAndSetRemoteOfferAndLocalAnswer();
2974 FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0);
2975 EXPECT_EQ(0U, channel->dtmf_info_queue().size());
2976
2977 // Insert DTMF
2978 const int expected_flags = DF_SEND;
2979 const int expected_duration = 90;
2980 session_->InsertDtmf(kAudioTrack1, 0, expected_duration);
2981 session_->InsertDtmf(kAudioTrack1, 1, expected_duration);
2982 session_->InsertDtmf(kAudioTrack1, 2, expected_duration);
2983
2984 // Verify
2985 ASSERT_EQ(3U, channel->dtmf_info_queue().size());
2986 const uint32 send_ssrc = channel->send_streams()[0].first_ssrc();
2987 EXPECT_TRUE(CompareDtmfInfo(channel->dtmf_info_queue()[0], send_ssrc, 0,
2988 expected_duration, expected_flags));
2989 EXPECT_TRUE(CompareDtmfInfo(channel->dtmf_info_queue()[1], send_ssrc, 1,
2990 expected_duration, expected_flags));
2991 EXPECT_TRUE(CompareDtmfInfo(channel->dtmf_info_queue()[2], send_ssrc, 2,
2992 expected_duration, expected_flags));
2993}
2994
2995// This test verifies the |initiator| flag when session initiates the call.
2996TEST_F(WebRtcSessionTest, TestInitiatorFlagAsOriginator) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002997 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002998 EXPECT_FALSE(session_->initiator());
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002999 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003000 SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
3001 SetLocalDescriptionWithoutError(offer);
3002 EXPECT_TRUE(session_->initiator());
3003 SetRemoteDescriptionWithoutError(answer);
3004 EXPECT_TRUE(session_->initiator());
3005}
3006
3007// This test verifies the |initiator| flag when session receives the call.
3008TEST_F(WebRtcSessionTest, TestInitiatorFlagAsReceiver) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003009 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003010 EXPECT_FALSE(session_->initiator());
3011 SessionDescriptionInterface* offer = CreateRemoteOffer();
3012 SetRemoteDescriptionWithoutError(offer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003013 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003014
3015 EXPECT_FALSE(session_->initiator());
3016 SetLocalDescriptionWithoutError(answer);
3017 EXPECT_FALSE(session_->initiator());
3018}
3019
3020// This test verifies the ice protocol type at initiator of the call
3021// if |a=ice-options:google-ice| is present in answer.
3022TEST_F(WebRtcSessionTest, TestInitiatorGIceInAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003023 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003024 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003025 SessionDescriptionInterface* offer = CreateOffer();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003026 rtc::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00003027 CreateRemoteAnswer(offer));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003028 SetLocalDescriptionWithoutError(offer);
3029 std::string sdp;
3030 EXPECT_TRUE(answer->ToString(&sdp));
3031 // Adding ice-options to the session level.
3032 InjectAfter("t=0 0\r\n",
3033 "a=ice-options:google-ice\r\n",
3034 &sdp);
3035 SessionDescriptionInterface* answer_with_gice =
3036 CreateSessionDescription(JsepSessionDescription::kAnswer, sdp, NULL);
jlmiller@webrtc.org804eb462015-02-20 02:20:03 +00003037 // Default offer is ICEPROTO_RFC5245, so we expect responder with
3038 // only gice to fail.
3039 SetRemoteDescriptionAnswerExpectError(kPushDownTDFailed, answer_with_gice);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003040}
3041
3042// This test verifies the ice protocol type at initiator of the call
3043// if ICE RFC5245 is supported in answer.
3044TEST_F(WebRtcSessionTest, TestInitiatorIceInAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003045 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003046 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003047 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003048 SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
3049 SetLocalDescriptionWithoutError(offer);
3050
3051 SetRemoteDescriptionWithoutError(answer);
3052 VerifyTransportType("audio", cricket::ICEPROTO_RFC5245);
3053 VerifyTransportType("video", cricket::ICEPROTO_RFC5245);
3054}
3055
3056// This test verifies the ice protocol type at receiver side of the call if
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003057// receiver decides to use ice RFC 5245.
3058TEST_F(WebRtcSessionTest, TestReceiverIceInOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003059 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003060 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003061 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003062 SetRemoteDescriptionWithoutError(offer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003063 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003064 SetLocalDescriptionWithoutError(answer);
3065 VerifyTransportType("audio", cricket::ICEPROTO_RFC5245);
3066 VerifyTransportType("video", cricket::ICEPROTO_RFC5245);
3067}
3068
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003069// Verifing local offer and remote answer have matching m-lines as per RFC 3264.
3070TEST_F(WebRtcSessionTest, TestIncorrectMLinesInRemoteAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003071 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003072 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003073 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003074 SetLocalDescriptionWithoutError(offer);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003075 rtc::scoped_ptr<SessionDescriptionInterface> answer(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003076 CreateRemoteAnswer(session_->local_description()));
3077
3078 cricket::SessionDescription* answer_copy = answer->description()->Copy();
3079 answer_copy->RemoveContentByName("video");
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00003080 JsepSessionDescription* modified_answer =
3081 new JsepSessionDescription(JsepSessionDescription::kAnswer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003082
3083 EXPECT_TRUE(modified_answer->Initialize(answer_copy,
3084 answer->session_id(),
3085 answer->session_version()));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003086 SetRemoteDescriptionAnswerExpectError(kMlineMismatch, modified_answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003087
wu@webrtc.org4e393072014-04-07 17:04:35 +00003088 // Different content names.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003089 std::string sdp;
3090 EXPECT_TRUE(answer->ToString(&sdp));
3091 const std::string kAudioMid = "a=mid:audio";
3092 const std::string kAudioMidReplaceStr = "a=mid:audio_content_name";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003093 rtc::replace_substrs(kAudioMid.c_str(), kAudioMid.length(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003094 kAudioMidReplaceStr.c_str(),
3095 kAudioMidReplaceStr.length(),
3096 &sdp);
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00003097 SessionDescriptionInterface* modified_answer1 =
3098 CreateSessionDescription(JsepSessionDescription::kAnswer, sdp, NULL);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003099 SetRemoteDescriptionAnswerExpectError(kMlineMismatch, modified_answer1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003100
wu@webrtc.org4e393072014-04-07 17:04:35 +00003101 // Different media types.
3102 EXPECT_TRUE(answer->ToString(&sdp));
3103 const std::string kAudioMline = "m=audio";
3104 const std::string kAudioMlineReplaceStr = "m=video";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003105 rtc::replace_substrs(kAudioMline.c_str(), kAudioMline.length(),
wu@webrtc.org4e393072014-04-07 17:04:35 +00003106 kAudioMlineReplaceStr.c_str(),
3107 kAudioMlineReplaceStr.length(),
3108 &sdp);
3109 SessionDescriptionInterface* modified_answer2 =
3110 CreateSessionDescription(JsepSessionDescription::kAnswer, sdp, NULL);
3111 SetRemoteDescriptionAnswerExpectError(kMlineMismatch, modified_answer2);
3112
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003113 SetRemoteDescriptionWithoutError(answer.release());
3114}
3115
3116// Verifying remote offer and local answer have matching m-lines as per
3117// RFC 3264.
3118TEST_F(WebRtcSessionTest, TestIncorrectMLinesInLocalAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003119 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003120 mediastream_signaling_.SendAudioVideoStream1();
3121 SessionDescriptionInterface* offer = CreateRemoteOffer();
3122 SetRemoteDescriptionWithoutError(offer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003123 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003124
3125 cricket::SessionDescription* answer_copy = answer->description()->Copy();
3126 answer_copy->RemoveContentByName("video");
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00003127 JsepSessionDescription* modified_answer =
3128 new JsepSessionDescription(JsepSessionDescription::kAnswer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003129
3130 EXPECT_TRUE(modified_answer->Initialize(answer_copy,
3131 answer->session_id(),
3132 answer->session_version()));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003133 SetLocalDescriptionAnswerExpectError(kMlineMismatch, modified_answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003134 SetLocalDescriptionWithoutError(answer);
3135}
3136
3137// This test verifies that WebRtcSession does not start candidate allocation
3138// before SetLocalDescription is called.
3139TEST_F(WebRtcSessionTest, TestIceStartAfterSetLocalDescriptionOnly) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003140 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003141 mediastream_signaling_.SendAudioVideoStream1();
3142 SessionDescriptionInterface* offer = CreateRemoteOffer();
3143 cricket::Candidate candidate;
3144 candidate.set_component(1);
3145 JsepIceCandidate ice_candidate(kMediaContentName0, kMediaContentIndex0,
3146 candidate);
3147 EXPECT_TRUE(offer->AddCandidate(&ice_candidate));
3148 cricket::Candidate candidate1;
3149 candidate1.set_component(1);
3150 JsepIceCandidate ice_candidate1(kMediaContentName1, kMediaContentIndex1,
3151 candidate1);
3152 EXPECT_TRUE(offer->AddCandidate(&ice_candidate1));
3153 SetRemoteDescriptionWithoutError(offer);
3154 ASSERT_TRUE(session_->GetTransportProxy("audio") != NULL);
3155 ASSERT_TRUE(session_->GetTransportProxy("video") != NULL);
3156
3157 // Pump for 1 second and verify that no candidates are generated.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003158 rtc::Thread::Current()->ProcessMessages(1000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003159 EXPECT_TRUE(observer_.mline_0_candidates_.empty());
3160 EXPECT_TRUE(observer_.mline_1_candidates_.empty());
3161
wu@webrtc.org91053e72013-08-10 07:18:04 +00003162 SessionDescriptionInterface* answer = CreateAnswer(NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003163 SetLocalDescriptionWithoutError(answer);
3164 EXPECT_TRUE(session_->GetTransportProxy("audio")->negotiated());
3165 EXPECT_TRUE(session_->GetTransportProxy("video")->negotiated());
3166 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
3167}
3168
3169// This test verifies that crypto parameter is updated in local session
3170// description as per security policy set in MediaSessionDescriptionFactory.
3171TEST_F(WebRtcSessionTest, TestCryptoAfterSetLocalDescription) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003172 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003173 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003174 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003175
3176 // Making sure SetLocalDescription correctly sets crypto value in
3177 // SessionDescription object after de-serialization of sdp string. The value
3178 // will be set as per MediaSessionDescriptionFactory.
3179 std::string offer_str;
3180 offer->ToString(&offer_str);
3181 SessionDescriptionInterface* jsep_offer_str =
3182 CreateSessionDescription(JsepSessionDescription::kOffer, offer_str, NULL);
3183 SetLocalDescriptionWithoutError(jsep_offer_str);
3184 EXPECT_TRUE(session_->voice_channel()->secure_required());
3185 EXPECT_TRUE(session_->video_channel()->secure_required());
3186}
3187
3188// This test verifies the crypto parameter when security is disabled.
3189TEST_F(WebRtcSessionTest, TestCryptoAfterSetLocalDescriptionWithDisabled) {
wu@webrtc.org97077a32013-10-25 21:18:33 +00003190 options_.disable_encryption = true;
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003191 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003192 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003193 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003194
3195 // Making sure SetLocalDescription correctly sets crypto value in
3196 // SessionDescription object after de-serialization of sdp string. The value
3197 // will be set as per MediaSessionDescriptionFactory.
3198 std::string offer_str;
3199 offer->ToString(&offer_str);
3200 SessionDescriptionInterface *jsep_offer_str =
3201 CreateSessionDescription(JsepSessionDescription::kOffer, offer_str, NULL);
3202 SetLocalDescriptionWithoutError(jsep_offer_str);
3203 EXPECT_FALSE(session_->voice_channel()->secure_required());
3204 EXPECT_FALSE(session_->video_channel()->secure_required());
3205}
3206
3207// This test verifies that an answer contains new ufrag and password if an offer
3208// with new ufrag and password is received.
3209TEST_F(WebRtcSessionTest, TestCreateAnswerWithNewUfragAndPassword) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003210 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003211 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00003212 options.recv_video = true;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003213 rtc::scoped_ptr<JsepSessionDescription> offer(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003214 CreateRemoteOffer(options));
3215 SetRemoteDescriptionWithoutError(offer.release());
3216
3217 mediastream_signaling_.SendAudioVideoStream1();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003218 rtc::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00003219 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003220 SetLocalDescriptionWithoutError(answer.release());
3221
3222 // Receive an offer with new ufrag and password.
3223 options.transport_options.ice_restart = true;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003224 rtc::scoped_ptr<JsepSessionDescription> updated_offer1(
wu@webrtc.org91053e72013-08-10 07:18:04 +00003225 CreateRemoteOffer(options, session_->remote_description()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003226 SetRemoteDescriptionWithoutError(updated_offer1.release());
3227
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003228 rtc::scoped_ptr<SessionDescriptionInterface> updated_answer1(
wu@webrtc.org91053e72013-08-10 07:18:04 +00003229 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003230
3231 CompareIceUfragAndPassword(updated_answer1->description(),
3232 session_->local_description()->description(),
3233 false);
3234
3235 SetLocalDescriptionWithoutError(updated_answer1.release());
wu@webrtc.org91053e72013-08-10 07:18:04 +00003236}
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003237
wu@webrtc.org91053e72013-08-10 07:18:04 +00003238// This test verifies that an answer contains old ufrag and password if an offer
3239// with old ufrag and password is received.
3240TEST_F(WebRtcSessionTest, TestCreateAnswerWithOldUfragAndPassword) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003241 Init();
wu@webrtc.org91053e72013-08-10 07:18:04 +00003242 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00003243 options.recv_video = true;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003244 rtc::scoped_ptr<JsepSessionDescription> offer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00003245 CreateRemoteOffer(options));
3246 SetRemoteDescriptionWithoutError(offer.release());
3247
3248 mediastream_signaling_.SendAudioVideoStream1();
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003249 rtc::scoped_ptr<SessionDescriptionInterface> answer(
wu@webrtc.org91053e72013-08-10 07:18:04 +00003250 CreateAnswer(NULL));
3251 SetLocalDescriptionWithoutError(answer.release());
3252
3253 // Receive an offer without changed ufrag or password.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003254 options.transport_options.ice_restart = false;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003255 rtc::scoped_ptr<JsepSessionDescription> updated_offer2(
wu@webrtc.org91053e72013-08-10 07:18:04 +00003256 CreateRemoteOffer(options, session_->remote_description()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003257 SetRemoteDescriptionWithoutError(updated_offer2.release());
3258
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003259 rtc::scoped_ptr<SessionDescriptionInterface> updated_answer2(
wu@webrtc.org91053e72013-08-10 07:18:04 +00003260 CreateAnswer(NULL));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003261
3262 CompareIceUfragAndPassword(updated_answer2->description(),
3263 session_->local_description()->description(),
3264 true);
3265
3266 SetLocalDescriptionWithoutError(updated_answer2.release());
3267}
3268
3269TEST_F(WebRtcSessionTest, TestSessionContentError) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003270 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003271 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003272 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003273 const std::string session_id_orig = offer->session_id();
3274 const std::string session_version_orig = offer->session_version();
3275 SetLocalDescriptionWithoutError(offer);
3276
3277 video_channel_ = media_engine_->GetVideoChannel(0);
3278 video_channel_->set_fail_set_send_codecs(true);
3279
3280 mediastream_signaling_.SendAudioVideoStream2();
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00003281 SessionDescriptionInterface* answer =
3282 CreateRemoteAnswer(session_->local_description());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003283 SetRemoteDescriptionAnswerExpectError("ERROR_CONTENT", answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003284}
3285
3286// Runs the loopback call test with BUNDLE and STUN disabled.
3287TEST_F(WebRtcSessionTest, TestIceStatesBasic) {
3288 // Lets try with only UDP ports.
buildbot@webrtc.org41451d42014-05-03 05:39:45 +00003289 allocator_->set_flags(cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00003290 cricket::PORTALLOCATOR_DISABLE_TCP |
3291 cricket::PORTALLOCATOR_DISABLE_STUN |
3292 cricket::PORTALLOCATOR_DISABLE_RELAY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003293 TestLoopbackCall();
3294}
3295
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00003296TEST_F(WebRtcSessionTest, TestIceStatesBasicIPv6) {
3297 allocator_->set_flags(cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
3298 cricket::PORTALLOCATOR_DISABLE_TCP |
3299 cricket::PORTALLOCATOR_DISABLE_STUN |
3300 cricket::PORTALLOCATOR_ENABLE_IPV6 |
3301 cricket::PORTALLOCATOR_DISABLE_RELAY);
3302
3303 // best connection is IPv6 since it has higher network preference.
3304 LoopbackNetworkConfiguration config;
3305 config.test_ipv6_network_ = true;
3306 config.best_connection_after_initial_ice_converged_ =
3307 LoopbackNetworkConfiguration::ExpectedBestConnection(0, 1);
3308
3309 TestLoopbackCall(config);
3310}
3311
mallinath@webrtc.orgd3dc4242014-03-01 00:05:52 +00003312// Runs the loopback call test with BUNDLE and STUN enabled.
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00003313TEST_F(WebRtcSessionTest, TestIceStatesBundle) {
buildbot@webrtc.org41451d42014-05-03 05:39:45 +00003314 allocator_->set_flags(cricket::PORTALLOCATOR_ENABLE_SHARED_UFRAG |
mallinath@webrtc.orgd3dc4242014-03-01 00:05:52 +00003315 cricket::PORTALLOCATOR_DISABLE_TCP |
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00003316 cricket::PORTALLOCATOR_DISABLE_RELAY);
3317 TestLoopbackCall();
3318}
3319
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003320TEST_F(WebRtcSessionTest, SetSdpFailedOnSessionError) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003321 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003322 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00003323 options.recv_video = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003324
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003325 cricket::BaseSession::Error error_code = cricket::BaseSession::ERROR_CONTENT;
3326 std::string error_code_str = "ERROR_CONTENT";
3327 std::string error_desc = "Fake session error description.";
3328 session_->SetError(error_code, error_desc);
3329
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003330 SessionDescriptionInterface* offer = CreateRemoteOffer(options);
3331 SessionDescriptionInterface* answer =
3332 CreateRemoteAnswer(offer, options);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003333
3334 std::string action;
3335 std::ostringstream session_error_msg;
3336 session_error_msg << kSessionError << error_code_str << ". ";
3337 session_error_msg << kSessionErrorDesc << error_desc << ".";
3338 SetRemoteDescriptionExpectError(action, session_error_msg.str(), offer);
3339 SetLocalDescriptionExpectError(action, session_error_msg.str(), answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003340}
3341
3342TEST_F(WebRtcSessionTest, TestRtpDataChannel) {
3343 constraints_.reset(new FakeConstraints());
3344 constraints_->AddOptional(
3345 webrtc::MediaConstraintsInterface::kEnableRtpDataChannels, true);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003346 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003347
3348 SetLocalDescriptionWithDataChannel();
3349 EXPECT_EQ(cricket::DCT_RTP, data_engine_->last_channel_type());
3350}
3351
3352TEST_F(WebRtcSessionTest, TestRtpDataChannelConstraintTakesPrecedence) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003353 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003354
3355 constraints_.reset(new FakeConstraints());
3356 constraints_->AddOptional(
3357 webrtc::MediaConstraintsInterface::kEnableRtpDataChannels, true);
wu@webrtc.org97077a32013-10-25 21:18:33 +00003358 options_.disable_sctp_data_channels = false;
3359
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003360 InitWithDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003361
3362 SetLocalDescriptionWithDataChannel();
3363 EXPECT_EQ(cricket::DCT_RTP, data_engine_->last_channel_type());
3364}
3365
wu@webrtc.org967bfff2013-09-19 05:49:50 +00003366TEST_F(WebRtcSessionTest, TestCreateOfferWithSctpEnabledWithoutStreams) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003367 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
wu@webrtc.org967bfff2013-09-19 05:49:50 +00003368
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003369 InitWithDtls();
sergeyu@chromium.orga59696b2013-09-13 23:48:58 +00003370
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003371 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
sergeyu@chromium.orga59696b2013-09-13 23:48:58 +00003372 EXPECT_TRUE(offer->description()->GetContentByName("data") == NULL);
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00003373 EXPECT_TRUE(offer->description()->GetTransportInfoByName("data") == NULL);
3374}
3375
3376TEST_F(WebRtcSessionTest, TestCreateAnswerWithSctpInOfferAndNoStreams) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003377 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00003378 SetFactoryDtlsSrtp();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003379 InitWithDtls();
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00003380
3381 // Create remote offer with SCTP.
3382 cricket::MediaSessionOptions options;
3383 options.data_channel_type = cricket::DCT_SCTP;
3384 JsepSessionDescription* offer =
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003385 CreateRemoteOffer(options, cricket::SEC_DISABLED);
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00003386 SetRemoteDescriptionWithoutError(offer);
3387
3388 // Verifies the answer contains SCTP.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003389 rtc::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00003390 EXPECT_TRUE(answer != NULL);
3391 EXPECT_TRUE(answer->description()->GetContentByName("data") != NULL);
3392 EXPECT_TRUE(answer->description()->GetTransportInfoByName("data") != NULL);
sergeyu@chromium.orga59696b2013-09-13 23:48:58 +00003393}
3394
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003395TEST_F(WebRtcSessionTest, TestSctpDataChannelWithoutDtls) {
3396 constraints_.reset(new FakeConstraints());
3397 constraints_->AddOptional(
sergeyu@chromium.orga59696b2013-09-13 23:48:58 +00003398 webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, false);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003399 InitWithDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003400
3401 SetLocalDescriptionWithDataChannel();
3402 EXPECT_EQ(cricket::DCT_NONE, data_engine_->last_channel_type());
3403}
3404
3405TEST_F(WebRtcSessionTest, TestSctpDataChannelWithDtls) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003406 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003407
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003408 InitWithDtls();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003409
3410 SetLocalDescriptionWithDataChannel();
3411 EXPECT_EQ(cricket::DCT_SCTP, data_engine_->last_channel_type());
3412}
wu@webrtc.org91053e72013-08-10 07:18:04 +00003413
wu@webrtc.org97077a32013-10-25 21:18:33 +00003414TEST_F(WebRtcSessionTest, TestDisableSctpDataChannels) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003415 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
wu@webrtc.org97077a32013-10-25 21:18:33 +00003416 options_.disable_sctp_data_channels = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003417 InitWithDtls();
wu@webrtc.org97077a32013-10-25 21:18:33 +00003418
3419 SetLocalDescriptionWithDataChannel();
3420 EXPECT_EQ(cricket::DCT_NONE, data_engine_->last_channel_type());
3421}
3422
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00003423TEST_F(WebRtcSessionTest, TestSctpDataChannelSendPortParsing) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003424 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00003425 const int new_send_port = 9998;
3426 const int new_recv_port = 7775;
3427
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003428 InitWithDtls();
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00003429 SetFactoryDtlsSrtp();
3430
3431 // By default, don't actually add the codecs to desc_factory_; they don't
3432 // actually get serialized for SCTP in BuildMediaDescription(). Instead,
3433 // let the session description get parsed. That'll get the proper codecs
3434 // into the stream.
3435 cricket::MediaSessionOptions options;
3436 JsepSessionDescription* offer = CreateRemoteOfferWithSctpPort(
3437 "stream1", new_send_port, options);
3438
3439 // SetRemoteDescription will take the ownership of the offer.
3440 SetRemoteDescriptionWithoutError(offer);
3441
3442 SessionDescriptionInterface* answer = ChangeSDPSctpPort(
3443 new_recv_port, CreateAnswer(NULL));
3444 ASSERT_TRUE(answer != NULL);
3445
3446 // Now set the local description, which'll take ownership of the answer.
3447 SetLocalDescriptionWithoutError(answer);
3448
3449 // TEST PLAN: Set the port number to something new, set it in the SDP,
3450 // and pass it all the way down.
henrika@webrtc.orgaebb1ad2014-01-14 10:00:58 +00003451 webrtc::InternalDataChannelInit dci;
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00003452 dci.reliable = true;
3453 EXPECT_EQ(cricket::DCT_SCTP, data_engine_->last_channel_type());
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003454 rtc::scoped_refptr<webrtc::DataChannel> dc =
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00003455 session_->CreateDataChannel("datachannel", &dci);
3456
3457 cricket::FakeDataMediaChannel* ch = data_engine_->GetChannel(0);
3458 int portnum = -1;
3459 ASSERT_TRUE(ch != NULL);
3460 ASSERT_EQ(1UL, ch->send_codecs().size());
3461 EXPECT_EQ(cricket::kGoogleSctpDataCodecId, ch->send_codecs()[0].id);
3462 EXPECT_TRUE(!strcmp(cricket::kGoogleSctpDataCodecName,
3463 ch->send_codecs()[0].name.c_str()));
3464 EXPECT_TRUE(ch->send_codecs()[0].GetParam(cricket::kCodecParamPort,
3465 &portnum));
3466 EXPECT_EQ(new_send_port, portnum);
3467
3468 ASSERT_EQ(1UL, ch->recv_codecs().size());
3469 EXPECT_EQ(cricket::kGoogleSctpDataCodecId, ch->recv_codecs()[0].id);
3470 EXPECT_TRUE(!strcmp(cricket::kGoogleSctpDataCodecName,
3471 ch->recv_codecs()[0].name.c_str()));
3472 EXPECT_TRUE(ch->recv_codecs()[0].GetParam(cricket::kCodecParamPort,
3473 &portnum));
3474 EXPECT_EQ(new_recv_port, portnum);
3475}
3476
wu@webrtc.org91053e72013-08-10 07:18:04 +00003477// Verifies that CreateOffer succeeds when CreateOffer is called before async
3478// identity generation is finished.
3479TEST_F(WebRtcSessionTest, TestCreateOfferBeforeIdentityRequestReturnSuccess) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003480 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003481 InitWithDtls();
wu@webrtc.org91053e72013-08-10 07:18:04 +00003482
3483 EXPECT_TRUE(session_->waiting_for_identity());
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003484 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003485 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
3486
wu@webrtc.org91053e72013-08-10 07:18:04 +00003487 EXPECT_TRUE(offer != NULL);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003488 VerifyNoCryptoParams(offer->description(), true);
3489 VerifyFingerprintStatus(offer->description(), true);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003490}
3491
3492// Verifies that CreateAnswer succeeds when CreateOffer is called before async
3493// identity generation is finished.
3494TEST_F(WebRtcSessionTest, TestCreateAnswerBeforeIdentityRequestReturnSuccess) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003495 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003496 InitWithDtls();
3497 SetFactoryDtlsSrtp();
wu@webrtc.org91053e72013-08-10 07:18:04 +00003498
3499 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00003500 options.recv_video = true;
wu@webrtc.org91053e72013-08-10 07:18:04 +00003501 scoped_ptr<JsepSessionDescription> offer(
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003502 CreateRemoteOffer(options, cricket::SEC_DISABLED));
wu@webrtc.org91053e72013-08-10 07:18:04 +00003503 ASSERT_TRUE(offer.get() != NULL);
3504 SetRemoteDescriptionWithoutError(offer.release());
3505
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003506 rtc::scoped_ptr<SessionDescriptionInterface> answer(CreateAnswer(NULL));
wu@webrtc.org91053e72013-08-10 07:18:04 +00003507 EXPECT_TRUE(answer != NULL);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003508 VerifyNoCryptoParams(answer->description(), true);
3509 VerifyFingerprintStatus(answer->description(), true);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003510}
3511
3512// Verifies that CreateOffer succeeds when CreateOffer is called after async
3513// identity generation is finished.
3514TEST_F(WebRtcSessionTest, TestCreateOfferAfterIdentityRequestReturnSuccess) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003515 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003516 InitWithDtls();
wu@webrtc.org91053e72013-08-10 07:18:04 +00003517
3518 EXPECT_TRUE_WAIT(!session_->waiting_for_identity(), 1000);
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003519
3520 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
wu@webrtc.org91053e72013-08-10 07:18:04 +00003521 EXPECT_TRUE(offer != NULL);
3522}
3523
3524// Verifies that CreateOffer fails when CreateOffer is called after async
3525// identity generation fails.
3526TEST_F(WebRtcSessionTest, TestCreateOfferAfterIdentityRequestReturnFailure) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003527 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.org7666db72013-08-22 14:45:42 +00003528 InitWithDtls(true);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003529
3530 EXPECT_TRUE_WAIT(!session_->waiting_for_identity(), 1000);
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003531
3532 rtc::scoped_ptr<SessionDescriptionInterface> offer(CreateOffer());
wu@webrtc.org91053e72013-08-10 07:18:04 +00003533 EXPECT_TRUE(offer == NULL);
3534}
3535
3536// Verifies that CreateOffer succeeds when Multiple CreateOffer calls are made
3537// before async identity generation is finished.
3538TEST_F(WebRtcSessionTest,
3539 TestMultipleCreateOfferBeforeIdentityRequestReturnSuccess) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003540 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003541 VerifyMultipleAsyncCreateDescription(
3542 true, CreateSessionDescriptionRequest::kOffer);
3543}
3544
3545// Verifies that CreateOffer fails when Multiple CreateOffer calls are made
3546// before async identity generation fails.
3547TEST_F(WebRtcSessionTest,
3548 TestMultipleCreateOfferBeforeIdentityRequestReturnFailure) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003549 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003550 VerifyMultipleAsyncCreateDescription(
3551 false, CreateSessionDescriptionRequest::kOffer);
3552}
3553
3554// Verifies that CreateAnswer succeeds when Multiple CreateAnswer calls are made
3555// before async identity generation is finished.
3556TEST_F(WebRtcSessionTest,
3557 TestMultipleCreateAnswerBeforeIdentityRequestReturnSuccess) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003558 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003559 VerifyMultipleAsyncCreateDescription(
3560 true, CreateSessionDescriptionRequest::kAnswer);
3561}
3562
3563// Verifies that CreateAnswer fails when Multiple CreateAnswer calls are made
3564// before async identity generation fails.
3565TEST_F(WebRtcSessionTest,
3566 TestMultipleCreateAnswerBeforeIdentityRequestReturnFailure) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003567 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
wu@webrtc.org91053e72013-08-10 07:18:04 +00003568 VerifyMultipleAsyncCreateDescription(
3569 false, CreateSessionDescriptionRequest::kAnswer);
3570}
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00003571
3572// Verifies that setRemoteDescription fails when DTLS is disabled and the remote
3573// offer has no SDES crypto but only DTLS fingerprint.
3574TEST_F(WebRtcSessionTest, TestSetRemoteOfferFailIfDtlsDisabledAndNoCrypto) {
3575 // Init without DTLS.
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003576 Init();
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00003577 // Create a remote offer with secured transport disabled.
3578 cricket::MediaSessionOptions options;
3579 JsepSessionDescription* offer(CreateRemoteOffer(
3580 options, cricket::SEC_DISABLED));
3581 // Adds a DTLS fingerprint to the remote offer.
3582 cricket::SessionDescription* sdp = offer->description();
3583 TransportInfo* audio = sdp->GetTransportInfoByName("audio");
3584 ASSERT_TRUE(audio != NULL);
3585 ASSERT_TRUE(audio->description.identity_fingerprint.get() == NULL);
3586 audio->description.identity_fingerprint.reset(
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003587 rtc::SSLFingerprint::CreateFromRfc4572(
3588 rtc::DIGEST_SHA_256, kFakeDtlsFingerprint));
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003589 SetRemoteDescriptionOfferExpectError(kSdpWithoutSdesCrypto,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003590 offer);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00003591}
3592
wu@webrtc.orgde305012013-10-31 15:40:38 +00003593// This test verifies DSCP is properly applied on the media channels.
3594TEST_F(WebRtcSessionTest, TestDscpConstraint) {
3595 constraints_.reset(new FakeConstraints());
3596 constraints_->AddOptional(
3597 webrtc::MediaConstraintsInterface::kEnableDscp, true);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003598 Init();
wu@webrtc.orgde305012013-10-31 15:40:38 +00003599 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003600 SessionDescriptionInterface* offer = CreateOffer();
wu@webrtc.orgde305012013-10-31 15:40:38 +00003601
3602 SetLocalDescriptionWithoutError(offer);
3603
3604 video_channel_ = media_engine_->GetVideoChannel(0);
3605 voice_channel_ = media_engine_->GetVoiceChannel(0);
3606
3607 ASSERT_TRUE(video_channel_ != NULL);
3608 ASSERT_TRUE(voice_channel_ != NULL);
3609 cricket::AudioOptions audio_options;
3610 EXPECT_TRUE(voice_channel_->GetOptions(&audio_options));
3611 cricket::VideoOptions video_options;
3612 EXPECT_TRUE(video_channel_->GetOptions(&video_options));
3613 EXPECT_TRUE(audio_options.dscp.IsSet());
3614 EXPECT_TRUE(audio_options.dscp.GetWithDefaultIfUnset(false));
3615 EXPECT_TRUE(video_options.dscp.IsSet());
3616 EXPECT_TRUE(video_options.dscp.GetWithDefaultIfUnset(false));
3617}
3618
henrike@webrtc.org6e3dbc22014-03-25 17:09:47 +00003619TEST_F(WebRtcSessionTest, TestSuspendBelowMinBitrateConstraint) {
3620 constraints_.reset(new FakeConstraints());
3621 constraints_->AddOptional(
3622 webrtc::MediaConstraintsInterface::kEnableVideoSuspendBelowMinBitrate,
3623 true);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003624 Init();
henrike@webrtc.org6e3dbc22014-03-25 17:09:47 +00003625 mediastream_signaling_.SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003626 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org6e3dbc22014-03-25 17:09:47 +00003627
3628 SetLocalDescriptionWithoutError(offer);
3629
3630 video_channel_ = media_engine_->GetVideoChannel(0);
3631
3632 ASSERT_TRUE(video_channel_ != NULL);
3633 cricket::VideoOptions video_options;
3634 EXPECT_TRUE(video_channel_->GetOptions(&video_options));
3635 EXPECT_TRUE(
3636 video_options.suspend_below_min_bitrate.GetWithDefaultIfUnset(false));
3637}
3638
buildbot@webrtc.org53df88c2014-08-07 22:46:01 +00003639TEST_F(WebRtcSessionTest, TestNumUnsignalledRecvStreamsConstraint) {
3640 // Number of unsignalled receiving streams should be between 0 and
3641 // kMaxUnsignalledRecvStreams.
3642 SetAndVerifyNumUnsignalledRecvStreams(10, 10);
3643 SetAndVerifyNumUnsignalledRecvStreams(kMaxUnsignalledRecvStreams + 1,
3644 kMaxUnsignalledRecvStreams);
3645 SetAndVerifyNumUnsignalledRecvStreams(-1, 0);
3646}
3647
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +00003648TEST_F(WebRtcSessionTest, TestCombinedAudioVideoBweConstraint) {
3649 constraints_.reset(new FakeConstraints());
3650 constraints_->AddOptional(
3651 webrtc::MediaConstraintsInterface::kCombinedAudioVideoBwe,
3652 true);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003653 Init();
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +00003654 mediastream_signaling_.SendAudioVideoStream1();
3655 SessionDescriptionInterface* offer = CreateOffer();
3656
3657 SetLocalDescriptionWithoutError(offer);
3658
3659 voice_channel_ = media_engine_->GetVoiceChannel(0);
3660
3661 ASSERT_TRUE(voice_channel_ != NULL);
3662 cricket::AudioOptions audio_options;
3663 EXPECT_TRUE(voice_channel_->GetOptions(&audio_options));
3664 EXPECT_TRUE(
3665 audio_options.combined_audio_video_bwe.GetWithDefaultIfUnset(false));
3666}
3667
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00003668// Tests that we can renegotiate new media content with ICE candidates in the
3669// new remote SDP.
3670TEST_F(WebRtcSessionTest, TestRenegotiateNewMediaWithCandidatesInSdp) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003671 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00003672 InitWithDtls();
3673 SetFactoryDtlsSrtp();
3674
3675 mediastream_signaling_.UseOptionsAudioOnly();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003676 SessionDescriptionInterface* offer = CreateOffer();
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00003677 SetLocalDescriptionWithoutError(offer);
3678
3679 SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
3680 SetRemoteDescriptionWithoutError(answer);
3681
3682 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00003683 options.recv_video = true;
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00003684 offer = CreateRemoteOffer(options, cricket::SEC_DISABLED);
3685
3686 cricket::Candidate candidate1;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003687 candidate1.set_address(rtc::SocketAddress("1.1.1.1", 5000));
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00003688 candidate1.set_component(1);
3689 JsepIceCandidate ice_candidate(kMediaContentName1, kMediaContentIndex1,
3690 candidate1);
3691 EXPECT_TRUE(offer->AddCandidate(&ice_candidate));
3692 SetRemoteDescriptionWithoutError(offer);
3693
3694 answer = CreateAnswer(NULL);
3695 SetLocalDescriptionWithoutError(answer);
3696}
3697
3698// Tests that we can renegotiate new media content with ICE candidates separated
3699// from the remote SDP.
3700TEST_F(WebRtcSessionTest, TestRenegotiateNewMediaWithCandidatesSeparated) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003701 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00003702 InitWithDtls();
3703 SetFactoryDtlsSrtp();
3704
3705 mediastream_signaling_.UseOptionsAudioOnly();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003706 SessionDescriptionInterface* offer = CreateOffer();
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00003707 SetLocalDescriptionWithoutError(offer);
3708
3709 SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
3710 SetRemoteDescriptionWithoutError(answer);
3711
3712 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00003713 options.recv_video = true;
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00003714 offer = CreateRemoteOffer(options, cricket::SEC_DISABLED);
3715 SetRemoteDescriptionWithoutError(offer);
3716
3717 cricket::Candidate candidate1;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003718 candidate1.set_address(rtc::SocketAddress("1.1.1.1", 5000));
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00003719 candidate1.set_component(1);
3720 JsepIceCandidate ice_candidate(kMediaContentName1, kMediaContentIndex1,
3721 candidate1);
3722 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate));
3723
3724 answer = CreateAnswer(NULL);
3725 SetLocalDescriptionWithoutError(answer);
3726}
changbin.shao@webrtc.org2d25b442015-03-16 04:14:34 +00003727// Tests that RTX codec is removed from the answer when it isn't supported
3728// by local side.
3729TEST_F(WebRtcSessionTest, TestRtxRemovedByCreateAnswer) {
3730 Init();
3731 mediastream_signaling_.SendAudioVideoStream1();
3732 std::string offer_sdp(kSdpWithRtx);
3733
3734 SessionDescriptionInterface* offer =
3735 CreateSessionDescription(JsepSessionDescription::kOffer, offer_sdp, NULL);
3736 EXPECT_TRUE(offer->ToString(&offer_sdp));
3737
3738 // Offer SDP contains the RTX codec.
3739 EXPECT_TRUE(offer_sdp.find("rtx") != std::string::npos);
3740 SetRemoteDescriptionWithoutError(offer);
3741
3742 SessionDescriptionInterface* answer = CreateAnswer(NULL);
3743 std::string answer_sdp;
3744 answer->ToString(&answer_sdp);
3745 // Answer SDP removes the unsupported RTX codec.
3746 EXPECT_TRUE(answer_sdp.find("rtx") == std::string::npos);
3747 SetLocalDescriptionWithoutError(answer);
3748}
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00003749
guoweis@webrtc.org4f852882015-03-12 20:09:44 +00003750// This verifies that the voice channel after bundle has both options from video
3751// and voice channels.
3752TEST_F(WebRtcSessionTest, TestSetSocketOptionBeforeBundle) {
3753 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyBalanced);
3754 mediastream_signaling_.SendAudioVideoStream1();
3755
3756 PeerConnectionInterface::RTCOfferAnswerOptions options;
3757 options.use_rtp_mux = true;
3758
3759 SessionDescriptionInterface* offer = CreateOffer(options);
3760 SetLocalDescriptionWithoutError(offer);
3761
3762 session_->video_channel()->SetOption(cricket::BaseChannel::ST_RTP,
3763 rtc::Socket::Option::OPT_SNDBUF, 4000);
3764
3765 session_->voice_channel()->SetOption(cricket::BaseChannel::ST_RTP,
3766 rtc::Socket::Option::OPT_RCVBUF, 8000);
3767
3768 int option_val;
3769 EXPECT_TRUE(session_->video_channel()->transport_channel()->GetOption(
3770 rtc::Socket::Option::OPT_SNDBUF, &option_val));
3771 EXPECT_EQ(4000, option_val);
3772 EXPECT_FALSE(session_->voice_channel()->transport_channel()->GetOption(
3773 rtc::Socket::Option::OPT_SNDBUF, &option_val));
3774
3775 EXPECT_TRUE(session_->voice_channel()->transport_channel()->GetOption(
3776 rtc::Socket::Option::OPT_RCVBUF, &option_val));
3777 EXPECT_EQ(8000, option_val);
3778 EXPECT_FALSE(session_->video_channel()->transport_channel()->GetOption(
3779 rtc::Socket::Option::OPT_RCVBUF, &option_val));
3780
3781 EXPECT_NE(session_->voice_channel()->transport_channel(),
3782 session_->video_channel()->transport_channel());
3783
3784 mediastream_signaling_.SendAudioVideoStream2();
3785 SessionDescriptionInterface* answer =
3786 CreateRemoteAnswer(session_->local_description());
3787 SetRemoteDescriptionWithoutError(answer);
3788
3789 EXPECT_TRUE(session_->voice_channel()->transport_channel()->GetOption(
3790 rtc::Socket::Option::OPT_SNDBUF, &option_val));
3791 EXPECT_EQ(4000, option_val);
3792
3793 EXPECT_TRUE(session_->voice_channel()->transport_channel()->GetOption(
3794 rtc::Socket::Option::OPT_RCVBUF, &option_val));
3795 EXPECT_EQ(8000, option_val);
3796}
3797
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003798// TODO(bemasc): Add a TestIceStatesBundle with BUNDLE enabled. That test
3799// currently fails because upon disconnection and reconnection OnIceComplete is
3800// called more than once without returning to IceGatheringGathering.