Remove PlatformFile from profile_browsertest
[chromium-blink-merge.git] / net / quic / reliable_quic_stream_test.cc
blob9ea4fd6b52da1caf4fe76d79b53346f15a0c6ced
1 // Copyright (c) 2012 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.
5 #include "net/quic/reliable_quic_stream.h"
7 #include "net/quic/quic_ack_notifier.h"
8 #include "net/quic/quic_connection.h"
9 #include "net/quic/quic_utils.h"
10 #include "net/quic/quic_write_blocked_list.h"
11 #include "net/quic/spdy_utils.h"
12 #include "net/quic/test_tools/quic_session_peer.h"
13 #include "net/quic/test_tools/quic_test_utils.h"
14 #include "net/quic/test_tools/reliable_quic_stream_peer.h"
15 #include "net/test/gtest_util.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gmock_mutant.h"
19 using base::StringPiece;
20 using std::min;
21 using testing::_;
22 using testing::CreateFunctor;
23 using testing::InSequence;
24 using testing::Invoke;
25 using testing::Return;
26 using testing::SaveArg;
27 using testing::StrictMock;
28 using testing::WithArgs;
30 namespace net {
31 namespace test {
32 namespace {
34 const char kData1[] = "FooAndBar";
35 const char kData2[] = "EepAndBaz";
36 const size_t kDataLen = 9;
37 const QuicConnectionId kStreamId = 3;
38 const bool kIsServer = true;
39 const bool kShouldProcessData = true;
41 class TestStream : public ReliableQuicStream {
42 public:
43 TestStream(QuicStreamId id,
44 QuicSession* session,
45 bool should_process_data)
46 : ReliableQuicStream(id, session),
47 should_process_data_(should_process_data) {}
49 virtual uint32 ProcessRawData(const char* data, uint32 data_len) OVERRIDE {
50 EXPECT_NE(0u, data_len);
51 DVLOG(1) << "ProcessData data_len: " << data_len;
52 data_ += string(data, data_len);
53 return should_process_data_ ? data_len : 0;
56 virtual QuicPriority EffectivePriority() const OVERRIDE {
57 return QuicUtils::HighestPriority();
60 using ReliableQuicStream::WriteOrBufferData;
61 using ReliableQuicStream::CloseReadSide;
62 using ReliableQuicStream::CloseWriteSide;
63 using ReliableQuicStream::OnClose;
65 private:
66 bool should_process_data_;
67 string data_;
70 class ReliableQuicStreamTest : public ::testing::TestWithParam<bool> {
71 public:
72 ReliableQuicStreamTest() {
73 headers_[":host"] = "www.google.com";
74 headers_[":path"] = "/index.hml";
75 headers_[":scheme"] = "https";
76 headers_["cookie"] =
77 "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; "
78 "__utmc=160408618; "
79 "GX=DQAAAOEAAACWJYdewdE9rIrW6qw3PtVi2-d729qaa-74KqOsM1NVQblK4VhX"
80 "hoALMsy6HOdDad2Sz0flUByv7etmo3mLMidGrBoljqO9hSVA40SLqpG_iuKKSHX"
81 "RW3Np4bq0F0SDGDNsW0DSmTS9ufMRrlpARJDS7qAI6M3bghqJp4eABKZiRqebHT"
82 "pMU-RXvTI5D5oCF1vYxYofH_l1Kviuiy3oQ1kS1enqWgbhJ2t61_SNdv-1XJIS0"
83 "O3YeHLmVCs62O6zp89QwakfAWK9d3IDQvVSJzCQsvxvNIvaZFa567MawWlXg0Rh"
84 "1zFMi5vzcns38-8_Sns; "
85 "GA=v*2%2Fmem*57968640*47239936%2Fmem*57968640*47114716%2Fno-nm-"
86 "yj*15%2Fno-cc-yj*5%2Fpc-ch*133685%2Fpc-s-cr*133947%2Fpc-s-t*1339"
87 "47%2Fno-nm-yj*4%2Fno-cc-yj*1%2Fceft-as*1%2Fceft-nqas*0%2Fad-ra-c"
88 "v_p%2Fad-nr-cv_p-f*1%2Fad-v-cv_p*859%2Fad-ns-cv_p-f*1%2Ffn-v-ad%"
89 "2Fpc-t*250%2Fpc-cm*461%2Fpc-s-cr*722%2Fpc-s-t*722%2Fau_p*4"
90 "SICAID=AJKiYcHdKgxum7KMXG0ei2t1-W4OD1uW-ecNsCqC0wDuAXiDGIcT_HA2o1"
91 "3Rs1UKCuBAF9g8rWNOFbxt8PSNSHFuIhOo2t6bJAVpCsMU5Laa6lewuTMYI8MzdQP"
92 "ARHKyW-koxuhMZHUnGBJAM1gJODe0cATO_KGoX4pbbFxxJ5IicRxOrWK_5rU3cdy6"
93 "edlR9FsEdH6iujMcHkbE5l18ehJDwTWmBKBzVD87naobhMMrF6VvnDGxQVGp9Ir_b"
94 "Rgj3RWUoPumQVCxtSOBdX0GlJOEcDTNCzQIm9BSfetog_eP_TfYubKudt5eMsXmN6"
95 "QnyXHeGeK2UINUzJ-D30AFcpqYgH9_1BvYSpi7fc7_ydBU8TaD8ZRxvtnzXqj0RfG"
96 "tuHghmv3aD-uzSYJ75XDdzKdizZ86IG6Fbn1XFhYZM-fbHhm3mVEXnyRW4ZuNOLFk"
97 "Fas6LMcVC6Q8QLlHYbXBpdNFuGbuZGUnav5C-2I_-46lL0NGg3GewxGKGHvHEfoyn"
98 "EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr"
99 "JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo ";
102 void Initialize(bool stream_should_process_data) {
103 connection_ = new StrictMock<MockConnection>(kIsServer);
104 session_.reset(new StrictMock<MockSession>(connection_));
105 stream_.reset(new TestStream(kStreamId, session_.get(),
106 stream_should_process_data));
107 stream2_.reset(new TestStream(kStreamId + 2, session_.get(),
108 stream_should_process_data));
109 write_blocked_list_ =
110 QuicSessionPeer::GetWriteblockedStreams(session_.get());
113 bool fin_sent() { return ReliableQuicStreamPeer::FinSent(stream_.get()); }
114 bool rst_sent() { return ReliableQuicStreamPeer::RstSent(stream_.get()); }
116 protected:
117 MockConnection* connection_;
118 scoped_ptr<MockSession> session_;
119 scoped_ptr<TestStream> stream_;
120 scoped_ptr<TestStream> stream2_;
121 SpdyHeaderBlock headers_;
122 QuicWriteBlockedList* write_blocked_list_;
125 TEST_F(ReliableQuicStreamTest, WriteAllData) {
126 Initialize(kShouldProcessData);
128 connection_->options()->max_packet_length =
129 1 + QuicPacketCreator::StreamFramePacketOverhead(
130 connection_->version(), PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
131 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
132 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(
133 Return(QuicConsumedData(kDataLen, true)));
134 stream_->WriteOrBufferData(kData1, false, NULL);
135 EXPECT_FALSE(write_blocked_list_->HasWriteBlockedStreams());
138 TEST_F(ReliableQuicStreamTest, NoBlockingIfNoDataOrFin) {
139 Initialize(kShouldProcessData);
141 // Write no data and no fin. If we consume nothing we should not be write
142 // blocked.
143 EXPECT_DFATAL(stream_->WriteOrBufferData(StringPiece(), false, NULL), "");
144 EXPECT_FALSE(write_blocked_list_->HasWriteBlockedStreams());
147 TEST_F(ReliableQuicStreamTest, BlockIfOnlySomeDataConsumed) {
148 Initialize(kShouldProcessData);
150 // Write some data and no fin. If we consume some but not all of the data,
151 // we should be write blocked a not all the data was consumed.
152 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(
153 Return(QuicConsumedData(1, false)));
154 stream_->WriteOrBufferData(StringPiece(kData1, 2), false, NULL);
155 ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams());
159 TEST_F(ReliableQuicStreamTest, BlockIfFinNotConsumedWithData) {
160 Initialize(kShouldProcessData);
162 // Write some data and no fin. If we consume all the data but not the fin,
163 // we should be write blocked because the fin was not consumed.
164 // (This should never actually happen as the fin should be sent out with the
165 // last data)
166 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(
167 Return(QuicConsumedData(2, false)));
168 stream_->WriteOrBufferData(StringPiece(kData1, 2), true, NULL);
169 ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams());
172 TEST_F(ReliableQuicStreamTest, BlockIfSoloFinNotConsumed) {
173 Initialize(kShouldProcessData);
175 // Write no data and a fin. If we consume nothing we should be write blocked,
176 // as the fin was not consumed.
177 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(
178 Return(QuicConsumedData(0, false)));
179 stream_->WriteOrBufferData(StringPiece(), true, NULL);
180 ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams());
183 TEST_F(ReliableQuicStreamTest, WriteOrBufferData) {
184 Initialize(kShouldProcessData);
186 EXPECT_FALSE(write_blocked_list_->HasWriteBlockedStreams());
187 connection_->options()->max_packet_length =
188 1 + QuicPacketCreator::StreamFramePacketOverhead(
189 connection_->version(), PACKET_8BYTE_CONNECTION_ID, !kIncludeVersion,
190 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
191 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).WillOnce(
192 Return(QuicConsumedData(kDataLen - 1, false)));
193 stream_->WriteOrBufferData(kData1, false, NULL);
194 EXPECT_TRUE(write_blocked_list_->HasWriteBlockedStreams());
196 // Queue a bytes_consumed write.
197 stream_->WriteOrBufferData(kData2, false, NULL);
199 // Make sure we get the tail of the first write followed by the bytes_consumed
200 InSequence s;
201 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).
202 WillOnce(Return(QuicConsumedData(1, false)));
203 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).
204 WillOnce(Return(QuicConsumedData(kDataLen - 2, false)));
205 stream_->OnCanWrite();
207 // And finally the end of the bytes_consumed.
208 EXPECT_CALL(*session_, WritevData(_, _, _, _, _)).
209 WillOnce(Return(QuicConsumedData(2, true)));
210 stream_->OnCanWrite();
213 TEST_F(ReliableQuicStreamTest, ConnectionCloseAfterStreamClose) {
214 Initialize(kShouldProcessData);
216 stream_->CloseReadSide();
217 stream_->CloseWriteSide();
218 EXPECT_EQ(QUIC_STREAM_NO_ERROR, stream_->stream_error());
219 EXPECT_EQ(QUIC_NO_ERROR, stream_->connection_error());
220 stream_->OnConnectionClosed(QUIC_INTERNAL_ERROR, false);
221 EXPECT_EQ(QUIC_STREAM_NO_ERROR, stream_->stream_error());
222 EXPECT_EQ(QUIC_NO_ERROR, stream_->connection_error());
225 TEST_F(ReliableQuicStreamTest, RstAlwaysSentIfNoFinSent) {
226 // For flow control accounting, a stream must send either a FIN or a RST frame
227 // before termination.
228 // Test that if no FIN has been sent, we send a RST.
230 Initialize(kShouldProcessData);
231 EXPECT_FALSE(fin_sent());
232 EXPECT_FALSE(rst_sent());
234 // Write some data, with no FIN.
235 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(
236 Return(QuicConsumedData(1, false)));
237 stream_->WriteOrBufferData(StringPiece(kData1, 1), false, NULL);
238 EXPECT_FALSE(fin_sent());
239 EXPECT_FALSE(rst_sent());
241 // Now close the stream, and expect that we send a RST.
242 EXPECT_CALL(*session_, SendRstStream(_, _, _));
243 stream_->OnClose();
244 EXPECT_FALSE(fin_sent());
245 EXPECT_TRUE(rst_sent());
248 TEST_F(ReliableQuicStreamTest, RstNotSentIfFinSent) {
249 // For flow control accounting, a stream must send either a FIN or a RST frame
250 // before termination.
251 // Test that if a FIN has been sent, we don't also send a RST.
253 Initialize(kShouldProcessData);
254 EXPECT_FALSE(fin_sent());
255 EXPECT_FALSE(rst_sent());
257 // Write some data, with FIN.
258 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(
259 Return(QuicConsumedData(1, true)));
260 stream_->WriteOrBufferData(StringPiece(kData1, 1), true, NULL);
261 EXPECT_TRUE(fin_sent());
262 EXPECT_FALSE(rst_sent());
264 // Now close the stream, and expect that we do not send a RST.
265 stream_->OnClose();
266 EXPECT_TRUE(fin_sent());
267 EXPECT_FALSE(rst_sent());
270 TEST_F(ReliableQuicStreamTest, OnlySendOneRst) {
271 // For flow control accounting, a stream must send either a FIN or a RST frame
272 // before termination.
273 // Test that if a stream sends a RST, it doesn't send an additional RST during
274 // OnClose() (this shouldn't be harmful, but we shouldn't do it anyway...)
276 Initialize(kShouldProcessData);
277 EXPECT_FALSE(fin_sent());
278 EXPECT_FALSE(rst_sent());
280 // Reset the stream.
281 const int expected_resets = 1;
282 EXPECT_CALL(*session_, SendRstStream(_, _, _)).Times(expected_resets);
283 stream_->Reset(QUIC_STREAM_CANCELLED);
284 EXPECT_FALSE(fin_sent());
285 EXPECT_TRUE(rst_sent());
287 // Now close the stream (any further resets being sent would break the
288 // expectation above).
289 stream_->OnClose();
290 EXPECT_FALSE(fin_sent());
291 EXPECT_TRUE(rst_sent());
294 void SaveProxyAckNotifierDelegate(
295 scoped_refptr<QuicAckNotifier::DelegateInterface>* delegate_out,
296 QuicAckNotifier::DelegateInterface* delegate) {
297 *delegate_out = delegate;
299 TEST_F(ReliableQuicStreamTest, WriteOrBufferDataWithQuicAckNotifier) {
300 Initialize(kShouldProcessData);
302 scoped_refptr<MockAckNotifierDelegate> delegate(
303 new StrictMock<MockAckNotifierDelegate>);
305 const int kDataSize = 16 * 1024;
306 const string kData(kDataSize, 'a');
308 const int kFirstWriteSize = 100;
309 const int kSecondWriteSize = 50;
310 const int kLastWriteSize = kDataSize - kFirstWriteSize - kSecondWriteSize;
312 scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate;
314 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(DoAll(
315 WithArgs<4>(Invoke(CreateFunctor(
316 &SaveProxyAckNotifierDelegate, &proxy_delegate))),
317 Return(QuicConsumedData(kFirstWriteSize, false))));
318 stream_->WriteOrBufferData(kData, false, delegate.get());
319 EXPECT_TRUE(write_blocked_list_->HasWriteBlockedStreams());
321 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, proxy_delegate.get())).
322 WillOnce(
323 Return(QuicConsumedData(kSecondWriteSize, false)));
324 stream_->OnCanWrite();
326 // No ack expected for an empty write.
327 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, proxy_delegate.get())).
328 WillOnce(
329 Return(QuicConsumedData(0, false)));
330 stream_->OnCanWrite();
332 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, proxy_delegate.get())).
333 WillOnce(
334 Return(QuicConsumedData(kLastWriteSize, false)));
335 stream_->OnCanWrite();
337 // There were two writes, so OnAckNotification is not propagated
338 // until the third Ack arrives.
339 proxy_delegate->OnAckNotification(1, 2, 3, 4);
340 proxy_delegate->OnAckNotification(10, 20, 30, 40);
342 // The arguments to delegate->OnAckNotification are the sum of the
343 // arguments to proxy_delegate OnAckNotification calls.
344 EXPECT_CALL(*delegate, OnAckNotification(111, 222, 333, 444));
345 proxy_delegate->OnAckNotification(100, 200, 300, 400);
348 // Verify delegate behavior when packets are acked before the
349 // WritevData call that sends out the last byte.
350 TEST_F(ReliableQuicStreamTest, WriteOrBufferDataAckNotificationBeforeFlush) {
351 Initialize(kShouldProcessData);
353 scoped_refptr<MockAckNotifierDelegate> delegate(
354 new StrictMock<MockAckNotifierDelegate>);
356 const int kDataSize = 16 * 1024;
357 const string kData(kDataSize, 'a');
359 const int kInitialWriteSize = 100;
361 scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate;
363 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(DoAll(
364 WithArgs<4>(Invoke(CreateFunctor(
365 &SaveProxyAckNotifierDelegate, &proxy_delegate))),
366 Return(QuicConsumedData(kInitialWriteSize, false))));
367 stream_->WriteOrBufferData(kData, false, delegate.get());
368 EXPECT_TRUE(write_blocked_list_->HasWriteBlockedStreams());
370 // Handle the ack of the first write.
371 proxy_delegate->OnAckNotification(1, 2, 3, 4);
372 proxy_delegate = NULL;
374 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(DoAll(
375 WithArgs<4>(Invoke(CreateFunctor(
376 &SaveProxyAckNotifierDelegate, &proxy_delegate))),
377 Return(QuicConsumedData(kDataSize - kInitialWriteSize, false))));
378 stream_->OnCanWrite();
380 // Handle the ack for the second write.
381 EXPECT_CALL(*delegate, OnAckNotification(101, 202, 303, 404));
382 proxy_delegate->OnAckNotification(100, 200, 300, 400);
385 // Verify delegate behavior when WriteOrBufferData does not buffer.
386 TEST_F(ReliableQuicStreamTest, WriteAndBufferDataWithAckNotiferNoBuffer) {
387 Initialize(kShouldProcessData);
389 scoped_refptr<MockAckNotifierDelegate> delegate(
390 new StrictMock<MockAckNotifierDelegate>);
392 scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate;
394 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(DoAll(
395 WithArgs<4>(Invoke(CreateFunctor(
396 &SaveProxyAckNotifierDelegate, &proxy_delegate))),
397 Return(QuicConsumedData(kDataLen, true))));
398 stream_->WriteOrBufferData(kData1, true, delegate.get());
399 EXPECT_FALSE(write_blocked_list_->HasWriteBlockedStreams());
401 // Handle the ack.
402 EXPECT_CALL(*delegate, OnAckNotification(1, 2, 3, 4));
403 proxy_delegate->OnAckNotification(1, 2, 3, 4);
406 // Verify delegate behavior when WriteOrBufferData buffers all the data.
407 TEST_F(ReliableQuicStreamTest, BufferOnWriteAndBufferDataWithAckNotifer) {
408 Initialize(kShouldProcessData);
410 scoped_refptr<MockAckNotifierDelegate> delegate(
411 new StrictMock<MockAckNotifierDelegate>);
413 scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate;
415 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(
416 Return(QuicConsumedData(0, false)));
417 stream_->WriteOrBufferData(kData1, true, delegate.get());
418 EXPECT_TRUE(write_blocked_list_->HasWriteBlockedStreams());
420 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(DoAll(
421 WithArgs<4>(Invoke(CreateFunctor(
422 &SaveProxyAckNotifierDelegate, &proxy_delegate))),
423 Return(QuicConsumedData(kDataLen, true))));
424 stream_->OnCanWrite();
426 // Handle the ack.
427 EXPECT_CALL(*delegate, OnAckNotification(1, 2, 3, 4));
428 proxy_delegate->OnAckNotification(1, 2, 3, 4);
431 // Verify delegate behavior when WriteOrBufferData when the FIN is
432 // sent out in a different packet.
433 TEST_F(ReliableQuicStreamTest, WriteAndBufferDataWithAckNotiferOnlyFinRemains) {
434 Initialize(kShouldProcessData);
436 scoped_refptr<MockAckNotifierDelegate> delegate(
437 new StrictMock<MockAckNotifierDelegate>);
439 scoped_refptr<QuicAckNotifier::DelegateInterface> proxy_delegate;
441 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(DoAll(
442 WithArgs<4>(Invoke(CreateFunctor(
443 &SaveProxyAckNotifierDelegate, &proxy_delegate))),
444 Return(QuicConsumedData(kDataLen, false))));
445 stream_->WriteOrBufferData(kData1, true, delegate.get());
446 EXPECT_TRUE(write_blocked_list_->HasWriteBlockedStreams());
448 EXPECT_CALL(*session_, WritevData(kStreamId, _, _, _, _)).WillOnce(DoAll(
449 WithArgs<4>(Invoke(CreateFunctor(
450 &SaveProxyAckNotifierDelegate, &proxy_delegate))),
451 Return(QuicConsumedData(0, true))));
452 stream_->OnCanWrite();
454 // Handle the acks.
455 proxy_delegate->OnAckNotification(1, 2, 3, 4);
456 EXPECT_CALL(*delegate, OnAckNotification(11, 22, 33, 44));
457 proxy_delegate->OnAckNotification(10, 20, 30, 40);
460 } // namespace
461 } // namespace test
462 } // namespace net