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