blob: 09e43b0d49e6488a421c1e077a6d54fb9ab1ed9c [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/page_load_metrics/observers/subresource_loading_page_load_metrics_observer.h"
#include <memory>
#include "base/command_line.h"
#include "chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h"
#include "components/page_load_metrics/browser/page_load_tracker.h"
#include "components/page_load_metrics/common/page_load_timing.h"
#include "components/page_load_metrics/common/test/page_load_metrics_test_util.h"
namespace {
const GURL kTestUrl("https://chromium.org");
page_load_metrics::mojom::ResourceDataUpdatePtr CreateBaseResource(
bool was_cached,
bool is_complete) {
return CreateResource(was_cached, 1234 /* delta_bytes */,
1234 /* encoded_body_length */, is_complete);
}
} // namespace
class SubresourceLoadingPageLoadMetricsObserverTest
: public page_load_metrics::PageLoadMetricsObserverTestHarness {
public:
SubresourceLoadingPageLoadMetricsObserverTest() = default;
void set_navigation_url(const GURL& url) { navigation_url_ = url; }
void set_in_main_frame(bool in_main_frame) { in_main_frame_ = in_main_frame; }
void StartTest(bool data_saver_enabled) {
ResetTest();
if (data_saver_enabled) {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
data_reduction_proxy::switches::kEnableDataReductionProxy);
}
NavigateAndCommit(navigation_url_);
SimulateTimingUpdate(timing_);
}
page_load_metrics::mojom::ResourceDataUpdatePtr CreateCSSResource(
bool was_cached,
bool is_complete,
bool completed_before_fcp) {
page_load_metrics::mojom::ResourceDataUpdatePtr update =
CreateBaseResource(was_cached, is_complete);
update->mime_type = "text/css";
update->is_main_frame_resource = in_main_frame_;
update->completed_before_fcp = completed_before_fcp;
return update;
}
page_load_metrics::mojom::ResourceDataUpdatePtr CreateJSResource(
bool was_cached,
bool is_complete,
bool completed_before_fcp) {
page_load_metrics::mojom::ResourceDataUpdatePtr update =
CreateBaseResource(was_cached, is_complete);
update->mime_type = "text/javascript";
update->is_main_frame_resource = in_main_frame_;
update->completed_before_fcp = completed_before_fcp;
return update;
}
page_load_metrics::mojom::ResourceDataUpdatePtr CreateOtherResource(
bool was_cached,
bool is_complete,
bool completed_before_fcp) {
page_load_metrics::mojom::ResourceDataUpdatePtr update =
CreateBaseResource(was_cached, is_complete);
update->mime_type = "other";
update->is_main_frame_resource = in_main_frame_;
update->completed_before_fcp = completed_before_fcp;
return update;
}
protected:
void RegisterObservers(page_load_metrics::PageLoadTracker* tracker) override {
tracker->AddObserver(
std::make_unique<SubresourceLoadingPageLoadMetricsObserver>());
}
private:
void ResetTest() {
page_load_metrics::InitPageLoadTimingForTest(&timing_);
timing_.navigation_start = base::Time::FromDoubleT(2);
timing_.response_start = base::TimeDelta::FromSeconds(3);
timing_.parse_timing->parse_start = base::TimeDelta::FromSeconds(4);
timing_.paint_timing->first_contentful_paint =
base::TimeDelta::FromSeconds(5);
timing_.paint_timing->first_image_paint = base::TimeDelta::FromSeconds(6);
timing_.document_timing->load_event_start = base::TimeDelta::FromSeconds(7);
PopulateRequiredTimingFields(&timing_);
}
page_load_metrics::mojom::PageLoadTiming timing_;
GURL navigation_url_ = kTestUrl;
bool in_main_frame_ = true;
DISALLOW_COPY_AND_ASSIGN(SubresourceLoadingPageLoadMetricsObserverTest);
};
TEST_F(SubresourceLoadingPageLoadMetricsObserverTest, BeforeFCP_CSS) {
StartTest(true /* data_saver_enabled */);
std::vector<page_load_metrics::mojom::ResourceDataUpdatePtr> resources;
resources.push_back(CreateCSSResource(true /* was_cached */,
true /* is_complete */,
true /* completed_before_fcp */));
resources.push_back(CreateCSSResource(true /* was_cached */,
true /* is_complete */,
true /* completed_before_fcp */));
resources.push_back(CreateCSSResource(true /* was_cached */,
true /* is_complete */,
true /* completed_before_fcp */));
resources.push_back(CreateCSSResource(false /* was_cached */,
true /* is_complete */,
true /* completed_before_fcp */));
resources.push_back(CreateCSSResource(false /* was_cached */,
true /* is_complete */,
true /* completed_before_fcp */));
SimulateResourceDataUseUpdate(resources);
NavigateToUntrackedUrl();
histogram_tester().ExpectUniqueSample(
"PageLoad.Clients.SubresourceLoading.LoadedCSSJSBeforeFCP.Noncached", 2,
1);
histogram_tester().ExpectUniqueSample(
"PageLoad.Clients.SubresourceLoading.LoadedCSSJSBeforeFCP.Cached", 3, 1);
}
TEST_F(SubresourceLoadingPageLoadMetricsObserverTest, BeforeFCP_JS) {
StartTest(true /* data_saver_enabled */);
std::vector<page_load_metrics::mojom::ResourceDataUpdatePtr> resources;
resources.push_back(CreateJSResource(true /* was_cached */,
true /* is_complete */,
true /* completed_before_fcp */));
resources.push_back(CreateJSResource(true /* was_cached */,
true /* is_complete */,
true /* completed_before_fcp */));
resources.push_back(CreateJSResource(true /* was_cached */,
true /* is_complete */,
true /* completed_before_fcp */));
resources.push_back(CreateJSResource(false /* was_cached */,
true /* is_complete */,
true /* completed_before_fcp */));
resources.push_back(CreateJSResource(false /* was_cached */,
true /* is_complete */,
true /* completed_before_fcp */));
SimulateResourceDataUseUpdate(resources);
NavigateToUntrackedUrl();
histogram_tester().ExpectUniqueSample(
"PageLoad.Clients.SubresourceLoading.LoadedCSSJSBeforeFCP.Noncached", 2,
1);
histogram_tester().ExpectUniqueSample(
"PageLoad.Clients.SubresourceLoading.LoadedCSSJSBeforeFCP.Cached", 3, 1);
}
TEST_F(SubresourceLoadingPageLoadMetricsObserverTest, BeforeFCP_Other) {
StartTest(true /* data_saver_enabled */);
std::vector<page_load_metrics::mojom::ResourceDataUpdatePtr> resources;
resources.push_back(CreateOtherResource(true /* was_cached */,
true /* is_complete */,
true /* completed_before_fcp */));
resources.push_back(CreateOtherResource(true /* was_cached */,
true /* is_complete */,
true /* completed_before_fcp */));
resources.push_back(CreateOtherResource(true /* was_cached */,
true /* is_complete */,
true /* completed_before_fcp */));
resources.push_back(CreateOtherResource(false /* was_cached */,
true /* is_complete */,
true /* completed_before_fcp */));
resources.push_back(CreateOtherResource(false /* was_cached */,
true /* is_complete */,
true /* completed_before_fcp */));
SimulateResourceDataUseUpdate(resources);
NavigateToUntrackedUrl();
histogram_tester().ExpectUniqueSample(
"PageLoad.Clients.SubresourceLoading.LoadedCSSJSBeforeFCP.Noncached", 0,
1);
histogram_tester().ExpectUniqueSample(
"PageLoad.Clients.SubresourceLoading.LoadedCSSJSBeforeFCP.Cached", 0, 1);
}
TEST_F(SubresourceLoadingPageLoadMetricsObserverTest, BeforeFCP_NotComplete) {
StartTest(true /* data_saver_enabled */);
std::vector<page_load_metrics::mojom::ResourceDataUpdatePtr> resources;
resources.push_back(CreateCSSResource(true /* was_cached */,
false /* is_complete */,
false /* completed_before_fcp */));
resources.push_back(CreateCSSResource(true /* was_cached */,
false /* is_complete */,
false /* completed_before_fcp */));
resources.push_back(CreateCSSResource(true /* was_cached */,
false /* is_complete */,
false /* completed_before_fcp */));
resources.push_back(CreateCSSResource(false /* was_cached */,
false /* is_complete */,
false /* completed_before_fcp */));
resources.push_back(CreateCSSResource(false /* was_cached */,
false /* is_complete */,
false /* completed_before_fcp */));
SimulateResourceDataUseUpdate(resources);
NavigateToUntrackedUrl();
histogram_tester().ExpectUniqueSample(
"PageLoad.Clients.SubresourceLoading.LoadedCSSJSBeforeFCP.Noncached", 0,
1);
histogram_tester().ExpectUniqueSample(
"PageLoad.Clients.SubresourceLoading.LoadedCSSJSBeforeFCP.Cached", 0, 1);
}
TEST_F(SubresourceLoadingPageLoadMetricsObserverTest, BeforeFCP_Subframe) {
StartTest(true /* data_saver_enabled */);
set_in_main_frame(false);
std::vector<page_load_metrics::mojom::ResourceDataUpdatePtr> resources;
resources.push_back(CreateCSSResource(true /* was_cached */,
true /* is_complete */,
true /* completed_before_fcp */));
resources.push_back(CreateCSSResource(true /* was_cached */,
true /* is_complete */,
true /* completed_before_fcp */));
resources.push_back(CreateCSSResource(true /* was_cached */,
true /* is_complete */,
true /* completed_before_fcp */));
resources.push_back(CreateCSSResource(false /* was_cached */,
true /* is_complete */,
true /* completed_before_fcp */));
resources.push_back(CreateCSSResource(false /* was_cached */,
true /* is_complete */,
true /* completed_before_fcp */));
SimulateResourceDataUseUpdate(resources);
NavigateToUntrackedUrl();
histogram_tester().ExpectUniqueSample(
"PageLoad.Clients.SubresourceLoading.LoadedCSSJSBeforeFCP.Noncached", 0,
1);
histogram_tester().ExpectUniqueSample(
"PageLoad.Clients.SubresourceLoading.LoadedCSSJSBeforeFCP.Cached", 0, 1);
}
TEST_F(SubresourceLoadingPageLoadMetricsObserverTest, AfterFCP) {
StartTest(true /* data_saver_enabled */);
std::vector<page_load_metrics::mojom::ResourceDataUpdatePtr> resources;
resources.push_back(CreateCSSResource(true /* was_cached */,
true /* is_complete */,
false /* completed_before_fcp */));
resources.push_back(CreateCSSResource(true /* was_cached */,
true /* is_complete */,
false /* completed_before_fcp */));
resources.push_back(CreateCSSResource(true /* was_cached */,
true /* is_complete */,
false /* completed_before_fcp */));
resources.push_back(CreateCSSResource(false /* was_cached */,
true /* is_complete */,
false /* completed_before_fcp */));
resources.push_back(CreateCSSResource(false /* was_cached */,
true /* is_complete */,
false /* completed_before_fcp */));
SimulateResourceDataUseUpdate(resources);
NavigateToUntrackedUrl();
histogram_tester().ExpectUniqueSample(
"PageLoad.Clients.SubresourceLoading.LoadedCSSJSBeforeFCP.Noncached", 0,
1);
histogram_tester().ExpectUniqueSample(
"PageLoad.Clients.SubresourceLoading.LoadedCSSJSBeforeFCP.Cached", 0, 1);
}
TEST_F(SubresourceLoadingPageLoadMetricsObserverTest, DontRecordForNonHttp) {
set_navigation_url(GURL("chrome://version"));
StartTest(true /* data_saver_enabled */);
std::vector<page_load_metrics::mojom::ResourceDataUpdatePtr> resources;
resources.push_back(CreateCSSResource(true /* was_cached */,
true /* is_complete */,
true /* completed_before_fcp */));
resources.push_back(CreateCSSResource(true /* was_cached */,
true /* is_complete */,
true /* completed_before_fcp */));
resources.push_back(CreateCSSResource(true /* was_cached */,
true /* is_complete */,
true /* completed_before_fcp */));
resources.push_back(CreateCSSResource(false /* was_cached */,
true /* is_complete */,
true /* completed_before_fcp */));
resources.push_back(CreateCSSResource(false /* was_cached */,
true /* is_complete */,
true /* completed_before_fcp */));
SimulateResourceDataUseUpdate(resources);
NavigateToUntrackedUrl();
histogram_tester().ExpectTotalCount(
"PageLoad.Clients.SubresourceLoading.LoadedCSSJSBeforeFCP.Noncached", 0);
histogram_tester().ExpectTotalCount(
"PageLoad.Clients.SubresourceLoading.LoadedCSSJSBeforeFCP.Cached", 0);
}