blob: 1a180317acc05953fe972fe8731cf5b67a104d85 [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
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000028#include "talk/app/webrtc/test/peerconnectiontestwrapper.h"
henrike@webrtc.orgd968dd02014-08-13 18:39:43 +000029#include "talk/app/webrtc/test/mockpeerconnectionobservers.h"
phoglund37ebcf02016-01-08 05:04:57 -080030#ifdef WEBRTC_ANDROID
31#include "talk/app/webrtc/test/androidtestinitializer.h"
32#endif
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000033#include "webrtc/base/gunit.h"
34#include "webrtc/base/logging.h"
35#include "webrtc/base/ssladapter.h"
36#include "webrtc/base/sslstreamadapter.h"
37#include "webrtc/base/stringencode.h"
38#include "webrtc/base/stringutils.h"
wu@webrtc.org364f2042013-11-20 21:49:41 +000039
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +000040#define MAYBE_SKIP_TEST(feature) \
41 if (!(feature())) { \
42 LOG(LS_INFO) << "Feature disabled... skipping"; \
43 return; \
44 }
45
46using webrtc::DataChannelInterface;
wu@webrtc.org364f2042013-11-20 21:49:41 +000047using webrtc::FakeConstraints;
48using webrtc::MediaConstraintsInterface;
49using webrtc::MediaStreamInterface;
50using webrtc::PeerConnectionInterface;
51
52namespace {
53
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +000054const size_t kMaxWait = 10000;
wu@webrtc.org364f2042013-11-20 21:49:41 +000055
wu@webrtc.org364f2042013-11-20 21:49:41 +000056} // namespace
57
58class PeerConnectionEndToEndTest
59 : public sigslot::has_slots<>,
60 public testing::Test {
61 public:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000062 typedef std::vector<rtc::scoped_refptr<DataChannelInterface> >
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +000063 DataChannelList;
64
wu@webrtc.org364f2042013-11-20 21:49:41 +000065 PeerConnectionEndToEndTest()
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000066 : caller_(new rtc::RefCountedObject<PeerConnectionTestWrapper>(
wu@webrtc.org364f2042013-11-20 21:49:41 +000067 "caller")),
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000068 callee_(new rtc::RefCountedObject<PeerConnectionTestWrapper>(
wu@webrtc.org364f2042013-11-20 21:49:41 +000069 "callee")) {
phoglund37ebcf02016-01-08 05:04:57 -080070#ifdef WEBRTC_ANDROID
71 webrtc::InitializeAndroidObjects();
72#endif
wu@webrtc.org364f2042013-11-20 21:49:41 +000073 }
74
75 void CreatePcs() {
76 CreatePcs(NULL);
77 }
78
79 void CreatePcs(const MediaConstraintsInterface* pc_constraints) {
80 EXPECT_TRUE(caller_->CreatePc(pc_constraints));
81 EXPECT_TRUE(callee_->CreatePc(pc_constraints));
82 PeerConnectionTestWrapper::Connect(caller_.get(), callee_.get());
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +000083
84 caller_->SignalOnDataChannel.connect(
85 this, &PeerConnectionEndToEndTest::OnCallerAddedDataChanel);
86 callee_->SignalOnDataChannel.connect(
87 this, &PeerConnectionEndToEndTest::OnCalleeAddedDataChannel);
wu@webrtc.org364f2042013-11-20 21:49:41 +000088 }
89
90 void GetAndAddUserMedia() {
91 FakeConstraints audio_constraints;
92 FakeConstraints video_constraints;
93 GetAndAddUserMedia(true, audio_constraints, true, video_constraints);
94 }
95
96 void GetAndAddUserMedia(bool audio, FakeConstraints audio_constraints,
97 bool video, FakeConstraints video_constraints) {
98 caller_->GetAndAddUserMedia(audio, audio_constraints,
99 video, video_constraints);
100 callee_->GetAndAddUserMedia(audio, audio_constraints,
101 video, video_constraints);
102 }
103
104 void Negotiate() {
105 caller_->CreateOffer(NULL);
106 }
107
108 void WaitForCallEstablished() {
109 caller_->WaitForCallEstablished();
110 callee_->WaitForCallEstablished();
111 }
112
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000113 void WaitForConnection() {
114 caller_->WaitForConnection();
115 callee_->WaitForConnection();
116 }
117
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000118 void OnCallerAddedDataChanel(DataChannelInterface* dc) {
119 caller_signaled_data_channels_.push_back(dc);
120 }
121
122 void OnCalleeAddedDataChannel(DataChannelInterface* dc) {
123 callee_signaled_data_channels_.push_back(dc);
124 }
125
126 // Tests that |dc1| and |dc2| can send to and receive from each other.
127 void TestDataChannelSendAndReceive(
128 DataChannelInterface* dc1, DataChannelInterface* dc2) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000129 rtc::scoped_ptr<webrtc::MockDataChannelObserver> dc1_observer(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000130 new webrtc::MockDataChannelObserver(dc1));
131
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000132 rtc::scoped_ptr<webrtc::MockDataChannelObserver> dc2_observer(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000133 new webrtc::MockDataChannelObserver(dc2));
134
135 static const std::string kDummyData = "abcdefg";
136 webrtc::DataBuffer buffer(kDummyData);
137 EXPECT_TRUE(dc1->Send(buffer));
138 EXPECT_EQ_WAIT(kDummyData, dc2_observer->last_message(), kMaxWait);
139
140 EXPECT_TRUE(dc2->Send(buffer));
141 EXPECT_EQ_WAIT(kDummyData, dc1_observer->last_message(), kMaxWait);
142
143 EXPECT_EQ(1U, dc1_observer->received_message_count());
144 EXPECT_EQ(1U, dc2_observer->received_message_count());
145 }
146
147 void WaitForDataChannelsToOpen(DataChannelInterface* local_dc,
148 const DataChannelList& remote_dc_list,
149 size_t remote_dc_index) {
150 EXPECT_EQ_WAIT(DataChannelInterface::kOpen, local_dc->state(), kMaxWait);
151
152 EXPECT_TRUE_WAIT(remote_dc_list.size() > remote_dc_index, kMaxWait);
153 EXPECT_EQ_WAIT(DataChannelInterface::kOpen,
154 remote_dc_list[remote_dc_index]->state(),
155 kMaxWait);
156 EXPECT_EQ(local_dc->id(), remote_dc_list[remote_dc_index]->id());
157 }
158
159 void CloseDataChannels(DataChannelInterface* local_dc,
160 const DataChannelList& remote_dc_list,
161 size_t remote_dc_index) {
162 local_dc->Close();
163 EXPECT_EQ_WAIT(DataChannelInterface::kClosed, local_dc->state(), kMaxWait);
164 EXPECT_EQ_WAIT(DataChannelInterface::kClosed,
165 remote_dc_list[remote_dc_index]->state(),
166 kMaxWait);
167 }
168
wu@webrtc.org364f2042013-11-20 21:49:41 +0000169 protected:
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000170 rtc::scoped_refptr<PeerConnectionTestWrapper> caller_;
171 rtc::scoped_refptr<PeerConnectionTestWrapper> callee_;
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000172 DataChannelList caller_signaled_data_channels_;
173 DataChannelList callee_signaled_data_channels_;
wu@webrtc.org364f2042013-11-20 21:49:41 +0000174};
175
kjellander@webrtc.org70c0e292015-11-30 21:45:35 +0100176// Disabled for TSan v2, see
177// https://bugs.chromium.org/p/webrtc/issues/detail?id=4719 for details.
kjellander@webrtc.org3c28d0d2015-12-02 22:53:26 +0100178// Disabled for Mac, see
179// https://bugs.chromium.org/p/webrtc/issues/detail?id=5231 for details.
180#if !defined(THREAD_SANITIZER) && !defined(WEBRTC_MAC)
deadbeefee8c6d32015-08-13 14:27:18 -0700181TEST_F(PeerConnectionEndToEndTest, Call) {
wu@webrtc.org364f2042013-11-20 21:49:41 +0000182 CreatePcs();
183 GetAndAddUserMedia();
184 Negotiate();
185 WaitForCallEstablished();
186}
kjellander@webrtc.org3c28d0d2015-12-02 22:53:26 +0100187#endif // if !defined(THREAD_SANITIZER) && !defined(WEBRTC_MAC)
wu@webrtc.org364f2042013-11-20 21:49:41 +0000188
deadbeefc9be0072015-12-14 18:27:57 -0800189TEST_F(PeerConnectionEndToEndTest, CallWithLegacySdp) {
wu@webrtc.org364f2042013-11-20 21:49:41 +0000190 FakeConstraints pc_constraints;
191 pc_constraints.AddMandatory(MediaConstraintsInterface::kEnableDtlsSrtp,
192 false);
193 CreatePcs(&pc_constraints);
wu@webrtc.org364f2042013-11-20 21:49:41 +0000194 GetAndAddUserMedia();
195 Negotiate();
196 WaitForCallEstablished();
197}
wu@webrtc.orgb43202d2013-11-22 19:14:25 +0000198
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000199// Verifies that a DataChannel created before the negotiation can transition to
200// "OPEN" and transfer data.
201TEST_F(PeerConnectionEndToEndTest, CreateDataChannelBeforeNegotiate) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000202 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000203
204 CreatePcs();
205
206 webrtc::DataChannelInit init;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000207 rtc::scoped_refptr<DataChannelInterface> caller_dc(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000208 caller_->CreateDataChannel("data", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000209 rtc::scoped_refptr<DataChannelInterface> callee_dc(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000210 callee_->CreateDataChannel("data", init));
211
212 Negotiate();
213 WaitForConnection();
214
215 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 0);
216 WaitForDataChannelsToOpen(callee_dc, caller_signaled_data_channels_, 0);
217
218 TestDataChannelSendAndReceive(caller_dc, callee_signaled_data_channels_[0]);
219 TestDataChannelSendAndReceive(callee_dc, caller_signaled_data_channels_[0]);
220
221 CloseDataChannels(caller_dc, callee_signaled_data_channels_, 0);
222 CloseDataChannels(callee_dc, caller_signaled_data_channels_, 0);
223}
224
225// Verifies that a DataChannel created after the negotiation can transition to
226// "OPEN" and transfer data.
henrik.lundin@webrtc.org22362672014-11-03 13:38:50 +0000227#if defined(MEMORY_SANITIZER)
228// Fails under MemorySanitizer:
229// See https://code.google.com/p/webrtc/issues/detail?id=3980.
230#define MAYBE_CreateDataChannelAfterNegotiate DISABLED_CreateDataChannelAfterNegotiate
231#else
232#define MAYBE_CreateDataChannelAfterNegotiate CreateDataChannelAfterNegotiate
233#endif
234TEST_F(PeerConnectionEndToEndTest, MAYBE_CreateDataChannelAfterNegotiate) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000235 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000236
237 CreatePcs();
238
239 webrtc::DataChannelInit init;
240
241 // This DataChannel is for creating the data content in the negotiation.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000242 rtc::scoped_refptr<DataChannelInterface> dummy(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000243 caller_->CreateDataChannel("data", init));
244 Negotiate();
245 WaitForConnection();
246
247 // Creates new DataChannels after the negotiation and verifies their states.
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000248 rtc::scoped_refptr<DataChannelInterface> caller_dc(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000249 caller_->CreateDataChannel("hello", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000250 rtc::scoped_refptr<DataChannelInterface> callee_dc(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000251 callee_->CreateDataChannel("hello", init));
252
253 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 1);
254 WaitForDataChannelsToOpen(callee_dc, caller_signaled_data_channels_, 0);
255
256 TestDataChannelSendAndReceive(caller_dc, callee_signaled_data_channels_[1]);
257 TestDataChannelSendAndReceive(callee_dc, caller_signaled_data_channels_[0]);
258
259 CloseDataChannels(caller_dc, callee_signaled_data_channels_, 1);
260 CloseDataChannels(callee_dc, caller_signaled_data_channels_, 0);
261}
262
263// Verifies that DataChannel IDs are even/odd based on the DTLS roles.
264TEST_F(PeerConnectionEndToEndTest, DataChannelIdAssignment) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000265 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000266
267 CreatePcs();
268
269 webrtc::DataChannelInit init;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000270 rtc::scoped_refptr<DataChannelInterface> caller_dc_1(
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_1(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000273 callee_->CreateDataChannel("data", init));
274
275 Negotiate();
276 WaitForConnection();
277
278 EXPECT_EQ(1U, caller_dc_1->id() % 2);
279 EXPECT_EQ(0U, callee_dc_1->id() % 2);
280
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000281 rtc::scoped_refptr<DataChannelInterface> caller_dc_2(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000282 caller_->CreateDataChannel("data", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000283 rtc::scoped_refptr<DataChannelInterface> callee_dc_2(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000284 callee_->CreateDataChannel("data", init));
285
286 EXPECT_EQ(1U, caller_dc_2->id() % 2);
287 EXPECT_EQ(0U, callee_dc_2->id() % 2);
288}
289
290// Verifies that the message is received by the right remote DataChannel when
291// there are multiple DataChannels.
292TEST_F(PeerConnectionEndToEndTest,
293 MessageTransferBetweenTwoPairsOfDataChannels) {
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000294 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000295
296 CreatePcs();
297
298 webrtc::DataChannelInit init;
299
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000300 rtc::scoped_refptr<DataChannelInterface> caller_dc_1(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000301 caller_->CreateDataChannel("data", init));
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000302 rtc::scoped_refptr<DataChannelInterface> caller_dc_2(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000303 caller_->CreateDataChannel("data", init));
304
305 Negotiate();
306 WaitForConnection();
307 WaitForDataChannelsToOpen(caller_dc_1, callee_signaled_data_channels_, 0);
308 WaitForDataChannelsToOpen(caller_dc_2, callee_signaled_data_channels_, 1);
309
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000310 rtc::scoped_ptr<webrtc::MockDataChannelObserver> dc_1_observer(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000311 new webrtc::MockDataChannelObserver(callee_signaled_data_channels_[0]));
312
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000313 rtc::scoped_ptr<webrtc::MockDataChannelObserver> dc_2_observer(
jiayl@webrtc.org1a6c6282014-06-12 21:59:29 +0000314 new webrtc::MockDataChannelObserver(callee_signaled_data_channels_[1]));
315
316 const std::string message_1 = "hello 1";
317 const std::string message_2 = "hello 2";
318
319 caller_dc_1->Send(webrtc::DataBuffer(message_1));
320 EXPECT_EQ_WAIT(message_1, dc_1_observer->last_message(), kMaxWait);
321
322 caller_dc_2->Send(webrtc::DataBuffer(message_2));
323 EXPECT_EQ_WAIT(message_2, dc_2_observer->last_message(), kMaxWait);
324
325 EXPECT_EQ(1U, dc_1_observer->received_message_count());
326 EXPECT_EQ(1U, dc_2_observer->received_message_count());
327}
deadbeefab9b2d12015-10-14 11:33:11 -0700328
329// Verifies that a DataChannel added from an OPEN message functions after
330// a channel has been previously closed (webrtc issue 3778).
331// This previously failed because the new channel re-uses the ID of the closed
332// channel, and the closed channel was incorrectly still assigned to the id.
333// TODO(deadbeef): This is disabled because there's currently a race condition
334// caused by the fact that a data channel signals that it's closed before it
335// really is. Re-enable this test once that's fixed.
336TEST_F(PeerConnectionEndToEndTest,
337 DISABLED_DataChannelFromOpenWorksAfterClose) {
338 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
339
340 CreatePcs();
341
342 webrtc::DataChannelInit init;
343 rtc::scoped_refptr<DataChannelInterface> caller_dc(
344 caller_->CreateDataChannel("data", init));
345
346 Negotiate();
347 WaitForConnection();
348
349 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 0);
350 CloseDataChannels(caller_dc, callee_signaled_data_channels_, 0);
351
352 // Create a new channel and ensure it works after closing the previous one.
353 caller_dc = caller_->CreateDataChannel("data2", init);
354
355 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 1);
356 TestDataChannelSendAndReceive(caller_dc, callee_signaled_data_channels_[1]);
357
358 CloseDataChannels(caller_dc, callee_signaled_data_channels_, 1);
359}
deadbeefbd292462015-12-14 18:15:29 -0800360
361// This tests that if a data channel is closed remotely while not referenced
362// by the application (meaning only the PeerConnection contributes to its
363// reference count), no memory access violation will occur.
364// See: https://code.google.com/p/chromium/issues/detail?id=565048
365TEST_F(PeerConnectionEndToEndTest, CloseDataChannelRemotelyWhileNotReferenced) {
366 MAYBE_SKIP_TEST(rtc::SSLStreamAdapter::HaveDtlsSrtp);
367
368 CreatePcs();
369
370 webrtc::DataChannelInit init;
371 rtc::scoped_refptr<DataChannelInterface> caller_dc(
372 caller_->CreateDataChannel("data", init));
373
374 Negotiate();
375 WaitForConnection();
376
377 WaitForDataChannelsToOpen(caller_dc, callee_signaled_data_channels_, 0);
378 // This removes the reference to the remote data channel that we hold.
379 callee_signaled_data_channels_.clear();
380 caller_dc->Close();
381 EXPECT_EQ_WAIT(DataChannelInterface::kClosed, caller_dc->state(), kMaxWait);
382
383 // Wait for a bit longer so the remote data channel will receive the
384 // close message and be destroyed.
385 rtc::Thread::Current()->ProcessMessages(100);
386}