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