Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(66)

Side by Side Diff: webrtc/media/sctp/sctptransport_unittest.cc

Issue 2564333002: Reland of: Separating SCTP code from BaseChannel/MediaChannel. (Closed)
Patch Set: Merge with master. Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/media/sctp/sctptransport.cc ('k') | webrtc/media/sctp/sctptransportinternal.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 *
4 * 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.
9 */
10
11 #include <errno.h>
12 #include <stdarg.h>
13 #include <stdio.h>
14
15 #include <memory>
16 #include <string>
17 #include <vector>
18
19 #include "webrtc/base/bind.h"
20 #include "webrtc/base/copyonwritebuffer.h"
21 #include "webrtc/base/criticalsection.h"
22 #include "webrtc/base/gunit.h"
23 #include "webrtc/base/helpers.h"
24 #include "webrtc/base/ssladapter.h"
25 #include "webrtc/base/thread.h"
26 #include "webrtc/media/sctp/sctptransport.h"
27 #include "webrtc/p2p/base/faketransportcontroller.h"
28
29 namespace {
30 static const int kDefaultTimeout = 10000; // 10 seconds.
31 // Use ports other than the default 5000 for testing.
32 static const int kTransport1Port = 5001;
33 static const int kTransport2Port = 5002;
34 }
35
36 namespace cricket {
37
38 // This is essentially a buffer to hold recieved data. It stores only the last
39 // received data. Calling OnDataReceived twice overwrites old data with the
40 // newer one.
41 // TODO(ldixon): Implement constraints, and allow new data to be added to old
42 // instead of replacing it.
43 class SctpFakeDataReceiver : public sigslot::has_slots<> {
44 public:
45 SctpFakeDataReceiver() : received_(false) {}
46
47 void Clear() {
48 received_ = false;
49 last_data_ = "";
50 last_params_ = ReceiveDataParams();
51 }
52
53 virtual void OnDataReceived(const ReceiveDataParams& params,
54 const rtc::CopyOnWriteBuffer& data) {
55 received_ = true;
56 last_data_ = std::string(data.data<char>(), data.size());
57 last_params_ = params;
58 }
59
60 bool received() const { return received_; }
61 std::string last_data() const { return last_data_; }
62 ReceiveDataParams last_params() const { return last_params_; }
63
64 private:
65 bool received_;
66 std::string last_data_;
67 ReceiveDataParams last_params_;
68 };
69
70 class SignalReadyToSendObserver : public sigslot::has_slots<> {
71 public:
72 SignalReadyToSendObserver() : signaled_(false) {}
73
74 void OnSignaled() { signaled_ = true; }
75
76 bool IsSignaled() { return signaled_; }
77
78 private:
79 bool signaled_;
80 };
81
82 class SignalTransportClosedObserver : public sigslot::has_slots<> {
83 public:
84 SignalTransportClosedObserver() {}
85 void BindSelf(SctpTransport* transport) {
86 transport->SignalStreamClosedRemotely.connect(
87 this, &SignalTransportClosedObserver::OnStreamClosed);
88 }
89 void OnStreamClosed(int stream) { streams_.push_back(stream); }
90
91 int StreamCloseCount(int stream) {
92 return std::count(streams_.begin(), streams_.end(), stream);
93 }
94
95 bool WasStreamClosed(int stream) {
96 return std::find(streams_.begin(), streams_.end(), stream) !=
97 streams_.end();
98 }
99
100 private:
101 std::vector<int> streams_;
102 };
103
104 class SignalTransportClosedReopener : public sigslot::has_slots<> {
105 public:
106 SignalTransportClosedReopener(SctpTransport* transport, SctpTransport* peer)
107 : transport_(transport), peer_(peer) {}
108
109 void OnStreamClosed(int stream) {
110 transport_->OpenStream(stream);
111 peer_->OpenStream(stream);
112 streams_.push_back(stream);
113 }
114
115 int StreamCloseCount(int stream) {
116 return std::count(streams_.begin(), streams_.end(), stream);
117 }
118
119 private:
120 SctpTransport* transport_;
121 SctpTransport* peer_;
122 std::vector<int> streams_;
123 };
124
125 // SCTP Data Engine testing framework.
126 class SctpTransportTest : public testing::Test, public sigslot::has_slots<> {
127 protected:
128 // usrsctp uses the NSS random number generator on non-Android platforms,
129 // so we need to initialize SSL.
130 static void SetUpTestCase() {}
131
132 void SetupConnectedTransportsWithTwoStreams() {
133 fake_dtls1_.reset(new FakeTransportChannel("fake dtls 1", 0));
134 fake_dtls2_.reset(new FakeTransportChannel("fake dtls 2", 0));
135 recv1_.reset(new SctpFakeDataReceiver());
136 recv2_.reset(new SctpFakeDataReceiver());
137 transport1_.reset(CreateTransport(fake_dtls1_.get(), recv1_.get()));
138 transport1_->set_debug_name_for_testing("transport1");
139 transport1_->SignalReadyToSendData.connect(
140 this, &SctpTransportTest::OnChan1ReadyToSend);
141 transport2_.reset(CreateTransport(fake_dtls2_.get(), recv2_.get()));
142 transport2_->set_debug_name_for_testing("transport2");
143 transport2_->SignalReadyToSendData.connect(
144 this, &SctpTransportTest::OnChan2ReadyToSend);
145 // Setup two connected transports ready to send and receive.
146 bool asymmetric = false;
147 fake_dtls1_->SetDestination(fake_dtls2_.get(), asymmetric);
148
149 LOG(LS_VERBOSE) << "Transport setup ----------------------------- ";
150 AddStream(1);
151 AddStream(2);
152
153 LOG(LS_VERBOSE) << "Connect the transports -----------------------------";
154 // Both transports need to have started (with matching ports) for an
155 // association to be formed.
156 transport1_->Start(kTransport1Port, kTransport2Port);
157 transport2_->Start(kTransport2Port, kTransport1Port);
158 }
159
160 bool AddStream(int sid) {
161 bool ret = true;
162 ret = ret && transport1_->OpenStream(sid);
163 ret = ret && transport2_->OpenStream(sid);
164 return ret;
165 }
166
167 SctpTransport* CreateTransport(FakeTransportChannel* fake_dtls,
168 SctpFakeDataReceiver* recv) {
169 SctpTransport* transport =
170 new SctpTransport(rtc::Thread::Current(), fake_dtls);
171 // When data is received, pass it to the SctpFakeDataReceiver.
172 transport->SignalDataReceived.connect(
173 recv, &SctpFakeDataReceiver::OnDataReceived);
174 return transport;
175 }
176
177 bool SendData(SctpTransport* chan,
178 int sid,
179 const std::string& msg,
180 SendDataResult* result) {
181 SendDataParams params;
182 params.sid = sid;
183
184 return chan->SendData(params, rtc::CopyOnWriteBuffer(&msg[0], msg.length()),
185 result);
186 }
187
188 bool ReceivedData(const SctpFakeDataReceiver* recv,
189 int sid,
190 const std::string& msg) {
191 return (recv->received() && recv->last_params().sid == sid &&
192 recv->last_data() == msg);
193 }
194
195 bool ProcessMessagesUntilIdle() {
196 rtc::Thread* thread = rtc::Thread::Current();
197 while (!thread->empty()) {
198 rtc::Message msg;
199 if (thread->Get(&msg, rtc::Thread::kForever)) {
200 thread->Dispatch(&msg);
201 }
202 }
203 return !thread->IsQuitting();
204 }
205
206 SctpTransport* transport1() { return transport1_.get(); }
207 SctpTransport* transport2() { return transport2_.get(); }
208 SctpFakeDataReceiver* receiver1() { return recv1_.get(); }
209 SctpFakeDataReceiver* receiver2() { return recv2_.get(); }
210 FakeTransportChannel* fake_dtls1() { return fake_dtls1_.get(); }
211 FakeTransportChannel* fake_dtls2() { return fake_dtls2_.get(); }
212
213 int transport1_ready_to_send_count() {
214 return transport1_ready_to_send_count_;
215 }
216 int transport2_ready_to_send_count() {
217 return transport2_ready_to_send_count_;
218 }
219
220 private:
221 std::unique_ptr<FakeTransportChannel> fake_dtls1_;
222 std::unique_ptr<FakeTransportChannel> fake_dtls2_;
223 std::unique_ptr<SctpFakeDataReceiver> recv1_;
224 std::unique_ptr<SctpFakeDataReceiver> recv2_;
225 std::unique_ptr<SctpTransport> transport1_;
226 std::unique_ptr<SctpTransport> transport2_;
227
228 int transport1_ready_to_send_count_ = 0;
229 int transport2_ready_to_send_count_ = 0;
230
231 void OnChan1ReadyToSend() { ++transport1_ready_to_send_count_; }
232 void OnChan2ReadyToSend() { ++transport2_ready_to_send_count_; }
233 };
234
235 // Test that data can be sent end-to-end when an SCTP transport starts with one
236 // transport channel (which is unwritable), and then switches to another
237 // channel. A common scenario due to how BUNDLE works.
238 TEST_F(SctpTransportTest, SwitchTransportChannel) {
239 FakeTransportChannel black_hole("black hole", 0);
240 FakeTransportChannel fake_dtls1("fake dtls 1", 0);
241 FakeTransportChannel fake_dtls2("fake dtls 2", 0);
242 SctpFakeDataReceiver recv1;
243 SctpFakeDataReceiver recv2;
244
245 // Construct transport1 with the "black hole" channel.
246 std::unique_ptr<SctpTransport> transport1(
247 CreateTransport(&black_hole, &recv1));
248 std::unique_ptr<SctpTransport> transport2(
249 CreateTransport(&fake_dtls2, &recv2));
250
251 // Add a stream.
252 transport1->OpenStream(1);
253 transport2->OpenStream(1);
254
255 // Tell them both to start (though transport1_ is connected to black_hole).
256 transport1->Start(kTransport1Port, kTransport2Port);
257 transport2->Start(kTransport2Port, kTransport1Port);
258
259 // Switch transport1_ to the normal fake_dtls1_ channel.
260 transport1->SetTransportChannel(&fake_dtls1);
261
262 // Connect the two fake DTLS channels.
263 bool asymmetric = false;
264 fake_dtls1.SetDestination(&fake_dtls2, asymmetric);
265
266 // Make sure we end up able to send data.
267 SendDataResult result;
268 ASSERT_TRUE(SendData(transport1.get(), 1, "foo", &result));
269 ASSERT_TRUE(SendData(transport2.get(), 1, "bar", &result));
270 EXPECT_TRUE_WAIT(ReceivedData(&recv2, 1, "foo"), kDefaultTimeout);
271 EXPECT_TRUE_WAIT(ReceivedData(&recv1, 1, "bar"), kDefaultTimeout);
272 }
273
274 // Calling Start twice shouldn't do anything bad, if with the same parameters.
275 TEST_F(SctpTransportTest, DuplicateStartCallsIgnored) {
276 SetupConnectedTransportsWithTwoStreams();
277 EXPECT_TRUE(transport1()->Start(kTransport1Port, kTransport2Port));
278
279 // Make sure we can still send/recv data.
280 SendDataResult result;
281 ASSERT_TRUE(SendData(transport1(), 1, "foo", &result));
282 ASSERT_TRUE(SendData(transport2(), 1, "bar", &result));
283 EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "foo"), kDefaultTimeout);
284 EXPECT_TRUE_WAIT(ReceivedData(receiver1(), 1, "bar"), kDefaultTimeout);
285 }
286
287 // Calling Start a second time with a different port should fail.
288 TEST_F(SctpTransportTest, CallingStartWithDifferentPortFails) {
289 SetupConnectedTransportsWithTwoStreams();
290 EXPECT_FALSE(transport1()->Start(kTransport1Port, 1234));
291 EXPECT_FALSE(transport1()->Start(1234, kTransport2Port));
292 }
293
294 // A value of -1 for the local/remote port should be treated as the default
295 // (5000).
296 TEST_F(SctpTransportTest, NegativeOnePortTreatedAsDefault) {
297 FakeTransportChannel fake_dtls1("fake dtls 1", 0);
298 FakeTransportChannel fake_dtls2("fake dtls 2", 0);
299 SctpFakeDataReceiver recv1;
300 SctpFakeDataReceiver recv2;
301 std::unique_ptr<SctpTransport> transport1(
302 CreateTransport(&fake_dtls1, &recv1));
303 std::unique_ptr<SctpTransport> transport2(
304 CreateTransport(&fake_dtls2, &recv2));
305
306 // Add a stream.
307 transport1->OpenStream(1);
308 transport2->OpenStream(1);
309
310 // Tell them both to start, giving one transport the default port and the
311 // other transport -1.
312 transport1->Start(kSctpDefaultPort, kSctpDefaultPort);
313 transport2->Start(-1, -1);
314
315 // Connect the two fake DTLS channels.
316 bool asymmetric = false;
317 fake_dtls1.SetDestination(&fake_dtls2, asymmetric);
318
319 // Make sure we end up able to send data.
320 SendDataResult result;
321 ASSERT_TRUE(SendData(transport1.get(), 1, "foo", &result));
322 ASSERT_TRUE(SendData(transport2.get(), 1, "bar", &result));
323 EXPECT_TRUE_WAIT(ReceivedData(&recv2, 1, "foo"), kDefaultTimeout);
324 EXPECT_TRUE_WAIT(ReceivedData(&recv1, 1, "bar"), kDefaultTimeout);
325 }
326
327 TEST_F(SctpTransportTest, OpenStreamWithAlreadyOpenedStreamFails) {
328 FakeTransportChannel fake_dtls("fake dtls", 0);
329 SctpFakeDataReceiver recv;
330 std::unique_ptr<SctpTransport> transport(CreateTransport(&fake_dtls, &recv));
331 EXPECT_TRUE(transport->OpenStream(1));
332 EXPECT_FALSE(transport->OpenStream(1));
333 }
334
335 TEST_F(SctpTransportTest, ResetStreamWithAlreadyResetStreamFails) {
336 FakeTransportChannel fake_dtls("fake dtls", 0);
337 SctpFakeDataReceiver recv;
338 std::unique_ptr<SctpTransport> transport(CreateTransport(&fake_dtls, &recv));
339 EXPECT_TRUE(transport->OpenStream(1));
340 EXPECT_TRUE(transport->ResetStream(1));
341 EXPECT_FALSE(transport->ResetStream(1));
342 }
343
344 // Test that SignalReadyToSendData is fired after Start has been called and the
345 // DTLS channel is writable.
346 TEST_F(SctpTransportTest, SignalReadyToSendDataAfterDtlsWritable) {
347 FakeTransportChannel fake_dtls("fake dtls", 0);
348 SctpFakeDataReceiver recv;
349 std::unique_ptr<SctpTransport> transport(CreateTransport(&fake_dtls, &recv));
350
351 SignalReadyToSendObserver signal_observer;
352 transport->SignalReadyToSendData.connect(
353 &signal_observer, &SignalReadyToSendObserver::OnSignaled);
354
355 transport->Start(kSctpDefaultPort, kSctpDefaultPort);
356 fake_dtls.SetWritable(true);
357 EXPECT_TRUE_WAIT(signal_observer.IsSignaled(), kDefaultTimeout);
358 }
359
360 // Test that after an SCTP socket's buffer is filled, SignalReadyToSendData
361 // is fired after it begins to be drained.
362 TEST_F(SctpTransportTest, SignalReadyToSendDataAfterBlocked) {
363 SetupConnectedTransportsWithTwoStreams();
364 // Wait for initial SCTP association to be formed.
365 EXPECT_EQ_WAIT(1, transport1_ready_to_send_count(), kDefaultTimeout);
366 // Make the fake transport unwritable so that messages pile up for the SCTP
367 // socket.
368 fake_dtls1()->SetWritable(false);
369 // Send messages until we get EWOULDBLOCK.
370 static const int kMaxMessages = 1024;
371 SendDataParams params;
372 params.sid = 1;
373 rtc::CopyOnWriteBuffer buf(1024);
374 memset(buf.data<uint8_t>(), 0, 1024);
375 SendDataResult result;
376 int message_count;
377 for (message_count = 0; message_count < kMaxMessages; ++message_count) {
378 if (!transport1()->SendData(params, buf, &result) && result == SDR_BLOCK) {
379 break;
380 }
381 }
382 ASSERT_NE(kMaxMessages, message_count)
383 << "Sent max number of messages without getting SDR_BLOCK?";
384 // Make sure the ready-to-send count hasn't changed.
385 EXPECT_EQ(1, transport1_ready_to_send_count());
386 // Make the transport writable again and expect a "SignalReadyToSendData" at
387 // some point.
388 fake_dtls1()->SetWritable(true);
389 EXPECT_EQ_WAIT(2, transport1_ready_to_send_count(), kDefaultTimeout);
390 }
391
392 TEST_F(SctpTransportTest, SendData) {
393 SetupConnectedTransportsWithTwoStreams();
394
395 SendDataResult result;
396 LOG(LS_VERBOSE)
397 << "transport1 sending: 'hello?' -----------------------------";
398 ASSERT_TRUE(SendData(transport1(), 1, "hello?", &result));
399 EXPECT_EQ(SDR_SUCCESS, result);
400 EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hello?"), kDefaultTimeout);
401 LOG(LS_VERBOSE) << "recv2.received=" << receiver2()->received()
402 << ", recv2.last_params.sid="
403 << receiver2()->last_params().sid
404 << ", recv2.last_params.timestamp="
405 << receiver2()->last_params().timestamp
406 << ", recv2.last_params.seq_num="
407 << receiver2()->last_params().seq_num
408 << ", recv2.last_data=" << receiver2()->last_data();
409
410 LOG(LS_VERBOSE)
411 << "transport2 sending: 'hi transport1' -----------------------------";
412 ASSERT_TRUE(SendData(transport2(), 2, "hi transport1", &result));
413 EXPECT_EQ(SDR_SUCCESS, result);
414 EXPECT_TRUE_WAIT(ReceivedData(receiver1(), 2, "hi transport1"),
415 kDefaultTimeout);
416 LOG(LS_VERBOSE) << "recv1.received=" << receiver1()->received()
417 << ", recv1.last_params.sid="
418 << receiver1()->last_params().sid
419 << ", recv1.last_params.timestamp="
420 << receiver1()->last_params().timestamp
421 << ", recv1.last_params.seq_num="
422 << receiver1()->last_params().seq_num
423 << ", recv1.last_data=" << receiver1()->last_data();
424 }
425
426 // Sends a lot of large messages at once and verifies SDR_BLOCK is returned.
427 TEST_F(SctpTransportTest, SendDataBlocked) {
428 SetupConnectedTransportsWithTwoStreams();
429
430 SendDataResult result;
431 SendDataParams params;
432 params.sid = 1;
433
434 std::vector<char> buffer(1024 * 64, 0);
435
436 for (size_t i = 0; i < 100; ++i) {
437 transport1()->SendData(
438 params, rtc::CopyOnWriteBuffer(&buffer[0], buffer.size()), &result);
439 if (result == SDR_BLOCK)
440 break;
441 }
442
443 EXPECT_EQ(SDR_BLOCK, result);
444 }
445
446 // Trying to send data for a nonexistent stream should fail.
447 TEST_F(SctpTransportTest, SendDataWithNonexistentStreamFails) {
448 SetupConnectedTransportsWithTwoStreams();
449 SendDataResult result;
450 EXPECT_FALSE(SendData(transport2(), 123, "some data", &result));
451 EXPECT_EQ(SDR_ERROR, result);
452 }
453
454 TEST_F(SctpTransportTest, ClosesRemoteStream) {
455 SetupConnectedTransportsWithTwoStreams();
456 SignalTransportClosedObserver transport1_sig_receiver,
457 transport2_sig_receiver;
458 transport1_sig_receiver.BindSelf(transport1());
459 transport2_sig_receiver.BindSelf(transport2());
460
461 SendDataResult result;
462 ASSERT_TRUE(SendData(transport1(), 1, "hello?", &result));
463 EXPECT_EQ(SDR_SUCCESS, result);
464 EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hello?"), kDefaultTimeout);
465 ASSERT_TRUE(SendData(transport2(), 2, "hi transport1", &result));
466 EXPECT_EQ(SDR_SUCCESS, result);
467 EXPECT_TRUE_WAIT(ReceivedData(receiver1(), 2, "hi transport1"),
468 kDefaultTimeout);
469
470 // Close transport 1. Transport 2 should notify us.
471 transport1()->ResetStream(1);
472 EXPECT_TRUE_WAIT(transport2_sig_receiver.WasStreamClosed(1), kDefaultTimeout);
473 }
474
475 TEST_F(SctpTransportTest, ClosesTwoRemoteStreams) {
476 SetupConnectedTransportsWithTwoStreams();
477 AddStream(3);
478 SignalTransportClosedObserver transport1_sig_receiver,
479 transport2_sig_receiver;
480 transport1_sig_receiver.BindSelf(transport1());
481 transport2_sig_receiver.BindSelf(transport2());
482
483 SendDataResult result;
484 ASSERT_TRUE(SendData(transport1(), 1, "hello?", &result));
485 EXPECT_EQ(SDR_SUCCESS, result);
486 EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hello?"), kDefaultTimeout);
487 ASSERT_TRUE(SendData(transport2(), 2, "hi transport1", &result));
488 EXPECT_EQ(SDR_SUCCESS, result);
489 EXPECT_TRUE_WAIT(ReceivedData(receiver1(), 2, "hi transport1"),
490 kDefaultTimeout);
491
492 // Close two streams on one side.
493 transport2()->ResetStream(2);
494 transport2()->ResetStream(3);
495 EXPECT_TRUE_WAIT(transport1_sig_receiver.WasStreamClosed(2), kDefaultTimeout);
496 EXPECT_TRUE_WAIT(transport1_sig_receiver.WasStreamClosed(3), kDefaultTimeout);
497 }
498
499 TEST_F(SctpTransportTest, ClosesStreamsOnBothSides) {
500 SetupConnectedTransportsWithTwoStreams();
501 AddStream(3);
502 AddStream(4);
503 SignalTransportClosedObserver transport1_sig_receiver,
504 transport2_sig_receiver;
505 transport1_sig_receiver.BindSelf(transport1());
506 transport2_sig_receiver.BindSelf(transport2());
507
508 SendDataResult result;
509 ASSERT_TRUE(SendData(transport1(), 1, "hello?", &result));
510 EXPECT_EQ(SDR_SUCCESS, result);
511 EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hello?"), kDefaultTimeout);
512 ASSERT_TRUE(SendData(transport2(), 2, "hi transport1", &result));
513 EXPECT_EQ(SDR_SUCCESS, result);
514 EXPECT_TRUE_WAIT(ReceivedData(receiver1(), 2, "hi transport1"),
515 kDefaultTimeout);
516
517 // Close one stream on transport1(), while closing three streams on
518 // transport2(). They will conflict (only one side can close anything at a
519 // time, apparently). Test the resolution of the conflict.
520 transport1()->ResetStream(1);
521
522 transport2()->ResetStream(2);
523 transport2()->ResetStream(3);
524 transport2()->ResetStream(4);
525 EXPECT_TRUE_WAIT(transport2_sig_receiver.WasStreamClosed(1), kDefaultTimeout);
526 EXPECT_TRUE_WAIT(transport1_sig_receiver.WasStreamClosed(2), kDefaultTimeout);
527 EXPECT_TRUE_WAIT(transport1_sig_receiver.WasStreamClosed(3), kDefaultTimeout);
528 EXPECT_TRUE_WAIT(transport1_sig_receiver.WasStreamClosed(4), kDefaultTimeout);
529 }
530
531 TEST_F(SctpTransportTest, RefusesHighNumberedTransports) {
532 SetupConnectedTransportsWithTwoStreams();
533 EXPECT_TRUE(AddStream(kMaxSctpSid));
534 EXPECT_FALSE(AddStream(kMaxSctpSid + 1));
535 }
536
537 // Flaky, see webrtc:4453.
538 TEST_F(SctpTransportTest, DISABLED_ReusesAStream) {
539 // Shut down transport 1, then open it up again for reuse.
540 SetupConnectedTransportsWithTwoStreams();
541 SendDataResult result;
542 SignalTransportClosedObserver transport2_sig_receiver;
543 transport2_sig_receiver.BindSelf(transport2());
544
545 ASSERT_TRUE(SendData(transport1(), 1, "hello?", &result));
546 EXPECT_EQ(SDR_SUCCESS, result);
547 EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hello?"), kDefaultTimeout);
548
549 transport1()->ResetStream(1);
550 EXPECT_TRUE_WAIT(transport2_sig_receiver.WasStreamClosed(1), kDefaultTimeout);
551 // Transport 1 is gone now.
552
553 // Create a new transport 1.
554 AddStream(1);
555 ASSERT_TRUE(SendData(transport1(), 1, "hi?", &result));
556 EXPECT_EQ(SDR_SUCCESS, result);
557 EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hi?"), kDefaultTimeout);
558 transport1()->ResetStream(1);
559 EXPECT_TRUE_WAIT(transport2_sig_receiver.StreamCloseCount(1) == 2,
560 kDefaultTimeout);
561 }
562
563 } // namespace cricket
OLDNEW
« no previous file with comments | « webrtc/media/sctp/sctptransport.cc ('k') | webrtc/media/sctp/sctptransportinternal.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698