1 /* 2 * libjingle 3 * Copyright 2013, Google Inc. 4 * 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 28 #include "talk/app/webrtc/datachannel.h" 29 #include "talk/app/webrtc/sctputils.h" 30 #include "talk/app/webrtc/test/fakedatachannelprovider.h" 31 #include "talk/base/gunit.h" 32 33 using webrtc::DataChannel; 34 35 class FakeDataChannelObserver : public webrtc::DataChannelObserver { 36 public: 37 FakeDataChannelObserver() 38 : messages_received_(0), on_state_change_count_(0) {} 39 40 void OnStateChange() { 41 ++on_state_change_count_; 42 } 43 44 void OnMessage(const webrtc::DataBuffer& buffer) { 45 ++messages_received_; 46 } 47 48 size_t messages_received() const { 49 return messages_received_; 50 } 51 52 void ResetOnStateChangeCount() { 53 on_state_change_count_ = 0; 54 } 55 56 size_t on_state_change_count() const { 57 return on_state_change_count_; 58 } 59 60 private: 61 size_t messages_received_; 62 size_t on_state_change_count_; 63 }; 64 65 class SctpDataChannelTest : public testing::Test { 66 protected: 67 SctpDataChannelTest() 68 : webrtc_data_channel_( 69 DataChannel::Create( 70 &provider_, cricket::DCT_SCTP, "test", init_)) { 71 } 72 73 void SetChannelReady() { 74 provider_.set_transport_available(true); 75 webrtc_data_channel_->OnTransportChannelCreated(); 76 if (webrtc_data_channel_->id() < 0) { 77 webrtc_data_channel_->SetSctpSid(0); 78 } 79 provider_.set_ready_to_send(true); 80 } 81 82 void AddObserver() { 83 observer_.reset(new FakeDataChannelObserver()); 84 webrtc_data_channel_->RegisterObserver(observer_.get()); 85 } 86 87 webrtc::InternalDataChannelInit init_; 88 FakeDataChannelProvider provider_; 89 talk_base::scoped_ptr<FakeDataChannelObserver> observer_; 90 talk_base::scoped_refptr<DataChannel> webrtc_data_channel_; 91 }; 92 93 // Verifies that the data channel is connected to the transport after creation. 94 TEST_F(SctpDataChannelTest, ConnectedToTransportOnCreated) { 95 provider_.set_transport_available(true); 96 talk_base::scoped_refptr<DataChannel> dc = DataChannel::Create( 97 &provider_, cricket::DCT_SCTP, "test1", init_); 98 99 EXPECT_TRUE(provider_.IsConnected(dc.get())); 100 // The sid is not set yet, so it should not have added the streams. 101 EXPECT_FALSE(provider_.IsSendStreamAdded(dc->id())); 102 EXPECT_FALSE(provider_.IsRecvStreamAdded(dc->id())); 103 104 dc->SetSctpSid(0); 105 EXPECT_TRUE(provider_.IsSendStreamAdded(dc->id())); 106 EXPECT_TRUE(provider_.IsRecvStreamAdded(dc->id())); 107 } 108 109 // Verifies that the data channel is connected to the transport if the transport 110 // is not available initially and becomes available later. 111 TEST_F(SctpDataChannelTest, ConnectedAfterTransportBecomesAvailable) { 112 EXPECT_FALSE(provider_.IsConnected(webrtc_data_channel_.get())); 113 114 provider_.set_transport_available(true); 115 webrtc_data_channel_->OnTransportChannelCreated(); 116 EXPECT_TRUE(provider_.IsConnected(webrtc_data_channel_.get())); 117 } 118 119 // Tests the state of the data channel. 120 TEST_F(SctpDataChannelTest, StateTransition) { 121 EXPECT_EQ(webrtc::DataChannelInterface::kConnecting, 122 webrtc_data_channel_->state()); 123 SetChannelReady(); 124 125 EXPECT_EQ(webrtc::DataChannelInterface::kOpen, webrtc_data_channel_->state()); 126 webrtc_data_channel_->Close(); 127 EXPECT_EQ(webrtc::DataChannelInterface::kClosed, 128 webrtc_data_channel_->state()); 129 // Verifies that it's disconnected from the transport. 130 EXPECT_FALSE(provider_.IsConnected(webrtc_data_channel_.get())); 131 } 132 133 // Tests that DataChannel::buffered_amount() is correct after the channel is 134 // blocked. 135 TEST_F(SctpDataChannelTest, BufferedAmountWhenBlocked) { 136 SetChannelReady(); 137 webrtc::DataBuffer buffer("abcd"); 138 EXPECT_TRUE(webrtc_data_channel_->Send(buffer)); 139 140 EXPECT_EQ(0U, webrtc_data_channel_->buffered_amount()); 141 142 provider_.set_send_blocked(true); 143 144 const int number_of_packets = 3; 145 for (int i = 0; i < number_of_packets; ++i) { 146 EXPECT_TRUE(webrtc_data_channel_->Send(buffer)); 147 } 148 EXPECT_EQ(buffer.data.length() * number_of_packets, 149 webrtc_data_channel_->buffered_amount()); 150 } 151 152 // Tests that the queued data are sent when the channel transitions from blocked 153 // to unblocked. 154 TEST_F(SctpDataChannelTest, QueuedDataSentWhenUnblocked) { 155 SetChannelReady(); 156 webrtc::DataBuffer buffer("abcd"); 157 provider_.set_send_blocked(true); 158 EXPECT_TRUE(webrtc_data_channel_->Send(buffer)); 159 160 provider_.set_send_blocked(false); 161 SetChannelReady(); 162 EXPECT_EQ(0U, webrtc_data_channel_->buffered_amount()); 163 } 164 165 // Tests that the queued control message is sent when channel is ready. 166 TEST_F(SctpDataChannelTest, OpenMessageSent) { 167 // Initially the id is unassigned. 168 EXPECT_EQ(-1, webrtc_data_channel_->id()); 169 170 SetChannelReady(); 171 EXPECT_GE(webrtc_data_channel_->id(), 0); 172 EXPECT_EQ(cricket::DMT_CONTROL, provider_.last_send_data_params().type); 173 EXPECT_EQ(provider_.last_send_data_params().ssrc, 174 static_cast<uint32>(webrtc_data_channel_->id())); 175 } 176 177 // Tests that the DataChannel created after transport gets ready can enter OPEN 178 // state. 179 TEST_F(SctpDataChannelTest, LateCreatedChannelTransitionToOpen) { 180 SetChannelReady(); 181 webrtc::InternalDataChannelInit init; 182 init.id = 1; 183 talk_base::scoped_refptr<DataChannel> dc = DataChannel::Create( 184 &provider_, cricket::DCT_SCTP, "test1", init); 185 EXPECT_EQ(webrtc::DataChannelInterface::kConnecting, dc->state()); 186 EXPECT_TRUE_WAIT(webrtc::DataChannelInterface::kOpen == dc->state(), 187 1000); 188 } 189 190 // Tests that an unordered DataChannel sends data as ordered until the OPEN_ACK 191 // message is received. 192 TEST_F(SctpDataChannelTest, SendUnorderedAfterReceivesOpenAck) { 193 SetChannelReady(); 194 webrtc::InternalDataChannelInit init; 195 init.id = 1; 196 init.ordered = false; 197 talk_base::scoped_refptr<DataChannel> dc = DataChannel::Create( 198 &provider_, cricket::DCT_SCTP, "test1", init); 199 200 EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kOpen, dc->state(), 1000); 201 202 // Sends a message and verifies it's ordered. 203 webrtc::DataBuffer buffer("some data"); 204 ASSERT_TRUE(dc->Send(buffer)); 205 EXPECT_TRUE(provider_.last_send_data_params().ordered); 206 207 // Emulates receiving an OPEN_ACK message. 208 cricket::ReceiveDataParams params; 209 params.ssrc = init.id; 210 params.type = cricket::DMT_CONTROL; 211 talk_base::Buffer payload; 212 webrtc::WriteDataChannelOpenAckMessage(&payload); 213 dc->OnDataReceived(NULL, params, payload); 214 215 // Sends another message and verifies it's unordered. 216 ASSERT_TRUE(dc->Send(buffer)); 217 EXPECT_FALSE(provider_.last_send_data_params().ordered); 218 } 219 220 // Tests that an unordered DataChannel sends unordered data after any DATA 221 // message is received. 222 TEST_F(SctpDataChannelTest, SendUnorderedAfterReceiveData) { 223 SetChannelReady(); 224 webrtc::InternalDataChannelInit init; 225 init.id = 1; 226 init.ordered = false; 227 talk_base::scoped_refptr<DataChannel> dc = DataChannel::Create( 228 &provider_, cricket::DCT_SCTP, "test1", init); 229 230 EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kOpen, dc->state(), 1000); 231 232 // Emulates receiving a DATA message. 233 cricket::ReceiveDataParams params; 234 params.ssrc = init.id; 235 params.type = cricket::DMT_TEXT; 236 webrtc::DataBuffer buffer("data"); 237 dc->OnDataReceived(NULL, params, buffer.data); 238 239 // Sends a message and verifies it's unordered. 240 ASSERT_TRUE(dc->Send(buffer)); 241 EXPECT_FALSE(provider_.last_send_data_params().ordered); 242 } 243 244 // Tests that messages are sent with the right ssrc. 245 TEST_F(SctpDataChannelTest, SendDataSsrc) { 246 webrtc_data_channel_->SetSctpSid(1); 247 SetChannelReady(); 248 webrtc::DataBuffer buffer("data"); 249 EXPECT_TRUE(webrtc_data_channel_->Send(buffer)); 250 EXPECT_EQ(1U, provider_.last_send_data_params().ssrc); 251 } 252 253 // Tests that the incoming messages with wrong ssrcs are rejected. 254 TEST_F(SctpDataChannelTest, ReceiveDataWithInvalidSsrc) { 255 webrtc_data_channel_->SetSctpSid(1); 256 SetChannelReady(); 257 258 AddObserver(); 259 260 cricket::ReceiveDataParams params; 261 params.ssrc = 0; 262 webrtc::DataBuffer buffer("abcd"); 263 webrtc_data_channel_->OnDataReceived(NULL, params, buffer.data); 264 265 EXPECT_EQ(0U, observer_->messages_received()); 266 } 267 268 // Tests that the incoming messages with right ssrcs are acceted. 269 TEST_F(SctpDataChannelTest, ReceiveDataWithValidSsrc) { 270 webrtc_data_channel_->SetSctpSid(1); 271 SetChannelReady(); 272 273 AddObserver(); 274 275 cricket::ReceiveDataParams params; 276 params.ssrc = 1; 277 webrtc::DataBuffer buffer("abcd"); 278 279 webrtc_data_channel_->OnDataReceived(NULL, params, buffer.data); 280 EXPECT_EQ(1U, observer_->messages_received()); 281 } 282 283 // Tests that no CONTROL message is sent if the datachannel is negotiated and 284 // not created from an OPEN message. 285 TEST_F(SctpDataChannelTest, NoMsgSentIfNegotiatedAndNotFromOpenMsg) { 286 webrtc::InternalDataChannelInit config; 287 config.id = 1; 288 config.negotiated = true; 289 config.open_handshake_role = webrtc::InternalDataChannelInit::kNone; 290 291 SetChannelReady(); 292 talk_base::scoped_refptr<DataChannel> dc = DataChannel::Create( 293 &provider_, cricket::DCT_SCTP, "test1", config); 294 295 EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kOpen, dc->state(), 1000); 296 EXPECT_EQ(0U, provider_.last_send_data_params().ssrc); 297 } 298 299 // Tests that OPEN_ACK message is sent if the datachannel is created from an 300 // OPEN message. 301 TEST_F(SctpDataChannelTest, OpenAckSentIfCreatedFromOpenMessage) { 302 webrtc::InternalDataChannelInit config; 303 config.id = 1; 304 config.negotiated = true; 305 config.open_handshake_role = webrtc::InternalDataChannelInit::kAcker; 306 307 SetChannelReady(); 308 talk_base::scoped_refptr<DataChannel> dc = DataChannel::Create( 309 &provider_, cricket::DCT_SCTP, "test1", config); 310 311 EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kOpen, dc->state(), 1000); 312 313 EXPECT_EQ(static_cast<unsigned int>(config.id), 314 provider_.last_send_data_params().ssrc); 315 EXPECT_EQ(cricket::DMT_CONTROL, provider_.last_send_data_params().type); 316 } 317 318 // Tests the OPEN_ACK role assigned by InternalDataChannelInit. 319 TEST_F(SctpDataChannelTest, OpenAckRoleInitialization) { 320 webrtc::InternalDataChannelInit init; 321 EXPECT_EQ(webrtc::InternalDataChannelInit::kOpener, init.open_handshake_role); 322 EXPECT_FALSE(init.negotiated); 323 324 webrtc::DataChannelInit base; 325 base.negotiated = true; 326 webrtc::InternalDataChannelInit init2(base); 327 EXPECT_EQ(webrtc::InternalDataChannelInit::kNone, init2.open_handshake_role); 328 } 329 330 // Tests that the DataChannel is closed if the sending buffer is full. 331 TEST_F(SctpDataChannelTest, ClosedWhenSendBufferFull) { 332 SetChannelReady(); 333 webrtc::DataBuffer buffer("abcd"); 334 provider_.set_send_blocked(true); 335 336 for (size_t i = 0; i < 101; ++i) { 337 EXPECT_TRUE(webrtc_data_channel_->Send(buffer)); 338 } 339 340 EXPECT_EQ(webrtc::DataChannelInterface::kClosed, 341 webrtc_data_channel_->state()); 342 } 343 344 // Tests that the DataChannel is closed on transport errors. 345 TEST_F(SctpDataChannelTest, ClosedOnTransportError) { 346 SetChannelReady(); 347 webrtc::DataBuffer buffer("abcd"); 348 provider_.set_transport_error(); 349 350 EXPECT_TRUE(webrtc_data_channel_->Send(buffer)); 351 352 EXPECT_EQ(webrtc::DataChannelInterface::kClosed, 353 webrtc_data_channel_->state()); 354 } 355 356 // Tests that a already closed DataChannel does not fire onStateChange again. 357 TEST_F(SctpDataChannelTest, ClosedDataChannelDoesNotFireOnStateChange) { 358 AddObserver(); 359 webrtc_data_channel_->Close(); 360 // OnStateChange called for kClosing and kClosed. 361 EXPECT_EQ(2U, observer_->on_state_change_count()); 362 363 observer_->ResetOnStateChangeCount(); 364 webrtc_data_channel_->RemotePeerRequestClose(); 365 EXPECT_EQ(0U, observer_->on_state_change_count()); 366 } 367 368 // Tests that RemotePeerRequestClose closes the local DataChannel. 369 TEST_F(SctpDataChannelTest, RemotePeerRequestClose) { 370 AddObserver(); 371 webrtc_data_channel_->RemotePeerRequestClose(); 372 373 // OnStateChange called for kClosing and kClosed. 374 EXPECT_EQ(2U, observer_->on_state_change_count()); 375 EXPECT_EQ(webrtc::DataChannelInterface::kClosed, 376 webrtc_data_channel_->state()); 377 } 378 379