| 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_config.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" |
| 16 #include "content/public/test/test_browser_thread_bundle.h" | 17 #include "content/public/test/test_browser_thread_bundle.h" |
| 17 #include "net/http/http_response_headers.h" | 18 #include "net/http/http_response_headers.h" |
| 18 #include "net/url_request/url_request_context.h" | 19 #include "net/url_request/url_request_context.h" |
| 19 #include "net/url_request/url_request_job.h" | 20 #include "net/url_request/url_request_job.h" |
| 20 #include "testing/gmock/include/gmock/gmock.h" | 21 #include "testing/gmock/include/gmock/gmock.h" |
| 21 #include "testing/gtest/include/gtest/gtest.h" | 22 #include "testing/gtest/include/gtest/gtest.h" |
| 22 | 23 |
| 23 using testing::StrictMock; | 24 using testing::StrictMock; |
| 24 | 25 |
| 25 namespace predictors { | 26 namespace predictors { |
| 26 | 27 |
| 27 class LoadingDataCollectorTest : public testing::Test { | 28 class LoadingDataCollectorTest : public testing::Test { |
| 28 public: | 29 public: |
| 30 LoadingDataCollectorTest() : profile_(new TestingProfile()) { |
| 31 LoadingPredictorConfig config; |
| 32 PopulateTestConfig(&config); |
| 33 mock_predictor_ = |
| 34 base::MakeUnique<StrictMock<MockResourcePrefetchPredictor>>( |
| 35 config, profile_.get()), |
| 36 collector_ = base::MakeUnique<LoadingDataCollector>(mock_predictor_.get(), |
| 37 nullptr, config); |
| 38 } |
| 39 |
| 29 void SetUp() override { | 40 void SetUp() override { |
| 41 base::RunLoop().RunUntilIdle(); // Runs the DB lookup. |
| 42 |
| 30 url_request_job_factory_.Reset(); | 43 url_request_job_factory_.Reset(); |
| 31 url_request_context_.set_job_factory(&url_request_job_factory_); | 44 url_request_context_.set_job_factory(&url_request_job_factory_); |
| 32 } | 45 } |
| 33 | 46 |
| 34 protected: | 47 protected: |
| 35 content::TestBrowserThreadBundle thread_bundle_; | 48 content::TestBrowserThreadBundle thread_bundle_; |
| 49 std::unique_ptr<TestingProfile> profile_; |
| 36 net::TestURLRequestContext url_request_context_; | 50 net::TestURLRequestContext url_request_context_; |
| 37 MockURLRequestJobFactory url_request_job_factory_; | 51 MockURLRequestJobFactory url_request_job_factory_; |
| 52 |
| 53 std::unique_ptr<StrictMock<MockResourcePrefetchPredictor>> mock_predictor_; |
| 54 std::unique_ptr<LoadingDataCollector> collector_; |
| 38 }; | 55 }; |
| 39 | 56 |
| 57 TEST_F(LoadingDataCollectorTest, SummarizeResponse) { |
| 58 net::HttpResponseInfo response_info; |
| 59 response_info.headers = |
| 60 MakeResponseHeaders("HTTP/1.1 200 OK\n\nSome: Headers\n"); |
| 61 response_info.was_cached = true; |
| 62 url_request_job_factory_.set_response_info(response_info); |
| 63 |
| 64 GURL url("http://www.google.com/cat.png"); |
| 65 std::unique_ptr<net::URLRequest> request = |
| 66 CreateURLRequest(url_request_context_, url, net::MEDIUM, |
| 67 content::RESOURCE_TYPE_IMAGE, true); |
| 68 URLRequestSummary summary; |
| 69 EXPECT_TRUE(URLRequestSummary::SummarizeResponse(*request, &summary)); |
| 70 EXPECT_EQ(url, summary.resource_url); |
| 71 EXPECT_EQ(content::RESOURCE_TYPE_IMAGE, summary.resource_type); |
| 72 EXPECT_TRUE(summary.was_cached); |
| 73 EXPECT_FALSE(summary.has_validators); |
| 74 EXPECT_FALSE(summary.always_revalidate); |
| 75 |
| 76 // Navigation_id elements should be unset by default. |
| 77 EXPECT_EQ(-1, summary.navigation_id.tab_id); |
| 78 EXPECT_EQ(GURL(), summary.navigation_id.main_frame_url); |
| 79 } |
| 80 |
| 81 TEST_F(LoadingDataCollectorTest, SummarizeResponseContentType) { |
| 82 net::HttpResponseInfo response_info; |
| 83 response_info.headers = MakeResponseHeaders( |
| 84 "HTTP/1.1 200 OK\n\n" |
| 85 "Some: Headers\n" |
| 86 "Content-Type: image/whatever\n"); |
| 87 url_request_job_factory_.set_response_info(response_info); |
| 88 url_request_job_factory_.set_mime_type("image/png"); |
| 89 |
| 90 std::unique_ptr<net::URLRequest> request = CreateURLRequest( |
| 91 url_request_context_, GURL("http://www.google.com/cat.png"), net::MEDIUM, |
| 92 content::RESOURCE_TYPE_PREFETCH, true); |
| 93 URLRequestSummary summary; |
| 94 EXPECT_TRUE(URLRequestSummary::SummarizeResponse(*request, &summary)); |
| 95 EXPECT_EQ(content::RESOURCE_TYPE_IMAGE, summary.resource_type); |
| 96 } |
| 97 |
| 98 TEST_F(LoadingDataCollectorTest, SummarizeResponseCachePolicy) { |
| 99 net::HttpResponseInfo response_info; |
| 100 response_info.headers = MakeResponseHeaders( |
| 101 "HTTP/1.1 200 OK\n" |
| 102 "Some: Headers\n"); |
| 103 url_request_job_factory_.set_response_info(response_info); |
| 104 |
| 105 std::unique_ptr<net::URLRequest> request_no_validators = CreateURLRequest( |
| 106 url_request_context_, GURL("http://www.google.com/cat.png"), net::MEDIUM, |
| 107 content::RESOURCE_TYPE_PREFETCH, true); |
| 108 |
| 109 URLRequestSummary summary; |
| 110 EXPECT_TRUE( |
| 111 URLRequestSummary::SummarizeResponse(*request_no_validators, &summary)); |
| 112 EXPECT_FALSE(summary.has_validators); |
| 113 |
| 114 response_info.headers = MakeResponseHeaders( |
| 115 "HTTP/1.1 200 OK\n" |
| 116 "ETag: \"Cr66\"\n" |
| 117 "Cache-Control: no-cache\n"); |
| 118 url_request_job_factory_.set_response_info(response_info); |
| 119 std::unique_ptr<net::URLRequest> request_etag = CreateURLRequest( |
| 120 url_request_context_, GURL("http://www.google.com/cat.png"), net::MEDIUM, |
| 121 content::RESOURCE_TYPE_PREFETCH, true); |
| 122 EXPECT_TRUE(URLRequestSummary::SummarizeResponse(*request_etag, &summary)); |
| 123 EXPECT_TRUE(summary.has_validators); |
| 124 EXPECT_TRUE(summary.always_revalidate); |
| 125 } |
| 126 |
| 40 TEST_F(LoadingDataCollectorTest, HandledResourceTypes) { | 127 TEST_F(LoadingDataCollectorTest, HandledResourceTypes) { |
| 41 EXPECT_TRUE(LoadingDataCollector::IsHandledResourceType( | 128 EXPECT_TRUE(LoadingDataCollector::IsHandledResourceType( |
| 42 content::RESOURCE_TYPE_STYLESHEET, "bogus/mime-type")); | 129 content::RESOURCE_TYPE_STYLESHEET, "bogus/mime-type")); |
| 43 EXPECT_TRUE(LoadingDataCollector::IsHandledResourceType( | 130 EXPECT_TRUE(LoadingDataCollector::IsHandledResourceType( |
| 44 content::RESOURCE_TYPE_STYLESHEET, "")); | 131 content::RESOURCE_TYPE_STYLESHEET, "")); |
| 45 EXPECT_FALSE(LoadingDataCollector::IsHandledResourceType( | 132 EXPECT_FALSE(LoadingDataCollector::IsHandledResourceType( |
| 46 content::RESOURCE_TYPE_WORKER, "text/css")); | 133 content::RESOURCE_TYPE_WORKER, "text/css")); |
| 47 EXPECT_FALSE(LoadingDataCollector::IsHandledResourceType( | 134 EXPECT_FALSE(LoadingDataCollector::IsHandledResourceType( |
| 48 content::RESOURCE_TYPE_WORKER, "")); | 135 content::RESOURCE_TYPE_WORKER, "")); |
| 49 EXPECT_TRUE(LoadingDataCollector::IsHandledResourceType( | 136 EXPECT_TRUE(LoadingDataCollector::IsHandledResourceType( |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 220 prefetch_unknown_font_request.get())); | 307 prefetch_unknown_font_request.get())); |
| 221 | 308 |
| 222 // Not main frame. | 309 // Not main frame. |
| 223 std::unique_ptr<net::URLRequest> font_request_sub_frame = CreateURLRequest( | 310 std::unique_ptr<net::URLRequest> font_request_sub_frame = CreateURLRequest( |
| 224 url_request_context_, GURL("http://www.google.com/comic-sans-ms.woff"), | 311 url_request_context_, GURL("http://www.google.com/comic-sans-ms.woff"), |
| 225 net::MEDIUM, content::RESOURCE_TYPE_FONT_RESOURCE, false); | 312 net::MEDIUM, content::RESOURCE_TYPE_FONT_RESOURCE, false); |
| 226 EXPECT_FALSE( | 313 EXPECT_FALSE( |
| 227 LoadingDataCollector::ShouldRecordResponse(font_request_sub_frame.get())); | 314 LoadingDataCollector::ShouldRecordResponse(font_request_sub_frame.get())); |
| 228 } | 315 } |
| 229 | 316 |
| 317 // Single navigation that will be recorded. Will check for duplicate |
| 318 // resources and also for number of resources saved. |
| 319 TEST_F(LoadingDataCollectorTest, SimpleNavigation) { |
| 320 URLRequestSummary main_frame = |
| 321 CreateURLRequestSummary(1, "http://www.google.com"); |
| 322 collector_->RecordURLRequest(main_frame); |
| 323 EXPECT_EQ(1U, collector_->inflight_navigations_.size()); |
| 324 |
| 325 std::vector<URLRequestSummary> resources; |
| 326 resources.push_back(CreateURLRequestSummary( |
| 327 1, "http://www.google.com", "http://google.com/style1.css", |
| 328 content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", false)); |
| 329 collector_->RecordURLResponse(resources.back()); |
| 330 resources.push_back(CreateURLRequestSummary( |
| 331 1, "http://www.google.com", "http://google.com/script1.js", |
| 332 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false)); |
| 333 collector_->RecordURLResponse(resources.back()); |
| 334 resources.push_back(CreateURLRequestSummary( |
| 335 1, "http://www.google.com", "http://google.com/script2.js", |
| 336 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false)); |
| 337 collector_->RecordURLResponse(resources.back()); |
| 338 resources.push_back(CreateURLRequestSummary( |
| 339 1, "http://www.google.com", "http://google.com/script1.js", |
| 340 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", true)); |
| 341 collector_->RecordURLResponse(resources.back()); |
| 342 resources.push_back(CreateURLRequestSummary( |
| 343 1, "http://www.google.com", "http://google.com/image1.png", |
| 344 content::RESOURCE_TYPE_IMAGE, net::MEDIUM, "image/png", false)); |
| 345 collector_->RecordURLResponse(resources.back()); |
| 346 resources.push_back(CreateURLRequestSummary( |
| 347 1, "http://www.google.com", "http://google.com/image2.png", |
| 348 content::RESOURCE_TYPE_IMAGE, net::MEDIUM, "image/png", false)); |
| 349 collector_->RecordURLResponse(resources.back()); |
| 350 resources.push_back(CreateURLRequestSummary( |
| 351 1, "http://www.google.com", "http://google.com/style2.css", |
| 352 content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", true)); |
| 353 collector_->RecordURLResponse(resources.back()); |
| 354 |
| 355 auto no_store = CreateURLRequestSummary( |
| 356 1, "http://www.google.com", |
| 357 "http://static.google.com/style2-no-store.css", |
| 358 content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", true); |
| 359 no_store.is_no_store = true; |
| 360 collector_->RecordURLResponse(no_store); |
| 361 |
| 362 auto redirected = CreateURLRequestSummary( |
| 363 1, "http://www.google.com", "http://reader.google.com/style.css", |
| 364 content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", true); |
| 365 redirected.redirect_url = GURL("http://dev.null.google.com/style.css"); |
| 366 collector_->RecordURLRedirect(redirected); |
| 367 |
| 368 auto summary = CreatePageRequestSummary("http://www.google.com", |
| 369 "http://www.google.com", resources); |
| 370 summary.UpdateOrAddToOrigins(no_store); |
| 371 summary.UpdateOrAddToOrigins(redirected); |
| 372 |
| 373 redirected.is_no_store = true; |
| 374 redirected.request_url = redirected.redirect_url; |
| 375 redirected.redirect_url = GURL(); |
| 376 collector_->RecordURLResponse(redirected); |
| 377 summary.UpdateOrAddToOrigins(redirected); |
| 378 |
| 379 EXPECT_CALL(*mock_predictor_, |
| 380 RecordPageRequestSummaryProxy(testing::Pointee(summary))); |
| 381 |
| 382 collector_->RecordMainFrameLoadComplete(main_frame.navigation_id); |
| 383 } |
| 384 |
| 385 TEST_F(LoadingDataCollectorTest, SimpleRedirect) { |
| 386 URLRequestSummary fb1 = CreateURLRequestSummary(1, "http://fb.com/google"); |
| 387 collector_->RecordURLRequest(fb1); |
| 388 EXPECT_EQ(1U, collector_->inflight_navigations_.size()); |
| 389 |
| 390 URLRequestSummary fb2 = CreateRedirectRequestSummary( |
| 391 1, "http://fb.com/google", "http://facebook.com/google"); |
| 392 collector_->RecordURLRedirect(fb2); |
| 393 URLRequestSummary fb3 = CreateRedirectRequestSummary( |
| 394 1, "http://facebook.com/google", "https://facebook.com/google"); |
| 395 collector_->RecordURLRedirect(fb3); |
| 396 NavigationID fb_end = CreateNavigationID(1, "https://facebook.com/google"); |
| 397 |
| 398 EXPECT_CALL( |
| 399 *mock_predictor_, |
| 400 RecordPageRequestSummaryProxy(testing::Pointee(CreatePageRequestSummary( |
| 401 "https://facebook.com/google", "http://fb.com/google", |
| 402 std::vector<URLRequestSummary>())))); |
| 403 |
| 404 collector_->RecordMainFrameLoadComplete(fb_end); |
| 405 } |
| 406 |
| 407 TEST_F(LoadingDataCollectorTest, OnMainFrameRequest) { |
| 408 URLRequestSummary summary1 = CreateURLRequestSummary( |
| 409 1, "http://www.google.com", "http://www.google.com", |
| 410 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); |
| 411 URLRequestSummary summary2 = CreateURLRequestSummary( |
| 412 2, "http://www.google.com", "http://www.google.com", |
| 413 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); |
| 414 URLRequestSummary summary3 = CreateURLRequestSummary( |
| 415 3, "http://www.yahoo.com", "http://www.yahoo.com", |
| 416 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); |
| 417 |
| 418 collector_->RecordURLRequest(summary1); |
| 419 EXPECT_EQ(1U, collector_->inflight_navigations_.size()); |
| 420 collector_->RecordURLRequest(summary2); |
| 421 EXPECT_EQ(2U, collector_->inflight_navigations_.size()); |
| 422 collector_->RecordURLRequest(summary3); |
| 423 EXPECT_EQ(3U, collector_->inflight_navigations_.size()); |
| 424 |
| 425 // Insert another with same navigation id. It should replace. |
| 426 URLRequestSummary summary4 = CreateURLRequestSummary( |
| 427 1, "http://www.nike.com", "http://www.nike.com", |
| 428 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); |
| 429 URLRequestSummary summary5 = CreateURLRequestSummary( |
| 430 2, "http://www.google.com", "http://www.google.com", |
| 431 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); |
| 432 |
| 433 collector_->RecordURLRequest(summary4); |
| 434 EXPECT_EQ(3U, collector_->inflight_navigations_.size()); |
| 435 |
| 436 // Change this creation time so that it will go away on the next insert. |
| 437 summary5.navigation_id.creation_time = |
| 438 base::TimeTicks::Now() - base::TimeDelta::FromDays(1); |
| 439 collector_->RecordURLRequest(summary5); |
| 440 EXPECT_EQ(3U, collector_->inflight_navigations_.size()); |
| 441 |
| 442 URLRequestSummary summary6 = CreateURLRequestSummary( |
| 443 4, "http://www.shoes.com", "http://www.shoes.com", |
| 444 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); |
| 445 collector_->RecordURLRequest(summary6); |
| 446 EXPECT_EQ(3U, collector_->inflight_navigations_.size()); |
| 447 |
| 448 EXPECT_TRUE(collector_->inflight_navigations_.find(summary3.navigation_id) != |
| 449 collector_->inflight_navigations_.end()); |
| 450 EXPECT_TRUE(collector_->inflight_navigations_.find(summary4.navigation_id) != |
| 451 collector_->inflight_navigations_.end()); |
| 452 EXPECT_TRUE(collector_->inflight_navigations_.find(summary6.navigation_id) != |
| 453 collector_->inflight_navigations_.end()); |
| 454 } |
| 455 |
| 456 TEST_F(LoadingDataCollectorTest, OnMainFrameRedirect) { |
| 457 URLRequestSummary yahoo = CreateURLRequestSummary(1, "http://yahoo.com"); |
| 458 |
| 459 URLRequestSummary bbc1 = CreateURLRequestSummary(2, "http://bbc.com"); |
| 460 URLRequestSummary bbc2 = |
| 461 CreateRedirectRequestSummary(2, "http://bbc.com", "https://www.bbc.com"); |
| 462 NavigationID bbc_end = CreateNavigationID(2, "https://www.bbc.com"); |
| 463 |
| 464 URLRequestSummary youtube1 = CreateURLRequestSummary(3, "http://youtube.com"); |
| 465 URLRequestSummary youtube2 = CreateRedirectRequestSummary( |
| 466 3, "http://youtube.com", "https://youtube.com"); |
| 467 NavigationID youtube_end = CreateNavigationID(3, "https://youtube.com"); |
| 468 |
| 469 URLRequestSummary nyt1 = CreateURLRequestSummary(4, "http://nyt.com"); |
| 470 URLRequestSummary nyt2 = |
| 471 CreateRedirectRequestSummary(4, "http://nyt.com", "http://nytimes.com"); |
| 472 URLRequestSummary nyt3 = CreateRedirectRequestSummary(4, "http://nytimes.com", |
| 473 "http://m.nytimes.com"); |
| 474 NavigationID nyt_end = CreateNavigationID(4, "http://m.nytimes.com"); |
| 475 |
| 476 URLRequestSummary fb1 = CreateURLRequestSummary(5, "http://fb.com"); |
| 477 URLRequestSummary fb2 = |
| 478 CreateRedirectRequestSummary(5, "http://fb.com", "http://facebook.com"); |
| 479 URLRequestSummary fb3 = CreateRedirectRequestSummary(5, "http://facebook.com", |
| 480 "https://facebook.com"); |
| 481 URLRequestSummary fb4 = CreateRedirectRequestSummary( |
| 482 5, "https://facebook.com", |
| 483 "https://m.facebook.com/?refsrc=https%3A%2F%2Fwww.facebook.com%2F&_rdr"); |
| 484 NavigationID fb_end = CreateNavigationID( |
| 485 5, |
| 486 "https://m.facebook.com/?refsrc=https%3A%2F%2Fwww.facebook.com%2F&_rdr"); |
| 487 |
| 488 // Redirect with empty redirect_url will be deleted. |
| 489 collector_->RecordURLRequest(yahoo); |
| 490 EXPECT_EQ(1U, collector_->inflight_navigations_.size()); |
| 491 collector_->OnMainFrameRedirect(yahoo); |
| 492 EXPECT_TRUE(collector_->inflight_navigations_.empty()); |
| 493 |
| 494 // Redirect without previous request works fine. |
| 495 // collector_->RecordURLRequest(bbc1) missing. |
| 496 collector_->OnMainFrameRedirect(bbc2); |
| 497 EXPECT_EQ(1U, collector_->inflight_navigations_.size()); |
| 498 EXPECT_EQ(bbc1.navigation_id.main_frame_url, |
| 499 collector_->inflight_navigations_[bbc_end]->initial_url); |
| 500 |
| 501 // http://youtube.com -> https://youtube.com. |
| 502 collector_->RecordURLRequest(youtube1); |
| 503 EXPECT_EQ(2U, collector_->inflight_navigations_.size()); |
| 504 collector_->OnMainFrameRedirect(youtube2); |
| 505 EXPECT_EQ(2U, collector_->inflight_navigations_.size()); |
| 506 EXPECT_EQ(youtube1.navigation_id.main_frame_url, |
| 507 collector_->inflight_navigations_[youtube_end]->initial_url); |
| 508 |
| 509 // http://nyt.com -> http://nytimes.com -> http://m.nytimes.com. |
| 510 collector_->RecordURLRequest(nyt1); |
| 511 EXPECT_EQ(3U, collector_->inflight_navigations_.size()); |
| 512 collector_->OnMainFrameRedirect(nyt2); |
| 513 collector_->OnMainFrameRedirect(nyt3); |
| 514 EXPECT_EQ(3U, collector_->inflight_navigations_.size()); |
| 515 EXPECT_EQ(nyt1.navigation_id.main_frame_url, |
| 516 collector_->inflight_navigations_[nyt_end]->initial_url); |
| 517 |
| 518 // http://fb.com -> http://facebook.com -> https://facebook.com -> |
| 519 // https://m.facebook.com/?refsrc=https%3A%2F%2Fwww.facebook.com%2F&_rdr. |
| 520 collector_->RecordURLRequest(fb1); |
| 521 EXPECT_EQ(4U, collector_->inflight_navigations_.size()); |
| 522 collector_->OnMainFrameRedirect(fb2); |
| 523 collector_->OnMainFrameRedirect(fb3); |
| 524 collector_->OnMainFrameRedirect(fb4); |
| 525 EXPECT_EQ(4U, collector_->inflight_navigations_.size()); |
| 526 EXPECT_EQ(fb1.navigation_id.main_frame_url, |
| 527 collector_->inflight_navigations_[fb_end]->initial_url); |
| 528 } |
| 529 |
| 530 TEST_F(LoadingDataCollectorTest, OnSubresourceResponse) { |
| 531 // If there is no inflight navigation, nothing happens. |
| 532 URLRequestSummary resource1 = CreateURLRequestSummary( |
| 533 1, "http://www.google.com", "http://google.com/style1.css", |
| 534 content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", false); |
| 535 collector_->RecordURLResponse(resource1); |
| 536 EXPECT_TRUE(collector_->inflight_navigations_.empty()); |
| 537 |
| 538 // Add an inflight navigation. |
| 539 URLRequestSummary main_frame1 = CreateURLRequestSummary( |
| 540 1, "http://www.google.com", "http://www.google.com", |
| 541 content::RESOURCE_TYPE_MAIN_FRAME, net::MEDIUM, std::string(), false); |
| 542 collector_->RecordURLRequest(main_frame1); |
| 543 EXPECT_EQ(1U, collector_->inflight_navigations_.size()); |
| 544 |
| 545 // Now add a few subresources. |
| 546 URLRequestSummary resource2 = CreateURLRequestSummary( |
| 547 1, "http://www.google.com", "http://google.com/script1.js", |
| 548 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false); |
| 549 URLRequestSummary resource3 = CreateURLRequestSummary( |
| 550 1, "http://www.google.com", "http://google.com/script2.js", |
| 551 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false); |
| 552 collector_->RecordURLResponse(resource1); |
| 553 collector_->RecordURLResponse(resource2); |
| 554 collector_->RecordURLResponse(resource3); |
| 555 |
| 556 EXPECT_EQ(1U, collector_->inflight_navigations_.size()); |
| 557 EXPECT_EQ(3U, collector_->inflight_navigations_[main_frame1.navigation_id] |
| 558 ->subresource_requests.size()); |
| 559 EXPECT_EQ(resource1, |
| 560 collector_->inflight_navigations_[main_frame1.navigation_id] |
| 561 ->subresource_requests[0]); |
| 562 EXPECT_EQ(resource2, |
| 563 collector_->inflight_navigations_[main_frame1.navigation_id] |
| 564 ->subresource_requests[1]); |
| 565 EXPECT_EQ(resource3, |
| 566 collector_->inflight_navigations_[main_frame1.navigation_id] |
| 567 ->subresource_requests[2]); |
| 568 } |
| 569 |
| 570 TEST_F(LoadingDataCollectorTest, TestRecordFirstContentfulPaint) { |
| 571 auto res1_time = base::TimeTicks::FromInternalValue(1); |
| 572 auto res2_time = base::TimeTicks::FromInternalValue(2); |
| 573 auto fcp_time = base::TimeTicks::FromInternalValue(3); |
| 574 auto res3_time = base::TimeTicks::FromInternalValue(4); |
| 575 |
| 576 URLRequestSummary main_frame = |
| 577 CreateURLRequestSummary(1, "http://www.google.com"); |
| 578 collector_->RecordURLRequest(main_frame); |
| 579 EXPECT_EQ(1U, collector_->inflight_navigations_.size()); |
| 580 |
| 581 URLRequestSummary resource1 = CreateURLRequestSummary( |
| 582 1, "http://www.google.com", "http://google.com/style1.css", |
| 583 content::RESOURCE_TYPE_STYLESHEET, net::MEDIUM, "text/css", false); |
| 584 resource1.response_time = res1_time; |
| 585 collector_->RecordURLResponse(resource1); |
| 586 URLRequestSummary resource2 = CreateURLRequestSummary( |
| 587 1, "http://www.google.com", "http://google.com/script1.js", |
| 588 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false); |
| 589 resource2.response_time = res2_time; |
| 590 collector_->RecordURLResponse(resource2); |
| 591 URLRequestSummary resource3 = CreateURLRequestSummary( |
| 592 1, "http://www.google.com", "http://google.com/script2.js", |
| 593 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM, "text/javascript", false); |
| 594 resource3.response_time = res3_time; |
| 595 collector_->RecordURLResponse(resource3); |
| 596 |
| 597 collector_->RecordFirstContentfulPaint(main_frame.navigation_id, fcp_time); |
| 598 |
| 599 // Since res3_time is after fcp_time, we expect this field to have been set to |
| 600 // false before RecordPageRequestSummary is called. |
| 601 resource3.before_first_contentful_paint = false; |
| 602 EXPECT_CALL( |
| 603 *mock_predictor_, |
| 604 RecordPageRequestSummaryProxy(testing::Pointee(CreatePageRequestSummary( |
| 605 "http://www.google.com", "http://www.google.com", |
| 606 {resource1, resource2, resource3})))); |
| 607 |
| 608 collector_->RecordMainFrameLoadComplete(main_frame.navigation_id); |
| 609 } |
| 610 |
| 230 } // namespace predictors | 611 } // namespace predictors |
| OLD | NEW |