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