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

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