3
* Copyright 2011 Google Inc.
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions are met:
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.
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.
30
#include "talk/base/gunit.h"
31
#include "talk/base/helpers.h"
32
#include "talk/base/messagehandler.h"
33
#include "talk/base/stream.h"
34
#include "talk/base/thread.h"
35
#include "talk/base/timeutils.h"
36
#include "talk/p2p/base/pseudotcp.h"
38
using cricket::PseudoTcp;
40
static const int kConnectTimeoutMs = 10000; // ~3 * default RTO of 3000ms
41
static const int kTransferTimeoutMs = 15000;
42
static const int kBlockSize = 4096;
44
class PseudoTcpForTest : public cricket::PseudoTcp {
46
PseudoTcpForTest(cricket::IPseudoTcpNotify* notify, uint32 conv)
47
: PseudoTcp(notify, conv) {
50
bool isReceiveBufferFull() const {
51
return PseudoTcp::isReceiveBufferFull();
54
void disableWindowScale() {
55
PseudoTcp::disableWindowScale();
59
class PseudoTcpTestBase : public testing::Test,
60
public talk_base::MessageHandler,
61
public cricket::IPseudoTcpNotify {
66
have_connected_(false),
67
have_disconnected_(false),
72
// Set use of the test RNG to get predictable loss patterns.
73
talk_base::SetRandomTestMode(true);
75
~PseudoTcpTestBase() {
76
// Put it back for the next test.
77
talk_base::SetRandomTestMode(false);
79
void SetLocalMtu(int mtu) {
80
local_.NotifyMTU(mtu);
83
void SetRemoteMtu(int mtu) {
84
remote_.NotifyMTU(mtu);
87
void SetDelay(int delay) {
90
void SetLoss(int percent) {
93
void SetOptNagling(bool enable_nagles) {
94
local_.SetOption(PseudoTcp::OPT_NODELAY, !enable_nagles);
95
remote_.SetOption(PseudoTcp::OPT_NODELAY, !enable_nagles);
97
void SetOptAckDelay(int ack_delay) {
98
local_.SetOption(PseudoTcp::OPT_ACKDELAY, ack_delay);
99
remote_.SetOption(PseudoTcp::OPT_ACKDELAY, ack_delay);
101
void SetOptSndBuf(int size) {
102
local_.SetOption(PseudoTcp::OPT_SNDBUF, size);
103
remote_.SetOption(PseudoTcp::OPT_SNDBUF, size);
105
void SetRemoteOptRcvBuf(int size) {
106
remote_.SetOption(PseudoTcp::OPT_RCVBUF, size);
108
void SetLocalOptRcvBuf(int size) {
109
local_.SetOption(PseudoTcp::OPT_RCVBUF, size);
111
void DisableRemoteWindowScale() {
112
remote_.disableWindowScale();
114
void DisableLocalWindowScale() {
115
local_.disableWindowScale();
120
int ret = local_.Connect();
131
enum { MSG_LPACKET, MSG_RPACKET, MSG_LCLOCK, MSG_RCLOCK, MSG_IOCOMPLETE,
133
virtual void OnTcpOpen(PseudoTcp* tcp) {
134
// Consider ourselves connected when the local side gets OnTcpOpen.
135
// OnTcpWriteable isn't fired at open, so we trigger it now.
136
LOG(LS_VERBOSE) << "Opened";
137
if (tcp == &local_) {
138
have_connected_ = true;
142
// Test derived from the base should override
143
// virtual void OnTcpReadable(PseudoTcp* tcp)
145
// virtual void OnTcpWritable(PseudoTcp* tcp)
146
virtual void OnTcpClosed(PseudoTcp* tcp, uint32 error) {
147
// Consider ourselves closed when the remote side gets OnTcpClosed.
148
// TODO: OnTcpClosed is only ever notified in case of error in
149
// the current implementation. Solicited close is not (yet) supported.
150
LOG(LS_VERBOSE) << "Closed";
151
EXPECT_EQ(0U, error);
152
if (tcp == &remote_) {
153
have_disconnected_ = true;
156
virtual WriteResult TcpWritePacket(PseudoTcp* tcp,
157
const char* buffer, size_t len) {
158
// Randomly drop the desired percentage of packets.
159
// Also drop packets that are larger than the configured MTU.
160
if (talk_base::CreateRandomId() % 100 < static_cast<uint32>(loss_)) {
161
LOG(LS_VERBOSE) << "Randomly dropping packet, size=" << len;
162
} else if (len > static_cast<size_t>(
163
talk_base::_min(local_mtu_, remote_mtu_))) {
164
LOG(LS_VERBOSE) << "Dropping packet that exceeds path MTU, size=" << len;
166
int id = (tcp == &local_) ? MSG_RPACKET : MSG_LPACKET;
167
std::string packet(buffer, len);
168
talk_base::Thread::Current()->PostDelayed(delay_, this, id,
169
talk_base::WrapMessageData(packet));
174
void UpdateLocalClock() { UpdateClock(&local_, MSG_LCLOCK); }
175
void UpdateRemoteClock() { UpdateClock(&remote_, MSG_RCLOCK); }
176
void UpdateClock(PseudoTcp* tcp, uint32 message) {
177
long interval; // NOLINT
178
tcp->GetNextClock(PseudoTcp::Now(), interval);
179
interval = talk_base::_max<int>(interval, 0L); // sometimes interval is < 0
180
talk_base::Thread::Current()->Clear(this, message);
181
talk_base::Thread::Current()->PostDelayed(interval, this, message);
184
virtual void OnMessage(talk_base::Message* message) {
185
switch (message->message_id) {
187
const std::string& s(
188
talk_base::UseMessageData<std::string>(message->pdata));
189
local_.NotifyPacket(s.c_str(), s.size());
194
const std::string& s(
195
talk_base::UseMessageData<std::string>(message->pdata));
196
remote_.NotifyPacket(s.c_str(), s.size());
201
local_.NotifyClock(PseudoTcp::Now());
205
remote_.NotifyClock(PseudoTcp::Now());
211
delete message->pdata;
214
PseudoTcpForTest local_;
215
PseudoTcpForTest remote_;
216
talk_base::MemoryStream send_stream_;
217
talk_base::MemoryStream recv_stream_;
218
bool have_connected_;
219
bool have_disconnected_;
226
class PseudoTcpTest : public PseudoTcpTestBase {
228
void TestTransfer(int size) {
229
uint32 start, elapsed;
231
// Create some dummy data to send.
232
send_stream_.ReserveSize(size);
233
for (int i = 0; i < size; ++i) {
234
char ch = static_cast<char>(i);
235
send_stream_.Write(&ch, 1, NULL, NULL);
237
send_stream_.Rewind();
238
// Prepare the receive stream.
239
recv_stream_.ReserveSize(size);
240
// Connect and wait until connected.
241
start = talk_base::Time();
242
EXPECT_EQ(0, Connect());
243
EXPECT_TRUE_WAIT(have_connected_, kConnectTimeoutMs);
244
// Sending will start from OnTcpWriteable and complete when all data has
246
EXPECT_TRUE_WAIT(have_disconnected_, kTransferTimeoutMs);
247
elapsed = talk_base::TimeSince(start);
248
recv_stream_.GetSize(&received);
249
// Ensure we closed down OK and we got the right data.
250
// TODO: Ensure the errors are cleared properly.
251
//EXPECT_EQ(0, local_.GetError());
252
//EXPECT_EQ(0, remote_.GetError());
253
EXPECT_EQ(static_cast<size_t>(size), received);
254
EXPECT_EQ(0, memcmp(send_stream_.GetBuffer(),
255
recv_stream_.GetBuffer(), size));
256
LOG(LS_INFO) << "Transferred " << received << " bytes in " << elapsed
257
<< " ms (" << size * 8 / elapsed << " Kbps)";
261
// IPseudoTcpNotify interface
263
virtual void OnTcpReadable(PseudoTcp* tcp) {
264
// Stream bytes to the recv stream as they arrive.
265
if (tcp == &remote_) {
268
// TODO: OnTcpClosed() is currently only notified on error -
269
// there is no on-the-wire equivalent of TCP FIN.
270
// So we fake the notification when all the data has been read.
271
size_t received, required;
272
recv_stream_.GetPosition(&received);
273
send_stream_.GetSize(&required);
274
if (received == required)
275
OnTcpClosed(&remote_, 0);
278
virtual void OnTcpWriteable(PseudoTcp* tcp) {
279
// Write bytes from the send stream when we can.
280
// Shut down when we've sent everything.
281
if (tcp == &local_) {
282
LOG(LS_VERBOSE) << "Flow Control Lifted";
292
char block[kBlockSize];
296
rcvd = remote_.Recv(block, sizeof(block));
298
recv_stream_.Write(block, rcvd, NULL, NULL);
299
recv_stream_.GetPosition(&position);
300
LOG(LS_VERBOSE) << "Received: " << position;
304
void WriteData(bool* done) {
305
size_t position, tosend;
307
char block[kBlockSize];
309
send_stream_.GetPosition(&position);
310
if (send_stream_.Read(block, sizeof(block), &tosend, NULL) !=
312
sent = local_.Send(block, tosend);
315
send_stream_.SetPosition(position + sent);
316
LOG(LS_VERBOSE) << "Sent: " << position + sent;
318
send_stream_.SetPosition(position);
319
LOG(LS_VERBOSE) << "Flow Controlled";
325
*done = (tosend == 0);
329
talk_base::MemoryStream send_stream_;
330
talk_base::MemoryStream recv_stream_;
334
class PseudoTcpTestPingPong : public PseudoTcpTestBase {
336
PseudoTcpTestPingPong()
337
: iterations_remaining_(0),
342
void SetBytesPerSend(int bytes) {
343
bytes_per_send_ = bytes;
345
void TestPingPong(int size, int iterations) {
346
uint32 start, elapsed;
347
iterations_remaining_ = iterations;
348
receiver_ = &remote_;
350
// Create some dummy data to send.
351
send_stream_.ReserveSize(size);
352
for (int i = 0; i < size; ++i) {
353
char ch = static_cast<char>(i);
354
send_stream_.Write(&ch, 1, NULL, NULL);
356
send_stream_.Rewind();
357
// Prepare the receive stream.
358
recv_stream_.ReserveSize(size);
359
// Connect and wait until connected.
360
start = talk_base::Time();
361
EXPECT_EQ(0, Connect());
362
EXPECT_TRUE_WAIT(have_connected_, kConnectTimeoutMs);
363
// Sending will start from OnTcpWriteable and stop when the required
364
// number of iterations have completed.
365
EXPECT_TRUE_WAIT(have_disconnected_, kTransferTimeoutMs);
366
elapsed = talk_base::TimeSince(start);
367
LOG(LS_INFO) << "Performed " << iterations << " pings in "
372
// IPseudoTcpNotify interface
374
virtual void OnTcpReadable(PseudoTcp* tcp) {
375
if (tcp != receiver_) {
376
LOG_F(LS_ERROR) << "unexpected OnTcpReadable";
379
// Stream bytes to the recv stream as they arrive.
381
// If we've received the desired amount of data, rewind things
382
// and send it back the other way!
383
size_t position, desired;
384
recv_stream_.GetPosition(&position);
385
send_stream_.GetSize(&desired);
386
if (position == desired) {
387
if (receiver_ == &local_ && --iterations_remaining_ == 0) {
389
// TODO: Fake OnTcpClosed() on the receiver for now.
390
OnTcpClosed(&remote_, 0);
393
PseudoTcp* tmp = receiver_;
396
recv_stream_.Rewind();
397
send_stream_.Rewind();
398
OnTcpWriteable(sender_);
401
virtual void OnTcpWriteable(PseudoTcp* tcp) {
404
// Write bytes from the send stream when we can.
405
// Shut down when we've sent everything.
406
LOG(LS_VERBOSE) << "Flow Control Lifted";
411
char block[kBlockSize];
415
rcvd = receiver_->Recv(block, sizeof(block));
417
recv_stream_.Write(block, rcvd, NULL, NULL);
418
recv_stream_.GetPosition(&position);
419
LOG(LS_VERBOSE) << "Received: " << position;
424
size_t position, tosend;
426
char block[kBlockSize];
428
send_stream_.GetPosition(&position);
429
tosend = bytes_per_send_ ? bytes_per_send_ : sizeof(block);
430
if (send_stream_.Read(block, tosend, &tosend, NULL) !=
432
sent = sender_->Send(block, tosend);
435
send_stream_.SetPosition(position + sent);
436
LOG(LS_VERBOSE) << "Sent: " << position + sent;
438
send_stream_.SetPosition(position);
439
LOG(LS_VERBOSE) << "Flow Controlled";
448
int iterations_remaining_;
450
PseudoTcp* receiver_;
454
// Fill the receiver window until it is full, drain it and then
455
// fill it with the same amount. This is to test that receiver window
456
// contracts and enlarges correctly.
457
class PseudoTcpTestReceiveWindow : public PseudoTcpTestBase {
459
// Not all the data are transfered, |size| just need to be big enough
460
// to fill up the receiver window twice.
461
void TestTransfer(int size) {
462
// Create some dummy data to send.
463
send_stream_.ReserveSize(size);
464
for (int i = 0; i < size; ++i) {
465
char ch = static_cast<char>(i);
466
send_stream_.Write(&ch, 1, NULL, NULL);
468
send_stream_.Rewind();
470
// Prepare the receive stream.
471
recv_stream_.ReserveSize(size);
473
// Connect and wait until connected.
474
EXPECT_EQ(0, Connect());
475
EXPECT_TRUE_WAIT(have_connected_, kConnectTimeoutMs);
477
talk_base::Thread::Current()->Post(this, MSG_WRITE);
478
EXPECT_TRUE_WAIT(have_disconnected_, kTransferTimeoutMs);
480
ASSERT_EQ(2u, send_position_.size());
481
ASSERT_EQ(2u, recv_position_.size());
483
const size_t estimated_recv_window = EstimateReceiveWindowSize();
485
// The difference in consecutive send positions should equal the
486
// receive window size or match very closely. This verifies that receive
487
// window is open after receiver drained all the data.
488
const size_t send_position_diff = send_position_[1] - send_position_[0];
489
EXPECT_GE(1024u, estimated_recv_window - send_position_diff);
491
// Receiver drained the receive window twice.
492
EXPECT_EQ(2 * estimated_recv_window, recv_position_[1]);
495
virtual void OnMessage(talk_base::Message* message) {
496
int message_id = message->message_id;
497
PseudoTcpTestBase::OnMessage(message);
499
switch (message_id) {
509
uint32 EstimateReceiveWindowSize() const {
510
return recv_position_[0];
513
uint32 EstimateSendWindowSize() const {
514
return send_position_[0] - recv_position_[0];
518
// IPseudoTcpNotify interface
519
virtual void OnTcpReadable(PseudoTcp* tcp) {
522
virtual void OnTcpWriteable(PseudoTcp* tcp) {
525
void ReadUntilIOPending() {
526
char block[kBlockSize];
531
rcvd = remote_.Recv(block, sizeof(block));
533
recv_stream_.Write(block, rcvd, NULL, NULL);
534
recv_stream_.GetPosition(&position);
535
LOG(LS_VERBOSE) << "Received: " << position;
539
recv_stream_.GetPosition(&position);
540
recv_position_.push_back(position);
542
// Disconnect if we have done two transfers.
543
if (recv_position_.size() == 2u) {
545
OnTcpClosed(&remote_, 0);
552
size_t position, tosend;
554
char block[kBlockSize];
556
send_stream_.GetPosition(&position);
557
if (send_stream_.Read(block, sizeof(block), &tosend, NULL) !=
559
sent = local_.Send(block, tosend);
562
send_stream_.SetPosition(position + sent);
563
LOG(LS_VERBOSE) << "Sent: " << position + sent;
565
send_stream_.SetPosition(position);
566
LOG(LS_VERBOSE) << "Flow Controlled";
572
// At this point, we've filled up the available space in the send queue.
574
int message_queue_size = talk_base::Thread::Current()->size();
575
// The message queue will always have at least 2 messages, an RCLOCK and
576
// an LCLOCK, since they are added back on the delay queue at the same time
577
// they are pulled off and therefore are never really removed.
578
if (message_queue_size > 2) {
579
// If there are non-clock messages remaining, attempt to continue sending
580
// after giving those messages time to process, which should free up the
582
talk_base::Thread::Current()->PostDelayed(10, this, MSG_WRITE);
584
if (!remote_.isReceiveBufferFull()) {
585
LOG(LS_ERROR) << "This shouldn't happen - the send buffer is full, "
586
<< "the receive buffer is not, and there are no "
587
<< "remaining messages to process.";
589
send_stream_.GetPosition(&position);
590
send_position_.push_back(position);
592
// Drain the receiver buffer.
593
ReadUntilIOPending();
598
talk_base::MemoryStream send_stream_;
599
talk_base::MemoryStream recv_stream_;
601
std::vector<size_t> send_position_;
602
std::vector<size_t> recv_position_;
605
// Basic end-to-end data transfer tests
607
// Test the normal case of sending data from one side to the other.
608
TEST_F(PseudoTcpTest, TestSend) {
611
TestTransfer(1000000);
614
// Test sending data with a 50 ms RTT. Transmission should take longer due
615
// to a slower ramp-up in send rate.
616
TEST_F(PseudoTcpTest, TestSendWithDelay) {
620
TestTransfer(1000000);
623
// Test sending data with packet loss. Transmission should take much longer due
624
// to send back-off when loss occurs.
625
TEST_F(PseudoTcpTest, TestSendWithLoss) {
629
TestTransfer(100000); // less data so test runs faster
632
// Test sending data with a 50 ms RTT and 10% packet loss. Transmission should
633
// take much longer due to send back-off and slower detection of loss.
634
TEST_F(PseudoTcpTest, TestSendWithDelayAndLoss) {
639
TestTransfer(100000); // less data so test runs faster
642
// Test sending data with 10% packet loss and Nagling disabled. Transmission
643
// should take about the same time as with Nagling enabled.
644
TEST_F(PseudoTcpTest, TestSendWithLossAndOptNaglingOff) {
648
SetOptNagling(false);
649
TestTransfer(100000); // less data so test runs faster
652
// Test sending data with 10% packet loss and Delayed ACK disabled.
653
// Transmission should be slightly faster than with it enabled.
654
TEST_F(PseudoTcpTest, TestSendWithLossAndOptAckDelayOff) {
659
TestTransfer(100000);
662
// Test sending data with 50ms delay and Nagling disabled.
663
TEST_F(PseudoTcpTest, TestSendWithDelayAndOptNaglingOff) {
667
SetOptNagling(false);
668
TestTransfer(100000); // less data so test runs faster
671
// Test sending data with 50ms delay and Delayed ACK disabled.
672
TEST_F(PseudoTcpTest, TestSendWithDelayAndOptAckDelayOff) {
677
TestTransfer(100000); // less data so test runs faster
680
// Test a large receive buffer with a sender that doesn't support scaling.
681
TEST_F(PseudoTcpTest, TestSendRemoteNoWindowScale) {
684
SetLocalOptRcvBuf(100000);
685
DisableRemoteWindowScale();
686
TestTransfer(1000000);
689
// Test a large sender-side receive buffer with a receiver that doesn't support
691
TEST_F(PseudoTcpTest, TestSendLocalNoWindowScale) {
694
SetRemoteOptRcvBuf(100000);
695
DisableLocalWindowScale();
696
TestTransfer(1000000);
699
// Test when both sides use window scaling.
700
TEST_F(PseudoTcpTest, TestSendBothUseWindowScale) {
703
SetRemoteOptRcvBuf(100000);
704
SetLocalOptRcvBuf(100000);
705
TestTransfer(1000000);
708
// Test using a large window scale value.
709
TEST_F(PseudoTcpTest, TestSendLargeInFlight) {
712
SetRemoteOptRcvBuf(100000);
713
SetLocalOptRcvBuf(100000);
714
SetOptSndBuf(150000);
715
TestTransfer(1000000);
718
TEST_F(PseudoTcpTest, TestSendBothUseLargeWindowScale) {
721
SetRemoteOptRcvBuf(1000000);
722
SetLocalOptRcvBuf(1000000);
723
TestTransfer(10000000);
726
// Test using a small receive buffer.
727
TEST_F(PseudoTcpTest, TestSendSmallReceiveBuffer) {
730
SetRemoteOptRcvBuf(10000);
731
SetLocalOptRcvBuf(10000);
732
TestTransfer(1000000);
735
// Test using a very small receive buffer.
736
TEST_F(PseudoTcpTest, TestSendVerySmallReceiveBuffer) {
739
SetRemoteOptRcvBuf(100);
740
SetLocalOptRcvBuf(100);
741
TestTransfer(100000);
744
// Ping-pong (request/response) tests
746
// Test sending <= 1x MTU of data in each ping/pong. Should take <10ms.
747
TEST_F(PseudoTcpTestPingPong, TestPingPong1xMtu) {
750
TestPingPong(100, 100);
753
// Test sending 2x-3x MTU of data in each ping/pong. Should take <10ms.
754
TEST_F(PseudoTcpTestPingPong, TestPingPong3xMtu) {
757
TestPingPong(400, 100);
760
// Test sending 1x-2x MTU of data in each ping/pong.
761
// Should take ~1s, due to interaction between Nagling and Delayed ACK.
762
TEST_F(PseudoTcpTestPingPong, TestPingPong2xMtu) {
765
TestPingPong(2000, 5);
768
// Test sending 1x-2x MTU of data in each ping/pong with Delayed ACK off.
769
// Should take <10ms.
770
TEST_F(PseudoTcpTestPingPong, TestPingPong2xMtuWithAckDelayOff) {
774
TestPingPong(2000, 100);
777
// Test sending 1x-2x MTU of data in each ping/pong with Nagling off.
778
// Should take <10ms.
779
TEST_F(PseudoTcpTestPingPong, TestPingPong2xMtuWithNaglingOff) {
782
SetOptNagling(false);
783
TestPingPong(2000, 5);
786
// Test sending a ping as pair of short (non-full) segments.
787
// Should take ~1s, due to Delayed ACK interaction with Nagling.
788
TEST_F(PseudoTcpTestPingPong, TestPingPongShortSegments) {
791
SetOptAckDelay(5000);
792
SetBytesPerSend(50); // i.e. two Send calls per payload
793
TestPingPong(100, 5);
796
// Test sending ping as a pair of short (non-full) segments, with Nagling off.
797
// Should take <10ms.
798
TEST_F(PseudoTcpTestPingPong, TestPingPongShortSegmentsWithNaglingOff) {
801
SetOptNagling(false);
802
SetBytesPerSend(50); // i.e. two Send calls per payload
803
TestPingPong(100, 5);
806
// Test sending <= 1x MTU of data ping/pong, in two segments, no Delayed ACK.
808
TEST_F(PseudoTcpTestPingPong, TestPingPongShortSegmentsWithAckDelayOff) {
811
SetBytesPerSend(50); // i.e. two Send calls per payload
813
TestPingPong(100, 5);
816
// Test that receive window expands and contract correctly.
817
TEST_F(PseudoTcpTestReceiveWindow, TestReceiveWindow) {
820
SetOptNagling(false);
822
TestTransfer(1024 * 1000);
825
// Test setting send window size to a very small value.
826
TEST_F(PseudoTcpTestReceiveWindow, TestSetVerySmallSendWindowSize) {
829
SetOptNagling(false);
832
TestTransfer(1024 * 1000);
833
EXPECT_EQ(900u, EstimateSendWindowSize());
836
// Test setting receive window size to a value other than default.
837
TEST_F(PseudoTcpTestReceiveWindow, TestSetReceiveWindowSize) {
840
SetOptNagling(false);
842
SetRemoteOptRcvBuf(100000);
843
SetLocalOptRcvBuf(100000);
844
TestTransfer(1024 * 1000);
845
EXPECT_EQ(100000u, EstimateReceiveWindowSize());
848
/* Test sending data with mismatched MTUs. We should detect this and reduce
849
// our packet size accordingly.
850
// TODO: This doesn't actually work right now. The current code
851
// doesn't detect if the MTU is set too high on either side.
852
TEST_F(PseudoTcpTest, TestSendWithMismatchedMtus) {
855
TestTransfer(1000000);