blob: 20df17bc63e439924002ab9f0dbb912256c3b77a [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"
perkj57db6522016-04-08 08:16:33 -070020#include "webrtc/base/thread.h"
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000021#include "webrtc/base/sslstreamadapter.h"
22#include "webrtc/base/stringencode.h"
23#include "webrtc/base/stringutils.h"
wu@webrtc.org364f2042013-11-20 21:49:41 +000024
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +000025#define MAYBE_SKIP_TEST(feature) \
26 if (!(feature())) { \
27 LOG(LS_INFO) << "Feature disabled... skipping"; \
28 return; \
29 }
30
31using webrtc::DataChannelInterface;
wu@webrtc.org364f2042013-11-20 21:49:41 +000032using webrtc::FakeConstraints;
33using webrtc::MediaConstraintsInterface;
34using webrtc::MediaStreamInterface;
35using webrtc::PeerConnectionInterface;
36
37namespace {
38
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +000039const size_t kMaxWait = 10000;
wu@webrtc.org364f2042013-11-20 21:49:41 +000040
wu@webrtc.org364f2042013-11-20 21:49:41 +000041} // namespace
42
43class PeerConnectionEndToEndTest
44 : public sigslot::has_slots<>,
45 public testing::Test {
46 public:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000047 typedef std::vector<rtc::scoped_refptr<DataChannelInterface> >
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +000048 DataChannelList;
49
perkj57db6522016-04-08 08:16:33 -070050 PeerConnectionEndToEndTest() {
51 RTC_CHECK(worker_thread_.Start());
52 caller_ = new rtc::RefCountedObject<PeerConnectionTestWrapper>(
53 "caller", &worker_thread_);
54 callee_ = new rtc::RefCountedObject<PeerConnectionTestWrapper>(
55 "callee", &worker_thread_);
phoglund37ebcf02016-01-08 05:04:57 -080056#ifdef WEBRTC_ANDROID
57 webrtc::InitializeAndroidObjects();
58#endif
wu@webrtc.org364f2042013-11-20 21:49:41 +000059 }
60
61 void CreatePcs() {
62 CreatePcs(NULL);
63 }
64
65 void CreatePcs(const MediaConstraintsInterface* pc_constraints) {
66 EXPECT_TRUE(caller_->CreatePc(pc_constraints));
67 EXPECT_TRUE(callee_->CreatePc(pc_constraints));
68 PeerConnectionTestWrapper::Connect(caller_.get(), callee_.get());
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +000069
70 caller_->SignalOnDataChannel.connect(
71 this, &PeerConnectionEndToEndTest::OnCallerAddedDataChanel);
72 callee_->SignalOnDataChannel.connect(
73 this, &PeerConnectionEndToEndTest::OnCalleeAddedDataChannel);
wu@webrtc.org364f2042013-11-20 21:49:41 +000074 }
75
76 void GetAndAddUserMedia() {
77 FakeConstraints audio_constraints;
78 FakeConstraints video_constraints;
79 GetAndAddUserMedia(true, audio_constraints, true, video_constraints);
80 }
81
82 void GetAndAddUserMedia(bool audio, FakeConstraints audio_constraints,
83 bool video, FakeConstraints video_constraints) {
84 caller_->GetAndAddUserMedia(audio, audio_constraints,
85 video, video_constraints);
86 callee_->GetAndAddUserMedia(audio, audio_constraints,
87 video, video_constraints);
88 }
89
90 void Negotiate() {
91 caller_->CreateOffer(NULL);
92 }
93
94 void WaitForCallEstablished() {
95 caller_->WaitForCallEstablished();
96 callee_->WaitForCallEstablished();
97 }
98
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +000099 void WaitForConnection() {
100 caller_->WaitForConnection();
101 callee_->WaitForConnection();
102 }
103
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000104 void OnCallerAddedDataChanel(DataChannelInterface* dc) {
105 caller_signaled_data_channels_.push_back(dc);
106 }
107
108 void OnCalleeAddedDataChannel(DataChannelInterface* dc) {
109 callee_signaled_data_channels_.push_back(dc);
110 }
111
112 // Tests that |dc1| and |dc2| can send to and receive from each other.
113 void TestDataChannelSendAndReceive(
114 DataChannelInterface* dc1, DataChannelInterface* dc2) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000115 rtc::scoped_ptr<webrtc::MockDataChannelObserver> dc1_observer(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000116 new webrtc::MockDataChannelObserver(dc1));
117
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000118 rtc::scoped_ptr<webrtc::MockDataChannelObserver> dc2_observer(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000119 new webrtc::MockDataChannelObserver(dc2));
120
121 static const std::string kDummyData = "abcdefg";
122 webrtc::DataBuffer buffer(kDummyData);
123 EXPECT_TRUE(dc1->Send(buffer));
124 EXPECT_EQ_WAIT(kDummyData, dc2_observer->last_message(), kMaxWait);
125
126 EXPECT_TRUE(dc2->Send(buffer));
127 EXPECT_EQ_WAIT(kDummyData, dc1_observer->last_message(), kMaxWait);
128
129 EXPECT_EQ(1U, dc1_observer->received_message_count());
130 EXPECT_EQ(1U, dc2_observer->received_message_count());
131 }
132
133 void WaitForDataChannelsToOpen(DataChannelInterface* local_dc,
134 const DataChannelList& remote_dc_list,
135 size_t remote_dc_index) {
136 EXPECT_EQ_WAIT(DataChannelInterface::kOpen, local_dc->state(), kMaxWait);
137
138 EXPECT_TRUE_WAIT(remote_dc_list.size() > remote_dc_index, kMaxWait);
139 EXPECT_EQ_WAIT(DataChannelInterface::kOpen,
140 remote_dc_list[remote_dc_index]->state(),
141 kMaxWait);
142 EXPECT_EQ(local_dc->id(), remote_dc_list[remote_dc_index]->id());
143 }
144
145 void CloseDataChannels(DataChannelInterface* local_dc,
146 const DataChannelList& remote_dc_list,
147 size_t remote_dc_index) {
148 local_dc->Close();
149 EXPECT_EQ_WAIT(DataChannelInterface::kClosed, local_dc->state(), kMaxWait);
150 EXPECT_EQ_WAIT(DataChannelInterface::kClosed,
151 remote_dc_list[remote_dc_index]->state(),
152 kMaxWait);
153 }
154
wu@webrtc.org364f2042013-11-20 21:49:41 +0000155 protected:
perkj57db6522016-04-08 08:16:33 -0700156 rtc::Thread worker_thread_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000157 rtc::scoped_refptr<PeerConnectionTestWrapper> caller_;
158 rtc::scoped_refptr<PeerConnectionTestWrapper> callee_;
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000159 DataChannelList caller_signaled_data_channels_;
160 DataChannelList callee_signaled_data_channels_;
wu@webrtc.org364f2042013-11-20 21:49:41 +0000161};
162
kjellander@webrtc.org70c0e292015-11-30 21:45:35 +0100163// Disabled for TSan v2, see
164// https://bugs.chromium.org/p/webrtc/issues/detail?id=4719 for details.
kjellander@webrtc.org3c28d0d2015-12-02 22:53:26 +0100165// Disabled for Mac, see
166// https://bugs.chromium.org/p/webrtc/issues/detail?id=5231 for details.
167#if !defined(THREAD_SANITIZER) && !defined(WEBRTC_MAC)
deadbeefee8c6d32015-08-13 14:27:18 -0700168TEST_F(PeerConnectionEndToEndTest, Call) {
wu@webrtc.org364f2042013-11-20 21:49:41 +0000169 CreatePcs();
170 GetAndAddUserMedia();
171 Negotiate();
172 WaitForCallEstablished();
173}
kjellander@webrtc.org3c28d0d2015-12-02 22:53:26 +0100174#endif // if !defined(THREAD_SANITIZER) && !defined(WEBRTC_MAC)
wu@webrtc.org364f2042013-11-20 21:49:41 +0000175
deadbeefc9be0072015-12-14 18:27:57 -0800176TEST_F(PeerConnectionEndToEndTest, CallWithLegacySdp) {
wu@webrtc.org364f2042013-11-20 21:49:41 +0000177 FakeConstraints pc_constraints;
178 pc_constraints.AddMandatory(MediaConstraintsInterface::kEnableDtlsSrtp,
179 false);
180 CreatePcs(&pc_constraints);
wu@webrtc.org364f2042013-11-20 21:49:41 +0000181 GetAndAddUserMedia();
182 Negotiate();
183 WaitForCallEstablished();
184}
wu@webrtc.orgb43202d2013-11-22 19:14:25 +0000185
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000186// Verifies that a DataChannel created before the negotiation can transition to
187// "OPEN" and transfer data.
188TEST_F(PeerConnectionEndToEndTest, CreateDataChannelBeforeNegotiate) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000189 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000190
191 CreatePcs();
192
193 webrtc::DataChannelInit init;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000194 rtc::scoped_refptr<DataChannelInterface> caller_dc(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000195 caller_->CreateDataChannel("data", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000196 rtc::scoped_refptr<DataChannelInterface> callee_dc(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000197 callee_->CreateDataChannel("data", init));
198
199 Negotiate();
200 WaitForConnection();
201
202 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 0);
203 WaitForDataChannelsToOpen(callee_dc, caller_signaled_data_channels_, 0);
204
205 TestDataChannelSendAndReceive(caller_dc, callee_signaled_data_channels_[0]);
206 TestDataChannelSendAndReceive(callee_dc, caller_signaled_data_channels_[0]);
207
208 CloseDataChannels(caller_dc, callee_signaled_data_channels_, 0);
209 CloseDataChannels(callee_dc, caller_signaled_data_channels_, 0);
210}
211
212// Verifies that a DataChannel created after the negotiation can transition to
213// "OPEN" and transfer data.
henrik.lundin@webrtc.org22362672014-11-03 13:38:50 +0000214#if defined(MEMORY_SANITIZER)
215// Fails under MemorySanitizer:
216// See https://code.google.com/p/webrtc/issues/detail?id=3980.
217#define MAYBE_CreateDataChannelAfterNegotiate DISABLED_CreateDataChannelAfterNegotiate
218#else
219#define MAYBE_CreateDataChannelAfterNegotiate CreateDataChannelAfterNegotiate
220#endif
221TEST_F(PeerConnectionEndToEndTest, MAYBE_CreateDataChannelAfterNegotiate) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000222 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000223
224 CreatePcs();
225
226 webrtc::DataChannelInit init;
227
228 // This DataChannel is for creating the data content in the negotiation.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000229 rtc::scoped_refptr<DataChannelInterface> dummy(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000230 caller_->CreateDataChannel("data", init));
231 Negotiate();
232 WaitForConnection();
233
234 // Creates new DataChannels after the negotiation and verifies their states.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000235 rtc::scoped_refptr<DataChannelInterface> caller_dc(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000236 caller_->CreateDataChannel("hello", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000237 rtc::scoped_refptr<DataChannelInterface> callee_dc(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000238 callee_->CreateDataChannel("hello", init));
239
240 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 1);
241 WaitForDataChannelsToOpen(callee_dc, caller_signaled_data_channels_, 0);
242
243 TestDataChannelSendAndReceive(caller_dc, callee_signaled_data_channels_[1]);
244 TestDataChannelSendAndReceive(callee_dc, caller_signaled_data_channels_[0]);
245
246 CloseDataChannels(caller_dc, callee_signaled_data_channels_, 1);
247 CloseDataChannels(callee_dc, caller_signaled_data_channels_, 0);
248}
249
250// Verifies that DataChannel IDs are even/odd based on the DTLS roles.
251TEST_F(PeerConnectionEndToEndTest, DataChannelIdAssignment) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000252 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000253
254 CreatePcs();
255
256 webrtc::DataChannelInit init;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000257 rtc::scoped_refptr<DataChannelInterface> caller_dc_1(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000258 caller_->CreateDataChannel("data", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000259 rtc::scoped_refptr<DataChannelInterface> callee_dc_1(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000260 callee_->CreateDataChannel("data", init));
261
262 Negotiate();
263 WaitForConnection();
264
265 EXPECT_EQ(1U, caller_dc_1->id() % 2);
266 EXPECT_EQ(0U, callee_dc_1->id() % 2);
267
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000268 rtc::scoped_refptr<DataChannelInterface> caller_dc_2(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000269 caller_->CreateDataChannel("data", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000270 rtc::scoped_refptr<DataChannelInterface> callee_dc_2(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000271 callee_->CreateDataChannel("data", init));
272
273 EXPECT_EQ(1U, caller_dc_2->id() % 2);
274 EXPECT_EQ(0U, callee_dc_2->id() % 2);
275}
276
277// Verifies that the message is received by the right remote DataChannel when
278// there are multiple DataChannels.
279TEST_F(PeerConnectionEndToEndTest,
280 MessageTransferBetweenTwoPairsOfDataChannels) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000281 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000282
283 CreatePcs();
284
285 webrtc::DataChannelInit init;
286
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000287 rtc::scoped_refptr<DataChannelInterface> caller_dc_1(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000288 caller_->CreateDataChannel("data", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000289 rtc::scoped_refptr<DataChannelInterface> caller_dc_2(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000290 caller_->CreateDataChannel("data", init));
291
292 Negotiate();
293 WaitForConnection();
294 WaitForDataChannelsToOpen(caller_dc_1, callee_signaled_data_channels_, 0);
295 WaitForDataChannelsToOpen(caller_dc_2, callee_signaled_data_channels_, 1);
296
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000297 rtc::scoped_ptr<webrtc::MockDataChannelObserver> dc_1_observer(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000298 new webrtc::MockDataChannelObserver(callee_signaled_data_channels_[0]));
299
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000300 rtc::scoped_ptr<webrtc::MockDataChannelObserver> dc_2_observer(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000301 new webrtc::MockDataChannelObserver(callee_signaled_data_channels_[1]));
302
303 const std::string message_1 = "hello 1";
304 const std::string message_2 = "hello 2";
305
306 caller_dc_1->Send(webrtc::DataBuffer(message_1));
307 EXPECT_EQ_WAIT(message_1, dc_1_observer->last_message(), kMaxWait);
308
309 caller_dc_2->Send(webrtc::DataBuffer(message_2));
310 EXPECT_EQ_WAIT(message_2, dc_2_observer->last_message(), kMaxWait);
311
312 EXPECT_EQ(1U, dc_1_observer->received_message_count());
313 EXPECT_EQ(1U, dc_2_observer->received_message_count());
314}
deadbeefab9b2d12015-10-14 11:33:11 -0700315
316// Verifies that a DataChannel added from an OPEN message functions after
317// a channel has been previously closed (webrtc issue 3778).
318// This previously failed because the new channel re-uses the ID of the closed
319// channel, and the closed channel was incorrectly still assigned to the id.
320// TODO(deadbeef): This is disabled because there's currently a race condition
321// caused by the fact that a data channel signals that it's closed before it
322// really is. Re-enable this test once that's fixed.
323TEST_F(PeerConnectionEndToEndTest,
324 DISABLED_DataChannelFromOpenWorksAfterClose) {
325 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
326
327 CreatePcs();
328
329 webrtc::DataChannelInit init;
330 rtc::scoped_refptr<DataChannelInterface> caller_dc(
331 caller_->CreateDataChannel("data", init));
332
333 Negotiate();
334 WaitForConnection();
335
336 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 0);
337 CloseDataChannels(caller_dc, callee_signaled_data_channels_, 0);
338
339 // Create a new channel and ensure it works after closing the previous one.
340 caller_dc = caller_->CreateDataChannel("data2", init);
341
342 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 1);
343 TestDataChannelSendAndReceive(caller_dc, callee_signaled_data_channels_[1]);
344
345 CloseDataChannels(caller_dc, callee_signaled_data_channels_, 1);
346}
deadbeefbd292462015-12-14 18:15:29 -0800347
348// This tests that if a data channel is closed remotely while not referenced
349// by the application (meaning only the PeerConnection contributes to its
350// reference count), no memory access violation will occur.
351// See: https://code.google.com/p/chromium/issues/detail?id=565048
352TEST_F(PeerConnectionEndToEndTest, CloseDataChannelRemotelyWhileNotReferenced) {
353 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
354
355 CreatePcs();
356
357 webrtc::DataChannelInit init;
358 rtc::scoped_refptr<DataChannelInterface> caller_dc(
359 caller_->CreateDataChannel("data", init));
360
361 Negotiate();
362 WaitForConnection();
363
364 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 0);
365 // This removes the reference to the remote data channel that we hold.
366 callee_signaled_data_channels_.clear();
367 caller_dc->Close();
368 EXPECT_EQ_WAIT(DataChannelInterface::kClosed, caller_dc->state(), kMaxWait);
369
370 // Wait for a bit longer so the remote data channel will receive the
371 // close message and be destroyed.
372 rtc::Thread::Current()->ProcessMessages(100);
373}