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

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

Issue 2519963002: predictors: Add browsertest that checks redirects. (Closed)
Patch Set: . 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "base/command_line.h" 5 #include "base/command_line.h"
6 #include "chrome/browser/predictors/resource_prefetch_predictor.h" 6 #include "chrome/browser/predictors/resource_prefetch_predictor.h"
7 #include "chrome/browser/predictors/resource_prefetch_predictor_factory.h" 7 #include "chrome/browser/predictors/resource_prefetch_predictor_factory.h"
8 #include "chrome/browser/predictors/resource_prefetch_predictor_test_util.h" 8 #include "chrome/browser/predictors/resource_prefetch_predictor_test_util.h"
9 #include "chrome/browser/profiles/profile.h" 9 #include "chrome/browser/profiles/profile.h"
10 #include "chrome/browser/ui/browser.h" 10 #include "chrome/browser/ui/browser.h"
11 #include "chrome/browser/ui/tabs/tab_strip_model.h" 11 #include "chrome/browser/ui/tabs/tab_strip_model.h"
12 #include "chrome/common/chrome_switches.h" 12 #include "chrome/common/chrome_switches.h"
13 #include "chrome/test/base/in_process_browser_test.h" 13 #include "chrome/test/base/in_process_browser_test.h"
14 #include "chrome/test/base/ui_test_utils.h" 14 #include "chrome/test/base/ui_test_utils.h"
15 #include "content/public/browser/render_frame_host.h" 15 #include "content/public/browser/render_frame_host.h"
16 #include "content/public/browser/render_process_host.h" 16 #include "content/public/browser/render_process_host.h"
17 #include "net/test/embedded_test_server/http_request.h" 17 #include "net/test/embedded_test_server/http_request.h"
18 #include "net/test/embedded_test_server/http_response.h" 18 #include "net/test/embedded_test_server/http_response.h"
19 #include "testing/gmock/include/gmock/gmock.h" 19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h" 20 #include "testing/gtest/include/gtest/gtest.h"
21 21
22 namespace predictors { 22 namespace predictors {
23 23
24 static const char kImageUrl[] = "/predictors/image.png"; 24 static const char kImagePath[] = "/predictors/image.png";
25 static const char kStyleUrl[] = "/predictors/style.css"; 25 static const char kStylePath[] = "/predictors/style.css";
26 static const char kScriptUrl[] = "/predictors/script.js"; 26 static const char kScriptPath[] = "/predictors/script.js";
27 static const char kFontUrl[] = "/predictors/font.ttf"; 27 static const char kFontPath[] = "/predictors/font.ttf";
28 static const char kHtmlSubresourcesUrl[] = "/predictors/html_subresources.html"; 28 static const char kHtmlSubresourcesPath[] =
29 "/predictors/html_subresources.html";
30 static const char kRedirectPath[] = "/predictors/redirect.html";
31 static const char kRedirectPath2[] = "/predictors/redirect2.html";
29 32
30 struct ResourceSummary { 33 struct ResourceSummary {
31 ResourceSummary() : is_no_store(false), version(0) {} 34 ResourceSummary() : is_no_store(false), version(0) {}
32 35
33 ResourcePrefetchPredictor::URLRequestSummary request; 36 ResourcePrefetchPredictor::URLRequestSummary request;
34 std::string content; 37 std::string content;
35 bool is_no_store; 38 bool is_no_store;
36 size_t version; 39 size_t version;
37 }; 40 };
38 41
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 using URLRequestSummary = ResourcePrefetchPredictor::URLRequestSummary; 96 using URLRequestSummary = ResourcePrefetchPredictor::URLRequestSummary;
94 97
95 void SetUpCommandLine(base::CommandLine* command_line) override { 98 void SetUpCommandLine(base::CommandLine* command_line) override {
96 command_line->AppendSwitchASCII( 99 command_line->AppendSwitchASCII(
97 switches::kSpeculativeResourcePrefetching, 100 switches::kSpeculativeResourcePrefetching,
98 switches::kSpeculativeResourcePrefetchingEnabled); 101 switches::kSpeculativeResourcePrefetchingEnabled);
99 } 102 }
100 103
101 void SetUpOnMainThread() override { 104 void SetUpOnMainThread() override {
102 embedded_test_server()->RegisterRequestHandler( 105 embedded_test_server()->RegisterRequestHandler(
103 base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleRequest, 106 base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleRedirectRequest,
107 base::Unretained(this)));
108 embedded_test_server()->RegisterRequestHandler(
109 base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleResourceRequest,
104 base::Unretained(this))); 110 base::Unretained(this)));
105 ASSERT_TRUE(embedded_test_server()->Start()); 111 ASSERT_TRUE(embedded_test_server()->Start());
106 predictor_ = 112 predictor_ =
107 ResourcePrefetchPredictorFactory::GetForProfile(browser()->profile()); 113 ResourcePrefetchPredictorFactory::GetForProfile(browser()->profile());
108 ASSERT_TRUE(predictor_); 114 ASSERT_TRUE(predictor_);
109 EnsurePredictorInitialized(); 115 EnsurePredictorInitialized();
110 } 116 }
111 117
112 void NavigateToURLAndCheckSubresources( 118 void NavigateToURLAndCheckSubresources(const std::string& main_frame_path) {
113 const std::string& main_frame_relative) { 119 std::string endpoint_path = GetRedirectEndpoint(main_frame_path);
114 GURL main_frame_absolute =
115 embedded_test_server()->GetURL(main_frame_relative);
116 std::vector<URLRequestSummary> url_request_summaries; 120 std::vector<URLRequestSummary> url_request_summaries;
117 for (const auto& kv : resources_) { 121 for (const auto& kv : resources_) {
118 if (kv.second.is_no_store) 122 if (kv.second.is_no_store)
119 continue; 123 continue;
120 url_request_summaries.push_back( 124 url_request_summaries.push_back(
121 GetURLRequestSummaryForResource(main_frame_absolute, kv.second)); 125 GetURLRequestSummaryForResource(endpoint_path, kv.second));
122 } 126 }
127 GURL endpoint_url = embedded_test_server()->GetURL(endpoint_path);
128 GURL main_frame_url = embedded_test_server()->GetURL(main_frame_path);
123 ResourcePrefetchPredictorTestObserver observer( 129 ResourcePrefetchPredictorTestObserver observer(
124 predictor_, UpdateAndGetVisitCount(main_frame_relative), 130 predictor_, UpdateAndGetVisitCount(main_frame_path),
125 CreatePageRequestSummary(main_frame_absolute.spec(), 131 CreatePageRequestSummary(endpoint_url.spec(), main_frame_url.spec(),
126 main_frame_absolute.spec(),
127 url_request_summaries)); 132 url_request_summaries));
128 ui_test_utils::NavigateToURL(browser(), main_frame_absolute); 133 ui_test_utils::NavigateToURL(browser(), main_frame_url);
129 observer.Wait(); 134 observer.Wait();
130 } 135 }
131 136
132 ResourceSummary* AddResource(const std::string& relative_url, 137 ResourceSummary* AddResource(const std::string& resource_path,
pasko 2016/11/21 18:42:39 should this method be protected?
alexilin 2016/11/22 11:04:29 I can't reveal the logic behind this decision. As
pasko 2016/11/22 15:42:14 Yeah, it does not make sense to keep some methods
alexilin 2016/11/22 16:12:35 Done.
133 content::ResourceType resource_type, 138 content::ResourceType resource_type,
134 net::RequestPriority priority) { 139 net::RequestPriority priority) {
135 ResourceSummary resource; 140 ResourceSummary resource;
136 resource.request.resource_url = 141 resource.request.resource_url =
137 embedded_test_server()->GetURL(relative_url); 142 embedded_test_server()->GetURL(resource_path);
138 resource.request.resource_type = resource_type; 143 resource.request.resource_type = resource_type;
139 resource.request.priority = priority; 144 resource.request.priority = priority;
140 auto result = resources_.insert(std::make_pair(relative_url, resource)); 145 resource.request.has_validators = true;
146 auto result = resources_.insert(std::make_pair(resource_path, resource));
pasko 2016/11/21 18:42:39 should we also assert that we are not inserting th
alexilin 2016/11/22 11:04:29 Here we definitely have problems with resources th
141 return &(result.first->second); 147 return &(result.first->second);
pasko 2016/11/21 18:42:39 'auto result' followed by '&(result.first->second)
alexilin 2016/11/22 11:04:29 Thanks, it works! Btw, what about DCHECK in this c
pasko 2016/11/22 15:42:14 argh, forgot about DCHECK, yeah, I think EXPECT_TR
alexilin 2016/11/22 16:12:35 Acknowledged.
142 } 148 }
143 149
150 void AddRedirectChain(const std::vector<std::string>& redirect_chain) {
pasko 2016/11/21 18:42:39 protected as well?
alexilin 2016/11/22 16:12:35 Done.
151 ASSERT_GE(redirect_chain.size(), 2U);
152 for (size_t i = 0; i + 1 < redirect_chain.size(); ++i) {
pasko 2016/11/21 18:42:39 looks unusual, a more common way to write it would
alexilin 2016/11/22 11:04:29 I rewrote this method to support various HTTP redi
pasko 2016/11/22 15:42:14 ah, it explains a lot, makes sense. I actually sho
alexilin 2016/11/22 16:12:35 Done. Actually, there is no difference between i <
153 auto result = redirects_.insert(
154 std::make_pair(redirect_chain[i], redirect_chain[i + 1]));
155 ASSERT_TRUE(result.second) << redirect_chain[i]
156 << " already has a redirect.";
157 }
158 }
159
144 private: 160 private:
145 // ResourcePrefetchPredictor needs to be initialized before the navigation 161 // ResourcePrefetchPredictor needs to be initialized before the navigation
146 // happens otherwise this navigation will be ignored by predictor. 162 // happens otherwise this navigation will be ignored by predictor.
147 void EnsurePredictorInitialized() { 163 void EnsurePredictorInitialized() {
148 if (predictor_->initialization_state_ == 164 if (predictor_->initialization_state_ ==
149 ResourcePrefetchPredictor::INITIALIZED) { 165 ResourcePrefetchPredictor::INITIALIZED) {
150 return; 166 return;
151 } 167 }
152 168
153 InitializationObserver observer(predictor_); 169 InitializationObserver observer(predictor_);
154 if (predictor_->initialization_state_ == 170 if (predictor_->initialization_state_ ==
155 ResourcePrefetchPredictor::NOT_INITIALIZED) { 171 ResourcePrefetchPredictor::NOT_INITIALIZED) {
156 predictor_->StartInitialization(); 172 predictor_->StartInitialization();
157 } 173 }
158 observer.Wait(); 174 observer.Wait();
159 } 175 }
160 176
161 URLRequestSummary GetURLRequestSummaryForResource( 177 URLRequestSummary GetURLRequestSummaryForResource(
162 const GURL& main_frame_url, 178 const std::string& main_frame_path,
163 const ResourceSummary& resource_summary) { 179 const ResourceSummary& resource_summary) {
164 URLRequestSummary summary(resource_summary.request); 180 URLRequestSummary summary(resource_summary.request);
165 content::WebContents* web_contents = 181 content::WebContents* web_contents =
166 browser()->tab_strip_model()->GetActiveWebContents(); 182 browser()->tab_strip_model()->GetActiveWebContents();
167 int process_id = web_contents->GetRenderProcessHost()->GetID(); 183 int process_id = web_contents->GetRenderProcessHost()->GetID();
168 int frame_id = web_contents->GetMainFrame()->GetRoutingID(); 184 int frame_id = web_contents->GetMainFrame()->GetRoutingID();
185 GURL main_frame_url = embedded_test_server()->GetURL(main_frame_path);
169 summary.navigation_id = 186 summary.navigation_id =
170 CreateNavigationID(process_id, frame_id, main_frame_url.spec()); 187 CreateNavigationID(process_id, frame_id, main_frame_url.spec());
171 return summary; 188 return summary;
172 } 189 }
173 190
174 std::unique_ptr<net::test_server::HttpResponse> HandleRequest( 191 std::string GetRedirectEndpoint(const std::string& path) {
192 const std::string* current = &path;
193 for (auto it = redirects_.find(*current); it != redirects_.end();
pasko 2016/11/21 18:42:39 this for-loop is multi-line and unusual enough so
alexilin 2016/11/22 11:04:29 Done.
194 it = redirects_.find(*current)) {
195 current = &(it->second);
196 }
197 return *current;
198 }
199
200 std::unique_ptr<net::test_server::HttpResponse> HandleResourceRequest(
175 const net::test_server::HttpRequest& request) { 201 const net::test_server::HttpRequest& request) {
176 auto resource_it = resources_.find(request.relative_url); 202 auto resource_it = resources_.find(request.relative_url);
177 if (resource_it == resources_.end()) 203 if (resource_it == resources_.end())
178 return nullptr; 204 return nullptr;
179 205
180 const ResourceSummary& summary = resource_it->second; 206 const ResourceSummary& summary = resource_it->second;
181 auto http_response = 207 auto http_response =
182 base::MakeUnique<net::test_server::BasicHttpResponse>(); 208 base::MakeUnique<net::test_server::BasicHttpResponse>();
183 http_response->set_code(net::HTTP_OK); 209 http_response->set_code(net::HTTP_OK);
184 if (!summary.request.mime_type.empty()) 210 if (!summary.request.mime_type.empty())
185 http_response->set_content_type(summary.request.mime_type); 211 http_response->set_content_type(summary.request.mime_type);
186 http_response->set_content(summary.content); 212 if (!summary.content.empty())
213 http_response->set_content(summary.content);
187 if (summary.is_no_store) 214 if (summary.is_no_store)
188 http_response->AddCustomHeader("Cache-Control", "no-store"); 215 http_response->AddCustomHeader("Cache-Control", "no-store");
189 if (summary.request.has_validators) { 216 if (summary.request.has_validators) {
190 http_response->AddCustomHeader( 217 http_response->AddCustomHeader(
191 "ETag", base::StringPrintf("'%zu%s'", summary.version, 218 "ETag", base::StringPrintf("'%zu%s'", summary.version,
192 request.relative_url.c_str())); 219 request.relative_url.c_str()));
193 } 220 }
194 if (summary.request.always_revalidate) 221 if (summary.request.always_revalidate)
195 http_response->AddCustomHeader("Cache-Control", "no-cache"); 222 http_response->AddCustomHeader("Cache-Control", "no-cache");
196 else 223 else
197 http_response->AddCustomHeader("Cache-Control", "max-age=2147483648"); 224 http_response->AddCustomHeader("Cache-Control", "max-age=2147483648");
198 return std::move(http_response); 225 return std::move(http_response);
199 } 226 }
200 227
201 size_t UpdateAndGetVisitCount(const std::string& main_frame_relative) { 228 std::unique_ptr<net::test_server::HttpResponse> HandleRedirectRequest(
202 return ++visit_count_[main_frame_relative]; 229 const net::test_server::HttpRequest& request) {
230 auto redirect_it = redirects_.find(request.relative_url);
231 if (redirect_it == redirects_.end())
232 return nullptr;
233
234 auto http_response =
235 base::MakeUnique<net::test_server::BasicHttpResponse>();
236 http_response->set_code(net::HTTP_FOUND);
Benoit L 2016/11/21 16:24:25 Can you also test with a 301?
alexilin 2016/11/21 18:47:35 Done.
237 http_response->AddCustomHeader(
238 "Location", embedded_test_server()->GetURL(redirect_it->second).spec());
239 return std::move(http_response);
240 }
241
242 size_t UpdateAndGetVisitCount(const std::string& main_frame_path) {
243 return ++visit_count_[main_frame_path];
203 } 244 }
204 245
205 ResourcePrefetchPredictor* predictor_; 246 ResourcePrefetchPredictor* predictor_;
206 std::map<std::string, ResourceSummary> resources_; 247 std::map<std::string, ResourceSummary> resources_;
248 std::map<std::string, std::string> redirects_;
207 std::map<std::string, size_t> visit_count_; 249 std::map<std::string, size_t> visit_count_;
208 }; 250 };
209 251
210 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, LearningSimple) { 252 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, LearningSimple) {
211 // These resources have default priorities that correspond to 253 // These resources have default priorities that correspond to
212 // blink::typeToPriority function. 254 // blink::typeToPriority function.
213 AddResource(kImageUrl, content::RESOURCE_TYPE_IMAGE, net::LOWEST); 255 AddResource(kImagePath, content::RESOURCE_TYPE_IMAGE, net::LOWEST);
214 AddResource(kStyleUrl, content::RESOURCE_TYPE_STYLESHEET, net::HIGHEST); 256 AddResource(kStylePath, content::RESOURCE_TYPE_STYLESHEET, net::HIGHEST);
215 AddResource(kScriptUrl, content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); 257 AddResource(kScriptPath, content::RESOURCE_TYPE_SCRIPT, net::MEDIUM);
216 AddResource(kFontUrl, content::RESOURCE_TYPE_FONT_RESOURCE, net::HIGHEST); 258 AddResource(kFontPath, content::RESOURCE_TYPE_FONT_RESOURCE, net::HIGHEST);
217 NavigateToURLAndCheckSubresources(kHtmlSubresourcesUrl); 259 NavigateToURLAndCheckSubresources(kHtmlSubresourcesPath);
260 }
261
262 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest,
263 LearningAfterRedirects) {
264 AddRedirectChain({kRedirectPath, kRedirectPath2, kHtmlSubresourcesPath});
265 AddResource(kImagePath, content::RESOURCE_TYPE_IMAGE, net::LOWEST);
266 AddResource(kStylePath, content::RESOURCE_TYPE_STYLESHEET, net::HIGHEST);
267 AddResource(kScriptPath, content::RESOURCE_TYPE_SCRIPT, net::MEDIUM);
268 AddResource(kFontPath, content::RESOURCE_TYPE_FONT_RESOURCE, net::HIGHEST);
269 NavigateToURLAndCheckSubresources(kRedirectPath);
218 } 270 }
219 271
220 } // namespace predictors 272 } // namespace predictors
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698