| // Copyright 2022 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "content/browser/back_forward_cache_test_util.h" |
| |
| #include "base/ranges/algorithm.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| |
| namespace content { |
| |
| namespace { |
| |
| using ::testing::_; |
| using ::testing::Each; |
| using ::testing::ElementsAre; |
| using ::testing::Not; |
| using ::testing::UnorderedElementsAreArray; |
| |
| void AddSampleToBuckets(std::vector<base::Bucket>* buckets, |
| base::HistogramBase::Sample sample) { |
| auto it = base::ranges::find(*buckets, sample, &base::Bucket::min); |
| if (it == buckets->end()) { |
| buckets->push_back(base::Bucket(sample, 1)); |
| } else { |
| it->count++; |
| } |
| } |
| |
| } // namespace |
| |
| BackForwardCacheMetricsTestMatcher::BackForwardCacheMetricsTestMatcher() = |
| default; |
| BackForwardCacheMetricsTestMatcher::~BackForwardCacheMetricsTestMatcher() = |
| default; |
| |
| void BackForwardCacheMetricsTestMatcher::DisableCheckingMetricsForAllSites() { |
| check_all_sites_ = false; |
| } |
| |
| void BackForwardCacheMetricsTestMatcher::ExpectOutcomeDidNotChange( |
| base::Location location) { |
| EXPECT_EQ(expected_outcomes_, |
| histogram_tester().GetAllSamples( |
| "BackForwardCache.HistoryNavigationOutcome")) |
| << location.ToString(); |
| |
| if (!check_all_sites_) |
| return; |
| |
| EXPECT_EQ(expected_outcomes_, |
| histogram_tester().GetAllSamples( |
| "BackForwardCache.AllSites.HistoryNavigationOutcome")) |
| << location.ToString(); |
| |
| std::string is_served_from_bfcache = |
| "BackForwardCache.IsServedFromBackForwardCache"; |
| EXPECT_THAT( |
| ukm_recorder().GetMetrics("HistoryNavigation", {is_served_from_bfcache}), |
| expected_ukm_outcomes_) |
| << location.ToString(); |
| } |
| |
| void BackForwardCacheMetricsTestMatcher::ExpectRestored( |
| base::Location location) { |
| ExpectOutcome(BackForwardCacheMetrics::HistoryNavigationOutcome::kRestored, |
| location); |
| ExpectReasons({}, {}, {}, {}, {}, location); |
| } |
| |
| void BackForwardCacheMetricsTestMatcher::ExpectNotRestored( |
| std::vector<BackForwardCacheMetrics::NotRestoredReason> not_restored, |
| std::vector<blink::scheduler::WebSchedulerTrackedFeature> block_listed, |
| const std::vector<ShouldSwapBrowsingInstance>& not_swapped, |
| const std::vector<BackForwardCache::DisabledReason>& |
| disabled_for_render_frame_host, |
| const std::vector<uint64_t>& disallow_activation, |
| base::Location location) { |
| ExpectOutcome(BackForwardCacheMetrics::HistoryNavigationOutcome::kNotRestored, |
| location); |
| ExpectReasons(not_restored, block_listed, not_swapped, |
| disabled_for_render_frame_host, disallow_activation, location); |
| } |
| |
| void BackForwardCacheMetricsTestMatcher::ExpectNotRestoredDidNotChange( |
| base::Location location) { |
| EXPECT_EQ(expected_not_restored_, |
| histogram_tester().GetAllSamples( |
| "BackForwardCache.HistoryNavigationOutcome." |
| "NotRestoredReason")) |
| << location.ToString(); |
| |
| std::string not_restored_reasons = "BackForwardCache.NotRestoredReasons"; |
| |
| if (!check_all_sites_) |
| return; |
| |
| EXPECT_EQ(expected_not_restored_, |
| histogram_tester().GetAllSamples( |
| "BackForwardCache.AllSites.HistoryNavigationOutcome." |
| "NotRestoredReason")) |
| << location.ToString(); |
| |
| EXPECT_THAT( |
| ukm_recorder().GetMetrics("HistoryNavigation", {not_restored_reasons}), |
| expected_ukm_not_restored_reasons_) |
| << location.ToString(); |
| } |
| |
| void BackForwardCacheMetricsTestMatcher::ExpectBlocklistedFeature( |
| blink::scheduler::WebSchedulerTrackedFeature feature, |
| base::Location location) { |
| ExpectBlocklistedFeatures({feature}, location); |
| } |
| |
| void BackForwardCacheMetricsTestMatcher::ExpectBrowsingInstanceNotSwappedReason( |
| ShouldSwapBrowsingInstance reason, |
| base::Location location) { |
| ExpectBrowsingInstanceNotSwappedReasons({reason}, location); |
| } |
| |
| void BackForwardCacheMetricsTestMatcher::ExpectEvictedAfterCommitted( |
| std::vector<BackForwardCacheMetrics::EvictedAfterDocumentRestoredReason> |
| reasons, |
| base::Location location) { |
| for (BackForwardCacheMetrics::EvictedAfterDocumentRestoredReason reason : |
| reasons) { |
| base::HistogramBase::Sample sample = base::HistogramBase::Sample(reason); |
| AddSampleToBuckets(&expected_eviction_after_committing_, sample); |
| } |
| |
| EXPECT_THAT(histogram_tester().GetAllSamples( |
| "BackForwardCache.EvictedAfterDocumentRestoredReason"), |
| UnorderedElementsAreArray(expected_eviction_after_committing_)) |
| << location.ToString(); |
| if (!check_all_sites_) |
| return; |
| |
| EXPECT_THAT( |
| histogram_tester().GetAllSamples( |
| "BackForwardCache.AllSites.EvictedAfterDocumentRestoredReason"), |
| UnorderedElementsAreArray(expected_eviction_after_committing_)) |
| << location.ToString(); |
| } |
| |
| void BackForwardCacheMetricsTestMatcher::ExpectOutcome( |
| BackForwardCacheMetrics::HistoryNavigationOutcome outcome, |
| base::Location location) { |
| base::HistogramBase::Sample sample = base::HistogramBase::Sample(outcome); |
| AddSampleToBuckets(&expected_outcomes_, sample); |
| |
| EXPECT_THAT(histogram_tester().GetAllSamples( |
| "BackForwardCache.HistoryNavigationOutcome"), |
| UnorderedElementsAreArray(expected_outcomes_)) |
| << location.ToString(); |
| if (!check_all_sites_) |
| return; |
| |
| EXPECT_THAT(histogram_tester().GetAllSamples( |
| "BackForwardCache.AllSites.HistoryNavigationOutcome"), |
| UnorderedElementsAreArray(expected_outcomes_)) |
| << location.ToString(); |
| |
| std::string is_served_from_bfcache = |
| "BackForwardCache.IsServedFromBackForwardCache"; |
| bool ukm_outcome = |
| outcome == BackForwardCacheMetrics::HistoryNavigationOutcome::kRestored; |
| expected_ukm_outcomes_.push_back( |
| {{is_served_from_bfcache, static_cast<int64_t>(ukm_outcome)}}); |
| EXPECT_THAT( |
| ukm_recorder().GetMetrics("HistoryNavigation", {is_served_from_bfcache}), |
| expected_ukm_outcomes_) |
| << location.ToString(); |
| } |
| |
| void BackForwardCacheMetricsTestMatcher::ExpectReasons( |
| std::vector<BackForwardCacheMetrics::NotRestoredReason> not_restored, |
| std::vector<blink::scheduler::WebSchedulerTrackedFeature> block_listed, |
| const std::vector<ShouldSwapBrowsingInstance>& not_swapped, |
| const std::vector<BackForwardCache::DisabledReason>& |
| disabled_for_render_frame_host, |
| const std::vector<uint64_t>& disallow_activation, |
| base::Location location) { |
| // Check that the expected reasons are consistent. |
| bool expect_blocklisted = |
| base::ranges::count( |
| not_restored, |
| BackForwardCacheMetrics::NotRestoredReason::kBlocklistedFeatures) > 0; |
| bool has_blocklisted = block_listed.size() > 0; |
| EXPECT_EQ(expect_blocklisted, has_blocklisted); |
| bool expect_disabled_for_render_frame_host = |
| base::ranges::count(not_restored, |
| BackForwardCacheMetrics::NotRestoredReason:: |
| kDisableForRenderFrameHostCalled) > 0; |
| bool has_disabled_for_render_frame_host = |
| disabled_for_render_frame_host.size() > 0; |
| EXPECT_EQ(expect_disabled_for_render_frame_host, |
| has_disabled_for_render_frame_host); |
| |
| // Check that the reasons are as expected. |
| ExpectNotRestoredReasons(not_restored, location); |
| ExpectBlocklistedFeatures(block_listed, location); |
| ExpectBrowsingInstanceNotSwappedReasons(not_swapped, location); |
| ExpectDisabledWithReasons(disabled_for_render_frame_host, location); |
| ExpectDisallowActivationReasons(disallow_activation, location); |
| } |
| |
| void BackForwardCacheMetricsTestMatcher::ExpectNotRestoredReasons( |
| std::vector<BackForwardCacheMetrics::NotRestoredReason> reasons, |
| base::Location location) { |
| uint64_t not_restored_reasons_bits = 0; |
| for (BackForwardCacheMetrics::NotRestoredReason reason : reasons) { |
| base::HistogramBase::Sample sample = base::HistogramBase::Sample(reason); |
| AddSampleToBuckets(&expected_not_restored_, sample); |
| not_restored_reasons_bits |= 1ull << static_cast<int>(reason); |
| } |
| |
| EXPECT_THAT(histogram_tester().GetAllSamples( |
| "BackForwardCache.HistoryNavigationOutcome." |
| "NotRestoredReason"), |
| UnorderedElementsAreArray(expected_not_restored_)) |
| << location.ToString(); |
| |
| if (!check_all_sites_) |
| return; |
| |
| EXPECT_THAT(histogram_tester().GetAllSamples( |
| "BackForwardCache.AllSites.HistoryNavigationOutcome." |
| "NotRestoredReason"), |
| UnorderedElementsAreArray(expected_not_restored_)) |
| << location.ToString(); |
| |
| std::string not_restored_reasons = "BackForwardCache.NotRestoredReasons"; |
| expected_ukm_not_restored_reasons_.push_back( |
| {{not_restored_reasons, not_restored_reasons_bits}}); |
| EXPECT_THAT( |
| ukm_recorder().GetMetrics("HistoryNavigation", {not_restored_reasons}), |
| expected_ukm_not_restored_reasons_) |
| << location.ToString(); |
| } |
| |
| void BackForwardCacheMetricsTestMatcher::ExpectBlocklistedFeatures( |
| std::vector<blink::scheduler::WebSchedulerTrackedFeature> features, |
| base::Location location) { |
| for (auto feature : features) { |
| base::HistogramBase::Sample sample = base::HistogramBase::Sample(feature); |
| AddSampleToBuckets(&expected_blocklisted_features_, sample); |
| } |
| |
| EXPECT_THAT(histogram_tester().GetAllSamples( |
| "BackForwardCache.HistoryNavigationOutcome." |
| "BlocklistedFeature"), |
| UnorderedElementsAreArray(expected_blocklisted_features_)) |
| << location.ToString(); |
| |
| if (!check_all_sites_) |
| return; |
| |
| EXPECT_THAT(histogram_tester().GetAllSamples( |
| "BackForwardCache.AllSites.HistoryNavigationOutcome." |
| "BlocklistedFeature"), |
| UnorderedElementsAreArray(expected_blocklisted_features_)) |
| << location.ToString(); |
| } |
| |
| void BackForwardCacheMetricsTestMatcher::ExpectDisabledWithReasons( |
| const std::vector<BackForwardCache::DisabledReason>& reasons, |
| base::Location location) { |
| for (BackForwardCache::DisabledReason reason : reasons) { |
| base::HistogramBase::Sample sample = base::HistogramBase::Sample( |
| content::BackForwardCacheMetrics::MetricValue(reason)); |
| AddSampleToBuckets(&expected_disabled_reasons_, sample); |
| } |
| EXPECT_THAT(histogram_tester().GetAllSamples( |
| "BackForwardCache.HistoryNavigationOutcome." |
| "DisabledForRenderFrameHostReason2"), |
| UnorderedElementsAreArray(expected_disabled_reasons_)) |
| << location.ToString(); |
| } |
| |
| void BackForwardCacheMetricsTestMatcher::ExpectDisallowActivationReasons( |
| const std::vector<uint64_t>& reasons, |
| base::Location location) { |
| for (const uint64_t& reason : reasons) { |
| base::HistogramBase::Sample sample(reason); |
| AddSampleToBuckets(&expected_disallow_activation_reasons_, sample); |
| } |
| EXPECT_THAT(histogram_tester().GetAllSamples( |
| "BackForwardCache.HistoryNavigationOutcome." |
| "DisallowActivationReason"), |
| UnorderedElementsAreArray(expected_disallow_activation_reasons_)) |
| << location.ToString(); |
| } |
| |
| void BackForwardCacheMetricsTestMatcher:: |
| ExpectBrowsingInstanceNotSwappedReasons( |
| const std::vector<ShouldSwapBrowsingInstance>& reasons, |
| base::Location location) { |
| for (auto reason : reasons) { |
| base::HistogramBase::Sample sample = base::HistogramBase::Sample(reason); |
| AddSampleToBuckets(&expected_browsing_instance_not_swapped_reasons_, |
| sample); |
| } |
| EXPECT_THAT(histogram_tester().GetAllSamples( |
| "BackForwardCache.HistoryNavigationOutcome." |
| "BrowsingInstanceNotSwappedReason"), |
| UnorderedElementsAreArray( |
| expected_browsing_instance_not_swapped_reasons_)) |
| << location.ToString(); |
| if (!check_all_sites_) |
| return; |
| |
| EXPECT_THAT(histogram_tester().GetAllSamples( |
| "BackForwardCache.AllSites.HistoryNavigationOutcome." |
| "BrowsingInstanceNotSwappedReason"), |
| UnorderedElementsAreArray( |
| expected_browsing_instance_not_swapped_reasons_)) |
| << location.ToString(); |
| } |
| |
| } // namespace content |