blob: 08523c518175514a3097f1770185664386e7ddae [file] [log] [blame]
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/omnibox/browser/omnibox_field_trial.h"
#include <memory>
#include <string>
#include <utility>
#include "base/command_line.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/field_trial_params.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "components/history/core/browser/url_database.h"
#include "components/omnibox/common/omnibox_features.h"
#include "components/search/search.h"
#include "components/variations/variations_associated_data.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/metrics_proto/omnibox_event.pb.h"
using metrics::OmniboxEventProto;
class OmniboxFieldTrialTest : public testing::Test {
public:
OmniboxFieldTrialTest() {
ResetFieldTrialList();
}
OmniboxFieldTrialTest(const OmniboxFieldTrialTest&) = delete;
OmniboxFieldTrialTest& operator=(const OmniboxFieldTrialTest&) = delete;
void ResetFieldTrialList() {
scoped_feature_list_.Reset();
variations::testing::ClearAllVariationParams();
scoped_feature_list_.Init();
}
void ResetAndEnableFeatureWithParameters(
const base::Feature& feature,
const base::FieldTrialParams& feature_parameters) {
scoped_feature_list_.Reset();
variations::testing::ClearAllVariationParams();
scoped_feature_list_.InitAndEnableFeatureWithParameters(feature,
feature_parameters);
}
// Creates and activates a field trial.
static base::FieldTrial* CreateTestTrial(const std::string& name,
const std::string& group_name) {
base::FieldTrial* trial = base::FieldTrialList::CreateFieldTrial(
name, group_name);
trial->Activate();
return trial;
}
// EXPECT()s that OmniboxFieldTrial::GetSuggestPollingStrategy returns
// |expected_from_last_keystroke| and |expected_delay_ms| for the given
// experiment params. If one the rule values is NULL, the corresponding
// variation parameter won't be set thus allowing to test the default
// behavior.
void VerifySuggestPollingStrategy(
const char* from_last_keystroke_rule_value,
const char* polling_delay_ms_rule_value,
bool expected_from_last_keystroke,
int expected_delay_ms);
private:
base::test::ScopedFeatureList scoped_feature_list_;
};
void OmniboxFieldTrialTest::VerifySuggestPollingStrategy(
const char* from_last_keystroke_rule_value,
const char* polling_delay_ms_rule_value,
bool expected_from_last_keystroke,
int expected_delay_ms) {
ResetFieldTrialList();
std::map<std::string, std::string> params;
if (from_last_keystroke_rule_value != nullptr) {
params[std::string(
OmniboxFieldTrial::kMeasureSuggestPollingDelayFromLastKeystrokeRule)] =
from_last_keystroke_rule_value;
}
if (polling_delay_ms_rule_value != nullptr) {
params[std::string(
OmniboxFieldTrial::kSuggestPollingDelayMsRule)] =
polling_delay_ms_rule_value;
}
ASSERT_TRUE(base::AssociateFieldTrialParams(
OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params));
base::FieldTrialList::CreateFieldTrial(
OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A");
bool from_last_keystroke;
int delay_ms;
OmniboxFieldTrial::GetSuggestPollingStrategy(&from_last_keystroke, &delay_ms);
EXPECT_EQ(expected_from_last_keystroke, from_last_keystroke);
EXPECT_EQ(expected_delay_ms, delay_ms);
}
// Test if GetDisabledProviderTypes() properly parses various field trial
// group names.
TEST_F(OmniboxFieldTrialTest, GetDisabledProviderTypes) {
EXPECT_EQ(0, OmniboxFieldTrial::GetDisabledProviderTypes());
{
SCOPED_TRACE("Valid field trial, missing param.");
ResetFieldTrialList();
std::map<std::string, std::string> params;
ASSERT_TRUE(base::AssociateFieldTrialParams(
OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params));
base::FieldTrialList::CreateFieldTrial(
OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A");
EXPECT_EQ(0, OmniboxFieldTrial::GetDisabledProviderTypes());
}
{
SCOPED_TRACE("Valid field trial, empty param value.");
ResetFieldTrialList();
std::map<std::string, std::string> params;
params[std::string(OmniboxFieldTrial::kDisableProvidersRule)] = "";
ASSERT_TRUE(base::AssociateFieldTrialParams(
OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params));
base::FieldTrialList::CreateFieldTrial(
OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A");
EXPECT_EQ(0, OmniboxFieldTrial::GetDisabledProviderTypes());
}
{
SCOPED_TRACE("Valid field trial, invalid param value.");
ResetFieldTrialList();
std::map<std::string, std::string> params;
params[std::string(OmniboxFieldTrial::kDisableProvidersRule)] = "aaa";
ASSERT_TRUE(base::AssociateFieldTrialParams(
OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params));
base::FieldTrialList::CreateFieldTrial(
OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A");
EXPECT_EQ(0, OmniboxFieldTrial::GetDisabledProviderTypes());
}
{
SCOPED_TRACE("Valid field trial and param.");
ResetFieldTrialList();
std::map<std::string, std::string> params;
params[std::string(OmniboxFieldTrial::kDisableProvidersRule)] = "12321";
ASSERT_TRUE(base::AssociateFieldTrialParams(
OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params));
base::FieldTrialList::CreateFieldTrial(
OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A");
EXPECT_EQ(12321, OmniboxFieldTrial::GetDisabledProviderTypes());
}
}
TEST_F(OmniboxFieldTrialTest, GetProviderMaxMatches) {
OmniboxFieldTrial::ScopedMLConfigForTesting scoped_ml_config;
scoped_ml_config.GetMLConfig().ml_url_scoring = false;
{
ResetAndEnableFeatureWithParameters(
omnibox::kUIExperimentMaxAutocompleteMatches,
{{OmniboxFieldTrial::kUIMaxAutocompleteMatchesByProviderParam,
"1:50,2:0"}});
ASSERT_EQ(50ul, OmniboxFieldTrial::GetProviderMaxMatches(
AutocompleteProvider::Type::TYPE_BOOKMARK));
ASSERT_EQ(0ul, OmniboxFieldTrial::GetProviderMaxMatches(
AutocompleteProvider::Type::TYPE_BUILTIN));
ASSERT_EQ(3ul, OmniboxFieldTrial::GetProviderMaxMatches(
AutocompleteProvider::Type::TYPE_HISTORY_QUICK));
}
{
ResetAndEnableFeatureWithParameters(
omnibox::kUIExperimentMaxAutocompleteMatches,
{{OmniboxFieldTrial::kUIMaxAutocompleteMatchesByProviderParam,
"1:60,*:61,2:62"}});
ASSERT_EQ(60ul, OmniboxFieldTrial::GetProviderMaxMatches(
AutocompleteProvider::Type::TYPE_BOOKMARK));
ASSERT_EQ(62ul, OmniboxFieldTrial::GetProviderMaxMatches(
AutocompleteProvider::Type::TYPE_BUILTIN));
ASSERT_EQ(61ul, OmniboxFieldTrial::GetProviderMaxMatches(
AutocompleteProvider::Type::TYPE_HISTORY_QUICK));
}
{
ResetFieldTrialList();
ASSERT_EQ(3ul, OmniboxFieldTrial::GetProviderMaxMatches(
AutocompleteProvider::Type::TYPE_BOOKMARK));
ASSERT_EQ(3ul, OmniboxFieldTrial::GetProviderMaxMatches(
AutocompleteProvider::Type::TYPE_BUILTIN));
ASSERT_EQ(3ul, OmniboxFieldTrial::GetProviderMaxMatches(
AutocompleteProvider::Type::TYPE_HISTORY_QUICK));
}
{
scoped_ml_config.GetMLConfig().ml_url_scoring = true;
scoped_ml_config.GetMLConfig().url_scoring_model = true;
scoped_ml_config.GetMLConfig().ml_url_scoring_max_matches_by_provider =
"1:10,4:10,8:10,64:10,65536:10";
ASSERT_EQ(10ul, OmniboxFieldTrial::GetProviderMaxMatches(
AutocompleteProvider::Type::TYPE_BOOKMARK));
ASSERT_EQ(10ul, OmniboxFieldTrial::GetProviderMaxMatches(
AutocompleteProvider::Type::TYPE_HISTORY_QUICK));
ASSERT_EQ(10ul, OmniboxFieldTrial::GetProviderMaxMatches(
AutocompleteProvider::Type::TYPE_HISTORY_URL));
ASSERT_EQ(10ul, OmniboxFieldTrial::GetProviderMaxMatches(
AutocompleteProvider::Type::TYPE_HISTORY_FUZZY));
}
}
TEST_F(OmniboxFieldTrialTest, HUPNewScoringFieldTrial) {
{
std::map<std::string, std::string> params;
params[std::string(
OmniboxFieldTrial::kHUPNewScoringTypedCountRelevanceCapParam)] = "56";
params[std::string(
OmniboxFieldTrial::kHUPNewScoringTypedCountHalfLifeTimeParam)] = "77";
params[std::string(
OmniboxFieldTrial::kHUPNewScoringTypedCountScoreBucketsParam)] =
"0.2:25,0.1:1001,2.3:777";
params[std::string(
OmniboxFieldTrial::kHUPNewScoringVisitedCountRelevanceCapParam)] = "11";
params[std::string(
OmniboxFieldTrial::kHUPNewScoringVisitedCountHalfLifeTimeParam)] = "31";
params[std::string(
OmniboxFieldTrial::kHUPNewScoringVisitedCountScoreBucketsParam)] =
"5:300,0:200";
ASSERT_TRUE(base::AssociateFieldTrialParams(
OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params));
}
base::FieldTrialList::CreateFieldTrial(
OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A");
HUPScoringParams scoring_params;
OmniboxFieldTrial::GetExperimentalHUPScoringParams(&scoring_params);
EXPECT_EQ(56, scoring_params.typed_count_buckets.relevance_cap());
EXPECT_EQ(77, scoring_params.typed_count_buckets.half_life_days());
ASSERT_EQ(3u, scoring_params.typed_count_buckets.buckets().size());
EXPECT_EQ(std::make_pair(2.3, 777),
scoring_params.typed_count_buckets.buckets()[0]);
EXPECT_EQ(std::make_pair(0.2, 25),
scoring_params.typed_count_buckets.buckets()[1]);
EXPECT_EQ(std::make_pair(0.1, 1001),
scoring_params.typed_count_buckets.buckets()[2]);
EXPECT_EQ(11, scoring_params.visited_count_buckets.relevance_cap());
EXPECT_EQ(31, scoring_params.visited_count_buckets.half_life_days());
ASSERT_EQ(2u, scoring_params.visited_count_buckets.buckets().size());
EXPECT_EQ(std::make_pair(5.0, 300),
scoring_params.visited_count_buckets.buckets()[0]);
EXPECT_EQ(std::make_pair(0.0, 200),
scoring_params.visited_count_buckets.buckets()[1]);
}
TEST_F(OmniboxFieldTrialTest, HUPNewScoringFieldTrialWithDecayFactor) {
{
std::map<std::string, std::string> params;
params[OmniboxFieldTrial::kHUPNewScoringTypedCountHalfLifeTimeParam] = "10";
params[OmniboxFieldTrial::kHUPNewScoringTypedCountUseDecayFactorParam] =
"1";
params[OmniboxFieldTrial::kHUPNewScoringTypedCountScoreBucketsParam] =
"0.1:100,0.5:500,1.0:1000";
ASSERT_TRUE(base::AssociateFieldTrialParams(
OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A", params));
}
base::FieldTrialList::CreateFieldTrial(
OmniboxFieldTrial::kBundledExperimentFieldTrialName, "A");
HUPScoringParams scoring_params;
OmniboxFieldTrial::GetExperimentalHUPScoringParams(&scoring_params);
EXPECT_EQ(10, scoring_params.typed_count_buckets.half_life_days());
ASSERT_EQ(3u, scoring_params.typed_count_buckets.buckets().size());
ASSERT_TRUE(scoring_params.typed_count_buckets.use_decay_factor());
}
TEST_F(OmniboxFieldTrialTest, HalfLifeTimeDecay) {
HUPScoringParams::ScoreBuckets buckets;
// No decay by default.
EXPECT_EQ(1.0, buckets.HalfLifeTimeDecay(base::Days(7)));
buckets.set_half_life_days(7);
EXPECT_EQ(0.5, buckets.HalfLifeTimeDecay(base::Days(7)));
EXPECT_EQ(0.25, buckets.HalfLifeTimeDecay(base::Days(14)));
EXPECT_EQ(1.0, buckets.HalfLifeTimeDecay(base::Days(0)));
EXPECT_EQ(1.0, buckets.HalfLifeTimeDecay(base::Days(-1)));
}
TEST_F(OmniboxFieldTrialTest, GetSuggestPollingStrategy) {
// Invalid params.
VerifySuggestPollingStrategy(
"", "", false,
OmniboxFieldTrial::kDefaultMinimumTimeBetweenSuggestQueriesMs);
VerifySuggestPollingStrategy(
"foo", "-1", false,
OmniboxFieldTrial::kDefaultMinimumTimeBetweenSuggestQueriesMs);
VerifySuggestPollingStrategy(
"TRUE", "xyz", false,
OmniboxFieldTrial::kDefaultMinimumTimeBetweenSuggestQueriesMs);
// Default values.
VerifySuggestPollingStrategy(
nullptr, nullptr, false,
OmniboxFieldTrial::kDefaultMinimumTimeBetweenSuggestQueriesMs);
// Valid params.
VerifySuggestPollingStrategy("true", "50", true, 50);
VerifySuggestPollingStrategy(nullptr, "35", false, 35);
VerifySuggestPollingStrategy(
"true", nullptr, true,
OmniboxFieldTrial::kDefaultMinimumTimeBetweenSuggestQueriesMs);
}