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_data_stream.h" |
6 | 6 |
| 7 #include <string> |
| 8 |
7 #include "net/quic/quic_ack_notifier.h" | 9 #include "net/quic/quic_ack_notifier.h" |
8 #include "net/quic/quic_connection.h" | 10 #include "net/quic/quic_connection.h" |
9 #include "net/quic/quic_utils.h" | 11 #include "net/quic/quic_utils.h" |
10 #include "net/quic/quic_write_blocked_list.h" | 12 #include "net/quic/quic_write_blocked_list.h" |
11 #include "net/quic/spdy_utils.h" | 13 #include "net/quic/spdy_utils.h" |
12 #include "net/quic/test_tools/quic_flow_controller_peer.h" | 14 #include "net/quic/test_tools/quic_flow_controller_peer.h" |
13 #include "net/quic/test_tools/quic_session_peer.h" | 15 #include "net/quic/test_tools/quic_session_peer.h" |
14 #include "net/quic/test_tools/quic_test_utils.h" | 16 #include "net/quic/test_tools/quic_test_utils.h" |
15 #include "net/quic/test_tools/reliable_quic_stream_peer.h" | 17 #include "net/quic/test_tools/reliable_quic_stream_peer.h" |
16 #include "net/test/gtest_util.h" | 18 #include "net/test/gtest_util.h" |
(...skipping 19 matching lines...) Expand all Loading... |
36 public: | 38 public: |
37 TestStream(QuicStreamId id, | 39 TestStream(QuicStreamId id, |
38 QuicSession* session, | 40 QuicSession* session, |
39 bool should_process_data) | 41 bool should_process_data) |
40 : QuicDataStream(id, session), | 42 : QuicDataStream(id, session), |
41 should_process_data_(should_process_data) {} | 43 should_process_data_(should_process_data) {} |
42 | 44 |
43 uint32 ProcessData(const char* data, uint32 data_len) override { | 45 uint32 ProcessData(const char* data, uint32 data_len) override { |
44 EXPECT_NE(0u, data_len); | 46 EXPECT_NE(0u, data_len); |
45 DVLOG(1) << "ProcessData data_len: " << data_len; | 47 DVLOG(1) << "ProcessData data_len: " << data_len; |
46 data_ += string(data, data_len); | 48 data_ += std::string(data, data_len); |
47 return should_process_data_ ? data_len : 0; | 49 return should_process_data_ ? data_len : 0; |
48 } | 50 } |
49 | 51 |
50 using ReliableQuicStream::WriteOrBufferData; | 52 using ReliableQuicStream::WriteOrBufferData; |
51 using ReliableQuicStream::CloseReadSide; | 53 using ReliableQuicStream::CloseReadSide; |
52 using ReliableQuicStream::CloseWriteSide; | 54 using ReliableQuicStream::CloseWriteSide; |
53 | 55 |
54 const string& data() const { return data_; } | 56 const std::string& data() const { return data_; } |
55 | 57 |
56 private: | 58 private: |
57 bool should_process_data_; | 59 bool should_process_data_; |
58 string data_; | 60 std::string data_; |
59 }; | 61 }; |
60 | 62 |
61 class QuicDataStreamTest : public ::testing::TestWithParam<QuicVersion> { | 63 class QuicDataStreamTest : public ::testing::TestWithParam<QuicVersion> { |
62 public: | 64 public: |
63 QuicDataStreamTest() { | 65 QuicDataStreamTest() { |
64 headers_[":host"] = "www.google.com"; | 66 headers_[":host"] = "www.google.com"; |
65 headers_[":path"] = "/index.hml"; | 67 headers_[":path"] = "/index.hml"; |
66 headers_[":scheme"] = "https"; | 68 headers_[":scheme"] = "https"; |
67 headers_["cookie"] = | 69 headers_["cookie"] = |
68 "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; " | 70 "__utma=208381060.1228362404.1372200928.1372200928.1372200928.1; " |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 SpdyHeaderBlock headers_; | 112 SpdyHeaderBlock headers_; |
111 QuicWriteBlockedList* write_blocked_list_; | 113 QuicWriteBlockedList* write_blocked_list_; |
112 }; | 114 }; |
113 | 115 |
114 INSTANTIATE_TEST_CASE_P(Tests, QuicDataStreamTest, | 116 INSTANTIATE_TEST_CASE_P(Tests, QuicDataStreamTest, |
115 ::testing::ValuesIn(QuicSupportedVersions())); | 117 ::testing::ValuesIn(QuicSupportedVersions())); |
116 | 118 |
117 TEST_P(QuicDataStreamTest, ProcessHeaders) { | 119 TEST_P(QuicDataStreamTest, ProcessHeaders) { |
118 Initialize(kShouldProcessData); | 120 Initialize(kShouldProcessData); |
119 | 121 |
120 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 122 std::string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
121 stream_->OnStreamHeadersPriority(QuicUtils::HighestPriority()); | 123 stream_->OnStreamHeadersPriority(QuicUtils::HighestPriority()); |
122 stream_->OnStreamHeaders(headers); | 124 stream_->OnStreamHeaders(headers); |
123 EXPECT_EQ(headers, stream_->data()); | 125 EXPECT_EQ(headers, stream_->data()); |
124 stream_->OnStreamHeadersComplete(false, headers.size()); | 126 stream_->OnStreamHeadersComplete(false, headers.size()); |
125 EXPECT_EQ(QuicUtils::HighestPriority(), stream_->EffectivePriority()); | 127 EXPECT_EQ(QuicUtils::HighestPriority(), stream_->EffectivePriority()); |
126 EXPECT_EQ(headers, stream_->data()); | 128 EXPECT_EQ(headers, stream_->data()); |
127 EXPECT_FALSE(stream_->IsDoneReading()); | 129 EXPECT_FALSE(stream_->IsDoneReading()); |
128 } | 130 } |
129 | 131 |
130 TEST_P(QuicDataStreamTest, ProcessHeadersAndBody) { | 132 TEST_P(QuicDataStreamTest, ProcessHeadersAndBody) { |
131 Initialize(kShouldProcessData); | 133 Initialize(kShouldProcessData); |
132 | 134 |
133 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 135 std::string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
134 string body = "this is the body"; | 136 std::string body = "this is the body"; |
135 | 137 |
136 stream_->OnStreamHeaders(headers); | 138 stream_->OnStreamHeaders(headers); |
137 EXPECT_EQ(headers, stream_->data()); | 139 EXPECT_EQ(headers, stream_->data()); |
138 stream_->OnStreamHeadersComplete(false, headers.size()); | 140 stream_->OnStreamHeadersComplete(false, headers.size()); |
139 QuicStreamFrame frame(kClientDataStreamId1, false, 0, MakeIOVector(body)); | 141 QuicStreamFrame frame(kClientDataStreamId1, false, 0, MakeIOVector(body)); |
140 stream_->OnStreamFrame(frame); | 142 stream_->OnStreamFrame(frame); |
141 | 143 |
142 EXPECT_EQ(headers + body, stream_->data()); | 144 EXPECT_EQ(headers + body, stream_->data()); |
143 } | 145 } |
144 | 146 |
145 TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyFragments) { | 147 TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyFragments) { |
146 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 148 std::string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
147 string body = "this is the body"; | 149 std::string body = "this is the body"; |
148 | 150 |
149 for (size_t fragment_size = 1; fragment_size < body.size(); | 151 for (size_t fragment_size = 1; fragment_size < body.size(); |
150 ++fragment_size) { | 152 ++fragment_size) { |
151 Initialize(kShouldProcessData); | 153 Initialize(kShouldProcessData); |
152 for (size_t offset = 0; offset < headers.size(); | 154 for (size_t offset = 0; offset < headers.size(); |
153 offset += fragment_size) { | 155 offset += fragment_size) { |
154 size_t remaining_data = headers.size() - offset; | 156 size_t remaining_data = headers.size() - offset; |
155 StringPiece fragment(headers.data() + offset, | 157 StringPiece fragment(headers.data() + offset, |
156 min(fragment_size, remaining_data)); | 158 min(fragment_size, remaining_data)); |
157 stream_->OnStreamHeaders(fragment); | 159 stream_->OnStreamHeaders(fragment); |
158 } | 160 } |
159 stream_->OnStreamHeadersComplete(false, headers.size()); | 161 stream_->OnStreamHeadersComplete(false, headers.size()); |
160 for (size_t offset = 0; offset < body.size(); offset += fragment_size) { | 162 for (size_t offset = 0; offset < body.size(); offset += fragment_size) { |
161 size_t remaining_data = body.size() - offset; | 163 size_t remaining_data = body.size() - offset; |
162 StringPiece fragment(body.data() + offset, | 164 StringPiece fragment(body.data() + offset, |
163 min(fragment_size, remaining_data)); | 165 min(fragment_size, remaining_data)); |
164 QuicStreamFrame frame(kClientDataStreamId1, false, offset, | 166 QuicStreamFrame frame(kClientDataStreamId1, false, offset, |
165 MakeIOVector(fragment)); | 167 MakeIOVector(fragment)); |
166 stream_->OnStreamFrame(frame); | 168 stream_->OnStreamFrame(frame); |
167 } | 169 } |
168 ASSERT_EQ(headers + body, | 170 ASSERT_EQ(headers + body, |
169 stream_->data()) << "fragment_size: " << fragment_size; | 171 stream_->data()) << "fragment_size: " << fragment_size; |
170 } | 172 } |
171 } | 173 } |
172 | 174 |
173 TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyFragmentsSplit) { | 175 TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyFragmentsSplit) { |
174 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 176 std::string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
175 string body = "this is the body"; | 177 std::string body = "this is the body"; |
176 | 178 |
177 for (size_t split_point = 1; split_point < body.size() - 1; ++split_point) { | 179 for (size_t split_point = 1; split_point < body.size() - 1; ++split_point) { |
178 Initialize(kShouldProcessData); | 180 Initialize(kShouldProcessData); |
179 StringPiece headers1(headers.data(), split_point); | 181 StringPiece headers1(headers.data(), split_point); |
180 stream_->OnStreamHeaders(headers1); | 182 stream_->OnStreamHeaders(headers1); |
181 | 183 |
182 StringPiece headers2(headers.data() + split_point, | 184 StringPiece headers2(headers.data() + split_point, |
183 headers.size() - split_point); | 185 headers.size() - split_point); |
184 stream_->OnStreamHeaders(headers2); | 186 stream_->OnStreamHeaders(headers2); |
185 stream_->OnStreamHeadersComplete(false, headers.size()); | 187 stream_->OnStreamHeadersComplete(false, headers.size()); |
(...skipping 10 matching lines...) Expand all Loading... |
196 stream_->OnStreamFrame(frame2); | 198 stream_->OnStreamFrame(frame2); |
197 | 199 |
198 ASSERT_EQ(headers + body, | 200 ASSERT_EQ(headers + body, |
199 stream_->data()) << "split_point: " << split_point; | 201 stream_->data()) << "split_point: " << split_point; |
200 } | 202 } |
201 } | 203 } |
202 | 204 |
203 TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyReadv) { | 205 TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyReadv) { |
204 Initialize(!kShouldProcessData); | 206 Initialize(!kShouldProcessData); |
205 | 207 |
206 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 208 std::string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
207 string body = "this is the body"; | 209 std::string body = "this is the body"; |
208 | 210 |
209 stream_->OnStreamHeaders(headers); | 211 stream_->OnStreamHeaders(headers); |
210 EXPECT_EQ(headers, stream_->data()); | 212 EXPECT_EQ(headers, stream_->data()); |
211 stream_->OnStreamHeadersComplete(false, headers.size()); | 213 stream_->OnStreamHeadersComplete(false, headers.size()); |
212 QuicStreamFrame frame(kClientDataStreamId1, false, 0, MakeIOVector(body)); | 214 QuicStreamFrame frame(kClientDataStreamId1, false, 0, MakeIOVector(body)); |
213 stream_->OnStreamFrame(frame); | 215 stream_->OnStreamFrame(frame); |
214 | 216 |
215 char buffer[2048]; | 217 char buffer[2048]; |
216 ASSERT_LT(headers.length() + body.length(), arraysize(buffer)); | 218 ASSERT_LT(headers.length() + body.length(), arraysize(buffer)); |
217 struct iovec vec; | 219 struct iovec vec; |
218 vec.iov_base = buffer; | 220 vec.iov_base = buffer; |
219 vec.iov_len = arraysize(buffer); | 221 vec.iov_len = arraysize(buffer); |
220 | 222 |
221 size_t bytes_read = stream_->Readv(&vec, 1); | 223 size_t bytes_read = stream_->Readv(&vec, 1); |
222 EXPECT_EQ(headers.length(), bytes_read); | 224 EXPECT_EQ(headers.length(), bytes_read); |
223 EXPECT_EQ(headers, string(buffer, bytes_read)); | 225 EXPECT_EQ(headers, std::string(buffer, bytes_read)); |
224 | 226 |
225 bytes_read = stream_->Readv(&vec, 1); | 227 bytes_read = stream_->Readv(&vec, 1); |
226 EXPECT_EQ(body.length(), bytes_read); | 228 EXPECT_EQ(body.length(), bytes_read); |
227 EXPECT_EQ(body, string(buffer, bytes_read)); | 229 EXPECT_EQ(body, std::string(buffer, bytes_read)); |
228 } | 230 } |
229 | 231 |
230 TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyIncrementalReadv) { | 232 TEST_P(QuicDataStreamTest, ProcessHeadersAndBodyIncrementalReadv) { |
231 Initialize(!kShouldProcessData); | 233 Initialize(!kShouldProcessData); |
232 | 234 |
233 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 235 std::string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
234 string body = "this is the body"; | 236 std::string body = "this is the body"; |
235 stream_->OnStreamHeaders(headers); | 237 stream_->OnStreamHeaders(headers); |
236 EXPECT_EQ(headers, stream_->data()); | 238 EXPECT_EQ(headers, stream_->data()); |
237 stream_->OnStreamHeadersComplete(false, headers.size()); | 239 stream_->OnStreamHeadersComplete(false, headers.size()); |
238 QuicStreamFrame frame(kClientDataStreamId1, false, 0, MakeIOVector(body)); | 240 QuicStreamFrame frame(kClientDataStreamId1, false, 0, MakeIOVector(body)); |
239 stream_->OnStreamFrame(frame); | 241 stream_->OnStreamFrame(frame); |
240 | 242 |
241 char buffer[1]; | 243 char buffer[1]; |
242 struct iovec vec; | 244 struct iovec vec; |
243 vec.iov_base = buffer; | 245 vec.iov_base = buffer; |
244 vec.iov_len = arraysize(buffer); | 246 vec.iov_len = arraysize(buffer); |
245 | 247 |
246 string data = headers + body; | 248 std::string data = headers + body; |
247 for (size_t i = 0; i < data.length(); ++i) { | 249 for (size_t i = 0; i < data.length(); ++i) { |
248 size_t bytes_read = stream_->Readv(&vec, 1); | 250 size_t bytes_read = stream_->Readv(&vec, 1); |
249 ASSERT_EQ(1u, bytes_read); | 251 ASSERT_EQ(1u, bytes_read); |
250 EXPECT_EQ(data.data()[i], buffer[0]); | 252 EXPECT_EQ(data.data()[i], buffer[0]); |
251 } | 253 } |
252 } | 254 } |
253 | 255 |
254 TEST_P(QuicDataStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) { | 256 TEST_P(QuicDataStreamTest, ProcessHeadersUsingReadvWithMultipleIovecs) { |
255 Initialize(!kShouldProcessData); | 257 Initialize(!kShouldProcessData); |
256 | 258 |
257 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 259 std::string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
258 string body = "this is the body"; | 260 std::string body = "this is the body"; |
259 stream_->OnStreamHeaders(headers); | 261 stream_->OnStreamHeaders(headers); |
260 EXPECT_EQ(headers, stream_->data()); | 262 EXPECT_EQ(headers, stream_->data()); |
261 stream_->OnStreamHeadersComplete(false, headers.size()); | 263 stream_->OnStreamHeadersComplete(false, headers.size()); |
262 QuicStreamFrame frame(kClientDataStreamId1, false, 0, MakeIOVector(body)); | 264 QuicStreamFrame frame(kClientDataStreamId1, false, 0, MakeIOVector(body)); |
263 stream_->OnStreamFrame(frame); | 265 stream_->OnStreamFrame(frame); |
264 | 266 |
265 char buffer1[1]; | 267 char buffer1[1]; |
266 char buffer2[1]; | 268 char buffer2[1]; |
267 struct iovec vec[2]; | 269 struct iovec vec[2]; |
268 vec[0].iov_base = buffer1; | 270 vec[0].iov_base = buffer1; |
269 vec[0].iov_len = arraysize(buffer1); | 271 vec[0].iov_len = arraysize(buffer1); |
270 vec[1].iov_base = buffer2; | 272 vec[1].iov_base = buffer2; |
271 vec[1].iov_len = arraysize(buffer2); | 273 vec[1].iov_len = arraysize(buffer2); |
272 string data = headers + body; | 274 std::string data = headers + body; |
273 for (size_t i = 0; i < data.length(); i += 2) { | 275 for (size_t i = 0; i < data.length(); i += 2) { |
274 size_t bytes_read = stream_->Readv(vec, 2); | 276 size_t bytes_read = stream_->Readv(vec, 2); |
275 ASSERT_EQ(2u, bytes_read) << i; | 277 ASSERT_EQ(2u, bytes_read) << i; |
276 ASSERT_EQ(data.data()[i], buffer1[0]) << i; | 278 ASSERT_EQ(data.data()[i], buffer1[0]) << i; |
277 ASSERT_EQ(data.data()[i + 1], buffer2[0]) << i; | 279 ASSERT_EQ(data.data()[i + 1], buffer2[0]) << i; |
278 } | 280 } |
279 } | 281 } |
280 | 282 |
281 TEST_P(QuicDataStreamTest, StreamFlowControlBlocked) { | 283 TEST_P(QuicDataStreamTest, StreamFlowControlBlocked) { |
282 // Tests that we send a BLOCKED frame to the peer when we attempt to write, | 284 // Tests that we send a BLOCKED frame to the peer when we attempt to write, |
283 // but are flow control blocked. | 285 // but are flow control blocked. |
284 Initialize(kShouldProcessData); | 286 Initialize(kShouldProcessData); |
285 | 287 |
286 // Set a small flow control limit. | 288 // Set a small flow control limit. |
287 const uint64 kWindow = 36; | 289 const uint64 kWindow = 36; |
288 QuicFlowControllerPeer::SetSendWindowOffset(stream_->flow_controller(), | 290 QuicFlowControllerPeer::SetSendWindowOffset(stream_->flow_controller(), |
289 kWindow); | 291 kWindow); |
290 EXPECT_EQ(kWindow, QuicFlowControllerPeer::SendWindowOffset( | 292 EXPECT_EQ(kWindow, QuicFlowControllerPeer::SendWindowOffset( |
291 stream_->flow_controller())); | 293 stream_->flow_controller())); |
292 | 294 |
293 // Try to send more data than the flow control limit allows. | 295 // Try to send more data than the flow control limit allows. |
294 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 296 std::string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
295 string body; | 297 std::string body; |
296 const uint64 kOverflow = 15; | 298 const uint64 kOverflow = 15; |
297 GenerateBody(&body, kWindow + kOverflow); | 299 GenerateBody(&body, kWindow + kOverflow); |
298 | 300 |
299 EXPECT_CALL(*connection_, SendBlocked(kClientDataStreamId1)); | 301 EXPECT_CALL(*connection_, SendBlocked(kClientDataStreamId1)); |
300 EXPECT_CALL(*session_, WritevData(kClientDataStreamId1, _, _, _, _, _)) | 302 EXPECT_CALL(*session_, WritevData(kClientDataStreamId1, _, _, _, _, _)) |
301 .WillOnce(Return(QuicConsumedData(kWindow, true))); | 303 .WillOnce(Return(QuicConsumedData(kWindow, true))); |
302 stream_->WriteOrBufferData(body, false, nullptr); | 304 stream_->WriteOrBufferData(body, false, nullptr); |
303 | 305 |
304 // Should have sent as much as possible, resulting in no send window left. | 306 // Should have sent as much as possible, resulting in no send window left. |
305 EXPECT_EQ(0u, | 307 EXPECT_EQ(0u, |
(...skipping 19 matching lines...) Expand all Loading... |
325 // Set a small flow control receive window. | 327 // Set a small flow control receive window. |
326 const uint64 kWindow = 36; | 328 const uint64 kWindow = 36; |
327 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), | 329 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), |
328 kWindow); | 330 kWindow); |
329 QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(), | 331 QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(), |
330 kWindow); | 332 kWindow); |
331 EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowOffset( | 333 EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowOffset( |
332 stream_->flow_controller())); | 334 stream_->flow_controller())); |
333 | 335 |
334 // Stream receives enough data to fill a fraction of the receive window. | 336 // Stream receives enough data to fill a fraction of the receive window. |
335 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 337 std::string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
336 string body; | 338 std::string body; |
337 GenerateBody(&body, kWindow / 3); | 339 GenerateBody(&body, kWindow / 3); |
338 stream_->OnStreamHeaders(headers); | 340 stream_->OnStreamHeaders(headers); |
339 EXPECT_EQ(headers, stream_->data()); | 341 EXPECT_EQ(headers, stream_->data()); |
340 stream_->OnStreamHeadersComplete(false, headers.size()); | 342 stream_->OnStreamHeadersComplete(false, headers.size()); |
341 | 343 |
342 QuicStreamFrame frame1(kClientDataStreamId1, false, 0, MakeIOVector(body)); | 344 QuicStreamFrame frame1(kClientDataStreamId1, false, 0, MakeIOVector(body)); |
343 stream_->OnStreamFrame(frame1); | 345 stream_->OnStreamFrame(frame1); |
344 EXPECT_EQ(kWindow - (kWindow / 3), QuicFlowControllerPeer::ReceiveWindowSize( | 346 EXPECT_EQ(kWindow - (kWindow / 3), QuicFlowControllerPeer::ReceiveWindowSize( |
345 stream_->flow_controller())); | 347 stream_->flow_controller())); |
346 | 348 |
(...skipping 17 matching lines...) Expand all Loading... |
364 // Set a small flow control limit. | 366 // Set a small flow control limit. |
365 const uint64 kWindow = 36; | 367 const uint64 kWindow = 36; |
366 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), | 368 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), |
367 kWindow); | 369 kWindow); |
368 QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(), | 370 QuicFlowControllerPeer::SetMaxReceiveWindow(stream_->flow_controller(), |
369 kWindow); | 371 kWindow); |
370 EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowOffset( | 372 EXPECT_EQ(kWindow, QuicFlowControllerPeer::ReceiveWindowOffset( |
371 stream_->flow_controller())); | 373 stream_->flow_controller())); |
372 | 374 |
373 // Stream receives enough data to fill a fraction of the receive window. | 375 // Stream receives enough data to fill a fraction of the receive window. |
374 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 376 std::string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
375 string body; | 377 std::string body; |
376 GenerateBody(&body, kWindow / 3); | 378 GenerateBody(&body, kWindow / 3); |
377 stream_->OnStreamHeaders(headers); | 379 stream_->OnStreamHeaders(headers); |
378 EXPECT_EQ(headers, stream_->data()); | 380 EXPECT_EQ(headers, stream_->data()); |
379 stream_->OnStreamHeadersComplete(false, headers.size()); | 381 stream_->OnStreamHeadersComplete(false, headers.size()); |
380 | 382 |
381 QuicStreamFrame frame1(kClientDataStreamId1, false, 0, MakeIOVector(body)); | 383 QuicStreamFrame frame1(kClientDataStreamId1, false, 0, MakeIOVector(body)); |
382 stream_->OnStreamFrame(frame1); | 384 stream_->OnStreamFrame(frame1); |
383 EXPECT_EQ(kWindow - (kWindow / 3), QuicFlowControllerPeer::ReceiveWindowSize( | 385 EXPECT_EQ(kWindow - (kWindow / 3), QuicFlowControllerPeer::ReceiveWindowSize( |
384 stream_->flow_controller())); | 386 stream_->flow_controller())); |
385 | 387 |
(...skipping 28 matching lines...) Expand all Loading... |
414 QuicFlowControllerPeer::SetReceiveWindowOffset(stream2_->flow_controller(), | 416 QuicFlowControllerPeer::SetReceiveWindowOffset(stream2_->flow_controller(), |
415 kWindow); | 417 kWindow); |
416 QuicFlowControllerPeer::SetMaxReceiveWindow(stream2_->flow_controller(), | 418 QuicFlowControllerPeer::SetMaxReceiveWindow(stream2_->flow_controller(), |
417 kWindow); | 419 kWindow); |
418 QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(), | 420 QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(), |
419 kWindow); | 421 kWindow); |
420 QuicFlowControllerPeer::SetMaxReceiveWindow(session_->flow_controller(), | 422 QuicFlowControllerPeer::SetMaxReceiveWindow(session_->flow_controller(), |
421 kWindow); | 423 kWindow); |
422 | 424 |
423 // Supply headers to both streams so that they are happy to receive data. | 425 // Supply headers to both streams so that they are happy to receive data. |
424 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 426 std::string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
425 stream_->OnStreamHeaders(headers); | 427 stream_->OnStreamHeaders(headers); |
426 stream_->OnStreamHeadersComplete(false, headers.size()); | 428 stream_->OnStreamHeadersComplete(false, headers.size()); |
427 stream2_->OnStreamHeaders(headers); | 429 stream2_->OnStreamHeaders(headers); |
428 stream2_->OnStreamHeadersComplete(false, headers.size()); | 430 stream2_->OnStreamHeadersComplete(false, headers.size()); |
429 | 431 |
430 // Each stream gets a quarter window of data. This should not trigger a | 432 // Each stream gets a quarter window of data. This should not trigger a |
431 // WINDOW_UPDATE for either stream, nor for the connection. | 433 // WINDOW_UPDATE for either stream, nor for the connection. |
432 string body; | 434 std::string body; |
433 GenerateBody(&body, kWindow / 4); | 435 GenerateBody(&body, kWindow / 4); |
434 QuicStreamFrame frame1(kClientDataStreamId1, false, 0, MakeIOVector(body)); | 436 QuicStreamFrame frame1(kClientDataStreamId1, false, 0, MakeIOVector(body)); |
435 stream_->OnStreamFrame(frame1); | 437 stream_->OnStreamFrame(frame1); |
436 QuicStreamFrame frame2(kClientDataStreamId2, false, 0, MakeIOVector(body)); | 438 QuicStreamFrame frame2(kClientDataStreamId2, false, 0, MakeIOVector(body)); |
437 stream2_->OnStreamFrame(frame2); | 439 stream2_->OnStreamFrame(frame2); |
438 | 440 |
439 // Now receive a further single byte on one stream - again this does not | 441 // Now receive a further single byte on one stream - again this does not |
440 // trigger a stream WINDOW_UPDATE, but now the connection flow control window | 442 // trigger a stream WINDOW_UPDATE, but now the connection flow control window |
441 // is over half full and thus a connection WINDOW_UPDATE is sent. | 443 // is over half full and thus a connection WINDOW_UPDATE is sent. |
442 EXPECT_CALL(*connection_, SendWindowUpdate(kClientDataStreamId1, _)).Times(0); | 444 EXPECT_CALL(*connection_, SendWindowUpdate(kClientDataStreamId1, _)).Times(0); |
(...skipping 13 matching lines...) Expand all Loading... |
456 | 458 |
457 // Stream should not process data, so that data gets buffered in the | 459 // Stream should not process data, so that data gets buffered in the |
458 // sequencer, triggering flow control limits. | 460 // sequencer, triggering flow control limits. |
459 Initialize(!kShouldProcessData); | 461 Initialize(!kShouldProcessData); |
460 | 462 |
461 // Set a small flow control limit. | 463 // Set a small flow control limit. |
462 const uint64 kWindow = 50; | 464 const uint64 kWindow = 50; |
463 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), | 465 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), |
464 kWindow); | 466 kWindow); |
465 | 467 |
466 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 468 std::string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
467 stream_->OnStreamHeaders(headers); | 469 stream_->OnStreamHeaders(headers); |
468 EXPECT_EQ(headers, stream_->data()); | 470 EXPECT_EQ(headers, stream_->data()); |
469 stream_->OnStreamHeadersComplete(false, headers.size()); | 471 stream_->OnStreamHeadersComplete(false, headers.size()); |
470 | 472 |
471 // Receive data to overflow the window, violating flow control. | 473 // Receive data to overflow the window, violating flow control. |
472 string body; | 474 std::string body; |
473 GenerateBody(&body, kWindow + 1); | 475 GenerateBody(&body, kWindow + 1); |
474 QuicStreamFrame frame(kClientDataStreamId1, false, 0, MakeIOVector(body)); | 476 QuicStreamFrame frame(kClientDataStreamId1, false, 0, MakeIOVector(body)); |
475 EXPECT_CALL(*connection_, | 477 EXPECT_CALL(*connection_, |
476 SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA)); | 478 SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA)); |
477 stream_->OnStreamFrame(frame); | 479 stream_->OnStreamFrame(frame); |
478 } | 480 } |
479 | 481 |
480 TEST_P(QuicDataStreamTest, ConnectionFlowControlViolation) { | 482 TEST_P(QuicDataStreamTest, ConnectionFlowControlViolation) { |
481 // Tests that on if the peer sends too much data (i.e. violates the flow | 483 // Tests that on if the peer sends too much data (i.e. violates the flow |
482 // control protocol), at the connection level (rather than the stream level) | 484 // control protocol), at the connection level (rather than the stream level) |
483 // then we terminate the connection. | 485 // then we terminate the connection. |
484 | 486 |
485 // Stream should not process data, so that data gets buffered in the | 487 // Stream should not process data, so that data gets buffered in the |
486 // sequencer, triggering flow control limits. | 488 // sequencer, triggering flow control limits. |
487 Initialize(!kShouldProcessData); | 489 Initialize(!kShouldProcessData); |
488 | 490 |
489 // Set a small flow control window on streams, and connection. | 491 // Set a small flow control window on streams, and connection. |
490 const uint64 kStreamWindow = 50; | 492 const uint64 kStreamWindow = 50; |
491 const uint64 kConnectionWindow = 10; | 493 const uint64 kConnectionWindow = 10; |
492 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), | 494 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), |
493 kStreamWindow); | 495 kStreamWindow); |
494 QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(), | 496 QuicFlowControllerPeer::SetReceiveWindowOffset(session_->flow_controller(), |
495 kConnectionWindow); | 497 kConnectionWindow); |
496 | 498 |
497 string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); | 499 std::string headers = SpdyUtils::SerializeUncompressedHeaders(headers_); |
498 stream_->OnStreamHeaders(headers); | 500 stream_->OnStreamHeaders(headers); |
499 EXPECT_EQ(headers, stream_->data()); | 501 EXPECT_EQ(headers, stream_->data()); |
500 stream_->OnStreamHeadersComplete(false, headers.size()); | 502 stream_->OnStreamHeadersComplete(false, headers.size()); |
501 | 503 |
502 // Send enough data to overflow the connection level flow control window. | 504 // Send enough data to overflow the connection level flow control window. |
503 string body; | 505 std::string body; |
504 GenerateBody(&body, kConnectionWindow + 1); | 506 GenerateBody(&body, kConnectionWindow + 1); |
505 EXPECT_LT(body.size(), kStreamWindow); | 507 EXPECT_LT(body.size(), kStreamWindow); |
506 QuicStreamFrame frame(kClientDataStreamId1, false, 0, MakeIOVector(body)); | 508 QuicStreamFrame frame(kClientDataStreamId1, false, 0, MakeIOVector(body)); |
507 | 509 |
508 EXPECT_CALL(*connection_, | 510 EXPECT_CALL(*connection_, |
509 SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA)); | 511 SendConnectionClose(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA)); |
510 stream_->OnStreamFrame(frame); | 512 stream_->OnStreamFrame(frame); |
511 } | 513 } |
512 | 514 |
513 TEST_P(QuicDataStreamTest, StreamFlowControlFinNotBlocked) { | 515 TEST_P(QuicDataStreamTest, StreamFlowControlFinNotBlocked) { |
514 // An attempt to write a FIN with no data should not be flow control blocked, | 516 // An attempt to write a FIN with no data should not be flow control blocked, |
515 // even if the send window is 0. | 517 // even if the send window is 0. |
516 | 518 |
517 Initialize(kShouldProcessData); | 519 Initialize(kShouldProcessData); |
518 | 520 |
519 // Set a flow control limit of zero. | 521 // Set a flow control limit of zero. |
520 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), 0); | 522 QuicFlowControllerPeer::SetReceiveWindowOffset(stream_->flow_controller(), 0); |
521 EXPECT_EQ(0u, QuicFlowControllerPeer::ReceiveWindowOffset( | 523 EXPECT_EQ(0u, QuicFlowControllerPeer::ReceiveWindowOffset( |
522 stream_->flow_controller())); | 524 stream_->flow_controller())); |
523 | 525 |
524 // Send a frame with a FIN but no data. This should not be blocked. | 526 // Send a frame with a FIN but no data. This should not be blocked. |
525 string body = ""; | 527 std::string body = ""; |
526 bool fin = true; | 528 bool fin = true; |
527 | 529 |
528 EXPECT_CALL(*connection_, SendBlocked(kClientDataStreamId1)).Times(0); | 530 EXPECT_CALL(*connection_, SendBlocked(kClientDataStreamId1)).Times(0); |
529 EXPECT_CALL(*session_, WritevData(kClientDataStreamId1, _, _, _, _, _)) | 531 EXPECT_CALL(*session_, WritevData(kClientDataStreamId1, _, _, _, _, _)) |
530 .WillOnce(Return(QuicConsumedData(0, fin))); | 532 .WillOnce(Return(QuicConsumedData(0, fin))); |
531 | 533 |
532 stream_->WriteOrBufferData(body, fin, nullptr); | 534 stream_->WriteOrBufferData(body, fin, nullptr); |
533 } | 535 } |
534 | 536 |
535 } // namespace | 537 } // namespace |
536 } // namespace test | 538 } // namespace test |
537 } // namespace net | 539 } // namespace net |
OLD | NEW |