blob: 40bb437494d6445265aa8d21f9d32bfe3f1ebe83 [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
kwibergd1fe2812016-04-27 06:47:29 -070011#include <memory>
12
Henrik Kjellander15583c12016-02-10 10:53:12 +010013#include "webrtc/api/test/peerconnectiontestwrapper.h"
kjellandera96e2d72016-02-04 23:52:28 -080014// Notice that mockpeerconnectionobservers.h must be included after the above!
Henrik Kjellander15583c12016-02-10 10:53:12 +010015#include "webrtc/api/test/mockpeerconnectionobservers.h"
phoglund37ebcf02016-01-08 05:04:57 -080016#ifdef WEBRTC_ANDROID
Henrik Kjellander15583c12016-02-10 10:53:12 +010017#include "webrtc/api/test/androidtestinitializer.h"
phoglund37ebcf02016-01-08 05:04:57 -080018#endif
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000019#include "webrtc/base/gunit.h"
20#include "webrtc/base/logging.h"
21#include "webrtc/base/ssladapter.h"
perkj57db6522016-04-08 08:16:33 -070022#include "webrtc/base/thread.h"
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000023#include "webrtc/base/sslstreamadapter.h"
24#include "webrtc/base/stringencode.h"
25#include "webrtc/base/stringutils.h"
wu@webrtc.org364f2042013-11-20 21:49:41 +000026
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +000027#define MAYBE_SKIP_TEST(feature) \
28 if (!(feature())) { \
29 LOG(LS_INFO) << "Feature disabled... skipping"; \
30 return; \
31 }
32
33using webrtc::DataChannelInterface;
wu@webrtc.org364f2042013-11-20 21:49:41 +000034using webrtc::FakeConstraints;
35using webrtc::MediaConstraintsInterface;
36using webrtc::MediaStreamInterface;
37using webrtc::PeerConnectionInterface;
38
39namespace {
40
Honghai Zhang82d78622016-05-06 11:29:15 -070041const int kMaxWait = 10000;
wu@webrtc.org364f2042013-11-20 21:49:41 +000042
wu@webrtc.org364f2042013-11-20 21:49:41 +000043} // namespace
44
45class PeerConnectionEndToEndTest
46 : public sigslot::has_slots<>,
47 public testing::Test {
48 public:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000049 typedef std::vector<rtc::scoped_refptr<DataChannelInterface> >
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +000050 DataChannelList;
51
perkj57db6522016-04-08 08:16:33 -070052 PeerConnectionEndToEndTest() {
53 RTC_CHECK(worker_thread_.Start());
54 caller_ = new rtc::RefCountedObject<PeerConnectionTestWrapper>(
55 "caller", &worker_thread_);
56 callee_ = new rtc::RefCountedObject<PeerConnectionTestWrapper>(
57 "callee", &worker_thread_);
phoglund37ebcf02016-01-08 05:04:57 -080058#ifdef WEBRTC_ANDROID
59 webrtc::InitializeAndroidObjects();
60#endif
wu@webrtc.org364f2042013-11-20 21:49:41 +000061 }
62
63 void CreatePcs() {
64 CreatePcs(NULL);
65 }
66
67 void CreatePcs(const MediaConstraintsInterface* pc_constraints) {
68 EXPECT_TRUE(caller_->CreatePc(pc_constraints));
69 EXPECT_TRUE(callee_->CreatePc(pc_constraints));
70 PeerConnectionTestWrapper::Connect(caller_.get(), callee_.get());
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +000071
72 caller_->SignalOnDataChannel.connect(
73 this, &PeerConnectionEndToEndTest::OnCallerAddedDataChanel);
74 callee_->SignalOnDataChannel.connect(
75 this, &PeerConnectionEndToEndTest::OnCalleeAddedDataChannel);
wu@webrtc.org364f2042013-11-20 21:49:41 +000076 }
77
78 void GetAndAddUserMedia() {
79 FakeConstraints audio_constraints;
80 FakeConstraints video_constraints;
81 GetAndAddUserMedia(true, audio_constraints, true, video_constraints);
82 }
83
84 void GetAndAddUserMedia(bool audio, FakeConstraints audio_constraints,
85 bool video, FakeConstraints video_constraints) {
86 caller_->GetAndAddUserMedia(audio, audio_constraints,
87 video, video_constraints);
88 callee_->GetAndAddUserMedia(audio, audio_constraints,
89 video, video_constraints);
90 }
91
92 void Negotiate() {
93 caller_->CreateOffer(NULL);
94 }
95
96 void WaitForCallEstablished() {
97 caller_->WaitForCallEstablished();
98 callee_->WaitForCallEstablished();
99 }
100
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000101 void WaitForConnection() {
102 caller_->WaitForConnection();
103 callee_->WaitForConnection();
104 }
105
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000106 void OnCallerAddedDataChanel(DataChannelInterface* dc) {
107 caller_signaled_data_channels_.push_back(dc);
108 }
109
110 void OnCalleeAddedDataChannel(DataChannelInterface* dc) {
111 callee_signaled_data_channels_.push_back(dc);
112 }
113
114 // Tests that |dc1| and |dc2| can send to and receive from each other.
115 void TestDataChannelSendAndReceive(
116 DataChannelInterface* dc1, DataChannelInterface* dc2) {
kwibergd1fe2812016-04-27 06:47:29 -0700117 std::unique_ptr<webrtc::MockDataChannelObserver> dc1_observer(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000118 new webrtc::MockDataChannelObserver(dc1));
119
kwibergd1fe2812016-04-27 06:47:29 -0700120 std::unique_ptr<webrtc::MockDataChannelObserver> dc2_observer(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000121 new webrtc::MockDataChannelObserver(dc2));
122
123 static const std::string kDummyData = "abcdefg";
124 webrtc::DataBuffer buffer(kDummyData);
125 EXPECT_TRUE(dc1->Send(buffer));
126 EXPECT_EQ_WAIT(kDummyData, dc2_observer->last_message(), kMaxWait);
127
128 EXPECT_TRUE(dc2->Send(buffer));
129 EXPECT_EQ_WAIT(kDummyData, dc1_observer->last_message(), kMaxWait);
130
131 EXPECT_EQ(1U, dc1_observer->received_message_count());
132 EXPECT_EQ(1U, dc2_observer->received_message_count());
133 }
134
135 void WaitForDataChannelsToOpen(DataChannelInterface* local_dc,
136 const DataChannelList& remote_dc_list,
137 size_t remote_dc_index) {
138 EXPECT_EQ_WAIT(DataChannelInterface::kOpen, local_dc->state(), kMaxWait);
139
140 EXPECT_TRUE_WAIT(remote_dc_list.size() > remote_dc_index, kMaxWait);
141 EXPECT_EQ_WAIT(DataChannelInterface::kOpen,
142 remote_dc_list[remote_dc_index]->state(),
143 kMaxWait);
144 EXPECT_EQ(local_dc->id(), remote_dc_list[remote_dc_index]->id());
145 }
146
147 void CloseDataChannels(DataChannelInterface* local_dc,
148 const DataChannelList& remote_dc_list,
149 size_t remote_dc_index) {
150 local_dc->Close();
151 EXPECT_EQ_WAIT(DataChannelInterface::kClosed, local_dc->state(), kMaxWait);
152 EXPECT_EQ_WAIT(DataChannelInterface::kClosed,
153 remote_dc_list[remote_dc_index]->state(),
154 kMaxWait);
155 }
156
wu@webrtc.org364f2042013-11-20 21:49:41 +0000157 protected:
perkj57db6522016-04-08 08:16:33 -0700158 rtc::Thread worker_thread_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000159 rtc::scoped_refptr<PeerConnectionTestWrapper> caller_;
160 rtc::scoped_refptr<PeerConnectionTestWrapper> callee_;
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000161 DataChannelList caller_signaled_data_channels_;
162 DataChannelList callee_signaled_data_channels_;
wu@webrtc.org364f2042013-11-20 21:49:41 +0000163};
164
kjellander@webrtc.org70c0e292015-11-30 21:45:35 +0100165// Disabled for TSan v2, see
166// https://bugs.chromium.org/p/webrtc/issues/detail?id=4719 for details.
kjellander@webrtc.org3c28d0d2015-12-02 22:53:26 +0100167// Disabled for Mac, see
168// https://bugs.chromium.org/p/webrtc/issues/detail?id=5231 for details.
169#if !defined(THREAD_SANITIZER) && !defined(WEBRTC_MAC)
deadbeefee8c6d32015-08-13 14:27:18 -0700170TEST_F(PeerConnectionEndToEndTest, Call) {
wu@webrtc.org364f2042013-11-20 21:49:41 +0000171 CreatePcs();
172 GetAndAddUserMedia();
173 Negotiate();
174 WaitForCallEstablished();
175}
kjellander@webrtc.org3c28d0d2015-12-02 22:53:26 +0100176#endif // if !defined(THREAD_SANITIZER) && !defined(WEBRTC_MAC)
wu@webrtc.org364f2042013-11-20 21:49:41 +0000177
deadbeefc9be0072015-12-14 18:27:57 -0800178TEST_F(PeerConnectionEndToEndTest, CallWithLegacySdp) {
wu@webrtc.org364f2042013-11-20 21:49:41 +0000179 FakeConstraints pc_constraints;
180 pc_constraints.AddMandatory(MediaConstraintsInterface::kEnableDtlsSrtp,
181 false);
182 CreatePcs(&pc_constraints);
wu@webrtc.org364f2042013-11-20 21:49:41 +0000183 GetAndAddUserMedia();
184 Negotiate();
185 WaitForCallEstablished();
186}
wu@webrtc.orgb43202d2013-11-22 19:14:25 +0000187
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000188// Verifies that a DataChannel created before the negotiation can transition to
189// "OPEN" and transfer data.
190TEST_F(PeerConnectionEndToEndTest, CreateDataChannelBeforeNegotiate) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000191 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000192
193 CreatePcs();
194
195 webrtc::DataChannelInit init;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000196 rtc::scoped_refptr<DataChannelInterface> caller_dc(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000197 caller_->CreateDataChannel("data", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000198 rtc::scoped_refptr<DataChannelInterface> callee_dc(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000199 callee_->CreateDataChannel("data", init));
200
201 Negotiate();
202 WaitForConnection();
203
204 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 0);
205 WaitForDataChannelsToOpen(callee_dc, caller_signaled_data_channels_, 0);
206
207 TestDataChannelSendAndReceive(caller_dc, callee_signaled_data_channels_[0]);
208 TestDataChannelSendAndReceive(callee_dc, caller_signaled_data_channels_[0]);
209
210 CloseDataChannels(caller_dc, callee_signaled_data_channels_, 0);
211 CloseDataChannels(callee_dc, caller_signaled_data_channels_, 0);
212}
213
214// Verifies that a DataChannel created after the negotiation can transition to
215// "OPEN" and transfer data.
henrik.lundin@webrtc.org22362672014-11-03 13:38:50 +0000216#if defined(MEMORY_SANITIZER)
217// Fails under MemorySanitizer:
218// See https://code.google.com/p/webrtc/issues/detail?id=3980.
219#define MAYBE_CreateDataChannelAfterNegotiate DISABLED_CreateDataChannelAfterNegotiate
220#else
221#define MAYBE_CreateDataChannelAfterNegotiate CreateDataChannelAfterNegotiate
222#endif
223TEST_F(PeerConnectionEndToEndTest, MAYBE_CreateDataChannelAfterNegotiate) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000224 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000225
226 CreatePcs();
227
228 webrtc::DataChannelInit init;
229
230 // This DataChannel is for creating the data content in the negotiation.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000231 rtc::scoped_refptr<DataChannelInterface> dummy(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000232 caller_->CreateDataChannel("data", init));
233 Negotiate();
234 WaitForConnection();
235
236 // Creates new DataChannels after the negotiation and verifies their states.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000237 rtc::scoped_refptr<DataChannelInterface> caller_dc(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000238 caller_->CreateDataChannel("hello", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000239 rtc::scoped_refptr<DataChannelInterface> callee_dc(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000240 callee_->CreateDataChannel("hello", init));
241
242 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 1);
243 WaitForDataChannelsToOpen(callee_dc, caller_signaled_data_channels_, 0);
244
245 TestDataChannelSendAndReceive(caller_dc, callee_signaled_data_channels_[1]);
246 TestDataChannelSendAndReceive(callee_dc, caller_signaled_data_channels_[0]);
247
248 CloseDataChannels(caller_dc, callee_signaled_data_channels_, 1);
249 CloseDataChannels(callee_dc, caller_signaled_data_channels_, 0);
250}
251
252// Verifies that DataChannel IDs are even/odd based on the DTLS roles.
253TEST_F(PeerConnectionEndToEndTest, DataChannelIdAssignment) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000254 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000255
256 CreatePcs();
257
258 webrtc::DataChannelInit init;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000259 rtc::scoped_refptr<DataChannelInterface> caller_dc_1(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000260 caller_->CreateDataChannel("data", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000261 rtc::scoped_refptr<DataChannelInterface> callee_dc_1(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000262 callee_->CreateDataChannel("data", init));
263
264 Negotiate();
265 WaitForConnection();
266
267 EXPECT_EQ(1U, caller_dc_1->id() % 2);
268 EXPECT_EQ(0U, callee_dc_1->id() % 2);
269
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000270 rtc::scoped_refptr<DataChannelInterface> caller_dc_2(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000271 caller_->CreateDataChannel("data", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000272 rtc::scoped_refptr<DataChannelInterface> callee_dc_2(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000273 callee_->CreateDataChannel("data", init));
274
275 EXPECT_EQ(1U, caller_dc_2->id() % 2);
276 EXPECT_EQ(0U, callee_dc_2->id() % 2);
277}
278
279// Verifies that the message is received by the right remote DataChannel when
280// there are multiple DataChannels.
281TEST_F(PeerConnectionEndToEndTest,
282 MessageTransferBetweenTwoPairsOfDataChannels) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000283 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000284
285 CreatePcs();
286
287 webrtc::DataChannelInit init;
288
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000289 rtc::scoped_refptr<DataChannelInterface> caller_dc_1(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000290 caller_->CreateDataChannel("data", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000291 rtc::scoped_refptr<DataChannelInterface> caller_dc_2(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000292 caller_->CreateDataChannel("data", init));
293
294 Negotiate();
295 WaitForConnection();
296 WaitForDataChannelsToOpen(caller_dc_1, callee_signaled_data_channels_, 0);
297 WaitForDataChannelsToOpen(caller_dc_2, callee_signaled_data_channels_, 1);
298
kwibergd1fe2812016-04-27 06:47:29 -0700299 std::unique_ptr<webrtc::MockDataChannelObserver> dc_1_observer(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000300 new webrtc::MockDataChannelObserver(callee_signaled_data_channels_[0]));
301
kwibergd1fe2812016-04-27 06:47:29 -0700302 std::unique_ptr<webrtc::MockDataChannelObserver> dc_2_observer(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000303 new webrtc::MockDataChannelObserver(callee_signaled_data_channels_[1]));
304
305 const std::string message_1 = "hello 1";
306 const std::string message_2 = "hello 2";
307
308 caller_dc_1->Send(webrtc::DataBuffer(message_1));
309 EXPECT_EQ_WAIT(message_1, dc_1_observer->last_message(), kMaxWait);
310
311 caller_dc_2->Send(webrtc::DataBuffer(message_2));
312 EXPECT_EQ_WAIT(message_2, dc_2_observer->last_message(), kMaxWait);
313
314 EXPECT_EQ(1U, dc_1_observer->received_message_count());
315 EXPECT_EQ(1U, dc_2_observer->received_message_count());
316}
deadbeefab9b2d12015-10-14 11:33:11 -0700317
318// Verifies that a DataChannel added from an OPEN message functions after
319// a channel has been previously closed (webrtc issue 3778).
320// This previously failed because the new channel re-uses the ID of the closed
321// channel, and the closed channel was incorrectly still assigned to the id.
322// TODO(deadbeef): This is disabled because there's currently a race condition
323// caused by the fact that a data channel signals that it's closed before it
324// really is. Re-enable this test once that's fixed.
325TEST_F(PeerConnectionEndToEndTest,
326 DISABLED_DataChannelFromOpenWorksAfterClose) {
327 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
328
329 CreatePcs();
330
331 webrtc::DataChannelInit init;
332 rtc::scoped_refptr<DataChannelInterface> caller_dc(
333 caller_->CreateDataChannel("data", init));
334
335 Negotiate();
336 WaitForConnection();
337
338 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 0);
339 CloseDataChannels(caller_dc, callee_signaled_data_channels_, 0);
340
341 // Create a new channel and ensure it works after closing the previous one.
342 caller_dc = caller_->CreateDataChannel("data2", init);
343
344 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 1);
345 TestDataChannelSendAndReceive(caller_dc, callee_signaled_data_channels_[1]);
346
347 CloseDataChannels(caller_dc, callee_signaled_data_channels_, 1);
348}
deadbeefbd292462015-12-14 18:15:29 -0800349
350// This tests that if a data channel is closed remotely while not referenced
351// by the application (meaning only the PeerConnection contributes to its
352// reference count), no memory access violation will occur.
353// See: https://code.google.com/p/chromium/issues/detail?id=565048
354TEST_F(PeerConnectionEndToEndTest, CloseDataChannelRemotelyWhileNotReferenced) {
355 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
356
357 CreatePcs();
358
359 webrtc::DataChannelInit init;
360 rtc::scoped_refptr<DataChannelInterface> caller_dc(
361 caller_->CreateDataChannel("data", init));
362
363 Negotiate();
364 WaitForConnection();
365
366 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 0);
367 // This removes the reference to the remote data channel that we hold.
368 callee_signaled_data_channels_.clear();
369 caller_dc->Close();
370 EXPECT_EQ_WAIT(DataChannelInterface::kClosed, caller_dc->state(), kMaxWait);
371
372 // Wait for a bit longer so the remote data channel will receive the
373 // close message and be destroyed.
374 rtc::Thread::Current()->ProcessMessages(100);
375}