blob: adcfe5710235bc8d63eb0bd7c38d82ca0bc0b9b5 [file] [log] [blame]
wu@webrtc.org364f2042013-11-20 21:49:41 +00001/*
2 * libjingle
jlmiller@webrtc.org5f93d0a2015-01-20 21:36:13 +00003 * Copyright 2013 Google Inc.
wu@webrtc.org364f2042013-11-20 21:49:41 +00004 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
Henrik Kjellander15583c12016-02-10 10:53:12 +010028#include "webrtc/api/test/peerconnectiontestwrapper.h"
kjellandera96e2d72016-02-04 23:52:28 -080029// Notice that mockpeerconnectionobservers.h must be included after the above!
Henrik Kjellander15583c12016-02-10 10:53:12 +010030#include "webrtc/api/test/mockpeerconnectionobservers.h"
phoglund37ebcf02016-01-08 05:04:57 -080031#ifdef WEBRTC_ANDROID
Henrik Kjellander15583c12016-02-10 10:53:12 +010032#include "webrtc/api/test/androidtestinitializer.h"
phoglund37ebcf02016-01-08 05:04:57 -080033#endif
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000034#include "webrtc/base/gunit.h"
35#include "webrtc/base/logging.h"
36#include "webrtc/base/ssladapter.h"
37#include "webrtc/base/sslstreamadapter.h"
38#include "webrtc/base/stringencode.h"
39#include "webrtc/base/stringutils.h"
wu@webrtc.org364f2042013-11-20 21:49:41 +000040
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +000041#define MAYBE_SKIP_TEST(feature) \
42 if (!(feature())) { \
43 LOG(LS_INFO) << "Feature disabled... skipping"; \
44 return; \
45 }
46
47using webrtc::DataChannelInterface;
wu@webrtc.org364f2042013-11-20 21:49:41 +000048using webrtc::FakeConstraints;
49using webrtc::MediaConstraintsInterface;
50using webrtc::MediaStreamInterface;
51using webrtc::PeerConnectionInterface;
52
53namespace {
54
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +000055const size_t kMaxWait = 10000;
wu@webrtc.org364f2042013-11-20 21:49:41 +000056
wu@webrtc.org364f2042013-11-20 21:49:41 +000057} // namespace
58
59class PeerConnectionEndToEndTest
60 : public sigslot::has_slots<>,
61 public testing::Test {
62 public:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000063 typedef std::vector<rtc::scoped_refptr<DataChannelInterface> >
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +000064 DataChannelList;
65
wu@webrtc.org364f2042013-11-20 21:49:41 +000066 PeerConnectionEndToEndTest()
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000067 : caller_(new rtc::RefCountedObject<PeerConnectionTestWrapper>(
wu@webrtc.org364f2042013-11-20 21:49:41 +000068 "caller")),
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000069 callee_(new rtc::RefCountedObject<PeerConnectionTestWrapper>(
wu@webrtc.org364f2042013-11-20 21:49:41 +000070 "callee")) {
phoglund37ebcf02016-01-08 05:04:57 -080071#ifdef WEBRTC_ANDROID
72 webrtc::InitializeAndroidObjects();
73#endif
wu@webrtc.org364f2042013-11-20 21:49:41 +000074 }
75
76 void CreatePcs() {
77 CreatePcs(NULL);
78 }
79
80 void CreatePcs(const MediaConstraintsInterface* pc_constraints) {
81 EXPECT_TRUE(caller_->CreatePc(pc_constraints));
82 EXPECT_TRUE(callee_->CreatePc(pc_constraints));
83 PeerConnectionTestWrapper::Connect(caller_.get(), callee_.get());
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +000084
85 caller_->SignalOnDataChannel.connect(
86 this, &PeerConnectionEndToEndTest::OnCallerAddedDataChanel);
87 callee_->SignalOnDataChannel.connect(
88 this, &PeerConnectionEndToEndTest::OnCalleeAddedDataChannel);
wu@webrtc.org364f2042013-11-20 21:49:41 +000089 }
90
91 void GetAndAddUserMedia() {
92 FakeConstraints audio_constraints;
93 FakeConstraints video_constraints;
94 GetAndAddUserMedia(true, audio_constraints, true, video_constraints);
95 }
96
97 void GetAndAddUserMedia(bool audio, FakeConstraints audio_constraints,
98 bool video, FakeConstraints video_constraints) {
99 caller_->GetAndAddUserMedia(audio, audio_constraints,
100 video, video_constraints);
101 callee_->GetAndAddUserMedia(audio, audio_constraints,
102 video, video_constraints);
103 }
104
105 void Negotiate() {
106 caller_->CreateOffer(NULL);
107 }
108
109 void WaitForCallEstablished() {
110 caller_->WaitForCallEstablished();
111 callee_->WaitForCallEstablished();
112 }
113
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000114 void WaitForConnection() {
115 caller_->WaitForConnection();
116 callee_->WaitForConnection();
117 }
118
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000119 void OnCallerAddedDataChanel(DataChannelInterface* dc) {
120 caller_signaled_data_channels_.push_back(dc);
121 }
122
123 void OnCalleeAddedDataChannel(DataChannelInterface* dc) {
124 callee_signaled_data_channels_.push_back(dc);
125 }
126
127 // Tests that |dc1| and |dc2| can send to and receive from each other.
128 void TestDataChannelSendAndReceive(
129 DataChannelInterface* dc1, DataChannelInterface* dc2) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000130 rtc::scoped_ptr<webrtc::MockDataChannelObserver> dc1_observer(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000131 new webrtc::MockDataChannelObserver(dc1));
132
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000133 rtc::scoped_ptr<webrtc::MockDataChannelObserver> dc2_observer(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000134 new webrtc::MockDataChannelObserver(dc2));
135
136 static const std::string kDummyData = "abcdefg";
137 webrtc::DataBuffer buffer(kDummyData);
138 EXPECT_TRUE(dc1->Send(buffer));
139 EXPECT_EQ_WAIT(kDummyData, dc2_observer->last_message(), kMaxWait);
140
141 EXPECT_TRUE(dc2->Send(buffer));
142 EXPECT_EQ_WAIT(kDummyData, dc1_observer->last_message(), kMaxWait);
143
144 EXPECT_EQ(1U, dc1_observer->received_message_count());
145 EXPECT_EQ(1U, dc2_observer->received_message_count());
146 }
147
148 void WaitForDataChannelsToOpen(DataChannelInterface* local_dc,
149 const DataChannelList& remote_dc_list,
150 size_t remote_dc_index) {
151 EXPECT_EQ_WAIT(DataChannelInterface::kOpen, local_dc->state(), kMaxWait);
152
153 EXPECT_TRUE_WAIT(remote_dc_list.size() > remote_dc_index, kMaxWait);
154 EXPECT_EQ_WAIT(DataChannelInterface::kOpen,
155 remote_dc_list[remote_dc_index]->state(),
156 kMaxWait);
157 EXPECT_EQ(local_dc->id(), remote_dc_list[remote_dc_index]->id());
158 }
159
160 void CloseDataChannels(DataChannelInterface* local_dc,
161 const DataChannelList& remote_dc_list,
162 size_t remote_dc_index) {
163 local_dc->Close();
164 EXPECT_EQ_WAIT(DataChannelInterface::kClosed, local_dc->state(), kMaxWait);
165 EXPECT_EQ_WAIT(DataChannelInterface::kClosed,
166 remote_dc_list[remote_dc_index]->state(),
167 kMaxWait);
168 }
169
wu@webrtc.org364f2042013-11-20 21:49:41 +0000170 protected:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000171 rtc::scoped_refptr<PeerConnectionTestWrapper> caller_;
172 rtc::scoped_refptr<PeerConnectionTestWrapper> callee_;
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000173 DataChannelList caller_signaled_data_channels_;
174 DataChannelList callee_signaled_data_channels_;
wu@webrtc.org364f2042013-11-20 21:49:41 +0000175};
176
kjellander@webrtc.org70c0e292015-11-30 21:45:35 +0100177// Disabled for TSan v2, see
178// https://bugs.chromium.org/p/webrtc/issues/detail?id=4719 for details.
kjellander@webrtc.org3c28d0d2015-12-02 22:53:26 +0100179// Disabled for Mac, see
180// https://bugs.chromium.org/p/webrtc/issues/detail?id=5231 for details.
181#if !defined(THREAD_SANITIZER) && !defined(WEBRTC_MAC)
deadbeefee8c6d32015-08-13 14:27:18 -0700182TEST_F(PeerConnectionEndToEndTest, Call) {
wu@webrtc.org364f2042013-11-20 21:49:41 +0000183 CreatePcs();
184 GetAndAddUserMedia();
185 Negotiate();
186 WaitForCallEstablished();
187}
kjellander@webrtc.org3c28d0d2015-12-02 22:53:26 +0100188#endif // if !defined(THREAD_SANITIZER) && !defined(WEBRTC_MAC)
wu@webrtc.org364f2042013-11-20 21:49:41 +0000189
deadbeefc9be0072015-12-14 18:27:57 -0800190TEST_F(PeerConnectionEndToEndTest, CallWithLegacySdp) {
wu@webrtc.org364f2042013-11-20 21:49:41 +0000191 FakeConstraints pc_constraints;
192 pc_constraints.AddMandatory(MediaConstraintsInterface::kEnableDtlsSrtp,
193 false);
194 CreatePcs(&pc_constraints);
wu@webrtc.org364f2042013-11-20 21:49:41 +0000195 GetAndAddUserMedia();
196 Negotiate();
197 WaitForCallEstablished();
198}
wu@webrtc.orgb43202d2013-11-22 19:14:25 +0000199
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000200// Verifies that a DataChannel created before the negotiation can transition to
201// "OPEN" and transfer data.
202TEST_F(PeerConnectionEndToEndTest, CreateDataChannelBeforeNegotiate) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000203 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000204
205 CreatePcs();
206
207 webrtc::DataChannelInit init;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000208 rtc::scoped_refptr<DataChannelInterface> caller_dc(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000209 caller_->CreateDataChannel("data", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000210 rtc::scoped_refptr<DataChannelInterface> callee_dc(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000211 callee_->CreateDataChannel("data", init));
212
213 Negotiate();
214 WaitForConnection();
215
216 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 0);
217 WaitForDataChannelsToOpen(callee_dc, caller_signaled_data_channels_, 0);
218
219 TestDataChannelSendAndReceive(caller_dc, callee_signaled_data_channels_[0]);
220 TestDataChannelSendAndReceive(callee_dc, caller_signaled_data_channels_[0]);
221
222 CloseDataChannels(caller_dc, callee_signaled_data_channels_, 0);
223 CloseDataChannels(callee_dc, caller_signaled_data_channels_, 0);
224}
225
226// Verifies that a DataChannel created after the negotiation can transition to
227// "OPEN" and transfer data.
henrik.lundin@webrtc.org22362672014-11-03 13:38:50 +0000228#if defined(MEMORY_SANITIZER)
229// Fails under MemorySanitizer:
230// See https://code.google.com/p/webrtc/issues/detail?id=3980.
231#define MAYBE_CreateDataChannelAfterNegotiate DISABLED_CreateDataChannelAfterNegotiate
232#else
233#define MAYBE_CreateDataChannelAfterNegotiate CreateDataChannelAfterNegotiate
234#endif
235TEST_F(PeerConnectionEndToEndTest, MAYBE_CreateDataChannelAfterNegotiate) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000236 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000237
238 CreatePcs();
239
240 webrtc::DataChannelInit init;
241
242 // This DataChannel is for creating the data content in the negotiation.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000243 rtc::scoped_refptr<DataChannelInterface> dummy(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000244 caller_->CreateDataChannel("data", init));
245 Negotiate();
246 WaitForConnection();
247
248 // Creates new DataChannels after the negotiation and verifies their states.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000249 rtc::scoped_refptr<DataChannelInterface> caller_dc(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000250 caller_->CreateDataChannel("hello", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000251 rtc::scoped_refptr<DataChannelInterface> callee_dc(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000252 callee_->CreateDataChannel("hello", init));
253
254 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 1);
255 WaitForDataChannelsToOpen(callee_dc, caller_signaled_data_channels_, 0);
256
257 TestDataChannelSendAndReceive(caller_dc, callee_signaled_data_channels_[1]);
258 TestDataChannelSendAndReceive(callee_dc, caller_signaled_data_channels_[0]);
259
260 CloseDataChannels(caller_dc, callee_signaled_data_channels_, 1);
261 CloseDataChannels(callee_dc, caller_signaled_data_channels_, 0);
262}
263
264// Verifies that DataChannel IDs are even/odd based on the DTLS roles.
265TEST_F(PeerConnectionEndToEndTest, DataChannelIdAssignment) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000266 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000267
268 CreatePcs();
269
270 webrtc::DataChannelInit init;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000271 rtc::scoped_refptr<DataChannelInterface> caller_dc_1(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000272 caller_->CreateDataChannel("data", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000273 rtc::scoped_refptr<DataChannelInterface> callee_dc_1(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000274 callee_->CreateDataChannel("data", init));
275
276 Negotiate();
277 WaitForConnection();
278
279 EXPECT_EQ(1U, caller_dc_1->id() % 2);
280 EXPECT_EQ(0U, callee_dc_1->id() % 2);
281
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000282 rtc::scoped_refptr<DataChannelInterface> caller_dc_2(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000283 caller_->CreateDataChannel("data", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000284 rtc::scoped_refptr<DataChannelInterface> callee_dc_2(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000285 callee_->CreateDataChannel("data", init));
286
287 EXPECT_EQ(1U, caller_dc_2->id() % 2);
288 EXPECT_EQ(0U, callee_dc_2->id() % 2);
289}
290
291// Verifies that the message is received by the right remote DataChannel when
292// there are multiple DataChannels.
293TEST_F(PeerConnectionEndToEndTest,
294 MessageTransferBetweenTwoPairsOfDataChannels) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000295 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000296
297 CreatePcs();
298
299 webrtc::DataChannelInit init;
300
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000301 rtc::scoped_refptr<DataChannelInterface> caller_dc_1(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000302 caller_->CreateDataChannel("data", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000303 rtc::scoped_refptr<DataChannelInterface> caller_dc_2(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000304 caller_->CreateDataChannel("data", init));
305
306 Negotiate();
307 WaitForConnection();
308 WaitForDataChannelsToOpen(caller_dc_1, callee_signaled_data_channels_, 0);
309 WaitForDataChannelsToOpen(caller_dc_2, callee_signaled_data_channels_, 1);
310
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000311 rtc::scoped_ptr<webrtc::MockDataChannelObserver> dc_1_observer(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000312 new webrtc::MockDataChannelObserver(callee_signaled_data_channels_[0]));
313
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000314 rtc::scoped_ptr<webrtc::MockDataChannelObserver> dc_2_observer(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000315 new webrtc::MockDataChannelObserver(callee_signaled_data_channels_[1]));
316
317 const std::string message_1 = "hello 1";
318 const std::string message_2 = "hello 2";
319
320 caller_dc_1->Send(webrtc::DataBuffer(message_1));
321 EXPECT_EQ_WAIT(message_1, dc_1_observer->last_message(), kMaxWait);
322
323 caller_dc_2->Send(webrtc::DataBuffer(message_2));
324 EXPECT_EQ_WAIT(message_2, dc_2_observer->last_message(), kMaxWait);
325
326 EXPECT_EQ(1U, dc_1_observer->received_message_count());
327 EXPECT_EQ(1U, dc_2_observer->received_message_count());
328}
deadbeefab9b2d12015-10-14 11:33:11 -0700329
330// Verifies that a DataChannel added from an OPEN message functions after
331// a channel has been previously closed (webrtc issue 3778).
332// This previously failed because the new channel re-uses the ID of the closed
333// channel, and the closed channel was incorrectly still assigned to the id.
334// TODO(deadbeef): This is disabled because there's currently a race condition
335// caused by the fact that a data channel signals that it's closed before it
336// really is. Re-enable this test once that's fixed.
337TEST_F(PeerConnectionEndToEndTest,
338 DISABLED_DataChannelFromOpenWorksAfterClose) {
339 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
340
341 CreatePcs();
342
343 webrtc::DataChannelInit init;
344 rtc::scoped_refptr<DataChannelInterface> caller_dc(
345 caller_->CreateDataChannel("data", init));
346
347 Negotiate();
348 WaitForConnection();
349
350 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 0);
351 CloseDataChannels(caller_dc, callee_signaled_data_channels_, 0);
352
353 // Create a new channel and ensure it works after closing the previous one.
354 caller_dc = caller_->CreateDataChannel("data2", init);
355
356 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 1);
357 TestDataChannelSendAndReceive(caller_dc, callee_signaled_data_channels_[1]);
358
359 CloseDataChannels(caller_dc, callee_signaled_data_channels_, 1);
360}
deadbeefbd292462015-12-14 18:15:29 -0800361
362// This tests that if a data channel is closed remotely while not referenced
363// by the application (meaning only the PeerConnection contributes to its
364// reference count), no memory access violation will occur.
365// See: https://code.google.com/p/chromium/issues/detail?id=565048
366TEST_F(PeerConnectionEndToEndTest, CloseDataChannelRemotelyWhileNotReferenced) {
367 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
368
369 CreatePcs();
370
371 webrtc::DataChannelInit init;
372 rtc::scoped_refptr<DataChannelInterface> caller_dc(
373 caller_->CreateDataChannel("data", init));
374
375 Negotiate();
376 WaitForConnection();
377
378 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 0);
379 // This removes the reference to the remote data channel that we hold.
380 callee_signaled_data_channels_.clear();
381 caller_dc->Close();
382 EXPECT_EQ_WAIT(DataChannelInterface::kClosed, caller_dc->state(), kMaxWait);
383
384 // Wait for a bit longer so the remote data channel will receive the
385 // close message and be destroyed.
386 rtc::Thread::Current()->ProcessMessages(100);
387}