blob: 22345095ec5f8b5dfc47a9aa5cac10607a636204 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
kjellanderb24317b2016-02-10 07:54:43 -08002 * Copyright 2012 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003 *
kjellanderb24317b2016-02-10 07:54:43 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00009 */
10
jbauch555604a2016-04-26 03:13:22 -070011#include <memory>
kwiberg0eb15ed2015-12-17 03:04:15 -080012#include <utility>
deadbeefcbecd352015-09-23 11:50:27 -070013#include <vector>
14
Henrik Kjellander15583c12016-02-10 10:53:12 +010015#include "webrtc/api/audiotrack.h"
16#include "webrtc/api/fakemediacontroller.h"
17#include "webrtc/api/fakemetricsobserver.h"
18#include "webrtc/api/jsepicecandidate.h"
19#include "webrtc/api/jsepsessiondescription.h"
20#include "webrtc/api/peerconnection.h"
21#include "webrtc/api/sctputils.h"
Henrik Boströmd79599d2016-06-01 13:58:50 +020022#include "webrtc/api/test/fakertccertificategenerator.h"
Henrik Kjellander15583c12016-02-10 10:53:12 +010023#include "webrtc/api/videotrack.h"
24#include "webrtc/api/webrtcsession.h"
25#include "webrtc/api/webrtcsessiondescriptionfactory.h"
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000026#include "webrtc/base/fakenetwork.h"
27#include "webrtc/base/firewallsocketserver.h"
28#include "webrtc/base/gunit.h"
29#include "webrtc/base/logging.h"
30#include "webrtc/base/network.h"
31#include "webrtc/base/physicalsocketserver.h"
32#include "webrtc/base/ssladapter.h"
Henrik Boström5e56c592015-08-11 10:33:13 +020033#include "webrtc/base/sslidentity.h"
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000034#include "webrtc/base/sslstreamadapter.h"
35#include "webrtc/base/stringutils.h"
36#include "webrtc/base/thread.h"
37#include "webrtc/base/virtualsocketserver.h"
kjellandera96e2d72016-02-04 23:52:28 -080038#include "webrtc/media/base/fakemediaengine.h"
39#include "webrtc/media/base/fakevideorenderer.h"
40#include "webrtc/media/base/mediachannel.h"
kjellander@webrtc.org5ad12972016-02-12 06:39:40 +010041#include "webrtc/media/engine/fakewebrtccall.h"
kjellandera96e2d72016-02-04 23:52:28 -080042#include "webrtc/p2p/base/stunserver.h"
43#include "webrtc/p2p/base/teststunserver.h"
44#include "webrtc/p2p/base/testturnserver.h"
45#include "webrtc/p2p/base/transportchannel.h"
46#include "webrtc/p2p/client/basicportallocator.h"
kjellander@webrtc.org9b8df252016-02-12 06:47:59 +010047#include "webrtc/pc/channelmanager.h"
48#include "webrtc/pc/mediasession.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000049
50#define MAYBE_SKIP_TEST(feature) \
51 if (!(feature())) { \
52 LOG(LS_INFO) << "Feature disabled... skipping"; \
53 return; \
54 }
55
henrike@webrtc.org28e20752013-07-10 00:45:36 +000056using cricket::FakeVoiceMediaChannel;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000057using cricket::TransportInfo;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000058using rtc::SocketAddress;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000059using rtc::Thread;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000060using webrtc::CreateSessionDescription;
wu@webrtc.org91053e72013-08-10 07:18:04 +000061using webrtc::CreateSessionDescriptionObserver;
62using webrtc::CreateSessionDescriptionRequest;
deadbeefab9b2d12015-10-14 11:33:11 -070063using webrtc::DataChannel;
jbauchac8869e2015-07-03 01:36:14 -070064using webrtc::FakeMetricsObserver;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000065using webrtc::IceCandidateCollection;
deadbeefab9b2d12015-10-14 11:33:11 -070066using webrtc::InternalDataChannelInit;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000067using webrtc::JsepIceCandidate;
68using webrtc::JsepSessionDescription;
wu@webrtc.org97077a32013-10-25 21:18:33 +000069using webrtc::PeerConnectionFactoryInterface;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000070using webrtc::PeerConnectionInterface;
71using webrtc::SessionDescriptionInterface;
deadbeefd59daf82015-10-14 15:02:44 -070072using webrtc::SessionStats;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000073using webrtc::StreamCollection;
wu@webrtc.org91053e72013-08-10 07:18:04 +000074using webrtc::WebRtcSession;
wu@webrtc.org364f2042013-11-20 21:49:41 +000075using webrtc::kBundleWithoutRtcpMux;
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +000076using webrtc::kCreateChannelFailed;
77using webrtc::kInvalidSdp;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000078using webrtc::kMlineMismatch;
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +000079using webrtc::kPushDownTDFailed;
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +000080using webrtc::kSdpWithoutIceUfragPwd;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +000081using webrtc::kSdpWithoutDtlsFingerprint;
82using webrtc::kSdpWithoutSdesCrypto;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000083using webrtc::kSessionError;
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +000084using webrtc::kSessionErrorDesc;
buildbot@webrtc.org53df88c2014-08-07 22:46:01 +000085using webrtc::kMaxUnsignalledRecvStreams;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000086
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +000087typedef PeerConnectionInterface::RTCOfferAnswerOptions RTCOfferAnswerOptions;
88
wu@webrtc.org364f2042013-11-20 21:49:41 +000089static const int kClientAddrPort = 0;
90static const char kClientAddrHost1[] = "11.11.11.11";
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +000091static const char kClientIPv6AddrHost1[] =
92 "2620:0:aaaa:bbbb:cccc:dddd:eeee:ffff";
wu@webrtc.org364f2042013-11-20 21:49:41 +000093static const char kClientAddrHost2[] = "22.22.22.22";
94static const char kStunAddrHost[] = "99.99.99.1";
buildbot@webrtc.org41451d42014-05-03 05:39:45 +000095static const SocketAddress kTurnUdpIntAddr("99.99.99.4", 3478);
96static const SocketAddress kTurnUdpExtAddr("99.99.99.6", 0);
mallinath@webrtc.org3d81b1b2014-09-09 14:38:10 +000097static const char kTurnUsername[] = "test";
98static const char kTurnPassword[] = "test";
henrike@webrtc.org28e20752013-07-10 00:45:36 +000099
100static const char kSessionVersion[] = "1";
101
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000102// Media index of candidates belonging to the first media content.
103static const int kMediaContentIndex0 = 0;
104static const char kMediaContentName0[] = "audio";
105
106// Media index of candidates belonging to the second media content.
107static const int kMediaContentIndex1 = 1;
108static const char kMediaContentName1[] = "video";
109
110static const int kIceCandidatesTimeout = 10000;
deadbeeff5f03e82016-06-06 11:16:06 -0700111// STUN timeout with all retransmissions is a total of 9500ms.
112static const int kStunTimeout = 9500;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000113
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +0000114static const char kFakeDtlsFingerprint[] =
115 "BB:CD:72:F7:2F:D0:BA:43:F3:68:B1:0C:23:72:B6:4A:"
116 "0F:DE:34:06:BC:E0:FE:01:BC:73:C8:6D:F4:65:D5:24";
117
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +0000118static const char kTooLongIceUfragPwd[] =
119 "IceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfrag"
120 "IceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfrag"
121 "IceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfrag"
122 "IceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfragIceUfrag";
123
changbin.shao@webrtc.org2d25b442015-03-16 04:14:34 +0000124static const char kSdpWithRtx[] =
125 "v=0\r\n"
126 "o=- 4104004319237231850 2 IN IP4 127.0.0.1\r\n"
127 "s=-\r\n"
128 "t=0 0\r\n"
129 "a=msid-semantic: WMS stream1\r\n"
130 "m=video 9 RTP/SAVPF 0 96\r\n"
131 "c=IN IP4 0.0.0.0\r\n"
132 "a=rtcp:9 IN IP4 0.0.0.0\r\n"
133 "a=ice-ufrag:CerjGp19G7wpXwl7\r\n"
134 "a=ice-pwd:cMvOlFvQ6ochez1ZOoC2uBEC\r\n"
135 "a=mid:video\r\n"
136 "a=sendrecv\r\n"
137 "a=rtcp-mux\r\n"
138 "a=crypto:1 AES_CM_128_HMAC_SHA1_80 "
139 "inline:5/4N5CDvMiyDArHtBByUM71VIkguH17ZNoX60GrA\r\n"
140 "a=rtpmap:0 fake_video_codec/90000\r\n"
141 "a=rtpmap:96 rtx/90000\r\n"
142 "a=fmtp:96 apt=0\r\n";
143
deadbeefab9b2d12015-10-14 11:33:11 -0700144static const char kStream1[] = "stream1";
145static const char kVideoTrack1[] = "video1";
146static const char kAudioTrack1[] = "audio1";
147
148static const char kStream2[] = "stream2";
149static const char kVideoTrack2[] = "video2";
150static const char kAudioTrack2[] = "audio2";
151
Henrik Boström87713d02015-08-25 09:53:21 +0200152enum RTCCertificateGenerationMethod { ALREADY_GENERATED, DTLS_IDENTITY_STORE };
153
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000154class MockIceObserver : public webrtc::IceObserver {
155 public:
156 MockIceObserver()
157 : oncandidatesready_(false),
158 ice_connection_state_(PeerConnectionInterface::kIceConnectionNew),
159 ice_gathering_state_(PeerConnectionInterface::kIceGatheringNew) {
160 }
161
Henrik Kjellander3fe372d2016-05-12 08:10:52 +0200162 virtual ~MockIceObserver() = default;
163
perkjdfb769d2016-02-09 03:09:43 -0800164 void OnIceConnectionChange(
165 PeerConnectionInterface::IceConnectionState new_state) override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000166 ice_connection_state_ = new_state;
skvlad6c87a672016-05-17 17:49:52 -0700167 ice_connection_state_history_.push_back(new_state);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000168 }
perkjdfb769d2016-02-09 03:09:43 -0800169 void OnIceGatheringChange(
170 PeerConnectionInterface::IceGatheringState new_state) override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000171 // We can never transition back to "new".
172 EXPECT_NE(PeerConnectionInterface::kIceGatheringNew, new_state);
173 ice_gathering_state_ = new_state;
perkjdfb769d2016-02-09 03:09:43 -0800174 oncandidatesready_ =
175 new_state == PeerConnectionInterface::kIceGatheringComplete;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000176 }
177
178 // Found a new candidate.
perkjdfb769d2016-02-09 03:09:43 -0800179 void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override {
wu@webrtc.org364f2042013-11-20 21:49:41 +0000180 switch (candidate->sdp_mline_index()) {
181 case kMediaContentIndex0:
182 mline_0_candidates_.push_back(candidate->candidate());
183 break;
184 case kMediaContentIndex1:
185 mline_1_candidates_.push_back(candidate->candidate());
186 break;
187 default:
188 ASSERT(false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000189 }
wu@webrtc.org364f2042013-11-20 21:49:41 +0000190
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000191 // The ICE gathering state should always be Gathering when a candidate is
192 // received (or possibly Completed in the case of the final candidate).
193 EXPECT_NE(PeerConnectionInterface::kIceGatheringNew, ice_gathering_state_);
194 }
195
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700196 // Some local candidates are removed.
197 void OnIceCandidatesRemoved(
nisseef8b61e2016-04-29 06:09:15 -0700198 const std::vector<cricket::Candidate>& candidates) override {
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700199 num_candidates_removed_ += candidates.size();
200 }
201
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000202 bool oncandidatesready_;
203 std::vector<cricket::Candidate> mline_0_candidates_;
204 std::vector<cricket::Candidate> mline_1_candidates_;
205 PeerConnectionInterface::IceConnectionState ice_connection_state_;
206 PeerConnectionInterface::IceGatheringState ice_gathering_state_;
skvlad6c87a672016-05-17 17:49:52 -0700207 std::vector<PeerConnectionInterface::IceConnectionState>
208 ice_connection_state_history_;
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700209 size_t num_candidates_removed_ = 0;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000210};
211
212class WebRtcSessionForTest : public webrtc::WebRtcSession {
213 public:
zhihuang29ff8442016-07-27 11:07:25 -0700214 WebRtcSessionForTest(
215 webrtc::MediaControllerInterface* media_controller,
216 rtc::Thread* network_thread,
217 rtc::Thread* worker_thread,
218 rtc::Thread* signaling_thread,
219 cricket::PortAllocator* port_allocator,
220 webrtc::IceObserver* ice_observer,
221 std::unique_ptr<cricket::TransportController> transport_controller)
stefanc1aeaf02015-10-15 07:26:07 -0700222 : WebRtcSession(media_controller,
danilchape9021a32016-05-17 01:52:02 -0700223 network_thread,
stefanc1aeaf02015-10-15 07:26:07 -0700224 worker_thread,
danilchape9021a32016-05-17 01:52:02 -0700225 signaling_thread,
zhihuang29ff8442016-07-27 11:07:25 -0700226 port_allocator,
227 std::move(transport_controller)) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000228 RegisterIceObserver(ice_observer);
229 }
230 virtual ~WebRtcSessionForTest() {}
231
deadbeefcbecd352015-09-23 11:50:27 -0700232 // Note that these methods are only safe to use if the signaling thread
233 // is the same as the worker thread
234 cricket::TransportChannel* voice_rtp_transport_channel() {
235 return rtp_transport_channel(voice_channel());
236 }
237
238 cricket::TransportChannel* voice_rtcp_transport_channel() {
239 return rtcp_transport_channel(voice_channel());
240 }
241
242 cricket::TransportChannel* video_rtp_transport_channel() {
243 return rtp_transport_channel(video_channel());
244 }
245
246 cricket::TransportChannel* video_rtcp_transport_channel() {
247 return rtcp_transport_channel(video_channel());
248 }
249
250 cricket::TransportChannel* data_rtp_transport_channel() {
251 return rtp_transport_channel(data_channel());
252 }
253
254 cricket::TransportChannel* data_rtcp_transport_channel() {
255 return rtcp_transport_channel(data_channel());
256 }
257
deadbeefcbecd352015-09-23 11:50:27 -0700258 private:
259 cricket::TransportChannel* rtp_transport_channel(cricket::BaseChannel* ch) {
260 if (!ch) {
261 return nullptr;
262 }
263 return ch->transport_channel();
264 }
265
266 cricket::TransportChannel* rtcp_transport_channel(cricket::BaseChannel* ch) {
267 if (!ch) {
268 return nullptr;
269 }
270 return ch->rtcp_transport_channel();
271 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000272};
273
wu@webrtc.org91053e72013-08-10 07:18:04 +0000274class WebRtcSessionCreateSDPObserverForTest
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000275 : public rtc::RefCountedObject<CreateSessionDescriptionObserver> {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000276 public:
wu@webrtc.org91053e72013-08-10 07:18:04 +0000277 enum State {
278 kInit,
279 kFailed,
280 kSucceeded,
281 };
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000282 WebRtcSessionCreateSDPObserverForTest() : state_(kInit) {}
wu@webrtc.org91053e72013-08-10 07:18:04 +0000283
284 // CreateSessionDescriptionObserver implementation.
285 virtual void OnSuccess(SessionDescriptionInterface* desc) {
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000286 description_.reset(desc);
wu@webrtc.org91053e72013-08-10 07:18:04 +0000287 state_ = kSucceeded;
288 }
289 virtual void OnFailure(const std::string& error) {
290 state_ = kFailed;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000291 }
292
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000293 SessionDescriptionInterface* description() { return description_.get(); }
294
295 SessionDescriptionInterface* ReleaseDescription() {
296 return description_.release();
297 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000298
wu@webrtc.org91053e72013-08-10 07:18:04 +0000299 State state() const { return state_; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000300
wu@webrtc.org91053e72013-08-10 07:18:04 +0000301 protected:
302 ~WebRtcSessionCreateSDPObserverForTest() {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000303
304 private:
kwibergd1fe2812016-04-27 06:47:29 -0700305 std::unique_ptr<SessionDescriptionInterface> description_;
wu@webrtc.org91053e72013-08-10 07:18:04 +0000306 State state_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000307};
308
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800309class FakeAudioSource : public cricket::AudioSource {
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000310 public:
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800311 FakeAudioSource() : sink_(NULL) {}
312 virtual ~FakeAudioSource() {
henrike@webrtc.orga7b98182014-02-21 15:51:43 +0000313 if (sink_)
314 sink_->OnClose();
315 }
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000316
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000317 void SetSink(Sink* sink) override { sink_ = sink; }
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000318
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800319 const cricket::AudioSource::Sink* sink() const { return sink_; }
320
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000321 private:
Taylor Brandstetter1a018dc2016-03-08 12:37:39 -0800322 cricket::AudioSource::Sink* sink_;
henrike@webrtc.org1e09a712013-07-26 19:17:59 +0000323};
324
Henrik Boström87713d02015-08-25 09:53:21 +0200325class WebRtcSessionTest
deadbeefab9b2d12015-10-14 11:33:11 -0700326 : public testing::TestWithParam<RTCCertificateGenerationMethod>,
327 public sigslot::has_slots<> {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000328 protected:
329 // TODO Investigate why ChannelManager crashes, if it's created
330 // after stun_server.
331 WebRtcSessionTest()
stefanc1aeaf02015-10-15 07:26:07 -0700332 : media_engine_(new cricket::FakeMediaEngine()),
333 data_engine_(new cricket::FakeDataEngine()),
334 channel_manager_(
335 new cricket::ChannelManager(media_engine_,
336 data_engine_,
stefanc1aeaf02015-10-15 07:26:07 -0700337 rtc::Thread::Current())),
338 fake_call_(webrtc::Call::Config()),
339 media_controller_(
nisse51542be2016-02-12 02:27:06 -0800340 webrtc::MediaControllerInterface::Create(cricket::MediaConfig(),
341 rtc::Thread::Current(),
stefanc1aeaf02015-10-15 07:26:07 -0700342 channel_manager_.get())),
343 tdesc_factory_(new cricket::TransportDescriptionFactory()),
344 desc_factory_(
345 new cricket::MediaSessionDescriptionFactory(channel_manager_.get(),
346 tdesc_factory_.get())),
347 pss_(new rtc::PhysicalSocketServer),
348 vss_(new rtc::VirtualSocketServer(pss_.get())),
349 fss_(new rtc::FirewallSocketServer(vss_.get())),
350 ss_scope_(fss_.get()),
351 stun_socket_addr_(
352 rtc::SocketAddress(kStunAddrHost, cricket::STUN_SERVER_PORT)),
353 stun_server_(cricket::TestStunServer::Create(Thread::Current(),
354 stun_socket_addr_)),
355 turn_server_(Thread::Current(), kTurnUdpIntAddr, kTurnUdpExtAddr),
356 metrics_observer_(new rtc::RefCountedObject<FakeMetricsObserver>()) {
buildbot@webrtc.org51c55082014-07-28 22:26:15 +0000357 cricket::ServerAddresses stun_servers;
358 stun_servers.insert(stun_socket_addr_);
359 allocator_.reset(new cricket::BasicPortAllocator(
360 &network_manager_,
361 stun_servers,
362 SocketAddress(), SocketAddress(), SocketAddress()));
buildbot@webrtc.org41451d42014-05-03 05:39:45 +0000363 allocator_->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
Peter Thatcher7cbd1882015-09-17 18:54:52 -0700364 cricket::PORTALLOCATOR_DISABLE_RELAY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000365 EXPECT_TRUE(channel_manager_->Init());
366 desc_factory_->set_add_legacy_streams(false);
buildbot@webrtc.org41451d42014-05-03 05:39:45 +0000367 allocator_->set_step_delay(cricket::kMinimumStepDelay);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000368 }
369
370 void AddInterface(const SocketAddress& addr) {
371 network_manager_.AddInterface(addr);
372 }
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700373 void RemoveInterface(const SocketAddress& addr) {
374 network_manager_.RemoveInterface(addr);
375 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000376
Henrik Boströmd79599d2016-06-01 13:58:50 +0200377 // If |cert_generator| != null or |rtc_configuration| contains |certificates|
378 // then DTLS will be enabled unless explicitly disabled by |rtc_configuration|
379 // options. When DTLS is enabled a certificate will be used if provided,
380 // otherwise one will be generated using the |cert_generator|.
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000381 void Init(
Henrik Boströmd79599d2016-06-01 13:58:50 +0200382 std::unique_ptr<rtc::RTCCertificateGeneratorInterface> cert_generator) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000383 ASSERT_TRUE(session_.get() == NULL);
384 session_.reset(new WebRtcSessionForTest(
stefanc1aeaf02015-10-15 07:26:07 -0700385 media_controller_.get(), rtc::Thread::Current(), rtc::Thread::Current(),
zhihuang29ff8442016-07-27 11:07:25 -0700386 rtc::Thread::Current(), allocator_.get(), &observer_,
387 std::unique_ptr<cricket::TransportController>(
388 new cricket::TransportController(rtc::Thread::Current(),
389 rtc::Thread::Current(),
390 allocator_.get()))));
deadbeefab9b2d12015-10-14 11:33:11 -0700391 session_->SignalDataChannelOpenMessage.connect(
392 this, &WebRtcSessionTest::OnDataChannelOpenMessage);
deadbeef057ecf02016-01-20 14:30:43 -0800393 session_->GetOnDestroyedSignal()->connect(
394 this, &WebRtcSessionTest::OnSessionDestroyed);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000395
396 EXPECT_EQ(PeerConnectionInterface::kIceConnectionNew,
397 observer_.ice_connection_state_);
398 EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
399 observer_.ice_gathering_state_);
400
Henrik Boströmd03c23b2016-06-01 11:44:18 +0200401 EXPECT_TRUE(session_->Initialize(options_, std::move(cert_generator),
htaa2a49d92016-03-04 02:51:39 -0800402 configuration_));
jbauchac8869e2015-07-03 01:36:14 -0700403 session_->set_metrics_observer(metrics_observer_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000404 }
405
deadbeefab9b2d12015-10-14 11:33:11 -0700406 void OnDataChannelOpenMessage(const std::string& label,
407 const InternalDataChannelInit& config) {
408 last_data_channel_label_ = label;
409 last_data_channel_config_ = config;
410 }
411
deadbeef057ecf02016-01-20 14:30:43 -0800412 void OnSessionDestroyed() { session_destroyed_ = true; }
413
htaa2a49d92016-03-04 02:51:39 -0800414 void Init() { Init(nullptr); }
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000415
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000416 void InitWithBundlePolicy(
417 PeerConnectionInterface::BundlePolicy bundle_policy) {
htaa2a49d92016-03-04 02:51:39 -0800418 configuration_.bundle_policy = bundle_policy;
419 Init();
Peter Thatcheraf55ccc2015-05-21 07:48:41 -0700420 }
421
422 void InitWithRtcpMuxPolicy(
423 PeerConnectionInterface::RtcpMuxPolicy rtcp_mux_policy) {
424 PeerConnectionInterface::RTCConfiguration configuration;
htaa2a49d92016-03-04 02:51:39 -0800425 configuration_.rtcp_mux_policy = rtcp_mux_policy;
426 Init();
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000427 }
428
Henrik Boström87713d02015-08-25 09:53:21 +0200429 // Successfully init with DTLS; with a certificate generated and supplied or
430 // with a store that generates it for us.
431 void InitWithDtls(RTCCertificateGenerationMethod cert_gen_method) {
Henrik Boströmd79599d2016-06-01 13:58:50 +0200432 std::unique_ptr<FakeRTCCertificateGenerator> cert_generator;
Henrik Boström87713d02015-08-25 09:53:21 +0200433 if (cert_gen_method == ALREADY_GENERATED) {
htaa2a49d92016-03-04 02:51:39 -0800434 configuration_.certificates.push_back(
Henrik Boströmd79599d2016-06-01 13:58:50 +0200435 FakeRTCCertificateGenerator::GenerateCertificate());
Henrik Boström87713d02015-08-25 09:53:21 +0200436 } else if (cert_gen_method == DTLS_IDENTITY_STORE) {
Henrik Boströmd79599d2016-06-01 13:58:50 +0200437 cert_generator.reset(new FakeRTCCertificateGenerator());
438 cert_generator->set_should_fail(false);
Henrik Boström87713d02015-08-25 09:53:21 +0200439 } else {
henrikg91d6ede2015-09-17 00:24:34 -0700440 RTC_CHECK(false);
Henrik Boström87713d02015-08-25 09:53:21 +0200441 }
Henrik Boströmd79599d2016-06-01 13:58:50 +0200442 Init(std::move(cert_generator));
Henrik Boström87713d02015-08-25 09:53:21 +0200443 }
444
445 // Init with DTLS with a store that will fail to generate a certificate.
446 void InitWithDtlsIdentityGenFail() {
Henrik Boströmd79599d2016-06-01 13:58:50 +0200447 std::unique_ptr<FakeRTCCertificateGenerator> cert_generator(
448 new FakeRTCCertificateGenerator());
449 cert_generator->set_should_fail(true);
450 Init(std::move(cert_generator));
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000451 }
452
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000453 void InitWithDtmfCodec() {
454 // Add kTelephoneEventCodec for dtmf test.
deadbeef67cf2c12016-04-13 10:07:16 -0700455 const cricket::AudioCodec kTelephoneEventCodec(106, "telephone-event", 8000,
456 0, 1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000457 std::vector<cricket::AudioCodec> codecs;
458 codecs.push_back(kTelephoneEventCodec);
459 media_engine_->SetAudioCodecs(codecs);
ossu075af922016-06-14 03:29:38 -0700460 desc_factory_->set_audio_codecs(codecs, codecs);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +0000461 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000462 }
463
jbauchcb560652016-08-04 05:20:32 -0700464 void InitWithGcm() {
465 rtc::CryptoOptions crypto_options;
466 crypto_options.enable_gcm_crypto_suites = true;
467 channel_manager_->SetCryptoOptions(crypto_options);
468 with_gcm_ = true;
469 Init();
470 }
471
deadbeefab9b2d12015-10-14 11:33:11 -0700472 void SendAudioVideoStream1() {
473 send_stream_1_ = true;
474 send_stream_2_ = false;
475 send_audio_ = true;
476 send_video_ = true;
477 }
478
479 void SendAudioVideoStream2() {
480 send_stream_1_ = false;
481 send_stream_2_ = true;
482 send_audio_ = true;
483 send_video_ = true;
484 }
485
486 void SendAudioVideoStream1And2() {
487 send_stream_1_ = true;
488 send_stream_2_ = true;
489 send_audio_ = true;
490 send_video_ = true;
491 }
492
493 void SendNothing() {
494 send_stream_1_ = false;
495 send_stream_2_ = false;
496 send_audio_ = false;
497 send_video_ = false;
498 }
499
500 void SendAudioOnlyStream2() {
501 send_stream_1_ = false;
502 send_stream_2_ = true;
503 send_audio_ = true;
504 send_video_ = false;
505 }
506
507 void SendVideoOnlyStream2() {
508 send_stream_1_ = false;
509 send_stream_2_ = true;
510 send_audio_ = false;
511 send_video_ = true;
512 }
513
514 void AddStreamsToOptions(cricket::MediaSessionOptions* session_options) {
515 if (send_stream_1_ && send_audio_) {
516 session_options->AddSendStream(cricket::MEDIA_TYPE_AUDIO, kAudioTrack1,
517 kStream1);
518 }
519 if (send_stream_1_ && send_video_) {
520 session_options->AddSendStream(cricket::MEDIA_TYPE_VIDEO, kVideoTrack1,
521 kStream1);
522 }
523 if (send_stream_2_ && send_audio_) {
524 session_options->AddSendStream(cricket::MEDIA_TYPE_AUDIO, kAudioTrack2,
525 kStream2);
526 }
527 if (send_stream_2_ && send_video_) {
528 session_options->AddSendStream(cricket::MEDIA_TYPE_VIDEO, kVideoTrack2,
529 kStream2);
530 }
531 if (data_channel_ && session_->data_channel_type() == cricket::DCT_RTP) {
532 session_options->AddSendStream(cricket::MEDIA_TYPE_DATA,
533 data_channel_->label(),
534 data_channel_->label());
535 }
536 }
537
538 void GetOptionsForOffer(
539 const PeerConnectionInterface::RTCOfferAnswerOptions& rtc_options,
540 cricket::MediaSessionOptions* session_options) {
htaaac2dea2016-03-10 13:35:55 -0800541 ASSERT_TRUE(ExtractMediaSessionOptions(rtc_options, true, session_options));
deadbeefab9b2d12015-10-14 11:33:11 -0700542
deadbeefc80741f2015-10-22 13:14:45 -0700543 AddStreamsToOptions(session_options);
544 if (rtc_options.offer_to_receive_audio ==
545 RTCOfferAnswerOptions::kUndefined) {
546 session_options->recv_audio =
547 session_options->HasSendMediaStream(cricket::MEDIA_TYPE_AUDIO);
548 }
549 if (rtc_options.offer_to_receive_video ==
550 RTCOfferAnswerOptions::kUndefined) {
551 session_options->recv_video =
552 session_options->HasSendMediaStream(cricket::MEDIA_TYPE_VIDEO);
553 }
554 session_options->bundle_enabled =
555 session_options->bundle_enabled &&
556 (session_options->has_audio() || session_options->has_video() ||
557 session_options->has_data());
558
deadbeefab9b2d12015-10-14 11:33:11 -0700559 if (session_->data_channel_type() == cricket::DCT_SCTP && data_channel_) {
560 session_options->data_channel_type = cricket::DCT_SCTP;
zhihuang34b54c32016-08-04 11:06:50 -0700561 } else if (session_->data_channel_type() == cricket::DCT_QUIC) {
562 session_options->data_channel_type = cricket::DCT_QUIC;
deadbeefab9b2d12015-10-14 11:33:11 -0700563 }
jbauchcb560652016-08-04 05:20:32 -0700564
565 if (with_gcm_) {
566 session_options->crypto_options.enable_gcm_crypto_suites = true;
567 }
deadbeefab9b2d12015-10-14 11:33:11 -0700568 }
569
htaa2a49d92016-03-04 02:51:39 -0800570 void GetOptionsForAnswer(cricket::MediaSessionOptions* session_options) {
571 // ParseConstraintsForAnswer is used to set some defaults.
572 ASSERT_TRUE(webrtc::ParseConstraintsForAnswer(nullptr, session_options));
deadbeefab9b2d12015-10-14 11:33:11 -0700573
deadbeefc80741f2015-10-22 13:14:45 -0700574 AddStreamsToOptions(session_options);
575 session_options->bundle_enabled =
576 session_options->bundle_enabled &&
577 (session_options->has_audio() || session_options->has_video() ||
578 session_options->has_data());
579
zhihuang34b54c32016-08-04 11:06:50 -0700580 session_options->data_channel_type = session_->data_channel_type();
jbauchcb560652016-08-04 05:20:32 -0700581
582 if (with_gcm_) {
583 session_options->crypto_options.enable_gcm_crypto_suites = true;
584 }
deadbeefab9b2d12015-10-14 11:33:11 -0700585 }
586
587 // Creates a local offer and applies it. Starts ICE.
588 // Call SendAudioVideoStreamX() before this function
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000589 // to decide which streams to create.
590 void InitiateCall() {
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +0000591 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000592 SetLocalDescriptionWithoutError(offer);
593 EXPECT_TRUE_WAIT(PeerConnectionInterface::kIceGatheringNew !=
594 observer_.ice_gathering_state_,
595 kIceCandidatesTimeout);
596 }
597
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +0000598 SessionDescriptionInterface* CreateOffer() {
599 PeerConnectionInterface::RTCOfferAnswerOptions options;
600 options.offer_to_receive_audio =
601 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
602
603 return CreateOffer(options);
604 }
605
wu@webrtc.org91053e72013-08-10 07:18:04 +0000606 SessionDescriptionInterface* CreateOffer(
htaa2a49d92016-03-04 02:51:39 -0800607 const PeerConnectionInterface::RTCOfferAnswerOptions options) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000608 rtc::scoped_refptr<WebRtcSessionCreateSDPObserverForTest>
wu@webrtc.org91053e72013-08-10 07:18:04 +0000609 observer = new WebRtcSessionCreateSDPObserverForTest();
deadbeefab9b2d12015-10-14 11:33:11 -0700610 cricket::MediaSessionOptions session_options;
611 GetOptionsForOffer(options, &session_options);
612 session_->CreateOffer(observer, options, session_options);
wu@webrtc.org91053e72013-08-10 07:18:04 +0000613 EXPECT_TRUE_WAIT(
614 observer->state() != WebRtcSessionCreateSDPObserverForTest::kInit,
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000615 2000);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000616 return observer->ReleaseDescription();
wu@webrtc.org91053e72013-08-10 07:18:04 +0000617 }
618
619 SessionDescriptionInterface* CreateAnswer(
htaa2a49d92016-03-04 02:51:39 -0800620 const cricket::MediaSessionOptions& options) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000621 rtc::scoped_refptr<WebRtcSessionCreateSDPObserverForTest> observer
wu@webrtc.org91053e72013-08-10 07:18:04 +0000622 = new WebRtcSessionCreateSDPObserverForTest();
htaa2a49d92016-03-04 02:51:39 -0800623 cricket::MediaSessionOptions session_options = options;
624 GetOptionsForAnswer(&session_options);
625 // Overwrite recv_audio and recv_video with passed-in values.
626 session_options.recv_video = options.recv_video;
627 session_options.recv_audio = options.recv_audio;
628 session_->CreateAnswer(observer, session_options);
wu@webrtc.org91053e72013-08-10 07:18:04 +0000629 EXPECT_TRUE_WAIT(
630 observer->state() != WebRtcSessionCreateSDPObserverForTest::kInit,
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000631 2000);
mallinath@webrtc.orga5506692013-08-12 21:18:15 +0000632 return observer->ReleaseDescription();
wu@webrtc.org91053e72013-08-10 07:18:04 +0000633 }
634
htaa2a49d92016-03-04 02:51:39 -0800635 SessionDescriptionInterface* CreateAnswer() {
636 cricket::MediaSessionOptions options;
637 options.recv_video = true;
638 options.recv_audio = true;
639 return CreateAnswer(options);
640 }
641
wu@webrtc.org364f2042013-11-20 21:49:41 +0000642 bool ChannelsExist() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000643 return (session_->voice_channel() != NULL &&
644 session_->video_channel() != NULL);
645 }
646
jbauchcb560652016-08-04 05:20:32 -0700647 void VerifyCryptoParams(const cricket::SessionDescription* sdp,
648 bool gcm_enabled = false) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000649 ASSERT_TRUE(session_.get() != NULL);
650 const cricket::ContentInfo* content = cricket::GetFirstAudioContent(sdp);
651 ASSERT_TRUE(content != NULL);
652 const cricket::AudioContentDescription* audio_content =
653 static_cast<const cricket::AudioContentDescription*>(
654 content->description);
655 ASSERT_TRUE(audio_content != NULL);
jbauchcb560652016-08-04 05:20:32 -0700656 if (!gcm_enabled) {
657 ASSERT_EQ(1U, audio_content->cryptos().size());
658 ASSERT_EQ(47U, audio_content->cryptos()[0].key_params.size());
659 ASSERT_EQ("AES_CM_128_HMAC_SHA1_80",
660 audio_content->cryptos()[0].cipher_suite);
661 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf),
662 audio_content->protocol());
663 } else {
664 // The offer contains 3 possible crypto suites, the answer 1.
665 EXPECT_LE(1U, audio_content->cryptos().size());
666 EXPECT_NE(2U, audio_content->cryptos().size());
667 EXPECT_GE(3U, audio_content->cryptos().size());
668 ASSERT_EQ(67U, audio_content->cryptos()[0].key_params.size());
669 ASSERT_EQ("AEAD_AES_256_GCM",
670 audio_content->cryptos()[0].cipher_suite);
671 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf),
672 audio_content->protocol());
673 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000674
675 content = cricket::GetFirstVideoContent(sdp);
676 ASSERT_TRUE(content != NULL);
677 const cricket::VideoContentDescription* video_content =
678 static_cast<const cricket::VideoContentDescription*>(
679 content->description);
680 ASSERT_TRUE(video_content != NULL);
jbauchcb560652016-08-04 05:20:32 -0700681 if (!gcm_enabled) {
682 ASSERT_EQ(1U, video_content->cryptos().size());
683 ASSERT_EQ("AES_CM_128_HMAC_SHA1_80",
684 video_content->cryptos()[0].cipher_suite);
685 ASSERT_EQ(47U, video_content->cryptos()[0].key_params.size());
686 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf),
687 video_content->protocol());
688 } else {
689 // The offer contains 3 possible crypto suites, the answer 1.
690 EXPECT_LE(1U, video_content->cryptos().size());
691 EXPECT_NE(2U, video_content->cryptos().size());
692 EXPECT_GE(3U, video_content->cryptos().size());
693 ASSERT_EQ("AEAD_AES_256_GCM",
694 video_content->cryptos()[0].cipher_suite);
695 ASSERT_EQ(67U, video_content->cryptos()[0].key_params.size());
696 EXPECT_EQ(std::string(cricket::kMediaProtocolSavpf),
697 video_content->protocol());
698 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000699 }
700
701 void VerifyNoCryptoParams(const cricket::SessionDescription* sdp, bool dtls) {
702 const cricket::ContentInfo* content = cricket::GetFirstAudioContent(sdp);
703 ASSERT_TRUE(content != NULL);
704 const cricket::AudioContentDescription* audio_content =
705 static_cast<const cricket::AudioContentDescription*>(
706 content->description);
707 ASSERT_TRUE(audio_content != NULL);
708 ASSERT_EQ(0U, audio_content->cryptos().size());
709
710 content = cricket::GetFirstVideoContent(sdp);
711 ASSERT_TRUE(content != NULL);
712 const cricket::VideoContentDescription* video_content =
713 static_cast<const cricket::VideoContentDescription*>(
714 content->description);
715 ASSERT_TRUE(video_content != NULL);
716 ASSERT_EQ(0U, video_content->cryptos().size());
717
718 if (dtls) {
deadbeeff3938292015-07-15 12:20:53 -0700719 EXPECT_EQ(std::string(cricket::kMediaProtocolDtlsSavpf),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000720 audio_content->protocol());
deadbeeff3938292015-07-15 12:20:53 -0700721 EXPECT_EQ(std::string(cricket::kMediaProtocolDtlsSavpf),
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000722 video_content->protocol());
723 } else {
724 EXPECT_EQ(std::string(cricket::kMediaProtocolAvpf),
725 audio_content->protocol());
726 EXPECT_EQ(std::string(cricket::kMediaProtocolAvpf),
727 video_content->protocol());
728 }
729 }
730
731 // Set the internal fake description factories to do DTLS-SRTP.
732 void SetFactoryDtlsSrtp() {
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000733 desc_factory_->set_secure(cricket::SEC_DISABLED);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000734 std::string identity_name = "WebRTC" +
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000735 rtc::ToString(rtc::CreateRandomId());
Torbjorn Granlundb6d4ec42015-08-17 14:08:59 +0200736 // Confirmed to work with KT_RSA and KT_ECDSA.
kwiberg0eb15ed2015-12-17 03:04:15 -0800737 tdesc_factory_->set_certificate(
jbauch555604a2016-04-26 03:13:22 -0700738 rtc::RTCCertificate::Create(std::unique_ptr<rtc::SSLIdentity>(
kwiberg0eb15ed2015-12-17 03:04:15 -0800739 rtc::SSLIdentity::Generate(identity_name, rtc::KT_DEFAULT))));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000740 tdesc_factory_->set_secure(cricket::SEC_REQUIRED);
741 }
742
743 void VerifyFingerprintStatus(const cricket::SessionDescription* sdp,
744 bool expected) {
745 const TransportInfo* audio = sdp->GetTransportInfoByName("audio");
746 ASSERT_TRUE(audio != NULL);
747 ASSERT_EQ(expected, audio->description.identity_fingerprint.get() != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000748 const TransportInfo* video = sdp->GetTransportInfoByName("video");
749 ASSERT_TRUE(video != NULL);
750 ASSERT_EQ(expected, video->description.identity_fingerprint.get() != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000751 }
752
753 void VerifyAnswerFromNonCryptoOffer() {
jiayl@webrtc.org7d4891d2014-09-09 21:43:15 +0000754 // Create an SDP without Crypto.
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000755 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +0000756 options.recv_video = true;
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000757 JsepSessionDescription* offer(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000758 CreateRemoteOffer(options, cricket::SEC_DISABLED));
henrike@webrtc.org28654cb2013-07-22 21:07:49 +0000759 ASSERT_TRUE(offer != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000760 VerifyNoCryptoParams(offer->description(), false);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000761 SetRemoteDescriptionOfferExpectError(kSdpWithoutSdesCrypto,
762 offer);
htaa2a49d92016-03-04 02:51:39 -0800763 const webrtc::SessionDescriptionInterface* answer = CreateAnswer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000764 // Answer should be NULL as no crypto params in offer.
765 ASSERT_TRUE(answer == NULL);
766 }
767
768 void VerifyAnswerFromCryptoOffer() {
769 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +0000770 options.recv_video = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000771 options.bundle_enabled = true;
kwibergd1fe2812016-04-27 06:47:29 -0700772 std::unique_ptr<JsepSessionDescription> offer(
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000773 CreateRemoteOffer(options, cricket::SEC_REQUIRED));
774 ASSERT_TRUE(offer.get() != NULL);
775 VerifyCryptoParams(offer->description());
776 SetRemoteDescriptionWithoutError(offer.release());
kwibergd1fe2812016-04-27 06:47:29 -0700777 std::unique_ptr<SessionDescriptionInterface> answer(CreateAnswer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000778 ASSERT_TRUE(answer.get() != NULL);
779 VerifyCryptoParams(answer->description());
780 }
781
deadbeef0ed85b22016-02-23 17:24:52 -0800782 bool IceUfragPwdEqual(const cricket::SessionDescription* desc1,
783 const cricket::SessionDescription* desc2) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000784 if (desc1->contents().size() != desc2->contents().size()) {
deadbeef0ed85b22016-02-23 17:24:52 -0800785 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000786 }
787
788 const cricket::ContentInfos& contents = desc1->contents();
789 cricket::ContentInfos::const_iterator it = contents.begin();
790
791 for (; it != contents.end(); ++it) {
792 const cricket::TransportDescription* transport_desc1 =
793 desc1->GetTransportDescriptionByName(it->name);
794 const cricket::TransportDescription* transport_desc2 =
795 desc2->GetTransportDescriptionByName(it->name);
796 if (!transport_desc1 || !transport_desc2) {
deadbeef0ed85b22016-02-23 17:24:52 -0800797 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000798 }
799 if (transport_desc1->ice_pwd != transport_desc2->ice_pwd ||
800 transport_desc1->ice_ufrag != transport_desc2->ice_ufrag) {
deadbeef0ed85b22016-02-23 17:24:52 -0800801 return false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000802 }
803 }
deadbeef0ed85b22016-02-23 17:24:52 -0800804 return true;
805 }
806
807 // Compares ufrag/password only for the specified |media_type|.
808 bool IceUfragPwdEqual(const cricket::SessionDescription* desc1,
809 const cricket::SessionDescription* desc2,
810 cricket::MediaType media_type) {
811 if (desc1->contents().size() != desc2->contents().size()) {
812 return false;
813 }
814
815 const cricket::ContentInfo* cinfo =
816 cricket::GetFirstMediaContent(desc1->contents(), media_type);
817 const cricket::TransportDescription* transport_desc1 =
818 desc1->GetTransportDescriptionByName(cinfo->name);
819 const cricket::TransportDescription* transport_desc2 =
820 desc2->GetTransportDescriptionByName(cinfo->name);
821 if (!transport_desc1 || !transport_desc2) {
822 return false;
823 }
824 if (transport_desc1->ice_pwd != transport_desc2->ice_pwd ||
825 transport_desc1->ice_ufrag != transport_desc2->ice_ufrag) {
826 return false;
827 }
828 return true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000829 }
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000830
831 void RemoveIceUfragPwdLines(const SessionDescriptionInterface* current_desc,
832 std::string *sdp) {
833 const cricket::SessionDescription* desc = current_desc->description();
834 EXPECT_TRUE(current_desc->ToString(sdp));
835
836 const cricket::ContentInfos& contents = desc->contents();
837 cricket::ContentInfos::const_iterator it = contents.begin();
838 // Replace ufrag and pwd lines with empty strings.
839 for (; it != contents.end(); ++it) {
840 const cricket::TransportDescription* transport_desc =
841 desc->GetTransportDescriptionByName(it->name);
842 std::string ufrag_line = "a=ice-ufrag:" + transport_desc->ice_ufrag
843 + "\r\n";
844 std::string pwd_line = "a=ice-pwd:" + transport_desc->ice_pwd
845 + "\r\n";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000846 rtc::replace_substrs(ufrag_line.c_str(), ufrag_line.length(),
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000847 "", 0,
848 sdp);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000849 rtc::replace_substrs(pwd_line.c_str(), pwd_line.length(),
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +0000850 "", 0,
851 sdp);
852 }
853 }
854
deadbeef0ed85b22016-02-23 17:24:52 -0800855 void SetIceUfragPwd(SessionDescriptionInterface* current_desc,
856 const std::string& ufrag,
857 const std::string& pwd) {
858 cricket::SessionDescription* desc = current_desc->description();
859 for (TransportInfo& transport_info : desc->transport_infos()) {
860 cricket::TransportDescription& transport_desc =
861 transport_info.description;
862 transport_desc.ice_ufrag = ufrag;
863 transport_desc.ice_pwd = pwd;
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +0000864 }
865 }
866
deadbeef0ed85b22016-02-23 17:24:52 -0800867 // Sets ufrag/pwd for specified |media_type|.
868 void SetIceUfragPwd(SessionDescriptionInterface* current_desc,
869 cricket::MediaType media_type,
870 const std::string& ufrag,
871 const std::string& pwd) {
872 cricket::SessionDescription* desc = current_desc->description();
873 const cricket::ContentInfo* cinfo =
874 cricket::GetFirstMediaContent(desc->contents(), media_type);
875 TransportInfo* transport_info = desc->GetTransportInfoByName(cinfo->name);
876 cricket::TransportDescription* transport_desc =
877 &transport_info->description;
878 transport_desc->ice_ufrag = ufrag;
879 transport_desc->ice_pwd = pwd;
880 }
881
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000882 // Creates a remote offer and and applies it as a remote description,
883 // creates a local answer and applies is as a local description.
deadbeefab9b2d12015-10-14 11:33:11 -0700884 // Call SendAudioVideoStreamX() before this function
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000885 // to decide which local and remote streams to create.
886 void CreateAndSetRemoteOfferAndLocalAnswer() {
887 SessionDescriptionInterface* offer = CreateRemoteOffer();
888 SetRemoteDescriptionWithoutError(offer);
htaa2a49d92016-03-04 02:51:39 -0800889 SessionDescriptionInterface* answer = CreateAnswer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000890 SetLocalDescriptionWithoutError(answer);
891 }
892 void SetLocalDescriptionWithoutError(SessionDescriptionInterface* desc) {
893 EXPECT_TRUE(session_->SetLocalDescription(desc, NULL));
deadbeefcbecd352015-09-23 11:50:27 -0700894 session_->MaybeStartGathering();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000895 }
896 void SetLocalDescriptionExpectState(SessionDescriptionInterface* desc,
deadbeefd59daf82015-10-14 15:02:44 -0700897 WebRtcSession::State expected_state) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000898 SetLocalDescriptionWithoutError(desc);
899 EXPECT_EQ(expected_state, session_->state());
900 }
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000901 void SetLocalDescriptionExpectError(const std::string& action,
902 const std::string& expected_error,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000903 SessionDescriptionInterface* desc) {
904 std::string error;
905 EXPECT_FALSE(session_->SetLocalDescription(desc, &error));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000906 std::string sdp_type = "local ";
907 sdp_type.append(action);
908 EXPECT_NE(std::string::npos, error.find(sdp_type));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000909 EXPECT_NE(std::string::npos, error.find(expected_error));
910 }
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000911 void SetLocalDescriptionOfferExpectError(const std::string& expected_error,
912 SessionDescriptionInterface* desc) {
913 SetLocalDescriptionExpectError(SessionDescriptionInterface::kOffer,
914 expected_error, desc);
915 }
916 void SetLocalDescriptionAnswerExpectError(const std::string& expected_error,
917 SessionDescriptionInterface* desc) {
918 SetLocalDescriptionExpectError(SessionDescriptionInterface::kAnswer,
919 expected_error, desc);
920 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000921 void SetRemoteDescriptionWithoutError(SessionDescriptionInterface* desc) {
922 EXPECT_TRUE(session_->SetRemoteDescription(desc, NULL));
923 }
924 void SetRemoteDescriptionExpectState(SessionDescriptionInterface* desc,
deadbeefd59daf82015-10-14 15:02:44 -0700925 WebRtcSession::State expected_state) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000926 SetRemoteDescriptionWithoutError(desc);
927 EXPECT_EQ(expected_state, session_->state());
928 }
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000929 void SetRemoteDescriptionExpectError(const std::string& action,
930 const std::string& expected_error,
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000931 SessionDescriptionInterface* desc) {
932 std::string error;
933 EXPECT_FALSE(session_->SetRemoteDescription(desc, &error));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000934 std::string sdp_type = "remote ";
935 sdp_type.append(action);
936 EXPECT_NE(std::string::npos, error.find(sdp_type));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000937 EXPECT_NE(std::string::npos, error.find(expected_error));
938 }
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +0000939 void SetRemoteDescriptionOfferExpectError(
940 const std::string& expected_error, SessionDescriptionInterface* desc) {
941 SetRemoteDescriptionExpectError(SessionDescriptionInterface::kOffer,
942 expected_error, desc);
943 }
944 void SetRemoteDescriptionPranswerExpectError(
945 const std::string& expected_error, SessionDescriptionInterface* desc) {
946 SetRemoteDescriptionExpectError(SessionDescriptionInterface::kPrAnswer,
947 expected_error, desc);
948 }
949 void SetRemoteDescriptionAnswerExpectError(
950 const std::string& expected_error, SessionDescriptionInterface* desc) {
951 SetRemoteDescriptionExpectError(SessionDescriptionInterface::kAnswer,
952 expected_error, desc);
953 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000954
955 void CreateCryptoOfferAndNonCryptoAnswer(SessionDescriptionInterface** offer,
956 SessionDescriptionInterface** nocrypto_answer) {
957 // Create a SDP without Crypto.
958 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +0000959 options.recv_video = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000960 options.bundle_enabled = true;
961 *offer = CreateRemoteOffer(options, cricket::SEC_ENABLED);
962 ASSERT_TRUE(*offer != NULL);
963 VerifyCryptoParams((*offer)->description());
964
965 *nocrypto_answer = CreateRemoteAnswer(*offer, options,
966 cricket::SEC_DISABLED);
967 EXPECT_TRUE(*nocrypto_answer != NULL);
968 }
969
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000970 void CreateDtlsOfferAndNonDtlsAnswer(SessionDescriptionInterface** offer,
971 SessionDescriptionInterface** nodtls_answer) {
972 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +0000973 options.recv_video = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000974 options.bundle_enabled = true;
975
kwibergd1fe2812016-04-27 06:47:29 -0700976 std::unique_ptr<SessionDescriptionInterface> temp_offer(
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +0000977 CreateRemoteOffer(options, cricket::SEC_ENABLED));
978
979 *nodtls_answer =
980 CreateRemoteAnswer(temp_offer.get(), options, cricket::SEC_ENABLED);
981 EXPECT_TRUE(*nodtls_answer != NULL);
982 VerifyFingerprintStatus((*nodtls_answer)->description(), false);
983 VerifyCryptoParams((*nodtls_answer)->description());
984
985 SetFactoryDtlsSrtp();
986 *offer = CreateRemoteOffer(options, cricket::SEC_ENABLED);
987 ASSERT_TRUE(*offer != NULL);
988 VerifyFingerprintStatus((*offer)->description(), true);
989 VerifyCryptoParams((*offer)->description());
990 }
991
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000992 JsepSessionDescription* CreateRemoteOfferWithVersion(
993 cricket::MediaSessionOptions options,
994 cricket::SecurePolicy secure_policy,
995 const std::string& session_version,
996 const SessionDescriptionInterface* current_desc) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000997 std::string session_id = rtc::ToString(rtc::CreateRandomId64());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000998 const cricket::SessionDescription* cricket_desc = NULL;
999 if (current_desc) {
1000 cricket_desc = current_desc->description();
1001 session_id = current_desc->session_id();
1002 }
1003
1004 desc_factory_->set_secure(secure_policy);
1005 JsepSessionDescription* offer(
1006 new JsepSessionDescription(JsepSessionDescription::kOffer));
1007 if (!offer->Initialize(desc_factory_->CreateOffer(options, cricket_desc),
1008 session_id, session_version)) {
1009 delete offer;
1010 offer = NULL;
1011 }
1012 return offer;
1013 }
1014 JsepSessionDescription* CreateRemoteOffer(
1015 cricket::MediaSessionOptions options) {
1016 return CreateRemoteOfferWithVersion(options, cricket::SEC_ENABLED,
1017 kSessionVersion, NULL);
1018 }
1019 JsepSessionDescription* CreateRemoteOffer(
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001020 cricket::MediaSessionOptions options, cricket::SecurePolicy sdes_policy) {
1021 return CreateRemoteOfferWithVersion(
1022 options, sdes_policy, kSessionVersion, NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001023 }
1024 JsepSessionDescription* CreateRemoteOffer(
1025 cricket::MediaSessionOptions options,
1026 const SessionDescriptionInterface* current_desc) {
1027 return CreateRemoteOfferWithVersion(options, cricket::SEC_ENABLED,
1028 kSessionVersion, current_desc);
1029 }
1030
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001031 JsepSessionDescription* CreateRemoteOfferWithSctpPort(
1032 const char* sctp_stream_name, int new_port,
1033 cricket::MediaSessionOptions options) {
1034 options.data_channel_type = cricket::DCT_SCTP;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001035 options.AddSendStream(cricket::MEDIA_TYPE_DATA, "datachannel",
1036 sctp_stream_name);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001037 return ChangeSDPSctpPort(new_port, CreateRemoteOffer(options));
1038 }
1039
1040 // Takes ownership of offer_basis (and deletes it).
1041 JsepSessionDescription* ChangeSDPSctpPort(
1042 int new_port, webrtc::SessionDescriptionInterface *offer_basis) {
1043 // Stringify the input SDP, swap the 5000 for 'new_port' and create a new
1044 // SessionDescription from the mutated string.
1045 const char* default_port_str = "5000";
1046 char new_port_str[16];
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001047 rtc::sprintfn(new_port_str, sizeof(new_port_str), "%d", new_port);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001048 std::string offer_str;
1049 offer_basis->ToString(&offer_str);
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001050 rtc::replace_substrs(default_port_str, strlen(default_port_str),
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00001051 new_port_str, strlen(new_port_str),
1052 &offer_str);
1053 JsepSessionDescription* offer = new JsepSessionDescription(
1054 offer_basis->type());
1055 delete offer_basis;
1056 offer->Initialize(offer_str, NULL);
1057 return offer;
1058 }
1059
deadbeefab9b2d12015-10-14 11:33:11 -07001060 // Create a remote offer. Call SendAudioVideoStreamX()
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001061 // before this function to decide which streams to create.
1062 JsepSessionDescription* CreateRemoteOffer() {
1063 cricket::MediaSessionOptions options;
htaa2a49d92016-03-04 02:51:39 -08001064 GetOptionsForAnswer(&options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001065 return CreateRemoteOffer(options, session_->remote_description());
1066 }
1067
1068 JsepSessionDescription* CreateRemoteAnswer(
1069 const SessionDescriptionInterface* offer,
1070 cricket::MediaSessionOptions options,
1071 cricket::SecurePolicy policy) {
1072 desc_factory_->set_secure(policy);
1073 const std::string session_id =
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001074 rtc::ToString(rtc::CreateRandomId64());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001075 JsepSessionDescription* answer(
1076 new JsepSessionDescription(JsepSessionDescription::kAnswer));
1077 if (!answer->Initialize(desc_factory_->CreateAnswer(offer->description(),
1078 options, NULL),
1079 session_id, kSessionVersion)) {
1080 delete answer;
1081 answer = NULL;
1082 }
1083 return answer;
1084 }
1085
1086 JsepSessionDescription* CreateRemoteAnswer(
1087 const SessionDescriptionInterface* offer,
1088 cricket::MediaSessionOptions options) {
1089 return CreateRemoteAnswer(offer, options, cricket::SEC_REQUIRED);
1090 }
1091
deadbeefab9b2d12015-10-14 11:33:11 -07001092 // Creates an answer session description.
1093 // Call SendAudioVideoStreamX() before this function
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001094 // to decide which streams to create.
1095 JsepSessionDescription* CreateRemoteAnswer(
1096 const SessionDescriptionInterface* offer) {
1097 cricket::MediaSessionOptions options;
htaa2a49d92016-03-04 02:51:39 -08001098 GetOptionsForAnswer(&options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001099 return CreateRemoteAnswer(offer, options, cricket::SEC_REQUIRED);
1100 }
1101
1102 void TestSessionCandidatesWithBundleRtcpMux(bool bundle, bool rtcp_mux) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001103 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001104 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07001105 SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001106
1107 PeerConnectionInterface::RTCOfferAnswerOptions options;
1108 options.use_rtp_mux = bundle;
1109
1110 SessionDescriptionInterface* offer = CreateOffer(options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001111 // SetLocalDescription and SetRemoteDescriptions takes ownership of offer
1112 // and answer.
1113 SetLocalDescriptionWithoutError(offer);
1114
kwibergd1fe2812016-04-27 06:47:29 -07001115 std::unique_ptr<SessionDescriptionInterface> answer(
henrike@webrtc.org723d6832013-07-12 16:04:50 +00001116 CreateRemoteAnswer(session_->local_description()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001117 std::string sdp;
1118 EXPECT_TRUE(answer->ToString(&sdp));
1119
1120 size_t expected_candidate_num = 2;
1121 if (!rtcp_mux) {
1122 // If rtcp_mux is enabled we should expect 4 candidates - host and srflex
1123 // for rtp and rtcp.
1124 expected_candidate_num = 4;
1125 // Disable rtcp-mux from the answer
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001126 const std::string kRtcpMux = "a=rtcp-mux";
1127 const std::string kXRtcpMux = "a=xrtcp-mux";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001128 rtc::replace_substrs(kRtcpMux.c_str(), kRtcpMux.length(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001129 kXRtcpMux.c_str(), kXRtcpMux.length(),
1130 &sdp);
1131 }
1132
1133 SessionDescriptionInterface* new_answer = CreateSessionDescription(
1134 JsepSessionDescription::kAnswer, sdp, NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001135
1136 // SetRemoteDescription to enable rtcp mux.
henrike@webrtc.org723d6832013-07-12 16:04:50 +00001137 SetRemoteDescriptionWithoutError(new_answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001138 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1139 EXPECT_EQ(expected_candidate_num, observer_.mline_0_candidates_.size());
deadbeefcbecd352015-09-23 11:50:27 -07001140 if (bundle) {
1141 EXPECT_EQ(0, observer_.mline_1_candidates_.size());
1142 } else {
1143 EXPECT_EQ(expected_candidate_num, observer_.mline_1_candidates_.size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001144 }
1145 }
1146 // Tests that we can only send DTMF when the dtmf codec is supported.
1147 void TestCanInsertDtmf(bool can) {
1148 if (can) {
1149 InitWithDtmfCodec();
1150 } else {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001151 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001152 }
deadbeefab9b2d12015-10-14 11:33:11 -07001153 SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001154 CreateAndSetRemoteOfferAndLocalAnswer();
1155 EXPECT_FALSE(session_->CanInsertDtmf(""));
1156 EXPECT_EQ(can, session_->CanInsertDtmf(kAudioTrack1));
1157 }
1158
zhihuang3a334652016-05-05 18:37:49 -07001159 bool ContainsVideoCodecWithName(const SessionDescriptionInterface* desc,
1160 const std::string& codec_name) {
1161 for (const auto& content : desc->description()->contents()) {
1162 if (static_cast<cricket::MediaContentDescription*>(content.description)
1163 ->type() == cricket::MEDIA_TYPE_VIDEO) {
1164 const auto* mdesc =
1165 static_cast<cricket::VideoContentDescription*>(content.description);
1166 for (const auto& codec : mdesc->codecs()) {
1167 if (codec.name == codec_name) {
1168 return true;
1169 }
1170 }
1171 }
1172 }
1173 return false;
1174 }
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001175 // Helper class to configure loopback network and verify Best
1176 // Connection using right IP protocol for TestLoopbackCall
1177 // method. LoopbackNetworkManager applies firewall rules to block
1178 // all ping traffic once ICE completed, and remove them to observe
1179 // ICE reconnected again. This LoopbackNetworkConfiguration struct
1180 // verifies the best connection is using the right IP protocol after
1181 // initial ICE convergences.
1182
1183 class LoopbackNetworkConfiguration {
deadbeefcbecd352015-09-23 11:50:27 -07001184 public:
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001185 LoopbackNetworkConfiguration()
1186 : test_ipv6_network_(false),
1187 test_extra_ipv4_network_(false),
1188 best_connection_after_initial_ice_converged_(1, 0) {}
1189
1190 // Used to track the expected best connection count in each IP protocol.
1191 struct ExpectedBestConnection {
1192 ExpectedBestConnection(int ipv4_count, int ipv6_count)
1193 : ipv4_count_(ipv4_count),
1194 ipv6_count_(ipv6_count) {}
1195
1196 int ipv4_count_;
1197 int ipv6_count_;
1198 };
1199
1200 bool test_ipv6_network_;
1201 bool test_extra_ipv4_network_;
1202 ExpectedBestConnection best_connection_after_initial_ice_converged_;
1203
1204 void VerifyBestConnectionAfterIceConverge(
jbauchac8869e2015-07-03 01:36:14 -07001205 const rtc::scoped_refptr<FakeMetricsObserver> metrics_observer) const {
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001206 Verify(metrics_observer, best_connection_after_initial_ice_converged_);
1207 }
1208
1209 private:
jbauchac8869e2015-07-03 01:36:14 -07001210 void Verify(const rtc::scoped_refptr<FakeMetricsObserver> metrics_observer,
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001211 const ExpectedBestConnection& expected) const {
1212 EXPECT_EQ(
Guo-wei Shieh3d564c12015-08-19 16:51:15 -07001213 metrics_observer->GetEnumCounter(webrtc::kEnumCounterAddressFamily,
1214 webrtc::kBestConnections_IPv4),
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001215 expected.ipv4_count_);
1216 EXPECT_EQ(
Guo-wei Shieh3d564c12015-08-19 16:51:15 -07001217 metrics_observer->GetEnumCounter(webrtc::kEnumCounterAddressFamily,
1218 webrtc::kBestConnections_IPv6),
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001219 expected.ipv6_count_);
Guo-wei Shieh3d564c12015-08-19 16:51:15 -07001220 // This is used in the loopback call so there is only single host to host
1221 // candidate pair.
1222 EXPECT_EQ(metrics_observer->GetEnumCounter(
1223 webrtc::kEnumCounterIceCandidatePairTypeUdp,
1224 webrtc::kIceCandidatePairHostHost),
Guo-wei Shieh3cc834a2015-09-04 15:52:14 -07001225 0);
1226 EXPECT_EQ(metrics_observer->GetEnumCounter(
1227 webrtc::kEnumCounterIceCandidatePairTypeUdp,
1228 webrtc::kIceCandidatePairHostPublicHostPublic),
Guo-wei Shieh3d564c12015-08-19 16:51:15 -07001229 1);
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001230 }
1231 };
1232
1233 class LoopbackNetworkManager {
1234 public:
1235 LoopbackNetworkManager(WebRtcSessionTest* session,
1236 const LoopbackNetworkConfiguration& config)
1237 : config_(config) {
1238 session->AddInterface(
1239 rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
1240 if (config_.test_extra_ipv4_network_) {
1241 session->AddInterface(
1242 rtc::SocketAddress(kClientAddrHost2, kClientAddrPort));
1243 }
1244 if (config_.test_ipv6_network_) {
1245 session->AddInterface(
1246 rtc::SocketAddress(kClientIPv6AddrHost1, kClientAddrPort));
1247 }
1248 }
1249
1250 void ApplyFirewallRules(rtc::FirewallSocketServer* fss) {
1251 fss->AddRule(false, rtc::FP_ANY, rtc::FD_ANY,
1252 rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
1253 if (config_.test_extra_ipv4_network_) {
1254 fss->AddRule(false, rtc::FP_ANY, rtc::FD_ANY,
1255 rtc::SocketAddress(kClientAddrHost2, kClientAddrPort));
1256 }
1257 if (config_.test_ipv6_network_) {
1258 fss->AddRule(false, rtc::FP_ANY, rtc::FD_ANY,
1259 rtc::SocketAddress(kClientIPv6AddrHost1, kClientAddrPort));
1260 }
1261 }
1262
1263 void ClearRules(rtc::FirewallSocketServer* fss) { fss->ClearRules(); }
1264
1265 private:
1266 LoopbackNetworkConfiguration config_;
1267 };
1268
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001269 // The method sets up a call from the session to itself, in a loopback
1270 // arrangement. It also uses a firewall rule to create a temporary
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00001271 // disconnection, and then a permanent disconnection.
1272 // This code is placed in a method so that it can be invoked
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001273 // by multiple tests with different allocators (e.g. with and without BUNDLE).
1274 // While running the call, this method also checks if the session goes through
1275 // the correct sequence of ICE states when a connection is established,
1276 // broken, and re-established.
1277 // The Connection state should go:
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00001278 // New -> Checking -> (Connected) -> Completed -> Disconnected -> Completed
1279 // -> Failed.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001280 // The Gathering state should go: New -> Gathering -> Completed.
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001281
stefanc1aeaf02015-10-15 07:26:07 -07001282 void SetupLoopbackCall() {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001283 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07001284 SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001285 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001286
1287 EXPECT_EQ(PeerConnectionInterface::kIceGatheringNew,
1288 observer_.ice_gathering_state_);
1289 SetLocalDescriptionWithoutError(offer);
1290 EXPECT_EQ(PeerConnectionInterface::kIceConnectionNew,
1291 observer_.ice_connection_state_);
1292 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceGatheringGathering,
stefanc1aeaf02015-10-15 07:26:07 -07001293 observer_.ice_gathering_state_, kIceCandidatesTimeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001294 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1295 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
stefanc1aeaf02015-10-15 07:26:07 -07001296 observer_.ice_gathering_state_, kIceCandidatesTimeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001297
1298 std::string sdp;
1299 offer->ToString(&sdp);
stefanc1aeaf02015-10-15 07:26:07 -07001300 SessionDescriptionInterface* desc = webrtc::CreateSessionDescription(
1301 JsepSessionDescription::kAnswer, sdp, nullptr);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001302 ASSERT_TRUE(desc != NULL);
1303 SetRemoteDescriptionWithoutError(desc);
1304
1305 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionChecking,
stefanc1aeaf02015-10-15 07:26:07 -07001306 observer_.ice_connection_state_, kIceCandidatesTimeout);
mallinath@webrtc.orgd3dc4242014-03-01 00:05:52 +00001307
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00001308 // The ice connection state is "Connected" too briefly to catch in a test.
1309 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
stefanc1aeaf02015-10-15 07:26:07 -07001310 observer_.ice_connection_state_, kIceCandidatesTimeout);
1311 }
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001312
stefanc1aeaf02015-10-15 07:26:07 -07001313 void TestLoopbackCall(const LoopbackNetworkConfiguration& config) {
1314 LoopbackNetworkManager loopback_network_manager(this, config);
1315 SetupLoopbackCall();
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001316 config.VerifyBestConnectionAfterIceConverge(metrics_observer_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001317 // Adding firewall rule to block ping requests, which should cause
1318 // transport channel failure.
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001319
1320 loopback_network_manager.ApplyFirewallRules(fss_.get());
1321
1322 LOG(LS_INFO) << "Firewall Rules applied";
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001323 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
1324 observer_.ice_connection_state_,
1325 kIceCandidatesTimeout);
1326
jbauchac8869e2015-07-03 01:36:14 -07001327 metrics_observer_->Reset();
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001328
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001329 // Clearing the rules, session should move back to completed state.
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001330 loopback_network_manager.ClearRules(fss_.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001331
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001332 LOG(LS_INFO) << "Firewall Rules cleared";
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00001333 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001334 observer_.ice_connection_state_,
1335 kIceCandidatesTimeout);
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00001336
1337 // Now we block ping requests and wait until the ICE connection transitions
1338 // to the Failed state. This will take at least 30 seconds because it must
1339 // wait for the Port to timeout.
1340 int port_timeout = 30000;
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001341
1342 loopback_network_manager.ApplyFirewallRules(fss_.get());
1343 LOG(LS_INFO) << "Firewall Rules applied again";
jlmiller@webrtc.org804eb462015-02-20 02:20:03 +00001344 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionDisconnected,
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00001345 observer_.ice_connection_state_,
1346 kIceCandidatesTimeout + port_timeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001347 }
1348
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00001349 void TestLoopbackCall() {
1350 LoopbackNetworkConfiguration config;
1351 TestLoopbackCall(config);
1352 }
1353
stefanc1aeaf02015-10-15 07:26:07 -07001354 void TestPacketOptions() {
1355 media_controller_.reset(
1356 new cricket::FakeMediaController(channel_manager_.get(), &fake_call_));
1357 LoopbackNetworkConfiguration config;
1358 LoopbackNetworkManager loopback_network_manager(this, config);
1359
1360 SetupLoopbackCall();
1361
Danil Chapovalov33b01f22016-05-11 19:55:27 +02001362 // Wait for channel to be ready for sending.
1363 EXPECT_TRUE_WAIT(media_engine_->GetVideoChannel(0)->sending(), 100);
stefanc1aeaf02015-10-15 07:26:07 -07001364 uint8_t test_packet[15] = {0};
1365 rtc::PacketOptions options;
1366 options.packet_id = 10;
1367 media_engine_->GetVideoChannel(0)
1368 ->SendRtp(test_packet, sizeof(test_packet), options);
1369
1370 const int kPacketTimeout = 2000;
deadbeef14461d42016-06-15 11:06:57 -07001371 EXPECT_EQ_WAIT(10, fake_call_.last_sent_nonnegative_packet_id(),
1372 kPacketTimeout);
stefanc1aeaf02015-10-15 07:26:07 -07001373 EXPECT_GT(fake_call_.last_sent_packet().send_time_ms, -1);
1374 }
1375
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001376 // Adds CN codecs to FakeMediaEngine and MediaDescriptionFactory.
1377 void AddCNCodecs() {
deadbeef67cf2c12016-04-13 10:07:16 -07001378 const cricket::AudioCodec kCNCodec1(102, "CN", 8000, 0, 1);
1379 const cricket::AudioCodec kCNCodec2(103, "CN", 16000, 0, 1);
wu@webrtc.org364f2042013-11-20 21:49:41 +00001380
1381 // Add kCNCodec for dtmf test.
ossudedfd282016-06-14 07:12:39 -07001382 std::vector<cricket::AudioCodec> codecs =
1383 media_engine_->audio_send_codecs();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001384 codecs.push_back(kCNCodec1);
1385 codecs.push_back(kCNCodec2);
1386 media_engine_->SetAudioCodecs(codecs);
ossu075af922016-06-14 03:29:38 -07001387 desc_factory_->set_audio_codecs(codecs, codecs);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001388 }
1389
1390 bool VerifyNoCNCodecs(const cricket::ContentInfo* content) {
1391 const cricket::ContentDescription* description = content->description;
1392 ASSERT(description != NULL);
1393 const cricket::AudioContentDescription* audio_content_desc =
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00001394 static_cast<const cricket::AudioContentDescription*>(description);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001395 ASSERT(audio_content_desc != NULL);
1396 for (size_t i = 0; i < audio_content_desc->codecs().size(); ++i) {
1397 if (audio_content_desc->codecs()[i].name == "CN")
1398 return false;
1399 }
1400 return true;
1401 }
1402
deadbeefab9b2d12015-10-14 11:33:11 -07001403 void CreateDataChannel() {
deadbeeffc648b62015-10-13 16:42:33 -07001404 webrtc::InternalDataChannelInit dci;
htaa2a49d92016-03-04 02:51:39 -08001405 ASSERT(session_.get());
deadbeefab9b2d12015-10-14 11:33:11 -07001406 dci.reliable = session_->data_channel_type() == cricket::DCT_SCTP;
1407 data_channel_ = DataChannel::Create(
1408 session_.get(), session_->data_channel_type(), "datachannel", dci);
1409 }
1410
1411 void SetLocalDescriptionWithDataChannel() {
1412 CreateDataChannel();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001413 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001414 SetLocalDescriptionWithoutError(offer);
1415 }
1416
wu@webrtc.org91053e72013-08-10 07:18:04 +00001417 void VerifyMultipleAsyncCreateDescription(
Henrik Boström87713d02015-08-25 09:53:21 +02001418 RTCCertificateGenerationMethod cert_gen_method,
1419 CreateSessionDescriptionRequest::Type type) {
1420 InitWithDtls(cert_gen_method);
1421 VerifyMultipleAsyncCreateDescriptionAfterInit(true, type);
1422 }
1423
1424 void VerifyMultipleAsyncCreateDescriptionIdentityGenFailure(
1425 CreateSessionDescriptionRequest::Type type) {
1426 InitWithDtlsIdentityGenFail();
1427 VerifyMultipleAsyncCreateDescriptionAfterInit(false, type);
1428 }
1429
1430 void VerifyMultipleAsyncCreateDescriptionAfterInit(
wu@webrtc.org91053e72013-08-10 07:18:04 +00001431 bool success, CreateSessionDescriptionRequest::Type type) {
henrikg91d6ede2015-09-17 00:24:34 -07001432 RTC_CHECK(session_);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001433 SetFactoryDtlsSrtp();
wu@webrtc.org91053e72013-08-10 07:18:04 +00001434 if (type == CreateSessionDescriptionRequest::kAnswer) {
1435 cricket::MediaSessionOptions options;
kwibergd1fe2812016-04-27 06:47:29 -07001436 std::unique_ptr<JsepSessionDescription> offer(
1437 CreateRemoteOffer(options, cricket::SEC_DISABLED));
wu@webrtc.org91053e72013-08-10 07:18:04 +00001438 ASSERT_TRUE(offer.get() != NULL);
1439 SetRemoteDescriptionWithoutError(offer.release());
1440 }
1441
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001442 PeerConnectionInterface::RTCOfferAnswerOptions options;
deadbeefab9b2d12015-10-14 11:33:11 -07001443 cricket::MediaSessionOptions session_options;
wu@webrtc.org91053e72013-08-10 07:18:04 +00001444 const int kNumber = 3;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001445 rtc::scoped_refptr<WebRtcSessionCreateSDPObserverForTest>
wu@webrtc.org91053e72013-08-10 07:18:04 +00001446 observers[kNumber];
1447 for (int i = 0; i < kNumber; ++i) {
1448 observers[i] = new WebRtcSessionCreateSDPObserverForTest();
1449 if (type == CreateSessionDescriptionRequest::kOffer) {
deadbeefab9b2d12015-10-14 11:33:11 -07001450 session_->CreateOffer(observers[i], options, session_options);
wu@webrtc.org91053e72013-08-10 07:18:04 +00001451 } else {
htaa2a49d92016-03-04 02:51:39 -08001452 session_->CreateAnswer(observers[i], session_options);
wu@webrtc.org91053e72013-08-10 07:18:04 +00001453 }
1454 }
1455
1456 WebRtcSessionCreateSDPObserverForTest::State expected_state =
1457 success ? WebRtcSessionCreateSDPObserverForTest::kSucceeded :
1458 WebRtcSessionCreateSDPObserverForTest::kFailed;
1459
1460 for (int i = 0; i < kNumber; ++i) {
1461 EXPECT_EQ_WAIT(expected_state, observers[i]->state(), 1000);
1462 if (success) {
1463 EXPECT_TRUE(observers[i]->description() != NULL);
1464 } else {
1465 EXPECT_TRUE(observers[i]->description() == NULL);
1466 }
1467 }
1468 }
1469
mallinath@webrtc.org3d81b1b2014-09-09 14:38:10 +00001470 void ConfigureAllocatorWithTurn() {
deadbeef653b8e02015-11-11 12:55:10 -08001471 cricket::RelayServerConfig turn_server(cricket::RELAY_TURN);
mallinath@webrtc.org3d81b1b2014-09-09 14:38:10 +00001472 cricket::RelayCredentials credentials(kTurnUsername, kTurnPassword);
deadbeef653b8e02015-11-11 12:55:10 -08001473 turn_server.credentials = credentials;
1474 turn_server.ports.push_back(
1475 cricket::ProtocolAddress(kTurnUdpIntAddr, cricket::PROTO_UDP, false));
1476 allocator_->AddTurnServer(turn_server);
mallinath@webrtc.org3d81b1b2014-09-09 14:38:10 +00001477 allocator_->set_step_delay(cricket::kMinimumStepDelay);
Peter Thatcher7cbd1882015-09-17 18:54:52 -07001478 allocator_->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP);
mallinath@webrtc.org3d81b1b2014-09-09 14:38:10 +00001479 }
1480
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001481 cricket::FakeMediaEngine* media_engine_;
1482 cricket::FakeDataEngine* data_engine_;
kwibergd1fe2812016-04-27 06:47:29 -07001483 std::unique_ptr<cricket::ChannelManager> channel_manager_;
stefanc1aeaf02015-10-15 07:26:07 -07001484 cricket::FakeCall fake_call_;
kwibergd1fe2812016-04-27 06:47:29 -07001485 std::unique_ptr<webrtc::MediaControllerInterface> media_controller_;
1486 std::unique_ptr<cricket::TransportDescriptionFactory> tdesc_factory_;
1487 std::unique_ptr<cricket::MediaSessionDescriptionFactory> desc_factory_;
1488 std::unique_ptr<rtc::PhysicalSocketServer> pss_;
1489 std::unique_ptr<rtc::VirtualSocketServer> vss_;
1490 std::unique_ptr<rtc::FirewallSocketServer> fss_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001491 rtc::SocketServerScope ss_scope_;
1492 rtc::SocketAddress stun_socket_addr_;
kwibergd1fe2812016-04-27 06:47:29 -07001493 std::unique_ptr<cricket::TestStunServer> stun_server_;
buildbot@webrtc.org41451d42014-05-03 05:39:45 +00001494 cricket::TestTurnServer turn_server_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001495 rtc::FakeNetworkManager network_manager_;
kwibergd1fe2812016-04-27 06:47:29 -07001496 std::unique_ptr<cricket::BasicPortAllocator> allocator_;
wu@webrtc.org97077a32013-10-25 21:18:33 +00001497 PeerConnectionFactoryInterface::Options options_;
htaa2a49d92016-03-04 02:51:39 -08001498 PeerConnectionInterface::RTCConfiguration configuration_;
kwibergd1fe2812016-04-27 06:47:29 -07001499 std::unique_ptr<WebRtcSessionForTest> session_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001500 MockIceObserver observer_;
1501 cricket::FakeVideoMediaChannel* video_channel_;
1502 cricket::FakeVoiceMediaChannel* voice_channel_;
jbauchac8869e2015-07-03 01:36:14 -07001503 rtc::scoped_refptr<FakeMetricsObserver> metrics_observer_;
deadbeefab9b2d12015-10-14 11:33:11 -07001504 // The following flags affect options created for CreateOffer/CreateAnswer.
1505 bool send_stream_1_ = false;
1506 bool send_stream_2_ = false;
1507 bool send_audio_ = false;
1508 bool send_video_ = false;
1509 rtc::scoped_refptr<DataChannel> data_channel_;
1510 // Last values received from data channel creation signal.
1511 std::string last_data_channel_label_;
1512 InternalDataChannelInit last_data_channel_config_;
deadbeef8947a012016-01-21 10:26:38 -08001513 bool session_destroyed_ = false;
jbauchcb560652016-08-04 05:20:32 -07001514 bool with_gcm_ = false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001515};
1516
Henrik Boström87713d02015-08-25 09:53:21 +02001517TEST_P(WebRtcSessionTest, TestInitializeWithDtls) {
1518 InitWithDtls(GetParam());
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001519 // SDES is disabled when DTLS is on.
1520 EXPECT_EQ(cricket::SEC_DISABLED, session_->SdesPolicy());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001521}
1522
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001523TEST_F(WebRtcSessionTest, TestInitializeWithoutDtls) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001524 Init();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001525 // SDES is required if DTLS is off.
1526 EXPECT_EQ(cricket::SEC_REQUIRED, session_->SdesPolicy());
wu@webrtc.org91053e72013-08-10 07:18:04 +00001527}
1528
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001529TEST_F(WebRtcSessionTest, TestSessionCandidates) {
1530 TestSessionCandidatesWithBundleRtcpMux(false, false);
1531}
1532
1533// Below test cases (TestSessionCandidatesWith*) verify the candidates gathered
1534// with rtcp-mux and/or bundle.
1535TEST_F(WebRtcSessionTest, TestSessionCandidatesWithRtcpMux) {
1536 TestSessionCandidatesWithBundleRtcpMux(false, true);
1537}
1538
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001539TEST_F(WebRtcSessionTest, TestSessionCandidatesWithBundleRtcpMux) {
1540 TestSessionCandidatesWithBundleRtcpMux(true, true);
1541}
1542
1543TEST_F(WebRtcSessionTest, TestMultihomeCandidates) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001544 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
1545 AddInterface(rtc::SocketAddress(kClientAddrHost2, kClientAddrPort));
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001546 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07001547 SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001548 InitiateCall();
1549 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
1550 EXPECT_EQ(8u, observer_.mline_0_candidates_.size());
1551 EXPECT_EQ(8u, observer_.mline_1_candidates_.size());
1552}
1553
deadbeeff5f03e82016-06-06 11:16:06 -07001554TEST_F(WebRtcSessionTest, TestStunError) {
1555 rtc::ScopedFakeClock clock;
1556
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001557 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
1558 AddInterface(rtc::SocketAddress(kClientAddrHost2, kClientAddrPort));
wu@webrtc.org364f2042013-11-20 21:49:41 +00001559 fss_->AddRule(false,
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001560 rtc::FP_UDP,
1561 rtc::FD_ANY,
1562 rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001563 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07001564 SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001565 InitiateCall();
wu@webrtc.org364f2042013-11-20 21:49:41 +00001566 // Since kClientAddrHost1 is blocked, not expecting stun candidates for it.
deadbeeff5f03e82016-06-06 11:16:06 -07001567 EXPECT_TRUE_SIMULATED_WAIT(observer_.oncandidatesready_, kStunTimeout, clock);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001568 EXPECT_EQ(6u, observer_.mline_0_candidates_.size());
1569 EXPECT_EQ(6u, observer_.mline_1_candidates_.size());
deadbeeff5f03e82016-06-06 11:16:06 -07001570 // Destroy session before scoped fake clock goes out of scope to avoid TSan
1571 // warning.
1572 session_->Close();
1573 session_.reset(nullptr);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001574}
1575
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001576TEST_F(WebRtcSessionTest, SetSdpFailedOnInvalidSdp) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001577 Init();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001578 SessionDescriptionInterface* offer = NULL;
1579 // Since |offer| is NULL, there's no way to tell if it's an offer or answer.
1580 std::string unknown_action;
1581 SetLocalDescriptionExpectError(unknown_action, kInvalidSdp, offer);
1582 SetRemoteDescriptionExpectError(unknown_action, kInvalidSdp, offer);
1583}
1584
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001585// Test creating offers and receive answers and make sure the
1586// media engine creates the expected send and receive streams.
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001587TEST_F(WebRtcSessionTest, TestCreateSdesOfferReceiveSdesAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001588 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07001589 SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001590 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001591 const std::string session_id_orig = offer->session_id();
1592 const std::string session_version_orig = offer->session_version();
1593 SetLocalDescriptionWithoutError(offer);
1594
deadbeefab9b2d12015-10-14 11:33:11 -07001595 SendAudioVideoStream2();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001596 SessionDescriptionInterface* answer =
1597 CreateRemoteAnswer(session_->local_description());
1598 SetRemoteDescriptionWithoutError(answer);
1599
1600 video_channel_ = media_engine_->GetVideoChannel(0);
1601 voice_channel_ = media_engine_->GetVoiceChannel(0);
1602
1603 ASSERT_EQ(1u, video_channel_->recv_streams().size());
1604 EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].id);
1605
1606 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
1607 EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].id);
1608
1609 ASSERT_EQ(1u, video_channel_->send_streams().size());
1610 EXPECT_TRUE(kVideoTrack1 == video_channel_->send_streams()[0].id);
1611 ASSERT_EQ(1u, voice_channel_->send_streams().size());
1612 EXPECT_TRUE(kAudioTrack1 == voice_channel_->send_streams()[0].id);
1613
1614 // Create new offer without send streams.
deadbeefab9b2d12015-10-14 11:33:11 -07001615 SendNothing();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001616 offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001617
1618 // Verify the session id is the same and the session version is
1619 // increased.
1620 EXPECT_EQ(session_id_orig, offer->session_id());
Peter Boström0c4e06b2015-10-07 12:23:21 +02001621 EXPECT_LT(rtc::FromString<uint64_t>(session_version_orig),
1622 rtc::FromString<uint64_t>(offer->session_version()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001623
1624 SetLocalDescriptionWithoutError(offer);
jiayl@webrtc.org7d4891d2014-09-09 21:43:15 +00001625 EXPECT_EQ(0u, video_channel_->send_streams().size());
1626 EXPECT_EQ(0u, voice_channel_->send_streams().size());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001627
deadbeefab9b2d12015-10-14 11:33:11 -07001628 SendAudioVideoStream2();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001629 answer = CreateRemoteAnswer(session_->local_description());
1630 SetRemoteDescriptionWithoutError(answer);
1631
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001632 // Make sure the receive streams have not changed.
1633 ASSERT_EQ(1u, video_channel_->recv_streams().size());
1634 EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].id);
1635 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
1636 EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].id);
1637}
1638
1639// Test receiving offers and creating answers and make sure the
1640// media engine creates the expected send and receive streams.
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001641TEST_F(WebRtcSessionTest, TestReceiveSdesOfferCreateSdesAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001642 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07001643 SendAudioVideoStream2();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001644 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001645 VerifyCryptoParams(offer->description());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001646 SetRemoteDescriptionWithoutError(offer);
1647
deadbeefab9b2d12015-10-14 11:33:11 -07001648 SendAudioVideoStream1();
htaa2a49d92016-03-04 02:51:39 -08001649 SessionDescriptionInterface* answer = CreateAnswer();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001650 VerifyCryptoParams(answer->description());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001651 SetLocalDescriptionWithoutError(answer);
1652
1653 const std::string session_id_orig = answer->session_id();
1654 const std::string session_version_orig = answer->session_version();
1655
1656 video_channel_ = media_engine_->GetVideoChannel(0);
1657 voice_channel_ = media_engine_->GetVoiceChannel(0);
1658
htaa2a49d92016-03-04 02:51:39 -08001659 ASSERT_TRUE(video_channel_);
1660 ASSERT_TRUE(voice_channel_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001661 ASSERT_EQ(1u, video_channel_->recv_streams().size());
1662 EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[0].id);
1663
1664 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
1665 EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[0].id);
1666
1667 ASSERT_EQ(1u, video_channel_->send_streams().size());
1668 EXPECT_TRUE(kVideoTrack1 == video_channel_->send_streams()[0].id);
1669 ASSERT_EQ(1u, voice_channel_->send_streams().size());
1670 EXPECT_TRUE(kAudioTrack1 == voice_channel_->send_streams()[0].id);
1671
deadbeefab9b2d12015-10-14 11:33:11 -07001672 SendAudioVideoStream1And2();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001673 offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001674 SetRemoteDescriptionWithoutError(offer);
1675
1676 // Answer by turning off all send streams.
deadbeefab9b2d12015-10-14 11:33:11 -07001677 SendNothing();
htaa2a49d92016-03-04 02:51:39 -08001678 answer = CreateAnswer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001679
1680 // Verify the session id is the same and the session version is
1681 // increased.
1682 EXPECT_EQ(session_id_orig, answer->session_id());
Peter Boström0c4e06b2015-10-07 12:23:21 +02001683 EXPECT_LT(rtc::FromString<uint64_t>(session_version_orig),
1684 rtc::FromString<uint64_t>(answer->session_version()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001685 SetLocalDescriptionWithoutError(answer);
1686
1687 ASSERT_EQ(2u, video_channel_->recv_streams().size());
1688 EXPECT_TRUE(kVideoTrack1 == video_channel_->recv_streams()[0].id);
1689 EXPECT_TRUE(kVideoTrack2 == video_channel_->recv_streams()[1].id);
1690 ASSERT_EQ(2u, voice_channel_->recv_streams().size());
1691 EXPECT_TRUE(kAudioTrack1 == voice_channel_->recv_streams()[0].id);
1692 EXPECT_TRUE(kAudioTrack2 == voice_channel_->recv_streams()[1].id);
1693
1694 // Make sure we have no send streams.
1695 EXPECT_EQ(0u, video_channel_->send_streams().size());
1696 EXPECT_EQ(0u, voice_channel_->send_streams().size());
1697}
1698
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001699TEST_F(WebRtcSessionTest, SetLocalSdpFailedOnCreateChannel) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001700 Init();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001701 media_engine_->set_fail_create_channel(true);
1702
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001703 SessionDescriptionInterface* offer = CreateOffer();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001704 ASSERT_TRUE(offer != NULL);
1705 // SetRemoteDescription and SetLocalDescription will take the ownership of
1706 // the offer.
1707 SetRemoteDescriptionOfferExpectError(kCreateChannelFailed, offer);
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001708 offer = CreateOffer();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00001709 ASSERT_TRUE(offer != NULL);
1710 SetLocalDescriptionOfferExpectError(kCreateChannelFailed, offer);
1711}
1712
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001713//
1714// Tests for creating/setting SDP under different SDES/DTLS polices:
1715//
1716// --DTLS off and SDES on
1717// TestCreateSdesOfferReceiveSdesAnswer/TestReceiveSdesOfferCreateSdesAnswer:
1718// set local/remote offer/answer with crypto --> success
1719// TestSetNonSdesOfferWhenSdesOn: set local/remote offer without crypto --->
1720// failure
1721// TestSetLocalNonSdesAnswerWhenSdesOn: set local answer without crypto -->
1722// failure
1723// TestSetRemoteNonSdesAnswerWhenSdesOn: set remote answer without crypto -->
1724// failure
1725//
1726// --DTLS on and SDES off
1727// TestCreateDtlsOfferReceiveDtlsAnswer/TestReceiveDtlsOfferCreateDtlsAnswer:
1728// set local/remote offer/answer with DTLS fingerprint --> success
1729// TestReceiveNonDtlsOfferWhenDtlsOn: set local/remote offer without DTLS
1730// fingerprint --> failure
1731// TestSetLocalNonDtlsAnswerWhenDtlsOn: set local answer without fingerprint
1732// --> failure
1733// TestSetRemoteNonDtlsAnswerWhenDtlsOn: set remote answer without fingerprint
1734// --> failure
1735//
1736// --Encryption disabled: DTLS off and SDES off
1737// TestCreateOfferReceiveAnswerWithoutEncryption: set local offer and remote
1738// answer without SDES or DTLS --> success
1739// TestCreateAnswerReceiveOfferWithoutEncryption: set remote offer and local
1740// answer without SDES or DTLS --> success
1741//
1742
1743// Test that we return a failure when applying a remote/local offer that doesn't
1744// have cryptos enabled when DTLS is off.
1745TEST_F(WebRtcSessionTest, TestSetNonSdesOfferWhenSdesOn) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001746 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001747 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001748 options.recv_video = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001749 JsepSessionDescription* offer = CreateRemoteOffer(
1750 options, cricket::SEC_DISABLED);
1751 ASSERT_TRUE(offer != NULL);
1752 VerifyNoCryptoParams(offer->description(), false);
1753 // SetRemoteDescription and SetLocalDescription will take the ownership of
1754 // the offer.
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001755 SetRemoteDescriptionOfferExpectError(kSdpWithoutSdesCrypto, offer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001756 offer = CreateRemoteOffer(options, cricket::SEC_DISABLED);
1757 ASSERT_TRUE(offer != NULL);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001758 SetLocalDescriptionOfferExpectError(kSdpWithoutSdesCrypto, offer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001759}
1760
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001761// Test that we return a failure when applying a local answer that doesn't have
1762// cryptos enabled when DTLS is off.
1763TEST_F(WebRtcSessionTest, TestSetLocalNonSdesAnswerWhenSdesOn) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001764 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001765 SessionDescriptionInterface* offer = NULL;
1766 SessionDescriptionInterface* answer = NULL;
1767 CreateCryptoOfferAndNonCryptoAnswer(&offer, &answer);
1768 // SetRemoteDescription and SetLocalDescription will take the ownership of
1769 // the offer.
1770 SetRemoteDescriptionWithoutError(offer);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001771 SetLocalDescriptionAnswerExpectError(kSdpWithoutSdesCrypto, answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001772}
1773
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001774// Test we will return fail when apply an remote answer that doesn't have
1775// crypto enabled when DTLS is off.
1776TEST_F(WebRtcSessionTest, TestSetRemoteNonSdesAnswerWhenSdesOn) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00001777 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001778 SessionDescriptionInterface* offer = NULL;
1779 SessionDescriptionInterface* answer = NULL;
1780 CreateCryptoOfferAndNonCryptoAnswer(&offer, &answer);
1781 // SetRemoteDescription and SetLocalDescription will take the ownership of
1782 // the offer.
1783 SetLocalDescriptionWithoutError(offer);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001784 SetRemoteDescriptionAnswerExpectError(kSdpWithoutSdesCrypto, answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001785}
1786
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001787// Test that we accept an offer with a DTLS fingerprint when DTLS is on
1788// and that we return an answer with a DTLS fingerprint.
Henrik Boström87713d02015-08-25 09:53:21 +02001789TEST_P(WebRtcSessionTest, TestReceiveDtlsOfferCreateDtlsAnswer) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001790 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
deadbeefab9b2d12015-10-14 11:33:11 -07001791 SendAudioVideoStream1();
Henrik Boström87713d02015-08-25 09:53:21 +02001792 InitWithDtls(GetParam());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001793 SetFactoryDtlsSrtp();
1794 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001795 options.recv_video = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001796 JsepSessionDescription* offer =
1797 CreateRemoteOffer(options, cricket::SEC_DISABLED);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001798 ASSERT_TRUE(offer != NULL);
1799 VerifyFingerprintStatus(offer->description(), true);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001800 VerifyNoCryptoParams(offer->description(), true);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001801
1802 // SetRemoteDescription will take the ownership of the offer.
1803 SetRemoteDescriptionWithoutError(offer);
1804
1805 // Verify that we get a crypto fingerprint in the answer.
htaa2a49d92016-03-04 02:51:39 -08001806 SessionDescriptionInterface* answer = CreateAnswer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001807 ASSERT_TRUE(answer != NULL);
1808 VerifyFingerprintStatus(answer->description(), true);
1809 // Check that we don't have an a=crypto line in the answer.
1810 VerifyNoCryptoParams(answer->description(), true);
1811
1812 // Now set the local description, which should work, even without a=crypto.
1813 SetLocalDescriptionWithoutError(answer);
1814}
1815
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001816// Test that we set a local offer with a DTLS fingerprint when DTLS is on
1817// and then we accept a remote answer with a DTLS fingerprint successfully.
Henrik Boström87713d02015-08-25 09:53:21 +02001818TEST_P(WebRtcSessionTest, TestCreateDtlsOfferReceiveDtlsAnswer) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001819 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
deadbeefab9b2d12015-10-14 11:33:11 -07001820 SendAudioVideoStream1();
Henrik Boström87713d02015-08-25 09:53:21 +02001821 InitWithDtls(GetParam());
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001822 SetFactoryDtlsSrtp();
1823
1824 // Verify that we get a crypto fingerprint in the answer.
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001825 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001826 ASSERT_TRUE(offer != NULL);
1827 VerifyFingerprintStatus(offer->description(), true);
1828 // Check that we don't have an a=crypto line in the offer.
1829 VerifyNoCryptoParams(offer->description(), true);
1830
1831 // Now set the local description, which should work, even without a=crypto.
1832 SetLocalDescriptionWithoutError(offer);
1833
1834 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001835 options.recv_video = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001836 JsepSessionDescription* answer =
1837 CreateRemoteAnswer(offer, options, cricket::SEC_DISABLED);
1838 ASSERT_TRUE(answer != NULL);
1839 VerifyFingerprintStatus(answer->description(), true);
1840 VerifyNoCryptoParams(answer->description(), true);
1841
1842 // SetRemoteDescription will take the ownership of the answer.
1843 SetRemoteDescriptionWithoutError(answer);
1844}
1845
1846// Test that if we support DTLS and the other side didn't offer a fingerprint,
1847// we will fail to set the remote description.
Henrik Boström87713d02015-08-25 09:53:21 +02001848TEST_P(WebRtcSessionTest, TestReceiveNonDtlsOfferWhenDtlsOn) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001849 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
Henrik Boström87713d02015-08-25 09:53:21 +02001850 InitWithDtls(GetParam());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001851 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001852 options.recv_video = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001853 options.bundle_enabled = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001854 JsepSessionDescription* offer = CreateRemoteOffer(
1855 options, cricket::SEC_REQUIRED);
1856 ASSERT_TRUE(offer != NULL);
1857 VerifyFingerprintStatus(offer->description(), false);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001858 VerifyCryptoParams(offer->description());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001859
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001860 // SetRemoteDescription will take the ownership of the offer.
1861 SetRemoteDescriptionOfferExpectError(
1862 kSdpWithoutDtlsFingerprint, offer);
1863
1864 offer = CreateRemoteOffer(options, cricket::SEC_REQUIRED);
1865 // SetLocalDescription will take the ownership of the offer.
1866 SetLocalDescriptionOfferExpectError(
1867 kSdpWithoutDtlsFingerprint, offer);
1868}
1869
1870// Test that we return a failure when applying a local answer that doesn't have
1871// a DTLS fingerprint when DTLS is required.
Henrik Boström87713d02015-08-25 09:53:21 +02001872TEST_P(WebRtcSessionTest, TestSetLocalNonDtlsAnswerWhenDtlsOn) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001873 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
Henrik Boström87713d02015-08-25 09:53:21 +02001874 InitWithDtls(GetParam());
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001875 SessionDescriptionInterface* offer = NULL;
1876 SessionDescriptionInterface* answer = NULL;
1877 CreateDtlsOfferAndNonDtlsAnswer(&offer, &answer);
1878
1879 // SetRemoteDescription and SetLocalDescription will take the ownership of
1880 // the offer and answer.
1881 SetRemoteDescriptionWithoutError(offer);
1882 SetLocalDescriptionAnswerExpectError(
1883 kSdpWithoutDtlsFingerprint, answer);
1884}
1885
1886// Test that we return a failure when applying a remote answer that doesn't have
1887// a DTLS fingerprint when DTLS is required.
Henrik Boström87713d02015-08-25 09:53:21 +02001888TEST_P(WebRtcSessionTest, TestSetRemoteNonDtlsAnswerWhenDtlsOn) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00001889 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
Henrik Boström87713d02015-08-25 09:53:21 +02001890 InitWithDtls(GetParam());
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001891 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001892 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001893 options.recv_video = true;
kwibergd1fe2812016-04-27 06:47:29 -07001894 std::unique_ptr<SessionDescriptionInterface> temp_offer(
deadbeefcbecd352015-09-23 11:50:27 -07001895 CreateRemoteOffer(options, cricket::SEC_ENABLED));
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001896 JsepSessionDescription* answer =
deadbeefcbecd352015-09-23 11:50:27 -07001897 CreateRemoteAnswer(temp_offer.get(), options, cricket::SEC_ENABLED);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001898
1899 // SetRemoteDescription and SetLocalDescription will take the ownership of
1900 // the offer and answer.
1901 SetLocalDescriptionWithoutError(offer);
1902 SetRemoteDescriptionAnswerExpectError(
1903 kSdpWithoutDtlsFingerprint, answer);
1904}
1905
1906// Test that we create a local offer without SDES or DTLS and accept a remote
1907// answer without SDES or DTLS when encryption is disabled.
Henrik Boström87713d02015-08-25 09:53:21 +02001908TEST_P(WebRtcSessionTest, TestCreateOfferReceiveAnswerWithoutEncryption) {
deadbeefab9b2d12015-10-14 11:33:11 -07001909 SendAudioVideoStream1();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001910 options_.disable_encryption = true;
Henrik Boström87713d02015-08-25 09:53:21 +02001911 InitWithDtls(GetParam());
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001912
1913 // Verify that we get a crypto fingerprint in the answer.
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00001914 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001915 ASSERT_TRUE(offer != NULL);
1916 VerifyFingerprintStatus(offer->description(), false);
1917 // Check that we don't have an a=crypto line in the offer.
1918 VerifyNoCryptoParams(offer->description(), false);
1919
1920 // Now set the local description, which should work, even without a=crypto.
1921 SetLocalDescriptionWithoutError(offer);
1922
1923 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001924 options.recv_video = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001925 JsepSessionDescription* answer =
1926 CreateRemoteAnswer(offer, options, cricket::SEC_DISABLED);
1927 ASSERT_TRUE(answer != NULL);
1928 VerifyFingerprintStatus(answer->description(), false);
1929 VerifyNoCryptoParams(answer->description(), false);
1930
1931 // SetRemoteDescription will take the ownership of the answer.
1932 SetRemoteDescriptionWithoutError(answer);
1933}
1934
1935// Test that we create a local answer without SDES or DTLS and accept a remote
1936// offer without SDES or DTLS when encryption is disabled.
Henrik Boström87713d02015-08-25 09:53:21 +02001937TEST_P(WebRtcSessionTest, TestCreateAnswerReceiveOfferWithoutEncryption) {
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001938 options_.disable_encryption = true;
Henrik Boström87713d02015-08-25 09:53:21 +02001939 InitWithDtls(GetParam());
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001940
1941 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00001942 options.recv_video = true;
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001943 JsepSessionDescription* offer =
1944 CreateRemoteOffer(options, cricket::SEC_DISABLED);
1945 ASSERT_TRUE(offer != NULL);
1946 VerifyFingerprintStatus(offer->description(), false);
1947 VerifyNoCryptoParams(offer->description(), false);
1948
1949 // SetRemoteDescription will take the ownership of the offer.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001950 SetRemoteDescriptionWithoutError(offer);
1951
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001952 // Verify that we get a crypto fingerprint in the answer.
htaa2a49d92016-03-04 02:51:39 -08001953 SessionDescriptionInterface* answer = CreateAnswer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001954 ASSERT_TRUE(answer != NULL);
1955 VerifyFingerprintStatus(answer->description(), false);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001956 // Check that we don't have an a=crypto line in the answer.
1957 VerifyNoCryptoParams(answer->description(), false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001958
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00001959 // Now set the local description, which should work, even without a=crypto.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001960 SetLocalDescriptionWithoutError(answer);
1961}
1962
Taylor Brandstetterf475d362016-01-08 15:35:57 -08001963// Test that we can create and set an answer correctly when different
1964// SSL roles have been negotiated for different transports.
1965// See: https://bugs.chromium.org/p/webrtc/issues/detail?id=4525
1966TEST_P(WebRtcSessionTest, TestCreateAnswerWithDifferentSslRoles) {
1967 SendAudioVideoStream1();
1968 InitWithDtls(GetParam());
1969 SetFactoryDtlsSrtp();
1970
1971 SessionDescriptionInterface* offer = CreateOffer();
1972 SetLocalDescriptionWithoutError(offer);
1973
1974 cricket::MediaSessionOptions options;
1975 options.recv_video = true;
1976
1977 // First, negotiate different SSL roles.
1978 SessionDescriptionInterface* answer =
1979 CreateRemoteAnswer(offer, options, cricket::SEC_DISABLED);
1980 TransportInfo* audio_transport_info =
1981 answer->description()->GetTransportInfoByName("audio");
1982 audio_transport_info->description.connection_role =
1983 cricket::CONNECTIONROLE_ACTIVE;
1984 TransportInfo* video_transport_info =
1985 answer->description()->GetTransportInfoByName("video");
1986 video_transport_info->description.connection_role =
1987 cricket::CONNECTIONROLE_PASSIVE;
1988 SetRemoteDescriptionWithoutError(answer);
1989
1990 // Now create an offer in the reverse direction, and ensure the initial
1991 // offerer responds with an answer with correct SSL roles.
1992 offer = CreateRemoteOfferWithVersion(options, cricket::SEC_DISABLED,
1993 kSessionVersion,
1994 session_->remote_description());
1995 SetRemoteDescriptionWithoutError(offer);
1996
htaa2a49d92016-03-04 02:51:39 -08001997 answer = CreateAnswer();
Taylor Brandstetterf475d362016-01-08 15:35:57 -08001998 audio_transport_info = answer->description()->GetTransportInfoByName("audio");
1999 EXPECT_EQ(cricket::CONNECTIONROLE_PASSIVE,
2000 audio_transport_info->description.connection_role);
2001 video_transport_info = answer->description()->GetTransportInfoByName("video");
2002 EXPECT_EQ(cricket::CONNECTIONROLE_ACTIVE,
2003 video_transport_info->description.connection_role);
2004 SetLocalDescriptionWithoutError(answer);
2005
2006 // Lastly, start BUNDLE-ing on "audio", expecting that the "passive" role of
2007 // audio is transferred over to video in the answer that completes the BUNDLE
2008 // negotiation.
2009 options.bundle_enabled = true;
2010 offer = CreateRemoteOfferWithVersion(options, cricket::SEC_DISABLED,
2011 kSessionVersion,
2012 session_->remote_description());
2013 SetRemoteDescriptionWithoutError(offer);
htaa2a49d92016-03-04 02:51:39 -08002014 answer = CreateAnswer();
Taylor Brandstetterf475d362016-01-08 15:35:57 -08002015 audio_transport_info = answer->description()->GetTransportInfoByName("audio");
2016 EXPECT_EQ(cricket::CONNECTIONROLE_PASSIVE,
2017 audio_transport_info->description.connection_role);
2018 video_transport_info = answer->description()->GetTransportInfoByName("video");
2019 EXPECT_EQ(cricket::CONNECTIONROLE_PASSIVE,
2020 video_transport_info->description.connection_role);
2021 SetLocalDescriptionWithoutError(answer);
2022}
2023
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002024TEST_F(WebRtcSessionTest, TestSetLocalOfferTwice) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002025 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07002026 SendNothing();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002027 // SetLocalDescription take ownership of offer.
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002028 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002029 SetLocalDescriptionWithoutError(offer);
2030
2031 // SetLocalDescription take ownership of offer.
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002032 SessionDescriptionInterface* offer2 = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002033 SetLocalDescriptionWithoutError(offer2);
2034}
2035
2036TEST_F(WebRtcSessionTest, TestSetRemoteOfferTwice) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002037 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07002038 SendNothing();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002039 // SetLocalDescription take ownership of offer.
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002040 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002041 SetRemoteDescriptionWithoutError(offer);
2042
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002043 SessionDescriptionInterface* offer2 = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002044 SetRemoteDescriptionWithoutError(offer2);
2045}
2046
2047TEST_F(WebRtcSessionTest, TestSetLocalAndRemoteOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002048 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07002049 SendNothing();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002050 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002051 SetLocalDescriptionWithoutError(offer);
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002052 offer = CreateOffer();
deadbeefd59daf82015-10-14 15:02:44 -07002053 SetRemoteDescriptionOfferExpectError("Called in wrong state: STATE_SENTOFFER",
2054 offer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002055}
2056
2057TEST_F(WebRtcSessionTest, TestSetRemoteAndLocalOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002058 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07002059 SendNothing();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002060 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002061 SetRemoteDescriptionWithoutError(offer);
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002062 offer = CreateOffer();
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00002063 SetLocalDescriptionOfferExpectError(
deadbeefd59daf82015-10-14 15:02:44 -07002064 "Called in wrong state: STATE_RECEIVEDOFFER", offer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002065}
2066
2067TEST_F(WebRtcSessionTest, TestSetLocalPrAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002068 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07002069 SendNothing();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002070 SessionDescriptionInterface* offer = CreateRemoteOffer();
deadbeefd59daf82015-10-14 15:02:44 -07002071 SetRemoteDescriptionExpectState(offer, WebRtcSession::STATE_RECEIVEDOFFER);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002072
htaa2a49d92016-03-04 02:51:39 -08002073 JsepSessionDescription* pranswer =
2074 static_cast<JsepSessionDescription*>(CreateAnswer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002075 pranswer->set_type(SessionDescriptionInterface::kPrAnswer);
deadbeefd59daf82015-10-14 15:02:44 -07002076 SetLocalDescriptionExpectState(pranswer, WebRtcSession::STATE_SENTPRANSWER);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002077
deadbeefab9b2d12015-10-14 11:33:11 -07002078 SendAudioVideoStream1();
htaa2a49d92016-03-04 02:51:39 -08002079 JsepSessionDescription* pranswer2 =
2080 static_cast<JsepSessionDescription*>(CreateAnswer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002081 pranswer2->set_type(SessionDescriptionInterface::kPrAnswer);
2082
deadbeefd59daf82015-10-14 15:02:44 -07002083 SetLocalDescriptionExpectState(pranswer2, WebRtcSession::STATE_SENTPRANSWER);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002084
deadbeefab9b2d12015-10-14 11:33:11 -07002085 SendAudioVideoStream2();
htaa2a49d92016-03-04 02:51:39 -08002086 SessionDescriptionInterface* answer = CreateAnswer();
deadbeefd59daf82015-10-14 15:02:44 -07002087 SetLocalDescriptionExpectState(answer, WebRtcSession::STATE_INPROGRESS);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002088}
2089
2090TEST_F(WebRtcSessionTest, TestSetRemotePrAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002091 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07002092 SendNothing();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002093 SessionDescriptionInterface* offer = CreateOffer();
deadbeefd59daf82015-10-14 15:02:44 -07002094 SetLocalDescriptionExpectState(offer, WebRtcSession::STATE_SENTOFFER);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002095
2096 JsepSessionDescription* pranswer =
2097 CreateRemoteAnswer(session_->local_description());
2098 pranswer->set_type(SessionDescriptionInterface::kPrAnswer);
2099
2100 SetRemoteDescriptionExpectState(pranswer,
deadbeefd59daf82015-10-14 15:02:44 -07002101 WebRtcSession::STATE_RECEIVEDPRANSWER);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002102
deadbeefab9b2d12015-10-14 11:33:11 -07002103 SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002104 JsepSessionDescription* pranswer2 =
2105 CreateRemoteAnswer(session_->local_description());
2106 pranswer2->set_type(SessionDescriptionInterface::kPrAnswer);
2107
2108 SetRemoteDescriptionExpectState(pranswer2,
deadbeefd59daf82015-10-14 15:02:44 -07002109 WebRtcSession::STATE_RECEIVEDPRANSWER);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002110
deadbeefab9b2d12015-10-14 11:33:11 -07002111 SendAudioVideoStream2();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002112 SessionDescriptionInterface* answer =
2113 CreateRemoteAnswer(session_->local_description());
deadbeefd59daf82015-10-14 15:02:44 -07002114 SetRemoteDescriptionExpectState(answer, WebRtcSession::STATE_INPROGRESS);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002115}
2116
2117TEST_F(WebRtcSessionTest, TestSetLocalAnswerWithoutOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002118 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07002119 SendNothing();
kwibergd1fe2812016-04-27 06:47:29 -07002120 std::unique_ptr<SessionDescriptionInterface> offer(CreateOffer());
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002121
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002122 SessionDescriptionInterface* answer =
2123 CreateRemoteAnswer(offer.get());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00002124 SetLocalDescriptionAnswerExpectError("Called in wrong state: STATE_INIT",
2125 answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002126}
2127
2128TEST_F(WebRtcSessionTest, TestSetRemoteAnswerWithoutOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002129 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07002130 SendNothing();
kwibergd1fe2812016-04-27 06:47:29 -07002131 std::unique_ptr<SessionDescriptionInterface> offer(CreateOffer());
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002132
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002133 SessionDescriptionInterface* answer =
2134 CreateRemoteAnswer(offer.get());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00002135 SetRemoteDescriptionAnswerExpectError(
2136 "Called in wrong state: STATE_INIT", answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002137}
2138
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002139// Tests that the remote candidates are added and removed successfully.
2140TEST_F(WebRtcSessionTest, TestAddAndRemoveRemoteCandidates) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002141 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07002142 SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002143
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002144 cricket::Candidate candidate(1, "udp", rtc::SocketAddress("1.1.1.1", 5000), 0,
2145 "", "", "host", 0, "");
2146 candidate.set_transport_name("audio");
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002147 JsepIceCandidate ice_candidate1(kMediaContentName0, 0, candidate);
2148
deadbeefd59daf82015-10-14 15:02:44 -07002149 // Fail since we have not set a remote description.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002150 EXPECT_FALSE(session_->ProcessIceMessage(&ice_candidate1));
2151
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002152 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002153 SetLocalDescriptionWithoutError(offer);
deadbeefd59daf82015-10-14 15:02:44 -07002154
2155 // Fail since we have not set a remote description.
2156 EXPECT_FALSE(session_->ProcessIceMessage(&ice_candidate1));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002157
2158 SessionDescriptionInterface* answer = CreateRemoteAnswer(
2159 session_->local_description());
2160 SetRemoteDescriptionWithoutError(answer);
2161
deadbeefd59daf82015-10-14 15:02:44 -07002162 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate1));
2163 candidate.set_component(2);
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002164 candidate.set_address(rtc::SocketAddress("2.2.2.2", 6000));
deadbeefd59daf82015-10-14 15:02:44 -07002165 JsepIceCandidate ice_candidate2(kMediaContentName0, 0, candidate);
2166 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate2));
2167
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002168 // Verifying the candidates are copied properly from internal vector.
2169 const SessionDescriptionInterface* remote_desc =
2170 session_->remote_description();
2171 ASSERT_TRUE(remote_desc != NULL);
2172 ASSERT_EQ(2u, remote_desc->number_of_mediasections());
2173 const IceCandidateCollection* candidates =
2174 remote_desc->candidates(kMediaContentIndex0);
2175 ASSERT_EQ(2u, candidates->count());
2176 EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
2177 EXPECT_EQ(kMediaContentName0, candidates->at(0)->sdp_mid());
2178 EXPECT_EQ(1, candidates->at(0)->candidate().component());
2179 EXPECT_EQ(2, candidates->at(1)->candidate().component());
2180
mallinath@webrtc.org67ee6b92014-02-03 16:57:16 +00002181 // |ice_candidate3| is identical to |ice_candidate2|. It can be added
2182 // successfully, but the total count of candidates will not increase.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002183 candidate.set_component(2);
2184 JsepIceCandidate ice_candidate3(kMediaContentName0, 0, candidate);
2185 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate3));
mallinath@webrtc.org67ee6b92014-02-03 16:57:16 +00002186 ASSERT_EQ(2u, candidates->count());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002187
2188 JsepIceCandidate bad_ice_candidate("bad content name", 99, candidate);
2189 EXPECT_FALSE(session_->ProcessIceMessage(&bad_ice_candidate));
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002190
2191 // Remove candidate1 and candidate2
2192 std::vector<cricket::Candidate> remote_candidates;
2193 remote_candidates.push_back(ice_candidate1.candidate());
2194 remote_candidates.push_back(ice_candidate2.candidate());
2195 EXPECT_TRUE(session_->RemoveRemoteIceCandidates(remote_candidates));
2196 EXPECT_EQ(0u, candidates->count());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002197}
2198
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002199// Tests that a remote candidate is added to the remote session description and
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002200// that it is retained if the remote session description is changed.
2201TEST_F(WebRtcSessionTest, TestRemoteCandidatesAddedToSessionDescription) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002202 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002203 cricket::Candidate candidate1;
2204 candidate1.set_component(1);
2205 JsepIceCandidate ice_candidate1(kMediaContentName0, kMediaContentIndex0,
2206 candidate1);
deadbeefab9b2d12015-10-14 11:33:11 -07002207 SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002208 CreateAndSetRemoteOfferAndLocalAnswer();
2209
2210 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate1));
2211 const SessionDescriptionInterface* remote_desc =
2212 session_->remote_description();
2213 ASSERT_TRUE(remote_desc != NULL);
2214 ASSERT_EQ(2u, remote_desc->number_of_mediasections());
2215 const IceCandidateCollection* candidates =
2216 remote_desc->candidates(kMediaContentIndex0);
2217 ASSERT_EQ(1u, candidates->count());
2218 EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
2219
2220 // Update the RemoteSessionDescription with a new session description and
2221 // a candidate and check that the new remote session description contains both
2222 // candidates.
2223 SessionDescriptionInterface* offer = CreateRemoteOffer();
2224 cricket::Candidate candidate2;
2225 JsepIceCandidate ice_candidate2(kMediaContentName0, kMediaContentIndex0,
2226 candidate2);
2227 EXPECT_TRUE(offer->AddCandidate(&ice_candidate2));
2228 SetRemoteDescriptionWithoutError(offer);
2229
2230 remote_desc = session_->remote_description();
2231 ASSERT_TRUE(remote_desc != NULL);
2232 ASSERT_EQ(2u, remote_desc->number_of_mediasections());
2233 candidates = remote_desc->candidates(kMediaContentIndex0);
2234 ASSERT_EQ(2u, candidates->count());
2235 EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
2236 // Username and password have be updated with the TransportInfo of the
2237 // SessionDescription, won't be equal to the original one.
2238 candidate2.set_username(candidates->at(0)->candidate().username());
2239 candidate2.set_password(candidates->at(0)->candidate().password());
2240 EXPECT_TRUE(candidate2.IsEquivalent(candidates->at(0)->candidate()));
2241 EXPECT_EQ(kMediaContentIndex0, candidates->at(1)->sdp_mline_index());
2242 // No need to verify the username and password.
2243 candidate1.set_username(candidates->at(1)->candidate().username());
2244 candidate1.set_password(candidates->at(1)->candidate().password());
2245 EXPECT_TRUE(candidate1.IsEquivalent(candidates->at(1)->candidate()));
2246
2247 // Test that the candidate is ignored if we can add the same candidate again.
2248 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate2));
2249}
2250
2251// Test that local candidates are added to the local session description and
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002252// that they are retained if the local session description is changed. And if
2253// continual gathering is enabled, they are removed from the local session
2254// description when the network is down.
2255TEST_F(WebRtcSessionTest,
2256 TestLocalCandidatesAddedAndRemovedIfGatherContinually) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002257 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002258 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07002259 SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002260 CreateAndSetRemoteOfferAndLocalAnswer();
2261
2262 const SessionDescriptionInterface* local_desc = session_->local_description();
2263 const IceCandidateCollection* candidates =
2264 local_desc->candidates(kMediaContentIndex0);
2265 ASSERT_TRUE(candidates != NULL);
2266 EXPECT_EQ(0u, candidates->count());
2267
2268 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
2269
2270 local_desc = session_->local_description();
2271 candidates = local_desc->candidates(kMediaContentIndex0);
2272 ASSERT_TRUE(candidates != NULL);
2273 EXPECT_LT(0u, candidates->count());
2274 candidates = local_desc->candidates(1);
2275 ASSERT_TRUE(candidates != NULL);
deadbeefcbecd352015-09-23 11:50:27 -07002276 EXPECT_EQ(0u, candidates->count());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002277
2278 // Update the session descriptions.
deadbeefab9b2d12015-10-14 11:33:11 -07002279 SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002280 CreateAndSetRemoteOfferAndLocalAnswer();
2281
2282 local_desc = session_->local_description();
2283 candidates = local_desc->candidates(kMediaContentIndex0);
2284 ASSERT_TRUE(candidates != NULL);
2285 EXPECT_LT(0u, candidates->count());
2286 candidates = local_desc->candidates(1);
2287 ASSERT_TRUE(candidates != NULL);
deadbeefcbecd352015-09-23 11:50:27 -07002288 EXPECT_EQ(0u, candidates->count());
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002289
2290 candidates = local_desc->candidates(kMediaContentIndex0);
2291 size_t num_local_candidates = candidates->count();
2292 // Enable Continual Gathering
Honghai Zhang5622c5e2016-07-01 13:59:29 -07002293 cricket::IceConfig config;
2294 config.continual_gathering_policy = cricket::GATHER_CONTINUALLY;
2295 session_->SetIceConfig(config);
Honghai Zhang7fb69db2016-03-14 11:59:18 -07002296 // Bring down the network interface to trigger candidate removals.
2297 RemoveInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
2298 // Verify that all local candidates are removed.
2299 EXPECT_EQ(0, observer_.num_candidates_removed_);
2300 EXPECT_EQ_WAIT(num_local_candidates, observer_.num_candidates_removed_,
2301 kIceCandidatesTimeout);
2302 EXPECT_EQ_WAIT(0u, candidates->count(), kIceCandidatesTimeout);
2303}
2304
2305// Tests that if continual gathering is disabled, local candidates won't be
2306// removed when the interface is turned down.
2307TEST_F(WebRtcSessionTest, TestLocalCandidatesNotRemovedIfNotGatherContinually) {
2308 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
2309 Init();
2310 SendAudioVideoStream1();
2311 CreateAndSetRemoteOfferAndLocalAnswer();
2312
2313 const SessionDescriptionInterface* local_desc = session_->local_description();
2314 const IceCandidateCollection* candidates =
2315 local_desc->candidates(kMediaContentIndex0);
2316 ASSERT_TRUE(candidates != NULL);
2317 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
2318
2319 size_t num_local_candidates = candidates->count();
2320 EXPECT_LT(0u, num_local_candidates);
2321 // By default, Continual Gathering is disabled.
2322 // Bring down the network interface.
2323 RemoveInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
2324 // Verify that the local candidates are not removed.
2325 rtc::Thread::Current()->ProcessMessages(1000);
2326 EXPECT_EQ(0, observer_.num_candidates_removed_);
2327 EXPECT_EQ(num_local_candidates, candidates->count());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002328}
2329
2330// Test that we can set a remote session description with remote candidates.
2331TEST_F(WebRtcSessionTest, TestSetRemoteSessionDescriptionWithCandidates) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002332 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002333
2334 cricket::Candidate candidate1;
2335 candidate1.set_component(1);
2336 JsepIceCandidate ice_candidate(kMediaContentName0, kMediaContentIndex0,
2337 candidate1);
deadbeefab9b2d12015-10-14 11:33:11 -07002338 SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002339 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002340
2341 EXPECT_TRUE(offer->AddCandidate(&ice_candidate));
2342 SetRemoteDescriptionWithoutError(offer);
2343
2344 const SessionDescriptionInterface* remote_desc =
2345 session_->remote_description();
2346 ASSERT_TRUE(remote_desc != NULL);
2347 ASSERT_EQ(2u, remote_desc->number_of_mediasections());
2348 const IceCandidateCollection* candidates =
2349 remote_desc->candidates(kMediaContentIndex0);
2350 ASSERT_EQ(1u, candidates->count());
2351 EXPECT_EQ(kMediaContentIndex0, candidates->at(0)->sdp_mline_index());
2352
htaa2a49d92016-03-04 02:51:39 -08002353 SessionDescriptionInterface* answer = CreateAnswer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002354 SetLocalDescriptionWithoutError(answer);
2355}
2356
2357// Test that offers and answers contains ice candidates when Ice candidates have
2358// been gathered.
2359TEST_F(WebRtcSessionTest, TestSetLocalAndRemoteDescriptionWithCandidates) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002360 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002361 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07002362 SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002363 // Ice is started but candidates are not provided until SetLocalDescription
2364 // is called.
2365 EXPECT_EQ(0u, observer_.mline_0_candidates_.size());
2366 EXPECT_EQ(0u, observer_.mline_1_candidates_.size());
2367 CreateAndSetRemoteOfferAndLocalAnswer();
2368 // Wait until at least one local candidate has been collected.
2369 EXPECT_TRUE_WAIT(0u < observer_.mline_0_candidates_.size(),
2370 kIceCandidatesTimeout);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002371
kwibergd1fe2812016-04-27 06:47:29 -07002372 std::unique_ptr<SessionDescriptionInterface> local_offer(CreateOffer());
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002373
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002374 ASSERT_TRUE(local_offer->candidates(kMediaContentIndex0) != NULL);
2375 EXPECT_LT(0u, local_offer->candidates(kMediaContentIndex0)->count());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002376
2377 SessionDescriptionInterface* remote_offer(CreateRemoteOffer());
2378 SetRemoteDescriptionWithoutError(remote_offer);
htaa2a49d92016-03-04 02:51:39 -08002379 SessionDescriptionInterface* answer = CreateAnswer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002380 ASSERT_TRUE(answer->candidates(kMediaContentIndex0) != NULL);
2381 EXPECT_LT(0u, answer->candidates(kMediaContentIndex0)->count());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002382 SetLocalDescriptionWithoutError(answer);
2383}
2384
2385// Verifies TransportProxy and media channels are created with content names
2386// present in the SessionDescription.
2387TEST_F(WebRtcSessionTest, TestChannelCreationsWithContentNames) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002388 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07002389 SendAudioVideoStream1();
kwibergd1fe2812016-04-27 06:47:29 -07002390 std::unique_ptr<SessionDescriptionInterface> offer(CreateOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002391
2392 // CreateOffer creates session description with the content names "audio" and
deadbeefd59daf82015-10-14 15:02:44 -07002393 // "video". Goal is to modify these content names and verify transport
2394 // channels
2395 // in the WebRtcSession, as channels are created with the content names
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002396 // present in SDP.
2397 std::string sdp;
2398 EXPECT_TRUE(offer->ToString(&sdp));
2399 const std::string kAudioMid = "a=mid:audio";
2400 const std::string kAudioMidReplaceStr = "a=mid:audio_content_name";
2401 const std::string kVideoMid = "a=mid:video";
2402 const std::string kVideoMidReplaceStr = "a=mid:video_content_name";
2403
2404 // Replacing |audio| with |audio_content_name|.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002405 rtc::replace_substrs(kAudioMid.c_str(), kAudioMid.length(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002406 kAudioMidReplaceStr.c_str(),
2407 kAudioMidReplaceStr.length(),
2408 &sdp);
2409 // Replacing |video| with |video_content_name|.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00002410 rtc::replace_substrs(kVideoMid.c_str(), kVideoMid.length(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002411 kVideoMidReplaceStr.c_str(),
2412 kVideoMidReplaceStr.length(),
2413 &sdp);
2414
2415 SessionDescriptionInterface* modified_offer =
2416 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
2417
2418 SetRemoteDescriptionWithoutError(modified_offer);
2419
htaa2a49d92016-03-04 02:51:39 -08002420 SessionDescriptionInterface* answer = CreateAnswer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002421 SetLocalDescriptionWithoutError(answer);
2422
deadbeefcbecd352015-09-23 11:50:27 -07002423 cricket::TransportChannel* voice_transport_channel =
2424 session_->voice_rtp_transport_channel();
2425 EXPECT_TRUE(voice_transport_channel != NULL);
2426 EXPECT_EQ(voice_transport_channel->transport_name(), "audio_content_name");
2427 cricket::TransportChannel* video_transport_channel =
2428 session_->video_rtp_transport_channel();
htaa2a49d92016-03-04 02:51:39 -08002429 ASSERT_TRUE(video_transport_channel != NULL);
deadbeefcbecd352015-09-23 11:50:27 -07002430 EXPECT_EQ(video_transport_channel->transport_name(), "video_content_name");
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002431 EXPECT_TRUE((video_channel_ = media_engine_->GetVideoChannel(0)) != NULL);
2432 EXPECT_TRUE((voice_channel_ = media_engine_->GetVoiceChannel(0)) != NULL);
2433}
2434
2435// Test that an offer contains the correct media content descriptions based on
2436// the send streams when no constraints have been set.
2437TEST_F(WebRtcSessionTest, CreateOfferWithoutConstraintsOrStreams) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002438 Init();
kwibergd1fe2812016-04-27 06:47:29 -07002439 std::unique_ptr<SessionDescriptionInterface> offer(CreateOffer());
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002440
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002441 ASSERT_TRUE(offer != NULL);
2442 const cricket::ContentInfo* content =
2443 cricket::GetFirstAudioContent(offer->description());
2444 EXPECT_TRUE(content != NULL);
2445 content = cricket::GetFirstVideoContent(offer->description());
2446 EXPECT_TRUE(content == NULL);
2447}
2448
2449// Test that an offer contains the correct media content descriptions based on
2450// the send streams when no constraints have been set.
2451TEST_F(WebRtcSessionTest, CreateOfferWithoutConstraints) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002452 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002453 // Test Audio only offer.
deadbeefab9b2d12015-10-14 11:33:11 -07002454 SendAudioOnlyStream2();
kwibergd1fe2812016-04-27 06:47:29 -07002455 std::unique_ptr<SessionDescriptionInterface> offer(CreateOffer());
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002456
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002457 const cricket::ContentInfo* content =
2458 cricket::GetFirstAudioContent(offer->description());
2459 EXPECT_TRUE(content != NULL);
2460 content = cricket::GetFirstVideoContent(offer->description());
2461 EXPECT_TRUE(content == NULL);
2462
2463 // Test Audio / Video offer.
deadbeefab9b2d12015-10-14 11:33:11 -07002464 SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002465 offer.reset(CreateOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002466 content = cricket::GetFirstAudioContent(offer->description());
2467 EXPECT_TRUE(content != NULL);
2468 content = cricket::GetFirstVideoContent(offer->description());
2469 EXPECT_TRUE(content != NULL);
2470}
2471
2472// Test that an offer contains no media content descriptions if
2473// kOfferToReceiveVideo and kOfferToReceiveAudio constraints are set to false.
2474TEST_F(WebRtcSessionTest, CreateOfferWithConstraintsWithoutStreams) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002475 Init();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002476 PeerConnectionInterface::RTCOfferAnswerOptions options;
2477 options.offer_to_receive_audio = 0;
2478 options.offer_to_receive_video = 0;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002479
kwibergd1fe2812016-04-27 06:47:29 -07002480 std::unique_ptr<SessionDescriptionInterface> offer(CreateOffer(options));
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002481
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002482 ASSERT_TRUE(offer != NULL);
2483 const cricket::ContentInfo* content =
2484 cricket::GetFirstAudioContent(offer->description());
2485 EXPECT_TRUE(content == NULL);
2486 content = cricket::GetFirstVideoContent(offer->description());
2487 EXPECT_TRUE(content == NULL);
2488}
2489
2490// Test that an offer contains only audio media content descriptions if
2491// kOfferToReceiveAudio constraints are set to true.
2492TEST_F(WebRtcSessionTest, CreateAudioOnlyOfferWithConstraints) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002493 Init();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002494 PeerConnectionInterface::RTCOfferAnswerOptions options;
2495 options.offer_to_receive_audio =
2496 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
2497
kwibergd1fe2812016-04-27 06:47:29 -07002498 std::unique_ptr<SessionDescriptionInterface> offer(CreateOffer(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002499
2500 const cricket::ContentInfo* content =
2501 cricket::GetFirstAudioContent(offer->description());
2502 EXPECT_TRUE(content != NULL);
2503 content = cricket::GetFirstVideoContent(offer->description());
2504 EXPECT_TRUE(content == NULL);
2505}
2506
2507// Test that an offer contains audio and video media content descriptions if
2508// kOfferToReceiveAudio and kOfferToReceiveVideo constraints are set to true.
2509TEST_F(WebRtcSessionTest, CreateOfferWithConstraints) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002510 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002511 // Test Audio / Video offer.
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002512 PeerConnectionInterface::RTCOfferAnswerOptions options;
2513 options.offer_to_receive_audio =
2514 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
2515 options.offer_to_receive_video =
2516 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
2517
kwibergd1fe2812016-04-27 06:47:29 -07002518 std::unique_ptr<SessionDescriptionInterface> offer(CreateOffer(options));
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002519
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002520 const cricket::ContentInfo* content =
2521 cricket::GetFirstAudioContent(offer->description());
jiayl@webrtc.orgc1723202014-09-08 20:44:36 +00002522 EXPECT_TRUE(content != NULL);
jiayl@webrtc.org7d4891d2014-09-09 21:43:15 +00002523
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002524 content = cricket::GetFirstVideoContent(offer->description());
2525 EXPECT_TRUE(content != NULL);
2526
jiayl@webrtc.org7d4891d2014-09-09 21:43:15 +00002527 // Sets constraints to false and verifies that audio/video contents are
2528 // removed.
2529 options.offer_to_receive_audio = 0;
2530 options.offer_to_receive_video = 0;
2531 offer.reset(CreateOffer(options));
2532
2533 content = cricket::GetFirstAudioContent(offer->description());
2534 EXPECT_TRUE(content == NULL);
2535 content = cricket::GetFirstVideoContent(offer->description());
2536 EXPECT_TRUE(content == NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002537}
2538
2539// Test that an answer can not be created if the last remote description is not
2540// an offer.
2541TEST_F(WebRtcSessionTest, CreateAnswerWithoutAnOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002542 Init();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002543 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002544 SetLocalDescriptionWithoutError(offer);
2545 SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
2546 SetRemoteDescriptionWithoutError(answer);
htaa2a49d92016-03-04 02:51:39 -08002547 EXPECT_TRUE(CreateAnswer() == NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002548}
2549
2550// Test that an answer contains the correct media content descriptions when no
2551// constraints have been set.
2552TEST_F(WebRtcSessionTest, CreateAnswerWithoutConstraintsOrStreams) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002553 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002554 // Create a remote offer with audio and video content.
kwibergd1fe2812016-04-27 06:47:29 -07002555 std::unique_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002556 SetRemoteDescriptionWithoutError(offer.release());
kwibergd1fe2812016-04-27 06:47:29 -07002557 std::unique_ptr<SessionDescriptionInterface> answer(CreateAnswer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002558 const cricket::ContentInfo* content =
2559 cricket::GetFirstAudioContent(answer->description());
2560 ASSERT_TRUE(content != NULL);
2561 EXPECT_FALSE(content->rejected);
2562
2563 content = cricket::GetFirstVideoContent(answer->description());
2564 ASSERT_TRUE(content != NULL);
2565 EXPECT_FALSE(content->rejected);
2566}
2567
2568// Test that an answer contains the correct media content descriptions when no
2569// constraints have been set and the offer only contain audio.
2570TEST_F(WebRtcSessionTest, CreateAudioAnswerWithoutConstraintsOrStreams) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002571 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002572 // Create a remote offer with audio only.
2573 cricket::MediaSessionOptions options;
jiayl@webrtc.org7d4891d2014-09-09 21:43:15 +00002574
kwibergd1fe2812016-04-27 06:47:29 -07002575 std::unique_ptr<JsepSessionDescription> offer(CreateRemoteOffer(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002576 ASSERT_TRUE(cricket::GetFirstVideoContent(offer->description()) == NULL);
2577 ASSERT_TRUE(cricket::GetFirstAudioContent(offer->description()) != NULL);
2578
2579 SetRemoteDescriptionWithoutError(offer.release());
kwibergd1fe2812016-04-27 06:47:29 -07002580 std::unique_ptr<SessionDescriptionInterface> answer(CreateAnswer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002581 const cricket::ContentInfo* content =
2582 cricket::GetFirstAudioContent(answer->description());
2583 ASSERT_TRUE(content != NULL);
2584 EXPECT_FALSE(content->rejected);
2585
2586 EXPECT_TRUE(cricket::GetFirstVideoContent(answer->description()) == NULL);
2587}
2588
2589// Test that an answer contains the correct media content descriptions when no
2590// constraints have been set.
2591TEST_F(WebRtcSessionTest, CreateAnswerWithoutConstraints) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002592 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002593 // Create a remote offer with audio and video content.
kwibergd1fe2812016-04-27 06:47:29 -07002594 std::unique_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002595 SetRemoteDescriptionWithoutError(offer.release());
2596 // Test with a stream with tracks.
deadbeefab9b2d12015-10-14 11:33:11 -07002597 SendAudioVideoStream1();
kwibergd1fe2812016-04-27 06:47:29 -07002598 std::unique_ptr<SessionDescriptionInterface> answer(CreateAnswer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002599 const cricket::ContentInfo* content =
2600 cricket::GetFirstAudioContent(answer->description());
2601 ASSERT_TRUE(content != NULL);
2602 EXPECT_FALSE(content->rejected);
2603
2604 content = cricket::GetFirstVideoContent(answer->description());
2605 ASSERT_TRUE(content != NULL);
2606 EXPECT_FALSE(content->rejected);
2607}
2608
2609// Test that an answer contains the correct media content descriptions when
2610// constraints have been set but no stream is sent.
2611TEST_F(WebRtcSessionTest, CreateAnswerWithConstraintsWithoutStreams) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002612 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002613 // Create a remote offer with audio and video content.
kwibergd1fe2812016-04-27 06:47:29 -07002614 std::unique_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002615 SetRemoteDescriptionWithoutError(offer.release());
2616
htaa2a49d92016-03-04 02:51:39 -08002617 cricket::MediaSessionOptions session_options;
2618 session_options.recv_audio = false;
2619 session_options.recv_video = false;
kwibergd1fe2812016-04-27 06:47:29 -07002620 std::unique_ptr<SessionDescriptionInterface> answer(
htaa2a49d92016-03-04 02:51:39 -08002621 CreateAnswer(session_options));
2622
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002623 const cricket::ContentInfo* content =
2624 cricket::GetFirstAudioContent(answer->description());
2625 ASSERT_TRUE(content != NULL);
2626 EXPECT_TRUE(content->rejected);
2627
2628 content = cricket::GetFirstVideoContent(answer->description());
2629 ASSERT_TRUE(content != NULL);
2630 EXPECT_TRUE(content->rejected);
2631}
2632
2633// Test that an answer contains the correct media content descriptions when
2634// constraints have been set and streams are sent.
2635TEST_F(WebRtcSessionTest, CreateAnswerWithConstraints) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002636 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002637 // Create a remote offer with audio and video content.
kwibergd1fe2812016-04-27 06:47:29 -07002638 std::unique_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002639 SetRemoteDescriptionWithoutError(offer.release());
2640
htaa2a49d92016-03-04 02:51:39 -08002641 cricket::MediaSessionOptions options;
2642 options.recv_audio = false;
2643 options.recv_video = false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002644
2645 // Test with a stream with tracks.
deadbeefab9b2d12015-10-14 11:33:11 -07002646 SendAudioVideoStream1();
kwibergd1fe2812016-04-27 06:47:29 -07002647 std::unique_ptr<SessionDescriptionInterface> answer(CreateAnswer(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002648
2649 // TODO(perkj): Should the direction be set to SEND_ONLY?
2650 const cricket::ContentInfo* content =
2651 cricket::GetFirstAudioContent(answer->description());
2652 ASSERT_TRUE(content != NULL);
2653 EXPECT_FALSE(content->rejected);
2654
2655 // TODO(perkj): Should the direction be set to SEND_ONLY?
2656 content = cricket::GetFirstVideoContent(answer->description());
2657 ASSERT_TRUE(content != NULL);
2658 EXPECT_FALSE(content->rejected);
2659}
2660
2661TEST_F(WebRtcSessionTest, CreateOfferWithoutCNCodecs) {
2662 AddCNCodecs();
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002663 Init();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002664 PeerConnectionInterface::RTCOfferAnswerOptions options;
2665 options.offer_to_receive_audio =
2666 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
2667 options.voice_activity_detection = false;
2668
kwibergd1fe2812016-04-27 06:47:29 -07002669 std::unique_ptr<SessionDescriptionInterface> offer(CreateOffer(options));
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002670
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002671 const cricket::ContentInfo* content =
2672 cricket::GetFirstAudioContent(offer->description());
2673 EXPECT_TRUE(content != NULL);
2674 EXPECT_TRUE(VerifyNoCNCodecs(content));
2675}
2676
2677TEST_F(WebRtcSessionTest, CreateAnswerWithoutCNCodecs) {
2678 AddCNCodecs();
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002679 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002680 // Create a remote offer with audio and video content.
kwibergd1fe2812016-04-27 06:47:29 -07002681 std::unique_ptr<JsepSessionDescription> offer(CreateRemoteOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002682 SetRemoteDescriptionWithoutError(offer.release());
2683
htaa2a49d92016-03-04 02:51:39 -08002684 cricket::MediaSessionOptions options;
2685 options.vad_enabled = false;
kwibergd1fe2812016-04-27 06:47:29 -07002686 std::unique_ptr<SessionDescriptionInterface> answer(CreateAnswer(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002687 const cricket::ContentInfo* content =
2688 cricket::GetFirstAudioContent(answer->description());
2689 ASSERT_TRUE(content != NULL);
2690 EXPECT_TRUE(VerifyNoCNCodecs(content));
2691}
2692
2693// This test verifies the call setup when remote answer with audio only and
2694// later updates with video.
2695TEST_F(WebRtcSessionTest, TestAVOfferWithAudioOnlyAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002696 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002697 EXPECT_TRUE(media_engine_->GetVideoChannel(0) == NULL);
2698 EXPECT_TRUE(media_engine_->GetVoiceChannel(0) == NULL);
2699
deadbeefab9b2d12015-10-14 11:33:11 -07002700 SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002701 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002702
2703 cricket::MediaSessionOptions options;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002704 SessionDescriptionInterface* answer = CreateRemoteAnswer(offer, options);
2705
2706 // SetLocalDescription and SetRemoteDescriptions takes ownership of offer
2707 // and answer;
2708 SetLocalDescriptionWithoutError(offer);
2709 SetRemoteDescriptionWithoutError(answer);
2710
2711 video_channel_ = media_engine_->GetVideoChannel(0);
2712 voice_channel_ = media_engine_->GetVoiceChannel(0);
2713
2714 ASSERT_TRUE(video_channel_ == NULL);
2715
2716 ASSERT_EQ(0u, voice_channel_->recv_streams().size());
2717 ASSERT_EQ(1u, voice_channel_->send_streams().size());
2718 EXPECT_EQ(kAudioTrack1, voice_channel_->send_streams()[0].id);
2719
2720 // Let the remote end update the session descriptions, with Audio and Video.
deadbeefab9b2d12015-10-14 11:33:11 -07002721 SendAudioVideoStream2();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002722 CreateAndSetRemoteOfferAndLocalAnswer();
2723
2724 video_channel_ = media_engine_->GetVideoChannel(0);
2725 voice_channel_ = media_engine_->GetVoiceChannel(0);
2726
2727 ASSERT_TRUE(video_channel_ != NULL);
2728 ASSERT_TRUE(voice_channel_ != NULL);
2729
2730 ASSERT_EQ(1u, video_channel_->recv_streams().size());
2731 ASSERT_EQ(1u, video_channel_->send_streams().size());
2732 EXPECT_EQ(kVideoTrack2, video_channel_->recv_streams()[0].id);
2733 EXPECT_EQ(kVideoTrack2, video_channel_->send_streams()[0].id);
2734 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
2735 ASSERT_EQ(1u, voice_channel_->send_streams().size());
2736 EXPECT_EQ(kAudioTrack2, voice_channel_->recv_streams()[0].id);
2737 EXPECT_EQ(kAudioTrack2, voice_channel_->send_streams()[0].id);
2738
2739 // Change session back to audio only.
deadbeefab9b2d12015-10-14 11:33:11 -07002740 SendAudioOnlyStream2();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002741 CreateAndSetRemoteOfferAndLocalAnswer();
2742
2743 EXPECT_EQ(0u, video_channel_->recv_streams().size());
2744 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
2745 EXPECT_EQ(kAudioTrack2, voice_channel_->recv_streams()[0].id);
2746 ASSERT_EQ(1u, voice_channel_->send_streams().size());
2747 EXPECT_EQ(kAudioTrack2, voice_channel_->send_streams()[0].id);
2748}
2749
2750// This test verifies the call setup when remote answer with video only and
2751// later updates with audio.
2752TEST_F(WebRtcSessionTest, TestAVOfferWithVideoOnlyAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002753 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002754 EXPECT_TRUE(media_engine_->GetVideoChannel(0) == NULL);
2755 EXPECT_TRUE(media_engine_->GetVoiceChannel(0) == NULL);
deadbeefab9b2d12015-10-14 11:33:11 -07002756 SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002757 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002758
2759 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00002760 options.recv_audio = false;
2761 options.recv_video = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002762 SessionDescriptionInterface* answer = CreateRemoteAnswer(
2763 offer, options, cricket::SEC_ENABLED);
2764
2765 // SetLocalDescription and SetRemoteDescriptions takes ownership of offer
2766 // and answer.
2767 SetLocalDescriptionWithoutError(offer);
2768 SetRemoteDescriptionWithoutError(answer);
2769
2770 video_channel_ = media_engine_->GetVideoChannel(0);
2771 voice_channel_ = media_engine_->GetVoiceChannel(0);
2772
2773 ASSERT_TRUE(voice_channel_ == NULL);
2774 ASSERT_TRUE(video_channel_ != NULL);
2775
2776 EXPECT_EQ(0u, video_channel_->recv_streams().size());
2777 ASSERT_EQ(1u, video_channel_->send_streams().size());
2778 EXPECT_EQ(kVideoTrack1, video_channel_->send_streams()[0].id);
2779
2780 // Update the session descriptions, with Audio and Video.
deadbeefab9b2d12015-10-14 11:33:11 -07002781 SendAudioVideoStream2();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002782 CreateAndSetRemoteOfferAndLocalAnswer();
2783
2784 voice_channel_ = media_engine_->GetVoiceChannel(0);
2785 ASSERT_TRUE(voice_channel_ != NULL);
2786
2787 ASSERT_EQ(1u, voice_channel_->recv_streams().size());
2788 ASSERT_EQ(1u, voice_channel_->send_streams().size());
2789 EXPECT_EQ(kAudioTrack2, voice_channel_->recv_streams()[0].id);
2790 EXPECT_EQ(kAudioTrack2, voice_channel_->send_streams()[0].id);
2791
2792 // Change session back to video only.
deadbeefab9b2d12015-10-14 11:33:11 -07002793 SendVideoOnlyStream2();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002794 CreateAndSetRemoteOfferAndLocalAnswer();
2795
2796 video_channel_ = media_engine_->GetVideoChannel(0);
2797 voice_channel_ = media_engine_->GetVoiceChannel(0);
2798
2799 ASSERT_EQ(1u, video_channel_->recv_streams().size());
2800 EXPECT_EQ(kVideoTrack2, video_channel_->recv_streams()[0].id);
2801 ASSERT_EQ(1u, video_channel_->send_streams().size());
2802 EXPECT_EQ(kVideoTrack2, video_channel_->send_streams()[0].id);
2803}
2804
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002805TEST_F(WebRtcSessionTest, VerifyCryptoParamsInSDP) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002806 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07002807 SendAudioVideoStream1();
kwibergd1fe2812016-04-27 06:47:29 -07002808 std::unique_ptr<SessionDescriptionInterface> offer(CreateOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002809 VerifyCryptoParams(offer->description());
2810 SetRemoteDescriptionWithoutError(offer.release());
kwibergd1fe2812016-04-27 06:47:29 -07002811 std::unique_ptr<SessionDescriptionInterface> answer(CreateAnswer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002812 VerifyCryptoParams(answer->description());
2813}
2814
jbauchcb560652016-08-04 05:20:32 -07002815TEST_F(WebRtcSessionTest, VerifyCryptoParamsInSDPGcm) {
2816 InitWithGcm();
2817 SendAudioVideoStream1();
2818 std::unique_ptr<SessionDescriptionInterface> offer(CreateOffer());
2819 VerifyCryptoParams(offer->description(), true);
2820 SetRemoteDescriptionWithoutError(offer.release());
2821 std::unique_ptr<SessionDescriptionInterface> answer(CreateAnswer());
2822 VerifyCryptoParams(answer->description(), true);
2823}
2824
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002825TEST_F(WebRtcSessionTest, VerifyNoCryptoParamsInSDP) {
wu@webrtc.org97077a32013-10-25 21:18:33 +00002826 options_.disable_encryption = true;
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002827 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07002828 SendAudioVideoStream1();
kwibergd1fe2812016-04-27 06:47:29 -07002829 std::unique_ptr<SessionDescriptionInterface> offer(CreateOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002830 VerifyNoCryptoParams(offer->description(), false);
2831}
2832
2833TEST_F(WebRtcSessionTest, VerifyAnswerFromNonCryptoOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002834 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002835 VerifyAnswerFromNonCryptoOffer();
2836}
2837
2838TEST_F(WebRtcSessionTest, VerifyAnswerFromCryptoOffer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002839 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00002840 VerifyAnswerFromCryptoOffer();
2841}
2842
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002843// This test verifies that setLocalDescription fails if
2844// no a=ice-ufrag and a=ice-pwd lines are present in the SDP.
2845TEST_F(WebRtcSessionTest, TestSetLocalDescriptionWithoutIce) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002846 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07002847 SendAudioVideoStream1();
kwibergd1fe2812016-04-27 06:47:29 -07002848 std::unique_ptr<SessionDescriptionInterface> offer(CreateOffer());
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00002849
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002850 std::string sdp;
2851 RemoveIceUfragPwdLines(offer.get(), &sdp);
2852 SessionDescriptionInterface* modified_offer =
2853 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00002854 SetLocalDescriptionOfferExpectError(kSdpWithoutIceUfragPwd, modified_offer);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002855}
2856
2857// This test verifies that setRemoteDescription fails if
2858// no a=ice-ufrag and a=ice-pwd lines are present in the SDP.
2859TEST_F(WebRtcSessionTest, TestSetRemoteDescriptionWithoutIce) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002860 Init();
kwibergd1fe2812016-04-27 06:47:29 -07002861 std::unique_ptr<SessionDescriptionInterface> offer(CreateRemoteOffer());
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002862 std::string sdp;
2863 RemoveIceUfragPwdLines(offer.get(), &sdp);
2864 SessionDescriptionInterface* modified_offer =
2865 CreateSessionDescription(JsepSessionDescription::kOffer, sdp, NULL);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00002866 SetRemoteDescriptionOfferExpectError(kSdpWithoutIceUfragPwd, modified_offer);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00002867}
2868
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +00002869// This test verifies that setLocalDescription fails if local offer has
2870// too short ice ufrag and pwd strings.
2871TEST_F(WebRtcSessionTest, TestSetLocalDescriptionInvalidIceCredentials) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002872 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07002873 SendAudioVideoStream1();
kwibergd1fe2812016-04-27 06:47:29 -07002874 std::unique_ptr<SessionDescriptionInterface> offer(CreateOffer());
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +00002875 // Modifying ice ufrag and pwd in local offer with strings smaller than the
2876 // recommended values of 4 and 22 bytes respectively.
deadbeef0ed85b22016-02-23 17:24:52 -08002877 SetIceUfragPwd(offer.get(), "ice", "icepwd");
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +00002878 std::string error;
deadbeef0ed85b22016-02-23 17:24:52 -08002879 EXPECT_FALSE(session_->SetLocalDescription(offer.release(), &error));
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +00002880
2881 // Test with string greater than 256.
deadbeef0ed85b22016-02-23 17:24:52 -08002882 offer.reset(CreateOffer());
2883 SetIceUfragPwd(offer.get(), kTooLongIceUfragPwd, kTooLongIceUfragPwd);
2884 EXPECT_FALSE(session_->SetLocalDescription(offer.release(), &error));
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +00002885}
2886
2887// This test verifies that setRemoteDescription fails if remote offer has
2888// too short ice ufrag and pwd strings.
2889TEST_F(WebRtcSessionTest, TestSetRemoteDescriptionInvalidIceCredentials) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00002890 Init();
kwibergd1fe2812016-04-27 06:47:29 -07002891 std::unique_ptr<SessionDescriptionInterface> offer(CreateRemoteOffer());
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +00002892 // Modifying ice ufrag and pwd in remote offer with strings smaller than the
2893 // recommended values of 4 and 22 bytes respectively.
deadbeef0ed85b22016-02-23 17:24:52 -08002894 SetIceUfragPwd(offer.get(), "ice", "icepwd");
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +00002895 std::string error;
deadbeef0ed85b22016-02-23 17:24:52 -08002896 EXPECT_FALSE(session_->SetRemoteDescription(offer.release(), &error));
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +00002897
deadbeef0ed85b22016-02-23 17:24:52 -08002898 offer.reset(CreateRemoteOffer());
2899 SetIceUfragPwd(offer.get(), kTooLongIceUfragPwd, kTooLongIceUfragPwd);
2900 EXPECT_FALSE(session_->SetRemoteDescription(offer.release(), &error));
buildbot@webrtc.org7aa1a472014-05-23 17:33:05 +00002901}
2902
Honghai Zhang04e91462015-12-11 14:26:22 -08002903// Test that if the remote offer indicates the peer requested ICE restart (via
2904// a new ufrag or pwd), the old ICE candidates are not copied, and vice versa.
2905TEST_F(WebRtcSessionTest, TestSetRemoteOfferWithIceRestart) {
honghaiz503726c2015-07-31 12:37:38 -07002906 Init();
honghaiz503726c2015-07-31 12:37:38 -07002907
2908 // Create the first offer.
kwibergd1fe2812016-04-27 06:47:29 -07002909 std::unique_ptr<SessionDescriptionInterface> offer(CreateRemoteOffer());
deadbeef0ed85b22016-02-23 17:24:52 -08002910 SetIceUfragPwd(offer.get(), "0123456789012345", "abcdefghijklmnopqrstuvwx");
honghaiz503726c2015-07-31 12:37:38 -07002911 cricket::Candidate candidate1(1, "udp", rtc::SocketAddress("1.1.1.1", 5000),
2912 0, "", "", "relay", 0, "");
2913 JsepIceCandidate ice_candidate1(kMediaContentName0, kMediaContentIndex0,
2914 candidate1);
deadbeef0ed85b22016-02-23 17:24:52 -08002915 EXPECT_TRUE(offer->AddCandidate(&ice_candidate1));
2916 SetRemoteDescriptionWithoutError(offer.release());
honghaiz503726c2015-07-31 12:37:38 -07002917 EXPECT_EQ(1, session_->remote_description()->candidates(0)->count());
2918
2919 // The second offer has the same ufrag and pwd but different address.
deadbeef0ed85b22016-02-23 17:24:52 -08002920 offer.reset(CreateRemoteOffer());
2921 SetIceUfragPwd(offer.get(), "0123456789012345", "abcdefghijklmnopqrstuvwx");
honghaiz503726c2015-07-31 12:37:38 -07002922 candidate1.set_address(rtc::SocketAddress("1.1.1.1", 6000));
2923 JsepIceCandidate ice_candidate2(kMediaContentName0, kMediaContentIndex0,
2924 candidate1);
deadbeef0ed85b22016-02-23 17:24:52 -08002925 EXPECT_TRUE(offer->AddCandidate(&ice_candidate2));
2926 SetRemoteDescriptionWithoutError(offer.release());
honghaiz503726c2015-07-31 12:37:38 -07002927 EXPECT_EQ(2, session_->remote_description()->candidates(0)->count());
2928
2929 // The third offer has a different ufrag and different address.
deadbeef0ed85b22016-02-23 17:24:52 -08002930 offer.reset(CreateRemoteOffer());
2931 SetIceUfragPwd(offer.get(), "0123456789012333", "abcdefghijklmnopqrstuvwx");
honghaiz503726c2015-07-31 12:37:38 -07002932 candidate1.set_address(rtc::SocketAddress("1.1.1.1", 7000));
2933 JsepIceCandidate ice_candidate3(kMediaContentName0, kMediaContentIndex0,
2934 candidate1);
deadbeef0ed85b22016-02-23 17:24:52 -08002935 EXPECT_TRUE(offer->AddCandidate(&ice_candidate3));
2936 SetRemoteDescriptionWithoutError(offer.release());
honghaiz503726c2015-07-31 12:37:38 -07002937 EXPECT_EQ(1, session_->remote_description()->candidates(0)->count());
2938
2939 // The fourth offer has no candidate but a different ufrag/pwd.
deadbeef0ed85b22016-02-23 17:24:52 -08002940 offer.reset(CreateRemoteOffer());
2941 SetIceUfragPwd(offer.get(), "0123456789012444", "abcdefghijklmnopqrstuvyz");
2942 SetRemoteDescriptionWithoutError(offer.release());
honghaiz503726c2015-07-31 12:37:38 -07002943 EXPECT_EQ(0, session_->remote_description()->candidates(0)->count());
2944}
2945
Honghai Zhang04e91462015-12-11 14:26:22 -08002946// Test that if the remote answer indicates the peer requested ICE restart (via
2947// a new ufrag or pwd), the old ICE candidates are not copied, and vice versa.
2948TEST_F(WebRtcSessionTest, TestSetRemoteAnswerWithIceRestart) {
2949 Init();
2950 SessionDescriptionInterface* offer = CreateOffer();
2951 SetLocalDescriptionWithoutError(offer);
Honghai Zhang04e91462015-12-11 14:26:22 -08002952
2953 // Create the first answer.
kwibergd1fe2812016-04-27 06:47:29 -07002954 std::unique_ptr<JsepSessionDescription> answer(CreateRemoteAnswer(offer));
deadbeef0ed85b22016-02-23 17:24:52 -08002955 answer->set_type(JsepSessionDescription::kPrAnswer);
2956 SetIceUfragPwd(answer.get(), "0123456789012345", "abcdefghijklmnopqrstuvwx");
Honghai Zhang04e91462015-12-11 14:26:22 -08002957 cricket::Candidate candidate1(1, "udp", rtc::SocketAddress("1.1.1.1", 5000),
2958 0, "", "", "relay", 0, "");
2959 JsepIceCandidate ice_candidate1(kMediaContentName0, kMediaContentIndex0,
2960 candidate1);
deadbeef0ed85b22016-02-23 17:24:52 -08002961 EXPECT_TRUE(answer->AddCandidate(&ice_candidate1));
2962 SetRemoteDescriptionWithoutError(answer.release());
Honghai Zhang04e91462015-12-11 14:26:22 -08002963 EXPECT_EQ(1, session_->remote_description()->candidates(0)->count());
2964
2965 // The second answer has the same ufrag and pwd but different address.
deadbeef0ed85b22016-02-23 17:24:52 -08002966 answer.reset(CreateRemoteAnswer(offer));
2967 answer->set_type(JsepSessionDescription::kPrAnswer);
2968 SetIceUfragPwd(answer.get(), "0123456789012345", "abcdefghijklmnopqrstuvwx");
Honghai Zhang04e91462015-12-11 14:26:22 -08002969 candidate1.set_address(rtc::SocketAddress("1.1.1.1", 6000));
2970 JsepIceCandidate ice_candidate2(kMediaContentName0, kMediaContentIndex0,
2971 candidate1);
deadbeef0ed85b22016-02-23 17:24:52 -08002972 EXPECT_TRUE(answer->AddCandidate(&ice_candidate2));
2973 SetRemoteDescriptionWithoutError(answer.release());
Honghai Zhang04e91462015-12-11 14:26:22 -08002974 EXPECT_EQ(2, session_->remote_description()->candidates(0)->count());
2975
2976 // The third answer has a different ufrag and different address.
deadbeef0ed85b22016-02-23 17:24:52 -08002977 answer.reset(CreateRemoteAnswer(offer));
2978 answer->set_type(JsepSessionDescription::kPrAnswer);
2979 SetIceUfragPwd(answer.get(), "0123456789012333", "abcdefghijklmnopqrstuvwx");
Honghai Zhang04e91462015-12-11 14:26:22 -08002980 candidate1.set_address(rtc::SocketAddress("1.1.1.1", 7000));
2981 JsepIceCandidate ice_candidate3(kMediaContentName0, kMediaContentIndex0,
2982 candidate1);
deadbeef0ed85b22016-02-23 17:24:52 -08002983 EXPECT_TRUE(answer->AddCandidate(&ice_candidate3));
2984 SetRemoteDescriptionWithoutError(answer.release());
Honghai Zhang04e91462015-12-11 14:26:22 -08002985 EXPECT_EQ(1, session_->remote_description()->candidates(0)->count());
2986
2987 // The fourth answer has no candidate but a different ufrag/pwd.
deadbeef0ed85b22016-02-23 17:24:52 -08002988 answer.reset(CreateRemoteAnswer(offer));
2989 answer->set_type(JsepSessionDescription::kPrAnswer);
2990 SetIceUfragPwd(answer.get(), "0123456789012444", "abcdefghijklmnopqrstuvyz");
2991 SetRemoteDescriptionWithoutError(answer.release());
Honghai Zhang04e91462015-12-11 14:26:22 -08002992 EXPECT_EQ(0, session_->remote_description()->candidates(0)->count());
2993}
2994
Donald Curtisd4f769d2015-05-28 09:48:21 -07002995// Test that candidates sent to the "video" transport do not get pushed down to
deadbeefd59daf82015-10-14 15:02:44 -07002996// the "audio" transport channel when bundling.
Donald Curtisd4f769d2015-05-28 09:48:21 -07002997TEST_F(WebRtcSessionTest, TestIgnoreCandidatesForUnusedTransportWhenBundling) {
2998 AddInterface(rtc::SocketAddress(kClientAddrHost1, kClientAddrPort));
2999
3000 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyBalanced);
deadbeefab9b2d12015-10-14 11:33:11 -07003001 SendAudioVideoStream1();
Donald Curtisd4f769d2015-05-28 09:48:21 -07003002
3003 PeerConnectionInterface::RTCOfferAnswerOptions options;
3004 options.use_rtp_mux = true;
3005
3006 SessionDescriptionInterface* offer = CreateRemoteOffer();
3007 SetRemoteDescriptionWithoutError(offer);
3008
htaa2a49d92016-03-04 02:51:39 -08003009 SessionDescriptionInterface* answer = CreateAnswer();
Donald Curtisd4f769d2015-05-28 09:48:21 -07003010 SetLocalDescriptionWithoutError(answer);
3011
deadbeefcbecd352015-09-23 11:50:27 -07003012 EXPECT_EQ(session_->voice_rtp_transport_channel(),
3013 session_->video_rtp_transport_channel());
Donald Curtisd4f769d2015-05-28 09:48:21 -07003014
deadbeefcbecd352015-09-23 11:50:27 -07003015 cricket::BaseChannel* voice_channel = session_->voice_channel();
3016 ASSERT(voice_channel != NULL);
Donald Curtisd4f769d2015-05-28 09:48:21 -07003017
3018 // Checks if one of the transport channels contains a connection using a given
3019 // port.
deadbeefcbecd352015-09-23 11:50:27 -07003020 auto connection_with_remote_port = [this, voice_channel](int port) {
deadbeefd59daf82015-10-14 15:02:44 -07003021 SessionStats stats;
deadbeefcbecd352015-09-23 11:50:27 -07003022 session_->GetChannelTransportStats(voice_channel, &stats);
3023 for (auto& kv : stats.transport_stats) {
3024 for (auto& chan_stat : kv.second.channel_stats) {
3025 for (auto& conn_info : chan_stat.connection_infos) {
3026 if (conn_info.remote_candidate.address().port() == port) {
3027 return true;
3028 }
Donald Curtisd4f769d2015-05-28 09:48:21 -07003029 }
3030 }
3031 }
3032 return false;
3033 };
3034
3035 EXPECT_FALSE(connection_with_remote_port(5000));
3036 EXPECT_FALSE(connection_with_remote_port(5001));
3037 EXPECT_FALSE(connection_with_remote_port(6000));
3038
3039 // The way the *_WAIT checks work is they only wait if the condition fails,
3040 // which does not help in the case where state is not changing. This is
3041 // problematic in this test since we want to verify that adding a video
3042 // candidate does _not_ change state. So we interleave candidates and assume
3043 // that messages are executed in the order they were posted.
3044
3045 // First audio candidate.
3046 cricket::Candidate candidate0;
3047 candidate0.set_address(rtc::SocketAddress("1.1.1.1", 5000));
3048 candidate0.set_component(1);
3049 candidate0.set_protocol("udp");
3050 JsepIceCandidate ice_candidate0(kMediaContentName0, kMediaContentIndex0,
3051 candidate0);
3052 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate0));
3053
3054 // Video candidate.
3055 cricket::Candidate candidate1;
3056 candidate1.set_address(rtc::SocketAddress("1.1.1.1", 6000));
3057 candidate1.set_component(1);
3058 candidate1.set_protocol("udp");
3059 JsepIceCandidate ice_candidate1(kMediaContentName1, kMediaContentIndex1,
3060 candidate1);
3061 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate1));
3062
3063 // Second audio candidate.
3064 cricket::Candidate candidate2;
3065 candidate2.set_address(rtc::SocketAddress("1.1.1.1", 5001));
3066 candidate2.set_component(1);
3067 candidate2.set_protocol("udp");
3068 JsepIceCandidate ice_candidate2(kMediaContentName0, kMediaContentIndex0,
3069 candidate2);
3070 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate2));
3071
3072 EXPECT_TRUE_WAIT(connection_with_remote_port(5000), 1000);
3073 EXPECT_TRUE_WAIT(connection_with_remote_port(5001), 1000);
3074
3075 // No need here for a _WAIT check since we are checking that state hasn't
3076 // changed: if this is false we would be doing waits for nothing and if this
3077 // is true then there will be no messages processed anyways.
3078 EXPECT_FALSE(connection_with_remote_port(6000));
3079}
3080
deadbeefcbecd352015-09-23 11:50:27 -07003081// kBundlePolicyBalanced BUNDLE policy and answer contains BUNDLE.
Donald Curtis0e209b02015-03-24 09:29:54 -07003082TEST_F(WebRtcSessionTest, TestBalancedBundleInAnswer) {
3083 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyBalanced);
deadbeefab9b2d12015-10-14 11:33:11 -07003084 SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003085
3086 PeerConnectionInterface::RTCOfferAnswerOptions options;
3087 options.use_rtp_mux = true;
3088
3089 SessionDescriptionInterface* offer = CreateOffer(options);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003090 SetLocalDescriptionWithoutError(offer);
Donald Curtis0e209b02015-03-24 09:29:54 -07003091
deadbeefcbecd352015-09-23 11:50:27 -07003092 EXPECT_NE(session_->voice_rtp_transport_channel(),
3093 session_->video_rtp_transport_channel());
Donald Curtis0e209b02015-03-24 09:29:54 -07003094
deadbeefab9b2d12015-10-14 11:33:11 -07003095 SendAudioVideoStream2();
Donald Curtis0e209b02015-03-24 09:29:54 -07003096 SessionDescriptionInterface* answer =
3097 CreateRemoteAnswer(session_->local_description());
3098 SetRemoteDescriptionWithoutError(answer);
3099
deadbeefcbecd352015-09-23 11:50:27 -07003100 EXPECT_EQ(session_->voice_rtp_transport_channel(),
3101 session_->video_rtp_transport_channel());
Donald Curtis0e209b02015-03-24 09:29:54 -07003102}
3103
deadbeefcbecd352015-09-23 11:50:27 -07003104// kBundlePolicyBalanced BUNDLE policy but no BUNDLE in the answer.
Donald Curtis0e209b02015-03-24 09:29:54 -07003105TEST_F(WebRtcSessionTest, TestBalancedNoBundleInAnswer) {
3106 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyBalanced);
deadbeefab9b2d12015-10-14 11:33:11 -07003107 SendAudioVideoStream1();
Peter Thatcher4eddf182015-04-30 10:55:59 -07003108
Donald Curtis0e209b02015-03-24 09:29:54 -07003109 PeerConnectionInterface::RTCOfferAnswerOptions options;
3110 options.use_rtp_mux = true;
3111
3112 SessionDescriptionInterface* offer = CreateOffer(options);
3113 SetLocalDescriptionWithoutError(offer);
3114
deadbeefcbecd352015-09-23 11:50:27 -07003115 EXPECT_NE(session_->voice_rtp_transport_channel(),
3116 session_->video_rtp_transport_channel());
Donald Curtis0e209b02015-03-24 09:29:54 -07003117
deadbeefab9b2d12015-10-14 11:33:11 -07003118 SendAudioVideoStream2();
Donald Curtis0e209b02015-03-24 09:29:54 -07003119
3120 // Remove BUNDLE from the answer.
kwibergd1fe2812016-04-27 06:47:29 -07003121 std::unique_ptr<SessionDescriptionInterface> answer(
Donald Curtis0e209b02015-03-24 09:29:54 -07003122 CreateRemoteAnswer(session_->local_description()));
3123 cricket::SessionDescription* answer_copy = answer->description()->Copy();
3124 answer_copy->RemoveGroupByName(cricket::GROUP_TYPE_BUNDLE);
3125 JsepSessionDescription* modified_answer =
3126 new JsepSessionDescription(JsepSessionDescription::kAnswer);
3127 modified_answer->Initialize(answer_copy, "1", "1");
3128 SetRemoteDescriptionWithoutError(modified_answer); //
3129
deadbeefcbecd352015-09-23 11:50:27 -07003130 EXPECT_NE(session_->voice_rtp_transport_channel(),
3131 session_->video_rtp_transport_channel());
Donald Curtis0e209b02015-03-24 09:29:54 -07003132}
3133
3134// kBundlePolicyMaxBundle policy with BUNDLE in the answer.
3135TEST_F(WebRtcSessionTest, TestMaxBundleBundleInAnswer) {
3136 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxBundle);
deadbeefab9b2d12015-10-14 11:33:11 -07003137 SendAudioVideoStream1();
Donald Curtis0e209b02015-03-24 09:29:54 -07003138
3139 PeerConnectionInterface::RTCOfferAnswerOptions options;
3140 options.use_rtp_mux = true;
3141
3142 SessionDescriptionInterface* offer = CreateOffer(options);
3143 SetLocalDescriptionWithoutError(offer);
3144
deadbeefcbecd352015-09-23 11:50:27 -07003145 EXPECT_EQ(session_->voice_rtp_transport_channel(),
3146 session_->video_rtp_transport_channel());
Donald Curtis0e209b02015-03-24 09:29:54 -07003147
deadbeefab9b2d12015-10-14 11:33:11 -07003148 SendAudioVideoStream2();
Donald Curtis0e209b02015-03-24 09:29:54 -07003149 SessionDescriptionInterface* answer =
3150 CreateRemoteAnswer(session_->local_description());
3151 SetRemoteDescriptionWithoutError(answer);
3152
deadbeefcbecd352015-09-23 11:50:27 -07003153 EXPECT_EQ(session_->voice_rtp_transport_channel(),
3154 session_->video_rtp_transport_channel());
3155}
3156
3157// kBundlePolicyMaxBundle policy with BUNDLE in the answer, but no
3158// audio content in the answer.
3159TEST_F(WebRtcSessionTest, TestMaxBundleRejectAudio) {
3160 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxBundle);
deadbeefab9b2d12015-10-14 11:33:11 -07003161 SendAudioVideoStream1();
deadbeefcbecd352015-09-23 11:50:27 -07003162
3163 PeerConnectionInterface::RTCOfferAnswerOptions options;
3164 options.use_rtp_mux = true;
3165
3166 SessionDescriptionInterface* offer = CreateOffer(options);
3167 SetLocalDescriptionWithoutError(offer);
3168
3169 EXPECT_EQ(session_->voice_rtp_transport_channel(),
3170 session_->video_rtp_transport_channel());
3171
deadbeefab9b2d12015-10-14 11:33:11 -07003172 SendAudioVideoStream2();
deadbeefcbecd352015-09-23 11:50:27 -07003173 cricket::MediaSessionOptions recv_options;
3174 recv_options.recv_audio = false;
3175 recv_options.recv_video = true;
3176 SessionDescriptionInterface* answer =
3177 CreateRemoteAnswer(session_->local_description(), recv_options);
3178 SetRemoteDescriptionWithoutError(answer);
3179
deadbeefd59daf82015-10-14 15:02:44 -07003180 EXPECT_TRUE(nullptr == session_->voice_channel());
3181 EXPECT_TRUE(nullptr != session_->video_rtp_transport_channel());
deadbeefcbecd352015-09-23 11:50:27 -07003182
deadbeefd59daf82015-10-14 15:02:44 -07003183 session_->Close();
3184 EXPECT_TRUE(nullptr == session_->voice_rtp_transport_channel());
3185 EXPECT_TRUE(nullptr == session_->voice_rtcp_transport_channel());
3186 EXPECT_TRUE(nullptr == session_->video_rtp_transport_channel());
3187 EXPECT_TRUE(nullptr == session_->video_rtcp_transport_channel());
Donald Curtis0e209b02015-03-24 09:29:54 -07003188}
3189
3190// kBundlePolicyMaxBundle policy but no BUNDLE in the answer.
3191TEST_F(WebRtcSessionTest, TestMaxBundleNoBundleInAnswer) {
3192 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxBundle);
deadbeefab9b2d12015-10-14 11:33:11 -07003193 SendAudioVideoStream1();
Peter Thatcher4eddf182015-04-30 10:55:59 -07003194
Donald Curtis0e209b02015-03-24 09:29:54 -07003195 PeerConnectionInterface::RTCOfferAnswerOptions options;
3196 options.use_rtp_mux = true;
3197
3198 SessionDescriptionInterface* offer = CreateOffer(options);
3199 SetLocalDescriptionWithoutError(offer);
3200
deadbeefcbecd352015-09-23 11:50:27 -07003201 EXPECT_EQ(session_->voice_rtp_transport_channel(),
3202 session_->video_rtp_transport_channel());
Donald Curtis0e209b02015-03-24 09:29:54 -07003203
deadbeefab9b2d12015-10-14 11:33:11 -07003204 SendAudioVideoStream2();
Donald Curtis0e209b02015-03-24 09:29:54 -07003205
3206 // Remove BUNDLE from the answer.
kwibergd1fe2812016-04-27 06:47:29 -07003207 std::unique_ptr<SessionDescriptionInterface> answer(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003208 CreateRemoteAnswer(session_->local_description()));
3209 cricket::SessionDescription* answer_copy = answer->description()->Copy();
3210 answer_copy->RemoveGroupByName(cricket::GROUP_TYPE_BUNDLE);
3211 JsepSessionDescription* modified_answer =
3212 new JsepSessionDescription(JsepSessionDescription::kAnswer);
3213 modified_answer->Initialize(answer_copy, "1", "1");
3214 SetRemoteDescriptionWithoutError(modified_answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003215
deadbeefcbecd352015-09-23 11:50:27 -07003216 EXPECT_EQ(session_->voice_rtp_transport_channel(),
3217 session_->video_rtp_transport_channel());
3218}
3219
3220// kBundlePolicyMaxBundle policy with BUNDLE in the remote offer.
3221TEST_F(WebRtcSessionTest, TestMaxBundleBundleInRemoteOffer) {
3222 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxBundle);
deadbeefab9b2d12015-10-14 11:33:11 -07003223 SendAudioVideoStream1();
deadbeefcbecd352015-09-23 11:50:27 -07003224
3225 SessionDescriptionInterface* offer = CreateRemoteOffer();
3226 SetRemoteDescriptionWithoutError(offer);
3227
3228 EXPECT_EQ(session_->voice_rtp_transport_channel(),
3229 session_->video_rtp_transport_channel());
3230
deadbeefab9b2d12015-10-14 11:33:11 -07003231 SendAudioVideoStream2();
htaa2a49d92016-03-04 02:51:39 -08003232 SessionDescriptionInterface* answer = CreateAnswer();
deadbeefcbecd352015-09-23 11:50:27 -07003233 SetLocalDescriptionWithoutError(answer);
3234
3235 EXPECT_EQ(session_->voice_rtp_transport_channel(),
3236 session_->video_rtp_transport_channel());
3237}
3238
3239// kBundlePolicyMaxBundle policy but no BUNDLE in the remote offer.
3240TEST_F(WebRtcSessionTest, TestMaxBundleNoBundleInRemoteOffer) {
3241 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxBundle);
deadbeefab9b2d12015-10-14 11:33:11 -07003242 SendAudioVideoStream1();
deadbeefcbecd352015-09-23 11:50:27 -07003243
3244 // Remove BUNDLE from the offer.
kwibergd1fe2812016-04-27 06:47:29 -07003245 std::unique_ptr<SessionDescriptionInterface> offer(CreateRemoteOffer());
deadbeefcbecd352015-09-23 11:50:27 -07003246 cricket::SessionDescription* offer_copy = offer->description()->Copy();
3247 offer_copy->RemoveGroupByName(cricket::GROUP_TYPE_BUNDLE);
3248 JsepSessionDescription* modified_offer =
3249 new JsepSessionDescription(JsepSessionDescription::kOffer);
3250 modified_offer->Initialize(offer_copy, "1", "1");
3251
3252 // Expect an error when applying the remote description
3253 SetRemoteDescriptionExpectError(JsepSessionDescription::kOffer,
3254 kCreateChannelFailed, modified_offer);
Donald Curtis0e209b02015-03-24 09:29:54 -07003255}
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003256
Peter Thatcher4eddf182015-04-30 10:55:59 -07003257// kBundlePolicyMaxCompat bundle policy and answer contains BUNDLE.
Donald Curtis0e209b02015-03-24 09:29:54 -07003258TEST_F(WebRtcSessionTest, TestMaxCompatBundleInAnswer) {
3259 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxCompat);
deadbeefab9b2d12015-10-14 11:33:11 -07003260 SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003261
Donald Curtis0e209b02015-03-24 09:29:54 -07003262 PeerConnectionInterface::RTCOfferAnswerOptions options;
3263 options.use_rtp_mux = true;
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003264
Donald Curtis0e209b02015-03-24 09:29:54 -07003265 SessionDescriptionInterface* offer = CreateOffer(options);
3266 SetLocalDescriptionWithoutError(offer);
3267
deadbeefcbecd352015-09-23 11:50:27 -07003268 EXPECT_NE(session_->voice_rtp_transport_channel(),
3269 session_->video_rtp_transport_channel());
Donald Curtis0e209b02015-03-24 09:29:54 -07003270
deadbeefab9b2d12015-10-14 11:33:11 -07003271 SendAudioVideoStream2();
Donald Curtis0e209b02015-03-24 09:29:54 -07003272 SessionDescriptionInterface* answer =
3273 CreateRemoteAnswer(session_->local_description());
3274 SetRemoteDescriptionWithoutError(answer);
3275
3276 // This should lead to an audio-only call but isn't implemented
3277 // correctly yet.
deadbeefcbecd352015-09-23 11:50:27 -07003278 EXPECT_EQ(session_->voice_rtp_transport_channel(),
3279 session_->video_rtp_transport_channel());
Donald Curtis0e209b02015-03-24 09:29:54 -07003280}
3281
deadbeefcbecd352015-09-23 11:50:27 -07003282// kBundlePolicyMaxCompat BUNDLE policy but no BUNDLE in the answer.
Donald Curtis0e209b02015-03-24 09:29:54 -07003283TEST_F(WebRtcSessionTest, TestMaxCompatNoBundleInAnswer) {
3284 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxCompat);
deadbeefab9b2d12015-10-14 11:33:11 -07003285 SendAudioVideoStream1();
Donald Curtis0e209b02015-03-24 09:29:54 -07003286 PeerConnectionInterface::RTCOfferAnswerOptions options;
3287 options.use_rtp_mux = true;
3288
3289 SessionDescriptionInterface* offer = CreateOffer(options);
3290 SetLocalDescriptionWithoutError(offer);
3291
deadbeefcbecd352015-09-23 11:50:27 -07003292 EXPECT_NE(session_->voice_rtp_transport_channel(),
3293 session_->video_rtp_transport_channel());
Donald Curtis0e209b02015-03-24 09:29:54 -07003294
deadbeefab9b2d12015-10-14 11:33:11 -07003295 SendAudioVideoStream2();
Donald Curtis0e209b02015-03-24 09:29:54 -07003296
3297 // Remove BUNDLE from the answer.
kwibergd1fe2812016-04-27 06:47:29 -07003298 std::unique_ptr<SessionDescriptionInterface> answer(
Donald Curtis0e209b02015-03-24 09:29:54 -07003299 CreateRemoteAnswer(session_->local_description()));
3300 cricket::SessionDescription* answer_copy = answer->description()->Copy();
3301 answer_copy->RemoveGroupByName(cricket::GROUP_TYPE_BUNDLE);
3302 JsepSessionDescription* modified_answer =
3303 new JsepSessionDescription(JsepSessionDescription::kAnswer);
3304 modified_answer->Initialize(answer_copy, "1", "1");
3305 SetRemoteDescriptionWithoutError(modified_answer); //
3306
deadbeefcbecd352015-09-23 11:50:27 -07003307 EXPECT_NE(session_->voice_rtp_transport_channel(),
3308 session_->video_rtp_transport_channel());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003309}
3310
Peter Thatcher4eddf182015-04-30 10:55:59 -07003311// kBundlePolicyMaxbundle and then we call SetRemoteDescription first.
3312TEST_F(WebRtcSessionTest, TestMaxBundleWithSetRemoteDescriptionFirst) {
3313 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyMaxBundle);
deadbeefab9b2d12015-10-14 11:33:11 -07003314 SendAudioVideoStream1();
Peter Thatcher4eddf182015-04-30 10:55:59 -07003315
3316 PeerConnectionInterface::RTCOfferAnswerOptions options;
3317 options.use_rtp_mux = true;
3318
3319 SessionDescriptionInterface* offer = CreateOffer(options);
3320 SetRemoteDescriptionWithoutError(offer);
3321
deadbeefcbecd352015-09-23 11:50:27 -07003322 EXPECT_EQ(session_->voice_rtp_transport_channel(),
3323 session_->video_rtp_transport_channel());
Peter Thatcher4eddf182015-04-30 10:55:59 -07003324}
3325
skvlad6c87a672016-05-17 17:49:52 -07003326// Adding a new channel to a BUNDLE which is already connected should directly
3327// assign the bundle transport to the channel, without first setting a
3328// disconnected non-bundle transport and then replacing it. The application
3329// should not receive any changes in the ICE state.
3330TEST_F(WebRtcSessionTest, TestAddChannelToConnectedBundle) {
3331 LoopbackNetworkConfiguration config;
3332 LoopbackNetworkManager loopback_network_manager(this, config);
3333 // Both BUNDLE and RTCP-mux need to be enabled for the ICE state to remain
3334 // connected. Disabling either of these two means that we need to wait for the
3335 // answer to find out if more transports are needed.
3336 configuration_.bundle_policy =
3337 PeerConnectionInterface::kBundlePolicyMaxBundle;
3338 configuration_.rtcp_mux_policy =
3339 PeerConnectionInterface::kRtcpMuxPolicyRequire;
3340 options_.disable_encryption = true;
3341 Init();
3342
3343 // Negotiate an audio channel with MAX_BUNDLE enabled.
3344 SendAudioOnlyStream2();
3345 SessionDescriptionInterface* offer = CreateOffer();
3346 SetLocalDescriptionWithoutError(offer);
3347 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceGatheringComplete,
3348 observer_.ice_gathering_state_, kIceCandidatesTimeout);
3349 std::string sdp;
3350 offer->ToString(&sdp);
3351 SessionDescriptionInterface* answer = webrtc::CreateSessionDescription(
3352 JsepSessionDescription::kAnswer, sdp, nullptr);
3353 ASSERT_TRUE(answer != NULL);
3354 SetRemoteDescriptionWithoutError(answer);
3355
3356 // Wait for the ICE state to stabilize.
3357 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
3358 observer_.ice_connection_state_, kIceCandidatesTimeout);
3359 observer_.ice_connection_state_history_.clear();
3360
3361 // Now add a video channel which should be using the same bundle transport.
3362 SendAudioVideoStream2();
3363 offer = CreateOffer();
3364 offer->ToString(&sdp);
3365 SetLocalDescriptionWithoutError(offer);
3366 answer = webrtc::CreateSessionDescription(JsepSessionDescription::kAnswer,
3367 sdp, nullptr);
3368 ASSERT_TRUE(answer != NULL);
3369 SetRemoteDescriptionWithoutError(answer);
3370
3371 // Wait for ICE state to stabilize
3372 rtc::Thread::Current()->ProcessMessages(0);
3373 EXPECT_EQ_WAIT(PeerConnectionInterface::kIceConnectionCompleted,
3374 observer_.ice_connection_state_, kIceCandidatesTimeout);
3375
3376 // No ICE state changes are expected to happen.
3377 EXPECT_EQ(0, observer_.ice_connection_state_history_.size());
3378}
3379
Peter Thatcheraf55ccc2015-05-21 07:48:41 -07003380TEST_F(WebRtcSessionTest, TestRequireRtcpMux) {
3381 InitWithRtcpMuxPolicy(PeerConnectionInterface::kRtcpMuxPolicyRequire);
deadbeefab9b2d12015-10-14 11:33:11 -07003382 SendAudioVideoStream1();
Peter Thatcheraf55ccc2015-05-21 07:48:41 -07003383
3384 PeerConnectionInterface::RTCOfferAnswerOptions options;
3385 SessionDescriptionInterface* offer = CreateOffer(options);
3386 SetLocalDescriptionWithoutError(offer);
3387
deadbeefcbecd352015-09-23 11:50:27 -07003388 EXPECT_TRUE(session_->voice_rtcp_transport_channel() == NULL);
3389 EXPECT_TRUE(session_->video_rtcp_transport_channel() == NULL);
Peter Thatcheraf55ccc2015-05-21 07:48:41 -07003390
deadbeefab9b2d12015-10-14 11:33:11 -07003391 SendAudioVideoStream2();
Peter Thatcheraf55ccc2015-05-21 07:48:41 -07003392 SessionDescriptionInterface* answer =
3393 CreateRemoteAnswer(session_->local_description());
3394 SetRemoteDescriptionWithoutError(answer);
3395
deadbeefcbecd352015-09-23 11:50:27 -07003396 EXPECT_TRUE(session_->voice_rtcp_transport_channel() == NULL);
3397 EXPECT_TRUE(session_->video_rtcp_transport_channel() == NULL);
Peter Thatcheraf55ccc2015-05-21 07:48:41 -07003398}
3399
3400TEST_F(WebRtcSessionTest, TestNegotiateRtcpMux) {
3401 InitWithRtcpMuxPolicy(PeerConnectionInterface::kRtcpMuxPolicyNegotiate);
deadbeefab9b2d12015-10-14 11:33:11 -07003402 SendAudioVideoStream1();
Peter Thatcheraf55ccc2015-05-21 07:48:41 -07003403
3404 PeerConnectionInterface::RTCOfferAnswerOptions options;
3405 SessionDescriptionInterface* offer = CreateOffer(options);
3406 SetLocalDescriptionWithoutError(offer);
3407
deadbeefcbecd352015-09-23 11:50:27 -07003408 EXPECT_TRUE(session_->voice_rtcp_transport_channel() != NULL);
3409 EXPECT_TRUE(session_->video_rtcp_transport_channel() != NULL);
Peter Thatcheraf55ccc2015-05-21 07:48:41 -07003410
deadbeefab9b2d12015-10-14 11:33:11 -07003411 SendAudioVideoStream2();
Peter Thatcheraf55ccc2015-05-21 07:48:41 -07003412 SessionDescriptionInterface* answer =
3413 CreateRemoteAnswer(session_->local_description());
3414 SetRemoteDescriptionWithoutError(answer);
3415
deadbeefcbecd352015-09-23 11:50:27 -07003416 EXPECT_TRUE(session_->voice_rtcp_transport_channel() == NULL);
3417 EXPECT_TRUE(session_->video_rtcp_transport_channel() == NULL);
Peter Thatcheraf55ccc2015-05-21 07:48:41 -07003418}
3419
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00003420// This test verifies that SetLocalDescription and SetRemoteDescription fails
3421// if BUNDLE is enabled but rtcp-mux is disabled in m-lines.
3422TEST_F(WebRtcSessionTest, TestDisabledRtcpMuxWithBundleEnabled) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003423 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07003424 SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003425
3426 PeerConnectionInterface::RTCOfferAnswerOptions options;
3427 options.use_rtp_mux = true;
3428
3429 SessionDescriptionInterface* offer = CreateOffer(options);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00003430 std::string offer_str;
3431 offer->ToString(&offer_str);
3432 // Disable rtcp-mux
3433 const std::string rtcp_mux = "rtcp-mux";
3434 const std::string xrtcp_mux = "xrtcp-mux";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003435 rtc::replace_substrs(rtcp_mux.c_str(), rtcp_mux.length(),
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00003436 xrtcp_mux.c_str(), xrtcp_mux.length(),
3437 &offer_str);
deadbeefcbecd352015-09-23 11:50:27 -07003438 JsepSessionDescription* local_offer =
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00003439 new JsepSessionDescription(JsepSessionDescription::kOffer);
3440 EXPECT_TRUE((local_offer)->Initialize(offer_str, NULL));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003441 SetLocalDescriptionOfferExpectError(kBundleWithoutRtcpMux, local_offer);
deadbeefcbecd352015-09-23 11:50:27 -07003442 JsepSessionDescription* remote_offer =
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00003443 new JsepSessionDescription(JsepSessionDescription::kOffer);
3444 EXPECT_TRUE((remote_offer)->Initialize(offer_str, NULL));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003445 SetRemoteDescriptionOfferExpectError(kBundleWithoutRtcpMux, remote_offer);
henrike@webrtc.org1e09a712013-07-26 19:17:59 +00003446 // Trying unmodified SDP.
3447 SetLocalDescriptionWithoutError(offer);
3448}
3449
jbauchcb560652016-08-04 05:20:32 -07003450TEST_F(WebRtcSessionTest, SetSetupGcm) {
3451 InitWithGcm();
3452 SendAudioVideoStream1();
3453 CreateAndSetRemoteOfferAndLocalAnswer();
3454}
3455
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003456TEST_F(WebRtcSessionTest, CanNotInsertDtmf) {
3457 TestCanInsertDtmf(false);
3458}
3459
3460TEST_F(WebRtcSessionTest, CanInsertDtmf) {
3461 TestCanInsertDtmf(true);
3462}
3463
3464TEST_F(WebRtcSessionTest, InsertDtmf) {
3465 // Setup
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003466 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07003467 SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003468 CreateAndSetRemoteOfferAndLocalAnswer();
3469 FakeVoiceMediaChannel* channel = media_engine_->GetVoiceChannel(0);
3470 EXPECT_EQ(0U, channel->dtmf_info_queue().size());
3471
3472 // Insert DTMF
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003473 const int expected_duration = 90;
3474 session_->InsertDtmf(kAudioTrack1, 0, expected_duration);
3475 session_->InsertDtmf(kAudioTrack1, 1, expected_duration);
3476 session_->InsertDtmf(kAudioTrack1, 2, expected_duration);
3477
3478 // Verify
3479 ASSERT_EQ(3U, channel->dtmf_info_queue().size());
Peter Boström0c4e06b2015-10-07 12:23:21 +02003480 const uint32_t send_ssrc = channel->send_streams()[0].first_ssrc();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003481 EXPECT_TRUE(CompareDtmfInfo(channel->dtmf_info_queue()[0], send_ssrc, 0,
solenberg1d63dd02015-12-02 12:35:09 -08003482 expected_duration));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003483 EXPECT_TRUE(CompareDtmfInfo(channel->dtmf_info_queue()[1], send_ssrc, 1,
solenberg1d63dd02015-12-02 12:35:09 -08003484 expected_duration));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003485 EXPECT_TRUE(CompareDtmfInfo(channel->dtmf_info_queue()[2], send_ssrc, 2,
solenberg1d63dd02015-12-02 12:35:09 -08003486 expected_duration));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003487}
3488
deadbeefd59daf82015-10-14 15:02:44 -07003489// This test verifies the |initial_offerer| flag when session initiates the
3490// call.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003491TEST_F(WebRtcSessionTest, TestInitiatorFlagAsOriginator) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003492 Init();
deadbeefd59daf82015-10-14 15:02:44 -07003493 EXPECT_FALSE(session_->initial_offerer());
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003494 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003495 SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
3496 SetLocalDescriptionWithoutError(offer);
deadbeefd59daf82015-10-14 15:02:44 -07003497 EXPECT_TRUE(session_->initial_offerer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003498 SetRemoteDescriptionWithoutError(answer);
deadbeefd59daf82015-10-14 15:02:44 -07003499 EXPECT_TRUE(session_->initial_offerer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003500}
3501
deadbeefd59daf82015-10-14 15:02:44 -07003502// This test verifies the |initial_offerer| flag when session receives the call.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003503TEST_F(WebRtcSessionTest, TestInitiatorFlagAsReceiver) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003504 Init();
deadbeefd59daf82015-10-14 15:02:44 -07003505 EXPECT_FALSE(session_->initial_offerer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003506 SessionDescriptionInterface* offer = CreateRemoteOffer();
3507 SetRemoteDescriptionWithoutError(offer);
htaa2a49d92016-03-04 02:51:39 -08003508 SessionDescriptionInterface* answer = CreateAnswer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003509
deadbeefd59daf82015-10-14 15:02:44 -07003510 EXPECT_FALSE(session_->initial_offerer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003511 SetLocalDescriptionWithoutError(answer);
deadbeefd59daf82015-10-14 15:02:44 -07003512 EXPECT_FALSE(session_->initial_offerer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003513}
3514
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003515// Verifing local offer and remote answer have matching m-lines as per RFC 3264.
3516TEST_F(WebRtcSessionTest, TestIncorrectMLinesInRemoteAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003517 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07003518 SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003519 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003520 SetLocalDescriptionWithoutError(offer);
kwibergd1fe2812016-04-27 06:47:29 -07003521 std::unique_ptr<SessionDescriptionInterface> answer(
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003522 CreateRemoteAnswer(session_->local_description()));
3523
3524 cricket::SessionDescription* answer_copy = answer->description()->Copy();
3525 answer_copy->RemoveContentByName("video");
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00003526 JsepSessionDescription* modified_answer =
3527 new JsepSessionDescription(JsepSessionDescription::kAnswer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003528
3529 EXPECT_TRUE(modified_answer->Initialize(answer_copy,
3530 answer->session_id(),
3531 answer->session_version()));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003532 SetRemoteDescriptionAnswerExpectError(kMlineMismatch, modified_answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003533
wu@webrtc.org4e393072014-04-07 17:04:35 +00003534 // Different content names.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003535 std::string sdp;
3536 EXPECT_TRUE(answer->ToString(&sdp));
3537 const std::string kAudioMid = "a=mid:audio";
3538 const std::string kAudioMidReplaceStr = "a=mid:audio_content_name";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003539 rtc::replace_substrs(kAudioMid.c_str(), kAudioMid.length(),
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003540 kAudioMidReplaceStr.c_str(),
3541 kAudioMidReplaceStr.length(),
3542 &sdp);
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00003543 SessionDescriptionInterface* modified_answer1 =
3544 CreateSessionDescription(JsepSessionDescription::kAnswer, sdp, NULL);
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003545 SetRemoteDescriptionAnswerExpectError(kMlineMismatch, modified_answer1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003546
wu@webrtc.org4e393072014-04-07 17:04:35 +00003547 // Different media types.
3548 EXPECT_TRUE(answer->ToString(&sdp));
3549 const std::string kAudioMline = "m=audio";
3550 const std::string kAudioMlineReplaceStr = "m=video";
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003551 rtc::replace_substrs(kAudioMline.c_str(), kAudioMline.length(),
wu@webrtc.org4e393072014-04-07 17:04:35 +00003552 kAudioMlineReplaceStr.c_str(),
3553 kAudioMlineReplaceStr.length(),
3554 &sdp);
3555 SessionDescriptionInterface* modified_answer2 =
3556 CreateSessionDescription(JsepSessionDescription::kAnswer, sdp, NULL);
3557 SetRemoteDescriptionAnswerExpectError(kMlineMismatch, modified_answer2);
3558
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003559 SetRemoteDescriptionWithoutError(answer.release());
3560}
3561
3562// Verifying remote offer and local answer have matching m-lines as per
3563// RFC 3264.
3564TEST_F(WebRtcSessionTest, TestIncorrectMLinesInLocalAnswer) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003565 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07003566 SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003567 SessionDescriptionInterface* offer = CreateRemoteOffer();
3568 SetRemoteDescriptionWithoutError(offer);
htaa2a49d92016-03-04 02:51:39 -08003569 SessionDescriptionInterface* answer = CreateAnswer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003570
3571 cricket::SessionDescription* answer_copy = answer->description()->Copy();
3572 answer_copy->RemoveContentByName("video");
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00003573 JsepSessionDescription* modified_answer =
3574 new JsepSessionDescription(JsepSessionDescription::kAnswer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003575
3576 EXPECT_TRUE(modified_answer->Initialize(answer_copy,
3577 answer->session_id(),
3578 answer->session_version()));
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003579 SetLocalDescriptionAnswerExpectError(kMlineMismatch, modified_answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003580 SetLocalDescriptionWithoutError(answer);
3581}
3582
3583// This test verifies that WebRtcSession does not start candidate allocation
3584// before SetLocalDescription is called.
3585TEST_F(WebRtcSessionTest, TestIceStartAfterSetLocalDescriptionOnly) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003586 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07003587 SendAudioVideoStream1();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003588 SessionDescriptionInterface* offer = CreateRemoteOffer();
3589 cricket::Candidate candidate;
3590 candidate.set_component(1);
3591 JsepIceCandidate ice_candidate(kMediaContentName0, kMediaContentIndex0,
3592 candidate);
3593 EXPECT_TRUE(offer->AddCandidate(&ice_candidate));
3594 cricket::Candidate candidate1;
3595 candidate1.set_component(1);
3596 JsepIceCandidate ice_candidate1(kMediaContentName1, kMediaContentIndex1,
3597 candidate1);
3598 EXPECT_TRUE(offer->AddCandidate(&ice_candidate1));
3599 SetRemoteDescriptionWithoutError(offer);
deadbeefcbecd352015-09-23 11:50:27 -07003600 ASSERT_TRUE(session_->voice_rtp_transport_channel() != NULL);
3601 ASSERT_TRUE(session_->video_rtp_transport_channel() != NULL);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003602
3603 // Pump for 1 second and verify that no candidates are generated.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003604 rtc::Thread::Current()->ProcessMessages(1000);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003605 EXPECT_TRUE(observer_.mline_0_candidates_.empty());
3606 EXPECT_TRUE(observer_.mline_1_candidates_.empty());
3607
htaa2a49d92016-03-04 02:51:39 -08003608 SessionDescriptionInterface* answer = CreateAnswer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003609 SetLocalDescriptionWithoutError(answer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003610 EXPECT_TRUE_WAIT(observer_.oncandidatesready_, kIceCandidatesTimeout);
3611}
3612
3613// This test verifies that crypto parameter is updated in local session
3614// description as per security policy set in MediaSessionDescriptionFactory.
3615TEST_F(WebRtcSessionTest, TestCryptoAfterSetLocalDescription) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003616 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07003617 SendAudioVideoStream1();
kwibergd1fe2812016-04-27 06:47:29 -07003618 std::unique_ptr<SessionDescriptionInterface> offer(CreateOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003619
3620 // Making sure SetLocalDescription correctly sets crypto value in
3621 // SessionDescription object after de-serialization of sdp string. The value
3622 // will be set as per MediaSessionDescriptionFactory.
3623 std::string offer_str;
3624 offer->ToString(&offer_str);
3625 SessionDescriptionInterface* jsep_offer_str =
3626 CreateSessionDescription(JsepSessionDescription::kOffer, offer_str, NULL);
3627 SetLocalDescriptionWithoutError(jsep_offer_str);
3628 EXPECT_TRUE(session_->voice_channel()->secure_required());
3629 EXPECT_TRUE(session_->video_channel()->secure_required());
3630}
3631
3632// This test verifies the crypto parameter when security is disabled.
3633TEST_F(WebRtcSessionTest, TestCryptoAfterSetLocalDescriptionWithDisabled) {
wu@webrtc.org97077a32013-10-25 21:18:33 +00003634 options_.disable_encryption = true;
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003635 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07003636 SendAudioVideoStream1();
kwibergd1fe2812016-04-27 06:47:29 -07003637 std::unique_ptr<SessionDescriptionInterface> offer(CreateOffer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003638
3639 // Making sure SetLocalDescription correctly sets crypto value in
3640 // SessionDescription object after de-serialization of sdp string. The value
3641 // will be set as per MediaSessionDescriptionFactory.
3642 std::string offer_str;
3643 offer->ToString(&offer_str);
deadbeefcbecd352015-09-23 11:50:27 -07003644 SessionDescriptionInterface* jsep_offer_str =
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003645 CreateSessionDescription(JsepSessionDescription::kOffer, offer_str, NULL);
3646 SetLocalDescriptionWithoutError(jsep_offer_str);
3647 EXPECT_FALSE(session_->voice_channel()->secure_required());
3648 EXPECT_FALSE(session_->video_channel()->secure_required());
3649}
3650
3651// This test verifies that an answer contains new ufrag and password if an offer
3652// with new ufrag and password is received.
3653TEST_F(WebRtcSessionTest, TestCreateAnswerWithNewUfragAndPassword) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003654 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003655 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00003656 options.recv_video = true;
kwibergd1fe2812016-04-27 06:47:29 -07003657 std::unique_ptr<JsepSessionDescription> offer(CreateRemoteOffer(options));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003658 SetRemoteDescriptionWithoutError(offer.release());
3659
deadbeefab9b2d12015-10-14 11:33:11 -07003660 SendAudioVideoStream1();
kwibergd1fe2812016-04-27 06:47:29 -07003661 std::unique_ptr<SessionDescriptionInterface> answer(CreateAnswer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003662 SetLocalDescriptionWithoutError(answer.release());
3663
3664 // Receive an offer with new ufrag and password.
deadbeef0ed85b22016-02-23 17:24:52 -08003665 for (const cricket::ContentInfo& content :
3666 session_->local_description()->description()->contents()) {
3667 options.transport_options[content.name].ice_restart = true;
3668 }
kwibergd1fe2812016-04-27 06:47:29 -07003669 std::unique_ptr<JsepSessionDescription> updated_offer1(
wu@webrtc.org91053e72013-08-10 07:18:04 +00003670 CreateRemoteOffer(options, session_->remote_description()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003671 SetRemoteDescriptionWithoutError(updated_offer1.release());
3672
kwibergd1fe2812016-04-27 06:47:29 -07003673 std::unique_ptr<SessionDescriptionInterface> updated_answer1(CreateAnswer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003674
deadbeef0ed85b22016-02-23 17:24:52 -08003675 EXPECT_FALSE(IceUfragPwdEqual(updated_answer1->description(),
3676 session_->local_description()->description()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003677
deadbeef0ed85b22016-02-23 17:24:52 -08003678 // Even a second answer (created before the description is set) should have
3679 // a new ufrag/password.
kwibergd1fe2812016-04-27 06:47:29 -07003680 std::unique_ptr<SessionDescriptionInterface> updated_answer2(CreateAnswer());
deadbeef0ed85b22016-02-23 17:24:52 -08003681
3682 EXPECT_FALSE(IceUfragPwdEqual(updated_answer2->description(),
3683 session_->local_description()->description()));
3684
3685 SetLocalDescriptionWithoutError(updated_answer2.release());
3686}
3687
3688// This test verifies that an answer contains new ufrag and password if an offer
3689// that changes either the ufrag or password (but not both) is received.
3690// RFC 5245 says: "If the offer contained a change in the a=ice-ufrag or
3691// a=ice-pwd attributes compared to the previous SDP from the peer, it
3692// indicates that ICE is restarting for this media stream."
3693TEST_F(WebRtcSessionTest, TestOfferChangingOnlyUfragOrPassword) {
3694 Init();
3695 cricket::MediaSessionOptions options;
3696 options.recv_audio = true;
3697 options.recv_video = true;
3698 // Create an offer with audio and video.
kwibergd1fe2812016-04-27 06:47:29 -07003699 std::unique_ptr<JsepSessionDescription> offer(CreateRemoteOffer(options));
deadbeef0ed85b22016-02-23 17:24:52 -08003700 SetIceUfragPwd(offer.get(), "original_ufrag", "original_password12345");
3701 SetRemoteDescriptionWithoutError(offer.release());
3702
3703 SendAudioVideoStream1();
kwibergd1fe2812016-04-27 06:47:29 -07003704 std::unique_ptr<SessionDescriptionInterface> answer(CreateAnswer());
deadbeef0ed85b22016-02-23 17:24:52 -08003705 SetLocalDescriptionWithoutError(answer.release());
3706
3707 // Receive an offer with a new ufrag but stale password.
kwibergd1fe2812016-04-27 06:47:29 -07003708 std::unique_ptr<JsepSessionDescription> ufrag_changed_offer(
deadbeef0ed85b22016-02-23 17:24:52 -08003709 CreateRemoteOffer(options, session_->remote_description()));
3710 SetIceUfragPwd(ufrag_changed_offer.get(), "modified_ufrag",
3711 "original_password12345");
3712 SetRemoteDescriptionWithoutError(ufrag_changed_offer.release());
3713
kwibergd1fe2812016-04-27 06:47:29 -07003714 std::unique_ptr<SessionDescriptionInterface> updated_answer1(CreateAnswer());
deadbeef0ed85b22016-02-23 17:24:52 -08003715 EXPECT_FALSE(IceUfragPwdEqual(updated_answer1->description(),
3716 session_->local_description()->description()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003717 SetLocalDescriptionWithoutError(updated_answer1.release());
deadbeef0ed85b22016-02-23 17:24:52 -08003718
3719 // Receive an offer with a new password but stale ufrag.
kwibergd1fe2812016-04-27 06:47:29 -07003720 std::unique_ptr<JsepSessionDescription> password_changed_offer(
deadbeef0ed85b22016-02-23 17:24:52 -08003721 CreateRemoteOffer(options, session_->remote_description()));
3722 SetIceUfragPwd(password_changed_offer.get(), "modified_ufrag",
3723 "modified_password12345");
3724 SetRemoteDescriptionWithoutError(password_changed_offer.release());
3725
kwibergd1fe2812016-04-27 06:47:29 -07003726 std::unique_ptr<SessionDescriptionInterface> updated_answer2(CreateAnswer());
deadbeef0ed85b22016-02-23 17:24:52 -08003727 EXPECT_FALSE(IceUfragPwdEqual(updated_answer2->description(),
3728 session_->local_description()->description()));
3729 SetLocalDescriptionWithoutError(updated_answer2.release());
wu@webrtc.org91053e72013-08-10 07:18:04 +00003730}
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003731
wu@webrtc.org91053e72013-08-10 07:18:04 +00003732// This test verifies that an answer contains old ufrag and password if an offer
3733// with old ufrag and password is received.
3734TEST_F(WebRtcSessionTest, TestCreateAnswerWithOldUfragAndPassword) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003735 Init();
wu@webrtc.org91053e72013-08-10 07:18:04 +00003736 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00003737 options.recv_video = true;
kwibergd1fe2812016-04-27 06:47:29 -07003738 std::unique_ptr<JsepSessionDescription> offer(CreateRemoteOffer(options));
wu@webrtc.org91053e72013-08-10 07:18:04 +00003739 SetRemoteDescriptionWithoutError(offer.release());
3740
deadbeefab9b2d12015-10-14 11:33:11 -07003741 SendAudioVideoStream1();
kwibergd1fe2812016-04-27 06:47:29 -07003742 std::unique_ptr<SessionDescriptionInterface> answer(CreateAnswer());
wu@webrtc.org91053e72013-08-10 07:18:04 +00003743 SetLocalDescriptionWithoutError(answer.release());
3744
3745 // Receive an offer without changed ufrag or password.
kwibergd1fe2812016-04-27 06:47:29 -07003746 std::unique_ptr<JsepSessionDescription> updated_offer2(
wu@webrtc.org91053e72013-08-10 07:18:04 +00003747 CreateRemoteOffer(options, session_->remote_description()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003748 SetRemoteDescriptionWithoutError(updated_offer2.release());
3749
kwibergd1fe2812016-04-27 06:47:29 -07003750 std::unique_ptr<SessionDescriptionInterface> updated_answer2(CreateAnswer());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003751
deadbeef0ed85b22016-02-23 17:24:52 -08003752 EXPECT_TRUE(IceUfragPwdEqual(updated_answer2->description(),
3753 session_->local_description()->description()));
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003754
3755 SetLocalDescriptionWithoutError(updated_answer2.release());
3756}
3757
deadbeef0ed85b22016-02-23 17:24:52 -08003758// This test verifies that if an offer does an ICE restart on some, but not all
3759// media sections, the answer will change the ufrag/password in the correct
3760// media sections.
3761TEST_F(WebRtcSessionTest, TestCreateAnswerWithNewAndOldUfragAndPassword) {
3762 Init();
3763 cricket::MediaSessionOptions options;
3764 options.recv_video = true;
3765 options.recv_audio = true;
3766 options.bundle_enabled = false;
kwibergd1fe2812016-04-27 06:47:29 -07003767 std::unique_ptr<JsepSessionDescription> offer(CreateRemoteOffer(options));
deadbeef0ed85b22016-02-23 17:24:52 -08003768
3769 SetIceUfragPwd(offer.get(), cricket::MEDIA_TYPE_AUDIO, "aaaa",
3770 "aaaaaaaaaaaaaaaaaaaaaa");
3771 SetIceUfragPwd(offer.get(), cricket::MEDIA_TYPE_VIDEO, "bbbb",
3772 "bbbbbbbbbbbbbbbbbbbbbb");
3773 SetRemoteDescriptionWithoutError(offer.release());
3774
3775 SendAudioVideoStream1();
kwibergd1fe2812016-04-27 06:47:29 -07003776 std::unique_ptr<SessionDescriptionInterface> answer(CreateAnswer());
deadbeef0ed85b22016-02-23 17:24:52 -08003777 SetLocalDescriptionWithoutError(answer.release());
3778
3779 // Receive an offer with new ufrag and password, but only for the video media
3780 // section.
kwibergd1fe2812016-04-27 06:47:29 -07003781 std::unique_ptr<JsepSessionDescription> updated_offer(
deadbeef0ed85b22016-02-23 17:24:52 -08003782 CreateRemoteOffer(options, session_->remote_description()));
3783 SetIceUfragPwd(updated_offer.get(), cricket::MEDIA_TYPE_VIDEO, "cccc",
3784 "cccccccccccccccccccccc");
3785 SetRemoteDescriptionWithoutError(updated_offer.release());
3786
kwibergd1fe2812016-04-27 06:47:29 -07003787 std::unique_ptr<SessionDescriptionInterface> updated_answer(CreateAnswer());
deadbeef0ed85b22016-02-23 17:24:52 -08003788
3789 EXPECT_TRUE(IceUfragPwdEqual(updated_answer->description(),
3790 session_->local_description()->description(),
3791 cricket::MEDIA_TYPE_AUDIO));
3792
3793 EXPECT_FALSE(IceUfragPwdEqual(updated_answer->description(),
3794 session_->local_description()->description(),
3795 cricket::MEDIA_TYPE_VIDEO));
3796
3797 SetLocalDescriptionWithoutError(updated_answer.release());
3798}
3799
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003800TEST_F(WebRtcSessionTest, TestSessionContentError) {
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003801 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07003802 SendAudioVideoStream1();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00003803 SessionDescriptionInterface* offer = CreateOffer();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003804 const std::string session_id_orig = offer->session_id();
3805 const std::string session_version_orig = offer->session_version();
3806 SetLocalDescriptionWithoutError(offer);
3807
3808 video_channel_ = media_engine_->GetVideoChannel(0);
3809 video_channel_->set_fail_set_send_codecs(true);
3810
henrike@webrtc.org28654cb2013-07-22 21:07:49 +00003811 SessionDescriptionInterface* answer =
3812 CreateRemoteAnswer(session_->local_description());
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00003813 SetRemoteDescriptionAnswerExpectError("ERROR_CONTENT", answer);
deadbeefd59daf82015-10-14 15:02:44 -07003814
3815 // Test that after a content error, setting any description will
3816 // result in an error.
3817 video_channel_->set_fail_set_send_codecs(false);
3818 answer = CreateRemoteAnswer(session_->local_description());
3819 SetRemoteDescriptionExpectError("", "ERROR_CONTENT", answer);
3820 offer = CreateRemoteOffer();
3821 SetLocalDescriptionExpectError("", "ERROR_CONTENT", offer);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003822}
3823
3824// Runs the loopback call test with BUNDLE and STUN disabled.
3825TEST_F(WebRtcSessionTest, TestIceStatesBasic) {
3826 // Lets try with only UDP ports.
Peter Thatcher7cbd1882015-09-17 18:54:52 -07003827 allocator_->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00003828 cricket::PORTALLOCATOR_DISABLE_STUN |
3829 cricket::PORTALLOCATOR_DISABLE_RELAY);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003830 TestLoopbackCall();
3831}
3832
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00003833TEST_F(WebRtcSessionTest, TestIceStatesBasicIPv6) {
Peter Thatcher7cbd1882015-09-17 18:54:52 -07003834 allocator_->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
guoweis@webrtc.org7169afd2014-12-04 17:59:29 +00003835 cricket::PORTALLOCATOR_DISABLE_STUN |
3836 cricket::PORTALLOCATOR_ENABLE_IPV6 |
3837 cricket::PORTALLOCATOR_DISABLE_RELAY);
3838
3839 // best connection is IPv6 since it has higher network preference.
3840 LoopbackNetworkConfiguration config;
3841 config.test_ipv6_network_ = true;
3842 config.best_connection_after_initial_ice_converged_ =
3843 LoopbackNetworkConfiguration::ExpectedBestConnection(0, 1);
3844
3845 TestLoopbackCall(config);
3846}
3847
mallinath@webrtc.orgd3dc4242014-03-01 00:05:52 +00003848// Runs the loopback call test with BUNDLE and STUN enabled.
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00003849TEST_F(WebRtcSessionTest, TestIceStatesBundle) {
Peter Thatcher7cbd1882015-09-17 18:54:52 -07003850 allocator_->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
3851 cricket::PORTALLOCATOR_DISABLE_RELAY);
mallinath@webrtc.org385857d2014-02-14 00:56:12 +00003852 TestLoopbackCall();
3853}
3854
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003855TEST_F(WebRtcSessionTest, TestRtpDataChannel) {
htaa2a49d92016-03-04 02:51:39 -08003856 configuration_.enable_rtp_data_channel = true;
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00003857 Init();
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003858 SetLocalDescriptionWithDataChannel();
htaa2a49d92016-03-04 02:51:39 -08003859 ASSERT_TRUE(data_engine_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003860 EXPECT_EQ(cricket::DCT_RTP, data_engine_->last_channel_type());
3861}
3862
Henrik Boström87713d02015-08-25 09:53:21 +02003863TEST_P(WebRtcSessionTest, TestRtpDataChannelConstraintTakesPrecedence) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003864 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003865
htaa2a49d92016-03-04 02:51:39 -08003866 configuration_.enable_rtp_data_channel = true;
wu@webrtc.org97077a32013-10-25 21:18:33 +00003867 options_.disable_sctp_data_channels = false;
3868
Henrik Boström87713d02015-08-25 09:53:21 +02003869 InitWithDtls(GetParam());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003870
3871 SetLocalDescriptionWithDataChannel();
3872 EXPECT_EQ(cricket::DCT_RTP, data_engine_->last_channel_type());
3873}
3874
Henrik Boström87713d02015-08-25 09:53:21 +02003875TEST_P(WebRtcSessionTest, TestCreateOfferWithSctpEnabledWithoutStreams) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003876 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
wu@webrtc.org967bfff2013-09-19 05:49:50 +00003877
Henrik Boström87713d02015-08-25 09:53:21 +02003878 InitWithDtls(GetParam());
sergeyu@chromium.orga59696b2013-09-13 23:48:58 +00003879
kwibergd1fe2812016-04-27 06:47:29 -07003880 std::unique_ptr<SessionDescriptionInterface> offer(CreateOffer());
sergeyu@chromium.orga59696b2013-09-13 23:48:58 +00003881 EXPECT_TRUE(offer->description()->GetContentByName("data") == NULL);
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00003882 EXPECT_TRUE(offer->description()->GetTransportInfoByName("data") == NULL);
3883}
3884
Henrik Boström87713d02015-08-25 09:53:21 +02003885TEST_P(WebRtcSessionTest, TestCreateAnswerWithSctpInOfferAndNoStreams) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003886 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00003887 SetFactoryDtlsSrtp();
Henrik Boström87713d02015-08-25 09:53:21 +02003888 InitWithDtls(GetParam());
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00003889
3890 // Create remote offer with SCTP.
3891 cricket::MediaSessionOptions options;
3892 options.data_channel_type = cricket::DCT_SCTP;
3893 JsepSessionDescription* offer =
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00003894 CreateRemoteOffer(options, cricket::SEC_DISABLED);
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00003895 SetRemoteDescriptionWithoutError(offer);
3896
3897 // Verifies the answer contains SCTP.
kwibergd1fe2812016-04-27 06:47:29 -07003898 std::unique_ptr<SessionDescriptionInterface> answer(CreateAnswer());
mallinath@webrtc.org1112c302013-09-23 20:34:45 +00003899 EXPECT_TRUE(answer != NULL);
3900 EXPECT_TRUE(answer->description()->GetContentByName("data") != NULL);
3901 EXPECT_TRUE(answer->description()->GetTransportInfoByName("data") != NULL);
sergeyu@chromium.orga59696b2013-09-13 23:48:58 +00003902}
3903
Henrik Boström87713d02015-08-25 09:53:21 +02003904TEST_P(WebRtcSessionTest, TestSctpDataChannelWithoutDtls) {
htaa2a49d92016-03-04 02:51:39 -08003905 configuration_.enable_dtls_srtp = rtc::Optional<bool>(false);
Henrik Boström87713d02015-08-25 09:53:21 +02003906 InitWithDtls(GetParam());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003907
3908 SetLocalDescriptionWithDataChannel();
3909 EXPECT_EQ(cricket::DCT_NONE, data_engine_->last_channel_type());
3910}
3911
Henrik Boström87713d02015-08-25 09:53:21 +02003912TEST_P(WebRtcSessionTest, TestSctpDataChannelWithDtls) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003913 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003914
Henrik Boström87713d02015-08-25 09:53:21 +02003915 InitWithDtls(GetParam());
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003916
3917 SetLocalDescriptionWithDataChannel();
3918 EXPECT_EQ(cricket::DCT_SCTP, data_engine_->last_channel_type());
3919}
wu@webrtc.org91053e72013-08-10 07:18:04 +00003920
Henrik Boström87713d02015-08-25 09:53:21 +02003921TEST_P(WebRtcSessionTest, TestDisableSctpDataChannels) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003922 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
wu@webrtc.org97077a32013-10-25 21:18:33 +00003923 options_.disable_sctp_data_channels = true;
Henrik Boström87713d02015-08-25 09:53:21 +02003924 InitWithDtls(GetParam());
wu@webrtc.org97077a32013-10-25 21:18:33 +00003925
3926 SetLocalDescriptionWithDataChannel();
3927 EXPECT_EQ(cricket::DCT_NONE, data_engine_->last_channel_type());
3928}
3929
Henrik Boström87713d02015-08-25 09:53:21 +02003930TEST_P(WebRtcSessionTest, TestSctpDataChannelSendPortParsing) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00003931 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00003932 const int new_send_port = 9998;
3933 const int new_recv_port = 7775;
3934
Henrik Boström87713d02015-08-25 09:53:21 +02003935 InitWithDtls(GetParam());
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00003936 SetFactoryDtlsSrtp();
3937
3938 // By default, don't actually add the codecs to desc_factory_; they don't
3939 // actually get serialized for SCTP in BuildMediaDescription(). Instead,
3940 // let the session description get parsed. That'll get the proper codecs
3941 // into the stream.
3942 cricket::MediaSessionOptions options;
3943 JsepSessionDescription* offer = CreateRemoteOfferWithSctpPort(
3944 "stream1", new_send_port, options);
3945
3946 // SetRemoteDescription will take the ownership of the offer.
3947 SetRemoteDescriptionWithoutError(offer);
3948
htaa2a49d92016-03-04 02:51:39 -08003949 SessionDescriptionInterface* answer =
3950 ChangeSDPSctpPort(new_recv_port, CreateAnswer());
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00003951 ASSERT_TRUE(answer != NULL);
3952
3953 // Now set the local description, which'll take ownership of the answer.
3954 SetLocalDescriptionWithoutError(answer);
3955
3956 // TEST PLAN: Set the port number to something new, set it in the SDP,
3957 // and pass it all the way down.
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00003958 EXPECT_EQ(cricket::DCT_SCTP, data_engine_->last_channel_type());
deadbeefab9b2d12015-10-14 11:33:11 -07003959 CreateDataChannel();
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00003960
3961 cricket::FakeDataMediaChannel* ch = data_engine_->GetChannel(0);
3962 int portnum = -1;
3963 ASSERT_TRUE(ch != NULL);
3964 ASSERT_EQ(1UL, ch->send_codecs().size());
3965 EXPECT_EQ(cricket::kGoogleSctpDataCodecId, ch->send_codecs()[0].id);
Donald Curtisd4f769d2015-05-28 09:48:21 -07003966 EXPECT_EQ(0, strcmp(cricket::kGoogleSctpDataCodecName,
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00003967 ch->send_codecs()[0].name.c_str()));
3968 EXPECT_TRUE(ch->send_codecs()[0].GetParam(cricket::kCodecParamPort,
3969 &portnum));
3970 EXPECT_EQ(new_send_port, portnum);
3971
3972 ASSERT_EQ(1UL, ch->recv_codecs().size());
3973 EXPECT_EQ(cricket::kGoogleSctpDataCodecId, ch->recv_codecs()[0].id);
Donald Curtisd4f769d2015-05-28 09:48:21 -07003974 EXPECT_EQ(0, strcmp(cricket::kGoogleSctpDataCodecName,
mallinath@webrtc.org19f27e62013-10-13 17:18:27 +00003975 ch->recv_codecs()[0].name.c_str()));
3976 EXPECT_TRUE(ch->recv_codecs()[0].GetParam(cricket::kCodecParamPort,
3977 &portnum));
3978 EXPECT_EQ(new_recv_port, portnum);
3979}
3980
deadbeefab9b2d12015-10-14 11:33:11 -07003981// Verifies that when a session's DataChannel receives an OPEN message,
3982// WebRtcSession signals the DataChannel creation request with the expected
3983// config.
3984TEST_P(WebRtcSessionTest, TestSctpDataChannelOpenMessage) {
3985 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
3986
3987 InitWithDtls(GetParam());
3988
3989 SetLocalDescriptionWithDataChannel();
3990 EXPECT_EQ(cricket::DCT_SCTP, data_engine_->last_channel_type());
3991
3992 webrtc::DataChannelInit config;
3993 config.id = 1;
jbaucheec21bd2016-03-20 06:15:43 -07003994 rtc::CopyOnWriteBuffer payload;
deadbeefab9b2d12015-10-14 11:33:11 -07003995 webrtc::WriteDataChannelOpenMessage("a", config, &payload);
3996 cricket::ReceiveDataParams params;
3997 params.ssrc = config.id;
3998 params.type = cricket::DMT_CONTROL;
3999
4000 cricket::DataChannel* data_channel = session_->data_channel();
4001 data_channel->SignalDataReceived(data_channel, params, payload);
4002
4003 EXPECT_EQ("a", last_data_channel_label_);
4004 EXPECT_EQ(config.id, last_data_channel_config_.id);
4005 EXPECT_FALSE(last_data_channel_config_.negotiated);
4006 EXPECT_EQ(webrtc::InternalDataChannelInit::kAcker,
4007 last_data_channel_config_.open_handshake_role);
4008}
4009
4010TEST_P(WebRtcSessionTest, TestUsesProvidedCertificate) {
Henrik Boströmd8281982015-08-27 10:12:24 +02004011 rtc::scoped_refptr<rtc::RTCCertificate> certificate =
Henrik Boströmd79599d2016-06-01 13:58:50 +02004012 FakeRTCCertificateGenerator::GenerateCertificate();
Henrik Boströmd8281982015-08-27 10:12:24 +02004013
htaa2a49d92016-03-04 02:51:39 -08004014 configuration_.certificates.push_back(certificate);
4015 Init();
Henrik Boströmd8281982015-08-27 10:12:24 +02004016 EXPECT_TRUE_WAIT(!session_->waiting_for_certificate_for_testing(), 1000);
4017
4018 EXPECT_EQ(session_->certificate_for_testing(), certificate);
4019}
wu@webrtc.org91053e72013-08-10 07:18:04 +00004020
Henrik Boström87713d02015-08-25 09:53:21 +02004021// Verifies that CreateOffer succeeds when CreateOffer is called before async
4022// identity generation is finished (even if a certificate is provided this is
4023// an async op).
4024TEST_P(WebRtcSessionTest, TestCreateOfferBeforeIdentityRequestReturnSuccess) {
4025 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
4026 InitWithDtls(GetParam());
4027
Henrik Boströmd8281982015-08-27 10:12:24 +02004028 EXPECT_TRUE(session_->waiting_for_certificate_for_testing());
deadbeefab9b2d12015-10-14 11:33:11 -07004029 SendAudioVideoStream1();
kwibergd1fe2812016-04-27 06:47:29 -07004030 std::unique_ptr<SessionDescriptionInterface> offer(CreateOffer());
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00004031
wu@webrtc.org91053e72013-08-10 07:18:04 +00004032 EXPECT_TRUE(offer != NULL);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00004033 VerifyNoCryptoParams(offer->description(), true);
4034 VerifyFingerprintStatus(offer->description(), true);
wu@webrtc.org91053e72013-08-10 07:18:04 +00004035}
4036
4037// Verifies that CreateAnswer succeeds when CreateOffer is called before async
Henrik Boström87713d02015-08-25 09:53:21 +02004038// identity generation is finished (even if a certificate is provided this is
4039// an async op).
4040TEST_P(WebRtcSessionTest, TestCreateAnswerBeforeIdentityRequestReturnSuccess) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00004041 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
Henrik Boström87713d02015-08-25 09:53:21 +02004042 InitWithDtls(GetParam());
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00004043 SetFactoryDtlsSrtp();
wu@webrtc.org91053e72013-08-10 07:18:04 +00004044
4045 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00004046 options.recv_video = true;
kwibergd1fe2812016-04-27 06:47:29 -07004047 std::unique_ptr<JsepSessionDescription> offer(
4048 CreateRemoteOffer(options, cricket::SEC_DISABLED));
wu@webrtc.org91053e72013-08-10 07:18:04 +00004049 ASSERT_TRUE(offer.get() != NULL);
4050 SetRemoteDescriptionWithoutError(offer.release());
4051
kwibergd1fe2812016-04-27 06:47:29 -07004052 std::unique_ptr<SessionDescriptionInterface> answer(CreateAnswer());
wu@webrtc.org91053e72013-08-10 07:18:04 +00004053 EXPECT_TRUE(answer != NULL);
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00004054 VerifyNoCryptoParams(answer->description(), true);
4055 VerifyFingerprintStatus(answer->description(), true);
wu@webrtc.org91053e72013-08-10 07:18:04 +00004056}
4057
4058// Verifies that CreateOffer succeeds when CreateOffer is called after async
Henrik Boström87713d02015-08-25 09:53:21 +02004059// identity generation is finished (even if a certificate is provided this is
4060// an async op).
4061TEST_P(WebRtcSessionTest, TestCreateOfferAfterIdentityRequestReturnSuccess) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00004062 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
Henrik Boström87713d02015-08-25 09:53:21 +02004063 InitWithDtls(GetParam());
wu@webrtc.org91053e72013-08-10 07:18:04 +00004064
Henrik Boströmd8281982015-08-27 10:12:24 +02004065 EXPECT_TRUE_WAIT(!session_->waiting_for_certificate_for_testing(), 1000);
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00004066
kwibergd1fe2812016-04-27 06:47:29 -07004067 std::unique_ptr<SessionDescriptionInterface> offer(CreateOffer());
wu@webrtc.org91053e72013-08-10 07:18:04 +00004068 EXPECT_TRUE(offer != NULL);
4069}
4070
4071// Verifies that CreateOffer fails when CreateOffer is called after async
4072// identity generation fails.
4073TEST_F(WebRtcSessionTest, TestCreateOfferAfterIdentityRequestReturnFailure) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00004074 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
Henrik Boström87713d02015-08-25 09:53:21 +02004075 InitWithDtlsIdentityGenFail();
wu@webrtc.org91053e72013-08-10 07:18:04 +00004076
Henrik Boströmd8281982015-08-27 10:12:24 +02004077 EXPECT_TRUE_WAIT(!session_->waiting_for_certificate_for_testing(), 1000);
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00004078
kwibergd1fe2812016-04-27 06:47:29 -07004079 std::unique_ptr<SessionDescriptionInterface> offer(CreateOffer());
wu@webrtc.org91053e72013-08-10 07:18:04 +00004080 EXPECT_TRUE(offer == NULL);
4081}
4082
4083// Verifies that CreateOffer succeeds when Multiple CreateOffer calls are made
4084// before async identity generation is finished.
Henrik Boström87713d02015-08-25 09:53:21 +02004085TEST_P(WebRtcSessionTest,
wu@webrtc.org91053e72013-08-10 07:18:04 +00004086 TestMultipleCreateOfferBeforeIdentityRequestReturnSuccess) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00004087 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
deadbeefcbecd352015-09-23 11:50:27 -07004088 VerifyMultipleAsyncCreateDescription(GetParam(),
4089 CreateSessionDescriptionRequest::kOffer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00004090}
4091
4092// Verifies that CreateOffer fails when Multiple CreateOffer calls are made
4093// before async identity generation fails.
4094TEST_F(WebRtcSessionTest,
4095 TestMultipleCreateOfferBeforeIdentityRequestReturnFailure) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00004096 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
Henrik Boström87713d02015-08-25 09:53:21 +02004097 VerifyMultipleAsyncCreateDescriptionIdentityGenFailure(
4098 CreateSessionDescriptionRequest::kOffer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00004099}
4100
4101// Verifies that CreateAnswer succeeds when Multiple CreateAnswer calls are made
4102// before async identity generation is finished.
Henrik Boström87713d02015-08-25 09:53:21 +02004103TEST_P(WebRtcSessionTest,
wu@webrtc.org91053e72013-08-10 07:18:04 +00004104 TestMultipleCreateAnswerBeforeIdentityRequestReturnSuccess) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00004105 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
wu@webrtc.org91053e72013-08-10 07:18:04 +00004106 VerifyMultipleAsyncCreateDescription(
Henrik Boström87713d02015-08-25 09:53:21 +02004107 GetParam(), CreateSessionDescriptionRequest::kAnswer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00004108}
4109
4110// Verifies that CreateAnswer fails when Multiple CreateAnswer calls are made
4111// before async identity generation fails.
4112TEST_F(WebRtcSessionTest,
4113 TestMultipleCreateAnswerBeforeIdentityRequestReturnFailure) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00004114 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
Henrik Boström87713d02015-08-25 09:53:21 +02004115 VerifyMultipleAsyncCreateDescriptionIdentityGenFailure(
4116 CreateSessionDescriptionRequest::kAnswer);
wu@webrtc.org91053e72013-08-10 07:18:04 +00004117}
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00004118
4119// Verifies that setRemoteDescription fails when DTLS is disabled and the remote
4120// offer has no SDES crypto but only DTLS fingerprint.
4121TEST_F(WebRtcSessionTest, TestSetRemoteOfferFailIfDtlsDisabledAndNoCrypto) {
4122 // Init without DTLS.
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00004123 Init();
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00004124 // Create a remote offer with secured transport disabled.
4125 cricket::MediaSessionOptions options;
4126 JsepSessionDescription* offer(CreateRemoteOffer(
4127 options, cricket::SEC_DISABLED));
4128 // Adds a DTLS fingerprint to the remote offer.
4129 cricket::SessionDescription* sdp = offer->description();
4130 TransportInfo* audio = sdp->GetTransportInfoByName("audio");
4131 ASSERT_TRUE(audio != NULL);
4132 ASSERT_TRUE(audio->description.identity_fingerprint.get() == NULL);
4133 audio->description.identity_fingerprint.reset(
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00004134 rtc::SSLFingerprint::CreateFromRfc4572(
4135 rtc::DIGEST_SHA_256, kFakeDtlsFingerprint));
henrike@webrtc.orgb90991d2014-03-04 19:54:57 +00004136 SetRemoteDescriptionOfferExpectError(kSdpWithoutSdesCrypto,
sergeyu@chromium.org4b26e2e2014-01-15 23:15:54 +00004137 offer);
mallinath@webrtc.orga27be8e2013-09-27 23:04:10 +00004138}
4139
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +00004140TEST_F(WebRtcSessionTest, TestCombinedAudioVideoBweConstraint) {
htaa2a49d92016-03-04 02:51:39 -08004141 configuration_.combined_audio_video_bwe = rtc::Optional<bool>(true);
pthatcher@webrtc.org877ac762015-02-04 22:03:09 +00004142 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07004143 SendAudioVideoStream1();
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +00004144 SessionDescriptionInterface* offer = CreateOffer();
4145
4146 SetLocalDescriptionWithoutError(offer);
4147
4148 voice_channel_ = media_engine_->GetVoiceChannel(0);
4149
4150 ASSERT_TRUE(voice_channel_ != NULL);
solenberg66f43392015-09-09 01:36:22 -07004151 const cricket::AudioOptions& audio_options = voice_channel_->options();
Karl Wibergbe579832015-11-10 22:34:18 +01004152 EXPECT_EQ(rtc::Optional<bool>(true), audio_options.combined_audio_video_bwe);
buildbot@webrtc.orgb4c7b092014-08-25 12:11:58 +00004153}
4154
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00004155// Tests that we can renegotiate new media content with ICE candidates in the
4156// new remote SDP.
Henrik Boström87713d02015-08-25 09:53:21 +02004157TEST_P(WebRtcSessionTest, TestRenegotiateNewMediaWithCandidatesInSdp) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00004158 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
Henrik Boström87713d02015-08-25 09:53:21 +02004159 InitWithDtls(GetParam());
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00004160 SetFactoryDtlsSrtp();
4161
deadbeefab9b2d12015-10-14 11:33:11 -07004162 SendAudioOnlyStream2();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00004163 SessionDescriptionInterface* offer = CreateOffer();
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00004164 SetLocalDescriptionWithoutError(offer);
4165
4166 SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
4167 SetRemoteDescriptionWithoutError(answer);
4168
4169 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00004170 options.recv_video = true;
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00004171 offer = CreateRemoteOffer(options, cricket::SEC_DISABLED);
4172
4173 cricket::Candidate candidate1;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00004174 candidate1.set_address(rtc::SocketAddress("1.1.1.1", 5000));
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00004175 candidate1.set_component(1);
4176 JsepIceCandidate ice_candidate(kMediaContentName1, kMediaContentIndex1,
4177 candidate1);
4178 EXPECT_TRUE(offer->AddCandidate(&ice_candidate));
4179 SetRemoteDescriptionWithoutError(offer);
4180
htaa2a49d92016-03-04 02:51:39 -08004181 answer = CreateAnswer();
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00004182 SetLocalDescriptionWithoutError(answer);
4183}
4184
4185// Tests that we can renegotiate new media content with ICE candidates separated
4186// from the remote SDP.
Henrik Boström87713d02015-08-25 09:53:21 +02004187TEST_P(WebRtcSessionTest, TestRenegotiateNewMediaWithCandidatesSeparated) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00004188 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
Henrik Boström87713d02015-08-25 09:53:21 +02004189 InitWithDtls(GetParam());
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00004190 SetFactoryDtlsSrtp();
4191
deadbeefab9b2d12015-10-14 11:33:11 -07004192 SendAudioOnlyStream2();
jiayl@webrtc.orgb18bf5e2014-08-04 18:34:16 +00004193 SessionDescriptionInterface* offer = CreateOffer();
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00004194 SetLocalDescriptionWithoutError(offer);
4195
4196 SessionDescriptionInterface* answer = CreateRemoteAnswer(offer);
4197 SetRemoteDescriptionWithoutError(answer);
4198
4199 cricket::MediaSessionOptions options;
jiayl@webrtc.org742922b2014-10-07 21:32:43 +00004200 options.recv_video = true;
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00004201 offer = CreateRemoteOffer(options, cricket::SEC_DISABLED);
4202 SetRemoteDescriptionWithoutError(offer);
4203
4204 cricket::Candidate candidate1;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +00004205 candidate1.set_address(rtc::SocketAddress("1.1.1.1", 5000));
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00004206 candidate1.set_component(1);
4207 JsepIceCandidate ice_candidate(kMediaContentName1, kMediaContentIndex1,
4208 candidate1);
4209 EXPECT_TRUE(session_->ProcessIceMessage(&ice_candidate));
4210
htaa2a49d92016-03-04 02:51:39 -08004211 answer = CreateAnswer();
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00004212 SetLocalDescriptionWithoutError(answer);
4213}
honghaiz7f777492016-02-02 21:54:01 -08004214
zhihuang34b54c32016-08-04 11:06:50 -07004215#ifdef HAVE_QUIC
4216TEST_P(WebRtcSessionTest, TestNegotiateQuic) {
4217 configuration_.enable_quic = true;
4218 InitWithDtls(GetParam());
4219 EXPECT_TRUE(session_->data_channel_type() == cricket::DCT_QUIC);
4220 SessionDescriptionInterface* offer = CreateOffer();
4221 ASSERT_TRUE(offer);
4222 ASSERT_TRUE(offer->description());
4223 SetLocalDescriptionWithoutError(offer);
4224 cricket::MediaSessionOptions options;
4225 options.recv_audio = true;
4226 options.recv_video = true;
4227 SessionDescriptionInterface* answer =
4228 CreateRemoteAnswer(offer, options, cricket::SEC_DISABLED);
4229 ASSERT_TRUE(answer);
4230 ASSERT_TRUE(answer->description());
4231 SetRemoteDescriptionWithoutError(answer);
4232}
4233#endif // HAVE_QUIC
4234
changbin.shao@webrtc.org2d25b442015-03-16 04:14:34 +00004235// Tests that RTX codec is removed from the answer when it isn't supported
4236// by local side.
zhihuang3a334652016-05-05 18:37:49 -07004237TEST_F(WebRtcSessionTest, TestRtxRemovedByCreateAnswer) {
changbin.shao@webrtc.org2d25b442015-03-16 04:14:34 +00004238 Init();
deadbeefab9b2d12015-10-14 11:33:11 -07004239 SendAudioVideoStream1();
changbin.shao@webrtc.org2d25b442015-03-16 04:14:34 +00004240 std::string offer_sdp(kSdpWithRtx);
4241
4242 SessionDescriptionInterface* offer =
4243 CreateSessionDescription(JsepSessionDescription::kOffer, offer_sdp, NULL);
4244 EXPECT_TRUE(offer->ToString(&offer_sdp));
4245
4246 // Offer SDP contains the RTX codec.
zhihuang3a334652016-05-05 18:37:49 -07004247 EXPECT_TRUE(ContainsVideoCodecWithName(offer, "rtx"));
changbin.shao@webrtc.org2d25b442015-03-16 04:14:34 +00004248 SetRemoteDescriptionWithoutError(offer);
4249
htaa2a49d92016-03-04 02:51:39 -08004250 SessionDescriptionInterface* answer = CreateAnswer();
zhihuang3a334652016-05-05 18:37:49 -07004251 // Answer SDP does not contain the RTX codec.
4252 EXPECT_FALSE(ContainsVideoCodecWithName(answer, "rtx"));
changbin.shao@webrtc.org2d25b442015-03-16 04:14:34 +00004253 SetLocalDescriptionWithoutError(answer);
4254}
jiayl@webrtc.orge10d28c2014-07-17 17:07:49 +00004255
guoweis@webrtc.org4f852882015-03-12 20:09:44 +00004256// This verifies that the voice channel after bundle has both options from video
4257// and voice channels.
4258TEST_F(WebRtcSessionTest, TestSetSocketOptionBeforeBundle) {
4259 InitWithBundlePolicy(PeerConnectionInterface::kBundlePolicyBalanced);
deadbeefab9b2d12015-10-14 11:33:11 -07004260 SendAudioVideoStream1();
guoweis@webrtc.org4f852882015-03-12 20:09:44 +00004261
4262 PeerConnectionInterface::RTCOfferAnswerOptions options;
4263 options.use_rtp_mux = true;
4264
4265 SessionDescriptionInterface* offer = CreateOffer(options);
4266 SetLocalDescriptionWithoutError(offer);
4267
4268 session_->video_channel()->SetOption(cricket::BaseChannel::ST_RTP,
4269 rtc::Socket::Option::OPT_SNDBUF, 4000);
4270
4271 session_->voice_channel()->SetOption(cricket::BaseChannel::ST_RTP,
4272 rtc::Socket::Option::OPT_RCVBUF, 8000);
4273
4274 int option_val;
deadbeefcbecd352015-09-23 11:50:27 -07004275 EXPECT_TRUE(session_->video_rtp_transport_channel()->GetOption(
guoweis@webrtc.org4f852882015-03-12 20:09:44 +00004276 rtc::Socket::Option::OPT_SNDBUF, &option_val));
4277 EXPECT_EQ(4000, option_val);
deadbeefcbecd352015-09-23 11:50:27 -07004278 EXPECT_FALSE(session_->voice_rtp_transport_channel()->GetOption(
guoweis@webrtc.org4f852882015-03-12 20:09:44 +00004279 rtc::Socket::Option::OPT_SNDBUF, &option_val));
4280
deadbeefcbecd352015-09-23 11:50:27 -07004281 EXPECT_TRUE(session_->voice_rtp_transport_channel()->GetOption(
guoweis@webrtc.org4f852882015-03-12 20:09:44 +00004282 rtc::Socket::Option::OPT_RCVBUF, &option_val));
4283 EXPECT_EQ(8000, option_val);
deadbeefcbecd352015-09-23 11:50:27 -07004284 EXPECT_FALSE(session_->video_rtp_transport_channel()->GetOption(
guoweis@webrtc.org4f852882015-03-12 20:09:44 +00004285 rtc::Socket::Option::OPT_RCVBUF, &option_val));
4286
deadbeefcbecd352015-09-23 11:50:27 -07004287 EXPECT_NE(session_->voice_rtp_transport_channel(),
4288 session_->video_rtp_transport_channel());
guoweis@webrtc.org4f852882015-03-12 20:09:44 +00004289
deadbeefab9b2d12015-10-14 11:33:11 -07004290 SendAudioVideoStream2();
guoweis@webrtc.org4f852882015-03-12 20:09:44 +00004291 SessionDescriptionInterface* answer =
4292 CreateRemoteAnswer(session_->local_description());
4293 SetRemoteDescriptionWithoutError(answer);
4294
deadbeefcbecd352015-09-23 11:50:27 -07004295 EXPECT_TRUE(session_->voice_rtp_transport_channel()->GetOption(
guoweis@webrtc.org4f852882015-03-12 20:09:44 +00004296 rtc::Socket::Option::OPT_SNDBUF, &option_val));
4297 EXPECT_EQ(4000, option_val);
4298
deadbeefcbecd352015-09-23 11:50:27 -07004299 EXPECT_TRUE(session_->voice_rtp_transport_channel()->GetOption(
guoweis@webrtc.org4f852882015-03-12 20:09:44 +00004300 rtc::Socket::Option::OPT_RCVBUF, &option_val));
4301 EXPECT_EQ(8000, option_val);
4302}
4303
tommi0f620f42015-07-09 03:25:02 -07004304// Test creating a session, request multiple offers, destroy the session
4305// and make sure we got success/failure callbacks for all of the requests.
4306// Background: crbug.com/507307
4307TEST_F(WebRtcSessionTest, CreateOffersAndShutdown) {
4308 Init();
4309
4310 rtc::scoped_refptr<WebRtcSessionCreateSDPObserverForTest> observers[100];
4311 PeerConnectionInterface::RTCOfferAnswerOptions options;
4312 options.offer_to_receive_audio =
4313 RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
deadbeefab9b2d12015-10-14 11:33:11 -07004314 cricket::MediaSessionOptions session_options;
4315 session_options.recv_audio = true;
tommi0f620f42015-07-09 03:25:02 -07004316
4317 for (auto& o : observers) {
4318 o = new WebRtcSessionCreateSDPObserverForTest();
deadbeefab9b2d12015-10-14 11:33:11 -07004319 session_->CreateOffer(o, options, session_options);
tommi0f620f42015-07-09 03:25:02 -07004320 }
4321
4322 session_.reset();
4323
tommi0f620f42015-07-09 03:25:02 -07004324 for (auto& o : observers) {
4325 // We expect to have received a notification now even if the session was
4326 // terminated. The offer creation may or may not have succeeded, but we
4327 // must have received a notification which, so the only invalid state
4328 // is kInit.
4329 EXPECT_NE(WebRtcSessionCreateSDPObserverForTest::kInit, o->state());
4330 }
4331}
4332
stefanc1aeaf02015-10-15 07:26:07 -07004333TEST_F(WebRtcSessionTest, TestPacketOptionsAndOnPacketSent) {
4334 TestPacketOptions();
4335}
4336
deadbeef057ecf02016-01-20 14:30:43 -08004337// Make sure the signal from "GetOnDestroyedSignal()" fires when the session
4338// is destroyed.
4339TEST_F(WebRtcSessionTest, TestOnDestroyedSignal) {
4340 Init();
4341 session_.reset();
4342 EXPECT_TRUE(session_destroyed_);
4343}
4344
henrike@webrtc.org28e20752013-07-10 00:45:36 +00004345// TODO(bemasc): Add a TestIceStatesBundle with BUNDLE enabled. That test
4346// currently fails because upon disconnection and reconnection OnIceComplete is
4347// called more than once without returning to IceGatheringGathering.
Henrik Boström87713d02015-08-25 09:53:21 +02004348
deadbeefcbecd352015-09-23 11:50:27 -07004349INSTANTIATE_TEST_CASE_P(WebRtcSessionTests,
4350 WebRtcSessionTest,
4351 testing::Values(ALREADY_GENERATED,
4352 DTLS_IDENTITY_STORE));