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

Side by Side Diff: content/child/url_response_body_consumer_unittest.cc

Issue 2573743002: Handle MOJO_RESULT_BUSY result in URLResponseBodyConsumer (Closed)
Patch Set: fix Created 4 years 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
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "content/child/url_response_body_consumer.h" 5 #include "content/child/url_response_body_consumer.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback_forward.h" 8 #include "base/callback_forward.h"
9 #include "base/macros.h" 9 #include "base/macros.h"
10 #include "base/memory/ptr_util.h" 10 #include "base/memory/ptr_util.h"
(...skipping 11 matching lines...) Expand all
22 #include "url/gurl.h" 22 #include "url/gurl.h"
23 #include "url/origin.h" 23 #include "url/origin.h"
24 24
25 namespace content { 25 namespace content {
26 26
27 namespace { 27 namespace {
28 28
29 class TestRequestPeer : public RequestPeer { 29 class TestRequestPeer : public RequestPeer {
30 public: 30 public:
31 struct Context; 31 struct Context;
32 explicit TestRequestPeer(Context* context) : context_(context) {} 32 TestRequestPeer(Context* context,
33 scoped_refptr<base::SingleThreadTaskRunner> task_runner)
34 : context_(context), task_runner_(std::move(task_runner)) {}
33 35
34 void OnUploadProgress(uint64_t position, uint64_t size) override { 36 void OnUploadProgress(uint64_t position, uint64_t size) override {
35 ADD_FAILURE() << "OnUploadProgress should not be called."; 37 ADD_FAILURE() << "OnUploadProgress should not be called.";
36 } 38 }
37 39
38 bool OnReceivedRedirect(const net::RedirectInfo& redirect_info, 40 bool OnReceivedRedirect(const net::RedirectInfo& redirect_info,
39 const ResourceResponseInfo& info) override { 41 const ResourceResponseInfo& info) override {
40 ADD_FAILURE() << "OnReceivedRedirect should not be called."; 42 ADD_FAILURE() << "OnReceivedRedirect should not be called.";
41 return false; 43 return false;
42 } 44 }
43 45
44 void OnReceivedResponse(const ResourceResponseInfo& info) override { 46 void OnReceivedResponse(const ResourceResponseInfo& info) override {
45 ADD_FAILURE() << "OnReceivedResponse should not be called."; 47 ADD_FAILURE() << "OnReceivedResponse should not be called.";
46 } 48 }
47 49
48 void OnDownloadedData(int len, int encoded_data_length) override { 50 void OnDownloadedData(int len, int encoded_data_length) override {
49 ADD_FAILURE() << "OnDownloadedData should not be called."; 51 ADD_FAILURE() << "OnDownloadedData should not be called.";
50 } 52 }
51 53
52 void OnReceivedData(std::unique_ptr<ReceivedData> data) override { 54 void OnReceivedData(std::unique_ptr<ReceivedData> data) override {
53 EXPECT_FALSE(context_->complete); 55 EXPECT_FALSE(context_->complete);
54 context_->data.append(data->payload(), data->length()); 56 context_->data.append(data->payload(), data->length());
57 if (context_->release_data_asynchronously)
58 task_runner_->DeleteSoon(FROM_HERE, data.release());
55 context_->run_loop_quit_closure.Run(); 59 context_->run_loop_quit_closure.Run();
56 } 60 }
57 61
58 void OnTransferSizeUpdated(int transfer_size_diff) override {} 62 void OnTransferSizeUpdated(int transfer_size_diff) override {}
59 63
60 void OnCompletedRequest(int error_code, 64 void OnCompletedRequest(int error_code,
61 bool was_ignored_by_handler, 65 bool was_ignored_by_handler,
62 bool stale_copy_in_cache, 66 bool stale_copy_in_cache,
63 const base::TimeTicks& completion_time, 67 const base::TimeTicks& completion_time,
64 int64_t total_transfer_size, 68 int64_t total_transfer_size,
65 int64_t encoded_body_size) override { 69 int64_t encoded_body_size) override {
66 EXPECT_FALSE(context_->complete); 70 EXPECT_FALSE(context_->complete);
67 context_->complete = true; 71 context_->complete = true;
68 context_->error_code = error_code; 72 context_->error_code = error_code;
69 context_->run_loop_quit_closure.Run(); 73 context_->run_loop_quit_closure.Run();
70 } 74 }
71 75
72 struct Context { 76 struct Context {
73 // Data received. If downloading to file, remains empty. 77 // Data received. If downloading to file, remains empty.
74 std::string data; 78 std::string data;
75 bool complete = false; 79 bool complete = false;
76 base::Closure run_loop_quit_closure; 80 base::Closure run_loop_quit_closure;
77 int error_code = net::OK; 81 int error_code = net::OK;
82 bool release_data_asynchronously = false;
78 }; 83 };
79 84
80 private: 85 private:
81 Context* context_; 86 Context* context_;
87 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
82 88
83 DISALLOW_COPY_AND_ASSIGN(TestRequestPeer); 89 DISALLOW_COPY_AND_ASSIGN(TestRequestPeer);
84 }; 90 };
85 91
86 class URLResponseBodyConsumerTest : public ::testing::Test, 92 class URLResponseBodyConsumerTest : public ::testing::Test,
87 public ::IPC::Sender { 93 public ::IPC::Sender {
88 protected: 94 protected:
89 URLResponseBodyConsumerTest() 95 URLResponseBodyConsumerTest()
90 : dispatcher_(new ResourceDispatcher(this, message_loop_.task_runner())) { 96 : dispatcher_(new ResourceDispatcher(this, message_loop_.task_runner())) {
91 } 97 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 options.element_num_bytes = 1; 129 options.element_num_bytes = 1;
124 options.capacity_num_bytes = 1024; 130 options.capacity_num_bytes = 1024;
125 return options; 131 return options;
126 } 132 }
127 133
128 // Returns the request id. 134 // Returns the request id.
129 int SetUpRequestPeer(std::unique_ptr<ResourceRequest> request, 135 int SetUpRequestPeer(std::unique_ptr<ResourceRequest> request,
130 TestRequestPeer::Context* context) { 136 TestRequestPeer::Context* context) {
131 return dispatcher_->StartAsync( 137 return dispatcher_->StartAsync(
132 std::move(request), 0, nullptr, url::Origin(), 138 std::move(request), 0, nullptr, url::Origin(),
133 base::MakeUnique<TestRequestPeer>(context), 139 base::MakeUnique<TestRequestPeer>(context, message_loop_.task_runner()),
134 blink::WebURLRequest::LoadingIPCType::ChromeIPC, nullptr, nullptr); 140 blink::WebURLRequest::LoadingIPCType::ChromeIPC, nullptr, nullptr);
135 } 141 }
136 142
137 void Run(TestRequestPeer::Context* context) { 143 void Run(TestRequestPeer::Context* context) {
138 base::RunLoop run_loop; 144 base::RunLoop run_loop;
139 context->run_loop_quit_closure = run_loop.QuitClosure(); 145 context->run_loop_quit_closure = run_loop.QuitClosure();
140 run_loop.Run(); 146 run_loop.Run();
141 } 147 }
142 148
143 base::MessageLoop message_loop_; 149 base::MessageLoop message_loop_;
144 std::unique_ptr<ResourceDispatcher> dispatcher_; 150 std::unique_ptr<ResourceDispatcher> dispatcher_;
145 static const MojoWriteDataFlags kNone = MOJO_WRITE_DATA_FLAG_NONE; 151 static const MojoWriteDataFlags kNone = MOJO_WRITE_DATA_FLAG_NONE;
146 }; 152 };
147 153
148 TEST_F(URLResponseBodyConsumerTest, ReceiveData) { 154 TEST_F(URLResponseBodyConsumerTest, ReceiveData) {
149 TestRequestPeer::Context context; 155 TestRequestPeer::Context context;
150 std::unique_ptr<ResourceRequest> request(CreateResourceRequest()); 156 std::unique_ptr<ResourceRequest> request(CreateResourceRequest());
151 int request_id = SetUpRequestPeer(std::move(request), &context); 157 int request_id = SetUpRequestPeer(std::move(request), &context);
152 mojo::DataPipe data_pipe(CreateDataPipeOptions()); 158 mojo::DataPipe data_pipe(CreateDataPipeOptions());
153 159
154 scoped_refptr<URLResponseBodyConsumer> consumer(new URLResponseBodyConsumer( 160 scoped_refptr<URLResponseBodyConsumer> consumer(new URLResponseBodyConsumer(
155 request_id, dispatcher_.get(), std::move(data_pipe.consumer_handle), 161 request_id, dispatcher_.get(), std::move(data_pipe.consumer_handle),
156 message_loop_.task_runner())); 162 message_loop_.task_runner()));
157 consumer->Start(message_loop_.task_runner().get()); 163 consumer->Start();
158 164
159 mojo::ScopedDataPipeProducerHandle writer = 165 mojo::ScopedDataPipeProducerHandle writer =
160 std::move(data_pipe.producer_handle); 166 std::move(data_pipe.producer_handle);
161 std::string buffer = "hello"; 167 std::string buffer = "hello";
162 uint32_t size = buffer.size(); 168 uint32_t size = buffer.size();
163 MojoResult result = 169 MojoResult result =
164 mojo::WriteDataRaw(writer.get(), buffer.c_str(), &size, kNone); 170 mojo::WriteDataRaw(writer.get(), buffer.c_str(), &size, kNone);
165 ASSERT_EQ(MOJO_RESULT_OK, result); 171 ASSERT_EQ(MOJO_RESULT_OK, result);
166 ASSERT_EQ(buffer.size(), size); 172 ASSERT_EQ(buffer.size(), size);
167 173
168 Run(&context); 174 Run(&context);
169 175
170 EXPECT_FALSE(context.complete); 176 EXPECT_FALSE(context.complete);
171 EXPECT_EQ("hello", context.data); 177 EXPECT_EQ("hello", context.data);
172 } 178 }
173 179
174 TEST_F(URLResponseBodyConsumerTest, OnCompleteThenClose) { 180 TEST_F(URLResponseBodyConsumerTest, OnCompleteThenClose) {
175 TestRequestPeer::Context context; 181 TestRequestPeer::Context context;
176 std::unique_ptr<ResourceRequest> request(CreateResourceRequest()); 182 std::unique_ptr<ResourceRequest> request(CreateResourceRequest());
177 int request_id = SetUpRequestPeer(std::move(request), &context); 183 int request_id = SetUpRequestPeer(std::move(request), &context);
178 mojo::DataPipe data_pipe(CreateDataPipeOptions()); 184 mojo::DataPipe data_pipe(CreateDataPipeOptions());
179 185
180 scoped_refptr<URLResponseBodyConsumer> consumer(new URLResponseBodyConsumer( 186 scoped_refptr<URLResponseBodyConsumer> consumer(new URLResponseBodyConsumer(
181 request_id, dispatcher_.get(), std::move(data_pipe.consumer_handle), 187 request_id, dispatcher_.get(), std::move(data_pipe.consumer_handle),
182 message_loop_.task_runner())); 188 message_loop_.task_runner()));
183 consumer->Start(message_loop_.task_runner().get()); 189 consumer->Start();
184 190
185 consumer->OnComplete(ResourceRequestCompletionStatus()); 191 consumer->OnComplete(ResourceRequestCompletionStatus());
186 mojo::ScopedDataPipeProducerHandle writer = 192 mojo::ScopedDataPipeProducerHandle writer =
193 std::move(data_pipe.producer_handle);
194 std::string buffer = "hello";
195 uint32_t size = buffer.size();
196 MojoResult result =
197 mojo::WriteDataRaw(writer.get(), buffer.c_str(), &size, kNone);
198 ASSERT_EQ(MOJO_RESULT_OK, result);
199 ASSERT_EQ(buffer.size(), size);
200
201 Run(&context);
202
203 writer.reset();
204 EXPECT_FALSE(context.complete);
205 EXPECT_EQ("hello", context.data);
206
207 Run(&context);
208
209 EXPECT_TRUE(context.complete);
210 EXPECT_EQ("hello", context.data);
211 }
212
213 // Release the received data asynchronously. This leads to MOJO_RESULT_BUSY
214 // from the BeginReadDataRaw call in OnReadable.
215 TEST_F(URLResponseBodyConsumerTest, OnCompleteThenCloseWithAsyncRelease) {
216 TestRequestPeer::Context context;
217 context.release_data_asynchronously = true;
218 std::unique_ptr<ResourceRequest> request(CreateResourceRequest());
219 int request_id = SetUpRequestPeer(std::move(request), &context);
220 mojo::DataPipe data_pipe(CreateDataPipeOptions());
221
222 scoped_refptr<URLResponseBodyConsumer> consumer(new URLResponseBodyConsumer(
223 request_id, dispatcher_.get(), std::move(data_pipe.consumer_handle),
224 message_loop_.task_runner()));
225 consumer->Start();
226
227 consumer->OnComplete(ResourceRequestCompletionStatus());
228 mojo::ScopedDataPipeProducerHandle writer =
187 std::move(data_pipe.producer_handle); 229 std::move(data_pipe.producer_handle);
188 std::string buffer = "hello"; 230 std::string buffer = "hello";
189 uint32_t size = buffer.size(); 231 uint32_t size = buffer.size();
190 MojoResult result = 232 MojoResult result =
191 mojo::WriteDataRaw(writer.get(), buffer.c_str(), &size, kNone); 233 mojo::WriteDataRaw(writer.get(), buffer.c_str(), &size, kNone);
192 ASSERT_EQ(MOJO_RESULT_OK, result); 234 ASSERT_EQ(MOJO_RESULT_OK, result);
193 ASSERT_EQ(buffer.size(), size); 235 ASSERT_EQ(buffer.size(), size);
194 236
195 Run(&context); 237 Run(&context);
196 238
197 writer.reset(); 239 writer.reset();
198 EXPECT_FALSE(context.complete); 240 EXPECT_FALSE(context.complete);
199 EXPECT_EQ("hello", context.data); 241 EXPECT_EQ("hello", context.data);
200 242
201 Run(&context); 243 Run(&context);
202 244
203 EXPECT_TRUE(context.complete); 245 EXPECT_TRUE(context.complete);
204 EXPECT_EQ("hello", context.data); 246 EXPECT_EQ("hello", context.data);
205 } 247 }
206 248
207 TEST_F(URLResponseBodyConsumerTest, CloseThenOnComplete) { 249 TEST_F(URLResponseBodyConsumerTest, CloseThenOnComplete) {
208 TestRequestPeer::Context context; 250 TestRequestPeer::Context context;
209 std::unique_ptr<ResourceRequest> request(CreateResourceRequest()); 251 std::unique_ptr<ResourceRequest> request(CreateResourceRequest());
210 int request_id = SetUpRequestPeer(std::move(request), &context); 252 int request_id = SetUpRequestPeer(std::move(request), &context);
211 mojo::DataPipe data_pipe(CreateDataPipeOptions()); 253 mojo::DataPipe data_pipe(CreateDataPipeOptions());
212 254
213 scoped_refptr<URLResponseBodyConsumer> consumer(new URLResponseBodyConsumer( 255 scoped_refptr<URLResponseBodyConsumer> consumer(new URLResponseBodyConsumer(
214 request_id, dispatcher_.get(), std::move(data_pipe.consumer_handle), 256 request_id, dispatcher_.get(), std::move(data_pipe.consumer_handle),
215 message_loop_.task_runner())); 257 message_loop_.task_runner()));
216 consumer->Start(message_loop_.task_runner().get()); 258 consumer->Start();
217 259
218 ResourceRequestCompletionStatus status; 260 ResourceRequestCompletionStatus status;
219 status.error_code = net::ERR_FAILED; 261 status.error_code = net::ERR_FAILED;
220 data_pipe.producer_handle.reset(); 262 data_pipe.producer_handle.reset();
221 consumer->OnComplete(status); 263 consumer->OnComplete(status);
222 264
223 Run(&context); 265 Run(&context);
224 266
225 EXPECT_TRUE(context.complete); 267 EXPECT_TRUE(context.complete);
226 EXPECT_EQ(net::ERR_FAILED, context.error_code); 268 EXPECT_EQ(net::ERR_FAILED, context.error_code);
227 EXPECT_EQ("", context.data); 269 EXPECT_EQ("", context.data);
228 } 270 }
229 271
230 } // namespace 272 } // namespace
231 273
232 } // namespace content 274 } // namespace content
OLDNEW
« no previous file with comments | « content/child/url_response_body_consumer.cc ('k') | third_party/WebKit/LayoutTests/TestExpectations » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698