| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "chrome/browser/predictors/resource_prefetch_predictor.h" | 5 #include "chrome/browser/predictors/resource_prefetch_predictor.h" |
| 6 | 6 |
| 7 #include <iostream> | 7 #include <iostream> |
| 8 #include <memory> | 8 #include <memory> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 #include "net/url_request/url_request_context.h" | 28 #include "net/url_request/url_request_context.h" |
| 29 #include "net/url_request/url_request_job.h" | 29 #include "net/url_request/url_request_job.h" |
| 30 #include "testing/gmock/include/gmock/gmock.h" | 30 #include "testing/gmock/include/gmock/gmock.h" |
| 31 #include "testing/gtest/include/gtest/gtest.h" | 31 #include "testing/gtest/include/gtest/gtest.h" |
| 32 | 32 |
| 33 using testing::StrictMock; | 33 using testing::StrictMock; |
| 34 using testing::UnorderedElementsAre; | 34 using testing::UnorderedElementsAre; |
| 35 | 35 |
| 36 namespace predictors { | 36 namespace predictors { |
| 37 | 37 |
| 38 using URLRequestSummary = ResourcePrefetchPredictor::URLRequestSummary; | |
| 39 using PageRequestSummary = ResourcePrefetchPredictor::PageRequestSummary; | |
| 40 using PrefetchDataMap = std::map<std::string, PrefetchData>; | 38 using PrefetchDataMap = std::map<std::string, PrefetchData>; |
| 41 using RedirectDataMap = std::map<std::string, RedirectData>; | 39 using RedirectDataMap = std::map<std::string, RedirectData>; |
| 42 using OriginDataMap = std::map<std::string, OriginData>; | 40 using OriginDataMap = std::map<std::string, OriginData>; |
| 43 using ManifestDataMap = std::map<std::string, precache::PrecacheManifest>; | 41 using ManifestDataMap = std::map<std::string, precache::PrecacheManifest>; |
| 44 | 42 |
| 45 template <typename T> | |
| 46 class FakeGlowplugKeyValueTable : public GlowplugKeyValueTable<T> { | |
| 47 public: | |
| 48 FakeGlowplugKeyValueTable() : GlowplugKeyValueTable<T>("") {} | |
| 49 void GetAllData(std::map<std::string, T>* data_map, | |
| 50 sql::Connection* db) const override { | |
| 51 *data_map = data_; | |
| 52 } | |
| 53 void UpdateData(const std::string& key, | |
| 54 const T& data, | |
| 55 sql::Connection* db) override { | |
| 56 data_[key] = data; | |
| 57 } | |
| 58 void DeleteData(const std::vector<std::string>& keys, | |
| 59 sql::Connection* db) override { | |
| 60 for (const auto& key : keys) | |
| 61 data_.erase(key); | |
| 62 } | |
| 63 void DeleteAllData(sql::Connection* db) override { data_.clear(); } | |
| 64 | |
| 65 std::map<std::string, T> data_; | |
| 66 }; | |
| 67 | |
| 68 class MockResourcePrefetchPredictorTables | |
| 69 : public ResourcePrefetchPredictorTables { | |
| 70 public: | |
| 71 MockResourcePrefetchPredictorTables() = default; | |
| 72 | |
| 73 void ScheduleDBTask(const tracked_objects::Location& from_here, | |
| 74 DBTask task) override { | |
| 75 ExecuteDBTaskOnDBThread(std::move(task)); | |
| 76 } | |
| 77 | |
| 78 void ExecuteDBTaskOnDBThread(DBTask task) override { | |
| 79 std::move(task).Run(nullptr); | |
| 80 } | |
| 81 | |
| 82 GlowplugKeyValueTable<PrefetchData>* url_resource_table() override { | |
| 83 return &url_resource_table_; | |
| 84 } | |
| 85 | |
| 86 GlowplugKeyValueTable<RedirectData>* url_redirect_table() override { | |
| 87 return &url_redirect_table_; | |
| 88 } | |
| 89 | |
| 90 GlowplugKeyValueTable<PrefetchData>* host_resource_table() override { | |
| 91 return &host_resource_table_; | |
| 92 } | |
| 93 | |
| 94 GlowplugKeyValueTable<RedirectData>* host_redirect_table() override { | |
| 95 return &host_redirect_table_; | |
| 96 } | |
| 97 | |
| 98 GlowplugKeyValueTable<precache::PrecacheManifest>* manifest_table() override { | |
| 99 return &manifest_table_; | |
| 100 } | |
| 101 | |
| 102 GlowplugKeyValueTable<OriginData>* origin_table() override { | |
| 103 return &origin_table_; | |
| 104 } | |
| 105 | |
| 106 FakeGlowplugKeyValueTable<PrefetchData> url_resource_table_; | |
| 107 FakeGlowplugKeyValueTable<RedirectData> url_redirect_table_; | |
| 108 FakeGlowplugKeyValueTable<PrefetchData> host_resource_table_; | |
| 109 FakeGlowplugKeyValueTable<RedirectData> host_redirect_table_; | |
| 110 FakeGlowplugKeyValueTable<precache::PrecacheManifest> manifest_table_; | |
| 111 FakeGlowplugKeyValueTable<OriginData> origin_table_; | |
| 112 | |
| 113 protected: | |
| 114 ~MockResourcePrefetchPredictorTables() override = default; | |
| 115 }; | |
| 116 | |
| 117 class MockResourcePrefetchPredictorObserver : public TestObserver { | |
| 118 public: | |
| 119 explicit MockResourcePrefetchPredictorObserver( | |
| 120 ResourcePrefetchPredictor* predictor) | |
| 121 : TestObserver(predictor) {} | |
| 122 | |
| 123 MOCK_METHOD2( | |
| 124 OnNavigationLearned, | |
| 125 void(size_t url_visit_count, | |
| 126 const ResourcePrefetchPredictor::PageRequestSummary& summary)); | |
| 127 }; | |
| 128 | |
| 129 class ResourcePrefetchPredictorTest : public testing::Test { | 43 class ResourcePrefetchPredictorTest : public testing::Test { |
| 130 public: | 44 public: |
| 131 ResourcePrefetchPredictorTest(); | 45 ResourcePrefetchPredictorTest(); |
| 132 ~ResourcePrefetchPredictorTest() override; | 46 ~ResourcePrefetchPredictorTest() override; |
| 133 void SetUp() override; | 47 void SetUp() override; |
| 134 void TearDown() override; | 48 void TearDown() override; |
| 135 | 49 |
| 136 protected: | 50 protected: |
| 137 void AddUrlToHistory(const std::string& url, int visit_count) { | |
| 138 HistoryServiceFactory::GetForProfile(profile_.get(), | |
| 139 ServiceAccessType::EXPLICIT_ACCESS)-> | |
| 140 AddPageWithDetails( | |
| 141 GURL(url), | |
| 142 base::string16(), | |
| 143 visit_count, | |
| 144 0, | |
| 145 base::Time::Now(), | |
| 146 false, | |
| 147 history::SOURCE_BROWSED); | |
| 148 profile_->BlockUntilHistoryProcessesPendingRequests(); | |
| 149 } | |
| 150 | |
| 151 URLRequestSummary CreateRedirectRequestSummary( | |
| 152 SessionID::id_type session_id, | |
| 153 const std::string& main_frame_url, | |
| 154 const std::string& redirect_url) { | |
| 155 URLRequestSummary summary = | |
| 156 CreateURLRequestSummary(session_id, main_frame_url); | |
| 157 summary.redirect_url = GURL(redirect_url); | |
| 158 return summary; | |
| 159 } | |
| 160 | |
| 161 void InitializePredictor() { | 51 void InitializePredictor() { |
| 162 loading_predictor_->StartInitialization(); | 52 loading_predictor_->StartInitialization(); |
| 163 base::RunLoop loop; | 53 base::RunLoop loop; |
| 164 loop.RunUntilIdle(); // Runs the DB lookup. | 54 loop.RunUntilIdle(); // Runs the DB lookup. |
| 165 profile_->BlockUntilHistoryProcessesPendingRequests(); | 55 profile_->BlockUntilHistoryProcessesPendingRequests(); |
| 166 } | 56 } |
| 167 | 57 |
| 168 void ResetPredictor(bool small_db = true) { | 58 void ResetPredictor(bool small_db = true) { |
| 169 LoadingPredictorConfig config; | 59 LoadingPredictorConfig config; |
| 170 PopulateTestConfig(&config, small_db); | 60 PopulateTestConfig(&config, small_db); |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 425 InitializePredictor(); | 315 InitializePredictor(); |
| 426 | 316 |
| 427 // Test that the internal variables correctly initialized. | 317 // Test that the internal variables correctly initialized. |
| 428 EXPECT_EQ(predictor_->initialization_state_, | 318 EXPECT_EQ(predictor_->initialization_state_, |
| 429 ResourcePrefetchPredictor::INITIALIZED); | 319 ResourcePrefetchPredictor::INITIALIZED); |
| 430 EXPECT_TRUE(predictor_->inflight_navigations_.empty()); | 320 EXPECT_TRUE(predictor_->inflight_navigations_.empty()); |
| 431 | 321 |
| 432 // Integrity of the cache and the backend storage is checked on TearDown. | 322 // Integrity of the cache and the backend storage is checked on TearDown. |
| 433 } | 323 } |
| 434 | 324 |
| 325 /* |
| 435 // Single navigation but history count is low, so should not record url data. | 326 // Single navigation but history count is low, so should not record url data. |
| 436 TEST_F(ResourcePrefetchPredictorTest, NavigationLowHistoryCount) { | 327 TEST_F(ResourcePrefetchPredictorTest, NavigationLowHistoryCount) { |
| 437 const int kVisitCount = 1; | 328 const int kVisitCount = 1; |
| 438 AddUrlToHistory("https://www.google.com", kVisitCount); | 329 AddUrlToHistory("https://www.google.com", kVisitCount); |
| 439 | 330 |
| 440 URLRequestSummary main_frame = | 331 URLRequestSummary main_frame = |
| 441 CreateURLRequestSummary(1, "http://www.google.com"); | 332 CreateURLRequestSummary(1, "http://www.google.com"); |
| 442 predictor_->RecordURLRequest(main_frame); | 333 predictor_->RecordURLRequest(main_frame); |
| 443 EXPECT_EQ(1U, predictor_->inflight_navigations_.size()); | 334 EXPECT_EQ(1U, predictor_->inflight_navigations_.size()); |
| 444 | 335 |
| (...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 922 RedirectData host_redirect_data = CreateRedirectData("fb.com"); | 813 RedirectData host_redirect_data = CreateRedirectData("fb.com"); |
| 923 InitializeRedirectStat(host_redirect_data.add_redirect_endpoints(), | 814 InitializeRedirectStat(host_redirect_data.add_redirect_endpoints(), |
| 924 "facebook.com", 1, 0, 0); | 815 "facebook.com", 1, 0, 0); |
| 925 RedirectDataMap expected_host_redirect_data = test_host_redirect_data_; | 816 RedirectDataMap expected_host_redirect_data = test_host_redirect_data_; |
| 926 expected_host_redirect_data.erase("bbc.com"); | 817 expected_host_redirect_data.erase("bbc.com"); |
| 927 expected_host_redirect_data[host_redirect_data.primary_key()] = | 818 expected_host_redirect_data[host_redirect_data.primary_key()] = |
| 928 host_redirect_data; | 819 host_redirect_data; |
| 929 EXPECT_EQ(mock_tables_->host_redirect_table_.data_, | 820 EXPECT_EQ(mock_tables_->host_redirect_table_.data_, |
| 930 expected_host_redirect_data); | 821 expected_host_redirect_data); |
| 931 } | 822 } |
| 823 */ |
| 932 | 824 |
| 933 TEST_F(ResourcePrefetchPredictorTest, ManifestHostNotInDB) { | 825 TEST_F(ResourcePrefetchPredictorTest, ManifestHostNotInDB) { |
| 934 precache::PrecacheManifest manifest = | 826 precache::PrecacheManifest manifest = |
| 935 CreateManifestData(base::Time::Now().ToDoubleT()); | 827 CreateManifestData(base::Time::Now().ToDoubleT()); |
| 936 InitializePrecacheResource(manifest.add_resource(), | 828 InitializePrecacheResource(manifest.add_resource(), |
| 937 "http://cdn.google.com/script.js", 0.9, | 829 "http://cdn.google.com/script.js", 0.9, |
| 938 precache::PrecacheResource::RESOURCE_TYPE_SCRIPT); | 830 precache::PrecacheResource::RESOURCE_TYPE_SCRIPT); |
| 939 InitializePrecacheResource( | 831 InitializePrecacheResource( |
| 940 manifest.add_resource(), "http://cdn.google.com/style.css", 0.75, | 832 manifest.add_resource(), "http://cdn.google.com/style.css", 0.75, |
| 941 precache::PrecacheResource::RESOURCE_TYPE_STYLESHEET); | 833 precache::PrecacheResource::RESOURCE_TYPE_STYLESHEET); |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1144 EXPECT_EQ(mock_tables_->manifest_table_.data_, manifests); | 1036 EXPECT_EQ(mock_tables_->manifest_table_.data_, manifests); |
| 1145 | 1037 |
| 1146 predictor_->DeleteAllUrls(); | 1038 predictor_->DeleteAllUrls(); |
| 1147 EXPECT_TRUE(mock_tables_->url_resource_table_.data_.empty()); | 1039 EXPECT_TRUE(mock_tables_->url_resource_table_.data_.empty()); |
| 1148 EXPECT_TRUE(mock_tables_->host_resource_table_.data_.empty()); | 1040 EXPECT_TRUE(mock_tables_->host_resource_table_.data_.empty()); |
| 1149 EXPECT_TRUE(mock_tables_->url_redirect_table_.data_.empty()); | 1041 EXPECT_TRUE(mock_tables_->url_redirect_table_.data_.empty()); |
| 1150 EXPECT_TRUE(mock_tables_->host_redirect_table_.data_.empty()); | 1042 EXPECT_TRUE(mock_tables_->host_redirect_table_.data_.empty()); |
| 1151 EXPECT_TRUE(mock_tables_->manifest_table_.data_.empty()); | 1043 EXPECT_TRUE(mock_tables_->manifest_table_.data_.empty()); |
| 1152 } | 1044 } |
| 1153 | 1045 |
| 1046 /* |
| 1154 TEST_F(ResourcePrefetchPredictorTest, OnMainFrameRequest) { | 1047 TEST_F(ResourcePrefetchPredictorTest, OnMainFrameRequest) { |
| 1155 URLRequestSummary summary1 = CreateURLRequestSummary( | 1048 URLRequestSummary summary1 = CreateURLRequestSummary( |
| 1156 1, "http://www.google.com", "http://www.google.com", | 1049 1, "http://www.google.com", "http://www.google.com", |
| 1157 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); | 1050 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); |
| 1158 URLRequestSummary summary2 = CreateURLRequestSummary( | 1051 URLRequestSummary summary2 = CreateURLRequestSummary( |
| 1159 2, "http://www.google.com", "http://www.google.com", | 1052 2, "http://www.google.com", "http://www.google.com", |
| 1160 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); | 1053 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); |
| 1161 URLRequestSummary summary3 = CreateURLRequestSummary( | 1054 URLRequestSummary summary3 = CreateURLRequestSummary( |
| 1162 3, "http://www.yahoo.com", "http://www.yahoo.com", | 1055 3, "http://www.yahoo.com", "http://www.yahoo.com", |
| 1163 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); | 1056 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1306 EXPECT_EQ(resource1, | 1199 EXPECT_EQ(resource1, |
| 1307 predictor_->inflight_navigations_[main_frame1.navigation_id] | 1200 predictor_->inflight_navigations_[main_frame1.navigation_id] |
| 1308 ->subresource_requests[0]); | 1201 ->subresource_requests[0]); |
| 1309 EXPECT_EQ(resource2, | 1202 EXPECT_EQ(resource2, |
| 1310 predictor_->inflight_navigations_[main_frame1.navigation_id] | 1203 predictor_->inflight_navigations_[main_frame1.navigation_id] |
| 1311 ->subresource_requests[1]); | 1204 ->subresource_requests[1]); |
| 1312 EXPECT_EQ(resource3, | 1205 EXPECT_EQ(resource3, |
| 1313 predictor_->inflight_navigations_[main_frame1.navigation_id] | 1206 predictor_->inflight_navigations_[main_frame1.navigation_id] |
| 1314 ->subresource_requests[2]); | 1207 ->subresource_requests[2]); |
| 1315 } | 1208 } |
| 1209 */ |
| 1316 | 1210 |
| 1317 TEST_F(ResourcePrefetchPredictorTest, SummarizeResponse) { | 1211 TEST_F(ResourcePrefetchPredictorTest, SummarizeResponse) { |
| 1318 net::HttpResponseInfo response_info; | 1212 net::HttpResponseInfo response_info; |
| 1319 response_info.headers = | 1213 response_info.headers = |
| 1320 MakeResponseHeaders("HTTP/1.1 200 OK\n\nSome: Headers\n"); | 1214 MakeResponseHeaders("HTTP/1.1 200 OK\n\nSome: Headers\n"); |
| 1321 response_info.was_cached = true; | 1215 response_info.was_cached = true; |
| 1322 url_request_job_factory_.set_response_info(response_info); | 1216 url_request_job_factory_.set_response_info(response_info); |
| 1323 | 1217 |
| 1324 GURL url("http://www.google.com/cat.png"); | 1218 GURL url("http://www.google.com/cat.png"); |
| 1325 std::unique_ptr<net::URLRequest> request = | 1219 std::unique_ptr<net::URLRequest> request = |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1623 content::RESOURCE_TYPE_FONT_RESOURCE, 10, 0, 1, 2.1, | 1517 content::RESOURCE_TYPE_FONT_RESOURCE, 10, 0, 1, 2.1, |
| 1624 net::MEDIUM, false, false); | 1518 net::MEDIUM, false, false); |
| 1625 predictor_->url_resource_data_->UpdateData(www_google_url.primary_key(), | 1519 predictor_->url_resource_data_->UpdateData(www_google_url.primary_key(), |
| 1626 www_google_url); | 1520 www_google_url); |
| 1627 | 1521 |
| 1628 urls.clear(); | 1522 urls.clear(); |
| 1629 EXPECT_TRUE(predictor_->GetPrefetchData(main_frame_url, &prediction)); | 1523 EXPECT_TRUE(predictor_->GetPrefetchData(main_frame_url, &prediction)); |
| 1630 EXPECT_THAT(urls, UnorderedElementsAre(GURL(font_url))); | 1524 EXPECT_THAT(urls, UnorderedElementsAre(GURL(font_url))); |
| 1631 } | 1525 } |
| 1632 | 1526 |
| 1527 /* |
| 1633 TEST_F(ResourcePrefetchPredictorTest, TestRecordFirstContentfulPaint) { | 1528 TEST_F(ResourcePrefetchPredictorTest, TestRecordFirstContentfulPaint) { |
| 1634 auto res1_time = base::TimeTicks::FromInternalValue(1); | 1529 auto res1_time = base::TimeTicks::FromInternalValue(1); |
| 1635 auto res2_time = base::TimeTicks::FromInternalValue(2); | 1530 auto res2_time = base::TimeTicks::FromInternalValue(2); |
| 1636 auto fcp_time = base::TimeTicks::FromInternalValue(3); | 1531 auto fcp_time = base::TimeTicks::FromInternalValue(3); |
| 1637 auto res3_time = base::TimeTicks::FromInternalValue(4); | 1532 auto res3_time = base::TimeTicks::FromInternalValue(4); |
| 1638 | 1533 |
| 1639 URLRequestSummary main_frame = | 1534 URLRequestSummary main_frame = |
| 1640 CreateURLRequestSummary(1, "http://www.google.com"); | 1535 CreateURLRequestSummary(1, "http://www.google.com"); |
| 1641 predictor_->RecordURLRequest(main_frame); | 1536 predictor_->RecordURLRequest(main_frame); |
| 1642 EXPECT_EQ(1U, predictor_->inflight_navigations_.size()); | 1537 EXPECT_EQ(1U, predictor_->inflight_navigations_.size()); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1662 predictor_->RecordMainFrameLoadComplete(main_frame.navigation_id); | 1557 predictor_->RecordMainFrameLoadComplete(main_frame.navigation_id); |
| 1663 profile_->BlockUntilHistoryProcessesPendingRequests(); | 1558 profile_->BlockUntilHistoryProcessesPendingRequests(); |
| 1664 | 1559 |
| 1665 PrefetchData host_data = CreatePrefetchData("www.google.com"); | 1560 PrefetchData host_data = CreatePrefetchData("www.google.com"); |
| 1666 InitializeResourceData(host_data.add_resources(), | 1561 InitializeResourceData(host_data.add_resources(), |
| 1667 "http://google.com/style1.css", | 1562 "http://google.com/style1.css", |
| 1668 content::RESOURCE_TYPE_STYLESHEET, 1, 0, 0, 1.0, | 1563 content::RESOURCE_TYPE_STYLESHEET, 1, 0, 0, 1.0, |
| 1669 net::MEDIUM, false, false); | 1564 net::MEDIUM, false, false); |
| 1670 InitializeResourceData( | 1565 InitializeResourceData( |
| 1671 host_data.add_resources(), "http://google.com/script1.js", | 1566 host_data.add_resources(), "http://google.com/script1.js", |
| 1672 content::RESOURCE_TYPE_SCRIPT, 1, 0, 0, 2.0, net::MEDIUM, false, false); | 1567 content::RESOURCE_TYPE_SCRIPT, 1, 0, 0, 2.0, net::MEDIUM, false, |
| 1568 false); |
| 1673 ResourceData* resource3_rd = host_data.add_resources(); | 1569 ResourceData* resource3_rd = host_data.add_resources(); |
| 1674 InitializeResourceData(resource3_rd, "http://google.com/script2.js", | 1570 InitializeResourceData(resource3_rd, "http://google.com/script2.js", |
| 1675 content::RESOURCE_TYPE_SCRIPT, 1, 0, 0, 3.0, | 1571 content::RESOURCE_TYPE_SCRIPT, 1, 0, 0, 3.0, |
| 1676 net::MEDIUM, false, false); | 1572 net::MEDIUM, false, false); |
| 1677 resource3_rd->set_before_first_contentful_paint(false); | 1573 resource3_rd->set_before_first_contentful_paint(false); |
| 1678 EXPECT_EQ(mock_tables_->host_resource_table_.data_, | 1574 EXPECT_EQ(mock_tables_->host_resource_table_.data_, |
| 1679 PrefetchDataMap({{host_data.primary_key(), host_data}})); | 1575 PrefetchDataMap({{host_data.primary_key(), host_data}})); |
| 1680 } | 1576 } |
| 1577 */ |
| 1681 | 1578 |
| 1682 } // namespace predictors | 1579 } // namespace predictors |
| OLD | NEW |