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

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

Issue 2482833002: Reland of predictors: Basic browsertest checks predictor learning. (Closed)
Patch Set: Wait for ResourcePrefetchPredictor initialization. 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 namespace predictors {
23
24 static const char kImageUrl[] = "/predictors/image.png";
25 static const char kStyleUrl[] = "/predictors/style.css";
26 static const char kScriptUrl[] = "/predictors/script.js";
27 static const char kFontUrl[] = "/predictors/font.ttf";
28 static const char kHtmlSubresourcesUrl[] = "/predictors/html_subresources.html";
29
30 struct ResourceSummary {
31 ResourceSummary() : is_no_store(false), version(0) {}
32
33 ResourcePrefetchPredictor::URLRequestSummary request;
34 std::string content;
35 bool is_no_store;
36 size_t version;
37 };
38
39 class InitializationObserver : public TestObserver {
40 public:
41 explicit InitializationObserver(ResourcePrefetchPredictor* predictor)
42 : TestObserver(predictor) {}
43
44 void OnPredictorInitialized() override { run_loop_.Quit(); }
45
46 void Wait() { run_loop_.Run(); }
47
48 private:
49 base::RunLoop run_loop_;
50
51 DISALLOW_COPY_AND_ASSIGN(InitializationObserver);
52 };
53
54 // Helper class to track and allow waiting for ResourcePrefetchPredictor events.
55 // These events are also used to verify that ResourcePrefetchPredictor works as
56 // expected.
57 class ResourcePrefetchPredictorTestObserver : public TestObserver {
58 public:
59 using PageRequestSummary = ResourcePrefetchPredictor::PageRequestSummary;
60
61 explicit ResourcePrefetchPredictorTestObserver(
62 ResourcePrefetchPredictor* predictor,
63 const size_t expected_url_visit_count,
64 const PageRequestSummary& expected_summary)
65 : TestObserver(predictor),
66 url_visit_count_(expected_url_visit_count),
67 summary_(expected_summary) {}
68
69 // TestObserver:
70 void OnNavigationLearned(size_t url_visit_count,
71 const PageRequestSummary& summary) override {
72 EXPECT_EQ(url_visit_count, url_visit_count_);
73 EXPECT_EQ(summary.main_frame_url, summary_.main_frame_url);
74 EXPECT_EQ(summary.initial_url, summary_.initial_url);
75 EXPECT_THAT(
76 summary.subresource_requests,
77 testing::UnorderedElementsAreArray(summary_.subresource_requests));
78 run_loop_.Quit();
79 }
80
81 void Wait() { run_loop_.Run(); }
82
83 private:
84 base::RunLoop run_loop_;
85 size_t url_visit_count_;
86 PageRequestSummary summary_;
87
88 DISALLOW_COPY_AND_ASSIGN(ResourcePrefetchPredictorTestObserver);
89 };
90
91 class ResourcePrefetchPredictorBrowserTest : public InProcessBrowserTest {
92 public:
93 using URLRequestSummary = ResourcePrefetchPredictor::URLRequestSummary;
94
95 void SetUpCommandLine(base::CommandLine* command_line) override {
96 command_line->AppendSwitchASCII(
97 switches::kSpeculativeResourcePrefetching,
98 switches::kSpeculativeResourcePrefetchingEnabled);
99 }
100
101 void SetUpOnMainThread() override {
102 embedded_test_server()->RegisterRequestHandler(
103 base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleRequest,
104 base::Unretained(this)));
105 ASSERT_TRUE(embedded_test_server()->Start());
106 predictor_ =
107 ResourcePrefetchPredictorFactory::GetForProfile(browser()->profile());
108 ASSERT_TRUE(predictor_);
109 }
110
111 void NavigateToURLAndCheckSubresources(
112 const std::string& main_frame_relative) {
113 EnsurePredictorInitialized();
Benoit L 2016/11/07 17:17:06 This would be better in SetUp(), since we're going
alexilin 2016/11/07 17:19:51 Done.
114 GURL main_frame_absolute =
115 embedded_test_server()->GetURL(main_frame_relative);
116 std::vector<URLRequestSummary> url_request_summaries;
117 for (const auto& kv : resources_) {
118 if (kv.second.is_no_store)
119 continue;
120 url_request_summaries.push_back(
121 GetURLRequestSummaryForResource(main_frame_absolute, kv.second));
122 }
123 ResourcePrefetchPredictorTestObserver observer(
124 predictor_, UpdateAndGetVisitCount(main_frame_relative),
125 CreatePageRequestSummary(main_frame_absolute.spec(),
126 main_frame_absolute.spec(),
127 url_request_summaries));
128 ui_test_utils::NavigateToURL(browser(), main_frame_absolute);
129 observer.Wait();
130 }
131
132 ResourceSummary* AddResource(const std::string& relative_url,
133 content::ResourceType resource_type,
134 net::RequestPriority priority) {
135 ResourceSummary resource;
136 resource.request.resource_url =
137 embedded_test_server()->GetURL(relative_url);
138 resource.request.resource_type = resource_type;
139 resource.request.priority = priority;
140 auto result = resources_.insert(std::make_pair(relative_url, resource));
141 return &(result.first->second);
142 }
143
144 private:
145 // ResourcePrefetchPredictor needs to be initialized before the navigation
146 // happens otherwise this navigation will be ignored by predictor.
147 void EnsurePredictorInitialized() {
148 if (predictor_->initialization_state_ ==
149 ResourcePrefetchPredictor::INITIALIZED) {
150 return;
151 }
152
153 InitializationObserver observer(predictor_);
154 if (predictor_->initialization_state_ ==
155 ResourcePrefetchPredictor::NOT_INITIALIZED) {
156 predictor_->StartInitialization();
157 }
158 observer.Wait();
159 }
160
161 URLRequestSummary GetURLRequestSummaryForResource(
162 const GURL& main_frame_url,
163 const ResourceSummary& resource_summary) {
164 URLRequestSummary summary(resource_summary.request);
165 content::WebContents* web_contents =
166 browser()->tab_strip_model()->GetActiveWebContents();
167 int process_id = web_contents->GetRenderProcessHost()->GetID();
168 int frame_id = web_contents->GetMainFrame()->GetRoutingID();
169 summary.navigation_id =
170 CreateNavigationID(process_id, frame_id, main_frame_url.spec());
171 return summary;
172 }
173
174 std::unique_ptr<net::test_server::HttpResponse> HandleRequest(
175 const net::test_server::HttpRequest& request) {
176 auto resource_it = resources_.find(request.relative_url);
177 if (resource_it == resources_.end())
178 return nullptr;
179
180 const ResourceSummary& summary = resource_it->second;
181 auto http_response =
182 base::MakeUnique<net::test_server::BasicHttpResponse>();
183 http_response->set_code(net::HTTP_OK);
184 if (!summary.request.mime_type.empty())
185 http_response->set_content_type(summary.request.mime_type);
186 http_response->set_content(summary.content);
187 if (summary.is_no_store)
188 http_response->AddCustomHeader("Cache-Control", "no-store");
189 if (summary.request.has_validators) {
190 http_response->AddCustomHeader(
191 "ETag", base::StringPrintf("'%zu%s'", summary.version,
192 request.relative_url.c_str()));
193 }
194 if (summary.request.always_revalidate)
195 http_response->AddCustomHeader("Cache-Control", "no-cache");
196 else
197 http_response->AddCustomHeader("Cache-Control", "max-age=2147483648");
198 return std::move(http_response);
199 }
200
201 size_t UpdateAndGetVisitCount(const std::string& main_frame_relative) {
202 return ++visit_count_[main_frame_relative];
203 }
204
205 ResourcePrefetchPredictor* predictor_;
206 std::map<std::string, ResourceSummary> resources_;
207 std::map<std::string, size_t> visit_count_;
208 };
209
210 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, LearningSimple) {
211 // These resources have default priorities that correspond to
212 // blink::typeToPriority function.
213 AddResource(kImageUrl, content::RESOURCE_TYPE_IMAGE, net::LOWEST);
214 AddResource(kStyleUrl, content::RESOURCE_TYPE_STYLESHEET, net::HIGHEST);
215 AddResource(kScriptUrl, content::RESOURCE_TYPE_SCRIPT, net::MEDIUM);
216 AddResource(kFontUrl, content::RESOURCE_TYPE_FONT_RESOURCE, net::HIGHEST);
217 NavigateToURLAndCheckSubresources(kHtmlSubresourcesUrl);
218 }
219
220 } // namespace predictors
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698