1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker * Copyright 2013 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker *
4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker */
10*d9f75844SAndroid Build Coastguard Worker
11*d9f75844SAndroid Build Coastguard Worker #include <stdint.h>
12*d9f75844SAndroid Build Coastguard Worker #include <string.h>
13*d9f75844SAndroid Build Coastguard Worker
14*d9f75844SAndroid Build Coastguard Worker #include <memory>
15*d9f75844SAndroid Build Coastguard Worker #include <string>
16*d9f75844SAndroid Build Coastguard Worker #include <vector>
17*d9f75844SAndroid Build Coastguard Worker
18*d9f75844SAndroid Build Coastguard Worker #include "api/data_channel_interface.h"
19*d9f75844SAndroid Build Coastguard Worker #include "api/rtc_error.h"
20*d9f75844SAndroid Build Coastguard Worker #include "api/scoped_refptr.h"
21*d9f75844SAndroid Build Coastguard Worker #include "api/transport/data_channel_transport_interface.h"
22*d9f75844SAndroid Build Coastguard Worker #include "media/base/media_channel.h"
23*d9f75844SAndroid Build Coastguard Worker #include "media/sctp/sctp_transport_internal.h"
24*d9f75844SAndroid Build Coastguard Worker #include "pc/sctp_data_channel.h"
25*d9f75844SAndroid Build Coastguard Worker #include "pc/sctp_utils.h"
26*d9f75844SAndroid Build Coastguard Worker #include "pc/test/fake_data_channel_controller.h"
27*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/copy_on_write_buffer.h"
28*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/gunit.h"
29*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/ssl_stream_adapter.h"
30*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/third_party/sigslot/sigslot.h"
31*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread.h"
32*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h"
33*d9f75844SAndroid Build Coastguard Worker
34*d9f75844SAndroid Build Coastguard Worker using webrtc::DataChannelInterface;
35*d9f75844SAndroid Build Coastguard Worker using webrtc::SctpDataChannel;
36*d9f75844SAndroid Build Coastguard Worker using webrtc::SctpSidAllocator;
37*d9f75844SAndroid Build Coastguard Worker
38*d9f75844SAndroid Build Coastguard Worker static constexpr int kDefaultTimeout = 10000;
39*d9f75844SAndroid Build Coastguard Worker
40*d9f75844SAndroid Build Coastguard Worker class FakeDataChannelObserver : public webrtc::DataChannelObserver {
41*d9f75844SAndroid Build Coastguard Worker public:
FakeDataChannelObserver()42*d9f75844SAndroid Build Coastguard Worker FakeDataChannelObserver()
43*d9f75844SAndroid Build Coastguard Worker : messages_received_(0),
44*d9f75844SAndroid Build Coastguard Worker on_state_change_count_(0),
45*d9f75844SAndroid Build Coastguard Worker on_buffered_amount_change_count_(0) {}
46*d9f75844SAndroid Build Coastguard Worker
OnStateChange()47*d9f75844SAndroid Build Coastguard Worker void OnStateChange() { ++on_state_change_count_; }
48*d9f75844SAndroid Build Coastguard Worker
OnBufferedAmountChange(uint64_t previous_amount)49*d9f75844SAndroid Build Coastguard Worker void OnBufferedAmountChange(uint64_t previous_amount) {
50*d9f75844SAndroid Build Coastguard Worker ++on_buffered_amount_change_count_;
51*d9f75844SAndroid Build Coastguard Worker }
52*d9f75844SAndroid Build Coastguard Worker
OnMessage(const webrtc::DataBuffer & buffer)53*d9f75844SAndroid Build Coastguard Worker void OnMessage(const webrtc::DataBuffer& buffer) { ++messages_received_; }
54*d9f75844SAndroid Build Coastguard Worker
messages_received() const55*d9f75844SAndroid Build Coastguard Worker size_t messages_received() const { return messages_received_; }
56*d9f75844SAndroid Build Coastguard Worker
ResetOnStateChangeCount()57*d9f75844SAndroid Build Coastguard Worker void ResetOnStateChangeCount() { on_state_change_count_ = 0; }
58*d9f75844SAndroid Build Coastguard Worker
ResetOnBufferedAmountChangeCount()59*d9f75844SAndroid Build Coastguard Worker void ResetOnBufferedAmountChangeCount() {
60*d9f75844SAndroid Build Coastguard Worker on_buffered_amount_change_count_ = 0;
61*d9f75844SAndroid Build Coastguard Worker }
62*d9f75844SAndroid Build Coastguard Worker
on_state_change_count() const63*d9f75844SAndroid Build Coastguard Worker size_t on_state_change_count() const { return on_state_change_count_; }
64*d9f75844SAndroid Build Coastguard Worker
on_buffered_amount_change_count() const65*d9f75844SAndroid Build Coastguard Worker size_t on_buffered_amount_change_count() const {
66*d9f75844SAndroid Build Coastguard Worker return on_buffered_amount_change_count_;
67*d9f75844SAndroid Build Coastguard Worker }
68*d9f75844SAndroid Build Coastguard Worker
69*d9f75844SAndroid Build Coastguard Worker private:
70*d9f75844SAndroid Build Coastguard Worker size_t messages_received_;
71*d9f75844SAndroid Build Coastguard Worker size_t on_state_change_count_;
72*d9f75844SAndroid Build Coastguard Worker size_t on_buffered_amount_change_count_;
73*d9f75844SAndroid Build Coastguard Worker };
74*d9f75844SAndroid Build Coastguard Worker
75*d9f75844SAndroid Build Coastguard Worker // TODO(deadbeef): The fact that these tests use a fake controller makes them
76*d9f75844SAndroid Build Coastguard Worker // not too valuable. Should rewrite using the
77*d9f75844SAndroid Build Coastguard Worker // peerconnection_datachannel_unittest.cc infrastructure.
78*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/11547): Incorporate a dedicated network thread.
79*d9f75844SAndroid Build Coastguard Worker class SctpDataChannelTest : public ::testing::Test {
80*d9f75844SAndroid Build Coastguard Worker protected:
SctpDataChannelTest()81*d9f75844SAndroid Build Coastguard Worker SctpDataChannelTest()
82*d9f75844SAndroid Build Coastguard Worker : controller_(new FakeDataChannelController()),
83*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_(SctpDataChannel::Create(controller_.get(),
84*d9f75844SAndroid Build Coastguard Worker "test",
85*d9f75844SAndroid Build Coastguard Worker init_,
86*d9f75844SAndroid Build Coastguard Worker rtc::Thread::Current(),
87*d9f75844SAndroid Build Coastguard Worker rtc::Thread::Current())) {}
88*d9f75844SAndroid Build Coastguard Worker
SetChannelReady()89*d9f75844SAndroid Build Coastguard Worker void SetChannelReady() {
90*d9f75844SAndroid Build Coastguard Worker controller_->set_transport_available(true);
91*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->OnTransportChannelCreated();
92*d9f75844SAndroid Build Coastguard Worker if (webrtc_data_channel_->id() < 0) {
93*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->SetSctpSid(0);
94*d9f75844SAndroid Build Coastguard Worker }
95*d9f75844SAndroid Build Coastguard Worker controller_->set_ready_to_send(true);
96*d9f75844SAndroid Build Coastguard Worker }
97*d9f75844SAndroid Build Coastguard Worker
AddObserver()98*d9f75844SAndroid Build Coastguard Worker void AddObserver() {
99*d9f75844SAndroid Build Coastguard Worker observer_.reset(new FakeDataChannelObserver());
100*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->RegisterObserver(observer_.get());
101*d9f75844SAndroid Build Coastguard Worker }
102*d9f75844SAndroid Build Coastguard Worker
103*d9f75844SAndroid Build Coastguard Worker rtc::AutoThread main_thread_;
104*d9f75844SAndroid Build Coastguard Worker webrtc::InternalDataChannelInit init_;
105*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<FakeDataChannelController> controller_;
106*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<FakeDataChannelObserver> observer_;
107*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<SctpDataChannel> webrtc_data_channel_;
108*d9f75844SAndroid Build Coastguard Worker };
109*d9f75844SAndroid Build Coastguard Worker
110*d9f75844SAndroid Build Coastguard Worker class StateSignalsListener : public sigslot::has_slots<> {
111*d9f75844SAndroid Build Coastguard Worker public:
opened_count() const112*d9f75844SAndroid Build Coastguard Worker int opened_count() const { return opened_count_; }
closed_count() const113*d9f75844SAndroid Build Coastguard Worker int closed_count() const { return closed_count_; }
114*d9f75844SAndroid Build Coastguard Worker
OnSignalOpened(DataChannelInterface * data_channel)115*d9f75844SAndroid Build Coastguard Worker void OnSignalOpened(DataChannelInterface* data_channel) { ++opened_count_; }
116*d9f75844SAndroid Build Coastguard Worker
OnSignalClosed(DataChannelInterface * data_channel)117*d9f75844SAndroid Build Coastguard Worker void OnSignalClosed(DataChannelInterface* data_channel) { ++closed_count_; }
118*d9f75844SAndroid Build Coastguard Worker
119*d9f75844SAndroid Build Coastguard Worker private:
120*d9f75844SAndroid Build Coastguard Worker int opened_count_ = 0;
121*d9f75844SAndroid Build Coastguard Worker int closed_count_ = 0;
122*d9f75844SAndroid Build Coastguard Worker };
123*d9f75844SAndroid Build Coastguard Worker
124*d9f75844SAndroid Build Coastguard Worker // Verifies that the data channel is connected to the transport after creation.
TEST_F(SctpDataChannelTest,ConnectedToTransportOnCreated)125*d9f75844SAndroid Build Coastguard Worker TEST_F(SctpDataChannelTest, ConnectedToTransportOnCreated) {
126*d9f75844SAndroid Build Coastguard Worker controller_->set_transport_available(true);
127*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<SctpDataChannel> dc =
128*d9f75844SAndroid Build Coastguard Worker SctpDataChannel::Create(controller_.get(), "test1", init_,
129*d9f75844SAndroid Build Coastguard Worker rtc::Thread::Current(), rtc::Thread::Current());
130*d9f75844SAndroid Build Coastguard Worker
131*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(controller_->IsConnected(dc.get()));
132*d9f75844SAndroid Build Coastguard Worker // The sid is not set yet, so it should not have added the streams.
133*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(controller_->IsSendStreamAdded(dc->id()));
134*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(controller_->IsRecvStreamAdded(dc->id()));
135*d9f75844SAndroid Build Coastguard Worker
136*d9f75844SAndroid Build Coastguard Worker dc->SetSctpSid(0);
137*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(controller_->IsSendStreamAdded(dc->id()));
138*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(controller_->IsRecvStreamAdded(dc->id()));
139*d9f75844SAndroid Build Coastguard Worker }
140*d9f75844SAndroid Build Coastguard Worker
141*d9f75844SAndroid Build Coastguard Worker // Verifies that the data channel is connected to the transport if the transport
142*d9f75844SAndroid Build Coastguard Worker // is not available initially and becomes available later.
TEST_F(SctpDataChannelTest,ConnectedAfterTransportBecomesAvailable)143*d9f75844SAndroid Build Coastguard Worker TEST_F(SctpDataChannelTest, ConnectedAfterTransportBecomesAvailable) {
144*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(controller_->IsConnected(webrtc_data_channel_.get()));
145*d9f75844SAndroid Build Coastguard Worker
146*d9f75844SAndroid Build Coastguard Worker controller_->set_transport_available(true);
147*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->OnTransportChannelCreated();
148*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(controller_->IsConnected(webrtc_data_channel_.get()));
149*d9f75844SAndroid Build Coastguard Worker }
150*d9f75844SAndroid Build Coastguard Worker
151*d9f75844SAndroid Build Coastguard Worker // Tests the state of the data channel.
TEST_F(SctpDataChannelTest,StateTransition)152*d9f75844SAndroid Build Coastguard Worker TEST_F(SctpDataChannelTest, StateTransition) {
153*d9f75844SAndroid Build Coastguard Worker StateSignalsListener state_signals_listener;
154*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->SignalOpened.connect(
155*d9f75844SAndroid Build Coastguard Worker &state_signals_listener, &StateSignalsListener::OnSignalOpened);
156*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->SignalClosed.connect(
157*d9f75844SAndroid Build Coastguard Worker &state_signals_listener, &StateSignalsListener::OnSignalClosed);
158*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(webrtc::DataChannelInterface::kConnecting,
159*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->state());
160*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(state_signals_listener.opened_count(), 0);
161*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(state_signals_listener.closed_count(), 0);
162*d9f75844SAndroid Build Coastguard Worker SetChannelReady();
163*d9f75844SAndroid Build Coastguard Worker
164*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(webrtc::DataChannelInterface::kOpen, webrtc_data_channel_->state());
165*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(state_signals_listener.opened_count(), 1);
166*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(state_signals_listener.closed_count(), 0);
167*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->Close();
168*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(webrtc::DataChannelInterface::kClosed,
169*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->state());
170*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(webrtc_data_channel_->error().ok());
171*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(state_signals_listener.opened_count(), 1);
172*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(state_signals_listener.closed_count(), 1);
173*d9f75844SAndroid Build Coastguard Worker // Verifies that it's disconnected from the transport.
174*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(controller_->IsConnected(webrtc_data_channel_.get()));
175*d9f75844SAndroid Build Coastguard Worker }
176*d9f75844SAndroid Build Coastguard Worker
177*d9f75844SAndroid Build Coastguard Worker // Tests that DataChannel::buffered_amount() is correct after the channel is
178*d9f75844SAndroid Build Coastguard Worker // blocked.
TEST_F(SctpDataChannelTest,BufferedAmountWhenBlocked)179*d9f75844SAndroid Build Coastguard Worker TEST_F(SctpDataChannelTest, BufferedAmountWhenBlocked) {
180*d9f75844SAndroid Build Coastguard Worker AddObserver();
181*d9f75844SAndroid Build Coastguard Worker SetChannelReady();
182*d9f75844SAndroid Build Coastguard Worker webrtc::DataBuffer buffer("abcd");
183*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(webrtc_data_channel_->Send(buffer));
184*d9f75844SAndroid Build Coastguard Worker size_t successful_send_count = 1;
185*d9f75844SAndroid Build Coastguard Worker
186*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0U, webrtc_data_channel_->buffered_amount());
187*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(successful_send_count,
188*d9f75844SAndroid Build Coastguard Worker observer_->on_buffered_amount_change_count());
189*d9f75844SAndroid Build Coastguard Worker
190*d9f75844SAndroid Build Coastguard Worker controller_->set_send_blocked(true);
191*d9f75844SAndroid Build Coastguard Worker
192*d9f75844SAndroid Build Coastguard Worker const int number_of_packets = 3;
193*d9f75844SAndroid Build Coastguard Worker for (int i = 0; i < number_of_packets; ++i) {
194*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(webrtc_data_channel_->Send(buffer));
195*d9f75844SAndroid Build Coastguard Worker }
196*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(buffer.data.size() * number_of_packets,
197*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->buffered_amount());
198*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(successful_send_count,
199*d9f75844SAndroid Build Coastguard Worker observer_->on_buffered_amount_change_count());
200*d9f75844SAndroid Build Coastguard Worker
201*d9f75844SAndroid Build Coastguard Worker controller_->set_send_blocked(false);
202*d9f75844SAndroid Build Coastguard Worker successful_send_count += number_of_packets;
203*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0U, webrtc_data_channel_->buffered_amount());
204*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(successful_send_count,
205*d9f75844SAndroid Build Coastguard Worker observer_->on_buffered_amount_change_count());
206*d9f75844SAndroid Build Coastguard Worker }
207*d9f75844SAndroid Build Coastguard Worker
208*d9f75844SAndroid Build Coastguard Worker // Tests that the queued data are sent when the channel transitions from blocked
209*d9f75844SAndroid Build Coastguard Worker // to unblocked.
TEST_F(SctpDataChannelTest,QueuedDataSentWhenUnblocked)210*d9f75844SAndroid Build Coastguard Worker TEST_F(SctpDataChannelTest, QueuedDataSentWhenUnblocked) {
211*d9f75844SAndroid Build Coastguard Worker AddObserver();
212*d9f75844SAndroid Build Coastguard Worker SetChannelReady();
213*d9f75844SAndroid Build Coastguard Worker webrtc::DataBuffer buffer("abcd");
214*d9f75844SAndroid Build Coastguard Worker controller_->set_send_blocked(true);
215*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(webrtc_data_channel_->Send(buffer));
216*d9f75844SAndroid Build Coastguard Worker
217*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0U, observer_->on_buffered_amount_change_count());
218*d9f75844SAndroid Build Coastguard Worker
219*d9f75844SAndroid Build Coastguard Worker controller_->set_send_blocked(false);
220*d9f75844SAndroid Build Coastguard Worker SetChannelReady();
221*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0U, webrtc_data_channel_->buffered_amount());
222*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1U, observer_->on_buffered_amount_change_count());
223*d9f75844SAndroid Build Coastguard Worker }
224*d9f75844SAndroid Build Coastguard Worker
225*d9f75844SAndroid Build Coastguard Worker // Tests that no crash when the channel is blocked right away while trying to
226*d9f75844SAndroid Build Coastguard Worker // send queued data.
TEST_F(SctpDataChannelTest,BlockedWhenSendQueuedDataNoCrash)227*d9f75844SAndroid Build Coastguard Worker TEST_F(SctpDataChannelTest, BlockedWhenSendQueuedDataNoCrash) {
228*d9f75844SAndroid Build Coastguard Worker AddObserver();
229*d9f75844SAndroid Build Coastguard Worker SetChannelReady();
230*d9f75844SAndroid Build Coastguard Worker webrtc::DataBuffer buffer("abcd");
231*d9f75844SAndroid Build Coastguard Worker controller_->set_send_blocked(true);
232*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(webrtc_data_channel_->Send(buffer));
233*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0U, observer_->on_buffered_amount_change_count());
234*d9f75844SAndroid Build Coastguard Worker
235*d9f75844SAndroid Build Coastguard Worker // Set channel ready while it is still blocked.
236*d9f75844SAndroid Build Coastguard Worker SetChannelReady();
237*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(buffer.size(), webrtc_data_channel_->buffered_amount());
238*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0U, observer_->on_buffered_amount_change_count());
239*d9f75844SAndroid Build Coastguard Worker
240*d9f75844SAndroid Build Coastguard Worker // Unblock the channel to send queued data again, there should be no crash.
241*d9f75844SAndroid Build Coastguard Worker controller_->set_send_blocked(false);
242*d9f75844SAndroid Build Coastguard Worker SetChannelReady();
243*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0U, webrtc_data_channel_->buffered_amount());
244*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1U, observer_->on_buffered_amount_change_count());
245*d9f75844SAndroid Build Coastguard Worker }
246*d9f75844SAndroid Build Coastguard Worker
247*d9f75844SAndroid Build Coastguard Worker // Tests that DataChannel::messages_sent() and DataChannel::bytes_sent() are
248*d9f75844SAndroid Build Coastguard Worker // correct, sending data both while unblocked and while blocked.
TEST_F(SctpDataChannelTest,VerifyMessagesAndBytesSent)249*d9f75844SAndroid Build Coastguard Worker TEST_F(SctpDataChannelTest, VerifyMessagesAndBytesSent) {
250*d9f75844SAndroid Build Coastguard Worker AddObserver();
251*d9f75844SAndroid Build Coastguard Worker SetChannelReady();
252*d9f75844SAndroid Build Coastguard Worker std::vector<webrtc::DataBuffer> buffers({
253*d9f75844SAndroid Build Coastguard Worker webrtc::DataBuffer("message 1"),
254*d9f75844SAndroid Build Coastguard Worker webrtc::DataBuffer("msg 2"),
255*d9f75844SAndroid Build Coastguard Worker webrtc::DataBuffer("message three"),
256*d9f75844SAndroid Build Coastguard Worker webrtc::DataBuffer("quadra message"),
257*d9f75844SAndroid Build Coastguard Worker webrtc::DataBuffer("fifthmsg"),
258*d9f75844SAndroid Build Coastguard Worker webrtc::DataBuffer("message of the beast"),
259*d9f75844SAndroid Build Coastguard Worker });
260*d9f75844SAndroid Build Coastguard Worker
261*d9f75844SAndroid Build Coastguard Worker // Default values.
262*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0U, webrtc_data_channel_->messages_sent());
263*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0U, webrtc_data_channel_->bytes_sent());
264*d9f75844SAndroid Build Coastguard Worker
265*d9f75844SAndroid Build Coastguard Worker // Send three buffers while not blocked.
266*d9f75844SAndroid Build Coastguard Worker controller_->set_send_blocked(false);
267*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(webrtc_data_channel_->Send(buffers[0]));
268*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(webrtc_data_channel_->Send(buffers[1]));
269*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(webrtc_data_channel_->Send(buffers[2]));
270*d9f75844SAndroid Build Coastguard Worker size_t bytes_sent = buffers[0].size() + buffers[1].size() + buffers[2].size();
271*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ_WAIT(0U, webrtc_data_channel_->buffered_amount(), kDefaultTimeout);
272*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(3U, webrtc_data_channel_->messages_sent());
273*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(bytes_sent, webrtc_data_channel_->bytes_sent());
274*d9f75844SAndroid Build Coastguard Worker
275*d9f75844SAndroid Build Coastguard Worker // Send three buffers while blocked, queuing the buffers.
276*d9f75844SAndroid Build Coastguard Worker controller_->set_send_blocked(true);
277*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(webrtc_data_channel_->Send(buffers[3]));
278*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(webrtc_data_channel_->Send(buffers[4]));
279*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(webrtc_data_channel_->Send(buffers[5]));
280*d9f75844SAndroid Build Coastguard Worker size_t bytes_queued =
281*d9f75844SAndroid Build Coastguard Worker buffers[3].size() + buffers[4].size() + buffers[5].size();
282*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(bytes_queued, webrtc_data_channel_->buffered_amount());
283*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(3U, webrtc_data_channel_->messages_sent());
284*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(bytes_sent, webrtc_data_channel_->bytes_sent());
285*d9f75844SAndroid Build Coastguard Worker
286*d9f75844SAndroid Build Coastguard Worker // Unblock and make sure everything was sent.
287*d9f75844SAndroid Build Coastguard Worker controller_->set_send_blocked(false);
288*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ_WAIT(0U, webrtc_data_channel_->buffered_amount(), kDefaultTimeout);
289*d9f75844SAndroid Build Coastguard Worker bytes_sent += bytes_queued;
290*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(6U, webrtc_data_channel_->messages_sent());
291*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(bytes_sent, webrtc_data_channel_->bytes_sent());
292*d9f75844SAndroid Build Coastguard Worker }
293*d9f75844SAndroid Build Coastguard Worker
294*d9f75844SAndroid Build Coastguard Worker // Tests that the queued control message is sent when channel is ready.
TEST_F(SctpDataChannelTest,OpenMessageSent)295*d9f75844SAndroid Build Coastguard Worker TEST_F(SctpDataChannelTest, OpenMessageSent) {
296*d9f75844SAndroid Build Coastguard Worker // Initially the id is unassigned.
297*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(-1, webrtc_data_channel_->id());
298*d9f75844SAndroid Build Coastguard Worker
299*d9f75844SAndroid Build Coastguard Worker SetChannelReady();
300*d9f75844SAndroid Build Coastguard Worker EXPECT_GE(webrtc_data_channel_->id(), 0);
301*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(webrtc::DataMessageType::kControl,
302*d9f75844SAndroid Build Coastguard Worker controller_->last_send_data_params().type);
303*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(controller_->last_sid(), webrtc_data_channel_->id());
304*d9f75844SAndroid Build Coastguard Worker }
305*d9f75844SAndroid Build Coastguard Worker
TEST_F(SctpDataChannelTest,QueuedOpenMessageSent)306*d9f75844SAndroid Build Coastguard Worker TEST_F(SctpDataChannelTest, QueuedOpenMessageSent) {
307*d9f75844SAndroid Build Coastguard Worker controller_->set_send_blocked(true);
308*d9f75844SAndroid Build Coastguard Worker SetChannelReady();
309*d9f75844SAndroid Build Coastguard Worker controller_->set_send_blocked(false);
310*d9f75844SAndroid Build Coastguard Worker
311*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(webrtc::DataMessageType::kControl,
312*d9f75844SAndroid Build Coastguard Worker controller_->last_send_data_params().type);
313*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(controller_->last_sid(), webrtc_data_channel_->id());
314*d9f75844SAndroid Build Coastguard Worker }
315*d9f75844SAndroid Build Coastguard Worker
316*d9f75844SAndroid Build Coastguard Worker // Tests that the DataChannel created after transport gets ready can enter OPEN
317*d9f75844SAndroid Build Coastguard Worker // state.
TEST_F(SctpDataChannelTest,LateCreatedChannelTransitionToOpen)318*d9f75844SAndroid Build Coastguard Worker TEST_F(SctpDataChannelTest, LateCreatedChannelTransitionToOpen) {
319*d9f75844SAndroid Build Coastguard Worker SetChannelReady();
320*d9f75844SAndroid Build Coastguard Worker webrtc::InternalDataChannelInit init;
321*d9f75844SAndroid Build Coastguard Worker init.id = 1;
322*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<SctpDataChannel> dc =
323*d9f75844SAndroid Build Coastguard Worker SctpDataChannel::Create(controller_.get(), "test1", init,
324*d9f75844SAndroid Build Coastguard Worker rtc::Thread::Current(), rtc::Thread::Current());
325*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(webrtc::DataChannelInterface::kConnecting, dc->state());
326*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE_WAIT(webrtc::DataChannelInterface::kOpen == dc->state(), 1000);
327*d9f75844SAndroid Build Coastguard Worker }
328*d9f75844SAndroid Build Coastguard Worker
329*d9f75844SAndroid Build Coastguard Worker // Tests that an unordered DataChannel sends data as ordered until the OPEN_ACK
330*d9f75844SAndroid Build Coastguard Worker // message is received.
TEST_F(SctpDataChannelTest,SendUnorderedAfterReceivesOpenAck)331*d9f75844SAndroid Build Coastguard Worker TEST_F(SctpDataChannelTest, SendUnorderedAfterReceivesOpenAck) {
332*d9f75844SAndroid Build Coastguard Worker SetChannelReady();
333*d9f75844SAndroid Build Coastguard Worker webrtc::InternalDataChannelInit init;
334*d9f75844SAndroid Build Coastguard Worker init.id = 1;
335*d9f75844SAndroid Build Coastguard Worker init.ordered = false;
336*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<SctpDataChannel> dc =
337*d9f75844SAndroid Build Coastguard Worker SctpDataChannel::Create(controller_.get(), "test1", init,
338*d9f75844SAndroid Build Coastguard Worker rtc::Thread::Current(), rtc::Thread::Current());
339*d9f75844SAndroid Build Coastguard Worker
340*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kOpen, dc->state(), 1000);
341*d9f75844SAndroid Build Coastguard Worker
342*d9f75844SAndroid Build Coastguard Worker // Sends a message and verifies it's ordered.
343*d9f75844SAndroid Build Coastguard Worker webrtc::DataBuffer buffer("some data");
344*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(dc->Send(buffer));
345*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(controller_->last_send_data_params().ordered);
346*d9f75844SAndroid Build Coastguard Worker
347*d9f75844SAndroid Build Coastguard Worker // Emulates receiving an OPEN_ACK message.
348*d9f75844SAndroid Build Coastguard Worker cricket::ReceiveDataParams params;
349*d9f75844SAndroid Build Coastguard Worker params.sid = init.id;
350*d9f75844SAndroid Build Coastguard Worker params.type = webrtc::DataMessageType::kControl;
351*d9f75844SAndroid Build Coastguard Worker rtc::CopyOnWriteBuffer payload;
352*d9f75844SAndroid Build Coastguard Worker webrtc::WriteDataChannelOpenAckMessage(&payload);
353*d9f75844SAndroid Build Coastguard Worker dc->OnDataReceived(params, payload);
354*d9f75844SAndroid Build Coastguard Worker
355*d9f75844SAndroid Build Coastguard Worker // Sends another message and verifies it's unordered.
356*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(dc->Send(buffer));
357*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(controller_->last_send_data_params().ordered);
358*d9f75844SAndroid Build Coastguard Worker }
359*d9f75844SAndroid Build Coastguard Worker
360*d9f75844SAndroid Build Coastguard Worker // Tests that an unordered DataChannel sends unordered data after any DATA
361*d9f75844SAndroid Build Coastguard Worker // message is received.
TEST_F(SctpDataChannelTest,SendUnorderedAfterReceiveData)362*d9f75844SAndroid Build Coastguard Worker TEST_F(SctpDataChannelTest, SendUnorderedAfterReceiveData) {
363*d9f75844SAndroid Build Coastguard Worker SetChannelReady();
364*d9f75844SAndroid Build Coastguard Worker webrtc::InternalDataChannelInit init;
365*d9f75844SAndroid Build Coastguard Worker init.id = 1;
366*d9f75844SAndroid Build Coastguard Worker init.ordered = false;
367*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<SctpDataChannel> dc =
368*d9f75844SAndroid Build Coastguard Worker SctpDataChannel::Create(controller_.get(), "test1", init,
369*d9f75844SAndroid Build Coastguard Worker rtc::Thread::Current(), rtc::Thread::Current());
370*d9f75844SAndroid Build Coastguard Worker
371*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kOpen, dc->state(), 1000);
372*d9f75844SAndroid Build Coastguard Worker
373*d9f75844SAndroid Build Coastguard Worker // Emulates receiving a DATA message.
374*d9f75844SAndroid Build Coastguard Worker cricket::ReceiveDataParams params;
375*d9f75844SAndroid Build Coastguard Worker params.sid = init.id;
376*d9f75844SAndroid Build Coastguard Worker params.type = webrtc::DataMessageType::kText;
377*d9f75844SAndroid Build Coastguard Worker webrtc::DataBuffer buffer("data");
378*d9f75844SAndroid Build Coastguard Worker dc->OnDataReceived(params, buffer.data);
379*d9f75844SAndroid Build Coastguard Worker
380*d9f75844SAndroid Build Coastguard Worker // Sends a message and verifies it's unordered.
381*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(dc->Send(buffer));
382*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(controller_->last_send_data_params().ordered);
383*d9f75844SAndroid Build Coastguard Worker }
384*d9f75844SAndroid Build Coastguard Worker
385*d9f75844SAndroid Build Coastguard Worker // Tests that the channel can't open until it's successfully sent the OPEN
386*d9f75844SAndroid Build Coastguard Worker // message.
TEST_F(SctpDataChannelTest,OpenWaitsForOpenMesssage)387*d9f75844SAndroid Build Coastguard Worker TEST_F(SctpDataChannelTest, OpenWaitsForOpenMesssage) {
388*d9f75844SAndroid Build Coastguard Worker webrtc::DataBuffer buffer("foo");
389*d9f75844SAndroid Build Coastguard Worker
390*d9f75844SAndroid Build Coastguard Worker controller_->set_send_blocked(true);
391*d9f75844SAndroid Build Coastguard Worker SetChannelReady();
392*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(webrtc::DataChannelInterface::kConnecting,
393*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->state());
394*d9f75844SAndroid Build Coastguard Worker controller_->set_send_blocked(false);
395*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kOpen,
396*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->state(), 1000);
397*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(webrtc::DataMessageType::kControl,
398*d9f75844SAndroid Build Coastguard Worker controller_->last_send_data_params().type);
399*d9f75844SAndroid Build Coastguard Worker }
400*d9f75844SAndroid Build Coastguard Worker
401*d9f75844SAndroid Build Coastguard Worker // Tests that close first makes sure all queued data gets sent.
TEST_F(SctpDataChannelTest,QueuedCloseFlushes)402*d9f75844SAndroid Build Coastguard Worker TEST_F(SctpDataChannelTest, QueuedCloseFlushes) {
403*d9f75844SAndroid Build Coastguard Worker webrtc::DataBuffer buffer("foo");
404*d9f75844SAndroid Build Coastguard Worker
405*d9f75844SAndroid Build Coastguard Worker controller_->set_send_blocked(true);
406*d9f75844SAndroid Build Coastguard Worker SetChannelReady();
407*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(webrtc::DataChannelInterface::kConnecting,
408*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->state());
409*d9f75844SAndroid Build Coastguard Worker controller_->set_send_blocked(false);
410*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kOpen,
411*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->state(), 1000);
412*d9f75844SAndroid Build Coastguard Worker controller_->set_send_blocked(true);
413*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->Send(buffer);
414*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->Close();
415*d9f75844SAndroid Build Coastguard Worker controller_->set_send_blocked(false);
416*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kClosed,
417*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->state(), 1000);
418*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(webrtc_data_channel_->error().ok());
419*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(webrtc::DataMessageType::kText,
420*d9f75844SAndroid Build Coastguard Worker controller_->last_send_data_params().type);
421*d9f75844SAndroid Build Coastguard Worker }
422*d9f75844SAndroid Build Coastguard Worker
423*d9f75844SAndroid Build Coastguard Worker // Tests that messages are sent with the right id.
TEST_F(SctpDataChannelTest,SendDataId)424*d9f75844SAndroid Build Coastguard Worker TEST_F(SctpDataChannelTest, SendDataId) {
425*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->SetSctpSid(1);
426*d9f75844SAndroid Build Coastguard Worker SetChannelReady();
427*d9f75844SAndroid Build Coastguard Worker webrtc::DataBuffer buffer("data");
428*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(webrtc_data_channel_->Send(buffer));
429*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1, controller_->last_sid());
430*d9f75844SAndroid Build Coastguard Worker }
431*d9f75844SAndroid Build Coastguard Worker
432*d9f75844SAndroid Build Coastguard Worker // Tests that the incoming messages with wrong ids are rejected.
TEST_F(SctpDataChannelTest,ReceiveDataWithInvalidId)433*d9f75844SAndroid Build Coastguard Worker TEST_F(SctpDataChannelTest, ReceiveDataWithInvalidId) {
434*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->SetSctpSid(1);
435*d9f75844SAndroid Build Coastguard Worker SetChannelReady();
436*d9f75844SAndroid Build Coastguard Worker
437*d9f75844SAndroid Build Coastguard Worker AddObserver();
438*d9f75844SAndroid Build Coastguard Worker
439*d9f75844SAndroid Build Coastguard Worker cricket::ReceiveDataParams params;
440*d9f75844SAndroid Build Coastguard Worker params.sid = 0;
441*d9f75844SAndroid Build Coastguard Worker webrtc::DataBuffer buffer("abcd");
442*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->OnDataReceived(params, buffer.data);
443*d9f75844SAndroid Build Coastguard Worker
444*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0U, observer_->messages_received());
445*d9f75844SAndroid Build Coastguard Worker }
446*d9f75844SAndroid Build Coastguard Worker
447*d9f75844SAndroid Build Coastguard Worker // Tests that the incoming messages with right ids are accepted.
TEST_F(SctpDataChannelTest,ReceiveDataWithValidId)448*d9f75844SAndroid Build Coastguard Worker TEST_F(SctpDataChannelTest, ReceiveDataWithValidId) {
449*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->SetSctpSid(1);
450*d9f75844SAndroid Build Coastguard Worker SetChannelReady();
451*d9f75844SAndroid Build Coastguard Worker
452*d9f75844SAndroid Build Coastguard Worker AddObserver();
453*d9f75844SAndroid Build Coastguard Worker
454*d9f75844SAndroid Build Coastguard Worker cricket::ReceiveDataParams params;
455*d9f75844SAndroid Build Coastguard Worker params.sid = 1;
456*d9f75844SAndroid Build Coastguard Worker webrtc::DataBuffer buffer("abcd");
457*d9f75844SAndroid Build Coastguard Worker
458*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->OnDataReceived(params, buffer.data);
459*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1U, observer_->messages_received());
460*d9f75844SAndroid Build Coastguard Worker }
461*d9f75844SAndroid Build Coastguard Worker
462*d9f75844SAndroid Build Coastguard Worker // Tests that no CONTROL message is sent if the datachannel is negotiated and
463*d9f75844SAndroid Build Coastguard Worker // not created from an OPEN message.
TEST_F(SctpDataChannelTest,NoMsgSentIfNegotiatedAndNotFromOpenMsg)464*d9f75844SAndroid Build Coastguard Worker TEST_F(SctpDataChannelTest, NoMsgSentIfNegotiatedAndNotFromOpenMsg) {
465*d9f75844SAndroid Build Coastguard Worker webrtc::InternalDataChannelInit config;
466*d9f75844SAndroid Build Coastguard Worker config.id = 1;
467*d9f75844SAndroid Build Coastguard Worker config.negotiated = true;
468*d9f75844SAndroid Build Coastguard Worker config.open_handshake_role = webrtc::InternalDataChannelInit::kNone;
469*d9f75844SAndroid Build Coastguard Worker
470*d9f75844SAndroid Build Coastguard Worker SetChannelReady();
471*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<SctpDataChannel> dc =
472*d9f75844SAndroid Build Coastguard Worker SctpDataChannel::Create(controller_.get(), "test1", config,
473*d9f75844SAndroid Build Coastguard Worker rtc::Thread::Current(), rtc::Thread::Current());
474*d9f75844SAndroid Build Coastguard Worker
475*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kOpen, dc->state(), 1000);
476*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, controller_->last_sid());
477*d9f75844SAndroid Build Coastguard Worker }
478*d9f75844SAndroid Build Coastguard Worker
479*d9f75844SAndroid Build Coastguard Worker // Tests that DataChannel::messages_received() and DataChannel::bytes_received()
480*d9f75844SAndroid Build Coastguard Worker // are correct, receiving data both while not open and while open.
TEST_F(SctpDataChannelTest,VerifyMessagesAndBytesReceived)481*d9f75844SAndroid Build Coastguard Worker TEST_F(SctpDataChannelTest, VerifyMessagesAndBytesReceived) {
482*d9f75844SAndroid Build Coastguard Worker AddObserver();
483*d9f75844SAndroid Build Coastguard Worker std::vector<webrtc::DataBuffer> buffers({
484*d9f75844SAndroid Build Coastguard Worker webrtc::DataBuffer("message 1"),
485*d9f75844SAndroid Build Coastguard Worker webrtc::DataBuffer("msg 2"),
486*d9f75844SAndroid Build Coastguard Worker webrtc::DataBuffer("message three"),
487*d9f75844SAndroid Build Coastguard Worker webrtc::DataBuffer("quadra message"),
488*d9f75844SAndroid Build Coastguard Worker webrtc::DataBuffer("fifthmsg"),
489*d9f75844SAndroid Build Coastguard Worker webrtc::DataBuffer("message of the beast"),
490*d9f75844SAndroid Build Coastguard Worker });
491*d9f75844SAndroid Build Coastguard Worker
492*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->SetSctpSid(1);
493*d9f75844SAndroid Build Coastguard Worker cricket::ReceiveDataParams params;
494*d9f75844SAndroid Build Coastguard Worker params.sid = 1;
495*d9f75844SAndroid Build Coastguard Worker
496*d9f75844SAndroid Build Coastguard Worker // Default values.
497*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0U, webrtc_data_channel_->messages_received());
498*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0U, webrtc_data_channel_->bytes_received());
499*d9f75844SAndroid Build Coastguard Worker
500*d9f75844SAndroid Build Coastguard Worker // Receive three buffers while data channel isn't open.
501*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->OnDataReceived(params, buffers[0].data);
502*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->OnDataReceived(params, buffers[1].data);
503*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->OnDataReceived(params, buffers[2].data);
504*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0U, observer_->messages_received());
505*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0U, webrtc_data_channel_->messages_received());
506*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0U, webrtc_data_channel_->bytes_received());
507*d9f75844SAndroid Build Coastguard Worker
508*d9f75844SAndroid Build Coastguard Worker // Open channel and make sure everything was received.
509*d9f75844SAndroid Build Coastguard Worker SetChannelReady();
510*d9f75844SAndroid Build Coastguard Worker size_t bytes_received =
511*d9f75844SAndroid Build Coastguard Worker buffers[0].size() + buffers[1].size() + buffers[2].size();
512*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(3U, observer_->messages_received());
513*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(3U, webrtc_data_channel_->messages_received());
514*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(bytes_received, webrtc_data_channel_->bytes_received());
515*d9f75844SAndroid Build Coastguard Worker
516*d9f75844SAndroid Build Coastguard Worker // Receive three buffers while open.
517*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->OnDataReceived(params, buffers[3].data);
518*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->OnDataReceived(params, buffers[4].data);
519*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->OnDataReceived(params, buffers[5].data);
520*d9f75844SAndroid Build Coastguard Worker bytes_received += buffers[3].size() + buffers[4].size() + buffers[5].size();
521*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(6U, observer_->messages_received());
522*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(6U, webrtc_data_channel_->messages_received());
523*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(bytes_received, webrtc_data_channel_->bytes_received());
524*d9f75844SAndroid Build Coastguard Worker }
525*d9f75844SAndroid Build Coastguard Worker
526*d9f75844SAndroid Build Coastguard Worker // Tests that OPEN_ACK message is sent if the datachannel is created from an
527*d9f75844SAndroid Build Coastguard Worker // OPEN message.
TEST_F(SctpDataChannelTest,OpenAckSentIfCreatedFromOpenMessage)528*d9f75844SAndroid Build Coastguard Worker TEST_F(SctpDataChannelTest, OpenAckSentIfCreatedFromOpenMessage) {
529*d9f75844SAndroid Build Coastguard Worker webrtc::InternalDataChannelInit config;
530*d9f75844SAndroid Build Coastguard Worker config.id = 1;
531*d9f75844SAndroid Build Coastguard Worker config.negotiated = true;
532*d9f75844SAndroid Build Coastguard Worker config.open_handshake_role = webrtc::InternalDataChannelInit::kAcker;
533*d9f75844SAndroid Build Coastguard Worker
534*d9f75844SAndroid Build Coastguard Worker SetChannelReady();
535*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<SctpDataChannel> dc =
536*d9f75844SAndroid Build Coastguard Worker SctpDataChannel::Create(controller_.get(), "test1", config,
537*d9f75844SAndroid Build Coastguard Worker rtc::Thread::Current(), rtc::Thread::Current());
538*d9f75844SAndroid Build Coastguard Worker
539*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kOpen, dc->state(), 1000);
540*d9f75844SAndroid Build Coastguard Worker
541*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(config.id, controller_->last_sid());
542*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(webrtc::DataMessageType::kControl,
543*d9f75844SAndroid Build Coastguard Worker controller_->last_send_data_params().type);
544*d9f75844SAndroid Build Coastguard Worker }
545*d9f75844SAndroid Build Coastguard Worker
546*d9f75844SAndroid Build Coastguard Worker // Tests the OPEN_ACK role assigned by InternalDataChannelInit.
TEST_F(SctpDataChannelTest,OpenAckRoleInitialization)547*d9f75844SAndroid Build Coastguard Worker TEST_F(SctpDataChannelTest, OpenAckRoleInitialization) {
548*d9f75844SAndroid Build Coastguard Worker webrtc::InternalDataChannelInit init;
549*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(webrtc::InternalDataChannelInit::kOpener, init.open_handshake_role);
550*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(init.negotiated);
551*d9f75844SAndroid Build Coastguard Worker
552*d9f75844SAndroid Build Coastguard Worker webrtc::DataChannelInit base;
553*d9f75844SAndroid Build Coastguard Worker base.negotiated = true;
554*d9f75844SAndroid Build Coastguard Worker webrtc::InternalDataChannelInit init2(base);
555*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(webrtc::InternalDataChannelInit::kNone, init2.open_handshake_role);
556*d9f75844SAndroid Build Coastguard Worker }
557*d9f75844SAndroid Build Coastguard Worker
558*d9f75844SAndroid Build Coastguard Worker // Tests that that Send() returns false if the sending buffer is full
559*d9f75844SAndroid Build Coastguard Worker // and the channel stays open.
TEST_F(SctpDataChannelTest,OpenWhenSendBufferFull)560*d9f75844SAndroid Build Coastguard Worker TEST_F(SctpDataChannelTest, OpenWhenSendBufferFull) {
561*d9f75844SAndroid Build Coastguard Worker SetChannelReady();
562*d9f75844SAndroid Build Coastguard Worker
563*d9f75844SAndroid Build Coastguard Worker const size_t packetSize = 1024;
564*d9f75844SAndroid Build Coastguard Worker
565*d9f75844SAndroid Build Coastguard Worker rtc::CopyOnWriteBuffer buffer(packetSize);
566*d9f75844SAndroid Build Coastguard Worker memset(buffer.MutableData(), 0, buffer.size());
567*d9f75844SAndroid Build Coastguard Worker
568*d9f75844SAndroid Build Coastguard Worker webrtc::DataBuffer packet(buffer, true);
569*d9f75844SAndroid Build Coastguard Worker controller_->set_send_blocked(true);
570*d9f75844SAndroid Build Coastguard Worker
571*d9f75844SAndroid Build Coastguard Worker for (size_t i = 0;
572*d9f75844SAndroid Build Coastguard Worker i < webrtc::DataChannelInterface::MaxSendQueueSize() / packetSize; ++i) {
573*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(webrtc_data_channel_->Send(packet));
574*d9f75844SAndroid Build Coastguard Worker }
575*d9f75844SAndroid Build Coastguard Worker
576*d9f75844SAndroid Build Coastguard Worker // The sending buffer shoul be full, send returns false.
577*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(webrtc_data_channel_->Send(packet));
578*d9f75844SAndroid Build Coastguard Worker
579*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(webrtc::DataChannelInterface::kOpen ==
580*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->state());
581*d9f75844SAndroid Build Coastguard Worker }
582*d9f75844SAndroid Build Coastguard Worker
583*d9f75844SAndroid Build Coastguard Worker // Tests that the DataChannel is closed on transport errors.
TEST_F(SctpDataChannelTest,ClosedOnTransportError)584*d9f75844SAndroid Build Coastguard Worker TEST_F(SctpDataChannelTest, ClosedOnTransportError) {
585*d9f75844SAndroid Build Coastguard Worker SetChannelReady();
586*d9f75844SAndroid Build Coastguard Worker webrtc::DataBuffer buffer("abcd");
587*d9f75844SAndroid Build Coastguard Worker controller_->set_transport_error();
588*d9f75844SAndroid Build Coastguard Worker
589*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(webrtc_data_channel_->Send(buffer));
590*d9f75844SAndroid Build Coastguard Worker
591*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(webrtc::DataChannelInterface::kClosed,
592*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->state());
593*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(webrtc_data_channel_->error().ok());
594*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(webrtc::RTCErrorType::NETWORK_ERROR,
595*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->error().type());
596*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(webrtc::RTCErrorDetailType::NONE,
597*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->error().error_detail());
598*d9f75844SAndroid Build Coastguard Worker }
599*d9f75844SAndroid Build Coastguard Worker
600*d9f75844SAndroid Build Coastguard Worker // Tests that the DataChannel is closed if the received buffer is full.
TEST_F(SctpDataChannelTest,ClosedWhenReceivedBufferFull)601*d9f75844SAndroid Build Coastguard Worker TEST_F(SctpDataChannelTest, ClosedWhenReceivedBufferFull) {
602*d9f75844SAndroid Build Coastguard Worker SetChannelReady();
603*d9f75844SAndroid Build Coastguard Worker rtc::CopyOnWriteBuffer buffer(1024);
604*d9f75844SAndroid Build Coastguard Worker memset(buffer.MutableData(), 0, buffer.size());
605*d9f75844SAndroid Build Coastguard Worker
606*d9f75844SAndroid Build Coastguard Worker cricket::ReceiveDataParams params;
607*d9f75844SAndroid Build Coastguard Worker params.sid = 0;
608*d9f75844SAndroid Build Coastguard Worker
609*d9f75844SAndroid Build Coastguard Worker // Receiving data without having an observer will overflow the buffer.
610*d9f75844SAndroid Build Coastguard Worker for (size_t i = 0; i < 16 * 1024 + 1; ++i) {
611*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->OnDataReceived(params, buffer);
612*d9f75844SAndroid Build Coastguard Worker }
613*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(webrtc::DataChannelInterface::kClosed,
614*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->state());
615*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(webrtc_data_channel_->error().ok());
616*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(webrtc::RTCErrorType::RESOURCE_EXHAUSTED,
617*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->error().type());
618*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(webrtc::RTCErrorDetailType::NONE,
619*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->error().error_detail());
620*d9f75844SAndroid Build Coastguard Worker }
621*d9f75844SAndroid Build Coastguard Worker
622*d9f75844SAndroid Build Coastguard Worker // Tests that sending empty data returns no error and keeps the channel open.
TEST_F(SctpDataChannelTest,SendEmptyData)623*d9f75844SAndroid Build Coastguard Worker TEST_F(SctpDataChannelTest, SendEmptyData) {
624*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->SetSctpSid(1);
625*d9f75844SAndroid Build Coastguard Worker SetChannelReady();
626*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(webrtc::DataChannelInterface::kOpen, webrtc_data_channel_->state());
627*d9f75844SAndroid Build Coastguard Worker
628*d9f75844SAndroid Build Coastguard Worker webrtc::DataBuffer buffer("");
629*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(webrtc_data_channel_->Send(buffer));
630*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(webrtc::DataChannelInterface::kOpen, webrtc_data_channel_->state());
631*d9f75844SAndroid Build Coastguard Worker }
632*d9f75844SAndroid Build Coastguard Worker
633*d9f75844SAndroid Build Coastguard Worker // Tests that a channel can be closed without being opened or assigned an sid.
TEST_F(SctpDataChannelTest,NeverOpened)634*d9f75844SAndroid Build Coastguard Worker TEST_F(SctpDataChannelTest, NeverOpened) {
635*d9f75844SAndroid Build Coastguard Worker controller_->set_transport_available(true);
636*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->OnTransportChannelCreated();
637*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->Close();
638*d9f75844SAndroid Build Coastguard Worker }
639*d9f75844SAndroid Build Coastguard Worker
640*d9f75844SAndroid Build Coastguard Worker // Test that the data channel goes to the "closed" state (and doesn't crash)
641*d9f75844SAndroid Build Coastguard Worker // when its transport goes away, even while data is buffered.
TEST_F(SctpDataChannelTest,TransportDestroyedWhileDataBuffered)642*d9f75844SAndroid Build Coastguard Worker TEST_F(SctpDataChannelTest, TransportDestroyedWhileDataBuffered) {
643*d9f75844SAndroid Build Coastguard Worker SetChannelReady();
644*d9f75844SAndroid Build Coastguard Worker
645*d9f75844SAndroid Build Coastguard Worker rtc::CopyOnWriteBuffer buffer(1024);
646*d9f75844SAndroid Build Coastguard Worker memset(buffer.MutableData(), 0, buffer.size());
647*d9f75844SAndroid Build Coastguard Worker webrtc::DataBuffer packet(buffer, true);
648*d9f75844SAndroid Build Coastguard Worker
649*d9f75844SAndroid Build Coastguard Worker // Send a packet while sending is blocked so it ends up buffered.
650*d9f75844SAndroid Build Coastguard Worker controller_->set_send_blocked(true);
651*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(webrtc_data_channel_->Send(packet));
652*d9f75844SAndroid Build Coastguard Worker
653*d9f75844SAndroid Build Coastguard Worker // Tell the data channel that its transport is being destroyed.
654*d9f75844SAndroid Build Coastguard Worker // It should then stop using the transport (allowing us to delete it) and
655*d9f75844SAndroid Build Coastguard Worker // transition to the "closed" state.
656*d9f75844SAndroid Build Coastguard Worker webrtc::RTCError error(webrtc::RTCErrorType::OPERATION_ERROR_WITH_DATA, "");
657*d9f75844SAndroid Build Coastguard Worker error.set_error_detail(webrtc::RTCErrorDetailType::SCTP_FAILURE);
658*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->OnTransportChannelClosed(error);
659*d9f75844SAndroid Build Coastguard Worker controller_.reset(nullptr);
660*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kClosed,
661*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->state(), kDefaultTimeout);
662*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(webrtc_data_channel_->error().ok());
663*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(webrtc::RTCErrorType::OPERATION_ERROR_WITH_DATA,
664*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->error().type());
665*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(webrtc::RTCErrorDetailType::SCTP_FAILURE,
666*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->error().error_detail());
667*d9f75844SAndroid Build Coastguard Worker }
668*d9f75844SAndroid Build Coastguard Worker
TEST_F(SctpDataChannelTest,TransportGotErrorCode)669*d9f75844SAndroid Build Coastguard Worker TEST_F(SctpDataChannelTest, TransportGotErrorCode) {
670*d9f75844SAndroid Build Coastguard Worker SetChannelReady();
671*d9f75844SAndroid Build Coastguard Worker
672*d9f75844SAndroid Build Coastguard Worker // Tell the data channel that its transport is being destroyed with an
673*d9f75844SAndroid Build Coastguard Worker // error code.
674*d9f75844SAndroid Build Coastguard Worker // It should then report that error code.
675*d9f75844SAndroid Build Coastguard Worker webrtc::RTCError error(webrtc::RTCErrorType::OPERATION_ERROR_WITH_DATA,
676*d9f75844SAndroid Build Coastguard Worker "Transport channel closed");
677*d9f75844SAndroid Build Coastguard Worker error.set_error_detail(webrtc::RTCErrorDetailType::SCTP_FAILURE);
678*d9f75844SAndroid Build Coastguard Worker error.set_sctp_cause_code(
679*d9f75844SAndroid Build Coastguard Worker static_cast<uint16_t>(cricket::SctpErrorCauseCode::kProtocolViolation));
680*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->OnTransportChannelClosed(error);
681*d9f75844SAndroid Build Coastguard Worker controller_.reset(nullptr);
682*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kClosed,
683*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->state(), kDefaultTimeout);
684*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(webrtc_data_channel_->error().ok());
685*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(webrtc::RTCErrorType::OPERATION_ERROR_WITH_DATA,
686*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->error().type());
687*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(webrtc::RTCErrorDetailType::SCTP_FAILURE,
688*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->error().error_detail());
689*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(
690*d9f75844SAndroid Build Coastguard Worker static_cast<uint16_t>(cricket::SctpErrorCauseCode::kProtocolViolation),
691*d9f75844SAndroid Build Coastguard Worker webrtc_data_channel_->error().sctp_cause_code());
692*d9f75844SAndroid Build Coastguard Worker }
693*d9f75844SAndroid Build Coastguard Worker
694*d9f75844SAndroid Build Coastguard Worker class SctpSidAllocatorTest : public ::testing::Test {
695*d9f75844SAndroid Build Coastguard Worker protected:
696*d9f75844SAndroid Build Coastguard Worker SctpSidAllocator allocator_;
697*d9f75844SAndroid Build Coastguard Worker };
698*d9f75844SAndroid Build Coastguard Worker
699*d9f75844SAndroid Build Coastguard Worker // Verifies that an even SCTP id is allocated for SSL_CLIENT and an odd id for
700*d9f75844SAndroid Build Coastguard Worker // SSL_SERVER.
TEST_F(SctpSidAllocatorTest,SctpIdAllocationBasedOnRole)701*d9f75844SAndroid Build Coastguard Worker TEST_F(SctpSidAllocatorTest, SctpIdAllocationBasedOnRole) {
702*d9f75844SAndroid Build Coastguard Worker int id;
703*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_SERVER, &id));
704*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1, id);
705*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_CLIENT, &id));
706*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, id);
707*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_SERVER, &id));
708*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(3, id);
709*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_CLIENT, &id));
710*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(2, id);
711*d9f75844SAndroid Build Coastguard Worker }
712*d9f75844SAndroid Build Coastguard Worker
713*d9f75844SAndroid Build Coastguard Worker // Verifies that SCTP ids of existing DataChannels are not reused.
TEST_F(SctpSidAllocatorTest,SctpIdAllocationNoReuse)714*d9f75844SAndroid Build Coastguard Worker TEST_F(SctpSidAllocatorTest, SctpIdAllocationNoReuse) {
715*d9f75844SAndroid Build Coastguard Worker int old_id = 1;
716*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(allocator_.ReserveSid(old_id));
717*d9f75844SAndroid Build Coastguard Worker
718*d9f75844SAndroid Build Coastguard Worker int new_id;
719*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_SERVER, &new_id));
720*d9f75844SAndroid Build Coastguard Worker EXPECT_NE(old_id, new_id);
721*d9f75844SAndroid Build Coastguard Worker
722*d9f75844SAndroid Build Coastguard Worker old_id = 0;
723*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(allocator_.ReserveSid(old_id));
724*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_CLIENT, &new_id));
725*d9f75844SAndroid Build Coastguard Worker EXPECT_NE(old_id, new_id);
726*d9f75844SAndroid Build Coastguard Worker }
727*d9f75844SAndroid Build Coastguard Worker
728*d9f75844SAndroid Build Coastguard Worker // Verifies that SCTP ids of removed DataChannels can be reused.
TEST_F(SctpSidAllocatorTest,SctpIdReusedForRemovedDataChannel)729*d9f75844SAndroid Build Coastguard Worker TEST_F(SctpSidAllocatorTest, SctpIdReusedForRemovedDataChannel) {
730*d9f75844SAndroid Build Coastguard Worker int odd_id = 1;
731*d9f75844SAndroid Build Coastguard Worker int even_id = 0;
732*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(allocator_.ReserveSid(odd_id));
733*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(allocator_.ReserveSid(even_id));
734*d9f75844SAndroid Build Coastguard Worker
735*d9f75844SAndroid Build Coastguard Worker int allocated_id = -1;
736*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_SERVER, &allocated_id));
737*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(odd_id + 2, allocated_id);
738*d9f75844SAndroid Build Coastguard Worker
739*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_CLIENT, &allocated_id));
740*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(even_id + 2, allocated_id);
741*d9f75844SAndroid Build Coastguard Worker
742*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_SERVER, &allocated_id));
743*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(odd_id + 4, allocated_id);
744*d9f75844SAndroid Build Coastguard Worker
745*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_CLIENT, &allocated_id));
746*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(even_id + 4, allocated_id);
747*d9f75844SAndroid Build Coastguard Worker
748*d9f75844SAndroid Build Coastguard Worker allocator_.ReleaseSid(odd_id);
749*d9f75844SAndroid Build Coastguard Worker allocator_.ReleaseSid(even_id);
750*d9f75844SAndroid Build Coastguard Worker
751*d9f75844SAndroid Build Coastguard Worker // Verifies that removed ids are reused.
752*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_SERVER, &allocated_id));
753*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(odd_id, allocated_id);
754*d9f75844SAndroid Build Coastguard Worker
755*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_CLIENT, &allocated_id));
756*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(even_id, allocated_id);
757*d9f75844SAndroid Build Coastguard Worker
758*d9f75844SAndroid Build Coastguard Worker // Verifies that used higher ids are not reused.
759*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_SERVER, &allocated_id));
760*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(odd_id + 6, allocated_id);
761*d9f75844SAndroid Build Coastguard Worker
762*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_CLIENT, &allocated_id));
763*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(even_id + 6, allocated_id);
764*d9f75844SAndroid Build Coastguard Worker }
765