Remove PlatformFile from profile_browsertest
[chromium-blink-merge.git] / net / quic / quic_data_stream_test.cc
blob40e6b9a51779cfb34046027365e2204e0ebaf454
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.
5 #include "net/quic/quic_data_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 "testing/gmock/include/gmock/gmock.h"
16 using base::StringPiece;
17 using std::min;
18 using testing::_;
19 using testing::InSequence;
20 using testing::SaveArg;
21 using testing::StrictMock;
23 namespace net {
24 namespace test {
25 namespace {
27 const QuicConnectionId kStreamId = 3;
28 const bool kIsServer = true;
29 const bool kShouldProcessData = true;
31 class TestStream : public QuicDataStream {
32 public:
33 TestStream(QuicStreamId id,
34 QuicSession* session,
35 bool should_process_data)
36 : QuicDataStream(id, session),
37 should_process_data_(should_process_data) {}
39 virtual uint32 ProcessData(const char* data, uint32 data_len) OVERRIDE {
40 EXPECT_NE(0u, data_len);
41 DVLOG(1) << "ProcessData data_len: " << data_len;
42 data_ += string(data, data_len);
43 return should_process_data_ ? data_len : 0;
46 using ReliableQuicStream::WriteOrBufferData;
47 using ReliableQuicStream::CloseReadSide;
48 using ReliableQuicStream::CloseWriteSide;
50 const string& data() const { return data_; }
52 private:
53 bool should_process_data_;
54 string data_;
57 class QuicDataStreamTest : public ::testing::TestWithParam<QuicVersion> {
58 public:
59 QuicDataStreamTest() {
60 headers_[":host"] = "www.google.com";
61 headers_[":path"] = "/index.hml";
62 headers_[":scheme"] = "https";
63 headers_["cookie"] =
64 "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; "
65 "__utmc=160408618; "
66 "GX=DQAAAOEAAACWJYdewdE9rIrW6qw3PtVi2-d729qaa-74KqOsM1NVQblK4VhX"
67 "hoALMsy6HOdDad2Sz0flUByv7etmo3mLMidGrBoljqO9hSVA40SLqpG_iuKKSHX"
68 "RW3Np4bq0F0SDGDNsW0DSmTS9ufMRrlpARJDS7qAI6M3bghqJp4eABKZiRqebHT"
69 "pMU-RXvTI5D5oCF1vYxYofH_l1Kviuiy3oQ1kS1enqWgbhJ2t61_SNdv-1XJIS0"
70 "O3YeHLmVCs62O6zp89QwakfAWK9d3IDQvVSJzCQsvxvNIvaZFa567MawWlXg0Rh"
71 "1zFMi5vzcns38-8_Sns; "
72 "GA=v*2%2Fmem*57968640*47239936%2Fmem*57968640*47114716%2Fno-nm-"
73 "yj*15%2Fno-cc-yj*5%2Fpc-ch*133685%2Fpc-s-cr*133947%2Fpc-s-t*1339"
74 "47%2Fno-nm-yj*4%2Fno-cc-yj*1%2Fceft-as*1%2Fceft-nqas*0%2Fad-ra-c"
75 "v_p%2Fad-nr-cv_p-f*1%2Fad-v-cv_p*859%2Fad-ns-cv_p-f*1%2Ffn-v-ad%"
76 "2Fpc-t*250%2Fpc-cm*461%2Fpc-s-cr*722%2Fpc-s-t*722%2Fau_p*4"
77 "SICAID=AJKiYcHdKgxum7KMXG0ei2t1-W4OD1uW-ecNsCqC0wDuAXiDGIcT_HA2o1"
78 "3Rs1UKCuBAF9g8rWNOFbxt8PSNSHFuIhOo2t6bJAVpCsMU5Laa6lewuTMYI8MzdQP"
79 "ARHKyW-koxuhMZHUnGBJAM1gJODe0cATO_KGoX4pbbFxxJ5IicRxOrWK_5rU3cdy6"
80 "edlR9FsEdH6iujMcHkbE5l18ehJDwTWmBKBzVD87naobhMMrF6VvnDGxQVGp9Ir_b"
81 "Rgj3RWUoPumQVCxtSOBdX0GlJOEcDTNCzQIm9BSfetog_eP_TfYubKudt5eMsXmN6"
82 "QnyXHeGeK2UINUzJ-D30AFcpqYgH9_1BvYSpi7fc7_ydBU8TaD8ZRxvtnzXqj0RfG"
83 "tuHghmv3aD-uzSYJ75XDdzKdizZ86IG6Fbn1XFhYZM-fbHhm3mVEXnyRW4ZuNOLFk"
84 "Fas6LMcVC6Q8QLlHYbXBpdNFuGbuZGUnav5C-2I_-46lL0NGg3GewxGKGHvHEfoyn"
85 "EFFlEYHsBQ98rXImL8ySDycdLEFvBPdtctPmWCfTxwmoSMLHU2SCVDhbqMWU5b0yr"
86 "JBCScs_ejbKaqBDoB7ZGxTvqlrB__2ZmnHHjCr8RgMRtKNtIeuZAo ";
89 void Initialize(bool stream_should_process_data) {
90 connection_ = new testing::StrictMock<MockConnection>(
91 kIsServer, SupportedVersions(GetParam()));
92 session_.reset(new testing::StrictMock<MockSession>(connection_));
93 stream_.reset(new TestStream(kStreamId, session_.get(),
94 stream_should_process_data));
95 stream2_.reset(new TestStream(kStreamId + 2, session_.get(),
96 stream_should_process_data));
97 write_blocked_list_ =
98 QuicSessionPeer::GetWriteblockedStreams(session_.get());
101 protected:
102 MockConnection* connection_;
103 scoped_ptr<MockSession> session_;
104 scoped_ptr<TestStream> stream_;
105 scoped_ptr<TestStream> stream2_;
106 SpdyHeaderBlock headers_;
107 QuicWriteBlockedList* write_blocked_list_;
110 INSTANTIATE_TEST_CASE_P(Tests, QuicDataStreamTest,
111 ::testing::ValuesIn(QuicSupportedVersions()));
113 TEST_P(QuicDataStreamTest, ProcessHeaders) {
114 Initialize(kShouldProcessData);
116 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
117 stream_->OnStreamHeadersPriority(QuicUtils::HighestPriority());
118 stream_->OnStreamHeaders(headers);
119 EXPECT_EQ(headers, stream_->data());
120 stream_->OnStreamHeadersComplete(false, headers.size());
121 EXPECT_EQ(QuicUtils::HighestPriority(), stream_->EffectivePriority());
122 EXPECT_EQ(headers, stream_->data());
123 EXPECT_FALSE(stream_->IsDoneReading());
126 TEST_P(QuicDataStreamTest, ProcessHeadersAndBody) {
127 Initialize(kShouldProcessData);
129 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
130 string body = "this is the body";
132 stream_->OnStreamHeaders(headers);
133 EXPECT_EQ(headers, stream_->data());
134 stream_->OnStreamHeadersComplete(false, headers.size());
135 QuicStreamFrame frame(kStreamId, false, 0, MakeIOVector(body));
136 stream_->OnStreamFrame(frame);
138 EXPECT_EQ(headers + body, stream_->data());
141 TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyFragments) {
142 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
143 string body = "this is the body";
145 for (size_t fragment_size = 1; fragment_size < body.size();
146 ++fragment_size) {
147 Initialize(kShouldProcessData);
148 for (size_t offset = 0; offset < headers.size();
149 offset += fragment_size) {
150 size_t remaining_data = headers.size() - offset;
151 StringPiece fragment(headers.data() + offset,
152 min(fragment_size, remaining_data));
153 stream_->OnStreamHeaders(fragment);
155 stream_->OnStreamHeadersComplete(false, headers.size());
156 for (size_t offset = 0; offset < body.size(); offset += fragment_size) {
157 size_t remaining_data = body.size() - offset;
158 StringPiece fragment(body.data() + offset,
159 min(fragment_size, remaining_data));
160 QuicStreamFrame frame(kStreamId, false, offset, MakeIOVector(fragment));
161 stream_->OnStreamFrame(frame);
163 ASSERT_EQ(headers + body,
164 stream_->data()) << "fragment_size: " << fragment_size;
168 TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyFragmentsSplit) {
169 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
170 string body = "this is the body";
172 for (size_t split_point = 1; split_point < body.size() - 1; ++split_point) {
173 Initialize(kShouldProcessData);
174 StringPiece headers1(headers.data(), split_point);
175 stream_->OnStreamHeaders(headers1);
177 StringPiece headers2(headers.data() + split_point,
178 headers.size() - split_point);
179 stream_->OnStreamHeaders(headers2);
180 stream_->OnStreamHeadersComplete(false, headers.size());
182 StringPiece fragment1(body.data(), split_point);
183 QuicStreamFrame frame1(kStreamId, false, 0, MakeIOVector(fragment1));
184 stream_->OnStreamFrame(frame1);
186 StringPiece fragment2(body.data() + split_point,
187 body.size() - split_point);
188 QuicStreamFrame frame2(
189 kStreamId, false, split_point, MakeIOVector(fragment2));
190 stream_->OnStreamFrame(frame2);
192 ASSERT_EQ(headers + body,
193 stream_->data()) << "split_point: " << split_point;
197 TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyReadv) {
198 Initialize(!kShouldProcessData);
200 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
201 string body = "this is the body";
203 stream_->OnStreamHeaders(headers);
204 EXPECT_EQ(headers, stream_->data());
205 stream_->OnStreamHeadersComplete(false, headers.size());
206 QuicStreamFrame frame(kStreamId, false, 0, MakeIOVector(body));
207 stream_->OnStreamFrame(frame);
209 char buffer[2048];
210 ASSERT_LT(headers.length() + body.length(), arraysize(buffer));
211 struct iovec vec;
212 vec.iov_base = buffer;
213 vec.iov_len = arraysize(buffer);
215 size_t bytes_read = stream_->Readv(&vec, 1);
216 EXPECT_EQ(headers.length(), bytes_read);
217 EXPECT_EQ(headers, string(buffer, bytes_read));
219 bytes_read = stream_->Readv(&vec, 1);
220 EXPECT_EQ(body.length(), bytes_read);
221 EXPECT_EQ(body, string(buffer, bytes_read));
224 TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyIncrementalReadv) {
225 Initialize(!kShouldProcessData);
227 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
228 string body = "this is the body";
229 stream_->OnStreamHeaders(headers);
230 EXPECT_EQ(headers, stream_->data());
231 stream_->OnStreamHeadersComplete(false, headers.size());
232 QuicStreamFrame frame(kStreamId, false, 0, MakeIOVector(body));
233 stream_->OnStreamFrame(frame);
236 char buffer[1];
237 struct iovec vec;
238 vec.iov_base = buffer;
239 vec.iov_len = arraysize(buffer);
241 string data = headers + body;
242 for (size_t i = 0; i < data.length(); ++i) {
243 size_t bytes_read = stream_->Readv(&vec, 1);
244 ASSERT_EQ(1u, bytes_read);
245 EXPECT_EQ(data.data()[i], buffer[0]);
249 TEST_P(QuicDataStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) {
250 Initialize(!kShouldProcessData);
252 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_);
253 string body = "this is the body";
254 stream_->OnStreamHeaders(headers);
255 EXPECT_EQ(headers, stream_->data());
256 stream_->OnStreamHeadersComplete(false, headers.size());
257 QuicStreamFrame frame(kStreamId, false, 0, MakeIOVector(body));
258 stream_->OnStreamFrame(frame);
261 char buffer1[1];
262 char buffer2[1];
263 struct iovec vec[2];
264 vec[0].iov_base = buffer1;
265 vec[0].iov_len = arraysize(buffer1);
266 vec[1].iov_base = buffer2;
267 vec[1].iov_len = arraysize(buffer2);
268 string data = headers + body;
269 for (size_t i = 0; i < data.length(); i += 2) {
270 size_t bytes_read = stream_->Readv(vec, 2);
271 ASSERT_EQ(2u, bytes_read) << i;
272 ASSERT_EQ(data.data()[i], buffer1[0]) << i;
273 ASSERT_EQ(data.data()[i + 1], buffer2[0]) << i;
277 } // namespace
278 } // namespace test
279 } // namespace net