Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(754)

Side by Side Diff: net/quic/reliable_quic_stream_test.cc

Issue 103973007: Land Recent QUIC Changes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix for android compile error Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/quic/reliable_quic_stream.cc ('k') | net/quic/test_tools/mock_random.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/quic/reliable_quic_stream.h" 5 #include "net/quic/reliable_quic_stream.h"
6 6
7 #include "net/quic/quic_ack_notifier.h" 7 #include "net/quic/quic_ack_notifier.h"
8 #include "net/quic/quic_connection.h" 8 #include "net/quic/quic_connection.h"
9 #include "net/quic/quic_spdy_compressor.h" 9 #include "net/quic/quic_spdy_compressor.h"
10 #include "net/quic/quic_spdy_decompressor.h" 10 #include "net/quic/quic_spdy_decompressor.h"
(...skipping 25 matching lines...) Expand all
36 const bool kShouldProcessData = true; 36 const bool kShouldProcessData = true;
37 37
38 class TestStream : public ReliableQuicStream { 38 class TestStream : public ReliableQuicStream {
39 public: 39 public:
40 TestStream(QuicStreamId id, 40 TestStream(QuicStreamId id,
41 QuicSession* session, 41 QuicSession* session,
42 bool should_process_data) 42 bool should_process_data)
43 : ReliableQuicStream(id, session), 43 : ReliableQuicStream(id, session),
44 should_process_data_(should_process_data) {} 44 should_process_data_(should_process_data) {}
45 45
46 virtual uint32 ProcessData(const char* data, uint32 data_len) OVERRIDE { 46 virtual uint32 ProcessRawData(const char* data, uint32 data_len) OVERRIDE {
47 EXPECT_NE(0u, data_len); 47 EXPECT_NE(0u, data_len);
48 DVLOG(1) << "ProcessData data_len: " << data_len; 48 DVLOG(1) << "ProcessData data_len: " << data_len;
49 data_ += string(data, data_len); 49 data_ += string(data, data_len);
50 return should_process_data_ ? data_len : 0; 50 return should_process_data_ ? data_len : 0;
51 } 51 }
52 52
53 using ReliableQuicStream::WriteData; 53 virtual QuicPriority EffectivePriority() const OVERRIDE { return 0; }
54
55 using ReliableQuicStream::WriteOrBufferData;
54 using ReliableQuicStream::CloseReadSide; 56 using ReliableQuicStream::CloseReadSide;
55 using ReliableQuicStream::CloseWriteSide; 57 using ReliableQuicStream::CloseWriteSide;
56 58
57 const string& data() const { return data_; } 59 const string& data() const { return data_; }
58 60
59 private: 61 private:
60 bool should_process_data_; 62 bool should_process_data_;
61 string data_; 63 string data_;
62 }; 64 };
63 65
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 123
122 TEST_F(ReliableQuicStreamTest, WriteAllData) { 124 TEST_F(ReliableQuicStreamTest, WriteAllData) {
123 Initialize(kShouldProcessData); 125 Initialize(kShouldProcessData);
124 126
125 connection_->options()->max_packet_length = 127 connection_->options()->max_packet_length =
126 1 + QuicPacketCreator::StreamFramePacketOverhead( 128 1 + QuicPacketCreator::StreamFramePacketOverhead(
127 connection_->version(), PACKET_8BYTE_GUID, !kIncludeVersion, 129 connection_->version(), PACKET_8BYTE_GUID, !kIncludeVersion,
128 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP); 130 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
129 EXPECT_CALL(*session_, WritevData(kStreamId, _, 1, _, _, _)).WillOnce( 131 EXPECT_CALL(*session_, WritevData(kStreamId, _, 1, _, _, _)).WillOnce(
130 Return(QuicConsumedData(kDataLen, true))); 132 Return(QuicConsumedData(kDataLen, true)));
131 EXPECT_EQ(kDataLen, stream_->WriteData(kData1, false).bytes_consumed); 133 stream_->WriteOrBufferData(kData1, false);
132 EXPECT_FALSE(write_blocked_list_->HasWriteBlockedStreams()); 134 EXPECT_FALSE(write_blocked_list_->HasWriteBlockedStreams());
133 } 135 }
134 136
135 // TODO(rtenneti): Death tests crash on OS_ANDROID. 137 // TODO(rtenneti): Death tests crash on OS_ANDROID.
136 #if GTEST_HAS_DEATH_TEST && !defined(NDEBUG) && !defined(OS_ANDROID) 138 #if GTEST_HAS_DEATH_TEST && !defined(NDEBUG) && !defined(OS_ANDROID)
137 TEST_F(ReliableQuicStreamTest, NoBlockingIfNoDataOrFin) { 139 TEST_F(ReliableQuicStreamTest, NoBlockingIfNoDataOrFin) {
138 Initialize(kShouldProcessData); 140 Initialize(kShouldProcessData);
139 141
140 // Write no data and no fin. If we consume nothing we should not be write 142 // Write no data and no fin. If we consume nothing we should not be write
141 // blocked. 143 // blocked.
142 EXPECT_DEBUG_DEATH({ 144 EXPECT_DEBUG_DEATH({
143 EXPECT_CALL(*session_, WritevData(kStreamId, _, 1, _, _, _)).WillOnce( 145 EXPECT_CALL(*session_, WritevData(kStreamId, _, 1, _, _, _)).WillOnce(
144 Return(QuicConsumedData(0, false))); 146 Return(QuicConsumedData(0, false)));
145 stream_->WriteData(StringPiece(), false); 147 stream_->WriteOrBufferData(StringPiece(), false);
146 EXPECT_FALSE(write_blocked_list_->HasWriteBlockedStreams()); 148 EXPECT_FALSE(write_blocked_list_->HasWriteBlockedStreams());
147 }, ""); 149 }, "");
148 } 150 }
149 #endif // GTEST_HAS_DEATH_TEST && !defined(NDEBUG) && !defined(OS_ANDROID) 151 #endif // GTEST_HAS_DEATH_TEST && !defined(NDEBUG) && !defined(OS_ANDROID)
150 152
151 TEST_F(ReliableQuicStreamTest, BlockIfOnlySomeDataConsumed) { 153 TEST_F(ReliableQuicStreamTest, BlockIfOnlySomeDataConsumed) {
152 Initialize(kShouldProcessData); 154 Initialize(kShouldProcessData);
153 155
154 // Write some data and no fin. If we consume some but not all of the data, 156 // Write some data and no fin. If we consume some but not all of the data,
155 // we should be write blocked a not all the data was consumed. 157 // we should be write blocked a not all the data was consumed.
156 EXPECT_CALL(*session_, WritevData(kStreamId, _, 1, _, _, _)).WillOnce( 158 EXPECT_CALL(*session_, WritevData(kStreamId, _, 1, _, _, _)).WillOnce(
157 Return(QuicConsumedData(1, false))); 159 Return(QuicConsumedData(1, false)));
158 stream_->WriteData(StringPiece(kData1, 2), false); 160 stream_->WriteOrBufferData(StringPiece(kData1, 2), false);
159 ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams()); 161 ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams());
160 } 162 }
161 163
162 164
163 TEST_F(ReliableQuicStreamTest, BlockIfFinNotConsumedWithData) { 165 TEST_F(ReliableQuicStreamTest, BlockIfFinNotConsumedWithData) {
164 Initialize(kShouldProcessData); 166 Initialize(kShouldProcessData);
165 167
166 // Write some data and no fin. If we consume all the data but not the fin, 168 // Write some data and no fin. If we consume all the data but not the fin,
167 // we should be write blocked because the fin was not consumed. 169 // we should be write blocked because the fin was not consumed.
168 // (This should never actually happen as the fin should be sent out with the 170 // (This should never actually happen as the fin should be sent out with the
169 // last data) 171 // last data)
170 EXPECT_CALL(*session_, WritevData(kStreamId, _, 1, _, _, _)).WillOnce( 172 EXPECT_CALL(*session_, WritevData(kStreamId, _, 1, _, _, _)).WillOnce(
171 Return(QuicConsumedData(2, false))); 173 Return(QuicConsumedData(2, false)));
172 stream_->WriteData(StringPiece(kData1, 2), true); 174 stream_->WriteOrBufferData(StringPiece(kData1, 2), true);
173 ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams()); 175 ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams());
174 } 176 }
175 177
176 TEST_F(ReliableQuicStreamTest, BlockIfSoloFinNotConsumed) { 178 TEST_F(ReliableQuicStreamTest, BlockIfSoloFinNotConsumed) {
177 Initialize(kShouldProcessData); 179 Initialize(kShouldProcessData);
178 180
179 // Write no data and a fin. If we consume nothing we should be write blocked, 181 // Write no data and a fin. If we consume nothing we should be write blocked,
180 // as the fin was not consumed. 182 // as the fin was not consumed.
181 EXPECT_CALL(*session_, WritevData(kStreamId, _, 1, _, _, _)).WillOnce( 183 EXPECT_CALL(*session_, WritevData(kStreamId, _, 1, _, _, _)).WillOnce(
182 Return(QuicConsumedData(0, false))); 184 Return(QuicConsumedData(0, false)));
183 stream_->WriteData(StringPiece(), true); 185 stream_->WriteOrBufferData(StringPiece(), true);
184 ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams()); 186 ASSERT_EQ(1u, write_blocked_list_->NumBlockedStreams());
185 } 187 }
186 188
187 TEST_F(ReliableQuicStreamTest, WriteData) { 189 TEST_F(ReliableQuicStreamTest, WriteOrBufferData) {
188 Initialize(kShouldProcessData); 190 Initialize(kShouldProcessData);
189 191
190 EXPECT_FALSE(write_blocked_list_->HasWriteBlockedStreams()); 192 EXPECT_FALSE(write_blocked_list_->HasWriteBlockedStreams());
191 connection_->options()->max_packet_length = 193 connection_->options()->max_packet_length =
192 1 + QuicPacketCreator::StreamFramePacketOverhead( 194 1 + QuicPacketCreator::StreamFramePacketOverhead(
193 connection_->version(), PACKET_8BYTE_GUID, !kIncludeVersion, 195 connection_->version(), PACKET_8BYTE_GUID, !kIncludeVersion,
194 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP); 196 PACKET_6BYTE_SEQUENCE_NUMBER, NOT_IN_FEC_GROUP);
195 EXPECT_CALL(*session_, WritevData(_, _, 1, _, _, _)).WillOnce( 197 EXPECT_CALL(*session_, WritevData(_, _, 1, _, _, _)).WillOnce(
196 Return(QuicConsumedData(kDataLen - 1, false))); 198 Return(QuicConsumedData(kDataLen - 1, false)));
197 // The return will be kDataLen, because the last byte gets buffered. 199 stream_->WriteOrBufferData(kData1, false);
198 EXPECT_EQ(kDataLen, stream_->WriteData(kData1, false).bytes_consumed);
199 EXPECT_TRUE(write_blocked_list_->HasWriteBlockedStreams()); 200 EXPECT_TRUE(write_blocked_list_->HasWriteBlockedStreams());
200 201
201 // Queue a bytes_consumed write. 202 // Queue a bytes_consumed write.
202 EXPECT_EQ(kDataLen, stream_->WriteData(kData2, false).bytes_consumed); 203 stream_->WriteOrBufferData(kData2, false);
203 204
204 // Make sure we get the tail of the first write followed by the bytes_consumed 205 // Make sure we get the tail of the first write followed by the bytes_consumed
205 InSequence s; 206 InSequence s;
206 EXPECT_CALL(*session_, WritevData(_, _, 1, _, _, _)). 207 EXPECT_CALL(*session_, WritevData(_, _, 1, _, _, _)).
207 WillOnce(Return(QuicConsumedData(1, false))); 208 WillOnce(Return(QuicConsumedData(1, false)));
208 EXPECT_CALL(*session_, WritevData(_, _, 1, _, _, _)). 209 EXPECT_CALL(*session_, WritevData(_, _, 1, _, _, _)).
209 WillOnce(Return(QuicConsumedData(kDataLen - 2, false))); 210 WillOnce(Return(QuicConsumedData(kDataLen - 2, false)));
210 stream_->OnCanWrite(); 211 stream_->OnCanWrite();
211 212
212 // And finally the end of the bytes_consumed. 213 // And finally the end of the bytes_consumed.
213 EXPECT_CALL(*session_, WritevData(_, _, 1, _, _, _)). 214 EXPECT_CALL(*session_, WritevData(_, _, 1, _, _, _)).
214 WillOnce(Return(QuicConsumedData(2, true))); 215 WillOnce(Return(QuicConsumedData(2, true)));
215 stream_->OnCanWrite(); 216 stream_->OnCanWrite();
216 } 217 }
217 218
218 TEST_F(ReliableQuicStreamTest, ConnectionCloseAfterStreamClose) { 219 TEST_F(ReliableQuicStreamTest, ConnectionCloseAfterStreamClose) {
219 Initialize(kShouldProcessData); 220 Initialize(kShouldProcessData);
220 221
221 stream_->CloseReadSide(); 222 stream_->CloseReadSide();
222 stream_->CloseWriteSide(); 223 stream_->CloseWriteSide();
223 EXPECT_EQ(QUIC_STREAM_NO_ERROR, stream_->stream_error()); 224 EXPECT_EQ(QUIC_STREAM_NO_ERROR, stream_->stream_error());
224 EXPECT_EQ(QUIC_NO_ERROR, stream_->connection_error()); 225 EXPECT_EQ(QUIC_NO_ERROR, stream_->connection_error());
225 stream_->OnConnectionClosed(QUIC_INTERNAL_ERROR, false); 226 stream_->OnConnectionClosed(QUIC_INTERNAL_ERROR, false);
226 EXPECT_EQ(QUIC_STREAM_NO_ERROR, stream_->stream_error()); 227 EXPECT_EQ(QUIC_STREAM_NO_ERROR, stream_->stream_error());
227 EXPECT_EQ(QUIC_NO_ERROR, stream_->connection_error()); 228 EXPECT_EQ(QUIC_NO_ERROR, stream_->connection_error());
228 } 229 }
229 230
230 TEST_F(ReliableQuicStreamTest, ProcessHeaders) {
231 Initialize(kShouldProcessData);
232
233 string compressed_headers = compressor_->CompressHeadersWithPriority(
234 kHighestPriority, headers_);
235 QuicStreamFrame frame(kStreamId, false, 0, MakeIOVector(compressed_headers));
236
237 stream_->OnStreamFrame(frame);
238 EXPECT_EQ(SpdyUtils::SerializeUncompressedHeaders(headers_), stream_->data());
239 EXPECT_EQ(static_cast<QuicPriority>(kHighestPriority),
240 stream_->EffectivePriority());
241 }
242
243 TEST_F(ReliableQuicStreamTest, ProcessHeadersWithInvalidHeaderId) {
244 Initialize(kShouldProcessData);
245
246 string compressed_headers = compressor_->CompressHeadersWithPriority(
247 kHighestPriority, headers_);
248 compressed_headers[4] = '\xFF'; // Illegal header id.
249 QuicStreamFrame frame(kStreamId, false, 0, MakeIOVector(compressed_headers));
250
251 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_INVALID_HEADER_ID));
252 stream_->OnStreamFrame(frame);
253 }
254
255 TEST_F(ReliableQuicStreamTest, ProcessHeadersWithInvalidPriority) {
256 Initialize(kShouldProcessData);
257
258 string compressed_headers = compressor_->CompressHeadersWithPriority(
259 kHighestPriority, headers_);
260 compressed_headers[0] = '\xFF'; // Illegal priority.
261 QuicStreamFrame frame(kStreamId, false, 0, MakeIOVector(compressed_headers));
262
263 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_INVALID_PRIORITY));
264 stream_->OnStreamFrame(frame);
265 }
266
267 TEST_F(ReliableQuicStreamTest, ProcessHeadersAndBody) {
268 Initialize(kShouldProcessData);
269
270 string compressed_headers = compressor_->CompressHeadersWithPriority(
271 kHighestPriority, headers_);
272 string body = "this is the body";
273 string data = compressed_headers + body;
274 QuicStreamFrame frame(kStreamId, false, 0, MakeIOVector(data));
275
276 stream_->OnStreamFrame(frame);
277 EXPECT_EQ(SpdyUtils::SerializeUncompressedHeaders(headers_) + body,
278 stream_->data());
279 }
280
281 TEST_F(ReliableQuicStreamTest, ProcessHeadersAndBodyFragments) {
282 Initialize(kShouldProcessData);
283
284 string compressed_headers = compressor_->CompressHeadersWithPriority(
285 kLowestPriority, headers_);
286 string body = "this is the body";
287 string data = compressed_headers + body;
288
289 for (size_t fragment_size = 1; fragment_size < data.size(); ++fragment_size) {
290 Initialize(kShouldProcessData);
291 for (size_t offset = 0; offset < data.size(); offset += fragment_size) {
292 size_t remaining_data = data.length() - offset;
293 StringPiece fragment(data.data() + offset,
294 min(fragment_size, remaining_data));
295 QuicStreamFrame frame(kStreamId, false, offset, MakeIOVector(fragment));
296
297 stream_->OnStreamFrame(frame);
298 }
299 ASSERT_EQ(SpdyUtils::SerializeUncompressedHeaders(headers_) + body,
300 stream_->data()) << "fragment_size: " << fragment_size;
301 }
302
303 for (size_t split_point = 1; split_point < data.size() - 1; ++split_point) {
304 Initialize(kShouldProcessData);
305
306 StringPiece fragment1(data.data(), split_point);
307 QuicStreamFrame frame1(kStreamId, false, 0, MakeIOVector(fragment1));
308 stream_->OnStreamFrame(frame1);
309
310 StringPiece fragment2(data.data() + split_point, data.size() - split_point);
311 QuicStreamFrame frame2(
312 kStreamId, false, split_point, MakeIOVector(fragment2));
313 stream_->OnStreamFrame(frame2);
314
315 ASSERT_EQ(SpdyUtils::SerializeUncompressedHeaders(headers_) + body,
316 stream_->data()) << "split_point: " << split_point;
317 }
318 EXPECT_EQ(static_cast<QuicPriority>(kLowestPriority),
319 stream_->EffectivePriority());
320 }
321
322 TEST_F(ReliableQuicStreamTest, ProcessHeadersAndBodyReadv) {
323 Initialize(!kShouldProcessData);
324
325 string compressed_headers = compressor_->CompressHeadersWithPriority(
326 kHighestPriority, headers_);
327 string body = "this is the body";
328 string data = compressed_headers + body;
329 QuicStreamFrame frame(kStreamId, false, 0, MakeIOVector(data));
330 string uncompressed_headers =
331 SpdyUtils::SerializeUncompressedHeaders(headers_);
332 string uncompressed_data = uncompressed_headers + body;
333
334 stream_->OnStreamFrame(frame);
335 EXPECT_EQ(uncompressed_headers, stream_->data());
336
337 char buffer[2048];
338 ASSERT_LT(data.length(), arraysize(buffer));
339 struct iovec vec;
340 vec.iov_base = buffer;
341 vec.iov_len = arraysize(buffer);
342
343 size_t bytes_read = stream_->Readv(&vec, 1);
344 EXPECT_EQ(uncompressed_headers.length(), bytes_read);
345 EXPECT_EQ(uncompressed_headers, string(buffer, bytes_read));
346
347 bytes_read = stream_->Readv(&vec, 1);
348 EXPECT_EQ(body.length(), bytes_read);
349 EXPECT_EQ(body, string(buffer, bytes_read));
350 }
351
352 TEST_F(ReliableQuicStreamTest, ProcessHeadersAndBodyIncrementalReadv) {
353 Initialize(!kShouldProcessData);
354
355 string compressed_headers = compressor_->CompressHeadersWithPriority(
356 kHighestPriority, headers_);
357 string body = "this is the body";
358 string data = compressed_headers + body;
359 QuicStreamFrame frame(kStreamId, false, 0, MakeIOVector(data));
360 string uncompressed_headers =
361 SpdyUtils::SerializeUncompressedHeaders(headers_);
362 string uncompressed_data = uncompressed_headers + body;
363
364 stream_->OnStreamFrame(frame);
365 EXPECT_EQ(uncompressed_headers, stream_->data());
366
367 char buffer[1];
368 struct iovec vec;
369 vec.iov_base = buffer;
370 vec.iov_len = arraysize(buffer);
371 for (size_t i = 0; i < uncompressed_data.length(); ++i) {
372 size_t bytes_read = stream_->Readv(&vec, 1);
373 ASSERT_EQ(1u, bytes_read);
374 EXPECT_EQ(uncompressed_data.data()[i], buffer[0]);
375 }
376 }
377
378 TEST_F(ReliableQuicStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) {
379 Initialize(!kShouldProcessData);
380
381 string compressed_headers = compressor_->CompressHeadersWithPriority(
382 kHighestPriority, headers_);
383 string body = "this is the body";
384 string data = compressed_headers + body;
385 QuicStreamFrame frame(kStreamId, false, 0, MakeIOVector(data));
386 string uncompressed_headers =
387 SpdyUtils::SerializeUncompressedHeaders(headers_);
388 string uncompressed_data = uncompressed_headers + body;
389
390 stream_->OnStreamFrame(frame);
391 EXPECT_EQ(uncompressed_headers, stream_->data());
392
393 char buffer1[1];
394 char buffer2[1];
395 struct iovec vec[2];
396 vec[0].iov_base = buffer1;
397 vec[0].iov_len = arraysize(buffer1);
398 vec[1].iov_base = buffer2;
399 vec[1].iov_len = arraysize(buffer2);
400 for (size_t i = 0; i < uncompressed_data.length(); i += 2) {
401 size_t bytes_read = stream_->Readv(vec, 2);
402 ASSERT_EQ(2u, bytes_read) << i;
403 ASSERT_EQ(uncompressed_data.data()[i], buffer1[0]) << i;
404 ASSERT_EQ(uncompressed_data.data()[i + 1], buffer2[0]) << i;
405 }
406 }
407
408 TEST_F(ReliableQuicStreamTest, ProcessCorruptHeadersEarly) {
409 Initialize(kShouldProcessData);
410
411 string compressed_headers1 = compressor_->CompressHeadersWithPriority(
412 kHighestPriority, headers_);
413 QuicStreamFrame frame1(
414 stream_->id(), false, 0, MakeIOVector(compressed_headers1));
415 string decompressed_headers1 =
416 SpdyUtils::SerializeUncompressedHeaders(headers_);
417
418 headers_["content-type"] = "text/plain";
419 string compressed_headers2 = compressor_->CompressHeadersWithPriority(
420 kHighestPriority, headers_);
421 // Corrupt the compressed data.
422 compressed_headers2[compressed_headers2.length() - 1] ^= 0xA1;
423 QuicStreamFrame frame2(
424 stream2_->id(), false, 0, MakeIOVector(compressed_headers2));
425 string decompressed_headers2 =
426 SpdyUtils::SerializeUncompressedHeaders(headers_);
427
428 // Deliver frame2 to stream2 out of order. The decompressor is not
429 // available yet, so no data will be processed. The compressed data
430 // will be buffered until OnDecompressorAvailable() is called
431 // to process it.
432 stream2_->OnStreamFrame(frame2);
433 EXPECT_EQ("", stream2_->data());
434
435 // Now deliver frame1 to stream1. The decompressor is available so
436 // the data will be processed, and the decompressor will become
437 // available for stream2.
438 stream_->OnStreamFrame(frame1);
439 EXPECT_EQ(decompressed_headers1, stream_->data());
440
441 // Verify that the decompressor is available, and inform stream2
442 // that it can now decompress the buffered compressed data. Since
443 // the compressed data is corrupt, the stream will shutdown the session.
444 EXPECT_EQ(2u, session_->decompressor()->current_header_id());
445 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_DECOMPRESSION_FAILURE));
446 stream2_->OnDecompressorAvailable();
447 EXPECT_EQ("", stream2_->data());
448 }
449
450 TEST_F(ReliableQuicStreamTest, ProcessPartialHeadersEarly) {
451 Initialize(kShouldProcessData);
452
453 string compressed_headers1 = compressor_->CompressHeadersWithPriority(
454 kHighestPriority, headers_);
455 QuicStreamFrame frame1(
456 stream_->id(), false, 0, MakeIOVector(compressed_headers1));
457 string decompressed_headers1 =
458 SpdyUtils::SerializeUncompressedHeaders(headers_);
459
460 headers_["content-type"] = "text/plain";
461 string compressed_headers2 = compressor_->CompressHeadersWithPriority(
462 kHighestPriority, headers_);
463 string partial_compressed_headers =
464 compressed_headers2.substr(0, compressed_headers2.length() / 2);
465 QuicStreamFrame frame2(
466 stream2_->id(), false, 0, MakeIOVector(partial_compressed_headers));
467 string decompressed_headers2 =
468 SpdyUtils::SerializeUncompressedHeaders(headers_);
469
470 // Deliver frame2 to stream2 out of order. The decompressor is not
471 // available yet, so no data will be processed. The compressed data
472 // will be buffered until OnDecompressorAvailable() is called
473 // to process it.
474 stream2_->OnStreamFrame(frame2);
475 EXPECT_EQ("", stream2_->data());
476
477 // Now deliver frame1 to stream1. The decompressor is available so
478 // the data will be processed, and the decompressor will become
479 // available for stream2.
480 stream_->OnStreamFrame(frame1);
481 EXPECT_EQ(decompressed_headers1, stream_->data());
482
483 // Verify that the decompressor is available, and inform stream2
484 // that it can now decompress the buffered compressed data. Since
485 // the compressed data is incomplete it will not be passed to
486 // the stream.
487 EXPECT_EQ(2u, session_->decompressor()->current_header_id());
488 stream2_->OnDecompressorAvailable();
489 EXPECT_EQ("", stream2_->data());
490
491 // Now send remaining data and verify that we have now received the
492 // compressed headers.
493 string remaining_compressed_headers =
494 compressed_headers2.substr(partial_compressed_headers.length());
495
496 QuicStreamFrame frame3(stream2_->id(), false,
497 partial_compressed_headers.length(),
498 MakeIOVector(remaining_compressed_headers));
499 stream2_->OnStreamFrame(frame3);
500 EXPECT_EQ(decompressed_headers2, stream2_->data());
501 }
502
503 TEST_F(ReliableQuicStreamTest, ProcessHeadersEarly) {
504 Initialize(kShouldProcessData);
505
506 string compressed_headers1 = compressor_->CompressHeadersWithPriority(
507 kHighestPriority, headers_);
508 QuicStreamFrame frame1(
509 stream_->id(), false, 0, MakeIOVector(compressed_headers1));
510 string decompressed_headers1 =
511 SpdyUtils::SerializeUncompressedHeaders(headers_);
512
513 headers_["content-type"] = "text/plain";
514 string compressed_headers2 = compressor_->CompressHeadersWithPriority(
515 kHighestPriority, headers_);
516 QuicStreamFrame frame2(
517 stream2_->id(), false, 0, MakeIOVector(compressed_headers2));
518 string decompressed_headers2 =
519 SpdyUtils::SerializeUncompressedHeaders(headers_);
520
521 // Deliver frame2 to stream2 out of order. The decompressor is not
522 // available yet, so no data will be processed. The compressed data
523 // will be buffered until OnDecompressorAvailable() is called
524 // to process it.
525 stream2_->OnStreamFrame(frame2);
526 EXPECT_EQ("", stream2_->data());
527
528 // Now deliver frame1 to stream1. The decompressor is available so
529 // the data will be processed, and the decompressor will become
530 // available for stream2.
531 stream_->OnStreamFrame(frame1);
532 EXPECT_EQ(decompressed_headers1, stream_->data());
533
534 // Verify that the decompressor is available, and inform stream2
535 // that it can now decompress the buffered compressed data.
536 EXPECT_EQ(2u, session_->decompressor()->current_header_id());
537 stream2_->OnDecompressorAvailable();
538 EXPECT_EQ(decompressed_headers2, stream2_->data());
539 }
540
541 TEST_F(ReliableQuicStreamTest, ProcessHeadersDelay) {
542 Initialize(!kShouldProcessData);
543
544 string compressed_headers = compressor_->CompressHeadersWithPriority(
545 kHighestPriority, headers_);
546 QuicStreamFrame frame1(
547 stream_->id(), false, 0, MakeIOVector(compressed_headers));
548 string decompressed_headers =
549 SpdyUtils::SerializeUncompressedHeaders(headers_);
550
551 // Send the headers to the stream and verify they were decompressed.
552 stream_->OnStreamFrame(frame1);
553 EXPECT_EQ(2u, session_->decompressor()->current_header_id());
554
555 // Verify that we are now able to handle the body data,
556 // even though the stream has not processed the headers.
557 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_INVALID_HEADER_ID))
558 .Times(0);
559 QuicStreamFrame frame2(stream_->id(), false, compressed_headers.length(),
560 MakeIOVector("body data"));
561 stream_->OnStreamFrame(frame2);
562 }
563
564 } // namespace 231 } // namespace
565 } // namespace test 232 } // namespace test
566 } // namespace net 233 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/reliable_quic_stream.cc ('k') | net/quic/test_tools/mock_random.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698