1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "net/quic/quic_flow_controller.h" 6 7 #include "base/strings/stringprintf.h" 8 #include "net/quic/quic_flags.h" 9 #include "net/quic/quic_utils.h" 10 #include "net/quic/test_tools/quic_connection_peer.h" 11 #include "net/quic/test_tools/quic_flow_controller_peer.h" 12 #include "net/quic/test_tools/quic_test_utils.h" 13 #include "net/test/gtest_util.h" 14 #include "testing/gmock/include/gmock/gmock.h" 15 16 using base::StringPrintf; 17 18 namespace net { 19 namespace test { 20 21 using ::testing::_; 22 23 class QuicFlowControllerTest : public ::testing::Test { 24 public: 25 QuicFlowControllerTest() 26 : stream_id_(1234), 27 send_window_(kInitialSessionFlowControlWindowForTest), 28 receive_window_(kInitialSessionFlowControlWindowForTest), 29 max_receive_window_(kInitialSessionFlowControlWindowForTest), 30 connection_(false), 31 old_flag_(&FLAGS_enable_quic_stream_flow_control_2, true) { 32 } 33 34 void Initialize() { 35 flow_controller_.reset(new QuicFlowController( 36 &connection_, stream_id_, false, send_window_, 37 receive_window_, max_receive_window_)); 38 } 39 40 protected: 41 QuicStreamId stream_id_; 42 uint64 send_window_; 43 uint64 receive_window_; 44 uint64 max_receive_window_; 45 scoped_ptr<QuicFlowController> flow_controller_; 46 MockConnection connection_; 47 ValueRestore<bool> old_flag_; 48 }; 49 50 TEST_F(QuicFlowControllerTest, SendingBytes) { 51 Initialize(); 52 53 EXPECT_TRUE(flow_controller_->IsEnabled()); 54 EXPECT_FALSE(flow_controller_->IsBlocked()); 55 EXPECT_FALSE(flow_controller_->FlowControlViolation()); 56 EXPECT_EQ(send_window_, flow_controller_->SendWindowSize()); 57 58 // Send some bytes, but not enough to block. 59 flow_controller_->AddBytesSent(send_window_ / 2); 60 EXPECT_FALSE(flow_controller_->IsBlocked()); 61 EXPECT_EQ(send_window_ / 2, flow_controller_->SendWindowSize()); 62 63 // Send enough bytes to block. 64 flow_controller_->AddBytesSent(send_window_ / 2); 65 EXPECT_TRUE(flow_controller_->IsBlocked()); 66 EXPECT_EQ(0u, flow_controller_->SendWindowSize()); 67 68 // BLOCKED frame should get sent. 69 EXPECT_CALL(connection_, SendBlocked(stream_id_)).Times(1); 70 flow_controller_->MaybeSendBlocked(); 71 72 // Update the send window, and verify this has unblocked. 73 EXPECT_TRUE(flow_controller_->UpdateSendWindowOffset(2 * send_window_)); 74 EXPECT_FALSE(flow_controller_->IsBlocked()); 75 EXPECT_EQ(send_window_, flow_controller_->SendWindowSize()); 76 77 // Updating with a smaller offset doesn't change anything. 78 EXPECT_FALSE(flow_controller_->UpdateSendWindowOffset(send_window_ / 10)); 79 EXPECT_EQ(send_window_, flow_controller_->SendWindowSize()); 80 81 // Try to send more bytes, violating flow control. 82 EXPECT_CALL(connection_, 83 SendConnectionClose(QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA)); 84 EXPECT_DFATAL( 85 flow_controller_->AddBytesSent(send_window_ * 10), 86 StringPrintf("Trying to send an extra %d bytes", 87 static_cast<int>(send_window_ * 10))); 88 EXPECT_TRUE(flow_controller_->IsBlocked()); 89 EXPECT_EQ(0u, flow_controller_->SendWindowSize()); 90 } 91 92 TEST_F(QuicFlowControllerTest, ReceivingBytes) { 93 Initialize(); 94 95 EXPECT_TRUE(flow_controller_->IsEnabled()); 96 EXPECT_FALSE(flow_controller_->IsBlocked()); 97 EXPECT_FALSE(flow_controller_->FlowControlViolation()); 98 EXPECT_EQ(kInitialSessionFlowControlWindowForTest, 99 QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get())); 100 101 // Receive some bytes, updating highest received offset, but not enough to 102 // fill flow control receive window. 103 EXPECT_TRUE( 104 flow_controller_->UpdateHighestReceivedOffset(1 + receive_window_ / 2)); 105 EXPECT_FALSE(flow_controller_->FlowControlViolation()); 106 EXPECT_EQ((receive_window_ / 2) - 1, 107 QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get())); 108 109 // Consume enough bytes to send a WINDOW_UPDATE frame. 110 EXPECT_CALL(connection_, SendWindowUpdate(stream_id_, _)).Times(1); 111 112 flow_controller_->AddBytesConsumed(1 + receive_window_ / 2); 113 114 // Result is that once again we have a fully open receive window. 115 EXPECT_FALSE(flow_controller_->FlowControlViolation()); 116 EXPECT_EQ(kInitialSessionFlowControlWindowForTest, 117 QuicFlowControllerPeer::ReceiveWindowSize(flow_controller_.get())); 118 } 119 120 TEST_F(QuicFlowControllerTest, 121 DisabledWhenQuicVersionDoesNotSupportFlowControl) { 122 // Only support version 16: no flow control. 123 QuicConnectionPeer::SetSupportedVersions(&connection_, 124 SupportedVersions(QUIC_VERSION_16)); 125 126 Initialize(); 127 128 MockConnection connection(false); 129 130 // Should not be enabled, and should not report as blocked. 131 EXPECT_FALSE(flow_controller_->IsEnabled()); 132 EXPECT_FALSE(flow_controller_->IsBlocked()); 133 EXPECT_FALSE(flow_controller_->FlowControlViolation()); 134 135 // Any attempts to add/remove bytes should have no effect. 136 EXPECT_EQ(send_window_, flow_controller_->SendWindowSize()); 137 EXPECT_EQ(send_window_, 138 QuicFlowControllerPeer::SendWindowOffset(flow_controller_.get())); 139 EXPECT_EQ(receive_window_, QuicFlowControllerPeer::ReceiveWindowOffset( 140 flow_controller_.get())); 141 flow_controller_->AddBytesSent(123); 142 flow_controller_->AddBytesConsumed(456); 143 flow_controller_->UpdateHighestReceivedOffset(789); 144 EXPECT_EQ(send_window_, flow_controller_->SendWindowSize()); 145 EXPECT_EQ(send_window_, 146 QuicFlowControllerPeer::SendWindowOffset(flow_controller_.get())); 147 EXPECT_EQ(receive_window_, QuicFlowControllerPeer::ReceiveWindowOffset( 148 flow_controller_.get())); 149 150 // Any attempt to change offset should have no effect. 151 EXPECT_EQ(send_window_, flow_controller_->SendWindowSize()); 152 EXPECT_EQ(send_window_, 153 QuicFlowControllerPeer::SendWindowOffset(flow_controller_.get())); 154 flow_controller_->UpdateSendWindowOffset(send_window_ + 12345); 155 EXPECT_EQ(send_window_, flow_controller_->SendWindowSize()); 156 EXPECT_EQ(send_window_, 157 QuicFlowControllerPeer::SendWindowOffset(flow_controller_.get())); 158 159 // The connection should never send WINDOW_UPDATE or BLOCKED frames, even if 160 // the internal state implies that it should. 161 162 // If the flow controller was enabled, then a send window size of 0 would 163 // trigger a BLOCKED frame to be sent. 164 EXPECT_EQ(send_window_, flow_controller_->SendWindowSize()); 165 EXPECT_CALL(connection_, SendBlocked(_)).Times(0); 166 flow_controller_->MaybeSendBlocked(); 167 168 // If the flow controller was enabled, then a WINDOW_UPDATE would be sent if 169 // (receive window) < (max receive window / 2) 170 QuicFlowControllerPeer::SetReceiveWindowOffset(flow_controller_.get(), 171 max_receive_window_ / 10); 172 EXPECT_TRUE(QuicFlowControllerPeer::ReceiveWindowSize( 173 flow_controller_.get()) < (max_receive_window_ / 2)); 174 EXPECT_CALL(connection_, SendWindowUpdate(_, _)).Times(0); 175 flow_controller_->AddBytesConsumed(0); 176 177 // Should not be enabled, and should not report as blocked. 178 EXPECT_FALSE(flow_controller_->IsEnabled()); 179 EXPECT_FALSE(flow_controller_->IsBlocked()); 180 EXPECT_FALSE(flow_controller_->FlowControlViolation()); 181 } 182 183 TEST_F(QuicFlowControllerTest, OnlySendBlockedFrameOncePerOffset) { 184 Initialize(); 185 186 // Test that we don't send duplicate BLOCKED frames. We should only send one 187 // BLOCKED frame at a given send window offset. 188 EXPECT_TRUE(flow_controller_->IsEnabled()); 189 EXPECT_FALSE(flow_controller_->IsBlocked()); 190 EXPECT_FALSE(flow_controller_->FlowControlViolation()); 191 EXPECT_EQ(send_window_, flow_controller_->SendWindowSize()); 192 193 // Send enough bytes to block. 194 flow_controller_->AddBytesSent(send_window_); 195 EXPECT_TRUE(flow_controller_->IsBlocked()); 196 EXPECT_EQ(0u, flow_controller_->SendWindowSize()); 197 198 // Expect that 2 BLOCKED frames should get sent in total. 199 EXPECT_CALL(connection_, SendBlocked(stream_id_)).Times(2); 200 201 // BLOCKED frame should get sent. 202 flow_controller_->MaybeSendBlocked(); 203 204 // BLOCKED frame should not get sent again until our send offset changes. 205 flow_controller_->MaybeSendBlocked(); 206 flow_controller_->MaybeSendBlocked(); 207 flow_controller_->MaybeSendBlocked(); 208 flow_controller_->MaybeSendBlocked(); 209 flow_controller_->MaybeSendBlocked(); 210 211 // Update the send window, then send enough bytes to block again. 212 EXPECT_TRUE(flow_controller_->UpdateSendWindowOffset(2 * send_window_)); 213 EXPECT_FALSE(flow_controller_->IsBlocked()); 214 EXPECT_EQ(send_window_, flow_controller_->SendWindowSize()); 215 flow_controller_->AddBytesSent(send_window_); 216 EXPECT_TRUE(flow_controller_->IsBlocked()); 217 EXPECT_EQ(0u, flow_controller_->SendWindowSize()); 218 219 // BLOCKED frame should get sent as send offset has changed. 220 flow_controller_->MaybeSendBlocked(); 221 } 222 223 } // namespace test 224 } // namespace net 225