blob: be662886d3fdef96a70c1d560fa2a5dfaa5087a5 [file] [log] [blame]
wu@webrtc.org364f2042013-11-20 21:49:41 +00001/*
kjellanderb24317b2016-02-10 07:54:43 -08002 * Copyright 2013 The WebRTC project authors. All Rights Reserved.
wu@webrtc.org364f2042013-11-20 21:49:41 +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.
wu@webrtc.org364f2042013-11-20 21:49:41 +00009 */
10
Henrik Kjellander15583c12016-02-10 10:53:12 +010011#include "webrtc/api/test/peerconnectiontestwrapper.h"
kjellandera96e2d72016-02-04 23:52:28 -080012// Notice that mockpeerconnectionobservers.h must be included after the above!
Henrik Kjellander15583c12016-02-10 10:53:12 +010013#include "webrtc/api/test/mockpeerconnectionobservers.h"
phoglund37ebcf02016-01-08 05:04:57 -080014#ifdef WEBRTC_ANDROID
Henrik Kjellander15583c12016-02-10 10:53:12 +010015#include "webrtc/api/test/androidtestinitializer.h"
phoglund37ebcf02016-01-08 05:04:57 -080016#endif
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000017#include "webrtc/base/gunit.h"
18#include "webrtc/base/logging.h"
19#include "webrtc/base/ssladapter.h"
20#include "webrtc/base/sslstreamadapter.h"
21#include "webrtc/base/stringencode.h"
22#include "webrtc/base/stringutils.h"
wu@webrtc.org364f2042013-11-20 21:49:41 +000023
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +000024#define MAYBE_SKIP_TEST(feature) \
25 if (!(feature())) { \
26 LOG(LS_INFO) << "Feature disabled... skipping"; \
27 return; \
28 }
29
30using webrtc::DataChannelInterface;
wu@webrtc.org364f2042013-11-20 21:49:41 +000031using webrtc::FakeConstraints;
32using webrtc::MediaConstraintsInterface;
33using webrtc::MediaStreamInterface;
34using webrtc::PeerConnectionInterface;
35
36namespace {
37
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +000038const size_t kMaxWait = 10000;
wu@webrtc.org364f2042013-11-20 21:49:41 +000039
wu@webrtc.org364f2042013-11-20 21:49:41 +000040} // namespace
41
42class PeerConnectionEndToEndTest
43 : public sigslot::has_slots<>,
44 public testing::Test {
45 public:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000046 typedef std::vector<rtc::scoped_refptr<DataChannelInterface> >
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +000047 DataChannelList;
48
wu@webrtc.org364f2042013-11-20 21:49:41 +000049 PeerConnectionEndToEndTest()
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000050 : caller_(new rtc::RefCountedObject<PeerConnectionTestWrapper>(
wu@webrtc.org364f2042013-11-20 21:49:41 +000051 "caller")),
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000052 callee_(new rtc::RefCountedObject<PeerConnectionTestWrapper>(
wu@webrtc.org364f2042013-11-20 21:49:41 +000053 "callee")) {
phoglund37ebcf02016-01-08 05:04:57 -080054#ifdef WEBRTC_ANDROID
55 webrtc::InitializeAndroidObjects();
56#endif
wu@webrtc.org364f2042013-11-20 21:49:41 +000057 }
58
59 void CreatePcs() {
60 CreatePcs(NULL);
61 }
62
63 void CreatePcs(const MediaConstraintsInterface* pc_constraints) {
64 EXPECT_TRUE(caller_->CreatePc(pc_constraints));
65 EXPECT_TRUE(callee_->CreatePc(pc_constraints));
66 PeerConnectionTestWrapper::Connect(caller_.get(), callee_.get());
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +000067
68 caller_->SignalOnDataChannel.connect(
69 this, &PeerConnectionEndToEndTest::OnCallerAddedDataChanel);
70 callee_->SignalOnDataChannel.connect(
71 this, &PeerConnectionEndToEndTest::OnCalleeAddedDataChannel);
wu@webrtc.org364f2042013-11-20 21:49:41 +000072 }
73
74 void GetAndAddUserMedia() {
75 FakeConstraints audio_constraints;
76 FakeConstraints video_constraints;
77 GetAndAddUserMedia(true, audio_constraints, true, video_constraints);
78 }
79
80 void GetAndAddUserMedia(bool audio, FakeConstraints audio_constraints,
81 bool video, FakeConstraints video_constraints) {
82 caller_->GetAndAddUserMedia(audio, audio_constraints,
83 video, video_constraints);
84 callee_->GetAndAddUserMedia(audio, audio_constraints,
85 video, video_constraints);
86 }
87
88 void Negotiate() {
89 caller_->CreateOffer(NULL);
90 }
91
92 void WaitForCallEstablished() {
93 caller_->WaitForCallEstablished();
94 callee_->WaitForCallEstablished();
95 }
96
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +000097 void WaitForConnection() {
98 caller_->WaitForConnection();
99 callee_->WaitForConnection();
100 }
101
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000102 void OnCallerAddedDataChanel(DataChannelInterface* dc) {
103 caller_signaled_data_channels_.push_back(dc);
104 }
105
106 void OnCalleeAddedDataChannel(DataChannelInterface* dc) {
107 callee_signaled_data_channels_.push_back(dc);
108 }
109
110 // Tests that |dc1| and |dc2| can send to and receive from each other.
111 void TestDataChannelSendAndReceive(
112 DataChannelInterface* dc1, DataChannelInterface* dc2) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000113 rtc::scoped_ptr<webrtc::MockDataChannelObserver> dc1_observer(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000114 new webrtc::MockDataChannelObserver(dc1));
115
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000116 rtc::scoped_ptr<webrtc::MockDataChannelObserver> dc2_observer(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000117 new webrtc::MockDataChannelObserver(dc2));
118
119 static const std::string kDummyData = "abcdefg";
120 webrtc::DataBuffer buffer(kDummyData);
121 EXPECT_TRUE(dc1->Send(buffer));
122 EXPECT_EQ_WAIT(kDummyData, dc2_observer->last_message(), kMaxWait);
123
124 EXPECT_TRUE(dc2->Send(buffer));
125 EXPECT_EQ_WAIT(kDummyData, dc1_observer->last_message(), kMaxWait);
126
127 EXPECT_EQ(1U, dc1_observer->received_message_count());
128 EXPECT_EQ(1U, dc2_observer->received_message_count());
129 }
130
131 void WaitForDataChannelsToOpen(DataChannelInterface* local_dc,
132 const DataChannelList& remote_dc_list,
133 size_t remote_dc_index) {
134 EXPECT_EQ_WAIT(DataChannelInterface::kOpen, local_dc->state(), kMaxWait);
135
136 EXPECT_TRUE_WAIT(remote_dc_list.size() > remote_dc_index, kMaxWait);
137 EXPECT_EQ_WAIT(DataChannelInterface::kOpen,
138 remote_dc_list[remote_dc_index]->state(),
139 kMaxWait);
140 EXPECT_EQ(local_dc->id(), remote_dc_list[remote_dc_index]->id());
141 }
142
143 void CloseDataChannels(DataChannelInterface* local_dc,
144 const DataChannelList& remote_dc_list,
145 size_t remote_dc_index) {
146 local_dc->Close();
147 EXPECT_EQ_WAIT(DataChannelInterface::kClosed, local_dc->state(), kMaxWait);
148 EXPECT_EQ_WAIT(DataChannelInterface::kClosed,
149 remote_dc_list[remote_dc_index]->state(),
150 kMaxWait);
151 }
152
wu@webrtc.org364f2042013-11-20 21:49:41 +0000153 protected:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000154 rtc::scoped_refptr<PeerConnectionTestWrapper> caller_;
155 rtc::scoped_refptr<PeerConnectionTestWrapper> callee_;
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000156 DataChannelList caller_signaled_data_channels_;
157 DataChannelList callee_signaled_data_channels_;
wu@webrtc.org364f2042013-11-20 21:49:41 +0000158};
159
kjellander@webrtc.org70c0e292015-11-30 21:45:35 +0100160// Disabled for TSan v2, see
161// https://bugs.chromium.org/p/webrtc/issues/detail?id=4719 for details.
kjellander@webrtc.org3c28d0d2015-12-02 22:53:26 +0100162// Disabled for Mac, see
163// https://bugs.chromium.org/p/webrtc/issues/detail?id=5231 for details.
164#if !defined(THREAD_SANITIZER) && !defined(WEBRTC_MAC)
deadbeefee8c6d32015-08-13 14:27:18 -0700165TEST_F(PeerConnectionEndToEndTest, Call) {
wu@webrtc.org364f2042013-11-20 21:49:41 +0000166 CreatePcs();
167 GetAndAddUserMedia();
168 Negotiate();
169 WaitForCallEstablished();
170}
kjellander@webrtc.org3c28d0d2015-12-02 22:53:26 +0100171#endif // if !defined(THREAD_SANITIZER) && !defined(WEBRTC_MAC)
wu@webrtc.org364f2042013-11-20 21:49:41 +0000172
deadbeefc9be0072015-12-14 18:27:57 -0800173TEST_F(PeerConnectionEndToEndTest, CallWithLegacySdp) {
wu@webrtc.org364f2042013-11-20 21:49:41 +0000174 FakeConstraints pc_constraints;
175 pc_constraints.AddMandatory(MediaConstraintsInterface::kEnableDtlsSrtp,
176 false);
177 CreatePcs(&pc_constraints);
wu@webrtc.org364f2042013-11-20 21:49:41 +0000178 GetAndAddUserMedia();
179 Negotiate();
180 WaitForCallEstablished();
181}
wu@webrtc.orgb43202d2013-11-22 19:14:25 +0000182
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000183// Verifies that a DataChannel created before the negotiation can transition to
184// "OPEN" and transfer data.
185TEST_F(PeerConnectionEndToEndTest, CreateDataChannelBeforeNegotiate) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000186 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000187
188 CreatePcs();
189
190 webrtc::DataChannelInit init;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000191 rtc::scoped_refptr<DataChannelInterface> caller_dc(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000192 caller_->CreateDataChannel("data", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000193 rtc::scoped_refptr<DataChannelInterface> callee_dc(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000194 callee_->CreateDataChannel("data", init));
195
196 Negotiate();
197 WaitForConnection();
198
199 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 0);
200 WaitForDataChannelsToOpen(callee_dc, caller_signaled_data_channels_, 0);
201
202 TestDataChannelSendAndReceive(caller_dc, callee_signaled_data_channels_[0]);
203 TestDataChannelSendAndReceive(callee_dc, caller_signaled_data_channels_[0]);
204
205 CloseDataChannels(caller_dc, callee_signaled_data_channels_, 0);
206 CloseDataChannels(callee_dc, caller_signaled_data_channels_, 0);
207}
208
209// Verifies that a DataChannel created after the negotiation can transition to
210// "OPEN" and transfer data.
henrik.lundin@webrtc.org22362672014-11-03 13:38:50 +0000211#if defined(MEMORY_SANITIZER)
212// Fails under MemorySanitizer:
213// See https://code.google.com/p/webrtc/issues/detail?id=3980.
214#define MAYBE_CreateDataChannelAfterNegotiate DISABLED_CreateDataChannelAfterNegotiate
215#else
216#define MAYBE_CreateDataChannelAfterNegotiate CreateDataChannelAfterNegotiate
217#endif
218TEST_F(PeerConnectionEndToEndTest, MAYBE_CreateDataChannelAfterNegotiate) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000219 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000220
221 CreatePcs();
222
223 webrtc::DataChannelInit init;
224
225 // This DataChannel is for creating the data content in the negotiation.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000226 rtc::scoped_refptr<DataChannelInterface> dummy(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000227 caller_->CreateDataChannel("data", init));
228 Negotiate();
229 WaitForConnection();
230
231 // Creates new DataChannels after the negotiation and verifies their states.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000232 rtc::scoped_refptr<DataChannelInterface> caller_dc(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000233 caller_->CreateDataChannel("hello", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000234 rtc::scoped_refptr<DataChannelInterface> callee_dc(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000235 callee_->CreateDataChannel("hello", init));
236
237 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 1);
238 WaitForDataChannelsToOpen(callee_dc, caller_signaled_data_channels_, 0);
239
240 TestDataChannelSendAndReceive(caller_dc, callee_signaled_data_channels_[1]);
241 TestDataChannelSendAndReceive(callee_dc, caller_signaled_data_channels_[0]);
242
243 CloseDataChannels(caller_dc, callee_signaled_data_channels_, 1);
244 CloseDataChannels(callee_dc, caller_signaled_data_channels_, 0);
245}
246
247// Verifies that DataChannel IDs are even/odd based on the DTLS roles.
248TEST_F(PeerConnectionEndToEndTest, DataChannelIdAssignment) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000249 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000250
251 CreatePcs();
252
253 webrtc::DataChannelInit init;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000254 rtc::scoped_refptr<DataChannelInterface> caller_dc_1(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000255 caller_->CreateDataChannel("data", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000256 rtc::scoped_refptr<DataChannelInterface> callee_dc_1(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000257 callee_->CreateDataChannel("data", init));
258
259 Negotiate();
260 WaitForConnection();
261
262 EXPECT_EQ(1U, caller_dc_1->id() % 2);
263 EXPECT_EQ(0U, callee_dc_1->id() % 2);
264
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000265 rtc::scoped_refptr<DataChannelInterface> caller_dc_2(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000266 caller_->CreateDataChannel("data", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000267 rtc::scoped_refptr<DataChannelInterface> callee_dc_2(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000268 callee_->CreateDataChannel("data", init));
269
270 EXPECT_EQ(1U, caller_dc_2->id() % 2);
271 EXPECT_EQ(0U, callee_dc_2->id() % 2);
272}
273
274// Verifies that the message is received by the right remote DataChannel when
275// there are multiple DataChannels.
276TEST_F(PeerConnectionEndToEndTest,
277 MessageTransferBetweenTwoPairsOfDataChannels) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000278 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000279
280 CreatePcs();
281
282 webrtc::DataChannelInit init;
283
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000284 rtc::scoped_refptr<DataChannelInterface> caller_dc_1(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000285 caller_->CreateDataChannel("data", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000286 rtc::scoped_refptr<DataChannelInterface> caller_dc_2(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000287 caller_->CreateDataChannel("data", init));
288
289 Negotiate();
290 WaitForConnection();
291 WaitForDataChannelsToOpen(caller_dc_1, callee_signaled_data_channels_, 0);
292 WaitForDataChannelsToOpen(caller_dc_2, callee_signaled_data_channels_, 1);
293
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000294 rtc::scoped_ptr<webrtc::MockDataChannelObserver> dc_1_observer(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000295 new webrtc::MockDataChannelObserver(callee_signaled_data_channels_[0]));
296
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000297 rtc::scoped_ptr<webrtc::MockDataChannelObserver> dc_2_observer(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000298 new webrtc::MockDataChannelObserver(callee_signaled_data_channels_[1]));
299
300 const std::string message_1 = "hello 1";
301 const std::string message_2 = "hello 2";
302
303 caller_dc_1->Send(webrtc::DataBuffer(message_1));
304 EXPECT_EQ_WAIT(message_1, dc_1_observer->last_message(), kMaxWait);
305
306 caller_dc_2->Send(webrtc::DataBuffer(message_2));
307 EXPECT_EQ_WAIT(message_2, dc_2_observer->last_message(), kMaxWait);
308
309 EXPECT_EQ(1U, dc_1_observer->received_message_count());
310 EXPECT_EQ(1U, dc_2_observer->received_message_count());
311}
deadbeefab9b2d12015-10-14 11:33:11 -0700312
313// Verifies that a DataChannel added from an OPEN message functions after
314// a channel has been previously closed (webrtc issue 3778).
315// This previously failed because the new channel re-uses the ID of the closed
316// channel, and the closed channel was incorrectly still assigned to the id.
317// TODO(deadbeef): This is disabled because there's currently a race condition
318// caused by the fact that a data channel signals that it's closed before it
319// really is. Re-enable this test once that's fixed.
320TEST_F(PeerConnectionEndToEndTest,
321 DISABLED_DataChannelFromOpenWorksAfterClose) {
322 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
323
324 CreatePcs();
325
326 webrtc::DataChannelInit init;
327 rtc::scoped_refptr<DataChannelInterface> caller_dc(
328 caller_->CreateDataChannel("data", init));
329
330 Negotiate();
331 WaitForConnection();
332
333 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 0);
334 CloseDataChannels(caller_dc, callee_signaled_data_channels_, 0);
335
336 // Create a new channel and ensure it works after closing the previous one.
337 caller_dc = caller_->CreateDataChannel("data2", init);
338
339 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 1);
340 TestDataChannelSendAndReceive(caller_dc, callee_signaled_data_channels_[1]);
341
342 CloseDataChannels(caller_dc, callee_signaled_data_channels_, 1);
343}
deadbeefbd292462015-12-14 18:15:29 -0800344
345// This tests that if a data channel is closed remotely while not referenced
346// by the application (meaning only the PeerConnection contributes to its
347// reference count), no memory access violation will occur.
348// See: https://code.google.com/p/chromium/issues/detail?id=565048
349TEST_F(PeerConnectionEndToEndTest, CloseDataChannelRemotelyWhileNotReferenced) {
350 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
351
352 CreatePcs();
353
354 webrtc::DataChannelInit init;
355 rtc::scoped_refptr<DataChannelInterface> caller_dc(
356 caller_->CreateDataChannel("data", init));
357
358 Negotiate();
359 WaitForConnection();
360
361 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 0);
362 // This removes the reference to the remote data channel that we hold.
363 callee_signaled_data_channels_.clear();
364 caller_dc->Close();
365 EXPECT_EQ_WAIT(DataChannelInterface::kClosed, caller_dc->state(), kMaxWait);
366
367 // Wait for a bit longer so the remote data channel will receive the
368 // close message and be destroyed.
369 rtc::Thread::Current()->ProcessMessages(100);
370}