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