1// Copyright 2013 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_data_stream.h"
6
7#include "net/quic/quic_ack_notifier.h"
8#include "net/quic/quic_connection.h"
9#include "net/quic/quic_flags.h"
10#include "net/quic/quic_utils.h"
11#include "net/quic/quic_write_blocked_list.h"
12#include "net/quic/spdy_utils.h"
13#include "net/quic/test_tools/quic_flow_controller_peer.h"
14#include "net/quic/test_tools/quic_session_peer.h"
15#include "net/quic/test_tools/quic_test_utils.h"
16#include "net/quic/test_tools/reliable_quic_stream_peer.h"
17#include "net/test/gtest_util.h"
18#include "testing/gmock/include/gmock/gmock.h"
19
20using base::StringPiece;
21using std::min;
22using testing::AnyNumber;
23using testing::InSequence;
24using testing::Return;
25using testing::SaveArg;
26using testing::StrictMock;
27using testing::_;
28
29namespace net {
30namespace test {
31namespace {
32
33const bool kIsServer = true;
34const bool kShouldProcessData = true;
35
36class TestStream : public QuicDataStream {
37 public:
38  TestStream(QuicStreamId id,
39             QuicSession* session,
40             bool should_process_data)
41      : QuicDataStream(id, session),
42        should_process_data_(should_process_data) {}
43
44  virtual uint32 ProcessData(const char* data, uint32 data_len) OVERRIDE {
45    EXPECT_NE(0u, data_len);
46    DVLOG(1) << "ProcessData data_len: " << data_len;
47    data_ += string(data, data_len);
48    return should_process_data_ ? data_len : 0;
49  }
50
51  using ReliableQuicStream::WriteOrBufferData;
52  using ReliableQuicStream::CloseReadSide;
53  using ReliableQuicStream::CloseWriteSide;
54
55  const string& data() const { return data_; }
56
57 private:
58  bool should_process_data_;
59  string data_;
60};
61
62class QuicDataStreamTest : public ::testing::TestWithParam<QuicVersion> {
63 public:
64  QuicDataStreamTest() {
65    headers_[":host"] = "www.google.com";
66    headers_[":path"] = "/index.hml";
67    headers_[":scheme"] = "https";
68    headers_["cookie"] =
69        "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; "
70        "__utmc=160408618; "
71        "GX=DQAAAOEAAACWJYdewdE9rIrW6qw3PtVi2-d729qaa-74KqOsM1NVQblK4VhX"
72        "hoALMsy6HOdDad2Sz0flUByv7etmo3mLMidGrBoljqO9hSVA40SLqpG_iuKKSHX"
73        "RW3Np4bq0F0SDGDNsW0DSmTS9ufMRrlpARJDS7qAI6M3bghqJp4eABKZiRqebHT"
74        "pMU-RXvTI5D5oCF1vYxYofH_l1Kviuiy3oQ1kS1enqWgbhJ2t61_SNdv-1XJIS0"
75        "O3YeHLmVCs62O6zp89QwakfAWK9d3IDQvVSJzCQsvxvNIvaZFa567MawWlXg0Rh"
76        "1zFMi5vzcns38-8_Sns; "
77        "GA=v*2%2Fmem*57968640*47239936%2Fmem*57968640*47114716%2Fno-nm-"
78        "yj*15%2Fno-cc-yj*5%2Fpc-ch*133685%2Fpc-s-cr*133947%2Fpc-s-t*1339"
79        "47%2Fno-nm-yj*4%2Fno-cc-yj*1%2Fceft-as*1%2Fceft-nqas*0%2Fad-ra-c"
80        "v_p%2Fad-nr-cv_p-f*1%2Fad-v-cv_p*859%2Fad-ns-cv_p-f*1%2Ffn-v-ad%"
81        "2Fpc-t*250%2Fpc-cm*461%2Fpc-s-cr*722%2Fpc-s-t*722%2Fau_p*4"
82        "SICAID=AJKiYcHdKgxum7KMXG0ei2t1-W4OD1uW-ecNsCqC0wDuAXiDGIcT_HA2o1"
83        "3Rs1UKCuBAF9g8rWNOFbxt8PSNSHFuIhOo2t6bJAVpCsMU5Laa6lewuTMYI8MzdQP"
84        "ARHKyW-koxuhMZHUnGBJAM1gJODe0cATO_KGoX4pbbFxxJ5IicRxOrWK_5rU3cdy6"
85        "edlR9FsEdH6iujMcHkbE5l18ehJDwTWmBKBzVD87naobhMMrF6VvnDGxQVGp9Ir_b"
86        "Rgj3RWUoPumQVCxtSOBdX0GlJOEcDTNCzQIm9BSfetog_eP_TfYubKudt5eMsXmN6"
87        "QnyXHeGeK2UINUzJ-D30AFcpqYgH9_1BvYSpi7fc7_ydBU8TaD8ZRxvtnzXqj0RfG"
88        "tuHghmv3aD-uzSYJ75XDdzKdizZ86IG6Fbn1XFhYZM-fbHhm3mVEXnyRW4ZuNOLFk"
89        "Fas6LMcVC6Q8QLlHYbXBpdNFuGbuZGUnav5C-2I_-46lL0NGg3GewxGKGHvHEfoyn"
90        "EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr"
91        "JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo ";
92  }
93
94  void Initialize(bool stream_should_process_data) {
95    connection_ = new testing::StrictMock<MockConnection>(
96        kIsServer, SupportedVersions(GetParam()));
97    session_.reset(new testing::StrictMock<MockSession>(connection_));
98    stream_.reset(new TestStream(kClientDataStreamId1, session_.get(),
99                                 stream_should_process_data));
100    stream2_.reset(new TestStream(kClientDataStreamId2, session_.get(),
101                                  stream_should_process_data));
102    write_blocked_list_ =
103        QuicSessionPeer::GetWriteBlockedStreams(session_.get());
104  }
105
106 protected:
107  MockConnection* connection_;
108  scoped_ptr<MockSession> session_;
109  scoped_ptr<TestStream> stream_;
110  scoped_ptr<TestStream> stream2_;
111  SpdyHeaderBlock headers_;
112  QuicWriteBlockedList* write_blocked_list_;
113};
114
115INSTANTIATE_TEST_CASE_P(Tests, QuicDataStreamTest,
116                        ::testing::ValuesIn(QuicSupportedVersions()));
117
118TEST_P(QuicDataStreamTest, ProcessHeaders) {
119  Initialize(kShouldProcessData);
120
121  string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
122  stream_->OnStreamHeadersPriority(QuicUtils::HighestPriority());
123  stream_->OnStreamHeaders(headers);
124  EXPECT_EQ(headers, stream_->data());
125  stream_->OnStreamHeadersComplete(false, headers.size());
126  EXPECT_EQ(QuicUtils::HighestPriority(), stream_->EffectivePriority());
127  EXPECT_EQ(headers, stream_->data());
128  EXPECT_FALSE(stream_->IsDoneReading());
129}
130
131TEST_P(QuicDataStreamTest, ProcessHeadersAndBody) {
132  Initialize(kShouldProcessData);
133
134  string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
135  string body = "this is the body";
136
137  stream_->OnStreamHeaders(headers);
138  EXPECT_EQ(headers, stream_->data());
139  stream_->OnStreamHeadersComplete(false, headers.size());
140  QuicStreamFrame frame(kClientDataStreamId1, false, 0, MakeIOVector(body));
141  stream_->OnStreamFrame(frame);
142
143  EXPECT_EQ(headers + body, stream_->data());
144}
145
146TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyFragments) {
147  string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
148  string body = "this is the body";
149
150  for (size_t fragment_size = 1; fragment_size < body.size();
151       ++fragment_size) {
152    Initialize(kShouldProcessData);
153    for (size_t offset = 0; offset < headers.size();
154         offset += fragment_size) {
155      size_t remaining_data = headers.size() - offset;
156      StringPiece fragment(headers.data() + offset,
157                           min(fragment_size, remaining_data));
158      stream_->OnStreamHeaders(fragment);
159    }
160    stream_->OnStreamHeadersComplete(false, headers.size());
161    for (size_t offset = 0; offset < body.size(); offset += fragment_size) {
162      size_t remaining_data = body.size() - offset;
163      StringPiece fragment(body.data() + offset,
164                           min(fragment_size, remaining_data));
165      QuicStreamFrame frame(kClientDataStreamId1, false, offset,
166                            MakeIOVector(fragment));
167      stream_->OnStreamFrame(frame);
168    }
169    ASSERT_EQ(headers + body,
170              stream_->data()) << "fragment_size: " << fragment_size;
171  }
172}
173
174TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyFragmentsSplit) {
175  string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
176  string body = "this is the body";
177
178  for (size_t split_point = 1; split_point < body.size() - 1; ++split_point) {
179    Initialize(kShouldProcessData);
180    StringPiece headers1(headers.data(), split_point);
181    stream_->OnStreamHeaders(headers1);
182
183    StringPiece headers2(headers.data() + split_point,
184                         headers.size() - split_point);
185    stream_->OnStreamHeaders(headers2);
186    stream_->OnStreamHeadersComplete(false, headers.size());
187
188    StringPiece fragment1(body.data(), split_point);
189    QuicStreamFrame frame1(kClientDataStreamId1, false, 0,
190                           MakeIOVector(fragment1));
191    stream_->OnStreamFrame(frame1);
192
193    StringPiece fragment2(body.data() + split_point,
194                          body.size() - split_point);
195    QuicStreamFrame frame2(kClientDataStreamId1, false, split_point,
196                           MakeIOVector(fragment2));
197    stream_->OnStreamFrame(frame2);
198
199    ASSERT_EQ(headers + body,
200              stream_->data()) << "split_point: " << split_point;
201  }
202}
203
204TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyReadv) {
205  Initialize(!kShouldProcessData);
206
207  string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
208  string body = "this is the body";
209
210  stream_->OnStreamHeaders(headers);
211  EXPECT_EQ(headers, stream_->data());
212  stream_->OnStreamHeadersComplete(false, headers.size());
213  QuicStreamFrame frame(kClientDataStreamId1, false, 0, MakeIOVector(body));
214  stream_->OnStreamFrame(frame);
215
216  char buffer[2048];
217  ASSERT_LT(headers.length() + body.length(), arraysize(buffer));
218  struct iovec vec;
219  vec.iov_base = buffer;
220  vec.iov_len = arraysize(buffer);
221
222  size_t bytes_read = stream_->Readv(&vec, 1);
223  EXPECT_EQ(headers.length(), bytes_read);
224  EXPECT_EQ(headers, string(buffer, bytes_read));
225
226  bytes_read = stream_->Readv(&vec, 1);
227  EXPECT_EQ(body.length(), bytes_read);
228  EXPECT_EQ(body, string(buffer, bytes_read));
229}
230
231TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyIncrementalReadv) {
232  Initialize(!kShouldProcessData);
233
234  string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
235  string body = "this is the body";
236  stream_->OnStreamHeaders(headers);
237  EXPECT_EQ(headers, stream_->data());
238  stream_->OnStreamHeadersComplete(false, headers.size());
239  QuicStreamFrame frame(kClientDataStreamId1, false, 0, MakeIOVector(body));
240  stream_->OnStreamFrame(frame);
241
242  char buffer[1];
243  struct iovec vec;
244  vec.iov_base = buffer;
245  vec.iov_len = arraysize(buffer);
246
247  string data = headers + body;
248  for (size_t i = 0; i < data.length(); ++i) {
249    size_t bytes_read = stream_->Readv(&vec, 1);
250    ASSERT_EQ(1u, bytes_read);
251    EXPECT_EQ(data.data()[i], buffer[0]);
252  }
253}
254
255TEST_P(QuicDataStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) {
256  Initialize(!kShouldProcessData);
257
258  string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
259  string body = "this is the body";
260  stream_->OnStreamHeaders(headers);
261  EXPECT_EQ(headers, stream_->data());
262  stream_->OnStreamHeadersComplete(false, headers.size());
263  QuicStreamFrame frame(kClientDataStreamId1, false, 0, MakeIOVector(body));
264  stream_->OnStreamFrame(frame);
265
266  char buffer1[1];
267  char buffer2[1];
268  struct iovec vec[2];
269  vec[0].iov_base = buffer1;
270  vec[0].iov_len = arraysize(buffer1);
271  vec[1].iov_base = buffer2;
272  vec[1].iov_len = arraysize(buffer2);
273  string data = headers + body;
274  for (size_t i = 0; i < data.length(); i += 2) {
275    size_t bytes_read = stream_->Readv(vec, 2);
276    ASSERT_EQ(2u, bytes_read) << i;
277    ASSERT_EQ(data.data()[i], buffer1[0]) << i;
278    ASSERT_EQ(data.data()[i + 1], buffer2[0]) << i;
279  }
280}
281
282TEST_P(QuicDataStreamTest, StreamFlowControlBlocked) {
283  // Tests that we send a BLOCKED frame to the peer when we attempt to write,
284  // but are flow control blocked.
285  if (GetParam() < QUIC_VERSION_17) {
286    return;
287  }
288  ValueRestore<bool> old_flag(&FLAGS_enable_quic_stream_flow_control_2, true);
289
290  Initialize(kShouldProcessData);
291
292  // Set a small flow control limit.
293  const uint64 kWindow = 36;
294  QuicFlowControllerPeer::SetSendWindowOffset(stream_->flow_controller(),
295                                              kWindow);
296  EXPECT_EQ(kWindow, QuicFlowControllerPeer::SendWindowOffset(
297                         stream_->flow_controller()));
298
299  // Try to send more data than the flow control limit allows.
300  string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
301  string body;
302  const uint64 kOverflow = 15;
303  GenerateBody(&body, kWindow + kOverflow);
304
305  EXPECT_CALL(*connection_, SendBlocked(kClientDataStreamId1));
306  EXPECT_CALL(*session_, WritevData(kClientDataStreamId1, _, _, _, _, _))
307      .WillOnce(Return(QuicConsumedData(kWindow, true)));
308  stream_->WriteOrBufferData(body, false, NULL);
309
310  // Should have sent as much as possible, resulting in no send window left.
311  EXPECT_EQ(0u,
312            QuicFlowControllerPeer::SendWindowSize(stream_->flow_controller()));
313
314  // And we should have queued the overflowed data.
315  EXPECT_EQ(kOverflow,
316            ReliableQuicStreamPeer::SizeOfQueuedData(stream_.get()));
317}
318
319TEST_P(QuicDataStreamTest, StreamFlowControlNoWindowUpdateIfNotConsumed) {
320  // The flow control receive window decreases whenever we add new bytes to the
321  // sequencer, whether they are consumed immediately or buffered. However we
322  // only send WINDOW_UPDATE frames based on increasing number of bytes
323  // consumed.
324  if (GetParam() < QUIC_VERSION_17) {
325    return;
326  }
327  ValueRestore<bool> old_flag(&FLAGS_enable_quic_stream_flow_control_2, true);
328
329  // Don't process data - it will be buffered instead.
330  Initialize(!kShouldProcessData);
331
332  // Expect no WINDOW_UPDATE frames to be sent.
333  EXPECT_CALL(*connection_, SendWindowUpdate(_, _)).Times(0);
334
335  // Set a small flow control receive window.
336  const uint64 kWindow = 36;
337  QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(),
338                                                 kWindow);
339  QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(),
340                                              kWindow);
341  EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowOffset(
342                         stream_->flow_controller()));
343
344  // Stream receives enough data to fill a fraction of the receive window.
345  string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
346  string body;
347  GenerateBody(&body, kWindow / 3);
348  stream_->OnStreamHeaders(headers);
349  EXPECT_EQ(headers, stream_->data());
350  stream_->OnStreamHeadersComplete(false, headers.size());
351
352  QuicStreamFrame frame1(kClientDataStreamId1, false, 0, MakeIOVector(body));
353  stream_->OnStreamFrame(frame1);
354  EXPECT_EQ(kWindow - (kWindow / 3), QuicFlowControllerPeer::ReceiveWindowSize(
355                                         stream_->flow_controller()));
356
357  // Now receive another frame which results in the receive window being over
358  // half full. This should all be buffered, decreasing the receive window but
359  // not sending WINDOW_UPDATE.
360  QuicStreamFrame frame2(kClientDataStreamId1, false, kWindow / 3,
361                         MakeIOVector(body));
362  stream_->OnStreamFrame(frame2);
363  EXPECT_EQ(
364      kWindow - (2 * kWindow / 3),
365      QuicFlowControllerPeer::ReceiveWindowSize(stream_->flow_controller()));
366}
367
368TEST_P(QuicDataStreamTest, StreamFlowControlWindowUpdate) {
369  // Tests that on receipt of data, the stream updates its receive window offset
370  // appropriately, and sends WINDOW_UPDATE frames when its receive window drops
371  // too low.
372  if (GetParam() < QUIC_VERSION_17) {
373    return;
374  }
375  ValueRestore<bool> old_flag(&FLAGS_enable_quic_stream_flow_control_2, true);
376
377  Initialize(kShouldProcessData);
378
379  // Set a small flow control limit.
380  const uint64 kWindow = 36;
381  QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(),
382                                                 kWindow);
383  QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(),
384                                              kWindow);
385  EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowOffset(
386                         stream_->flow_controller()));
387
388  // Stream receives enough data to fill a fraction of the receive window.
389  string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
390  string body;
391  GenerateBody(&body, kWindow / 3);
392  stream_->OnStreamHeaders(headers);
393  EXPECT_EQ(headers, stream_->data());
394  stream_->OnStreamHeadersComplete(false, headers.size());
395
396  QuicStreamFrame frame1(kClientDataStreamId1, false, 0, MakeIOVector(body));
397  stream_->OnStreamFrame(frame1);
398  EXPECT_EQ(kWindow - (kWindow / 3), QuicFlowControllerPeer::ReceiveWindowSize(
399                                         stream_->flow_controller()));
400
401  // Now receive another frame which results in the receive window being over
402  // half full.  This will trigger the stream to increase its receive window
403  // offset and send a WINDOW_UPDATE. The result will be again an available
404  // window of kWindow bytes.
405  QuicStreamFrame frame2(kClientDataStreamId1, false, kWindow / 3,
406                         MakeIOVector(body));
407  EXPECT_CALL(*connection_,
408              SendWindowUpdate(kClientDataStreamId1,
409                               QuicFlowControllerPeer::ReceiveWindowOffset(
410                                   stream_->flow_controller()) +
411                                   2 * kWindow / 3));
412  stream_->OnStreamFrame(frame2);
413  EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowSize(
414                         stream_->flow_controller()));
415}
416
417TEST_P(QuicDataStreamTest, ConnectionFlowControlWindowUpdate) {
418  // Tests that on receipt of data, the connection updates its receive window
419  // offset appropriately, and sends WINDOW_UPDATE frames when its receive
420  // window drops too low.
421  if (GetParam() < QUIC_VERSION_19) {
422    return;
423  }
424  ValueRestore<bool> old_flag2(&FLAGS_enable_quic_stream_flow_control_2, true);
425  ValueRestore<bool> old_flag(&FLAGS_enable_quic_connection_flow_control_2,
426                              true);
427
428  Initialize(kShouldProcessData);
429
430  // Set a small flow control limit for streams and connection.
431  const uint64 kWindow = 36;
432  QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(),
433                                                 kWindow);
434  QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(),
435                                              kWindow);
436  QuicFlowControllerPeer::SetReceiveWindowOffset(stream2_->flow_controller(),
437                                                 kWindow);
438  QuicFlowControllerPeer::SetMaxReceiveWindow(stream2_->flow_controller(),
439                                              kWindow);
440  QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(),
441                                                 kWindow);
442  QuicFlowControllerPeer::SetMaxReceiveWindow(session_->flow_controller(),
443                                              kWindow);
444
445  // Supply headers to both streams so that they are happy to receive data.
446  string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
447  stream_->OnStreamHeaders(headers);
448  stream_->OnStreamHeadersComplete(false, headers.size());
449  stream2_->OnStreamHeaders(headers);
450  stream2_->OnStreamHeadersComplete(false, headers.size());
451
452  // Each stream gets a quarter window of data. This should not trigger a
453  // WINDOW_UPDATE for either stream, nor for the connection.
454  string body;
455  GenerateBody(&body, kWindow / 4);
456  QuicStreamFrame frame1(kClientDataStreamId1, false, 0, MakeIOVector(body));
457  stream_->OnStreamFrame(frame1);
458  QuicStreamFrame frame2(kClientDataStreamId2, false, 0, MakeIOVector(body));
459  stream2_->OnStreamFrame(frame2);
460
461  // Now receive a further single byte on one stream - again this does not
462  // trigger a stream WINDOW_UPDATE, but now the connection flow control window
463  // is over half full and thus a connection WINDOW_UPDATE is sent.
464  EXPECT_CALL(*connection_, SendWindowUpdate(kClientDataStreamId1, _)).Times(0);
465  EXPECT_CALL(*connection_, SendWindowUpdate(kClientDataStreamId2, _)).Times(0);
466  EXPECT_CALL(*connection_,
467              SendWindowUpdate(0, QuicFlowControllerPeer::ReceiveWindowOffset(
468                                      session_->flow_controller()) +
469                                      1 + kWindow / 2));
470  QuicStreamFrame frame3(kClientDataStreamId1, false, (kWindow / 4),
471                         MakeIOVector("a"));
472  stream_->OnStreamFrame(frame3);
473}
474
475TEST_P(QuicDataStreamTest, StreamFlowControlViolation) {
476  // Tests that on if the peer sends too much data (i.e. violates the flow
477  // control protocol), then we terminate the connection.
478  if (GetParam() < QUIC_VERSION_17) {
479    return;
480  }
481  ValueRestore<bool> old_flag(&FLAGS_enable_quic_stream_flow_control_2, true);
482
483  // Stream should not process data, so that data gets buffered in the
484  // sequencer, triggering flow control limits.
485  Initialize(!kShouldProcessData);
486
487  // Set a small flow control limit.
488  const uint64 kWindow = 50;
489  QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(),
490                                                 kWindow);
491
492  string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
493  stream_->OnStreamHeaders(headers);
494  EXPECT_EQ(headers, stream_->data());
495  stream_->OnStreamHeadersComplete(false, headers.size());
496
497  // Receive data to overflow the window, violating flow control.
498  string body;
499  GenerateBody(&body, kWindow + 1);
500  QuicStreamFrame frame(kClientDataStreamId1, false, 0, MakeIOVector(body));
501  EXPECT_CALL(*connection_,
502              SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA));
503  stream_->OnStreamFrame(frame);
504}
505
506TEST_P(QuicDataStreamTest, ConnectionFlowControlViolation) {
507  // Tests that on if the peer sends too much data (i.e. violates the flow
508  // control protocol), at the connection level (rather than the stream level)
509  // then we terminate the connection.
510  if (GetParam() < QUIC_VERSION_19) {
511    return;
512  }
513  ValueRestore<bool> old_flag2(&FLAGS_enable_quic_stream_flow_control_2, true);
514  ValueRestore<bool> old_flag(&FLAGS_enable_quic_connection_flow_control_2,
515                              true);
516
517  // Stream should not process data, so that data gets buffered in the
518  // sequencer, triggering flow control limits.
519  Initialize(!kShouldProcessData);
520
521  // Set a small flow control window on streams, and connection.
522  const uint64 kStreamWindow = 50;
523  const uint64 kConnectionWindow = 10;
524  QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(),
525                                                 kStreamWindow);
526  QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(),
527                                                 kConnectionWindow);
528
529  string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
530  stream_->OnStreamHeaders(headers);
531  EXPECT_EQ(headers, stream_->data());
532  stream_->OnStreamHeadersComplete(false, headers.size());
533
534  // Send enough data to overflow the connection level flow control window.
535  string body;
536  GenerateBody(&body, kConnectionWindow + 1);
537  EXPECT_LT(body.size(),  kStreamWindow);
538  QuicStreamFrame frame(kClientDataStreamId1, false, 0, MakeIOVector(body));
539
540  EXPECT_CALL(*connection_,
541              SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA));
542  stream_->OnStreamFrame(frame);
543}
544
545TEST_P(QuicDataStreamTest, StreamFlowControlFinNotBlocked) {
546  // An attempt to write a FIN with no data should not be flow control blocked,
547  // even if the send window is 0.
548  if (GetParam() < QUIC_VERSION_17) {
549    return;
550  }
551  ValueRestore<bool> old_flag(&FLAGS_enable_quic_stream_flow_control_2, true);
552
553  Initialize(kShouldProcessData);
554
555  // Set a flow control limit of zero.
556  QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), 0);
557  EXPECT_EQ(0u, QuicFlowControllerPeer::ReceiveWindowOffset(
558                    stream_->flow_controller()));
559
560  // Send a frame with a FIN but no data. This should not be blocked.
561  string body = "";
562  bool fin = true;
563
564  EXPECT_CALL(*connection_, SendBlocked(kClientDataStreamId1)).Times(0);
565  EXPECT_CALL(*session_, WritevData(kClientDataStreamId1, _, _, _, _, _))
566      .WillOnce(Return(QuicConsumedData(0, fin)));
567
568  stream_->WriteOrBufferData(body, fin, NULL);
569}
570
571}  // namespace
572}  // namespace test
573}  // namespace net
574