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

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

Issue 14651009: Land Recent QUIC changes (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix integer constant is too large for 'unsigned long' type Created 7 years, 7 months 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/spdy_utils.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_connection.h" 7 #include "net/quic/quic_connection.h"
8 #include "net/quic/quic_spdy_compressor.h"
9 #include "net/quic/quic_spdy_decompressor.h"
8 #include "net/quic/quic_utils.h" 10 #include "net/quic/quic_utils.h"
11 #include "net/quic/spdy_utils.h"
9 #include "net/quic/test_tools/quic_test_utils.h" 12 #include "net/quic/test_tools/quic_test_utils.h"
10 #include "testing/gmock/include/gmock/gmock.h" 13 #include "testing/gmock/include/gmock/gmock.h"
11 14
12 using base::StringPiece; 15 using base::StringPiece;
16 using std::min;
13 using testing::_; 17 using testing::_;
14 using testing::InSequence; 18 using testing::InSequence;
15 using testing::Return; 19 using testing::Return;
20 using testing::SaveArg;
16 using testing::StrEq; 21 using testing::StrEq;
22 using testing::StrictMock;
17 23
18 namespace net { 24 namespace net {
19 namespace test { 25 namespace test {
20 namespace { 26 namespace {
21 27
22 const char kData1[] = "FooAndBar"; 28 const char kData1[] = "FooAndBar";
23 const char kData2[] = "EepAndBaz"; 29 const char kData2[] = "EepAndBaz";
24 const size_t kDataLen = 9; 30 const size_t kDataLen = 9;
25 31 const QuicGuid kGuid = 42;
26 class QuicReliableTestStream : public ReliableQuicStream { 32 const QuicGuid kStreamId = 3;
33 const bool kIsServer = true;
34 const bool kShouldProcessData = true;
35
36 class TestStream : public ReliableQuicStream {
27 public: 37 public:
28 QuicReliableTestStream(QuicStreamId id, QuicSession* session) 38 TestStream(QuicStreamId id,
29 : ReliableQuicStream(id, session) { 39 QuicSession* session,
30 } 40 bool should_process_data)
41 : ReliableQuicStream(id, session),
42 should_process_data_(should_process_data) {
43 }
44
31 virtual uint32 ProcessData(const char* data, uint32 data_len) OVERRIDE { 45 virtual uint32 ProcessData(const char* data, uint32 data_len) OVERRIDE {
32 return 0; 46 LOG(INFO) << "data_len: " << data_len;
33 } 47 data_ += string(data, data_len);
48 return should_process_data_ ? data_len : 0;
49 }
50
34 using ReliableQuicStream::WriteData; 51 using ReliableQuicStream::WriteData;
35 using ReliableQuicStream::CloseReadSide; 52 using ReliableQuicStream::CloseReadSide;
36 using ReliableQuicStream::CloseWriteSide; 53 using ReliableQuicStream::CloseWriteSide;
54
55 const string& data() const { return data_; }
56
57 private:
58 bool should_process_data_;
59 string data_;
37 }; 60 };
38 61
39 class ReliableQuicStreamTest : public ::testing::TestWithParam<bool> { 62 class ReliableQuicStreamTest : public ::testing::TestWithParam<bool> {
40 public: 63 public:
41 ReliableQuicStreamTest() 64 ReliableQuicStreamTest() {
42 : connection_(new MockConnection(1, IPEndPoint(), false)), 65 headers_[":host"] = "www.google.com";
43 session_(connection_, true), 66 headers_[":path"] = "/index.hml";
44 stream_(1, &session_) { 67 headers_[":scheme"] = "https";
45 } 68 }
46 69
70 void Initialize(bool stream_should_process_data) {
71 connection_ = new MockConnection(kGuid, IPEndPoint(), kIsServer);
72 session_.reset(new MockSession(connection_, kIsServer));
73 stream_.reset(new TestStream(kStreamId, session_.get(),
74 stream_should_process_data));
75 stream2_.reset(new TestStream(kStreamId + 2, session_.get(),
76 stream_should_process_data));
77 compressor_.reset(new QuicSpdyCompressor());
78 decompressor_.reset(new QuicSpdyDecompressor);
79 }
80
81 protected:
47 MockConnection* connection_; 82 MockConnection* connection_;
48 MockSession session_; 83 scoped_ptr<MockSession> session_;
49 QuicReliableTestStream stream_; 84 scoped_ptr<TestStream> stream_;
85 scoped_ptr<TestStream> stream2_;
86 scoped_ptr<QuicSpdyCompressor> compressor_;
87 scoped_ptr<QuicSpdyDecompressor> decompressor_;
88 SpdyHeaderBlock headers_;
50 }; 89 };
51 90
52 TEST_F(ReliableQuicStreamTest, WriteAllData) { 91 TEST_F(ReliableQuicStreamTest, WriteAllData) {
92 Initialize(kShouldProcessData);
93
53 connection_->options()->max_packet_length = 94 connection_->options()->max_packet_length =
54 1 + QuicPacketCreator::StreamFramePacketOverhead(1, !kIncludeVersion); 95 1 + QuicPacketCreator::StreamFramePacketOverhead(1, !kIncludeVersion);
55 // TODO(rch): figure out how to get StrEq working here. 96 // TODO(rch): figure out how to get StrEq working here.
56 //EXPECT_CALL(session_, WriteData(_, StrEq(kData1), _, _)).WillOnce( 97 //EXPECT_CALL(*session_, WriteData(kStreamId, StrEq(kData1), _, _)).WillOnce(
57 EXPECT_CALL(session_, WriteData(1, _, _, _)).WillOnce( 98 EXPECT_CALL(*session_, WriteData(kStreamId, _, _, _)).WillOnce(
58 Return(QuicConsumedData(kDataLen, true))); 99 Return(QuicConsumedData(kDataLen, true)));
59 EXPECT_EQ(kDataLen, stream_.WriteData(kData1, false).bytes_consumed); 100 EXPECT_EQ(kDataLen, stream_->WriteData(kData1, false).bytes_consumed);
60 } 101 }
61 102
62 TEST_F(ReliableQuicStreamTest, WriteData) { 103 TEST_F(ReliableQuicStreamTest, WriteData) {
104 Initialize(kShouldProcessData);
105
63 connection_->options()->max_packet_length = 106 connection_->options()->max_packet_length =
64 1 + QuicPacketCreator::StreamFramePacketOverhead(1, !kIncludeVersion); 107 1 + QuicPacketCreator::StreamFramePacketOverhead(1, !kIncludeVersion);
65 // TODO(rch): figure out how to get StrEq working here. 108 // TODO(rch): figure out how to get StrEq working here.
66 //EXPECT_CALL(session_, WriteData(_, StrEq(kData1), _, _)).WillOnce( 109 //EXPECT_CALL(*session_, WriteData(_, StrEq(kData1), _, _)).WillOnce(
67 EXPECT_CALL(session_, WriteData(_, _, _, _)).WillOnce( 110 EXPECT_CALL(*session_, WriteData(_, _, _, _)).WillOnce(
68 Return(QuicConsumedData(kDataLen - 1, false))); 111 Return(QuicConsumedData(kDataLen - 1, false)));
69 // The return will be kDataLen, because the last byte gets buffered. 112 // The return will be kDataLen, because the last byte gets buffered.
70 EXPECT_EQ(kDataLen, stream_.WriteData(kData1, false).bytes_consumed); 113 EXPECT_EQ(kDataLen, stream_->WriteData(kData1, false).bytes_consumed);
71 114
72 // Queue a bytes_consumed write. 115 // Queue a bytes_consumed write.
73 EXPECT_EQ(kDataLen, stream_.WriteData(kData2, false).bytes_consumed); 116 EXPECT_EQ(kDataLen, stream_->WriteData(kData2, false).bytes_consumed);
74 117
75 // Make sure we get the tail of the first write followed by the bytes_consumed 118 // Make sure we get the tail of the first write followed by the bytes_consumed
76 InSequence s; 119 InSequence s;
77 //EXPECT_CALL(session_, WriteData(_, StrEq(&kData2[kDataLen - 1]), _, _)). 120 //EXPECT_CALL(*session_, WriteData(_, StrEq(&kData1[kDataLen - 1]), _, _)).
78 EXPECT_CALL(session_, WriteData(_, _, _, _)). 121 EXPECT_CALL(*session_, WriteData(_, _, _, _)).
79 WillOnce(Return(QuicConsumedData(1, false))); 122 WillOnce(Return(QuicConsumedData(1, false)));
80 //EXPECT_CALL(session_, WriteData(_, StrEq(kData2), _, _)). 123 //EXPECT_CALL(*session_, WriteData(_, StrEq(kData2), _, _)).
81 EXPECT_CALL(session_, WriteData(_, _, _, _)). 124 EXPECT_CALL(*session_, WriteData(_, _, _, _)).
82 WillOnce(Return(QuicConsumedData(kDataLen - 2, false))); 125 WillOnce(Return(QuicConsumedData(kDataLen - 2, false)));
83 stream_.OnCanWrite(); 126 stream_->OnCanWrite();
84 127
85 // And finally the end of the bytes_consumed 128 // And finally the end of the bytes_consumed
86 //EXPECT_CALL(session_, WriteData(_, StrEq(&kData2[kDataLen - 2]), _, _)). 129 //EXPECT_CALL(*session_, WriteData(_, StrEq(&kData2[kDataLen - 2]), _, _)).
87 EXPECT_CALL(session_, WriteData(_, _, _, _)). 130 EXPECT_CALL(*session_, WriteData(_, _, _, _)).
88 WillOnce(Return(QuicConsumedData(2, true))); 131 WillOnce(Return(QuicConsumedData(2, true)));
89 stream_.OnCanWrite(); 132 stream_->OnCanWrite();
90 } 133 }
91 134
92 TEST_F(ReliableQuicStreamTest, ConnectionCloseAfterStreamClose) { 135 TEST_F(ReliableQuicStreamTest, ConnectionCloseAfterStreamClose) {
93 stream_.CloseReadSide(); 136 Initialize(kShouldProcessData);
94 stream_.CloseWriteSide(); 137
95 EXPECT_EQ(QUIC_STREAM_NO_ERROR, stream_.stream_error()); 138 stream_->CloseReadSide();
96 EXPECT_EQ(QUIC_NO_ERROR, stream_.connection_error()); 139 stream_->CloseWriteSide();
97 stream_.ConnectionClose(QUIC_INTERNAL_ERROR, false); 140 EXPECT_EQ(QUIC_STREAM_NO_ERROR, stream_->stream_error());
98 EXPECT_EQ(QUIC_STREAM_NO_ERROR, stream_.stream_error()); 141 EXPECT_EQ(QUIC_NO_ERROR, stream_->connection_error());
99 EXPECT_EQ(QUIC_NO_ERROR, stream_.connection_error()); 142 stream_->ConnectionClose(QUIC_INTERNAL_ERROR, false);
143 EXPECT_EQ(QUIC_STREAM_NO_ERROR, stream_->stream_error());
144 EXPECT_EQ(QUIC_NO_ERROR, stream_->connection_error());
145 }
146
147 TEST_F(ReliableQuicStreamTest, ProcessHeaders) {
148 Initialize(kShouldProcessData);
149
150 string compressed_headers = compressor_->CompressHeaders(headers_);
151 QuicStreamFrame frame(kStreamId, false, 0, compressed_headers);
152
153 stream_->OnStreamFrame(frame);
154 EXPECT_EQ(SpdyUtils::SerializeUncompressedHeaders(headers_), stream_->data());
155 }
156
157 TEST_F(ReliableQuicStreamTest, ProcessHeadersWithInvalidHeaderId) {
158 Initialize(kShouldProcessData);
159
160 string compressed_headers = compressor_->CompressHeaders(headers_);
161 compressed_headers.replace(0, 1, 1, '\xFF'); // Illegal header id.
162 QuicStreamFrame frame(kStreamId, false, 0, compressed_headers);
163
164 EXPECT_CALL(*connection_, SendConnectionClose(QUIC_INVALID_HEADER_ID));
165 stream_->OnStreamFrame(frame);
166 }
167
168 TEST_F(ReliableQuicStreamTest, ProcessHeadersAndBody) {
169 Initialize(kShouldProcessData);
170
171 string compressed_headers = compressor_->CompressHeaders(headers_);
172 string body = "this is the body";
173 string data = compressed_headers + body;
174 QuicStreamFrame frame(kStreamId, false, 0, data);
175
176 stream_->OnStreamFrame(frame);
177 EXPECT_EQ(SpdyUtils::SerializeUncompressedHeaders(headers_) + body,
178 stream_->data());
179 }
180
181 TEST_F(ReliableQuicStreamTest, ProcessHeadersAndBodyFragments) {
182 Initialize(kShouldProcessData);
183
184 string compressed_headers = compressor_->CompressHeaders(headers_);
185 string body = "this is the body";
186 string data = compressed_headers + body;
187
188 for (size_t fragment_size = 1; fragment_size < data.size(); ++fragment_size) {
189 Initialize(kShouldProcessData);
190 for (size_t offset = 0; offset < data.size(); offset += fragment_size) {
191 size_t remaining_data = data.length() - offset;
192 StringPiece fragment(data.data() + offset,
193 min(fragment_size, remaining_data));
194 QuicStreamFrame frame(kStreamId, false, offset, fragment);
195
196 stream_->OnStreamFrame(frame);
197 }
198 ASSERT_EQ(SpdyUtils::SerializeUncompressedHeaders(headers_) + body,
199 stream_->data()) << "fragment_size: " << fragment_size;
200 }
201 }
202
203 TEST_F(ReliableQuicStreamTest, ProcessHeadersAndBodyReadv) {
204 Initialize(!kShouldProcessData);
205
206 string compressed_headers = compressor_->CompressHeaders(headers_);
207 string body = "this is the body";
208 string data = compressed_headers + body;
209 QuicStreamFrame frame(kStreamId, false, 0, data);
210 string uncompressed_headers =
211 SpdyUtils::SerializeUncompressedHeaders(headers_);
212 string uncompressed_data = uncompressed_headers + body;
213
214 stream_->OnStreamFrame(frame);
215 EXPECT_EQ(uncompressed_data, stream_->data());
216
217 char buffer[1024];
218 ASSERT_LT(data.length(), arraysize(buffer));
219 struct iovec vec;
220 vec.iov_base = buffer;
221 vec.iov_len = arraysize(buffer);
222
223 size_t bytes_read = stream_->Readv(&vec, 1);
224 EXPECT_EQ(uncompressed_headers.length(), bytes_read);
225 EXPECT_EQ(uncompressed_headers, string(buffer, bytes_read));
226
227 bytes_read = stream_->Readv(&vec, 1);
228 EXPECT_EQ(body.length(), bytes_read);
229 EXPECT_EQ(body, string(buffer, bytes_read));
230 }
231
232 TEST_F(ReliableQuicStreamTest, ProcessHeadersAndBodyIncrementalReadv) {
233 Initialize(!kShouldProcessData);
234
235 string compressed_headers = compressor_->CompressHeaders(headers_);
236 string body = "this is the body";
237 string data = compressed_headers + body;
238 QuicStreamFrame frame(kStreamId, false, 0, data);
239 string uncompressed_headers =
240 SpdyUtils::SerializeUncompressedHeaders(headers_);
241 string uncompressed_data = uncompressed_headers + body;
242
243 stream_->OnStreamFrame(frame);
244 EXPECT_EQ(uncompressed_data, stream_->data());
245
246 char buffer[1];
247 struct iovec vec;
248 vec.iov_base = buffer;
249 vec.iov_len = arraysize(buffer);
250 for (size_t i = 0; i < uncompressed_data.length(); ++i) {
251 size_t bytes_read = stream_->Readv(&vec, 1);
252 ASSERT_EQ(1u, bytes_read);
253 EXPECT_EQ(uncompressed_data.data()[i], buffer[0]);
254 }
255 }
256
257 TEST_F(ReliableQuicStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) {
258 Initialize(!kShouldProcessData);
259
260 string compressed_headers = compressor_->CompressHeaders(headers_);
261 string body = "this is the body";
262 string data = compressed_headers + body;
263 QuicStreamFrame frame(kStreamId, false, 0, data);
264 string uncompressed_headers =
265 SpdyUtils::SerializeUncompressedHeaders(headers_);
266 string uncompressed_data = uncompressed_headers + body;
267
268 stream_->OnStreamFrame(frame);
269 EXPECT_EQ(uncompressed_data, stream_->data());
270
271 char buffer1[1];
272 char buffer2[1];
273 struct iovec vec[2];
274 vec[0].iov_base = buffer1;
275 vec[0].iov_len = arraysize(buffer1);
276 vec[1].iov_base = buffer2;
277 vec[1].iov_len = arraysize(buffer2);
278 for (size_t i = 0; i < uncompressed_data.length(); i += 2) {
279 size_t bytes_read = stream_->Readv(vec, 2);
280 ASSERT_EQ(2u, bytes_read) << i;
281 ASSERT_EQ(uncompressed_data.data()[i], buffer1[0]) << i;
282 ASSERT_EQ(uncompressed_data.data()[i + 1], buffer2[0]) << i;
283 }
284 }
285
286 TEST_F(ReliableQuicStreamTest, ProcessHeadersEarly) {
287 Initialize(kShouldProcessData);
288
289 string compressed_headers1 = compressor_->CompressHeaders(headers_);
290 QuicStreamFrame frame1(stream_->id(), false, 0, compressed_headers1);
291 string decompressed_headers1 =
292 SpdyUtils::SerializeUncompressedHeaders(headers_);
293
294 headers_["content-type"] = "text/plain";
295 string compressed_headers2 = compressor_->CompressHeaders(headers_);
296 QuicStreamFrame frame2(stream2_->id(), false, 0, compressed_headers2);
297 string decompressed_headers2 =
298 SpdyUtils::SerializeUncompressedHeaders(headers_);
299
300 stream2_->OnStreamFrame(frame2);
301 EXPECT_EQ("", stream_->data());
302
303 stream_->OnStreamFrame(frame1);
304 EXPECT_EQ(decompressed_headers1, stream_->data());
305
306 EXPECT_EQ(2u, session_->decompressor()->current_header_id());
307 stream2_->OnDecompressorAvailable();
308 EXPECT_EQ(decompressed_headers2, stream2_->data());
100 } 309 }
101 310
102 } // namespace 311 } // namespace
103 } // namespace test 312 } // namespace test
104 } // namespace net 313 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/reliable_quic_stream.cc ('k') | net/quic/spdy_utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698