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

Side by Side Diff: chrome/browser/predictors/resource_prefetch_predictor_browsertest.cc

Issue 2449323005: predictors: Basic browsertest checks predictor learning. (Closed)
Patch Set: Reuse URLRequestSummary for ResourceSummary + Defaults. Created 4 years, 1 month 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 "base/command_line.h"
6 #include "chrome/browser/predictors/resource_prefetch_predictor.h"
7 #include "chrome/browser/predictors/resource_prefetch_predictor_factory.h"
8 #include "chrome/browser/predictors/resource_prefetch_predictor_test_util.h"
9 #include "chrome/browser/profiles/profile.h"
10 #include "chrome/browser/ui/browser.h"
11 #include "chrome/browser/ui/tabs/tab_strip_model.h"
12 #include "chrome/common/chrome_switches.h"
13 #include "chrome/test/base/in_process_browser_test.h"
14 #include "chrome/test/base/ui_test_utils.h"
15 #include "content/public/browser/render_frame_host.h"
16 #include "content/public/browser/render_process_host.h"
17 #include "net/test/embedded_test_server/http_request.h"
18 #include "net/test/embedded_test_server/http_response.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 using testing::UnorderedElementsAreArray;
23
24 namespace predictors {
25
26 using PageRequestSummary = ResourcePrefetchPredictor::PageRequestSummary;
27 using URLRequestSummary = ResourcePrefetchPredictor::URLRequestSummary;
28 using net::test_server::HttpRequest;
29 using net::test_server::HttpResponse;
30 using net::test_server::BasicHttpResponse;
31
32 struct ResourceSummary {
33 ResourceSummary() : is_no_store(false), version(0) {}
34
35 URLRequestSummary request;
36 std::string content;
37 bool is_no_store;
38 size_t version;
39 };
40
41 // Corresponds to blink::typeToPrioriity function.
Benoit L 2016/11/02 17:35:47 typo: typeToPriority.
alexilin 2016/11/02 17:49:17 Done.
42 net::RequestPriority GetDefaultPriorityForType(content::ResourceType type) {
Benoit L 2016/11/02 17:35:47 Per offline discussion, I think it's simpler to ha
alexilin 2016/11/02 17:49:17 Never mind. Done.
43 switch (type) {
44 case content::RESOURCE_TYPE_STYLESHEET:
45 case content::RESOURCE_TYPE_FONT_RESOURCE:
46 return net::HIGHEST;
47 case content::RESOURCE_TYPE_SCRIPT:
48 return net::MEDIUM;
49 case content::RESOURCE_TYPE_IMAGE:
50 return net::LOWEST;
51 default:
52 return net::DEFAULT_PRIORITY;
53 }
54 }
55
56 std::string GetDefaultMimeTypeForType(content::ResourceType type) {
57 switch (type) {
58 case content::RESOURCE_TYPE_STYLESHEET:
59 return "text/css";
60 case content::RESOURCE_TYPE_FONT_RESOURCE:
61 return "application/x-font-truetype";
62 case content::RESOURCE_TYPE_SCRIPT:
63 return "application/javascript";
64 case content::RESOURCE_TYPE_IMAGE:
65 return "image/png";
66 default:
67 return "application/octet-stream";
68 }
69 }
70
71 std::string GetDefaultResourceUrlForType(content::ResourceType type) {
72 switch (type) {
73 case content::RESOURCE_TYPE_STYLESHEET:
74 return "/predictors/style.css";
75 case content::RESOURCE_TYPE_FONT_RESOURCE:
76 return "/predictors/font.ttf";
77 case content::RESOURCE_TYPE_SCRIPT:
78 return "/predictors/script.js";
79 case content::RESOURCE_TYPE_IMAGE:
80 return "/predictors/image.png";
81 default:
82 return "/predictors/resource";
83 }
84 }
85
86 // Helper class to track and allow waiting for ResourcePrefetchPredictor events.
87 class ResourcePrefetchPredictorTestObserver : public TestObserver {
88 public:
89 explicit ResourcePrefetchPredictorTestObserver(
90 ResourcePrefetchPredictor* predictor,
91 const size_t expected_url_visit_count,
92 const PageRequestSummary& expected_summary)
93 : TestObserver(predictor),
94 message_loop_runner_(new content::MessageLoopRunner()),
95 url_visit_count_(expected_url_visit_count),
96 summary_(expected_summary) {}
97
98 ~ResourcePrefetchPredictorTestObserver() override {}
99
100 // ResourcePrefetchPredictor::Observer
101 void OnNavigationLearned(size_t url_visit_count,
102 const PageRequestSummary& summary) override {
103 EXPECT_EQ(url_visit_count, url_visit_count_);
104 EXPECT_EQ(summary.main_frame_url, summary_.main_frame_url);
105 EXPECT_EQ(summary.initial_url, summary_.initial_url);
106 EXPECT_THAT(summary.subresource_requests,
107 UnorderedElementsAreArray(summary_.subresource_requests));
108 message_loop_runner_->Quit();
109 }
110
111 void Wait() { message_loop_runner_->Run(); }
112
113 private:
114 scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
115 size_t url_visit_count_;
116 PageRequestSummary summary_;
117
118 DISALLOW_COPY_AND_ASSIGN(ResourcePrefetchPredictorTestObserver);
119 };
120
121 class ResourcePrefetchPredictorBrowserTest : public InProcessBrowserTest {
122 public:
123 void SetUpCommandLine(base::CommandLine* command_line) override {
124 command_line->AppendSwitchASCII(
125 switches::kSpeculativeResourcePrefetching,
126 switches::kSpeculativeResourcePrefetchingEnabled);
127 }
128
129 void SetUpOnMainThread() override {
130 embedded_test_server()->RegisterRequestHandler(
131 base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleRequest,
132 base::Unretained(this)));
133 ASSERT_TRUE(embedded_test_server()->Start());
134 predictor_ =
135 ResourcePrefetchPredictorFactory::GetForProfile(browser()->profile());
136 ASSERT_TRUE(predictor_);
137 }
138
139 void NavigateToURLAndCheckSubresources(
140 const std::string& main_frame_relative) {
141 GURL main_frame_absolute =
142 embedded_test_server()->GetURL(main_frame_relative);
143 std::vector<URLRequestSummary> url_request_summaries;
144 for (const auto& kv : resources_) {
145 if (kv.second.is_no_store)
146 continue;
147 url_request_summaries.push_back(
148 GetURLRequestSummaryForResource(main_frame_absolute, kv.second));
149 }
150 ResourcePrefetchPredictorTestObserver observer(
151 predictor_, UpdateAndGetVisitCount(main_frame_relative),
152 CreatePageRequestSummary(main_frame_absolute.spec(),
153 main_frame_absolute.spec(),
154 url_request_summaries));
155 ui_test_utils::NavigateToURL(browser(), main_frame_absolute);
156 observer.Wait();
157 }
158
159 void AddDefaultResourceByType(content::ResourceType resource_type) {
160 AddResource(GetDefaultResourceUrlForType(resource_type), resource_type,
161 GetDefaultPriorityForType(resource_type),
162 GetDefaultMimeTypeForType(resource_type));
163 }
164
165 void AddResource(const std::string& relative_url,
166 content::ResourceType resource_type,
167 net::RequestPriority priority,
168 const std::string& mime_type,
169 bool has_validators = true,
170 bool always_revalidate = false,
171 const std::string& content = std::string(),
172 bool is_no_store = false) {
173 ResourceSummary resource;
174 GURL resource_url = embedded_test_server()->GetURL(relative_url);
175 resource.request = CreateURLRequestSummary(
176 -1, -1, std::string(), resource_url.spec(), resource_type, priority,
177 mime_type, false, std::string(), has_validators, always_revalidate);
178 resource.content = content;
179 resource.is_no_store = is_no_store;
180 resources_[relative_url] = resource;
181 }
182
183 private:
184 URLRequestSummary GetURLRequestSummaryForResource(
185 const GURL& main_frame_url,
186 const ResourceSummary& resource_summary) {
187 URLRequestSummary summary(resource_summary.request);
188 content::WebContents* web_contents =
189 browser()->tab_strip_model()->GetActiveWebContents();
190 int process_id = web_contents->GetRenderProcessHost()->GetID();
191 int frame_id = web_contents->GetMainFrame()->GetRoutingID();
192 summary.navigation_id =
193 CreateNavigationID(process_id, frame_id, main_frame_url.spec());
194 return summary;
195 }
196
197 std::unique_ptr<HttpResponse> HandleRequest(const HttpRequest& request) {
198 auto resource_it = resources_.find(request.relative_url);
199 if (resource_it == resources_.end())
200 return nullptr;
201
202 const ResourceSummary& summary = resource_it->second;
203 std::unique_ptr<BasicHttpResponse> http_response =
204 base::MakeUnique<BasicHttpResponse>();
205 http_response->set_code(net::HTTP_OK);
206 http_response->set_content_type(summary.request.mime_type);
207 http_response->set_content(summary.content);
208 if (summary.is_no_store)
209 http_response->AddCustomHeader("Cache-Control", "no-store");
210 if (summary.request.has_validators) {
211 http_response->AddCustomHeader(
212 "ETag", base::StringPrintf("'%zu%s'", summary.version,
213 request.relative_url.c_str()));
214 }
215 if (summary.request.always_revalidate)
216 http_response->AddCustomHeader("Cache-Control", "no-cache");
217 else
218 http_response->AddCustomHeader("Cache-Control", "max-age=2147483648");
219 return std::move(http_response);
220 }
221
222 size_t UpdateAndGetVisitCount(const std::string& main_frame_relative) {
223 return ++visit_count_[main_frame_relative];
224 }
225
226 ResourcePrefetchPredictor* predictor_;
227 std::map<std::string, ResourceSummary> resources_;
228 std::map<std::string, size_t> visit_count_;
229 };
230
231 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, ) {
232 AddDefaultResourceByType(content::RESOURCE_TYPE_IMAGE);
233 AddDefaultResourceByType(content::RESOURCE_TYPE_STYLESHEET);
234 AddDefaultResourceByType(content::RESOURCE_TYPE_SCRIPT);
235 AddDefaultResourceByType(content::RESOURCE_TYPE_FONT_RESOURCE);
236 NavigateToURLAndCheckSubresources("/predictors/html_subresources.html");
237 }
238
239 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698