Chromium Code Reviews| 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/loading_data_collector.h" | 5 #include "chrome/browser/predictors/loading_data_collector.h" |
| 6 | 6 |
| 7 #include <iostream> | 7 #include <iostream> |
| 8 #include <memory> | 8 #include <memory> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/run_loop.h" | 11 #include "base/run_loop.h" |
| 12 #include "base/test/histogram_tester.h" | 12 #include "base/test/histogram_tester.h" |
| 13 #include "chrome/browser/history/history_service_factory.h" | 13 #include "chrome/browser/history/history_service_factory.h" |
| 14 #include "chrome/browser/predictors/loading_predictor.h" | |
| 14 #include "chrome/browser/predictors/loading_test_util.h" | 15 #include "chrome/browser/predictors/loading_test_util.h" |
| 15 #include "chrome/test/base/testing_profile.h" | 16 #include "chrome/test/base/testing_profile.h" |
| 17 #include "components/history/core/browser/history_service.h" | |
| 16 #include "content/public/test/test_browser_thread_bundle.h" | 18 #include "content/public/test/test_browser_thread_bundle.h" |
| 17 #include "net/http/http_response_headers.h" | 19 #include "net/http/http_response_headers.h" |
| 18 #include "net/url_request/url_request_context.h" | 20 #include "net/url_request/url_request_context.h" |
| 19 #include "net/url_request/url_request_job.h" | 21 #include "net/url_request/url_request_job.h" |
| 20 #include "testing/gmock/include/gmock/gmock.h" | 22 #include "testing/gmock/include/gmock/gmock.h" |
| 21 #include "testing/gtest/include/gtest/gtest.h" | 23 #include "testing/gtest/include/gtest/gtest.h" |
| 22 | 24 |
| 23 using testing::StrictMock; | 25 using testing::StrictMock; |
| 24 | 26 |
| 25 namespace predictors { | 27 namespace predictors { |
| 26 | 28 |
| 29 using PrefetchDataMap = std::map<std::string, PrefetchData>; | |
| 30 using RedirectDataMap = std::map<std::string, RedirectData>; | |
| 31 using OriginDataMap = std::map<std::string, OriginData>; | |
| 32 // using ManifestDataMap = std::map<std::string, precache::PrecacheManifest>; | |
| 33 | |
| 27 class LoadingDataCollectorTest : public testing::Test { | 34 class LoadingDataCollectorTest : public testing::Test { |
| 28 public: | 35 public: |
| 36 LoadingDataCollectorTest() : profile_(new TestingProfile()) { | |
| 37 PopulateTestConfig(&config_); | |
| 38 mock_predictor_ = | |
| 39 base::MakeUnique<StrictMock<MockResourcePrefetchPredictor>>( | |
| 40 config_, profile_.get()), | |
| 41 collector_ = base::MakeUnique<LoadingDataCollector>(mock_predictor_.get(), | |
| 42 nullptr, config_); | |
| 43 } | |
| 44 | |
| 29 void SetUp() override { | 45 void SetUp() override { |
| 46 // mock_predictor_ = | |
| 47 // base::MakeUnique<StrictMock<MockResourcePrefetchPredictor>>( | |
| 48 // config, profile_.get()); | |
| 49 | |
| 50 base::RunLoop loop; | |
| 51 loop.RunUntilIdle(); // Runs the DB lookup. | |
| 52 // profile_->BlockUntilHistoryProcessesPendingRequests(); | |
| 53 | |
| 30 url_request_job_factory_.Reset(); | 54 url_request_job_factory_.Reset(); |
| 31 url_request_context_.set_job_factory(&url_request_job_factory_); | 55 url_request_context_.set_job_factory(&url_request_job_factory_); |
| 32 } | 56 } |
| 33 | 57 |
| 34 protected: | 58 protected: |
| 59 void AddUrlToHistory(const std::string& url, int visit_count) { | |
| 60 HistoryServiceFactory::GetForProfile(profile_.get(), | |
| 61 ServiceAccessType::EXPLICIT_ACCESS) | |
| 62 ->AddPageWithDetails(GURL(url), base::string16(), visit_count, 0, | |
| 63 base::Time::Now(), false, history::SOURCE_BROWSED); | |
| 64 profile_->BlockUntilHistoryProcessesPendingRequests(); | |
| 65 } | |
| 66 | |
| 67 URLRequestSummary CreateRedirectRequestSummary( | |
| 68 SessionID::id_type session_id, | |
| 69 const std::string& main_frame_url, | |
| 70 const std::string& redirect_url) { | |
| 71 URLRequestSummary summary = | |
| 72 CreateURLRequestSummary(session_id, main_frame_url); | |
| 73 summary.redirect_url = GURL(redirect_url); | |
| 74 return summary; | |
| 75 } | |
| 76 | |
| 35 content::TestBrowserThreadBundle thread_bundle_; | 77 content::TestBrowserThreadBundle thread_bundle_; |
| 78 std::unique_ptr<TestingProfile> profile_; | |
| 36 net::TestURLRequestContext url_request_context_; | 79 net::TestURLRequestContext url_request_context_; |
| 37 MockURLRequestJobFactory url_request_job_factory_; | 80 MockURLRequestJobFactory url_request_job_factory_; |
| 81 LoadingPredictorConfig config_; | |
| 82 | |
| 83 // std::unique_ptr<LoadingPredictor> loading_predictor_; | |
| 84 std::unique_ptr<StrictMock<MockResourcePrefetchPredictor>> mock_predictor_; | |
| 85 // scoped_refptr<StrictMock<MockResourcePrefetchPredictorTables>> | |
| 86 // mock_tables_; | |
| 87 std::unique_ptr<LoadingDataCollector> collector_; | |
| 38 }; | 88 }; |
| 39 | 89 |
| 40 TEST_F(LoadingDataCollectorTest, HandledResourceTypes) { | 90 TEST_F(LoadingDataCollectorTest, HandledResourceTypes) { |
| 41 EXPECT_TRUE(LoadingDataCollector::IsHandledResourceType( | 91 EXPECT_TRUE(LoadingDataCollector::IsHandledResourceType( |
| 42 content::RESOURCE_TYPE_STYLESHEET, "bogus/mime-type")); | 92 content::RESOURCE_TYPE_STYLESHEET, "bogus/mime-type")); |
| 43 EXPECT_TRUE(LoadingDataCollector::IsHandledResourceType( | 93 EXPECT_TRUE(LoadingDataCollector::IsHandledResourceType( |
| 44 content::RESOURCE_TYPE_STYLESHEET, "")); | 94 content::RESOURCE_TYPE_STYLESHEET, "")); |
| 45 EXPECT_FALSE(LoadingDataCollector::IsHandledResourceType( | 95 EXPECT_FALSE(LoadingDataCollector::IsHandledResourceType( |
| 46 content::RESOURCE_TYPE_WORKER, "text/css")); | 96 content::RESOURCE_TYPE_WORKER, "text/css")); |
| 47 EXPECT_FALSE(LoadingDataCollector::IsHandledResourceType( | 97 EXPECT_FALSE(LoadingDataCollector::IsHandledResourceType( |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 220 prefetch_unknown_font_request.get())); | 270 prefetch_unknown_font_request.get())); |
| 221 | 271 |
| 222 // Not main frame. | 272 // Not main frame. |
| 223 std::unique_ptr<net::URLRequest> font_request_sub_frame = CreateURLRequest( | 273 std::unique_ptr<net::URLRequest> font_request_sub_frame = CreateURLRequest( |
| 224 url_request_context_, GURL("http://www.google.com/comic-sans-ms.woff"), | 274 url_request_context_, GURL("http://www.google.com/comic-sans-ms.woff"), |
| 225 net::MEDIUM, content::RESOURCE_TYPE_FONT_RESOURCE, false); | 275 net::MEDIUM, content::RESOURCE_TYPE_FONT_RESOURCE, false); |
| 226 EXPECT_FALSE( | 276 EXPECT_FALSE( |
| 227 LoadingDataCollector::ShouldRecordResponse(font_request_sub_frame.get())); | 277 LoadingDataCollector::ShouldRecordResponse(font_request_sub_frame.get())); |
| 228 } | 278 } |
| 229 | 279 |
| 280 // 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
| |
| 281 TEST_F(LoadingDataCollectorTest, NavigationLowHistoryCount) { | |
| 282 URLRequestSummary main_frame = | |
| 283 CreateURLRequestSummary(1, "http://www.google.com"); | |
| 284 collector_->RecordURLRequest(main_frame); | |
| 285 EXPECT_EQ(1U, collector_->inflight_navigations_.size()); | |
| 286 | |
| 287 URLRequestSummary main_frame_redirect = CreateRedirectRequestSummary( | |
| 288 1, "http://www.google.com", "https://www.google.com"); | |
| 289 collector_->RecordURLRedirect(main_frame_redirect); | |
| 290 EXPECT_EQ(1U, collector_->inflight_navigations_.size()); | |
| 291 main_frame = CreateURLRequestSummary(1, "https://www.google.com"); | |
| 292 | |
| 293 // Now add a few subresources. | |
| 294 URLRequestSummary resource1 = CreateURLRequestSummary( | |
| 295 1, "https://www.google.com", "https://google.com/style1.css", | |
| 296 content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", false); | |
| 297 collector_->RecordURLResponse(resource1); | |
| 298 URLRequestSummary resource2 = CreateURLRequestSummary( | |
| 299 1, "https://www.google.com", "https://google.com/script1.js", | |
| 300 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false); | |
| 301 collector_->RecordURLResponse(resource2); | |
| 302 URLRequestSummary resource3 = CreateURLRequestSummary( | |
| 303 1, "https://www.google.com", "https://google.com/script2.js", | |
| 304 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false); | |
| 305 collector_->RecordURLResponse(resource3); | |
| 306 | |
| 307 EXPECT_CALL( | |
| 308 *mock_predictor_, | |
| 309 RecordPageRequestSummaryProxy(testing::Pointee(CreatePageRequestSummary( | |
| 310 "https://www.google.com", "http://www.google.com", | |
| 311 {resource1, resource2, resource3})))); | |
| 312 | |
| 313 collector_->RecordMainFrameLoadComplete(main_frame.navigation_id); | |
| 314 } | |
| 315 | |
| 316 // Single navigation that will be recorded. Will check for duplicate | |
| 317 // resources and also for number of resources saved. | |
| 318 TEST_F(LoadingDataCollectorTest, NavigationUrlNotInDB) { | |
| 319 URLRequestSummary main_frame = | |
| 320 CreateURLRequestSummary(1, "http://www.google.com"); | |
| 321 collector_->RecordURLRequest(main_frame); | |
| 322 EXPECT_EQ(1U, collector_->inflight_navigations_.size()); | |
| 323 | |
| 324 std::vector<URLRequestSummary> resources; | |
| 325 resources.push_back(CreateURLRequestSummary( | |
| 326 1, "http://www.google.com", "http://google.com/style1.css", | |
| 327 content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", false)); | |
| 328 collector_->RecordURLResponse(resources.back()); | |
| 329 resources.push_back(CreateURLRequestSummary( | |
| 330 1, "http://www.google.com", "http://google.com/script1.js", | |
| 331 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false)); | |
| 332 collector_->RecordURLResponse(resources.back()); | |
| 333 resources.push_back(CreateURLRequestSummary( | |
| 334 1, "http://www.google.com", "http://google.com/script2.js", | |
| 335 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false)); | |
| 336 collector_->RecordURLResponse(resources.back()); | |
| 337 resources.push_back(CreateURLRequestSummary( | |
| 338 1, "http://www.google.com", "http://google.com/script1.js", | |
| 339 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", true)); | |
| 340 collector_->RecordURLResponse(resources.back()); | |
| 341 resources.push_back(CreateURLRequestSummary( | |
| 342 1, "http://www.google.com", "http://google.com/image1.png", | |
| 343 content::RESOURCE_TYPE_IMAGE, net::MEDIUM, "image/png", false)); | |
| 344 collector_->RecordURLResponse(resources.back()); | |
| 345 resources.push_back(CreateURLRequestSummary( | |
| 346 1, "http://www.google.com", "http://google.com/image2.png", | |
| 347 content::RESOURCE_TYPE_IMAGE, net::MEDIUM, "image/png", false)); | |
| 348 collector_->RecordURLResponse(resources.back()); | |
| 349 resources.push_back(CreateURLRequestSummary( | |
| 350 1, "http://www.google.com", "http://google.com/style2.css", | |
| 351 content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", true)); | |
| 352 collector_->RecordURLResponse(resources.back()); | |
| 353 | |
| 354 auto no_store = CreateURLRequestSummary( | |
| 355 1, "http://www.google.com", | |
| 356 "http://static.google.com/style2-no-store.css", | |
| 357 content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", true); | |
| 358 no_store.is_no_store = true; | |
| 359 collector_->RecordURLResponse(no_store); | |
| 360 | |
| 361 auto redirected = CreateURLRequestSummary( | |
| 362 1, "http://www.google.com", "http://reader.google.com/style.css", | |
| 363 content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", true); | |
| 364 redirected.redirect_url = GURL("http://dev.null.google.com/style.css"); | |
| 365 | |
| 366 collector_->RecordURLRedirect(redirected); | |
| 367 redirected.is_no_store = true; | |
| 368 redirected.request_url = redirected.redirect_url; | |
| 369 redirected.redirect_url = GURL(); | |
| 370 | |
| 371 collector_->RecordURLResponse(redirected); | |
| 372 | |
| 373 EXPECT_CALL( | |
| 374 *mock_predictor_, | |
| 375 RecordPageRequestSummaryProxy(testing::Pointee(CreatePageRequestSummary( | |
| 376 "http://www.google.com", "http://www.google.com", resources)))); | |
| 377 | |
| 378 collector_->RecordMainFrameLoadComplete(main_frame.navigation_id); | |
| 379 } | |
| 380 | |
| 381 // Tests that navigation is recorded correctly for URL already present in | |
| 382 // the database cache. | |
| 383 TEST_F(LoadingDataCollectorTest, NavigationUrlInDB) { | |
| 384 URLRequestSummary main_frame = CreateURLRequestSummary( | |
| 385 1, "http://www.google.com", "http://www.google.com", | |
| 386 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); | |
| 387 collector_->RecordURLRequest(main_frame); | |
| 388 EXPECT_EQ(1U, collector_->inflight_navigations_.size()); | |
| 389 | |
| 390 std::vector<URLRequestSummary> resources; | |
| 391 resources.push_back(CreateURLRequestSummary( | |
| 392 1, "http://www.google.com", "http://google.com/style1.css", | |
| 393 content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", false)); | |
| 394 collector_->RecordURLResponse(resources.back()); | |
| 395 resources.push_back(CreateURLRequestSummary( | |
| 396 1, "http://www.google.com", "http://google.com/script1.js", | |
| 397 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false)); | |
| 398 collector_->RecordURLResponse(resources.back()); | |
| 399 resources.push_back(CreateURLRequestSummary( | |
| 400 1, "http://www.google.com", "http://google.com/script2.js", | |
| 401 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false)); | |
| 402 collector_->RecordURLResponse(resources.back()); | |
| 403 resources.push_back(CreateURLRequestSummary( | |
| 404 1, "http://www.google.com", "http://google.com/script1.js", | |
| 405 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", true)); | |
| 406 collector_->RecordURLResponse(resources.back()); | |
| 407 resources.push_back(CreateURLRequestSummary( | |
| 408 1, "http://www.google.com", "http://google.com/image1.png", | |
| 409 content::RESOURCE_TYPE_IMAGE, net::MEDIUM, "image/png", false)); | |
| 410 collector_->RecordURLResponse(resources.back()); | |
| 411 resources.push_back(CreateURLRequestSummary( | |
| 412 1, "http://www.google.com", "http://google.com/image2.png", | |
| 413 content::RESOURCE_TYPE_IMAGE, net::MEDIUM, "image/png", false)); | |
| 414 collector_->RecordURLResponse(resources.back()); | |
| 415 resources.push_back(CreateURLRequestSummary( | |
| 416 1, "http://www.google.com", "http://google.com/style2.css", | |
| 417 content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", true)); | |
| 418 collector_->RecordURLResponse(resources.back()); | |
| 419 auto no_store = CreateURLRequestSummary( | |
| 420 1, "http://www.google.com", | |
| 421 "http://static.google.com/style2-no-store.css", | |
| 422 content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", true); | |
| 423 no_store.is_no_store = true; | |
| 424 collector_->RecordURLResponse(no_store); | |
| 425 | |
| 426 EXPECT_CALL( | |
| 427 *mock_predictor_, | |
| 428 RecordPageRequestSummaryProxy(testing::Pointee(CreatePageRequestSummary( | |
| 429 "http://www.google.com", "http://www.google.com", resources)))); | |
| 430 | |
| 431 collector_->RecordMainFrameLoadComplete(main_frame.navigation_id); | |
| 432 } | |
| 433 | |
| 434 // Tests that a URL is deleted before another is added if the cache is full. | |
| 435 TEST_F(LoadingDataCollectorTest, NavigationUrlNotInDBAndDBFull) { | |
| 436 URLRequestSummary main_frame = CreateURLRequestSummary( | |
| 437 1, "http://www.nike.com", "http://www.nike.com", | |
| 438 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); | |
| 439 collector_->RecordURLRequest(main_frame); | |
| 440 EXPECT_EQ(1U, collector_->inflight_navigations_.size()); | |
| 441 | |
| 442 URLRequestSummary resource1 = CreateURLRequestSummary( | |
| 443 1, "http://www.nike.com", "http://nike.com/style1.css", | |
| 444 content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", false); | |
| 445 collector_->RecordURLResponse(resource1); | |
| 446 URLRequestSummary resource2 = CreateURLRequestSummary( | |
| 447 1, "http://www.nike.com", "http://nike.com/image2.png", | |
| 448 content::RESOURCE_TYPE_IMAGE, net::MEDIUM, "image/png", false); | |
| 449 collector_->RecordURLResponse(resource2); | |
| 450 | |
| 451 EXPECT_CALL( | |
| 452 *mock_predictor_, | |
| 453 RecordPageRequestSummaryProxy(testing::Pointee( | |
| 454 CreatePageRequestSummary("http://www.nike.com", "http://www.nike.com", | |
| 455 {resource1, resource2})))); | |
| 456 | |
| 457 collector_->RecordMainFrameLoadComplete(main_frame.navigation_id); | |
| 458 } | |
| 459 | |
| 460 TEST_F(LoadingDataCollectorTest, RedirectUrlNotInDB) { | |
| 461 URLRequestSummary fb1 = CreateURLRequestSummary(1, "http://fb.com/google"); | |
| 462 collector_->RecordURLRequest(fb1); | |
| 463 EXPECT_EQ(1U, collector_->inflight_navigations_.size()); | |
| 464 | |
| 465 URLRequestSummary fb2 = CreateRedirectRequestSummary( | |
| 466 1, "http://fb.com/google", "http://facebook.com/google"); | |
| 467 collector_->RecordURLRedirect(fb2); | |
| 468 URLRequestSummary fb3 = CreateRedirectRequestSummary( | |
| 469 1, "http://facebook.com/google", "https://facebook.com/google"); | |
| 470 collector_->RecordURLRedirect(fb3); | |
| 471 NavigationID fb_end = CreateNavigationID(1, "https://facebook.com/google"); | |
| 472 | |
| 473 EXPECT_CALL( | |
| 474 *mock_predictor_, | |
| 475 RecordPageRequestSummaryProxy(testing::Pointee(CreatePageRequestSummary( | |
| 476 "https://facebook.com/google", "http://fb.com/google", | |
| 477 std::vector<URLRequestSummary>())))); | |
| 478 | |
| 479 collector_->RecordMainFrameLoadComplete(fb_end); | |
| 480 } | |
| 481 | |
| 482 // Tests that redirect is recorded correctly for URL already present in | |
| 483 // the database cache. | |
| 484 TEST_F(LoadingDataCollectorTest, RedirectUrlInDB) { | |
| 485 URLRequestSummary fb1 = CreateURLRequestSummary(1, "http://fb.com/google"); | |
| 486 collector_->RecordURLRequest(fb1); | |
| 487 EXPECT_EQ(1U, collector_->inflight_navigations_.size()); | |
| 488 | |
| 489 URLRequestSummary fb2 = CreateRedirectRequestSummary( | |
| 490 1, "http://fb.com/google", "http://facebook.com/google"); | |
| 491 collector_->RecordURLRedirect(fb2); | |
| 492 URLRequestSummary fb3 = CreateRedirectRequestSummary( | |
| 493 1, "http://facebook.com/google", "https://facebook.com/google"); | |
| 494 collector_->RecordURLRedirect(fb3); | |
| 495 NavigationID fb_end = CreateNavigationID(1, "https://facebook.com/google"); | |
| 496 | |
| 497 EXPECT_CALL( | |
| 498 *mock_predictor_, | |
| 499 RecordPageRequestSummaryProxy(testing::Pointee(CreatePageRequestSummary( | |
| 500 "https://facebook.com/google", "http://fb.com/google", | |
| 501 std::vector<URLRequestSummary>())))); | |
| 502 | |
| 503 collector_->RecordMainFrameLoadComplete(fb_end); | |
| 504 } | |
| 505 | |
| 506 TEST_F(LoadingDataCollectorTest, OnMainFrameRequest) { | |
| 507 URLRequestSummary summary1 = CreateURLRequestSummary( | |
| 508 1, "http://www.google.com", "http://www.google.com", | |
| 509 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); | |
| 510 URLRequestSummary summary2 = CreateURLRequestSummary( | |
| 511 2, "http://www.google.com", "http://www.google.com", | |
| 512 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); | |
| 513 URLRequestSummary summary3 = CreateURLRequestSummary( | |
| 514 3, "http://www.yahoo.com", "http://www.yahoo.com", | |
| 515 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); | |
| 516 | |
| 517 collector_->RecordURLRequest(summary1); | |
| 518 EXPECT_EQ(1U, collector_->inflight_navigations_.size()); | |
| 519 collector_->RecordURLRequest(summary2); | |
| 520 EXPECT_EQ(2U, collector_->inflight_navigations_.size()); | |
| 521 collector_->RecordURLRequest(summary3); | |
| 522 EXPECT_EQ(3U, collector_->inflight_navigations_.size()); | |
| 523 | |
| 524 // Insert another with same navigation id. It should replace. | |
| 525 URLRequestSummary summary4 = CreateURLRequestSummary( | |
| 526 1, "http://www.nike.com", "http://www.nike.com", | |
| 527 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); | |
| 528 URLRequestSummary summary5 = CreateURLRequestSummary( | |
| 529 2, "http://www.google.com", "http://www.google.com", | |
| 530 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); | |
| 531 | |
| 532 collector_->RecordURLRequest(summary4); | |
| 533 EXPECT_EQ(3U, collector_->inflight_navigations_.size()); | |
| 534 | |
| 535 // Change this creation time so that it will go away on the next insert. | |
| 536 summary5.navigation_id.creation_time = | |
| 537 base::TimeTicks::Now() - base::TimeDelta::FromDays(1); | |
| 538 collector_->RecordURLRequest(summary5); | |
| 539 EXPECT_EQ(3U, collector_->inflight_navigations_.size()); | |
| 540 | |
| 541 URLRequestSummary summary6 = CreateURLRequestSummary( | |
| 542 4, "http://www.shoes.com", "http://www.shoes.com", | |
| 543 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); | |
| 544 collector_->RecordURLRequest(summary6); | |
| 545 EXPECT_EQ(3U, collector_->inflight_navigations_.size()); | |
| 546 | |
| 547 EXPECT_TRUE(collector_->inflight_navigations_.find(summary3.navigation_id) != | |
| 548 collector_->inflight_navigations_.end()); | |
| 549 EXPECT_TRUE(collector_->inflight_navigations_.find(summary4.navigation_id) != | |
| 550 collector_->inflight_navigations_.end()); | |
| 551 EXPECT_TRUE(collector_->inflight_navigations_.find(summary6.navigation_id) != | |
| 552 collector_->inflight_navigations_.end()); | |
| 553 } | |
| 554 | |
| 555 TEST_F(LoadingDataCollectorTest, OnMainFrameRedirect) { | |
| 556 URLRequestSummary yahoo = CreateURLRequestSummary(1, "http://yahoo.com"); | |
| 557 | |
| 558 URLRequestSummary bbc1 = CreateURLRequestSummary(2, "http://bbc.com"); | |
| 559 URLRequestSummary bbc2 = | |
| 560 CreateRedirectRequestSummary(2, "http://bbc.com", "https://www.bbc.com"); | |
| 561 NavigationID bbc_end = CreateNavigationID(2, "https://www.bbc.com"); | |
| 562 | |
| 563 URLRequestSummary youtube1 = CreateURLRequestSummary(3, "http://youtube.com"); | |
| 564 URLRequestSummary youtube2 = CreateRedirectRequestSummary( | |
| 565 3, "http://youtube.com", "https://youtube.com"); | |
| 566 NavigationID youtube_end = CreateNavigationID(3, "https://youtube.com"); | |
| 567 | |
| 568 URLRequestSummary nyt1 = CreateURLRequestSummary(4, "http://nyt.com"); | |
| 569 URLRequestSummary nyt2 = | |
| 570 CreateRedirectRequestSummary(4, "http://nyt.com", "http://nytimes.com"); | |
| 571 URLRequestSummary nyt3 = CreateRedirectRequestSummary(4, "http://nytimes.com", | |
| 572 "http://m.nytimes.com"); | |
| 573 NavigationID nyt_end = CreateNavigationID(4, "http://m.nytimes.com"); | |
| 574 | |
| 575 URLRequestSummary fb1 = CreateURLRequestSummary(5, "http://fb.com"); | |
| 576 URLRequestSummary fb2 = | |
| 577 CreateRedirectRequestSummary(5, "http://fb.com", "http://facebook.com"); | |
| 578 URLRequestSummary fb3 = CreateRedirectRequestSummary(5, "http://facebook.com", | |
| 579 "https://facebook.com"); | |
| 580 URLRequestSummary fb4 = CreateRedirectRequestSummary( | |
| 581 5, "https://facebook.com", | |
| 582 "https://m.facebook.com/?refsrc=https%3A%2F%2Fwww.facebook.com%2F&_rdr"); | |
| 583 NavigationID fb_end = CreateNavigationID( | |
| 584 5, | |
| 585 "https://m.facebook.com/?refsrc=https%3A%2F%2Fwww.facebook.com%2F&_rdr"); | |
| 586 | |
| 587 // Redirect with empty redirect_url will be deleted. | |
| 588 collector_->RecordURLRequest(yahoo); | |
| 589 EXPECT_EQ(1U, collector_->inflight_navigations_.size()); | |
| 590 collector_->OnMainFrameRedirect(yahoo); | |
| 591 EXPECT_TRUE(collector_->inflight_navigations_.empty()); | |
| 592 | |
| 593 // Redirect without previous request works fine. | |
| 594 // collector_->RecordURLRequest(bbc1) missing. | |
| 595 collector_->OnMainFrameRedirect(bbc2); | |
| 596 EXPECT_EQ(1U, collector_->inflight_navigations_.size()); | |
| 597 EXPECT_EQ(bbc1.navigation_id.main_frame_url, | |
| 598 collector_->inflight_navigations_[bbc_end]->initial_url); | |
| 599 | |
| 600 // http://youtube.com -> https://youtube.com. | |
| 601 collector_->RecordURLRequest(youtube1); | |
| 602 EXPECT_EQ(2U, collector_->inflight_navigations_.size()); | |
| 603 collector_->OnMainFrameRedirect(youtube2); | |
| 604 EXPECT_EQ(2U, collector_->inflight_navigations_.size()); | |
| 605 EXPECT_EQ(youtube1.navigation_id.main_frame_url, | |
| 606 collector_->inflight_navigations_[youtube_end]->initial_url); | |
| 607 | |
| 608 // http://nyt.com -> http://nytimes.com -> http://m.nytimes.com. | |
| 609 collector_->RecordURLRequest(nyt1); | |
| 610 EXPECT_EQ(3U, collector_->inflight_navigations_.size()); | |
| 611 collector_->OnMainFrameRedirect(nyt2); | |
| 612 collector_->OnMainFrameRedirect(nyt3); | |
| 613 EXPECT_EQ(3U, collector_->inflight_navigations_.size()); | |
| 614 EXPECT_EQ(nyt1.navigation_id.main_frame_url, | |
| 615 collector_->inflight_navigations_[nyt_end]->initial_url); | |
| 616 | |
| 617 // http://fb.com -> http://facebook.com -> https://facebook.com -> | |
| 618 // https://m.facebook.com/?refsrc=https%3A%2F%2Fwww.facebook.com%2F&_rdr. | |
| 619 collector_->RecordURLRequest(fb1); | |
| 620 EXPECT_EQ(4U, collector_->inflight_navigations_.size()); | |
| 621 collector_->OnMainFrameRedirect(fb2); | |
| 622 collector_->OnMainFrameRedirect(fb3); | |
| 623 collector_->OnMainFrameRedirect(fb4); | |
| 624 EXPECT_EQ(4U, collector_->inflight_navigations_.size()); | |
| 625 EXPECT_EQ(fb1.navigation_id.main_frame_url, | |
| 626 collector_->inflight_navigations_[fb_end]->initial_url); | |
| 627 } | |
| 628 | |
| 629 TEST_F(LoadingDataCollectorTest, OnSubresourceResponse) { | |
| 630 // If there is no inflight navigation, nothing happens. | |
| 631 URLRequestSummary resource1 = CreateURLRequestSummary( | |
| 632 1, "http://www.google.com", "http://google.com/style1.css", | |
| 633 content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", false); | |
| 634 collector_->RecordURLResponse(resource1); | |
| 635 EXPECT_TRUE(collector_->inflight_navigations_.empty()); | |
| 636 | |
| 637 // Add an inflight navigation. | |
| 638 URLRequestSummary main_frame1 = CreateURLRequestSummary( | |
| 639 1, "http://www.google.com", "http://www.google.com", | |
| 640 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); | |
| 641 collector_->RecordURLRequest(main_frame1); | |
| 642 EXPECT_EQ(1U, collector_->inflight_navigations_.size()); | |
| 643 | |
| 644 // Now add a few subresources. | |
| 645 URLRequestSummary resource2 = CreateURLRequestSummary( | |
| 646 1, "http://www.google.com", "http://google.com/script1.js", | |
| 647 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false); | |
| 648 URLRequestSummary resource3 = CreateURLRequestSummary( | |
| 649 1, "http://www.google.com", "http://google.com/script2.js", | |
| 650 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false); | |
| 651 collector_->RecordURLResponse(resource1); | |
| 652 collector_->RecordURLResponse(resource2); | |
| 653 collector_->RecordURLResponse(resource3); | |
| 654 | |
| 655 EXPECT_EQ(1U, collector_->inflight_navigations_.size()); | |
| 656 EXPECT_EQ(3U, collector_->inflight_navigations_[main_frame1.navigation_id] | |
| 657 ->subresource_requests.size()); | |
| 658 EXPECT_EQ(resource1, | |
| 659 collector_->inflight_navigations_[main_frame1.navigation_id] | |
| 660 ->subresource_requests[0]); | |
| 661 EXPECT_EQ(resource2, | |
| 662 collector_->inflight_navigations_[main_frame1.navigation_id] | |
| 663 ->subresource_requests[1]); | |
| 664 EXPECT_EQ(resource3, | |
| 665 collector_->inflight_navigations_[main_frame1.navigation_id] | |
| 666 ->subresource_requests[2]); | |
| 667 } | |
| 668 | |
| 669 TEST_F(LoadingDataCollectorTest, TestRecordFirstContentfulPaint) { | |
| 670 auto res1_time = base::TimeTicks::FromInternalValue(1); | |
| 671 auto res2_time = base::TimeTicks::FromInternalValue(2); | |
| 672 auto fcp_time = base::TimeTicks::FromInternalValue(3); | |
| 673 auto res3_time = base::TimeTicks::FromInternalValue(4); | |
| 674 | |
| 675 URLRequestSummary main_frame = | |
| 676 CreateURLRequestSummary(1, "http://www.google.com"); | |
| 677 collector_->RecordURLRequest(main_frame); | |
| 678 EXPECT_EQ(1U, collector_->inflight_navigations_.size()); | |
| 679 | |
| 680 URLRequestSummary resource1 = CreateURLRequestSummary( | |
| 681 1, "http://www.google.com", "http://google.com/style1.css", | |
| 682 content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", false); | |
| 683 resource1.response_time = res1_time; | |
| 684 collector_->RecordURLResponse(resource1); | |
| 685 URLRequestSummary resource2 = CreateURLRequestSummary( | |
| 686 1, "http://www.google.com", "http://google.com/script1.js", | |
| 687 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false); | |
| 688 resource2.response_time = res2_time; | |
| 689 collector_->RecordURLResponse(resource2); | |
| 690 URLRequestSummary resource3 = CreateURLRequestSummary( | |
| 691 1, "http://www.google.com", "http://google.com/script2.js", | |
| 692 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false); | |
| 693 resource3.response_time = res3_time; | |
| 694 collector_->RecordURLResponse(resource3); | |
| 695 | |
| 696 collector_->RecordFirstContentfulPaint(main_frame.navigation_id, fcp_time); | |
| 697 | |
| 698 // Since res3_time is after fcp_time, we expect this field to have been set to | |
| 699 // false before RecordPageRequestSummary is called. | |
| 700 resource3.before_first_contentful_paint = false; | |
| 701 EXPECT_CALL( | |
| 702 *mock_predictor_, | |
| 703 RecordPageRequestSummaryProxy(testing::Pointee(CreatePageRequestSummary( | |
| 704 "http://www.google.com", "http://www.google.com", | |
| 705 std::vector<URLRequestSummary>{resource1, resource2, resource3})))); | |
| 706 | |
| 707 collector_->RecordMainFrameLoadComplete(main_frame.navigation_id); | |
| 708 } | |
| 709 | |
| 230 } // namespace predictors | 710 } // namespace predictors |
| OLD | NEW |