OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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/quic_data_stream.h" | 5 #include "net/quic/quic_spdy_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_utils.h" | 9 #include "net/quic/quic_utils.h" |
10 #include "net/quic/quic_write_blocked_list.h" | 10 #include "net/quic/quic_write_blocked_list.h" |
11 #include "net/quic/spdy_utils.h" | 11 #include "net/quic/spdy_utils.h" |
12 #include "net/quic/test_tools/quic_flow_controller_peer.h" | 12 #include "net/quic/test_tools/quic_flow_controller_peer.h" |
13 #include "net/quic/test_tools/quic_session_peer.h" | 13 #include "net/quic/test_tools/quic_session_peer.h" |
14 #include "net/quic/test_tools/quic_test_utils.h" | 14 #include "net/quic/test_tools/quic_test_utils.h" |
15 #include "net/quic/test_tools/reliable_quic_stream_peer.h" | 15 #include "net/quic/test_tools/reliable_quic_stream_peer.h" |
16 #include "net/test/gtest_util.h" | 16 #include "net/test/gtest_util.h" |
17 #include "testing/gmock/include/gmock/gmock.h" | 17 #include "testing/gmock/include/gmock/gmock.h" |
18 | 18 |
19 using base::StringPiece; | 19 using base::StringPiece; |
20 using std::min; | 20 using std::min; |
21 using std::string; | 21 using std::string; |
22 using testing::Return; | 22 using testing::Return; |
23 using testing::StrictMock; | 23 using testing::StrictMock; |
24 using testing::_; | 24 using testing::_; |
25 | 25 |
26 namespace net { | 26 namespace net { |
27 namespace test { | 27 namespace test { |
28 namespace { | 28 namespace { |
29 | 29 |
30 const bool kShouldProcessData = true; | 30 const bool kShouldProcessData = true; |
31 | 31 |
32 class TestStream : public QuicDataStream { | 32 class TestStream : public QuicSpdyStream { |
33 public: | 33 public: |
34 TestStream(QuicStreamId id, | 34 TestStream(QuicStreamId id, |
35 QuicSpdySession* session, | 35 QuicSpdySession* session, |
36 bool should_process_data) | 36 bool should_process_data) |
37 : QuicDataStream(id, session), | 37 : QuicSpdyStream(id, session), |
38 should_process_data_(should_process_data) {} | 38 should_process_data_(should_process_data) {} |
39 | 39 |
40 void OnDataAvailable() override { | 40 void OnDataAvailable() override { |
41 if (!should_process_data_) { | 41 if (!should_process_data_) { |
42 return; | 42 return; |
43 } | 43 } |
44 char buffer[2048]; | 44 char buffer[2048]; |
45 struct iovec vec; | 45 struct iovec vec; |
46 vec.iov_base = buffer; | 46 vec.iov_base = buffer; |
47 vec.iov_len = arraysize(buffer); | 47 vec.iov_len = arraysize(buffer); |
48 size_t bytes_read = Readv(&vec, 1); | 48 size_t bytes_read = Readv(&vec, 1); |
49 data_ += string(buffer, bytes_read); | 49 data_ += string(buffer, bytes_read); |
50 } | 50 } |
51 | 51 |
52 using ReliableQuicStream::WriteOrBufferData; | 52 using ReliableQuicStream::WriteOrBufferData; |
53 using ReliableQuicStream::CloseWriteSide; | 53 using ReliableQuicStream::CloseWriteSide; |
54 | 54 |
55 const string& data() const { return data_; } | 55 const string& data() const { return data_; } |
56 | 56 |
57 private: | 57 private: |
58 bool should_process_data_; | 58 bool should_process_data_; |
59 string data_; | 59 string data_; |
60 }; | 60 }; |
61 | 61 |
62 class QuicDataStreamTest : public ::testing::Test { | 62 class QuicSpdyStreamTest : public ::testing::Test { |
63 public: | 63 public: |
64 QuicDataStreamTest() { | 64 QuicSpdyStreamTest() { |
65 headers_[":host"] = "www.google.com"; | 65 headers_[":host"] = "www.google.com"; |
66 headers_[":path"] = "/index.hml"; | 66 headers_[":path"] = "/index.hml"; |
67 headers_[":scheme"] = "https"; | 67 headers_[":scheme"] = "https"; |
68 headers_["cookie"] = | 68 headers_["cookie"] = |
69 "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; " | 69 "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; " |
70 "__utmc=160408618; " | 70 "__utmc=160408618; " |
71 "GX=DQAAAOEAAACWJYdewdE9rIrW6qw3PtVi2-d729qaa-74KqOsM1NVQblK4VhX" | 71 "GX=DQAAAOEAAACWJYdewdE9rIrW6qw3PtVi2-d729qaa-74KqOsM1NVQblK4VhX" |
72 "hoALMsy6HOdDad2Sz0flUByv7etmo3mLMidGrBoljqO9hSVA40SLqpG_iuKKSHX" | 72 "hoALMsy6HOdDad2Sz0flUByv7etmo3mLMidGrBoljqO9hSVA40SLqpG_iuKKSHX" |
73 "RW3Np4bq0F0SDGDNsW0DSmTS9ufMRrlpARJDS7qAI6M3bghqJp4eABKZiRqebHT" | 73 "RW3Np4bq0F0SDGDNsW0DSmTS9ufMRrlpARJDS7qAI6M3bghqJp4eABKZiRqebHT" |
74 "pMU-RXvTI5D5oCF1vYxYofH_l1Kviuiy3oQ1kS1enqWgbhJ2t61_SNdv-1XJIS0" | 74 "pMU-RXvTI5D5oCF1vYxYofH_l1Kviuiy3oQ1kS1enqWgbhJ2t61_SNdv-1XJIS0" |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 protected: | 106 protected: |
107 MockHelper helper_; | 107 MockHelper helper_; |
108 MockConnection* connection_; | 108 MockConnection* connection_; |
109 scoped_ptr<MockQuicSpdySession> session_; | 109 scoped_ptr<MockQuicSpdySession> session_; |
110 scoped_ptr<TestStream> stream_; | 110 scoped_ptr<TestStream> stream_; |
111 scoped_ptr<TestStream> stream2_; | 111 scoped_ptr<TestStream> stream2_; |
112 SpdyHeaderBlock headers_; | 112 SpdyHeaderBlock headers_; |
113 QuicWriteBlockedList* write_blocked_list_; | 113 QuicWriteBlockedList* write_blocked_list_; |
114 }; | 114 }; |
115 | 115 |
116 TEST_F(QuicDataStreamTest, ProcessHeaders) { | 116 TEST_F(QuicSpdyStreamTest, ProcessHeaders) { |
117 Initialize(kShouldProcessData); | 117 Initialize(kShouldProcessData); |
118 | 118 |
119 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 119 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
120 stream_->OnStreamHeadersPriority(QuicUtils::HighestPriority()); | 120 stream_->OnStreamHeadersPriority(QuicUtils::HighestPriority()); |
121 stream_->OnStreamHeaders(headers); | 121 stream_->OnStreamHeaders(headers); |
122 EXPECT_EQ("", stream_->data()); | 122 EXPECT_EQ("", stream_->data()); |
123 EXPECT_EQ(headers, stream_->decompressed_headers()); | 123 EXPECT_EQ(headers, stream_->decompressed_headers()); |
124 stream_->OnStreamHeadersComplete(false, headers.size()); | 124 stream_->OnStreamHeadersComplete(false, headers.size()); |
125 EXPECT_EQ(QuicUtils::HighestPriority(), stream_->EffectivePriority()); | 125 EXPECT_EQ(QuicUtils::HighestPriority(), stream_->EffectivePriority()); |
126 EXPECT_EQ("", stream_->data()); | 126 EXPECT_EQ("", stream_->data()); |
127 EXPECT_EQ(headers, stream_->decompressed_headers()); | 127 EXPECT_EQ(headers, stream_->decompressed_headers()); |
128 EXPECT_FALSE(stream_->IsDoneReading()); | 128 EXPECT_FALSE(stream_->IsDoneReading()); |
129 } | 129 } |
130 | 130 |
131 TEST_F(QuicDataStreamTest, ProcessHeadersWithFin) { | 131 TEST_F(QuicSpdyStreamTest, ProcessHeadersWithFin) { |
132 Initialize(kShouldProcessData); | 132 Initialize(kShouldProcessData); |
133 | 133 |
134 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 134 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
135 stream_->OnStreamHeadersPriority(QuicUtils::HighestPriority()); | 135 stream_->OnStreamHeadersPriority(QuicUtils::HighestPriority()); |
136 stream_->OnStreamHeaders(headers); | 136 stream_->OnStreamHeaders(headers); |
137 EXPECT_EQ("", stream_->data()); | 137 EXPECT_EQ("", stream_->data()); |
138 EXPECT_EQ(headers, stream_->decompressed_headers()); | 138 EXPECT_EQ(headers, stream_->decompressed_headers()); |
139 stream_->OnStreamHeadersComplete(true, headers.size()); | 139 stream_->OnStreamHeadersComplete(true, headers.size()); |
140 EXPECT_EQ(QuicUtils::HighestPriority(), stream_->EffectivePriority()); | 140 EXPECT_EQ(QuicUtils::HighestPriority(), stream_->EffectivePriority()); |
141 EXPECT_EQ("", stream_->data()); | 141 EXPECT_EQ("", stream_->data()); |
142 EXPECT_EQ(headers, stream_->decompressed_headers()); | 142 EXPECT_EQ(headers, stream_->decompressed_headers()); |
143 EXPECT_FALSE(stream_->IsDoneReading()); | 143 EXPECT_FALSE(stream_->IsDoneReading()); |
144 EXPECT_TRUE(stream_->HasFinalReceivedByteOffset()); | 144 EXPECT_TRUE(stream_->HasFinalReceivedByteOffset()); |
145 } | 145 } |
146 | 146 |
147 TEST_F(QuicDataStreamTest, MarkHeadersConsumed) { | 147 TEST_F(QuicSpdyStreamTest, MarkHeadersConsumed) { |
148 Initialize(kShouldProcessData); | 148 Initialize(kShouldProcessData); |
149 | 149 |
150 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 150 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
151 string body = "this is the body"; | 151 string body = "this is the body"; |
152 | 152 |
153 stream_->OnStreamHeaders(headers); | 153 stream_->OnStreamHeaders(headers); |
154 stream_->OnStreamHeadersComplete(false, headers.size()); | 154 stream_->OnStreamHeadersComplete(false, headers.size()); |
155 EXPECT_EQ(headers, stream_->decompressed_headers()); | 155 EXPECT_EQ(headers, stream_->decompressed_headers()); |
156 | 156 |
157 headers.erase(0, 10); | 157 headers.erase(0, 10); |
158 stream_->MarkHeadersConsumed(10); | 158 stream_->MarkHeadersConsumed(10); |
159 EXPECT_EQ(headers, stream_->decompressed_headers()); | 159 EXPECT_EQ(headers, stream_->decompressed_headers()); |
160 | 160 |
161 stream_->MarkHeadersConsumed(headers.length()); | 161 stream_->MarkHeadersConsumed(headers.length()); |
162 EXPECT_EQ("", stream_->decompressed_headers()); | 162 EXPECT_EQ("", stream_->decompressed_headers()); |
163 } | 163 } |
164 | 164 |
165 TEST_F(QuicDataStreamTest, ProcessHeadersAndBody) { | 165 TEST_F(QuicSpdyStreamTest, ProcessHeadersAndBody) { |
166 Initialize(kShouldProcessData); | 166 Initialize(kShouldProcessData); |
167 | 167 |
168 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 168 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
169 string body = "this is the body"; | 169 string body = "this is the body"; |
170 | 170 |
171 stream_->OnStreamHeaders(headers); | 171 stream_->OnStreamHeaders(headers); |
172 EXPECT_EQ("", stream_->data()); | 172 EXPECT_EQ("", stream_->data()); |
173 EXPECT_EQ(headers, stream_->decompressed_headers()); | 173 EXPECT_EQ(headers, stream_->decompressed_headers()); |
174 stream_->OnStreamHeadersComplete(false, headers.size()); | 174 stream_->OnStreamHeadersComplete(false, headers.size()); |
175 EXPECT_EQ(headers, stream_->decompressed_headers()); | 175 EXPECT_EQ(headers, stream_->decompressed_headers()); |
176 stream_->MarkHeadersConsumed(headers.length()); | 176 stream_->MarkHeadersConsumed(headers.length()); |
177 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); | 177 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); |
178 stream_->OnStreamFrame(frame); | 178 stream_->OnStreamFrame(frame); |
179 EXPECT_EQ("", stream_->decompressed_headers()); | 179 EXPECT_EQ("", stream_->decompressed_headers()); |
180 EXPECT_EQ(body, stream_->data()); | 180 EXPECT_EQ(body, stream_->data()); |
181 } | 181 } |
182 | 182 |
183 TEST_F(QuicDataStreamTest, ProcessHeadersAndBodyFragments) { | 183 TEST_F(QuicSpdyStreamTest, ProcessHeadersAndBodyFragments) { |
184 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 184 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
185 string body = "this is the body"; | 185 string body = "this is the body"; |
186 | 186 |
187 for (size_t fragment_size = 1; fragment_size < body.size(); | 187 for (size_t fragment_size = 1; fragment_size < body.size(); ++fragment_size) { |
188 ++fragment_size) { | |
189 Initialize(kShouldProcessData); | 188 Initialize(kShouldProcessData); |
190 for (size_t offset = 0; offset < headers.size(); | 189 for (size_t offset = 0; offset < headers.size(); offset += fragment_size) { |
191 offset += fragment_size) { | |
192 size_t remaining_data = headers.size() - offset; | 190 size_t remaining_data = headers.size() - offset; |
193 StringPiece fragment(headers.data() + offset, | 191 StringPiece fragment(headers.data() + offset, |
194 min(fragment_size, remaining_data)); | 192 min(fragment_size, remaining_data)); |
195 stream_->OnStreamHeaders(fragment); | 193 stream_->OnStreamHeaders(fragment); |
196 } | 194 } |
197 stream_->OnStreamHeadersComplete(false, headers.size()); | 195 stream_->OnStreamHeadersComplete(false, headers.size()); |
198 ASSERT_EQ(headers, stream_->decompressed_headers()) | 196 ASSERT_EQ(headers, stream_->decompressed_headers()) << "fragment_size: " |
199 << "fragment_size: " << fragment_size; | 197 << fragment_size; |
200 stream_->MarkHeadersConsumed(headers.length()); | 198 stream_->MarkHeadersConsumed(headers.length()); |
201 for (size_t offset = 0; offset < body.size(); offset += fragment_size) { | 199 for (size_t offset = 0; offset < body.size(); offset += fragment_size) { |
202 size_t remaining_data = body.size() - offset; | 200 size_t remaining_data = body.size() - offset; |
203 StringPiece fragment(body.data() + offset, | 201 StringPiece fragment(body.data() + offset, |
204 min(fragment_size, remaining_data)); | 202 min(fragment_size, remaining_data)); |
205 QuicStreamFrame frame(kClientDataStreamId1, false, offset, | 203 QuicStreamFrame frame(kClientDataStreamId1, false, offset, |
206 StringPiece(fragment)); | 204 StringPiece(fragment)); |
207 stream_->OnStreamFrame(frame); | 205 stream_->OnStreamFrame(frame); |
208 } | 206 } |
209 ASSERT_EQ(body, stream_->data()) << "fragment_size: " << fragment_size; | 207 ASSERT_EQ(body, stream_->data()) << "fragment_size: " << fragment_size; |
210 } | 208 } |
211 } | 209 } |
212 | 210 |
213 TEST_F(QuicDataStreamTest, ProcessHeadersAndBodyFragmentsSplit) { | 211 TEST_F(QuicSpdyStreamTest, ProcessHeadersAndBodyFragmentsSplit) { |
214 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 212 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
215 string body = "this is the body"; | 213 string body = "this is the body"; |
216 | 214 |
217 for (size_t split_point = 1; split_point < body.size() - 1; ++split_point) { | 215 for (size_t split_point = 1; split_point < body.size() - 1; ++split_point) { |
218 Initialize(kShouldProcessData); | 216 Initialize(kShouldProcessData); |
219 StringPiece headers1(headers.data(), split_point); | 217 StringPiece headers1(headers.data(), split_point); |
220 stream_->OnStreamHeaders(headers1); | 218 stream_->OnStreamHeaders(headers1); |
221 | 219 |
222 StringPiece headers2(headers.data() + split_point, | 220 StringPiece headers2(headers.data() + split_point, |
223 headers.size() - split_point); | 221 headers.size() - split_point); |
224 stream_->OnStreamHeaders(headers2); | 222 stream_->OnStreamHeaders(headers2); |
225 stream_->OnStreamHeadersComplete(false, headers.size()); | 223 stream_->OnStreamHeadersComplete(false, headers.size()); |
226 ASSERT_EQ(headers, stream_->decompressed_headers()) | 224 ASSERT_EQ(headers, stream_->decompressed_headers()) << "split_point: " |
227 << "split_point: " << split_point; | 225 << split_point; |
228 stream_->MarkHeadersConsumed(headers.length()); | 226 stream_->MarkHeadersConsumed(headers.length()); |
229 | 227 |
230 StringPiece fragment1(body.data(), split_point); | 228 StringPiece fragment1(body.data(), split_point); |
231 QuicStreamFrame frame1(kClientDataStreamId1, false, 0, | 229 QuicStreamFrame frame1(kClientDataStreamId1, false, 0, |
232 StringPiece(fragment1)); | 230 StringPiece(fragment1)); |
233 stream_->OnStreamFrame(frame1); | 231 stream_->OnStreamFrame(frame1); |
234 | 232 |
235 StringPiece fragment2(body.data() + split_point, | 233 StringPiece fragment2(body.data() + split_point, body.size() - split_point); |
236 body.size() - split_point); | |
237 QuicStreamFrame frame2(kClientDataStreamId1, false, split_point, | 234 QuicStreamFrame frame2(kClientDataStreamId1, false, split_point, |
238 StringPiece(fragment2)); | 235 StringPiece(fragment2)); |
239 stream_->OnStreamFrame(frame2); | 236 stream_->OnStreamFrame(frame2); |
240 | 237 |
241 ASSERT_EQ(body, stream_->data()) << "split_point: " << split_point; | 238 ASSERT_EQ(body, stream_->data()) << "split_point: " << split_point; |
242 } | 239 } |
243 } | 240 } |
244 | 241 |
245 TEST_F(QuicDataStreamTest, ProcessHeadersAndBodyReadv) { | 242 TEST_F(QuicSpdyStreamTest, ProcessHeadersAndBodyReadv) { |
246 Initialize(!kShouldProcessData); | 243 Initialize(!kShouldProcessData); |
247 | 244 |
248 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 245 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
249 string body = "this is the body"; | 246 string body = "this is the body"; |
250 | 247 |
251 stream_->OnStreamHeaders(headers); | 248 stream_->OnStreamHeaders(headers); |
252 stream_->OnStreamHeadersComplete(false, headers.size()); | 249 stream_->OnStreamHeadersComplete(false, headers.size()); |
253 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); | 250 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); |
254 stream_->OnStreamFrame(frame); | 251 stream_->OnStreamFrame(frame); |
255 stream_->MarkHeadersConsumed(headers.length()); | 252 stream_->MarkHeadersConsumed(headers.length()); |
256 | 253 |
257 char buffer[2048]; | 254 char buffer[2048]; |
258 ASSERT_LT(body.length(), arraysize(buffer)); | 255 ASSERT_LT(body.length(), arraysize(buffer)); |
259 struct iovec vec; | 256 struct iovec vec; |
260 vec.iov_base = buffer; | 257 vec.iov_base = buffer; |
261 vec.iov_len = arraysize(buffer); | 258 vec.iov_len = arraysize(buffer); |
262 | 259 |
263 size_t bytes_read = stream_->Readv(&vec, 1); | 260 size_t bytes_read = stream_->Readv(&vec, 1); |
264 EXPECT_EQ(body.length(), bytes_read); | 261 EXPECT_EQ(body.length(), bytes_read); |
265 EXPECT_EQ(body, string(buffer, bytes_read)); | 262 EXPECT_EQ(body, string(buffer, bytes_read)); |
266 } | 263 } |
267 | 264 |
268 TEST_F(QuicDataStreamTest, ProcessHeadersAndBodyMarkConsumed) { | 265 TEST_F(QuicSpdyStreamTest, ProcessHeadersAndBodyMarkConsumed) { |
269 Initialize(!kShouldProcessData); | 266 Initialize(!kShouldProcessData); |
270 | 267 |
271 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 268 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
272 string body = "this is the body"; | 269 string body = "this is the body"; |
273 | 270 |
274 stream_->OnStreamHeaders(headers); | 271 stream_->OnStreamHeaders(headers); |
275 stream_->OnStreamHeadersComplete(false, headers.size()); | 272 stream_->OnStreamHeadersComplete(false, headers.size()); |
276 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); | 273 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); |
277 stream_->OnStreamFrame(frame); | 274 stream_->OnStreamFrame(frame); |
278 stream_->MarkHeadersConsumed(headers.length()); | 275 stream_->MarkHeadersConsumed(headers.length()); |
279 | 276 |
280 struct iovec vec; | 277 struct iovec vec; |
281 | 278 |
282 EXPECT_EQ(1, stream_->GetReadableRegions(&vec, 1)); | 279 EXPECT_EQ(1, stream_->GetReadableRegions(&vec, 1)); |
283 EXPECT_EQ(body.length(), vec.iov_len); | 280 EXPECT_EQ(body.length(), vec.iov_len); |
284 EXPECT_EQ(body, string(static_cast<char*>(vec.iov_base), vec.iov_len)); | 281 EXPECT_EQ(body, string(static_cast<char*>(vec.iov_base), vec.iov_len)); |
285 | 282 |
286 stream_->MarkConsumed(body.length()); | 283 stream_->MarkConsumed(body.length()); |
287 EXPECT_EQ(body.length(), stream_->flow_controller()->bytes_consumed()); | 284 EXPECT_EQ(body.length(), stream_->flow_controller()->bytes_consumed()); |
288 } | 285 } |
289 | 286 |
290 TEST_F(QuicDataStreamTest, ProcessHeadersAndBodyIncrementalReadv) { | 287 TEST_F(QuicSpdyStreamTest, ProcessHeadersAndBodyIncrementalReadv) { |
291 Initialize(!kShouldProcessData); | 288 Initialize(!kShouldProcessData); |
292 | 289 |
293 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 290 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
294 string body = "this is the body"; | 291 string body = "this is the body"; |
295 stream_->OnStreamHeaders(headers); | 292 stream_->OnStreamHeaders(headers); |
296 stream_->OnStreamHeadersComplete(false, headers.size()); | 293 stream_->OnStreamHeadersComplete(false, headers.size()); |
297 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); | 294 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); |
298 stream_->OnStreamFrame(frame); | 295 stream_->OnStreamFrame(frame); |
299 stream_->MarkHeadersConsumed(headers.length()); | 296 stream_->MarkHeadersConsumed(headers.length()); |
300 | 297 |
301 char buffer[1]; | 298 char buffer[1]; |
302 struct iovec vec; | 299 struct iovec vec; |
303 vec.iov_base = buffer; | 300 vec.iov_base = buffer; |
304 vec.iov_len = arraysize(buffer); | 301 vec.iov_len = arraysize(buffer); |
305 | 302 |
306 for (size_t i = 0; i < body.length(); ++i) { | 303 for (size_t i = 0; i < body.length(); ++i) { |
307 size_t bytes_read = stream_->Readv(&vec, 1); | 304 size_t bytes_read = stream_->Readv(&vec, 1); |
308 ASSERT_EQ(1u, bytes_read); | 305 ASSERT_EQ(1u, bytes_read); |
309 EXPECT_EQ(body.data()[i], buffer[0]); | 306 EXPECT_EQ(body.data()[i], buffer[0]); |
310 } | 307 } |
311 } | 308 } |
312 | 309 |
313 TEST_F(QuicDataStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) { | 310 TEST_F(QuicSpdyStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) { |
314 Initialize(!kShouldProcessData); | 311 Initialize(!kShouldProcessData); |
315 | 312 |
316 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 313 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
317 string body = "this is the body"; | 314 string body = "this is the body"; |
318 stream_->OnStreamHeaders(headers); | 315 stream_->OnStreamHeaders(headers); |
319 stream_->OnStreamHeadersComplete(false, headers.size()); | 316 stream_->OnStreamHeadersComplete(false, headers.size()); |
320 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); | 317 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); |
321 stream_->OnStreamFrame(frame); | 318 stream_->OnStreamFrame(frame); |
322 stream_->MarkHeadersConsumed(headers.length()); | 319 stream_->MarkHeadersConsumed(headers.length()); |
323 | 320 |
324 char buffer1[1]; | 321 char buffer1[1]; |
325 char buffer2[1]; | 322 char buffer2[1]; |
326 struct iovec vec[2]; | 323 struct iovec vec[2]; |
327 vec[0].iov_base = buffer1; | 324 vec[0].iov_base = buffer1; |
328 vec[0].iov_len = arraysize(buffer1); | 325 vec[0].iov_len = arraysize(buffer1); |
329 vec[1].iov_base = buffer2; | 326 vec[1].iov_base = buffer2; |
330 vec[1].iov_len = arraysize(buffer2); | 327 vec[1].iov_len = arraysize(buffer2); |
331 | 328 |
332 for (size_t i = 0; i < body.length(); i += 2) { | 329 for (size_t i = 0; i < body.length(); i += 2) { |
333 size_t bytes_read = stream_->Readv(vec, 2); | 330 size_t bytes_read = stream_->Readv(vec, 2); |
334 ASSERT_EQ(2u, bytes_read) << i; | 331 ASSERT_EQ(2u, bytes_read) << i; |
335 ASSERT_EQ(body.data()[i], buffer1[0]) << i; | 332 ASSERT_EQ(body.data()[i], buffer1[0]) << i; |
336 ASSERT_EQ(body.data()[i + 1], buffer2[0]) << i; | 333 ASSERT_EQ(body.data()[i + 1], buffer2[0]) << i; |
337 } | 334 } |
338 } | 335 } |
339 | 336 |
340 TEST_F(QuicDataStreamTest, StreamFlowControlBlocked) { | 337 TEST_F(QuicSpdyStreamTest, StreamFlowControlBlocked) { |
341 // Tests that we send a BLOCKED frame to the peer when we attempt to write, | 338 // Tests that we send a BLOCKED frame to the peer when we attempt to write, |
342 // but are flow control blocked. | 339 // but are flow control blocked. |
343 Initialize(kShouldProcessData); | 340 Initialize(kShouldProcessData); |
344 | 341 |
345 // Set a small flow control limit. | 342 // Set a small flow control limit. |
346 const uint64 kWindow = 36; | 343 const uint64 kWindow = 36; |
347 QuicFlowControllerPeer::SetSendWindowOffset(stream_->flow_controller(), | 344 QuicFlowControllerPeer::SetSendWindowOffset(stream_->flow_controller(), |
348 kWindow); | 345 kWindow); |
349 EXPECT_EQ(kWindow, QuicFlowControllerPeer::SendWindowOffset( | 346 EXPECT_EQ(kWindow, QuicFlowControllerPeer::SendWindowOffset( |
350 stream_->flow_controller())); | 347 stream_->flow_controller())); |
351 | 348 |
352 // Try to send more data than the flow control limit allows. | 349 // Try to send more data than the flow control limit allows. |
353 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 350 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
354 string body; | 351 string body; |
355 const uint64 kOverflow = 15; | 352 const uint64 kOverflow = 15; |
356 GenerateBody(&body, kWindow + kOverflow); | 353 GenerateBody(&body, kWindow + kOverflow); |
357 | 354 |
358 EXPECT_CALL(*connection_, SendBlocked(kClientDataStreamId1)); | 355 EXPECT_CALL(*connection_, SendBlocked(kClientDataStreamId1)); |
359 EXPECT_CALL(*session_, WritevData(kClientDataStreamId1, _, _, _, _, _)) | 356 EXPECT_CALL(*session_, WritevData(kClientDataStreamId1, _, _, _, _, _)) |
360 .WillOnce(Return(QuicConsumedData(kWindow, true))); | 357 .WillOnce(Return(QuicConsumedData(kWindow, true))); |
361 stream_->WriteOrBufferData(body, false, nullptr); | 358 stream_->WriteOrBufferData(body, false, nullptr); |
362 | 359 |
363 // Should have sent as much as possible, resulting in no send window left. | 360 // Should have sent as much as possible, resulting in no send window left. |
364 EXPECT_EQ(0u, | 361 EXPECT_EQ(0u, |
365 QuicFlowControllerPeer::SendWindowSize(stream_->flow_controller())); | 362 QuicFlowControllerPeer::SendWindowSize(stream_->flow_controller())); |
366 | 363 |
367 // And we should have queued the overflowed data. | 364 // And we should have queued the overflowed data. |
368 EXPECT_EQ(kOverflow, | 365 EXPECT_EQ(kOverflow, ReliableQuicStreamPeer::SizeOfQueuedData(stream_.get())); |
369 ReliableQuicStreamPeer::SizeOfQueuedData(stream_.get())); | |
370 } | 366 } |
371 | 367 |
372 TEST_F(QuicDataStreamTest, StreamFlowControlNoWindowUpdateIfNotConsumed) { | 368 TEST_F(QuicSpdyStreamTest, StreamFlowControlNoWindowUpdateIfNotConsumed) { |
373 // The flow control receive window decreases whenever we add new bytes to the | 369 // The flow control receive window decreases whenever we add new bytes to the |
374 // sequencer, whether they are consumed immediately or buffered. However we | 370 // sequencer, whether they are consumed immediately or buffered. However we |
375 // only send WINDOW_UPDATE frames based on increasing number of bytes | 371 // only send WINDOW_UPDATE frames based on increasing number of bytes |
376 // consumed. | 372 // consumed. |
377 | 373 |
378 // Don't process data - it will be buffered instead. | 374 // Don't process data - it will be buffered instead. |
379 Initialize(!kShouldProcessData); | 375 Initialize(!kShouldProcessData); |
380 | 376 |
381 // Expect no WINDOW_UPDATE frames to be sent. | 377 // Expect no WINDOW_UPDATE frames to be sent. |
382 EXPECT_CALL(*connection_, SendWindowUpdate(_, _)).Times(0); | 378 EXPECT_CALL(*connection_, SendWindowUpdate(_, _)).Times(0); |
(...skipping 23 matching lines...) Expand all Loading... |
406 // half full. This should all be buffered, decreasing the receive window but | 402 // half full. This should all be buffered, decreasing the receive window but |
407 // not sending WINDOW_UPDATE. | 403 // not sending WINDOW_UPDATE. |
408 QuicStreamFrame frame2(kClientDataStreamId1, false, kWindow / 3, | 404 QuicStreamFrame frame2(kClientDataStreamId1, false, kWindow / 3, |
409 StringPiece(body)); | 405 StringPiece(body)); |
410 stream_->OnStreamFrame(frame2); | 406 stream_->OnStreamFrame(frame2); |
411 EXPECT_EQ( | 407 EXPECT_EQ( |
412 kWindow - (2 * kWindow / 3), | 408 kWindow - (2 * kWindow / 3), |
413 QuicFlowControllerPeer::ReceiveWindowSize(stream_->flow_controller())); | 409 QuicFlowControllerPeer::ReceiveWindowSize(stream_->flow_controller())); |
414 } | 410 } |
415 | 411 |
416 TEST_F(QuicDataStreamTest, StreamFlowControlWindowUpdate) { | 412 TEST_F(QuicSpdyStreamTest, StreamFlowControlWindowUpdate) { |
417 // Tests that on receipt of data, the stream updates its receive window offset | 413 // Tests that on receipt of data, the stream updates its receive window offset |
418 // appropriately, and sends WINDOW_UPDATE frames when its receive window drops | 414 // appropriately, and sends WINDOW_UPDATE frames when its receive window drops |
419 // too low. | 415 // too low. |
420 Initialize(kShouldProcessData); | 416 Initialize(kShouldProcessData); |
421 | 417 |
422 // Set a small flow control limit. | 418 // Set a small flow control limit. |
423 const uint64 kWindow = 36; | 419 const uint64 kWindow = 36; |
424 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), | 420 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), |
425 kWindow); | 421 kWindow); |
426 QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(), | 422 QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(), |
(...skipping 23 matching lines...) Expand all Loading... |
450 EXPECT_CALL(*connection_, | 446 EXPECT_CALL(*connection_, |
451 SendWindowUpdate(kClientDataStreamId1, | 447 SendWindowUpdate(kClientDataStreamId1, |
452 QuicFlowControllerPeer::ReceiveWindowOffset( | 448 QuicFlowControllerPeer::ReceiveWindowOffset( |
453 stream_->flow_controller()) + | 449 stream_->flow_controller()) + |
454 2 * kWindow / 3)); | 450 2 * kWindow / 3)); |
455 stream_->OnStreamFrame(frame2); | 451 stream_->OnStreamFrame(frame2); |
456 EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowSize( | 452 EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowSize( |
457 stream_->flow_controller())); | 453 stream_->flow_controller())); |
458 } | 454 } |
459 | 455 |
460 TEST_F(QuicDataStreamTest, ConnectionFlowControlWindowUpdate) { | 456 TEST_F(QuicSpdyStreamTest, ConnectionFlowControlWindowUpdate) { |
461 // Tests that on receipt of data, the connection updates its receive window | 457 // Tests that on receipt of data, the connection updates its receive window |
462 // offset appropriately, and sends WINDOW_UPDATE frames when its receive | 458 // offset appropriately, and sends WINDOW_UPDATE frames when its receive |
463 // window drops too low. | 459 // window drops too low. |
464 Initialize(kShouldProcessData); | 460 Initialize(kShouldProcessData); |
465 | 461 |
466 // Set a small flow control limit for streams and connection. | 462 // Set a small flow control limit for streams and connection. |
467 const uint64 kWindow = 36; | 463 const uint64 kWindow = 36; |
468 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), | 464 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), |
469 kWindow); | 465 kWindow); |
470 QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(), | 466 QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(), |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
503 EXPECT_CALL(*connection_, SendWindowUpdate(kClientDataStreamId2, _)).Times(0); | 499 EXPECT_CALL(*connection_, SendWindowUpdate(kClientDataStreamId2, _)).Times(0); |
504 EXPECT_CALL(*connection_, | 500 EXPECT_CALL(*connection_, |
505 SendWindowUpdate(0, QuicFlowControllerPeer::ReceiveWindowOffset( | 501 SendWindowUpdate(0, QuicFlowControllerPeer::ReceiveWindowOffset( |
506 session_->flow_controller()) + | 502 session_->flow_controller()) + |
507 1 + kWindow / 2)); | 503 1 + kWindow / 2)); |
508 QuicStreamFrame frame3(kClientDataStreamId1, false, (kWindow / 4), | 504 QuicStreamFrame frame3(kClientDataStreamId1, false, (kWindow / 4), |
509 StringPiece("a")); | 505 StringPiece("a")); |
510 stream_->OnStreamFrame(frame3); | 506 stream_->OnStreamFrame(frame3); |
511 } | 507 } |
512 | 508 |
513 TEST_F(QuicDataStreamTest, StreamFlowControlViolation) { | 509 TEST_F(QuicSpdyStreamTest, StreamFlowControlViolation) { |
514 // Tests that on if the peer sends too much data (i.e. violates the flow | 510 // Tests that on if the peer sends too much data (i.e. violates the flow |
515 // control protocol), then we terminate the connection. | 511 // control protocol), then we terminate the connection. |
516 | 512 |
517 // Stream should not process data, so that data gets buffered in the | 513 // Stream should not process data, so that data gets buffered in the |
518 // sequencer, triggering flow control limits. | 514 // sequencer, triggering flow control limits. |
519 Initialize(!kShouldProcessData); | 515 Initialize(!kShouldProcessData); |
520 | 516 |
521 // Set a small flow control limit. | 517 // Set a small flow control limit. |
522 const uint64 kWindow = 50; | 518 const uint64 kWindow = 50; |
523 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), | 519 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), |
524 kWindow); | 520 kWindow); |
525 | 521 |
526 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 522 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
527 stream_->OnStreamHeaders(headers); | 523 stream_->OnStreamHeaders(headers); |
528 stream_->OnStreamHeadersComplete(false, headers.size()); | 524 stream_->OnStreamHeadersComplete(false, headers.size()); |
529 | 525 |
530 // Receive data to overflow the window, violating flow control. | 526 // Receive data to overflow the window, violating flow control. |
531 string body; | 527 string body; |
532 GenerateBody(&body, kWindow + 1); | 528 GenerateBody(&body, kWindow + 1); |
533 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); | 529 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); |
534 EXPECT_CALL(*connection_, | 530 EXPECT_CALL(*connection_, |
535 SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA)); | 531 SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA)); |
536 stream_->OnStreamFrame(frame); | 532 stream_->OnStreamFrame(frame); |
537 } | 533 } |
538 | 534 |
539 TEST_F(QuicDataStreamTest, ConnectionFlowControlViolation) { | 535 TEST_F(QuicSpdyStreamTest, ConnectionFlowControlViolation) { |
540 // Tests that on if the peer sends too much data (i.e. violates the flow | 536 // Tests that on if the peer sends too much data (i.e. violates the flow |
541 // control protocol), at the connection level (rather than the stream level) | 537 // control protocol), at the connection level (rather than the stream level) |
542 // then we terminate the connection. | 538 // then we terminate the connection. |
543 | 539 |
544 // Stream should not process data, so that data gets buffered in the | 540 // Stream should not process data, so that data gets buffered in the |
545 // sequencer, triggering flow control limits. | 541 // sequencer, triggering flow control limits. |
546 Initialize(!kShouldProcessData); | 542 Initialize(!kShouldProcessData); |
547 | 543 |
548 // Set a small flow control window on streams, and connection. | 544 // Set a small flow control window on streams, and connection. |
549 const uint64 kStreamWindow = 50; | 545 const uint64 kStreamWindow = 50; |
550 const uint64 kConnectionWindow = 10; | 546 const uint64 kConnectionWindow = 10; |
551 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), | 547 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), |
552 kStreamWindow); | 548 kStreamWindow); |
553 QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(), | 549 QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(), |
554 kConnectionWindow); | 550 kConnectionWindow); |
555 | 551 |
556 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 552 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
557 stream_->OnStreamHeaders(headers); | 553 stream_->OnStreamHeaders(headers); |
558 stream_->OnStreamHeadersComplete(false, headers.size()); | 554 stream_->OnStreamHeadersComplete(false, headers.size()); |
559 | 555 |
560 // Send enough data to overflow the connection level flow control window. | 556 // Send enough data to overflow the connection level flow control window. |
561 string body; | 557 string body; |
562 GenerateBody(&body, kConnectionWindow + 1); | 558 GenerateBody(&body, kConnectionWindow + 1); |
563 EXPECT_LT(body.size(), kStreamWindow); | 559 EXPECT_LT(body.size(), kStreamWindow); |
564 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); | 560 QuicStreamFrame frame(kClientDataStreamId1, false, 0, StringPiece(body)); |
565 | 561 |
566 EXPECT_CALL(*connection_, | 562 EXPECT_CALL(*connection_, |
567 SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA)); | 563 SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA)); |
568 stream_->OnStreamFrame(frame); | 564 stream_->OnStreamFrame(frame); |
569 } | 565 } |
570 | 566 |
571 TEST_F(QuicDataStreamTest, StreamFlowControlFinNotBlocked) { | 567 TEST_F(QuicSpdyStreamTest, StreamFlowControlFinNotBlocked) { |
572 // An attempt to write a FIN with no data should not be flow control blocked, | 568 // An attempt to write a FIN with no data should not be flow control blocked, |
573 // even if the send window is 0. | 569 // even if the send window is 0. |
574 | 570 |
575 Initialize(kShouldProcessData); | 571 Initialize(kShouldProcessData); |
576 | 572 |
577 // Set a flow control limit of zero. | 573 // Set a flow control limit of zero. |
578 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), 0); | 574 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), 0); |
579 EXPECT_EQ(0u, QuicFlowControllerPeer::ReceiveWindowOffset( | 575 EXPECT_EQ(0u, QuicFlowControllerPeer::ReceiveWindowOffset( |
580 stream_->flow_controller())); | 576 stream_->flow_controller())); |
581 | 577 |
582 // Send a frame with a FIN but no data. This should not be blocked. | 578 // Send a frame with a FIN but no data. This should not be blocked. |
583 string body = ""; | 579 string body = ""; |
584 bool fin = true; | 580 bool fin = true; |
585 | 581 |
586 EXPECT_CALL(*connection_, SendBlocked(kClientDataStreamId1)).Times(0); | 582 EXPECT_CALL(*connection_, SendBlocked(kClientDataStreamId1)).Times(0); |
587 EXPECT_CALL(*session_, WritevData(kClientDataStreamId1, _, _, _, _, _)) | 583 EXPECT_CALL(*session_, WritevData(kClientDataStreamId1, _, _, _, _, _)) |
588 .WillOnce(Return(QuicConsumedData(0, fin))); | 584 .WillOnce(Return(QuicConsumedData(0, fin))); |
589 | 585 |
590 stream_->WriteOrBufferData(body, fin, nullptr); | 586 stream_->WriteOrBufferData(body, fin, nullptr); |
591 } | 587 } |
592 | 588 |
593 } // namespace | 589 } // namespace |
594 } // namespace test | 590 } // namespace test |
595 } // namespace net | 591 } // namespace net |
OLD | NEW |