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

Side by Side Diff: content/browser/loader/async_resource_handler_unittest.cc

Issue 2092993002: Browser process changes for Resource Timing sizes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix base::FeatureList DCHECK again Created 4 years, 5 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
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "content/browser/loader/async_resource_handler.h"
6
7 #include <stddef.h>
8 #include <stdint.h>
9 #include <memory>
10 #include <string>
11 #include <tuple>
12 #include <utility>
13 #include <vector>
14
15 #include "base/bind.h"
16 #include "base/bind_helpers.h"
17 #include "base/feature_list.h"
18 #include "base/format_macros.h"
19 #include "base/logging.h"
20 #include "base/memory/ptr_util.h"
21 #include "base/memory/ref_counted.h"
22 #include "base/memory/weak_ptr.h"
23 #include "base/process/process.h"
24 #include "base/run_loop.h"
25 #include "base/strings/stringprintf.h"
26 #include "content/browser/loader/resource_dispatcher_host_impl.h"
27 #include "content/browser/loader/resource_loader.h"
28 #include "content/browser/loader/resource_loader_delegate.h"
29 #include "content/browser/loader/resource_message_filter.h"
30 #include "content/browser/loader/resource_request_info_impl.h"
31 #include "content/common/resource_messages.h"
32 #include "content/common/resource_request.h"
33 #include "content/public/browser/resource_context.h"
34 #include "content/public/browser/resource_request_info.h"
35 #include "content/public/common/content_features.h"
36 #include "content/public/common/process_type.h"
37 #include "content/public/common/resource_type.h"
38 #include "content/public/test/mock_resource_context.h"
39 #include "content/public/test/test_browser_thread_bundle.h"
40 #include "ipc/ipc_message.h"
41 #include "ipc/ipc_message_macros.h"
42 #include "net/http/http_response_headers.h"
43 #include "net/http/http_util.h"
44 #include "net/ssl/client_cert_store.h"
45 #include "net/url_request/url_request.h"
46 #include "net/url_request/url_request_context.h"
47 #include "net/url_request/url_request_job_factory_impl.h"
48 #include "net/url_request/url_request_test_job.h"
49 #include "net/url_request/url_request_test_util.h"
50 #include "testing/gtest/include/gtest/gtest.h"
51 #include "ui/base/page_transition_types.h"
52 #include "url/gurl.h"
53
54 namespace content {
55
56 namespace {
57
58 std::string GenerateHeader(size_t response_data_size) {
59 return base::StringPrintf(
60 "HTTP/1.1 200 OK\n"
61 "Content-type: text/html\n"
62 "Content-Length: %" PRIuS "\n",
63 response_data_size);
64 }
65
66 std::string GenerateData(size_t response_data_size) {
67 return std::string(response_data_size, 'a');
68 }
69
70 // This test job adds a Content-Length header and implements
71 // GetTotalReceivedBytes().
72 class TestJob : public net::URLRequestTestJob {
73 public:
74 TestJob(net::URLRequest* request,
75 net::NetworkDelegate* network_delegate,
76 size_t response_data_size)
77 : net::URLRequestTestJob(request,
78 network_delegate,
79 GenerateHeader(response_data_size),
80 GenerateData(response_data_size),
81 true) {}
82
83 static TestJob* CreateJob(net::URLRequest* request,
84 net::NetworkDelegate* network_delegate,
85 size_t response_data_size) {
86 return new TestJob(request, network_delegate, response_data_size);
87 }
88
89 // URLRequestJob implementation:
90 // TODO(ricea): Move this to URLRequestTestJob.
91 int64_t GetTotalReceivedBytes() const override {
92 std::string http_headers = net::HttpUtil::ConvertHeadersBackToHTTPResponse(
93 response_headers_->raw_headers());
94 return http_headers.size() + offset_;
95 }
96
97 private:
98 DISALLOW_COPY_AND_ASSIGN(TestJob);
99 };
100
101 class TestJobProtocolHandler
102 : public net::URLRequestJobFactory::ProtocolHandler {
103 public:
104 TestJobProtocolHandler(size_t response_data_size)
105 : response_data_size_(response_data_size) {}
106
107 net::URLRequestJob* MaybeCreateJob(
108 net::URLRequest* request,
109 net::NetworkDelegate* network_delegate) const override {
110 return TestJob::CreateJob(request, network_delegate, response_data_size_);
111 }
112
113 private:
114 size_t response_data_size_;
115 };
116
117 // A subclass of ResourceMessageFilter that records IPC messages that are sent.
118 class RecordingResourceMessageFilter : public ResourceMessageFilter {
119 public:
120 RecordingResourceMessageFilter(ResourceContext* resource_context,
121 net::URLRequestContext* request_context)
122 : ResourceMessageFilter(
123 0,
124 PROCESS_TYPE_RENDERER,
125 nullptr,
126 nullptr,
127 nullptr,
128 nullptr,
129 nullptr,
130 base::Bind(&RecordingResourceMessageFilter::GetContexts,
131 base::Unretained(this))),
132 resource_context_(resource_context),
133 request_context_(request_context) {
134 set_peer_process_for_testing(base::Process::Current());
135 }
136
137 const std::vector<std::unique_ptr<IPC::Message>>& messages() const {
138 return messages_;
139 }
140
141 // IPC::Sender implementation:
142 bool Send(IPC::Message* message) override {
143 // Unpickle the base::SharedMemoryHandle to avoid warnings about
144 // "MessageAttachmentSet destroyed with unconsumed descriptors".
145 if (message->type() == ResourceMsg_SetDataBuffer::ID) {
146 ResourceMsg_SetDataBuffer::Param params;
147 ResourceMsg_SetDataBuffer::Read(message, &params);
148 }
149 messages_.push_back(base::WrapUnique(message));
150 return true;
151 }
152
153 private:
154 ~RecordingResourceMessageFilter() override {}
155
156 void GetContexts(ResourceType resource_type,
157 int origin_pid,
158 ResourceContext** resource_context,
159 net::URLRequestContext** request_context) {
160 *resource_context = resource_context_;
161 *request_context = request_context_;
162 }
163
164 ResourceContext* const resource_context_;
165 net::URLRequestContext* const request_context_;
166 std::vector<std::unique_ptr<IPC::Message>> messages_;
167 };
168
169 class AsyncResourceHandlerTest : public ::testing::Test,
170 public ResourceLoaderDelegate {
171 protected:
172 AsyncResourceHandlerTest()
173 : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP), context_(true) {}
174
175 void TearDown() override {
176 // Prevent memory leaks.
177 rdh_.Shutdown();
178 base::RunLoop().RunUntilIdle();
179 }
180
181 void CreateRequest(size_t response_data_size) {
kinuko 2016/07/11 14:29:36 nit: CreateRequestWithResponseDataSize or somethin
182 test_job_factory_.SetProtocolHandler(
183 "test", base::MakeUnique<TestJobProtocolHandler>(response_data_size));
184 context_.set_job_factory(&test_job_factory_);
185 context_.Init();
186 std::unique_ptr<net::URLRequest> request = context_.CreateRequest(
187 GURL("test:test"), net::DEFAULT_PRIORITY, nullptr);
188 resource_context_ = base::MakeUnique<MockResourceContext>(&context_);
189 filter_ = make_scoped_refptr(
kinuko 2016/07/11 14:29:36 nit: probably we can remove this make_scoped_refpt
190 new RecordingResourceMessageFilter(resource_context_.get(), &context_));
191 ResourceRequestInfoImpl* info = new ResourceRequestInfoImpl(
192 PROCESS_TYPE_RENDERER, // process_type
193 0, // child_id
194 0, // route_id
195 -1, // frame_tree_node_id
196 0, // origin_pid
197 0, // request_id
198 0, // render_frame_id
199 false, // is_main_frame
200 false, // parent_is_main_frame
201 RESOURCE_TYPE_IMAGE, // resource_type
202 ui::PAGE_TRANSITION_LINK, // transition_type
203 false, // should_replace_current_entry
204 false, // is_download
205 false, // is_stream
206 false, // allow_download
207 false, // has_user_gesture
208 false, // enable load timing
209 false, // enable upload progress
210 false, // do_not_prompt_for_login
211 blink::WebReferrerPolicyDefault, // referrer_policy
212 blink::WebPageVisibilityStateVisible, // visibility_state
213 resource_context_.get(), // context
214 filter_->GetWeakPtr(), // filter
215 false, // report_raw_headers
216 true, // is_async
217 false, // is_using_lofi
218 std::string(), // original_headers
219 nullptr, // body
220 false); // initiated_in_secure_context
221 info->AssociateWithRequest(request.get());
222 std::unique_ptr<AsyncResourceHandler> handler =
223 base::MakeUnique<AsyncResourceHandler>(request.get(), &rdh_);
224 loader_ = base::MakeUnique<ResourceLoader>(
225 std::move(request), std::move(handler), nullptr, this);
226 }
227
228 void CreateStartAndWait(size_t response_data_size) {
kinuko 2016/07/11 14:29:36 nit: the name is a bit hard to parse... (so many v
229 CreateRequest(response_data_size);
230 loader_->StartRequest();
231 finish_waiter_.reset(new base::RunLoop);
232 finish_waiter_->Run();
233 }
234
235 scoped_refptr<RecordingResourceMessageFilter> filter_;
236
237 private:
238 // ResourceLoaderDelegate implementation:
239 ResourceDispatcherHostLoginDelegate* CreateLoginDelegate(
240 ResourceLoader* loader,
241 net::AuthChallengeInfo* auth_info) override {
242 return nullptr;
243 }
244
245 bool HandleExternalProtocol(ResourceLoader* loader,
246 const GURL& url) override {
247 return false;
248 }
249 void DidStartRequest(ResourceLoader* loader) override {}
250 void DidReceiveRedirect(ResourceLoader* loader,
251 const GURL& new_url) override {}
252 void DidReceiveResponse(ResourceLoader* loader) override {}
253 void DidFinishLoading(ResourceLoader* loader) override {
254 loader_.reset();
255 finish_waiter_->Quit();
256 }
257 std::unique_ptr<net::ClientCertStore> CreateClientCertStore(
258 ResourceLoader* loader) override {
259 return nullptr;
260 }
261
262 TestBrowserThreadBundle thread_bundle_;
263 ResourceDispatcherHostImpl rdh_;
264 net::TestURLRequestContext context_;
265 net::URLRequestJobFactoryImpl test_job_factory_;
266 std::unique_ptr<MockResourceContext> resource_context_;
267 std::unique_ptr<ResourceLoader> loader_;
268 std::unique_ptr<base::RunLoop> finish_waiter_;
269 };
270
271 TEST_F(AsyncResourceHandlerTest, Construct) {
272 CreateRequest(1);
273 }
274
275 TEST_F(AsyncResourceHandlerTest, OneChunkLengths) {
276 // Larger than kInlinedLeadingChunkSize and smaller than
277 // kMaxAllocationSize.
278 CreateStartAndWait(4096);
279 const auto& messages = filter_->messages();
280 ASSERT_EQ(4u, messages.size());
281 ASSERT_EQ(ResourceMsg_DataReceived::ID, messages[2]->type());
282 ResourceMsg_DataReceived::Param params;
283 ResourceMsg_DataReceived::Read(messages[2].get(), &params);
284
285 int encoded_data_length = std::get<3>(params);
286 EXPECT_EQ(4162, encoded_data_length);
287 int encoded_body_length = std::get<4>(params);
288 EXPECT_EQ(4096, encoded_body_length);
289 }
290
291 TEST_F(AsyncResourceHandlerTest, InlinedChunkLengths) {
292 // TODO(ricea): Remove this Feature-enabling code once the feature is on by
293 // default.
294 auto feature_list = base::MakeUnique<base::FeatureList>();
295 feature_list->InitializeFromCommandLine(
296 features::kOptimizeLoadingIPCForSmallResources.name, "");
297 base::FeatureList::ClearInstanceForTesting();
298 base::FeatureList::SetInstance(std::move(feature_list));
299
300 // Smaller than kInlinedLeadingChunkSize.
301 CreateStartAndWait(8);
302 const auto& messages = filter_->messages();
303 ASSERT_EQ(3u, messages.size());
304 ASSERT_EQ(ResourceMsg_InlinedDataChunkReceived::ID, messages[1]->type());
305 ResourceMsg_InlinedDataChunkReceived::Param params;
306 ResourceMsg_InlinedDataChunkReceived::Read(messages[1].get(), &params);
307
308 int encoded_data_length = std::get<2>(params);
309 EXPECT_EQ(71, encoded_data_length);
310 int encoded_body_length = std::get<3>(params);
311 EXPECT_EQ(8, encoded_body_length);
312 }
313
314 TEST_F(AsyncResourceHandlerTest, TwoChunksLengths) {
315 // Larger than kMaxAllocationSize.
316 CreateStartAndWait(64*1024);
317 const auto& messages = filter_->messages();
318 ASSERT_EQ(5u, messages.size());
319 ASSERT_EQ(ResourceMsg_DataReceived::ID, messages[2]->type());
320 ResourceMsg_DataReceived::Param params;
321 ResourceMsg_DataReceived::Read(messages[2].get(), &params);
322
323 int encoded_data_length = std::get<3>(params);
324 EXPECT_EQ(32835, encoded_data_length);
325 int encoded_body_length = std::get<4>(params);
326 EXPECT_EQ(32768, encoded_body_length);
327
328 ASSERT_EQ(ResourceMsg_DataReceived::ID, messages[3]->type());
329 ResourceMsg_DataReceived::Read(messages[3].get(), &params);
330
331 encoded_data_length = std::get<3>(params);
332 EXPECT_EQ(32768, encoded_data_length);
333 encoded_body_length = std::get<4>(params);
334 EXPECT_EQ(32768, encoded_body_length);
335 }
336
337 } // namespace
338
339 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/loader/async_resource_handler.cc ('k') | content/browser/loader/sync_resource_handler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698