Chromium Code Reviews| Index: chrome/browser/predictors/loading_data_collector_unittest.cc |
| diff --git a/chrome/browser/predictors/loading_data_collector_unittest.cc b/chrome/browser/predictors/loading_data_collector_unittest.cc |
| index 7c75e1b0bcb729a180f7d57f70a93a2e6b8ba84f..aa548b5ee05f15507ca1eafd4cf85f799d64df74 100644 |
| --- a/chrome/browser/predictors/loading_data_collector_unittest.cc |
| +++ b/chrome/browser/predictors/loading_data_collector_unittest.cc |
| @@ -11,8 +11,10 @@ |
| #include "base/run_loop.h" |
| #include "base/test/histogram_tester.h" |
| #include "chrome/browser/history/history_service_factory.h" |
| +#include "chrome/browser/predictors/loading_predictor.h" |
| #include "chrome/browser/predictors/loading_test_util.h" |
| #include "chrome/test/base/testing_profile.h" |
| +#include "components/history/core/browser/history_service.h" |
| #include "content/public/test/test_browser_thread_bundle.h" |
| #include "net/http/http_response_headers.h" |
| #include "net/url_request/url_request_context.h" |
| @@ -24,17 +26,65 @@ using testing::StrictMock; |
| namespace predictors { |
| +using PrefetchDataMap = std::map<std::string, PrefetchData>; |
| +using RedirectDataMap = std::map<std::string, RedirectData>; |
| +using OriginDataMap = std::map<std::string, OriginData>; |
| +// using ManifestDataMap = std::map<std::string, precache::PrecacheManifest>; |
| + |
| class LoadingDataCollectorTest : public testing::Test { |
| public: |
| + LoadingDataCollectorTest() : profile_(new TestingProfile()) { |
| + PopulateTestConfig(&config_); |
| + mock_predictor_ = |
| + base::MakeUnique<StrictMock<MockResourcePrefetchPredictor>>( |
| + config_, profile_.get()), |
| + collector_ = base::MakeUnique<LoadingDataCollector>(mock_predictor_.get(), |
| + nullptr, config_); |
| + } |
| + |
| void SetUp() override { |
| + // mock_predictor_ = |
| + // base::MakeUnique<StrictMock<MockResourcePrefetchPredictor>>( |
| + // config, profile_.get()); |
| + |
| + base::RunLoop loop; |
| + loop.RunUntilIdle(); // Runs the DB lookup. |
| + // profile_->BlockUntilHistoryProcessesPendingRequests(); |
| + |
| url_request_job_factory_.Reset(); |
| url_request_context_.set_job_factory(&url_request_job_factory_); |
| } |
| protected: |
| + void AddUrlToHistory(const std::string& url, int visit_count) { |
| + HistoryServiceFactory::GetForProfile(profile_.get(), |
| + ServiceAccessType::EXPLICIT_ACCESS) |
| + ->AddPageWithDetails(GURL(url), base::string16(), visit_count, 0, |
| + base::Time::Now(), false, history::SOURCE_BROWSED); |
| + profile_->BlockUntilHistoryProcessesPendingRequests(); |
| + } |
| + |
| + URLRequestSummary CreateRedirectRequestSummary( |
| + SessionID::id_type session_id, |
| + const std::string& main_frame_url, |
| + const std::string& redirect_url) { |
| + URLRequestSummary summary = |
| + CreateURLRequestSummary(session_id, main_frame_url); |
| + summary.redirect_url = GURL(redirect_url); |
| + return summary; |
| + } |
| + |
| content::TestBrowserThreadBundle thread_bundle_; |
| + std::unique_ptr<TestingProfile> profile_; |
| net::TestURLRequestContext url_request_context_; |
| MockURLRequestJobFactory url_request_job_factory_; |
| + LoadingPredictorConfig config_; |
| + |
| + // std::unique_ptr<LoadingPredictor> loading_predictor_; |
| + std::unique_ptr<StrictMock<MockResourcePrefetchPredictor>> mock_predictor_; |
| + // scoped_refptr<StrictMock<MockResourcePrefetchPredictorTables>> |
| + // mock_tables_; |
| + std::unique_ptr<LoadingDataCollector> collector_; |
| }; |
| TEST_F(LoadingDataCollectorTest, HandledResourceTypes) { |
| @@ -227,4 +277,434 @@ TEST_F(LoadingDataCollectorTest, ShouldRecordResponseSubresource) { |
| LoadingDataCollector::ShouldRecordResponse(font_request_sub_frame.get())); |
| } |
| +// Single navigation but history count is low, so should not record url data. |
|
trevordixon
2017/06/19 20:41:08
Copied these tests without changing names, updatin
alexilin
2017/06/20 09:00:19
Yes, I agree with your plan. At first, I've though
|
| +TEST_F(LoadingDataCollectorTest, NavigationLowHistoryCount) { |
| + URLRequestSummary main_frame = |
| + CreateURLRequestSummary(1, "http://www.google.com"); |
| + collector_->RecordURLRequest(main_frame); |
| + EXPECT_EQ(1U, collector_->inflight_navigations_.size()); |
| + |
| + URLRequestSummary main_frame_redirect = CreateRedirectRequestSummary( |
| + 1, "http://www.google.com", "https://www.google.com"); |
| + collector_->RecordURLRedirect(main_frame_redirect); |
| + EXPECT_EQ(1U, collector_->inflight_navigations_.size()); |
| + main_frame = CreateURLRequestSummary(1, "https://www.google.com"); |
| + |
| + // Now add a few subresources. |
| + URLRequestSummary resource1 = CreateURLRequestSummary( |
| + 1, "https://www.google.com", "https://google.com/style1.css", |
| + content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", false); |
| + collector_->RecordURLResponse(resource1); |
| + URLRequestSummary resource2 = CreateURLRequestSummary( |
| + 1, "https://www.google.com", "https://google.com/script1.js", |
| + content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false); |
| + collector_->RecordURLResponse(resource2); |
| + URLRequestSummary resource3 = CreateURLRequestSummary( |
| + 1, "https://www.google.com", "https://google.com/script2.js", |
| + content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false); |
| + collector_->RecordURLResponse(resource3); |
| + |
| + EXPECT_CALL( |
| + *mock_predictor_, |
| + RecordPageRequestSummaryProxy(testing::Pointee(CreatePageRequestSummary( |
| + "https://www.google.com", "http://www.google.com", |
| + {resource1, resource2, resource3})))); |
| + |
| + collector_->RecordMainFrameLoadComplete(main_frame.navigation_id); |
| +} |
| + |
| +// Single navigation that will be recorded. Will check for duplicate |
| +// resources and also for number of resources saved. |
| +TEST_F(LoadingDataCollectorTest, NavigationUrlNotInDB) { |
| + URLRequestSummary main_frame = |
| + CreateURLRequestSummary(1, "http://www.google.com"); |
| + collector_->RecordURLRequest(main_frame); |
| + EXPECT_EQ(1U, collector_->inflight_navigations_.size()); |
| + |
| + std::vector<URLRequestSummary> resources; |
| + resources.push_back(CreateURLRequestSummary( |
| + 1, "http://www.google.com", "http://google.com/style1.css", |
| + content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", false)); |
| + collector_->RecordURLResponse(resources.back()); |
| + resources.push_back(CreateURLRequestSummary( |
| + 1, "http://www.google.com", "http://google.com/script1.js", |
| + content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false)); |
| + collector_->RecordURLResponse(resources.back()); |
| + resources.push_back(CreateURLRequestSummary( |
| + 1, "http://www.google.com", "http://google.com/script2.js", |
| + content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false)); |
| + collector_->RecordURLResponse(resources.back()); |
| + resources.push_back(CreateURLRequestSummary( |
| + 1, "http://www.google.com", "http://google.com/script1.js", |
| + content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", true)); |
| + collector_->RecordURLResponse(resources.back()); |
| + resources.push_back(CreateURLRequestSummary( |
| + 1, "http://www.google.com", "http://google.com/image1.png", |
| + content::RESOURCE_TYPE_IMAGE, net::MEDIUM, "image/png", false)); |
| + collector_->RecordURLResponse(resources.back()); |
| + resources.push_back(CreateURLRequestSummary( |
| + 1, "http://www.google.com", "http://google.com/image2.png", |
| + content::RESOURCE_TYPE_IMAGE, net::MEDIUM, "image/png", false)); |
| + collector_->RecordURLResponse(resources.back()); |
| + resources.push_back(CreateURLRequestSummary( |
| + 1, "http://www.google.com", "http://google.com/style2.css", |
| + content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", true)); |
| + collector_->RecordURLResponse(resources.back()); |
| + |
| + auto no_store = CreateURLRequestSummary( |
| + 1, "http://www.google.com", |
| + "http://static.google.com/style2-no-store.css", |
| + content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", true); |
| + no_store.is_no_store = true; |
| + collector_->RecordURLResponse(no_store); |
| + |
| + auto redirected = CreateURLRequestSummary( |
| + 1, "http://www.google.com", "http://reader.google.com/style.css", |
| + content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", true); |
| + redirected.redirect_url = GURL("http://dev.null.google.com/style.css"); |
| + |
| + collector_->RecordURLRedirect(redirected); |
| + redirected.is_no_store = true; |
| + redirected.request_url = redirected.redirect_url; |
| + redirected.redirect_url = GURL(); |
| + |
| + collector_->RecordURLResponse(redirected); |
| + |
| + EXPECT_CALL( |
| + *mock_predictor_, |
| + RecordPageRequestSummaryProxy(testing::Pointee(CreatePageRequestSummary( |
| + "http://www.google.com", "http://www.google.com", resources)))); |
| + |
| + collector_->RecordMainFrameLoadComplete(main_frame.navigation_id); |
| +} |
| + |
| +// Tests that navigation is recorded correctly for URL already present in |
| +// the database cache. |
| +TEST_F(LoadingDataCollectorTest, NavigationUrlInDB) { |
| + URLRequestSummary main_frame = CreateURLRequestSummary( |
| + 1, "http://www.google.com", "http://www.google.com", |
| + content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); |
| + collector_->RecordURLRequest(main_frame); |
| + EXPECT_EQ(1U, collector_->inflight_navigations_.size()); |
| + |
| + std::vector<URLRequestSummary> resources; |
| + resources.push_back(CreateURLRequestSummary( |
| + 1, "http://www.google.com", "http://google.com/style1.css", |
| + content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", false)); |
| + collector_->RecordURLResponse(resources.back()); |
| + resources.push_back(CreateURLRequestSummary( |
| + 1, "http://www.google.com", "http://google.com/script1.js", |
| + content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false)); |
| + collector_->RecordURLResponse(resources.back()); |
| + resources.push_back(CreateURLRequestSummary( |
| + 1, "http://www.google.com", "http://google.com/script2.js", |
| + content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false)); |
| + collector_->RecordURLResponse(resources.back()); |
| + resources.push_back(CreateURLRequestSummary( |
| + 1, "http://www.google.com", "http://google.com/script1.js", |
| + content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", true)); |
| + collector_->RecordURLResponse(resources.back()); |
| + resources.push_back(CreateURLRequestSummary( |
| + 1, "http://www.google.com", "http://google.com/image1.png", |
| + content::RESOURCE_TYPE_IMAGE, net::MEDIUM, "image/png", false)); |
| + collector_->RecordURLResponse(resources.back()); |
| + resources.push_back(CreateURLRequestSummary( |
| + 1, "http://www.google.com", "http://google.com/image2.png", |
| + content::RESOURCE_TYPE_IMAGE, net::MEDIUM, "image/png", false)); |
| + collector_->RecordURLResponse(resources.back()); |
| + resources.push_back(CreateURLRequestSummary( |
| + 1, "http://www.google.com", "http://google.com/style2.css", |
| + content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", true)); |
| + collector_->RecordURLResponse(resources.back()); |
| + auto no_store = CreateURLRequestSummary( |
| + 1, "http://www.google.com", |
| + "http://static.google.com/style2-no-store.css", |
| + content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", true); |
| + no_store.is_no_store = true; |
| + collector_->RecordURLResponse(no_store); |
| + |
| + EXPECT_CALL( |
| + *mock_predictor_, |
| + RecordPageRequestSummaryProxy(testing::Pointee(CreatePageRequestSummary( |
| + "http://www.google.com", "http://www.google.com", resources)))); |
| + |
| + collector_->RecordMainFrameLoadComplete(main_frame.navigation_id); |
| +} |
| + |
| +// Tests that a URL is deleted before another is added if the cache is full. |
| +TEST_F(LoadingDataCollectorTest, NavigationUrlNotInDBAndDBFull) { |
| + URLRequestSummary main_frame = CreateURLRequestSummary( |
| + 1, "http://www.nike.com", "http://www.nike.com", |
| + content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); |
| + collector_->RecordURLRequest(main_frame); |
| + EXPECT_EQ(1U, collector_->inflight_navigations_.size()); |
| + |
| + URLRequestSummary resource1 = CreateURLRequestSummary( |
| + 1, "http://www.nike.com", "http://nike.com/style1.css", |
| + content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", false); |
| + collector_->RecordURLResponse(resource1); |
| + URLRequestSummary resource2 = CreateURLRequestSummary( |
| + 1, "http://www.nike.com", "http://nike.com/image2.png", |
| + content::RESOURCE_TYPE_IMAGE, net::MEDIUM, "image/png", false); |
| + collector_->RecordURLResponse(resource2); |
| + |
| + EXPECT_CALL( |
| + *mock_predictor_, |
| + RecordPageRequestSummaryProxy(testing::Pointee( |
| + CreatePageRequestSummary("http://www.nike.com", "http://www.nike.com", |
| + {resource1, resource2})))); |
| + |
| + collector_->RecordMainFrameLoadComplete(main_frame.navigation_id); |
| +} |
| + |
| +TEST_F(LoadingDataCollectorTest, RedirectUrlNotInDB) { |
| + URLRequestSummary fb1 = CreateURLRequestSummary(1, "http://fb.com/google"); |
| + collector_->RecordURLRequest(fb1); |
| + EXPECT_EQ(1U, collector_->inflight_navigations_.size()); |
| + |
| + URLRequestSummary fb2 = CreateRedirectRequestSummary( |
| + 1, "http://fb.com/google", "http://facebook.com/google"); |
| + collector_->RecordURLRedirect(fb2); |
| + URLRequestSummary fb3 = CreateRedirectRequestSummary( |
| + 1, "http://facebook.com/google", "https://facebook.com/google"); |
| + collector_->RecordURLRedirect(fb3); |
| + NavigationID fb_end = CreateNavigationID(1, "https://facebook.com/google"); |
| + |
| + EXPECT_CALL( |
| + *mock_predictor_, |
| + RecordPageRequestSummaryProxy(testing::Pointee(CreatePageRequestSummary( |
| + "https://facebook.com/google", "http://fb.com/google", |
| + std::vector<URLRequestSummary>())))); |
| + |
| + collector_->RecordMainFrameLoadComplete(fb_end); |
| +} |
| + |
| +// Tests that redirect is recorded correctly for URL already present in |
| +// the database cache. |
| +TEST_F(LoadingDataCollectorTest, RedirectUrlInDB) { |
| + URLRequestSummary fb1 = CreateURLRequestSummary(1, "http://fb.com/google"); |
| + collector_->RecordURLRequest(fb1); |
| + EXPECT_EQ(1U, collector_->inflight_navigations_.size()); |
| + |
| + URLRequestSummary fb2 = CreateRedirectRequestSummary( |
| + 1, "http://fb.com/google", "http://facebook.com/google"); |
| + collector_->RecordURLRedirect(fb2); |
| + URLRequestSummary fb3 = CreateRedirectRequestSummary( |
| + 1, "http://facebook.com/google", "https://facebook.com/google"); |
| + collector_->RecordURLRedirect(fb3); |
| + NavigationID fb_end = CreateNavigationID(1, "https://facebook.com/google"); |
| + |
| + EXPECT_CALL( |
| + *mock_predictor_, |
| + RecordPageRequestSummaryProxy(testing::Pointee(CreatePageRequestSummary( |
| + "https://facebook.com/google", "http://fb.com/google", |
| + std::vector<URLRequestSummary>())))); |
| + |
| + collector_->RecordMainFrameLoadComplete(fb_end); |
| +} |
| + |
| +TEST_F(LoadingDataCollectorTest, OnMainFrameRequest) { |
| + URLRequestSummary summary1 = CreateURLRequestSummary( |
| + 1, "http://www.google.com", "http://www.google.com", |
| + content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); |
| + URLRequestSummary summary2 = CreateURLRequestSummary( |
| + 2, "http://www.google.com", "http://www.google.com", |
| + content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); |
| + URLRequestSummary summary3 = CreateURLRequestSummary( |
| + 3, "http://www.yahoo.com", "http://www.yahoo.com", |
| + content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); |
| + |
| + collector_->RecordURLRequest(summary1); |
| + EXPECT_EQ(1U, collector_->inflight_navigations_.size()); |
| + collector_->RecordURLRequest(summary2); |
| + EXPECT_EQ(2U, collector_->inflight_navigations_.size()); |
| + collector_->RecordURLRequest(summary3); |
| + EXPECT_EQ(3U, collector_->inflight_navigations_.size()); |
| + |
| + // Insert another with same navigation id. It should replace. |
| + URLRequestSummary summary4 = CreateURLRequestSummary( |
| + 1, "http://www.nike.com", "http://www.nike.com", |
| + content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); |
| + URLRequestSummary summary5 = CreateURLRequestSummary( |
| + 2, "http://www.google.com", "http://www.google.com", |
| + content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); |
| + |
| + collector_->RecordURLRequest(summary4); |
| + EXPECT_EQ(3U, collector_->inflight_navigations_.size()); |
| + |
| + // Change this creation time so that it will go away on the next insert. |
| + summary5.navigation_id.creation_time = |
| + base::TimeTicks::Now() - base::TimeDelta::FromDays(1); |
| + collector_->RecordURLRequest(summary5); |
| + EXPECT_EQ(3U, collector_->inflight_navigations_.size()); |
| + |
| + URLRequestSummary summary6 = CreateURLRequestSummary( |
| + 4, "http://www.shoes.com", "http://www.shoes.com", |
| + content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); |
| + collector_->RecordURLRequest(summary6); |
| + EXPECT_EQ(3U, collector_->inflight_navigations_.size()); |
| + |
| + EXPECT_TRUE(collector_->inflight_navigations_.find(summary3.navigation_id) != |
| + collector_->inflight_navigations_.end()); |
| + EXPECT_TRUE(collector_->inflight_navigations_.find(summary4.navigation_id) != |
| + collector_->inflight_navigations_.end()); |
| + EXPECT_TRUE(collector_->inflight_navigations_.find(summary6.navigation_id) != |
| + collector_->inflight_navigations_.end()); |
| +} |
| + |
| +TEST_F(LoadingDataCollectorTest, OnMainFrameRedirect) { |
| + URLRequestSummary yahoo = CreateURLRequestSummary(1, "http://yahoo.com"); |
| + |
| + URLRequestSummary bbc1 = CreateURLRequestSummary(2, "http://bbc.com"); |
| + URLRequestSummary bbc2 = |
| + CreateRedirectRequestSummary(2, "http://bbc.com", "https://www.bbc.com"); |
| + NavigationID bbc_end = CreateNavigationID(2, "https://www.bbc.com"); |
| + |
| + URLRequestSummary youtube1 = CreateURLRequestSummary(3, "http://youtube.com"); |
| + URLRequestSummary youtube2 = CreateRedirectRequestSummary( |
| + 3, "http://youtube.com", "https://youtube.com"); |
| + NavigationID youtube_end = CreateNavigationID(3, "https://youtube.com"); |
| + |
| + URLRequestSummary nyt1 = CreateURLRequestSummary(4, "http://nyt.com"); |
| + URLRequestSummary nyt2 = |
| + CreateRedirectRequestSummary(4, "http://nyt.com", "http://nytimes.com"); |
| + URLRequestSummary nyt3 = CreateRedirectRequestSummary(4, "http://nytimes.com", |
| + "http://m.nytimes.com"); |
| + NavigationID nyt_end = CreateNavigationID(4, "http://m.nytimes.com"); |
| + |
| + URLRequestSummary fb1 = CreateURLRequestSummary(5, "http://fb.com"); |
| + URLRequestSummary fb2 = |
| + CreateRedirectRequestSummary(5, "http://fb.com", "http://facebook.com"); |
| + URLRequestSummary fb3 = CreateRedirectRequestSummary(5, "http://facebook.com", |
| + "https://facebook.com"); |
| + URLRequestSummary fb4 = CreateRedirectRequestSummary( |
| + 5, "https://facebook.com", |
| + "https://m.facebook.com/?refsrc=https%3A%2F%2Fwww.facebook.com%2F&_rdr"); |
| + NavigationID fb_end = CreateNavigationID( |
| + 5, |
| + "https://m.facebook.com/?refsrc=https%3A%2F%2Fwww.facebook.com%2F&_rdr"); |
| + |
| + // Redirect with empty redirect_url will be deleted. |
| + collector_->RecordURLRequest(yahoo); |
| + EXPECT_EQ(1U, collector_->inflight_navigations_.size()); |
| + collector_->OnMainFrameRedirect(yahoo); |
| + EXPECT_TRUE(collector_->inflight_navigations_.empty()); |
| + |
| + // Redirect without previous request works fine. |
| + // collector_->RecordURLRequest(bbc1) missing. |
| + collector_->OnMainFrameRedirect(bbc2); |
| + EXPECT_EQ(1U, collector_->inflight_navigations_.size()); |
| + EXPECT_EQ(bbc1.navigation_id.main_frame_url, |
| + collector_->inflight_navigations_[bbc_end]->initial_url); |
| + |
| + // http://youtube.com -> https://youtube.com. |
| + collector_->RecordURLRequest(youtube1); |
| + EXPECT_EQ(2U, collector_->inflight_navigations_.size()); |
| + collector_->OnMainFrameRedirect(youtube2); |
| + EXPECT_EQ(2U, collector_->inflight_navigations_.size()); |
| + EXPECT_EQ(youtube1.navigation_id.main_frame_url, |
| + collector_->inflight_navigations_[youtube_end]->initial_url); |
| + |
| + // http://nyt.com -> http://nytimes.com -> http://m.nytimes.com. |
| + collector_->RecordURLRequest(nyt1); |
| + EXPECT_EQ(3U, collector_->inflight_navigations_.size()); |
| + collector_->OnMainFrameRedirect(nyt2); |
| + collector_->OnMainFrameRedirect(nyt3); |
| + EXPECT_EQ(3U, collector_->inflight_navigations_.size()); |
| + EXPECT_EQ(nyt1.navigation_id.main_frame_url, |
| + collector_->inflight_navigations_[nyt_end]->initial_url); |
| + |
| + // http://fb.com -> http://facebook.com -> https://facebook.com -> |
| + // https://m.facebook.com/?refsrc=https%3A%2F%2Fwww.facebook.com%2F&_rdr. |
| + collector_->RecordURLRequest(fb1); |
| + EXPECT_EQ(4U, collector_->inflight_navigations_.size()); |
| + collector_->OnMainFrameRedirect(fb2); |
| + collector_->OnMainFrameRedirect(fb3); |
| + collector_->OnMainFrameRedirect(fb4); |
| + EXPECT_EQ(4U, collector_->inflight_navigations_.size()); |
| + EXPECT_EQ(fb1.navigation_id.main_frame_url, |
| + collector_->inflight_navigations_[fb_end]->initial_url); |
| +} |
| + |
| +TEST_F(LoadingDataCollectorTest, OnSubresourceResponse) { |
| + // If there is no inflight navigation, nothing happens. |
| + URLRequestSummary resource1 = CreateURLRequestSummary( |
| + 1, "http://www.google.com", "http://google.com/style1.css", |
| + content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", false); |
| + collector_->RecordURLResponse(resource1); |
| + EXPECT_TRUE(collector_->inflight_navigations_.empty()); |
| + |
| + // Add an inflight navigation. |
| + URLRequestSummary main_frame1 = CreateURLRequestSummary( |
| + 1, "http://www.google.com", "http://www.google.com", |
| + content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); |
| + collector_->RecordURLRequest(main_frame1); |
| + EXPECT_EQ(1U, collector_->inflight_navigations_.size()); |
| + |
| + // Now add a few subresources. |
| + URLRequestSummary resource2 = CreateURLRequestSummary( |
| + 1, "http://www.google.com", "http://google.com/script1.js", |
| + content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false); |
| + URLRequestSummary resource3 = CreateURLRequestSummary( |
| + 1, "http://www.google.com", "http://google.com/script2.js", |
| + content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false); |
| + collector_->RecordURLResponse(resource1); |
| + collector_->RecordURLResponse(resource2); |
| + collector_->RecordURLResponse(resource3); |
| + |
| + EXPECT_EQ(1U, collector_->inflight_navigations_.size()); |
| + EXPECT_EQ(3U, collector_->inflight_navigations_[main_frame1.navigation_id] |
| + ->subresource_requests.size()); |
| + EXPECT_EQ(resource1, |
| + collector_->inflight_navigations_[main_frame1.navigation_id] |
| + ->subresource_requests[0]); |
| + EXPECT_EQ(resource2, |
| + collector_->inflight_navigations_[main_frame1.navigation_id] |
| + ->subresource_requests[1]); |
| + EXPECT_EQ(resource3, |
| + collector_->inflight_navigations_[main_frame1.navigation_id] |
| + ->subresource_requests[2]); |
| +} |
| + |
| +TEST_F(LoadingDataCollectorTest, TestRecordFirstContentfulPaint) { |
| + auto res1_time = base::TimeTicks::FromInternalValue(1); |
| + auto res2_time = base::TimeTicks::FromInternalValue(2); |
| + auto fcp_time = base::TimeTicks::FromInternalValue(3); |
| + auto res3_time = base::TimeTicks::FromInternalValue(4); |
| + |
| + URLRequestSummary main_frame = |
| + CreateURLRequestSummary(1, "http://www.google.com"); |
| + collector_->RecordURLRequest(main_frame); |
| + EXPECT_EQ(1U, collector_->inflight_navigations_.size()); |
| + |
| + URLRequestSummary resource1 = CreateURLRequestSummary( |
| + 1, "http://www.google.com", "http://google.com/style1.css", |
| + content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", false); |
| + resource1.response_time = res1_time; |
| + collector_->RecordURLResponse(resource1); |
| + URLRequestSummary resource2 = CreateURLRequestSummary( |
| + 1, "http://www.google.com", "http://google.com/script1.js", |
| + content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false); |
| + resource2.response_time = res2_time; |
| + collector_->RecordURLResponse(resource2); |
| + URLRequestSummary resource3 = CreateURLRequestSummary( |
| + 1, "http://www.google.com", "http://google.com/script2.js", |
| + content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false); |
| + resource3.response_time = res3_time; |
| + collector_->RecordURLResponse(resource3); |
| + |
| + collector_->RecordFirstContentfulPaint(main_frame.navigation_id, fcp_time); |
| + |
| + // Since res3_time is after fcp_time, we expect this field to have been set to |
| + // false before RecordPageRequestSummary is called. |
| + resource3.before_first_contentful_paint = false; |
| + EXPECT_CALL( |
| + *mock_predictor_, |
| + RecordPageRequestSummaryProxy(testing::Pointee(CreatePageRequestSummary( |
| + "http://www.google.com", "http://www.google.com", |
| + std::vector<URLRequestSummary>{resource1, resource2, resource3})))); |
| + |
| + collector_->RecordMainFrameLoadComplete(main_frame.navigation_id); |
| +} |
| + |
| } // namespace predictors |