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

Side by Side Diff: net/http/http_response_body_drainer_unittest.cc

Issue 992733002: Remove //net (except for Android test stuff) and sdch (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/http/http_response_body_drainer.cc ('k') | net/http/http_response_headers.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/http/http_response_body_drainer.h"
6
7 #include <cstring>
8
9 #include "base/bind.h"
10 #include "base/compiler_specific.h"
11 #include "base/memory/weak_ptr.h"
12 #include "base/message_loop/message_loop.h"
13 #include "net/base/io_buffer.h"
14 #include "net/base/net_errors.h"
15 #include "net/base/test_completion_callback.h"
16 #include "net/http/http_network_session.h"
17 #include "net/http/http_server_properties_impl.h"
18 #include "net/http/http_stream.h"
19 #include "net/http/transport_security_state.h"
20 #include "net/proxy/proxy_service.h"
21 #include "net/ssl/ssl_config_service_defaults.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23
24 namespace net {
25
26 namespace {
27
28 const int kMagicChunkSize = 1024;
29 static_assert((HttpResponseBodyDrainer::kDrainBodyBufferSize %
30 kMagicChunkSize) == 0,
31 "chunk size needs to divide evenly into buffer size");
32
33 class CloseResultWaiter {
34 public:
35 CloseResultWaiter()
36 : result_(false),
37 have_result_(false),
38 waiting_for_result_(false) {}
39
40 int WaitForResult() {
41 CHECK(!waiting_for_result_);
42 while (!have_result_) {
43 waiting_for_result_ = true;
44 base::MessageLoop::current()->Run();
45 waiting_for_result_ = false;
46 }
47 return result_;
48 }
49
50 void set_result(bool result) {
51 result_ = result;
52 have_result_ = true;
53 if (waiting_for_result_)
54 base::MessageLoop::current()->Quit();
55 }
56
57 private:
58 int result_;
59 bool have_result_;
60 bool waiting_for_result_;
61
62 DISALLOW_COPY_AND_ASSIGN(CloseResultWaiter);
63 };
64
65 class MockHttpStream : public HttpStream {
66 public:
67 MockHttpStream(CloseResultWaiter* result_waiter)
68 : result_waiter_(result_waiter),
69 buf_len_(0),
70 closed_(false),
71 stall_reads_forever_(false),
72 num_chunks_(0),
73 is_sync_(false),
74 is_last_chunk_zero_size_(false),
75 is_complete_(false),
76 weak_factory_(this) {}
77 ~MockHttpStream() override {}
78
79 // HttpStream implementation.
80 int InitializeStream(const HttpRequestInfo* request_info,
81 RequestPriority priority,
82 const BoundNetLog& net_log,
83 const CompletionCallback& callback) override {
84 return ERR_UNEXPECTED;
85 }
86 int SendRequest(const HttpRequestHeaders& request_headers,
87 HttpResponseInfo* response,
88 const CompletionCallback& callback) override {
89 return ERR_UNEXPECTED;
90 }
91 UploadProgress GetUploadProgress() const override { return UploadProgress(); }
92 int ReadResponseHeaders(const CompletionCallback& callback) override {
93 return ERR_UNEXPECTED;
94 }
95
96 bool CanFindEndOfResponse() const override { return true; }
97 bool IsConnectionReused() const override { return false; }
98 void SetConnectionReused() override {}
99 bool IsConnectionReusable() const override { return false; }
100 int64 GetTotalReceivedBytes() const override { return 0; }
101 void GetSSLInfo(SSLInfo* ssl_info) override {}
102 void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {}
103
104 // Mocked API
105 int ReadResponseBody(IOBuffer* buf,
106 int buf_len,
107 const CompletionCallback& callback) override;
108 void Close(bool not_reusable) override {
109 CHECK(!closed_);
110 closed_ = true;
111 result_waiter_->set_result(not_reusable);
112 }
113
114 HttpStream* RenewStreamForAuth() override { return NULL; }
115
116 bool IsResponseBodyComplete() const override { return is_complete_; }
117
118 bool IsSpdyHttpStream() const override { return false; }
119
120 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
121 return false;
122 }
123
124 void Drain(HttpNetworkSession*) override {}
125
126 void SetPriority(RequestPriority priority) override {}
127
128 // Methods to tweak/observer mock behavior:
129 void set_stall_reads_forever() { stall_reads_forever_ = true; }
130
131 void set_num_chunks(int num_chunks) { num_chunks_ = num_chunks; }
132
133 void set_sync() { is_sync_ = true; }
134
135 void set_is_last_chunk_zero_size() { is_last_chunk_zero_size_ = true; }
136
137 private:
138 int ReadResponseBodyImpl(IOBuffer* buf, int buf_len);
139 void CompleteRead();
140
141 bool closed() const { return closed_; }
142
143 CloseResultWaiter* const result_waiter_;
144 scoped_refptr<IOBuffer> user_buf_;
145 CompletionCallback callback_;
146 int buf_len_;
147 bool closed_;
148 bool stall_reads_forever_;
149 int num_chunks_;
150 bool is_sync_;
151 bool is_last_chunk_zero_size_;
152 bool is_complete_;
153 base::WeakPtrFactory<MockHttpStream> weak_factory_;
154 };
155
156 int MockHttpStream::ReadResponseBody(IOBuffer* buf,
157 int buf_len,
158 const CompletionCallback& callback) {
159 CHECK(!callback.is_null());
160 CHECK(callback_.is_null());
161 CHECK(buf);
162
163 if (stall_reads_forever_)
164 return ERR_IO_PENDING;
165
166 if (is_complete_)
167 return ERR_UNEXPECTED;
168
169 if (!is_sync_) {
170 user_buf_ = buf;
171 buf_len_ = buf_len;
172 callback_ = callback;
173 base::MessageLoop::current()->PostTask(
174 FROM_HERE,
175 base::Bind(&MockHttpStream::CompleteRead, weak_factory_.GetWeakPtr()));
176 return ERR_IO_PENDING;
177 } else {
178 return ReadResponseBodyImpl(buf, buf_len);
179 }
180 }
181
182 int MockHttpStream::ReadResponseBodyImpl(IOBuffer* buf, int buf_len) {
183 if (is_last_chunk_zero_size_ && num_chunks_ == 1) {
184 buf_len = 0;
185 } else {
186 if (buf_len > kMagicChunkSize)
187 buf_len = kMagicChunkSize;
188 std::memset(buf->data(), 1, buf_len);
189 }
190 num_chunks_--;
191 if (!num_chunks_)
192 is_complete_ = true;
193
194 return buf_len;
195 }
196
197 void MockHttpStream::CompleteRead() {
198 int result = ReadResponseBodyImpl(user_buf_.get(), buf_len_);
199 user_buf_ = NULL;
200 CompletionCallback callback = callback_;
201 callback_.Reset();
202 callback.Run(result);
203 }
204
205 class HttpResponseBodyDrainerTest : public testing::Test {
206 protected:
207 HttpResponseBodyDrainerTest()
208 : proxy_service_(ProxyService::CreateDirect()),
209 ssl_config_service_(new SSLConfigServiceDefaults),
210 http_server_properties_(new HttpServerPropertiesImpl()),
211 transport_security_state_(new TransportSecurityState()),
212 session_(CreateNetworkSession()),
213 mock_stream_(new MockHttpStream(&result_waiter_)),
214 drainer_(new HttpResponseBodyDrainer(mock_stream_)) {}
215
216 ~HttpResponseBodyDrainerTest() override {}
217
218 HttpNetworkSession* CreateNetworkSession() const {
219 HttpNetworkSession::Params params;
220 params.proxy_service = proxy_service_.get();
221 params.ssl_config_service = ssl_config_service_.get();
222 params.http_server_properties = http_server_properties_->GetWeakPtr();
223 params.transport_security_state = transport_security_state_.get();
224 return new HttpNetworkSession(params);
225 }
226
227 scoped_ptr<ProxyService> proxy_service_;
228 scoped_refptr<SSLConfigService> ssl_config_service_;
229 scoped_ptr<HttpServerPropertiesImpl> http_server_properties_;
230 scoped_ptr<TransportSecurityState> transport_security_state_;
231 const scoped_refptr<HttpNetworkSession> session_;
232 CloseResultWaiter result_waiter_;
233 MockHttpStream* const mock_stream_; // Owned by |drainer_|.
234 HttpResponseBodyDrainer* const drainer_; // Deletes itself.
235 };
236
237 TEST_F(HttpResponseBodyDrainerTest, DrainBodySyncSingleOK) {
238 mock_stream_->set_num_chunks(1);
239 mock_stream_->set_sync();
240 drainer_->Start(session_.get());
241 EXPECT_FALSE(result_waiter_.WaitForResult());
242 }
243
244 TEST_F(HttpResponseBodyDrainerTest, DrainBodySyncOK) {
245 mock_stream_->set_num_chunks(3);
246 mock_stream_->set_sync();
247 drainer_->Start(session_.get());
248 EXPECT_FALSE(result_waiter_.WaitForResult());
249 }
250
251 TEST_F(HttpResponseBodyDrainerTest, DrainBodyAsyncOK) {
252 mock_stream_->set_num_chunks(3);
253 drainer_->Start(session_.get());
254 EXPECT_FALSE(result_waiter_.WaitForResult());
255 }
256
257 // Test the case when the final chunk is 0 bytes. This can happen when
258 // the final 0-byte chunk of a chunk-encoded http response is read in a last
259 // call to ReadResponseBody, after all data were returned from HttpStream.
260 TEST_F(HttpResponseBodyDrainerTest, DrainBodyAsyncEmptyChunk) {
261 mock_stream_->set_num_chunks(4);
262 mock_stream_->set_is_last_chunk_zero_size();
263 drainer_->Start(session_.get());
264 EXPECT_FALSE(result_waiter_.WaitForResult());
265 }
266
267 TEST_F(HttpResponseBodyDrainerTest, DrainBodySyncEmptyChunk) {
268 mock_stream_->set_num_chunks(4);
269 mock_stream_->set_sync();
270 mock_stream_->set_is_last_chunk_zero_size();
271 drainer_->Start(session_.get());
272 EXPECT_FALSE(result_waiter_.WaitForResult());
273 }
274
275 TEST_F(HttpResponseBodyDrainerTest, DrainBodySizeEqualsDrainBuffer) {
276 mock_stream_->set_num_chunks(
277 HttpResponseBodyDrainer::kDrainBodyBufferSize / kMagicChunkSize);
278 drainer_->Start(session_.get());
279 EXPECT_FALSE(result_waiter_.WaitForResult());
280 }
281
282 TEST_F(HttpResponseBodyDrainerTest, DrainBodyTimeOut) {
283 mock_stream_->set_num_chunks(2);
284 mock_stream_->set_stall_reads_forever();
285 drainer_->Start(session_.get());
286 EXPECT_TRUE(result_waiter_.WaitForResult());
287 }
288
289 TEST_F(HttpResponseBodyDrainerTest, CancelledBySession) {
290 mock_stream_->set_num_chunks(2);
291 mock_stream_->set_stall_reads_forever();
292 drainer_->Start(session_.get());
293 // HttpNetworkSession should delete |drainer_|.
294 }
295
296 TEST_F(HttpResponseBodyDrainerTest, DrainBodyTooLarge) {
297 int too_many_chunks =
298 HttpResponseBodyDrainer::kDrainBodyBufferSize / kMagicChunkSize;
299 too_many_chunks += 1; // Now it's too large.
300
301 mock_stream_->set_num_chunks(too_many_chunks);
302 drainer_->Start(session_.get());
303 EXPECT_TRUE(result_waiter_.WaitForResult());
304 }
305
306 } // namespace
307
308 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_response_body_drainer.cc ('k') | net/http/http_response_headers.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698