Chromium Code Reviews| OLD | NEW |
|---|---|
| (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 static const char kImageUrl[] = "/predictors/image.png"; | |
| 27 static const char kStyleUrl[] = "/predictors/style.css"; | |
| 28 static const char kScriptUrl[] = "/predictors/script.js"; | |
| 29 static const char kFontUrl[] = "/predictors/font.ttf"; | |
| 30 static const char kHtmlSubresourcesUrl[] = "/predictors/html_subresources.html"; | |
| 31 | |
| 32 using PageRequestSummary = ResourcePrefetchPredictor::PageRequestSummary; | |
| 33 using URLRequestSummary = ResourcePrefetchPredictor::URLRequestSummary; | |
| 34 using net::test_server::HttpRequest; | |
| 35 using net::test_server::HttpResponse; | |
| 36 using net::test_server::BasicHttpResponse; | |
|
pasko
2016/11/03 16:23:13
the walls of 'using' statements are not adding too
alexilin
2016/11/03 18:42:12
Done.
| |
| 37 | |
| 38 struct ResourceSummary { | |
| 39 ResourceSummary() : is_no_store(false), version(0) {} | |
| 40 | |
| 41 URLRequestSummary request; | |
| 42 std::string content; | |
| 43 bool is_no_store; | |
| 44 size_t version; | |
| 45 }; | |
| 46 | |
| 47 // Helper class to track and allow waiting for ResourcePrefetchPredictor events. | |
|
pasko
2016/11/02 19:37:02
not only waiting, but also verifying that a PageRe
alexilin
2016/11/03 13:49:08
That's why I don't like comments: they become stal
| |
| 48 class ResourcePrefetchPredictorTestObserver : public TestObserver { | |
| 49 public: | |
| 50 explicit ResourcePrefetchPredictorTestObserver( | |
| 51 ResourcePrefetchPredictor* predictor, | |
| 52 const size_t expected_url_visit_count, | |
| 53 const PageRequestSummary& expected_summary) | |
| 54 : TestObserver(predictor), | |
| 55 message_loop_runner_(new content::MessageLoopRunner()), | |
|
pasko
2016/11/02 19:37:01
using content::MessageLoopRunner without calling Q
alexilin
2016/11/03 13:49:09
MessageLoopRunner does additional work internally
pasko
2016/11/03 16:23:12
Frankly, this code keeps changing and I lost track
alexilin
2016/11/03 18:42:12
Acknowledged.
| |
| 56 url_visit_count_(expected_url_visit_count), | |
| 57 summary_(expected_summary) {} | |
| 58 | |
| 59 ~ResourcePrefetchPredictorTestObserver() override {} | |
|
pasko
2016/11/02 19:37:02
is this necessary? does not add to readability
alexilin
2016/11/03 13:49:09
Done.
| |
| 60 | |
| 61 // ResourcePrefetchPredictor::Observer | |
|
pasko
2016/11/02 19:37:02
// TestObserver implementation.
alexilin
2016/11/03 13:49:08
Done.
Btw, I've seen alike comments with the word
pasko
2016/11/03 16:23:13
me too, also 'blah methods.'. What we do in cases
alexilin
2016/11/03 18:42:12
Actually, your suggestion wasn't completely mislea
| |
| 62 void OnNavigationLearned(size_t url_visit_count, | |
| 63 const PageRequestSummary& summary) override { | |
| 64 EXPECT_EQ(url_visit_count, url_visit_count_); | |
| 65 EXPECT_EQ(summary.main_frame_url, summary_.main_frame_url); | |
| 66 EXPECT_EQ(summary.initial_url, summary_.initial_url); | |
| 67 EXPECT_THAT(summary.subresource_requests, | |
| 68 UnorderedElementsAreArray(summary_.subresource_requests)); | |
| 69 message_loop_runner_->Quit(); | |
| 70 } | |
| 71 | |
| 72 void Wait() { message_loop_runner_->Run(); } | |
| 73 | |
| 74 private: | |
| 75 scoped_refptr<content::MessageLoopRunner> message_loop_runner_; | |
| 76 size_t url_visit_count_; | |
| 77 PageRequestSummary summary_; | |
| 78 | |
| 79 DISALLOW_COPY_AND_ASSIGN(ResourcePrefetchPredictorTestObserver); | |
| 80 }; | |
| 81 | |
| 82 class ResourcePrefetchPredictorBrowserTest : public InProcessBrowserTest { | |
| 83 public: | |
| 84 void SetUpCommandLine(base::CommandLine* command_line) override { | |
| 85 command_line->AppendSwitchASCII( | |
| 86 switches::kSpeculativeResourcePrefetching, | |
| 87 switches::kSpeculativeResourcePrefetchingEnabled); | |
| 88 } | |
| 89 | |
| 90 void SetUpOnMainThread() override { | |
| 91 embedded_test_server()->RegisterRequestHandler( | |
| 92 base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleRequest, | |
| 93 base::Unretained(this))); | |
| 94 ASSERT_TRUE(embedded_test_server()->Start()); | |
| 95 predictor_ = | |
| 96 ResourcePrefetchPredictorFactory::GetForProfile(browser()->profile()); | |
| 97 ASSERT_TRUE(predictor_); | |
| 98 } | |
| 99 | |
| 100 void NavigateToURLAndCheckSubresources( | |
| 101 const std::string& main_frame_relative) { | |
| 102 GURL main_frame_absolute = | |
| 103 embedded_test_server()->GetURL(main_frame_relative); | |
| 104 std::vector<URLRequestSummary> url_request_summaries; | |
| 105 for (const auto& kv : resources_) { | |
| 106 if (kv.second.is_no_store) | |
| 107 continue; | |
| 108 url_request_summaries.push_back( | |
| 109 GetURLRequestSummaryForResource(main_frame_absolute, kv.second)); | |
| 110 } | |
| 111 ResourcePrefetchPredictorTestObserver observer( | |
| 112 predictor_, UpdateAndGetVisitCount(main_frame_relative), | |
| 113 CreatePageRequestSummary(main_frame_absolute.spec(), | |
| 114 main_frame_absolute.spec(), | |
| 115 url_request_summaries)); | |
| 116 ui_test_utils::NavigateToURL(browser(), main_frame_absolute); | |
| 117 observer.Wait(); | |
| 118 } | |
| 119 | |
| 120 void AddResource(const std::string& relative_url, | |
| 121 content::ResourceType resource_type, | |
| 122 net::RequestPriority priority, | |
| 123 const std::string& mime_type, | |
| 124 bool has_validators = true, | |
|
pasko
2016/11/02 19:37:01
the style guide "somewhat discourages" function ov
alexilin
2016/11/03 13:49:09
Many of the tests for ResourcePrefetchPredictors c
pasko
2016/11/03 16:23:12
Yes. I did not have a chance to object at the time
alexilin
2016/11/03 18:42:12
Acknowledged.
| |
| 125 bool always_revalidate = false, | |
| 126 const std::string& content = std::string(), | |
| 127 bool is_no_store = false) { | |
| 128 ResourceSummary resource; | |
| 129 GURL resource_url = embedded_test_server()->GetURL(relative_url); | |
| 130 resource.request = CreateURLRequestSummary( | |
| 131 -1, -1, std::string(), resource_url.spec(), resource_type, priority, | |
| 132 mime_type, false, std::string(), has_validators, always_revalidate); | |
| 133 resource.content = content; | |
| 134 resource.is_no_store = is_no_store; | |
| 135 resources_[relative_url] = resource; | |
| 136 } | |
| 137 | |
| 138 private: | |
| 139 URLRequestSummary GetURLRequestSummaryForResource( | |
| 140 const GURL& main_frame_url, | |
| 141 const ResourceSummary& resource_summary) { | |
| 142 URLRequestSummary summary(resource_summary.request); | |
| 143 content::WebContents* web_contents = | |
| 144 browser()->tab_strip_model()->GetActiveWebContents(); | |
| 145 int process_id = web_contents->GetRenderProcessHost()->GetID(); | |
| 146 int frame_id = web_contents->GetMainFrame()->GetRoutingID(); | |
| 147 summary.navigation_id = | |
| 148 CreateNavigationID(process_id, frame_id, main_frame_url.spec()); | |
| 149 return summary; | |
| 150 } | |
| 151 | |
| 152 std::unique_ptr<HttpResponse> HandleRequest(const HttpRequest& request) { | |
|
pasko
2016/11/02 19:37:02
A few concerns with manually handling requests in
alexilin
2016/11/03 13:49:08
I don't see anything special or wrong in manual ha
pasko
2016/11/03 16:23:12
What do you mean by 'nice' in this case?
alexilin
2016/11/03 18:42:12
Pardon, I had in mind "expected_body" parameter bu
pasko
2016/11/04 15:05:34
What makes you say that? How about:
chrome/test/d
alexilin
2016/11/04 16:07:52
Oh, I didn't know that HTTP response code is a par
| |
| 153 auto resource_it = resources_.find(request.relative_url); | |
| 154 if (resource_it == resources_.end()) | |
| 155 return nullptr; | |
| 156 | |
| 157 const ResourceSummary& summary = resource_it->second; | |
| 158 std::unique_ptr<BasicHttpResponse> http_response = | |
|
pasko
2016/11/03 16:23:12
nit: since the type should be obvious: auto http_r
alexilin
2016/11/03 18:42:12
Done.
| |
| 159 base::MakeUnique<BasicHttpResponse>(); | |
| 160 http_response->set_code(net::HTTP_OK); | |
| 161 http_response->set_content_type(summary.request.mime_type); | |
| 162 http_response->set_content(summary.content); | |
| 163 if (summary.is_no_store) | |
| 164 http_response->AddCustomHeader("Cache-Control", "no-store"); | |
| 165 if (summary.request.has_validators) { | |
| 166 http_response->AddCustomHeader( | |
| 167 "ETag", base::StringPrintf("'%zu%s'", summary.version, | |
| 168 request.relative_url.c_str())); | |
| 169 } | |
| 170 if (summary.request.always_revalidate) | |
| 171 http_response->AddCustomHeader("Cache-Control", "no-cache"); | |
| 172 else | |
| 173 http_response->AddCustomHeader("Cache-Control", "max-age=2147483648"); | |
| 174 return std::move(http_response); | |
| 175 } | |
| 176 | |
| 177 size_t UpdateAndGetVisitCount(const std::string& main_frame_relative) { | |
| 178 return ++visit_count_[main_frame_relative]; | |
| 179 } | |
| 180 | |
| 181 ResourcePrefetchPredictor* predictor_; | |
| 182 std::map<std::string, ResourceSummary> resources_; | |
| 183 std::map<std::string, size_t> visit_count_; | |
|
pasko
2016/11/02 19:37:01
This value gets updated, but the test only observe
alexilin
2016/11/03 13:49:09
In future tests we definitely will navigate to the
pasko
2016/11/03 16:23:13
I see, makes sense, thanks.
alexilin
2016/11/03 18:42:12
Acknowledged.
| |
| 184 }; | |
| 185 | |
| 186 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, ) { | |
|
pasko
2016/11/02 19:37:01
name of the test missing, suggest: ResourcePrefetc
alexilin
2016/11/03 13:49:09
Wow, how does it even work? Yeah, I see GTest uses
| |
| 187 // These resources have default priorities that correspond to | |
| 188 // blink::typeToPriority function. | |
| 189 AddResource(kImageUrl, content::RESOURCE_TYPE_IMAGE, net::LOWEST, | |
| 190 "image/png"); | |
|
pasko
2016/11/04 15:05:34
let's try to remove setting the mime types returne
alexilin
2016/11/04 16:07:52
Done.
| |
| 191 AddResource(kStyleUrl, content::RESOURCE_TYPE_STYLESHEET, net::HIGHEST, | |
| 192 "text/css"); | |
| 193 AddResource(kScriptUrl, content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, | |
| 194 "application/javascript"); | |
| 195 AddResource(kFontUrl, content::RESOURCE_TYPE_FONT_RESOURCE, net::HIGHEST, | |
| 196 "application/x-font-truetype"); | |
| 197 NavigateToURLAndCheckSubresources(kHtmlSubresourcesUrl); | |
| 198 } | |
| 199 | |
| 200 } // namespace predictors | |
| OLD | NEW |