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 "webrtc/base/gunit.h" 32 33using webrtc::DataChannel; 34using webrtc::SctpSidAllocator; 35 36class FakeDataChannelObserver : public webrtc::DataChannelObserver { 37 public: 38 FakeDataChannelObserver() 39 : messages_received_(0), 40 on_state_change_count_(0), 41 on_buffered_amount_change_count_(0) {} 42 43 void OnStateChange() { 44 ++on_state_change_count_; 45 } 46 47 void OnBufferedAmountChange(uint64_t previous_amount) { 48 ++on_buffered_amount_change_count_; 49 } 50 51 void OnMessage(const webrtc::DataBuffer& buffer) { 52 ++messages_received_; 53 } 54 55 size_t messages_received() const { 56 return messages_received_; 57 } 58 59 void ResetOnStateChangeCount() { 60 on_state_change_count_ = 0; 61 } 62 63 void ResetOnBufferedAmountChangeCount() { 64 on_buffered_amount_change_count_ = 0; 65 } 66 67 size_t on_state_change_count() const { 68 return on_state_change_count_; 69 } 70 71 size_t on_buffered_amount_change_count() const { 72 return on_buffered_amount_change_count_; 73 } 74 75 private: 76 size_t messages_received_; 77 size_t on_state_change_count_; 78 size_t on_buffered_amount_change_count_; 79}; 80 81class SctpDataChannelTest : public testing::Test { 82 protected: 83 SctpDataChannelTest() 84 : webrtc_data_channel_( 85 DataChannel::Create( 86 &provider_, cricket::DCT_SCTP, "test", init_)) { 87 } 88 89 void SetChannelReady() { 90 provider_.set_transport_available(true); 91 webrtc_data_channel_->OnTransportChannelCreated(); 92 if (webrtc_data_channel_->id() < 0) { 93 webrtc_data_channel_->SetSctpSid(0); 94 } 95 provider_.set_ready_to_send(true); 96 } 97 98 void AddObserver() { 99 observer_.reset(new FakeDataChannelObserver()); 100 webrtc_data_channel_->RegisterObserver(observer_.get()); 101 } 102 103 webrtc::InternalDataChannelInit init_; 104 FakeDataChannelProvider provider_; 105 rtc::scoped_ptr<FakeDataChannelObserver> observer_; 106 rtc::scoped_refptr<DataChannel> webrtc_data_channel_; 107}; 108 109// Verifies that the data channel is connected to the transport after creation. 110TEST_F(SctpDataChannelTest, ConnectedToTransportOnCreated) { 111 provider_.set_transport_available(true); 112 rtc::scoped_refptr<DataChannel> dc = DataChannel::Create( 113 &provider_, cricket::DCT_SCTP, "test1", init_); 114 115 EXPECT_TRUE(provider_.IsConnected(dc.get())); 116 // The sid is not set yet, so it should not have added the streams. 117 EXPECT_FALSE(provider_.IsSendStreamAdded(dc->id())); 118 EXPECT_FALSE(provider_.IsRecvStreamAdded(dc->id())); 119 120 dc->SetSctpSid(0); 121 EXPECT_TRUE(provider_.IsSendStreamAdded(dc->id())); 122 EXPECT_TRUE(provider_.IsRecvStreamAdded(dc->id())); 123} 124 125// Verifies that the data channel is connected to the transport if the transport 126// is not available initially and becomes available later. 127TEST_F(SctpDataChannelTest, ConnectedAfterTransportBecomesAvailable) { 128 EXPECT_FALSE(provider_.IsConnected(webrtc_data_channel_.get())); 129 130 provider_.set_transport_available(true); 131 webrtc_data_channel_->OnTransportChannelCreated(); 132 EXPECT_TRUE(provider_.IsConnected(webrtc_data_channel_.get())); 133} 134 135// Tests the state of the data channel. 136TEST_F(SctpDataChannelTest, StateTransition) { 137 EXPECT_EQ(webrtc::DataChannelInterface::kConnecting, 138 webrtc_data_channel_->state()); 139 SetChannelReady(); 140 141 EXPECT_EQ(webrtc::DataChannelInterface::kOpen, webrtc_data_channel_->state()); 142 webrtc_data_channel_->Close(); 143 EXPECT_EQ(webrtc::DataChannelInterface::kClosed, 144 webrtc_data_channel_->state()); 145 // Verifies that it's disconnected from the transport. 146 EXPECT_FALSE(provider_.IsConnected(webrtc_data_channel_.get())); 147} 148 149// Tests that DataChannel::buffered_amount() is correct after the channel is 150// blocked. 151TEST_F(SctpDataChannelTest, BufferedAmountWhenBlocked) { 152 AddObserver(); 153 SetChannelReady(); 154 webrtc::DataBuffer buffer("abcd"); 155 EXPECT_TRUE(webrtc_data_channel_->Send(buffer)); 156 157 EXPECT_EQ(0U, webrtc_data_channel_->buffered_amount()); 158 EXPECT_EQ(0U, observer_->on_buffered_amount_change_count()); 159 160 provider_.set_send_blocked(true); 161 162 const int number_of_packets = 3; 163 for (int i = 0; i < number_of_packets; ++i) { 164 EXPECT_TRUE(webrtc_data_channel_->Send(buffer)); 165 } 166 EXPECT_EQ(buffer.data.size() * number_of_packets, 167 webrtc_data_channel_->buffered_amount()); 168 EXPECT_EQ(number_of_packets, observer_->on_buffered_amount_change_count()); 169} 170 171// Tests that the queued data are sent when the channel transitions from blocked 172// to unblocked. 173TEST_F(SctpDataChannelTest, QueuedDataSentWhenUnblocked) { 174 AddObserver(); 175 SetChannelReady(); 176 webrtc::DataBuffer buffer("abcd"); 177 provider_.set_send_blocked(true); 178 EXPECT_TRUE(webrtc_data_channel_->Send(buffer)); 179 180 EXPECT_EQ(1U, observer_->on_buffered_amount_change_count()); 181 182 provider_.set_send_blocked(false); 183 SetChannelReady(); 184 EXPECT_EQ(0U, webrtc_data_channel_->buffered_amount()); 185 EXPECT_EQ(2U, observer_->on_buffered_amount_change_count()); 186} 187 188// Tests that no crash when the channel is blocked right away while trying to 189// send queued data. 190TEST_F(SctpDataChannelTest, BlockedWhenSendQueuedDataNoCrash) { 191 AddObserver(); 192 SetChannelReady(); 193 webrtc::DataBuffer buffer("abcd"); 194 provider_.set_send_blocked(true); 195 EXPECT_TRUE(webrtc_data_channel_->Send(buffer)); 196 EXPECT_EQ(1U, observer_->on_buffered_amount_change_count()); 197 198 // Set channel ready while it is still blocked. 199 SetChannelReady(); 200 EXPECT_EQ(buffer.size(), webrtc_data_channel_->buffered_amount()); 201 EXPECT_EQ(1U, observer_->on_buffered_amount_change_count()); 202 203 // Unblock the channel to send queued data again, there should be no crash. 204 provider_.set_send_blocked(false); 205 SetChannelReady(); 206 EXPECT_EQ(0U, webrtc_data_channel_->buffered_amount()); 207 EXPECT_EQ(2U, observer_->on_buffered_amount_change_count()); 208} 209 210// Tests that the queued control message is sent when channel is ready. 211TEST_F(SctpDataChannelTest, OpenMessageSent) { 212 // Initially the id is unassigned. 213 EXPECT_EQ(-1, webrtc_data_channel_->id()); 214 215 SetChannelReady(); 216 EXPECT_GE(webrtc_data_channel_->id(), 0); 217 EXPECT_EQ(cricket::DMT_CONTROL, provider_.last_send_data_params().type); 218 EXPECT_EQ(provider_.last_send_data_params().ssrc, 219 static_cast<uint32_t>(webrtc_data_channel_->id())); 220} 221 222TEST_F(SctpDataChannelTest, QueuedOpenMessageSent) { 223 provider_.set_send_blocked(true); 224 SetChannelReady(); 225 provider_.set_send_blocked(false); 226 227 EXPECT_EQ(cricket::DMT_CONTROL, provider_.last_send_data_params().type); 228 EXPECT_EQ(provider_.last_send_data_params().ssrc, 229 static_cast<uint32_t>(webrtc_data_channel_->id())); 230} 231 232// Tests that the DataChannel created after transport gets ready can enter OPEN 233// state. 234TEST_F(SctpDataChannelTest, LateCreatedChannelTransitionToOpen) { 235 SetChannelReady(); 236 webrtc::InternalDataChannelInit init; 237 init.id = 1; 238 rtc::scoped_refptr<DataChannel> dc = DataChannel::Create( 239 &provider_, cricket::DCT_SCTP, "test1", init); 240 EXPECT_EQ(webrtc::DataChannelInterface::kConnecting, dc->state()); 241 EXPECT_TRUE_WAIT(webrtc::DataChannelInterface::kOpen == dc->state(), 242 1000); 243} 244 245// Tests that an unordered DataChannel sends data as ordered until the OPEN_ACK 246// message is received. 247TEST_F(SctpDataChannelTest, SendUnorderedAfterReceivesOpenAck) { 248 SetChannelReady(); 249 webrtc::InternalDataChannelInit init; 250 init.id = 1; 251 init.ordered = false; 252 rtc::scoped_refptr<DataChannel> dc = DataChannel::Create( 253 &provider_, cricket::DCT_SCTP, "test1", init); 254 255 EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kOpen, dc->state(), 1000); 256 257 // Sends a message and verifies it's ordered. 258 webrtc::DataBuffer buffer("some data"); 259 ASSERT_TRUE(dc->Send(buffer)); 260 EXPECT_TRUE(provider_.last_send_data_params().ordered); 261 262 // Emulates receiving an OPEN_ACK message. 263 cricket::ReceiveDataParams params; 264 params.ssrc = init.id; 265 params.type = cricket::DMT_CONTROL; 266 rtc::Buffer payload; 267 webrtc::WriteDataChannelOpenAckMessage(&payload); 268 dc->OnDataReceived(NULL, params, payload); 269 270 // Sends another message and verifies it's unordered. 271 ASSERT_TRUE(dc->Send(buffer)); 272 EXPECT_FALSE(provider_.last_send_data_params().ordered); 273} 274 275// Tests that an unordered DataChannel sends unordered data after any DATA 276// message is received. 277TEST_F(SctpDataChannelTest, SendUnorderedAfterReceiveData) { 278 SetChannelReady(); 279 webrtc::InternalDataChannelInit init; 280 init.id = 1; 281 init.ordered = false; 282 rtc::scoped_refptr<DataChannel> dc = DataChannel::Create( 283 &provider_, cricket::DCT_SCTP, "test1", init); 284 285 EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kOpen, dc->state(), 1000); 286 287 // Emulates receiving a DATA message. 288 cricket::ReceiveDataParams params; 289 params.ssrc = init.id; 290 params.type = cricket::DMT_TEXT; 291 webrtc::DataBuffer buffer("data"); 292 dc->OnDataReceived(NULL, params, buffer.data); 293 294 // Sends a message and verifies it's unordered. 295 ASSERT_TRUE(dc->Send(buffer)); 296 EXPECT_FALSE(provider_.last_send_data_params().ordered); 297} 298 299// Tests that the channel can't open until it's successfully sent the OPEN 300// message. 301TEST_F(SctpDataChannelTest, OpenWaitsForOpenMesssage) { 302 webrtc::DataBuffer buffer("foo"); 303 304 provider_.set_send_blocked(true); 305 SetChannelReady(); 306 EXPECT_EQ(webrtc::DataChannelInterface::kConnecting, 307 webrtc_data_channel_->state()); 308 provider_.set_send_blocked(false); 309 EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kOpen, 310 webrtc_data_channel_->state(), 1000); 311 EXPECT_EQ(cricket::DMT_CONTROL, provider_.last_send_data_params().type); 312} 313 314// Tests that close first makes sure all queued data gets sent. 315TEST_F(SctpDataChannelTest, QueuedCloseFlushes) { 316 webrtc::DataBuffer buffer("foo"); 317 318 provider_.set_send_blocked(true); 319 SetChannelReady(); 320 EXPECT_EQ(webrtc::DataChannelInterface::kConnecting, 321 webrtc_data_channel_->state()); 322 provider_.set_send_blocked(false); 323 EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kOpen, 324 webrtc_data_channel_->state(), 1000); 325 provider_.set_send_blocked(true); 326 webrtc_data_channel_->Send(buffer); 327 webrtc_data_channel_->Close(); 328 provider_.set_send_blocked(false); 329 EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kClosed, 330 webrtc_data_channel_->state(), 1000); 331 EXPECT_EQ(cricket::DMT_TEXT, provider_.last_send_data_params().type); 332} 333 334// Tests that messages are sent with the right ssrc. 335TEST_F(SctpDataChannelTest, SendDataSsrc) { 336 webrtc_data_channel_->SetSctpSid(1); 337 SetChannelReady(); 338 webrtc::DataBuffer buffer("data"); 339 EXPECT_TRUE(webrtc_data_channel_->Send(buffer)); 340 EXPECT_EQ(1U, provider_.last_send_data_params().ssrc); 341} 342 343// Tests that the incoming messages with wrong ssrcs are rejected. 344TEST_F(SctpDataChannelTest, ReceiveDataWithInvalidSsrc) { 345 webrtc_data_channel_->SetSctpSid(1); 346 SetChannelReady(); 347 348 AddObserver(); 349 350 cricket::ReceiveDataParams params; 351 params.ssrc = 0; 352 webrtc::DataBuffer buffer("abcd"); 353 webrtc_data_channel_->OnDataReceived(NULL, params, buffer.data); 354 355 EXPECT_EQ(0U, observer_->messages_received()); 356} 357 358// Tests that the incoming messages with right ssrcs are acceted. 359TEST_F(SctpDataChannelTest, ReceiveDataWithValidSsrc) { 360 webrtc_data_channel_->SetSctpSid(1); 361 SetChannelReady(); 362 363 AddObserver(); 364 365 cricket::ReceiveDataParams params; 366 params.ssrc = 1; 367 webrtc::DataBuffer buffer("abcd"); 368 369 webrtc_data_channel_->OnDataReceived(NULL, params, buffer.data); 370 EXPECT_EQ(1U, observer_->messages_received()); 371} 372 373// Tests that no CONTROL message is sent if the datachannel is negotiated and 374// not created from an OPEN message. 375TEST_F(SctpDataChannelTest, NoMsgSentIfNegotiatedAndNotFromOpenMsg) { 376 webrtc::InternalDataChannelInit config; 377 config.id = 1; 378 config.negotiated = true; 379 config.open_handshake_role = webrtc::InternalDataChannelInit::kNone; 380 381 SetChannelReady(); 382 rtc::scoped_refptr<DataChannel> dc = DataChannel::Create( 383 &provider_, cricket::DCT_SCTP, "test1", config); 384 385 EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kOpen, dc->state(), 1000); 386 EXPECT_EQ(0U, provider_.last_send_data_params().ssrc); 387} 388 389// Tests that OPEN_ACK message is sent if the datachannel is created from an 390// OPEN message. 391TEST_F(SctpDataChannelTest, OpenAckSentIfCreatedFromOpenMessage) { 392 webrtc::InternalDataChannelInit config; 393 config.id = 1; 394 config.negotiated = true; 395 config.open_handshake_role = webrtc::InternalDataChannelInit::kAcker; 396 397 SetChannelReady(); 398 rtc::scoped_refptr<DataChannel> dc = DataChannel::Create( 399 &provider_, cricket::DCT_SCTP, "test1", config); 400 401 EXPECT_EQ_WAIT(webrtc::DataChannelInterface::kOpen, dc->state(), 1000); 402 403 EXPECT_EQ(static_cast<unsigned int>(config.id), 404 provider_.last_send_data_params().ssrc); 405 EXPECT_EQ(cricket::DMT_CONTROL, provider_.last_send_data_params().type); 406} 407 408// Tests the OPEN_ACK role assigned by InternalDataChannelInit. 409TEST_F(SctpDataChannelTest, OpenAckRoleInitialization) { 410 webrtc::InternalDataChannelInit init; 411 EXPECT_EQ(webrtc::InternalDataChannelInit::kOpener, init.open_handshake_role); 412 EXPECT_FALSE(init.negotiated); 413 414 webrtc::DataChannelInit base; 415 base.negotiated = true; 416 webrtc::InternalDataChannelInit init2(base); 417 EXPECT_EQ(webrtc::InternalDataChannelInit::kNone, init2.open_handshake_role); 418} 419 420// Tests that the DataChannel is closed if the sending buffer is full. 421TEST_F(SctpDataChannelTest, ClosedWhenSendBufferFull) { 422 SetChannelReady(); 423 424 rtc::Buffer buffer(1024); 425 memset(buffer.data(), 0, buffer.size()); 426 427 webrtc::DataBuffer packet(buffer, true); 428 provider_.set_send_blocked(true); 429 430 for (size_t i = 0; i < 16 * 1024 + 1; ++i) { 431 EXPECT_TRUE(webrtc_data_channel_->Send(packet)); 432 } 433 434 EXPECT_TRUE( 435 webrtc::DataChannelInterface::kClosed == webrtc_data_channel_->state() || 436 webrtc::DataChannelInterface::kClosing == webrtc_data_channel_->state()); 437} 438 439// Tests that the DataChannel is closed on transport errors. 440TEST_F(SctpDataChannelTest, ClosedOnTransportError) { 441 SetChannelReady(); 442 webrtc::DataBuffer buffer("abcd"); 443 provider_.set_transport_error(); 444 445 EXPECT_TRUE(webrtc_data_channel_->Send(buffer)); 446 447 EXPECT_EQ(webrtc::DataChannelInterface::kClosed, 448 webrtc_data_channel_->state()); 449} 450 451// Tests that a already closed DataChannel does not fire onStateChange again. 452TEST_F(SctpDataChannelTest, ClosedDataChannelDoesNotFireOnStateChange) { 453 AddObserver(); 454 webrtc_data_channel_->Close(); 455 // OnStateChange called for kClosing and kClosed. 456 EXPECT_EQ(2U, observer_->on_state_change_count()); 457 458 observer_->ResetOnStateChangeCount(); 459 webrtc_data_channel_->RemotePeerRequestClose(); 460 EXPECT_EQ(0U, observer_->on_state_change_count()); 461} 462 463// Tests that RemotePeerRequestClose closes the local DataChannel. 464TEST_F(SctpDataChannelTest, RemotePeerRequestClose) { 465 AddObserver(); 466 webrtc_data_channel_->RemotePeerRequestClose(); 467 468 // OnStateChange called for kClosing and kClosed. 469 EXPECT_EQ(2U, observer_->on_state_change_count()); 470 EXPECT_EQ(webrtc::DataChannelInterface::kClosed, 471 webrtc_data_channel_->state()); 472} 473 474// Tests that the DataChannel is closed if the received buffer is full. 475TEST_F(SctpDataChannelTest, ClosedWhenReceivedBufferFull) { 476 SetChannelReady(); 477 rtc::Buffer buffer(1024); 478 memset(buffer.data(), 0, buffer.size()); 479 480 cricket::ReceiveDataParams params; 481 params.ssrc = 0; 482 483 // Receiving data without having an observer will overflow the buffer. 484 for (size_t i = 0; i < 16 * 1024 + 1; ++i) { 485 webrtc_data_channel_->OnDataReceived(NULL, params, buffer); 486 } 487 EXPECT_EQ(webrtc::DataChannelInterface::kClosed, 488 webrtc_data_channel_->state()); 489} 490 491// Tests that sending empty data returns no error and keeps the channel open. 492TEST_F(SctpDataChannelTest, SendEmptyData) { 493 webrtc_data_channel_->SetSctpSid(1); 494 SetChannelReady(); 495 EXPECT_EQ(webrtc::DataChannelInterface::kOpen, 496 webrtc_data_channel_->state()); 497 498 webrtc::DataBuffer buffer(""); 499 EXPECT_TRUE(webrtc_data_channel_->Send(buffer)); 500 EXPECT_EQ(webrtc::DataChannelInterface::kOpen, 501 webrtc_data_channel_->state()); 502} 503 504// Tests that a channel can be closed without being opened or assigned an sid. 505TEST_F(SctpDataChannelTest, NeverOpened) { 506 provider_.set_transport_available(true); 507 webrtc_data_channel_->OnTransportChannelCreated(); 508 webrtc_data_channel_->Close(); 509} 510 511class SctpSidAllocatorTest : public testing::Test { 512 protected: 513 SctpSidAllocator allocator_; 514}; 515 516// Verifies that an even SCTP id is allocated for SSL_CLIENT and an odd id for 517// SSL_SERVER. 518TEST_F(SctpSidAllocatorTest, SctpIdAllocationBasedOnRole) { 519 int id; 520 EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_SERVER, &id)); 521 EXPECT_EQ(1, id); 522 EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_CLIENT, &id)); 523 EXPECT_EQ(0, id); 524 EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_SERVER, &id)); 525 EXPECT_EQ(3, id); 526 EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_CLIENT, &id)); 527 EXPECT_EQ(2, id); 528} 529 530// Verifies that SCTP ids of existing DataChannels are not reused. 531TEST_F(SctpSidAllocatorTest, SctpIdAllocationNoReuse) { 532 int old_id = 1; 533 EXPECT_TRUE(allocator_.ReserveSid(old_id)); 534 535 int new_id; 536 EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_SERVER, &new_id)); 537 EXPECT_NE(old_id, new_id); 538 539 old_id = 0; 540 EXPECT_TRUE(allocator_.ReserveSid(old_id)); 541 EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_CLIENT, &new_id)); 542 EXPECT_NE(old_id, new_id); 543} 544 545// Verifies that SCTP ids of removed DataChannels can be reused. 546TEST_F(SctpSidAllocatorTest, SctpIdReusedForRemovedDataChannel) { 547 int odd_id = 1; 548 int even_id = 0; 549 EXPECT_TRUE(allocator_.ReserveSid(odd_id)); 550 EXPECT_TRUE(allocator_.ReserveSid(even_id)); 551 552 int allocated_id = -1; 553 EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_SERVER, &allocated_id)); 554 EXPECT_EQ(odd_id + 2, allocated_id); 555 556 EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_CLIENT, &allocated_id)); 557 EXPECT_EQ(even_id + 2, allocated_id); 558 559 EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_SERVER, &allocated_id)); 560 EXPECT_EQ(odd_id + 4, allocated_id); 561 562 EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_CLIENT, &allocated_id)); 563 EXPECT_EQ(even_id + 4, allocated_id); 564 565 allocator_.ReleaseSid(odd_id); 566 allocator_.ReleaseSid(even_id); 567 568 // Verifies that removed ids are reused. 569 EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_SERVER, &allocated_id)); 570 EXPECT_EQ(odd_id, allocated_id); 571 572 EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_CLIENT, &allocated_id)); 573 EXPECT_EQ(even_id, allocated_id); 574 575 // Verifies that used higher ids are not reused. 576 EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_SERVER, &allocated_id)); 577 EXPECT_EQ(odd_id + 6, allocated_id); 578 579 EXPECT_TRUE(allocator_.AllocateSid(rtc::SSL_CLIENT, &allocated_id)); 580 EXPECT_EQ(even_id + 6, allocated_id); 581} 582