| // Copyright 2018 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 "components/previews/content/previews_hints.h" |
| |
| #include <string> |
| |
| #include "base/command_line.h" |
| #include "base/files/file_util.h" |
| #include "base/files/scoped_temp_dir.h" |
| #include "base/test/metrics/histogram_tester.h" |
| #include "base/test/scoped_feature_list.h" |
| #include "components/optimization_guide/hints_component_info.h" |
| #include "components/optimization_guide/proto/hints.pb.h" |
| #include "components/previews/core/previews_features.h" |
| #include "components/previews/core/previews_switches.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "url/gurl.h" |
| |
| namespace previews { |
| |
| namespace { |
| |
| const int kBlackBlacklistBloomFilterNumHashFunctions = 7; |
| const int kBlackBlacklistBloomFilterNumBits = 511; |
| |
| void PopulateBlackBlacklistBloomFilter(BloomFilter* bloom_filter) { |
| bloom_filter->Add("black.com"); |
| } |
| |
| void AddBlacklistBloomFilterToConfig( |
| const BloomFilter& blacklist_bloom_filter, |
| int num_hash_functions, |
| int num_bits, |
| optimization_guide::proto::Configuration* config) { |
| std::string blacklist_data((char*)&blacklist_bloom_filter.bytes()[0], |
| blacklist_bloom_filter.bytes().size()); |
| optimization_guide::proto::OptimizationFilter* blacklist_proto = |
| config->add_optimization_blacklists(); |
| blacklist_proto->set_optimization_type( |
| optimization_guide::proto::LITE_PAGE_REDIRECT); |
| std::unique_ptr<optimization_guide::proto::BloomFilter> bloom_filter_proto = |
| std::make_unique<optimization_guide::proto::BloomFilter>(); |
| bloom_filter_proto->set_num_hash_functions(num_hash_functions); |
| bloom_filter_proto->set_num_bits(num_bits); |
| bloom_filter_proto->set_data(blacklist_data); |
| blacklist_proto->set_allocated_bloom_filter(bloom_filter_proto.release()); |
| } |
| |
| } // namespace |
| |
| class TestHostFilter : public previews::HostFilter { |
| public: |
| explicit TestHostFilter(std::string single_host_match) |
| : HostFilter(nullptr), single_host_match_(single_host_match) {} |
| |
| bool ContainsHostSuffix(const GURL& url) const override { |
| return single_host_match_ == url.host(); |
| } |
| |
| private: |
| std::string single_host_match_; |
| }; |
| |
| class PreviewsHintsTest : public testing::Test { |
| public: |
| PreviewsHintsTest() : previews_hints_(nullptr) {} |
| |
| ~PreviewsHintsTest() override {} |
| |
| void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); } |
| |
| void ParseConfig(const optimization_guide::proto::Configuration& config) { |
| optimization_guide::HintsComponentInfo info( |
| base::Version("1.0"), |
| temp_dir_.GetPath().Append(FILE_PATH_LITERAL("somefile.pb"))); |
| ASSERT_NO_FATAL_FAILURE(WriteConfigToFile(config, info.path)); |
| previews_hints_ = PreviewsHints::CreateFromHintsComponent(info); |
| } |
| |
| PreviewsHints* previews_hints() { return previews_hints_.get(); } |
| |
| bool HasLitePageRedirectBlacklist() { |
| return previews_hints_->lite_page_redirect_blacklist_.get() != nullptr; |
| } |
| |
| private: |
| void WriteConfigToFile(const optimization_guide::proto::Configuration& config, |
| const base::FilePath& filePath) { |
| std::string serialized_config; |
| ASSERT_TRUE(config.SerializeToString(&serialized_config)); |
| ASSERT_EQ(static_cast<int32_t>(serialized_config.length()), |
| base::WriteFile(filePath, serialized_config.data(), |
| serialized_config.length())); |
| } |
| |
| base::ScopedTempDir temp_dir_; |
| std::unique_ptr<PreviewsHints> previews_hints_; |
| }; |
| |
| // NOTE: most of the PreviewsHints tests are still included in the tests for |
| // PreviewsOptimizationGuide. |
| |
| TEST_F(PreviewsHintsTest, FindPageHintForSubstringPagePattern) { |
| optimization_guide::proto::Hint hint1; |
| |
| // Page hint for "/one/" |
| optimization_guide::proto::PageHint* page_hint1 = hint1.add_page_hints(); |
| page_hint1->set_page_pattern("foo.org/*/one/"); |
| |
| // Page hint for "two" |
| optimization_guide::proto::PageHint* page_hint2 = hint1.add_page_hints(); |
| page_hint2->set_page_pattern("two"); |
| |
| // Page hint for "three.jpg" |
| optimization_guide::proto::PageHint* page_hint3 = hint1.add_page_hints(); |
| page_hint3->set_page_pattern("three.jpg"); |
| |
| EXPECT_EQ(nullptr, PreviewsHints::FindPageHint(GURL(""), hint1)); |
| EXPECT_EQ(nullptr, |
| PreviewsHints::FindPageHint(GURL("https://www.foo.org/"), hint1)); |
| EXPECT_EQ(nullptr, PreviewsHints::FindPageHint( |
| GURL("https://www.foo.org/one"), hint1)); |
| |
| EXPECT_EQ(nullptr, PreviewsHints::FindPageHint( |
| GURL("https://www.foo.org/one/"), hint1)); |
| EXPECT_EQ(page_hint1, PreviewsHints::FindPageHint( |
| GURL("https://www.foo.org/pages/one/"), hint1)); |
| EXPECT_EQ(page_hint1, |
| PreviewsHints::FindPageHint( |
| GURL("https://www.foo.org/pages/subpages/one/"), hint1)); |
| EXPECT_EQ(page_hint1, PreviewsHints::FindPageHint( |
| GURL("https://www.foo.org/pages/one/two"), hint1)); |
| EXPECT_EQ(page_hint1, |
| PreviewsHints::FindPageHint( |
| GURL("https://www.foo.org/pages/one/two/three.jpg"), hint1)); |
| |
| EXPECT_EQ(page_hint2, |
| PreviewsHints::FindPageHint( |
| GURL("https://www.foo.org/pages/onetwo/three.jpg"), hint1)); |
| EXPECT_EQ(page_hint2, |
| PreviewsHints::FindPageHint( |
| GURL("https://www.foo.org/one/two/three.jpg"), hint1)); |
| EXPECT_EQ(page_hint2, |
| PreviewsHints::FindPageHint(GURL("https://one.two.org"), hint1)); |
| |
| EXPECT_EQ(page_hint3, PreviewsHints::FindPageHint( |
| GURL("https://www.foo.org/bar/three.jpg"), hint1)); |
| } |
| |
| TEST_F(PreviewsHintsTest, LogHintCacheMatch) { |
| base::test::ScopedFeatureList scoped_list; |
| scoped_list.InitAndEnableFeature(features::kResourceLoadingHints); |
| |
| optimization_guide::proto::Configuration config; |
| optimization_guide::proto::Hint* hint1 = config.add_hints(); |
| hint1->set_key("somedomain.org"); |
| hint1->set_key_representation(optimization_guide::proto::HOST_SUFFIX); |
| optimization_guide::proto::PageHint* page_hint1 = hint1->add_page_hints(); |
| page_hint1->set_page_pattern("/news/"); |
| optimization_guide::proto::Optimization* optimization1 = |
| page_hint1->add_whitelisted_optimizations(); |
| optimization1->set_optimization_type( |
| optimization_guide::proto::RESOURCE_LOADING); |
| optimization_guide::proto::ResourceLoadingHint* resource_loading_hint1 = |
| optimization1->add_resource_loading_hints(); |
| resource_loading_hint1->set_loading_optimization_type( |
| optimization_guide::proto::LOADING_BLOCK_RESOURCE); |
| resource_loading_hint1->set_resource_pattern("news_cruft.js"); |
| ParseConfig(config); |
| |
| base::HistogramTester histogram_tester; |
| |
| // First verify no histogram counts for non-matching URL host. |
| previews_hints()->LogHintCacheMatch( |
| GURL("https://someotherdomain.com/news/story.html"), |
| false /* is_committed */, net::EFFECTIVE_CONNECTION_TYPE_3G); |
| previews_hints()->LogHintCacheMatch( |
| GURL("https://someotherdomain.com/news/story2.html"), |
| true /* is_committed */, net::EFFECTIVE_CONNECTION_TYPE_4G); |
| histogram_tester.ExpectTotalCount( |
| "Previews.OptimizationGuide.HintCache.HasHint.BeforeCommit", 0); |
| histogram_tester.ExpectTotalCount( |
| "Previews.OptimizationGuide.HintCache.HasHint.AtCommit", 0); |
| histogram_tester.ExpectTotalCount( |
| "Previews.OptimizationGuide.HintCache.HintLoaded.AtCommit", 0); |
| histogram_tester.ExpectTotalCount( |
| "Previews.OptimizationGuide.HintCache.PageMatch.AtCommit", 0); |
| |
| // Now verify do have histogram counts for matching URL host. |
| previews_hints()->LogHintCacheMatch( |
| GURL("https://somedomain.org/news/story.html"), false /* is_committed */, |
| net::EFFECTIVE_CONNECTION_TYPE_3G); |
| previews_hints()->LogHintCacheMatch( |
| GURL("https://somedomain.org/news/story2.html"), true /* is_committed */, |
| net::EFFECTIVE_CONNECTION_TYPE_4G); |
| histogram_tester.ExpectBucketCount( |
| "Previews.OptimizationGuide.HintCache.HasHint.BeforeCommit", |
| 4 /* EFFECTIVE_CONNECTION_TYPE_3G */, 1); |
| histogram_tester.ExpectBucketCount( |
| "Previews.OptimizationGuide.HintCache.HasHint.AtCommit", |
| 5 /* EFFECTIVE_CONNECTION_TYPE_4G */, 1); |
| histogram_tester.ExpectBucketCount( |
| "Previews.OptimizationGuide.HintCache.HostMatch.AtCommit", |
| 5 /* EFFECTIVE_CONNECTION_TYPE_4G */, 1); |
| histogram_tester.ExpectBucketCount( |
| "Previews.OptimizationGuide.HintCache.PageMatch.AtCommit", |
| 5 /* EFFECTIVE_CONNECTION_TYPE_4G */, 1); |
| } |
| |
| TEST_F(PreviewsHintsTest, IsBlacklisted) { |
| base::test::ScopedFeatureList scoped_list; |
| scoped_list.InitAndEnableFeature(features::kLitePageServerPreviews); |
| |
| BloomFilter blacklist_bloom_filter(kBlackBlacklistBloomFilterNumHashFunctions, |
| kBlackBlacklistBloomFilterNumBits); |
| PopulateBlackBlacklistBloomFilter(&blacklist_bloom_filter); |
| |
| optimization_guide::proto::Configuration config; |
| AddBlacklistBloomFilterToConfig(blacklist_bloom_filter, |
| kBlackBlacklistBloomFilterNumHashFunctions, |
| kBlackBlacklistBloomFilterNumBits, &config); |
| ParseConfig(config); |
| |
| EXPECT_TRUE(HasLitePageRedirectBlacklist()); |
| EXPECT_FALSE(previews_hints()->IsBlacklisted(GURL("https://black.com/path"), |
| PreviewsType::LOFI)); |
| EXPECT_TRUE(previews_hints()->IsBlacklisted( |
| GURL("https://black.com/path"), PreviewsType::LITE_PAGE_REDIRECT)); |
| EXPECT_TRUE(previews_hints()->IsBlacklisted( |
| GURL("https://joe.black.com/path"), PreviewsType::LITE_PAGE_REDIRECT)); |
| EXPECT_FALSE(previews_hints()->IsBlacklisted( |
| GURL("https://nonblack.com"), PreviewsType::LITE_PAGE_REDIRECT)); |
| } |
| |
| TEST_F(PreviewsHintsTest, IgnoreLitePageRedirectBlacklist) { |
| base::test::ScopedFeatureList scoped_list; |
| scoped_list.InitAndEnableFeature(features::kLitePageServerPreviews); |
| |
| BloomFilter blacklist_bloom_filter(kBlackBlacklistBloomFilterNumHashFunctions, |
| kBlackBlacklistBloomFilterNumBits); |
| PopulateBlackBlacklistBloomFilter(&blacklist_bloom_filter); |
| |
| optimization_guide::proto::Configuration config; |
| AddBlacklistBloomFilterToConfig(blacklist_bloom_filter, |
| kBlackBlacklistBloomFilterNumHashFunctions, |
| kBlackBlacklistBloomFilterNumBits, &config); |
| ParseConfig(config); |
| |
| base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| switches::kIgnoreLitePageRedirectOptimizationBlacklist); |
| |
| EXPECT_FALSE(previews_hints()->IsBlacklisted(GURL("https://black.com/path"), |
| PreviewsType::LOFI)); |
| EXPECT_FALSE(previews_hints()->IsBlacklisted( |
| GURL("https://black.com/path"), PreviewsType::LITE_PAGE_REDIRECT)); |
| EXPECT_FALSE(previews_hints()->IsBlacklisted( |
| GURL("https://joe.black.com/path"), PreviewsType::LITE_PAGE_REDIRECT)); |
| EXPECT_FALSE(previews_hints()->IsBlacklisted( |
| GURL("https://nonblack.com"), PreviewsType::LITE_PAGE_REDIRECT)); |
| } |
| |
| TEST_F(PreviewsHintsTest, ParseConfigWithInsufficientConfigDetails) { |
| base::HistogramTester histogram_tester; |
| base::test::ScopedFeatureList scoped_list; |
| scoped_list.InitAndEnableFeature(features::kLitePageServerPreviews); |
| |
| BloomFilter blacklist_bloom_filter(kBlackBlacklistBloomFilterNumHashFunctions, |
| kBlackBlacklistBloomFilterNumBits); |
| PopulateBlackBlacklistBloomFilter(&blacklist_bloom_filter); |
| |
| // Set num_bits in config to one more than the size of the data. |
| int num_bits = blacklist_bloom_filter.bytes().size() * 8 + 1; |
| |
| optimization_guide::proto::Configuration config; |
| AddBlacklistBloomFilterToConfig(blacklist_bloom_filter, |
| kBlackBlacklistBloomFilterNumHashFunctions, |
| num_bits, &config); |
| ParseConfig(config); |
| |
| EXPECT_FALSE(HasLitePageRedirectBlacklist()); |
| histogram_tester.ExpectBucketCount( |
| "Previews.OptimizationFilterStatus.LitePageRedirect", |
| 0 /* FOUND_SERVER_BLACKLIST_CONFIG */, 1); |
| histogram_tester.ExpectBucketCount( |
| "Previews.OptimizationFilterStatus.LitePageRedirect", |
| 2 /* FAILED_SERVER_BLACKLIST_BAD_CONFIG */, 1); |
| |
| EXPECT_FALSE(previews_hints()->IsBlacklisted( |
| GURL("https://black.com/path"), PreviewsType::LITE_PAGE_REDIRECT)); |
| } |
| |
| TEST_F(PreviewsHintsTest, ParseConfigWithTooLargeBlacklist) { |
| base::HistogramTester histogram_tester; |
| base::test::ScopedFeatureList scoped_list; |
| scoped_list.InitAndEnableFeature(features::kLitePageServerPreviews); |
| |
| int too_many_bits = |
| previews::params::LitePageRedirectPreviewMaxServerBlacklistByteSize() * |
| 8 + |
| 1; |
| |
| BloomFilter blacklist_bloom_filter(kBlackBlacklistBloomFilterNumHashFunctions, |
| too_many_bits); |
| PopulateBlackBlacklistBloomFilter(&blacklist_bloom_filter); |
| |
| optimization_guide::proto::Configuration config; |
| AddBlacklistBloomFilterToConfig(blacklist_bloom_filter, |
| kBlackBlacklistBloomFilterNumHashFunctions, |
| too_many_bits, &config); |
| ParseConfig(config); |
| |
| EXPECT_FALSE(HasLitePageRedirectBlacklist()); |
| histogram_tester.ExpectBucketCount( |
| "Previews.OptimizationFilterStatus.LitePageRedirect", |
| 0 /* FOUND_SERVER_BLACKLIST_CONFIG */, 1); |
| histogram_tester.ExpectBucketCount( |
| "Previews.OptimizationFilterStatus.LitePageRedirect", |
| 3 /* FAILED_SERVER_BLACKLIST_TOO_BIG */, 1); |
| |
| EXPECT_FALSE(previews_hints()->IsBlacklisted( |
| GURL("https://black.com/path"), PreviewsType::LITE_PAGE_REDIRECT)); |
| } |
| |
| TEST_F(PreviewsHintsTest, IsWhitelistedOutParams) { |
| base::test::ScopedFeatureList scoped_list; |
| scoped_list.InitAndEnableFeature(features::kResourceLoadingHints); |
| optimization_guide::proto::Configuration config; |
| |
| optimization_guide::proto::Hint* hint1 = config.add_hints(); |
| hint1->set_key("somedomain.org"); |
| hint1->set_key_representation(optimization_guide::proto::HOST_SUFFIX); |
| |
| // Page hint for "/has_inflation_percent/" |
| optimization_guide::proto::PageHint* page_hint1 = hint1->add_page_hints(); |
| page_hint1->set_page_pattern("/has_inflation_percent/"); |
| optimization_guide::proto::Optimization* optimization_with_inflation_percent = |
| page_hint1->add_whitelisted_optimizations(); |
| optimization_with_inflation_percent->set_inflation_percent(55); |
| optimization_with_inflation_percent->set_optimization_type( |
| optimization_guide::proto::RESOURCE_LOADING); |
| optimization_guide::proto::ResourceLoadingHint* resource_hint1 = |
| optimization_with_inflation_percent->add_resource_loading_hints(); |
| resource_hint1->set_loading_optimization_type( |
| optimization_guide::proto::LOADING_BLOCK_RESOURCE); |
| resource_hint1->set_resource_pattern("default_resource.js"); |
| // Page hint for "/has_max_ect_trigger/" |
| optimization_guide::proto::PageHint* page_hint2 = hint1->add_page_hints(); |
| page_hint2->set_page_pattern("/has_max_ect_trigger/"); |
| page_hint2->set_max_ect_trigger( |
| optimization_guide::proto::EffectiveConnectionType:: |
| EFFECTIVE_CONNECTION_TYPE_4G); |
| optimization_guide::proto::Optimization* |
| optimization_without_inflation_percent = |
| page_hint2->add_whitelisted_optimizations(); |
| optimization_without_inflation_percent->set_optimization_type( |
| optimization_guide::proto::RESOURCE_LOADING); |
| optimization_guide::proto::ResourceLoadingHint* resource_hint2 = |
| optimization_without_inflation_percent->add_resource_loading_hints(); |
| resource_hint2->set_loading_optimization_type( |
| optimization_guide::proto::LOADING_BLOCK_RESOURCE); |
| resource_hint2->set_resource_pattern("default_resource.js"); |
| ParseConfig(config); |
| |
| // Verify optimization providing inflation_percent. |
| int inflation_percent = 0; |
| net::EffectiveConnectionType ect_threshold = |
| net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_UNKNOWN; |
| EXPECT_TRUE(previews_hints()->IsWhitelisted( |
| GURL("https://www.somedomain.org/has_inflation_percent/"), |
| PreviewsType::RESOURCE_LOADING_HINTS, &inflation_percent, |
| &ect_threshold)); |
| EXPECT_EQ(55, inflation_percent); |
| EXPECT_EQ(net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_UNKNOWN, |
| ect_threshold); |
| |
| // Verify page hint providing ECT trigger. |
| inflation_percent = 0; |
| ect_threshold = |
| net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_UNKNOWN; |
| EXPECT_TRUE(previews_hints()->IsWhitelisted( |
| GURL("https://www.somedomain.org/has_max_ect_trigger/"), |
| PreviewsType::RESOURCE_LOADING_HINTS, &inflation_percent, |
| &ect_threshold)); |
| EXPECT_EQ(0, inflation_percent); |
| EXPECT_EQ(net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_4G, |
| ect_threshold); |
| } |
| |
| TEST_F(PreviewsHintsTest, |
| IsWhitelistedForNoScriptInPageHintsWithResourceLoadingHintsDisabled) { |
| optimization_guide::proto::Configuration config; |
| |
| optimization_guide::proto::Hint* hint1 = config.add_hints(); |
| hint1->set_key("somedomain.org"); |
| hint1->set_key_representation(optimization_guide::proto::HOST_SUFFIX); |
| |
| // Page hint with NOSCRIPT optimization |
| optimization_guide::proto::PageHint* page_hint1 = hint1->add_page_hints(); |
| page_hint1->set_page_pattern("/has_noscript/"); |
| optimization_guide::proto::Optimization* optimization_with_inflation_percent = |
| page_hint1->add_whitelisted_optimizations(); |
| optimization_with_inflation_percent->set_optimization_type( |
| optimization_guide::proto::NOSCRIPT); |
| |
| ParseConfig(config); |
| |
| int inflation_percent = 0; |
| net::EffectiveConnectionType ect_threshold = |
| net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_UNKNOWN; |
| EXPECT_TRUE(previews_hints()->IsWhitelisted( |
| GURL("https://www.somedomain.org/has_noscript/"), PreviewsType::NOSCRIPT, |
| &inflation_percent, &ect_threshold)); |
| } |
| |
| TEST_F(PreviewsHintsTest, IsWhitelistedForExperimentalPreview) { |
| base::test::ScopedFeatureList scoped_list; |
| scoped_list.InitAndEnableFeature(features::kResourceLoadingHints); |
| optimization_guide::proto::Configuration config; |
| |
| optimization_guide::proto::Hint* hint1 = config.add_hints(); |
| hint1->set_key("somedomain.org"); |
| hint1->set_key_representation(optimization_guide::proto::HOST_SUFFIX); |
| |
| // Page hint for "/experimental_preview/" |
| optimization_guide::proto::PageHint* page_hint1 = hint1->add_page_hints(); |
| page_hint1->set_page_pattern("/experimental_preview/"); |
| page_hint1->set_max_ect_trigger( |
| optimization_guide::proto::EffectiveConnectionType:: |
| EFFECTIVE_CONNECTION_TYPE_3G); |
| // First add experimental PageHint optimization. |
| optimization_guide::proto::Optimization* experimental_optimization = |
| page_hint1->add_whitelisted_optimizations(); |
| experimental_optimization->set_experiment_name("foo_experiment"); |
| experimental_optimization->set_inflation_percent(99); |
| experimental_optimization->set_optimization_type( |
| optimization_guide::proto::RESOURCE_LOADING); |
| optimization_guide::proto::ResourceLoadingHint* experimental_resourcehint = |
| experimental_optimization->add_resource_loading_hints(); |
| experimental_resourcehint->set_loading_optimization_type( |
| optimization_guide::proto::LOADING_BLOCK_RESOURCE); |
| experimental_resourcehint->set_resource_pattern("experimental_resource.js"); |
| // Add a non-experimental PageHint optimization with same resource pattern. |
| optimization_guide::proto::Optimization* default_pagehint_optimization = |
| page_hint1->add_whitelisted_optimizations(); |
| default_pagehint_optimization->set_inflation_percent(33); |
| default_pagehint_optimization->set_optimization_type( |
| optimization_guide::proto::RESOURCE_LOADING); |
| optimization_guide::proto::ResourceLoadingHint* default_resourcehint = |
| default_pagehint_optimization->add_resource_loading_hints(); |
| default_resourcehint->set_loading_optimization_type( |
| optimization_guide::proto::LOADING_BLOCK_RESOURCE); |
| default_resourcehint->set_resource_pattern("experimental_resource.js"); |
| |
| // Test with the experiment disabled. |
| { |
| base::HistogramTester histogram_tester; |
| |
| ParseConfig(config); |
| |
| // Verify default resource hint whitelisted (via inflation_percent). |
| int inflation_percent = 0; |
| net::EffectiveConnectionType ect_threshold = |
| net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_UNKNOWN; |
| EXPECT_TRUE(previews_hints()->IsWhitelisted( |
| GURL("https://www.somedomain.org/experimental_preview/" |
| "experimental_resource.js"), |
| PreviewsType::RESOURCE_LOADING_HINTS, &inflation_percent, |
| &ect_threshold)); |
| EXPECT_EQ(33, inflation_percent); |
| EXPECT_EQ(net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_3G, |
| ect_threshold); |
| |
| // Verify that the experimental optimization was not added when it was |
| // disabled. |
| histogram_tester.ExpectUniqueSample( |
| "ResourceLoadingHints.ResourceHints.TotalReceived", 1, 1); |
| } |
| |
| // Now enable the experiment and verify experimental resource hint chosen. |
| { |
| base::HistogramTester histogram_tester; |
| |
| base::test::ScopedFeatureList scoped_list2; |
| scoped_list2.InitAndEnableFeatureWithParameters( |
| features::kOptimizationHintsExperiments, |
| {{"experiment_name", "foo_experiment"}}); |
| |
| // Parse the config again with the experiment enabled. |
| ParseConfig(config); |
| |
| int inflation_percent = 0; |
| net::EffectiveConnectionType ect_threshold = |
| net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_2G; |
| EXPECT_TRUE(previews_hints()->IsWhitelisted( |
| GURL("https://www.somedomain.org/experimental_preview/" |
| "experimental_resource.js"), |
| PreviewsType::RESOURCE_LOADING_HINTS, &inflation_percent, |
| &ect_threshold)); |
| EXPECT_EQ(99, inflation_percent); |
| EXPECT_EQ(net::EffectiveConnectionType::EFFECTIVE_CONNECTION_TYPE_3G, |
| ect_threshold); |
| |
| // Verify that the second optimization was not added when the experimental |
| // optimization was enabled. |
| histogram_tester.ExpectUniqueSample( |
| "ResourceLoadingHints.ResourceHints.TotalReceived", 1, 1); |
| } |
| } |
| |
| } // namespace previews |