blob: 7e98345c6704c685edd6b0ac0ff2884a1807d152 [file] [log] [blame]
// Copyright 2017 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/feature_engagement/internal/chrome_variations_configuration.h"
#include <map>
#include <string>
#include <vector>
#include "base/feature_list.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/field_trial_param_associator.h"
#include "base/metrics/field_trial_params.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "components/feature_engagement/public/configuration.h"
#include "components/feature_engagement/public/configuration_provider.h"
#include "components/feature_engagement/public/group_constants.h"
#include "components/feature_engagement/public/stats.h"
#include "components/feature_engagement/public/tracker.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace feature_engagement {
namespace {
BASE_FEATURE(kChromeTestFeatureFoo,
"test_foo",
base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kChromeTestFeatureBar,
"test_bar",
base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kChromeTestFeatureQux,
"test_qux",
base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kChromeTestGroupOne,
"test_group_one",
base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kChromeTestGroupTwo,
"test_group_two",
base::FEATURE_DISABLED_BY_DEFAULT);
BASE_FEATURE(kChromeTestGroupThree,
"test_group_three",
base::FEATURE_DISABLED_BY_DEFAULT);
const char kFooTrialName[] = "FooTrial";
const char kBarTrialName[] = "BarTrial";
const char kQuxTrialName[] = "QuxTrial";
const char kGroupOneTrialName[] = "GroupOneTrial";
const char kGroupTwoTrialName[] = "GroupTwoTrial";
const char kGroupThreeTrialName[] = "GroupThreeTrial";
const char kTrialGroupName[] = "FieldTrialGroup1";
const char kConfigParseEventName[] = "InProductHelp.Config.ParsingEvent";
SessionRateImpact CreateSessionRateImpactExplicit(
std::vector<std::string> affected_features) {
SessionRateImpact impact;
impact.type = SessionRateImpact::Type::EXPLICIT;
impact.affected_features = affected_features;
return impact;
}
BlockedBy CreateBlockedByExplicit(std::vector<std::string> affected_features) {
BlockedBy blocked_by;
blocked_by.type = BlockedBy::Type::EXPLICIT;
blocked_by.affected_features = affected_features;
return blocked_by;
}
#if BUILDFLAG(IS_CHROMEOS)
class TestConfigurationProvider : public ConfigurationProvider {
public:
TestConfigurationProvider() = default;
~TestConfigurationProvider() override = default;
// ConfigurationProvider:
bool MaybeProvideFeatureConfiguration(
const base::Feature& feature,
feature_engagement::FeatureConfig& config,
const feature_engagement::FeatureVector& known_features,
const feature_engagement::GroupVector& known_groups) const override {
config = config_;
return true;
}
const char* GetConfigurationSourceDescription() const override {
return "Test Configuration Provider";
}
std::set<std::string> MaybeProvideAllowedEventPrefixes(
const base::Feature& feature) const override {
return {"TestEventPrefix"};
}
void SetConfig(const FeatureConfig& config) { config_ = config; }
private:
FeatureConfig config_;
};
#endif
class ChromeVariationsConfigurationTest : public ::testing::Test {
public:
ChromeVariationsConfigurationTest() {
base::FieldTrial* foo_trial =
base::FieldTrialList::CreateFieldTrial(kFooTrialName, kTrialGroupName);
base::FieldTrial* bar_trial =
base::FieldTrialList::CreateFieldTrial(kBarTrialName, kTrialGroupName);
base::FieldTrial* qux_trial =
base::FieldTrialList::CreateFieldTrial(kQuxTrialName, kTrialGroupName);
base::FieldTrial* group_one_trial = base::FieldTrialList::CreateFieldTrial(
kGroupOneTrialName, kTrialGroupName);
base::FieldTrial* group_two_trial = base::FieldTrialList::CreateFieldTrial(
kGroupTwoTrialName, kTrialGroupName);
base::FieldTrial* group_three_trial =
base::FieldTrialList::CreateFieldTrial(kGroupThreeTrialName,
kTrialGroupName);
trials_[kChromeTestFeatureFoo.name] = foo_trial;
trials_[kChromeTestFeatureBar.name] = bar_trial;
trials_[kChromeTestFeatureQux.name] = qux_trial;
trials_[kChromeTestGroupOne.name] = group_one_trial;
trials_[kChromeTestGroupTwo.name] = group_two_trial;
trials_[kChromeTestGroupThree.name] = group_three_trial;
std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
feature_list->RegisterFieldTrialOverride(
kChromeTestFeatureFoo.name, base::FeatureList::OVERRIDE_ENABLE_FEATURE,
foo_trial);
feature_list->RegisterFieldTrialOverride(
kChromeTestFeatureBar.name, base::FeatureList::OVERRIDE_ENABLE_FEATURE,
bar_trial);
feature_list->RegisterFieldTrialOverride(
kChromeTestFeatureQux.name, base::FeatureList::OVERRIDE_ENABLE_FEATURE,
qux_trial);
feature_list->RegisterFieldTrialOverride(
kChromeTestGroupOne.name, base::FeatureList::OVERRIDE_ENABLE_FEATURE,
group_one_trial);
feature_list->RegisterFieldTrialOverride(
kChromeTestGroupTwo.name, base::FeatureList::OVERRIDE_ENABLE_FEATURE,
group_two_trial);
feature_list->RegisterFieldTrialOverride(
kChromeTestGroupThree.name, base::FeatureList::OVERRIDE_ENABLE_FEATURE,
group_three_trial);
scoped_feature_list_.InitWithFeatureList(std::move(feature_list));
EXPECT_EQ(foo_trial,
base::FeatureList::GetFieldTrial(kChromeTestFeatureFoo));
EXPECT_EQ(bar_trial,
base::FeatureList::GetFieldTrial(kChromeTestFeatureBar));
EXPECT_EQ(qux_trial,
base::FeatureList::GetFieldTrial(kChromeTestFeatureQux));
EXPECT_EQ(group_one_trial,
base::FeatureList::GetFieldTrial(kChromeTestGroupOne));
EXPECT_EQ(group_two_trial,
base::FeatureList::GetFieldTrial(kChromeTestGroupTwo));
EXPECT_EQ(group_three_trial,
base::FeatureList::GetFieldTrial(kChromeTestGroupThree));
}
ChromeVariationsConfigurationTest(const ChromeVariationsConfigurationTest&) =
delete;
ChromeVariationsConfigurationTest& operator=(
const ChromeVariationsConfigurationTest&) = delete;
void TearDown() override {
// This is required to ensure each test can define its own params.
base::FieldTrialParamAssociator::GetInstance()->ClearAllParamsForTesting();
}
void SetFeatureParams(const base::Feature& feature,
std::map<std::string, std::string> params) {
ASSERT_TRUE(
base::FieldTrialParamAssociator::GetInstance()
->AssociateFieldTrialParams(trials_[feature.name]->trial_name(),
kTrialGroupName, params));
std::map<std::string, std::string> actualParams;
EXPECT_TRUE(base::GetFieldTrialParamsByFeature(feature, &actualParams));
EXPECT_EQ(params, actualParams);
}
void LoadConfigs(const FeatureVector& features, const GroupVector& groups) {
configuration_.LoadConfigs(Tracker::GetDefaultConfigurationProviders(),
features, groups);
}
protected:
void VerifyInvalid(const std::string& event_config) {
std::map<std::string, std::string> foo_params;
foo_params["event_used"] = "name:u;comparator:any;window:0;storage:1";
foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
foo_params["event_0"] = event_config;
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
GroupVector groups;
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_FALSE(foo.valid);
}
ChromeVariationsConfiguration configuration_;
private:
base::test::ScopedFeatureList scoped_feature_list_;
std::map<std::string, base::FieldTrial*> trials_;
};
} // namespace
TEST_F(ChromeVariationsConfigurationTest,
DisabledFeatureShouldHaveInvalidConfig) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitWithFeatures({}, {kChromeTestFeatureFoo});
FeatureVector features;
features.push_back(&kChromeTestFeatureFoo);
GroupVector groups;
base::HistogramTester histogram_tester;
LoadConfigs(features, groups);
FeatureConfig foo_config =
configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_FALSE(foo_config.valid);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE_NO_FIELD_TRIAL), 1);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 1);
}
TEST_F(ChromeVariationsConfigurationTest, ParseSingleFeature) {
std::map<std::string, std::string> foo_params;
foo_params["event_used"] =
"name:page_download_started;comparator:any;window:0;storage:360";
foo_params["event_trigger"] =
"name:opened_chrome_home;comparator:any;window:0;storage:360";
foo_params["event_1"] =
"name:user_has_seen_dino;comparator:>=1;window:120;storage:180";
foo_params["event_2"] =
"name:user_opened_app_menu;comparator:<=0;window:120;storage:180";
foo_params["event_3"] =
"name:user_opened_downloads_home;comparator:any;window:0;storage:360";
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
base::HistogramTester histogram_tester;
std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
GroupVector groups;
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_TRUE(foo.valid);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::SUCCESS), 1);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 1);
FeatureConfig expected_foo;
expected_foo.valid = true;
expected_foo.used =
EventConfig("page_download_started", Comparator(ANY, 0), 0, 360);
expected_foo.trigger =
EventConfig("opened_chrome_home", Comparator(ANY, 0), 0, 360);
expected_foo.event_configs.insert(EventConfig(
"user_has_seen_dino", Comparator(GREATER_THAN_OR_EQUAL, 1), 120, 180));
expected_foo.event_configs.insert(EventConfig(
"user_opened_app_menu", Comparator(LESS_THAN_OR_EQUAL, 0), 120, 180));
expected_foo.event_configs.insert(
EventConfig("user_opened_downloads_home", Comparator(ANY, 0), 0, 360));
EXPECT_EQ(expected_foo, foo);
}
TEST_F(ChromeVariationsConfigurationTest, ParsePrefixedParamNames) {
std::map<std::string, std::string> foo_params;
// Prefixed param names.
foo_params["test_foo_session_rate"] = "!=6";
foo_params["test_foo_availability"] = ">=1";
foo_params["test_foo_event_used"] =
"name:page_download_started;comparator:any;window:0;storage:360";
foo_params["test_foo_event_trigger"] =
"name:opened_chrome_home;comparator:any;window:0;storage:360";
foo_params["test_foo_event_1"] =
"name:user_has_seen_dino;comparator:>=1;window:120;storage:180";
foo_params["event_2"] =
"name:user_opened_app_menu;comparator:<=0;window:120;storage:180";
foo_params["event_3"] =
"name:user_opened_downloads_home;comparator:any;window:0;storage:360";
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
base::HistogramTester histogram_tester;
std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
GroupVector groups;
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_TRUE(foo.valid);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::SUCCESS), 1);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 1);
FeatureConfig expected_foo;
expected_foo.valid = true;
expected_foo.used =
EventConfig("page_download_started", Comparator(ANY, 0), 0, 360);
expected_foo.trigger =
EventConfig("opened_chrome_home", Comparator(ANY, 0), 0, 360);
expected_foo.event_configs.insert(EventConfig(
"user_has_seen_dino", Comparator(GREATER_THAN_OR_EQUAL, 1), 120, 180));
expected_foo.event_configs.insert(EventConfig(
"user_opened_app_menu", Comparator(LESS_THAN_OR_EQUAL, 0), 120, 180));
expected_foo.event_configs.insert(
EventConfig("user_opened_downloads_home", Comparator(ANY, 0), 0, 360));
expected_foo.session_rate = Comparator(NOT_EQUAL, 6);
expected_foo.availability = Comparator(GREATER_THAN_OR_EQUAL, 1);
EXPECT_EQ(expected_foo, foo);
}
TEST_F(ChromeVariationsConfigurationTest,
MultipleFeaturesWithPrefixedAndUnprefixedParams) {
std::map<std::string, std::string> foo_params;
foo_params["test_foo_session_rate"] = "!=6";
foo_params["test_foo_availability"] = ">=1";
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
std::map<std::string, std::string> bar_params;
bar_params["test_bar_session_rate"] = "!=7";
bar_params["test_bar_availability"] = ">=2";
SetFeatureParams(kChromeTestFeatureBar, bar_params);
std::map<std::string, std::string> qux_params;
qux_params["session_rate"] = "!=3";
qux_params["availability"] = ">=5";
SetFeatureParams(kChromeTestFeatureQux, qux_params);
std::vector<const base::Feature*> features = {
&kChromeTestFeatureFoo, &kChromeTestFeatureBar, &kChromeTestFeatureQux};
GroupVector groups;
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
FeatureConfig bar = configuration_.GetFeatureConfig(kChromeTestFeatureBar);
FeatureConfig qux = configuration_.GetFeatureConfig(kChromeTestFeatureQux);
FeatureConfig expected_foo;
expected_foo.session_rate = Comparator(NOT_EQUAL, 6);
expected_foo.availability = Comparator(GREATER_THAN_OR_EQUAL, 1);
EXPECT_EQ(expected_foo, foo);
FeatureConfig expected_bar;
expected_bar.session_rate = Comparator(NOT_EQUAL, 7);
expected_bar.availability = Comparator(GREATER_THAN_OR_EQUAL, 2);
EXPECT_EQ(expected_bar, bar);
FeatureConfig expected_qux;
expected_qux.session_rate = Comparator(NOT_EQUAL, 3);
expected_qux.availability = Comparator(GREATER_THAN_OR_EQUAL, 5);
EXPECT_EQ(expected_qux, qux);
}
TEST_F(ChromeVariationsConfigurationTest, MissingUsedIsInvalid) {
std::map<std::string, std::string> foo_params;
foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
base::HistogramTester histogram_tester;
std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
GroupVector groups;
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_FALSE(foo.valid);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE_USED_EVENT_MISSING),
1);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE), 1);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 2);
}
TEST_F(ChromeVariationsConfigurationTest, MissingTriggerIsInvalid) {
std::map<std::string, std::string> foo_params;
foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
base::HistogramTester histogram_tester;
std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
GroupVector groups;
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_FALSE(foo.valid);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(
stats::ConfigParsingEvent::FAILURE_TRIGGER_EVENT_MISSING),
1);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE), 1);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 2);
}
TEST_F(ChromeVariationsConfigurationTest, OnlyTriggerAndUsedIsValid) {
std::map<std::string, std::string> foo_params;
foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
base::HistogramTester histogram_tester;
std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
GroupVector groups;
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_TRUE(foo.valid);
FeatureConfig expected_foo;
expected_foo.valid = true;
expected_foo.used = EventConfig("eu", Comparator(ANY, 0), 0, 360);
expected_foo.trigger = EventConfig("et", Comparator(ANY, 0), 0, 360);
EXPECT_EQ(expected_foo, foo);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::SUCCESS), 1);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 1);
}
void RunBlockedByTest(ChromeVariationsConfigurationTest* test,
ChromeVariationsConfiguration* configuration,
std::vector<const base::Feature*> features,
std::string blocked_by_param_value,
BlockedBy expected_blocked_by,
bool is_valid) {
base::HistogramTester histogram_tester;
std::map<std::string, std::string> foo_params;
foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
foo_params["blocked_by"] = blocked_by_param_value;
test->SetFeatureParams(kChromeTestFeatureFoo, foo_params);
GroupVector groups;
configuration->LoadConfigs(Tracker::GetDefaultConfigurationProviders(),
features, groups);
FeatureConfig foo = configuration->GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_EQ(is_valid, foo.valid);
FeatureConfig expected_foo;
expected_foo.valid = is_valid;
expected_foo.used = EventConfig("eu", Comparator(ANY, 0), 0, 360);
expected_foo.trigger = EventConfig("et", Comparator(ANY, 0), 0, 360);
expected_foo.blocked_by = expected_blocked_by;
EXPECT_EQ(expected_foo, foo);
if (is_valid) {
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::SUCCESS), 1);
} else {
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE), 1);
}
}
TEST_F(ChromeVariationsConfigurationTest, ParseBlockingNone) {
std::map<std::string, std::string> foo_params;
foo_params["blocking"] = "none";
foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
GroupVector groups;
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_EQ(foo.blocking.type, Blocking::Type::NONE);
EXPECT_TRUE(foo.valid);
}
TEST_F(ChromeVariationsConfigurationTest, ParseBlockingAll) {
std::map<std::string, std::string> foo_params;
foo_params["blocking"] = "all";
foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
GroupVector groups;
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_EQ(foo.blocking.type, Blocking::Type::ALL);
EXPECT_TRUE(foo.valid);
}
TEST_F(ChromeVariationsConfigurationTest, ParseInvalidBlockingParams) {
std::map<std::string, std::string> foo_params;
// Anything other than all/none should be invalid.
foo_params["blocking"] = "123";
foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
GroupVector groups;
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_EQ(foo.blocking.type, Blocking::Type::ALL);
EXPECT_FALSE(foo.valid);
}
TEST_F(ChromeVariationsConfigurationTest, ParseBlockedByAll) {
RunBlockedByTest(this, &configuration_, {&kChromeTestFeatureFoo}, "all",
BlockedBy(), true /* is_valid */);
}
TEST_F(ChromeVariationsConfigurationTest, ParseBlockedByNone) {
BlockedBy blocked_by;
blocked_by.type = BlockedBy::Type::NONE;
RunBlockedByTest(this, &configuration_, {&kChromeTestFeatureFoo}, "none",
blocked_by, true /* is_valid */);
}
TEST_F(ChromeVariationsConfigurationTest, ParseBlockedByExplicitSelf) {
RunBlockedByTest(this, &configuration_, {&kChromeTestFeatureFoo},
kChromeTestFeatureFoo.name,
CreateBlockedByExplicit({kChromeTestFeatureFoo.name}),
true /* is_valid */);
}
TEST_F(ChromeVariationsConfigurationTest, ParseBlockedByExplicitOther) {
RunBlockedByTest(this, &configuration_,
{&kChromeTestFeatureFoo, &kChromeTestFeatureBar},
kChromeTestFeatureBar.name,
CreateBlockedByExplicit({kChromeTestFeatureBar.name}),
true /* is_valid */);
}
TEST_F(ChromeVariationsConfigurationTest, ParseBlockedByExplicitMultiple) {
RunBlockedByTest(
this, &configuration_,
{&kChromeTestFeatureFoo, &kChromeTestFeatureBar, &kChromeTestFeatureQux},
"test_bar,test_qux",
CreateBlockedByExplicit(
{kChromeTestFeatureBar.name, kChromeTestFeatureQux.name}),
true /* is_valid */);
}
TEST_F(ChromeVariationsConfigurationTest, ParseBlockedByExplicitEmpty) {
RunBlockedByTest(this, &configuration_, {&kChromeTestFeatureFoo}, "",
BlockedBy(), false /* is_valid */);
}
TEST_F(ChromeVariationsConfigurationTest, ParseBlockedByExplicitOnlySeparator) {
RunBlockedByTest(this, &configuration_, {&kChromeTestFeatureFoo}, ",",
BlockedBy(), false /* is_valid */);
}
TEST_F(ChromeVariationsConfigurationTest,
ParseBlockedByExplicitUnknownFeature) {
RunBlockedByTest(this, &configuration_, {&kChromeTestFeatureFoo}, "random",
BlockedBy(), false /* is_valid */);
}
TEST_F(ChromeVariationsConfigurationTest, ParseBlockedByExplicitAll) {
RunBlockedByTest(this, &configuration_, {&kChromeTestFeatureFoo},
"all,test_foo", BlockedBy(), false /* is_valid */);
}
void RunSessionRateImpactTest(ChromeVariationsConfigurationTest* test,
ChromeVariationsConfiguration* configuration,
std::vector<const base::Feature*> features,
std::string session_rate_impact_param_value,
SessionRateImpact expected_impact,
bool is_valid) {
std::map<std::string, std::string> foo_params;
foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
foo_params["session_rate_impact"] = session_rate_impact_param_value;
test->SetFeatureParams(kChromeTestFeatureFoo, foo_params);
GroupVector groups;
configuration->LoadConfigs(Tracker::GetDefaultConfigurationProviders(),
features, groups);
FeatureConfig foo = configuration->GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_EQ(is_valid, foo.valid);
FeatureConfig expected_foo;
expected_foo.valid = is_valid;
expected_foo.used = EventConfig("eu", Comparator(ANY, 0), 0, 360);
expected_foo.trigger = EventConfig("et", Comparator(ANY, 0), 0, 360);
expected_foo.session_rate_impact =
is_valid ? expected_impact : SessionRateImpact();
EXPECT_EQ(expected_foo, foo);
}
TEST_F(ChromeVariationsConfigurationTest, SessionRateImpactAll) {
base::HistogramTester histogram_tester;
RunSessionRateImpactTest(this, &configuration_, {&kChromeTestFeatureFoo},
"all", SessionRateImpact(), true /* is_valid */);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::SUCCESS), 1);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 1);
}
TEST_F(ChromeVariationsConfigurationTest, SessionRateImpactNone) {
base::HistogramTester histogram_tester;
SessionRateImpact impact;
impact.type = SessionRateImpact::Type::NONE;
RunSessionRateImpactTest(this, &configuration_, {&kChromeTestFeatureFoo},
"none", impact, true /* is_valid */);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::SUCCESS), 1);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 1);
}
TEST_F(ChromeVariationsConfigurationTest, SessionRateImpactExplicitSelf) {
base::HistogramTester histogram_tester;
RunSessionRateImpactTest(
this, &configuration_, {&kChromeTestFeatureFoo}, "test_foo",
CreateSessionRateImpactExplicit({kChromeTestFeatureFoo.name}),
true /* is_valid */);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::SUCCESS), 1);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 1);
}
TEST_F(ChromeVariationsConfigurationTest, SessionRateImpactExplicitOther) {
base::HistogramTester histogram_tester;
RunSessionRateImpactTest(
this, &configuration_, {&kChromeTestFeatureFoo, &kChromeTestFeatureBar},
"test_bar", CreateSessionRateImpactExplicit({kChromeTestFeatureBar.name}),
true /* is_valid */);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::SUCCESS), 1);
// bar has no configuration.
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE_NO_FIELD_TRIAL), 1);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 2);
}
TEST_F(ChromeVariationsConfigurationTest, SessionRateImpactExplicitMultiple) {
base::HistogramTester histogram_tester;
RunSessionRateImpactTest(
this, &configuration_,
{&kChromeTestFeatureFoo, &kChromeTestFeatureBar, &kChromeTestFeatureQux},
"test_bar,test_qux",
CreateSessionRateImpactExplicit(
{kChromeTestFeatureBar.name, kChromeTestFeatureQux.name}),
true /* is_valid */);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::SUCCESS), 1);
// bar and qux have no configuration.
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE_NO_FIELD_TRIAL), 2);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 3);
}
TEST_F(ChromeVariationsConfigurationTest,
SessionRateImpactExplicitAtLeastOneValidFeature) {
base::HistogramTester histogram_tester;
RunSessionRateImpactTest(
this, &configuration_,
{&kChromeTestFeatureFoo, &kChromeTestFeatureBar, &kChromeTestFeatureQux},
"test_foo,no_feature",
CreateSessionRateImpactExplicit(
{kChromeTestFeatureBar.name, kChromeTestFeatureQux.name}),
true /* is_valid */);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::SUCCESS), 1);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::
FAILURE_SESSION_RATE_IMPACT_UNKNOWN_FEATURE),
1);
// bar and qux have no configuration.
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE_NO_FIELD_TRIAL), 2);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 4);
}
TEST_F(ChromeVariationsConfigurationTest,
SessionRateImpactExplicitAtLeastOneValidFeaturePlusEmpty) {
base::HistogramTester histogram_tester;
RunSessionRateImpactTest(
this, &configuration_,
{&kChromeTestFeatureFoo, &kChromeTestFeatureBar, &kChromeTestFeatureQux},
"test_foo, ",
CreateSessionRateImpactExplicit(
{kChromeTestFeatureBar.name, kChromeTestFeatureQux.name}),
true /* is_valid */);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::SUCCESS), 1);
// bar and qux have no configuration.
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE_NO_FIELD_TRIAL), 2);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 3);
}
void TestInvalidSessionRateImpactParamValue(
ChromeVariationsConfigurationTest* test,
ChromeVariationsConfiguration* configuration,
std::string session_rate_impact_param_value,
uint32_t parse_errors,
uint32_t unknown_features) {
base::HistogramTester histogram_tester;
RunSessionRateImpactTest(
test, configuration,
{&kChromeTestFeatureFoo, &kChromeTestFeatureBar, &kChromeTestFeatureQux},
session_rate_impact_param_value, SessionRateImpact(),
false /* is_valid */);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE), 1);
if (parse_errors > 0) {
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(
stats::ConfigParsingEvent::FAILURE_SESSION_RATE_IMPACT_PARSE),
parse_errors);
}
if (unknown_features > 0) {
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::
FAILURE_SESSION_RATE_IMPACT_UNKNOWN_FEATURE),
unknown_features);
}
// bar and qux has no configuration.
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE_NO_FIELD_TRIAL), 2);
histogram_tester.ExpectTotalCount(kConfigParseEventName,
3 + parse_errors + unknown_features);
}
TEST_F(ChromeVariationsConfigurationTest, SessionRateImpactExplicitEmpty) {
TestInvalidSessionRateImpactParamValue(this, &configuration_, "", 1, 0);
}
TEST_F(ChromeVariationsConfigurationTest,
SessionRateImpactExplicitEmptyWhitespace) {
TestInvalidSessionRateImpactParamValue(this, &configuration_, " ", 1, 0);
}
TEST_F(ChromeVariationsConfigurationTest,
SessionRateImpactExplicitOnlySeparator) {
TestInvalidSessionRateImpactParamValue(this, &configuration_, ",", 1, 0);
}
TEST_F(ChromeVariationsConfigurationTest,
SessionRateImpactExplicitOnlySeparatorWhitespace) {
TestInvalidSessionRateImpactParamValue(this, &configuration_, " , ", 1, 0);
}
TEST_F(ChromeVariationsConfigurationTest,
SessionRateImpactExplicitOnlyUnknownFeature) {
TestInvalidSessionRateImpactParamValue(this, &configuration_, "not_feature",
1, 1);
}
TEST_F(ChromeVariationsConfigurationTest,
SessionRateImpactExplicitOnlyMultipleUnknownFeatures) {
TestInvalidSessionRateImpactParamValue(
this, &configuration_, "not_feature,another_not_feature", 1, 2);
}
TEST_F(ChromeVariationsConfigurationTest,
SessionRateImpactExplicitOnlyUnknownFeaturePlusEmpty) {
TestInvalidSessionRateImpactParamValue(this, &configuration_, "not_feature, ",
1, 1);
}
TEST_F(ChromeVariationsConfigurationTest,
SessionRateImpactExplicitInvalidFeatureNameAllFirst) {
TestInvalidSessionRateImpactParamValue(this, &configuration_, "all,test_foo",
1, 0);
}
TEST_F(ChromeVariationsConfigurationTest,
SessionRateImpactExplicitInvalidFeatureNameAllLast) {
TestInvalidSessionRateImpactParamValue(this, &configuration_, "test_foo,all",
1, 0);
}
TEST_F(ChromeVariationsConfigurationTest,
SessionRateImpactExplicitInvalidFeatureNameAllLastInvalidFirst) {
TestInvalidSessionRateImpactParamValue(this, &configuration_,
"not_feature,all", 1, 1);
}
TEST_F(ChromeVariationsConfigurationTest,
SessionRateImpactExplicitInvalidFeatureNameNoneFirst) {
TestInvalidSessionRateImpactParamValue(this, &configuration_, "none,test_foo",
1, 0);
}
TEST_F(ChromeVariationsConfigurationTest,
SessionRateImpactExplicitInvalidFeatureNameNoneLast) {
TestInvalidSessionRateImpactParamValue(this, &configuration_, "test_foo,none",
1, 0);
}
TEST_F(ChromeVariationsConfigurationTest,
SessionRateImpactExplicitInvalidFeatureNameNoneLastInvalidFirst) {
TestInvalidSessionRateImpactParamValue(this, &configuration_,
"not_feature,none", 1, 1);
}
TEST_F(ChromeVariationsConfigurationTest,
SessionRateImpactExplicitInvalidFeatureNameFromCodeReview) {
TestInvalidSessionRateImpactParamValue(this, &configuration_,
"test_foo,all,none,mwahahaha", 1, 0);
}
void RunGroupsTest(ChromeVariationsConfigurationTest* test,
ChromeVariationsConfiguration* configuration,
FeatureVector features,
GroupVector groups,
std::string groups_param_value,
std::vector<std::string> expected_groups,
bool is_valid) {
base::HistogramTester histogram_tester;
std::map<std::string, std::string> foo_params;
foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
foo_params["groups"] = groups_param_value;
test->SetFeatureParams(kChromeTestFeatureFoo, foo_params);
configuration->LoadConfigs(Tracker::GetDefaultConfigurationProviders(),
features, groups);
FeatureConfig foo = configuration->GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_EQ(is_valid, foo.valid);
FeatureConfig expected_foo;
expected_foo.valid = is_valid;
expected_foo.used = EventConfig("eu", Comparator(ANY, 0), 0, 360);
expected_foo.trigger = EventConfig("et", Comparator(ANY, 0), 0, 360);
expected_foo.groups = expected_groups;
EXPECT_EQ(expected_foo, foo);
if (is_valid) {
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::SUCCESS), 1);
} else {
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE), 1);
}
}
TEST_F(ChromeVariationsConfigurationTest, ParseGroupsItem) {
RunGroupsTest(this, &configuration_, {&kChromeTestFeatureFoo},
{&kChromeTestGroupOne}, kChromeTestGroupOne.name,
{kChromeTestGroupOne.name}, true /* is_valid */);
}
TEST_F(ChromeVariationsConfigurationTest, ParseGroupsMultiple) {
RunGroupsTest(this, &configuration_, {&kChromeTestFeatureFoo},
{&kChromeTestGroupOne, &kChromeTestGroupTwo},
"test_group_one,test_group_two",
{kChromeTestGroupOne.name, kChromeTestGroupTwo.name},
true /* is_valid */);
}
TEST_F(ChromeVariationsConfigurationTest, ParseGroupsEmpty) {
RunGroupsTest(this, &configuration_, {&kChromeTestFeatureFoo},
{&kChromeTestGroupOne}, "", std::vector<std::string>(),
false /* is_valid */);
}
TEST_F(ChromeVariationsConfigurationTest, ParseGroupsOnlySeparator) {
RunGroupsTest(this, &configuration_, {&kChromeTestFeatureFoo},
{&kChromeTestGroupOne}, ",", std::vector<std::string>(),
false /* is_valid */);
}
TEST_F(ChromeVariationsConfigurationTest, ParseGroupsUnknownGroup) {
RunGroupsTest(this, &configuration_, {&kChromeTestFeatureFoo},
{&kChromeTestGroupOne}, "random", std::vector<std::string>(),
false /* is_valid */);
}
TEST_F(ChromeVariationsConfigurationTest,
ParseGroupsCombinationKnownAndUnknownGroups) {
base::HistogramTester histogram_tester;
RunGroupsTest(this, &configuration_, {&kChromeTestFeatureFoo},
{&kChromeTestGroupOne}, "test_group_one,random",
{kChromeTestGroupOne.name}, true /* is_valid */);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE_GROUPS_UNKNOWN_GROUP),
1);
}
TEST_F(ChromeVariationsConfigurationTest, WhitespaceIsValid) {
std::map<std::string, std::string> foo_params;
foo_params["event_used"] =
" name : eu ; comparator : any ; window : 1 ; storage : 320 ";
foo_params["event_trigger"] =
" name:et;comparator : any ;window: 2;storage:330 ";
foo_params["event_0"] = "name:e0;comparator: <1 ;window:3\n;storage:340";
foo_params["event_1"] = "name:e1;comparator: > 2 ;window:4;\rstorage:350";
foo_params["event_2"] = "name:e2;comparator: <= 3 ;window:5;\tstorage:360";
foo_params["event_3"] = "name:e3;comparator: <\n4 ;window:6;storage:370";
foo_params["event_4"] = "name:e4;comparator: >\t5 ;window:7;storage:380";
foo_params["event_5"] = "name:e5;comparator: <=\r6 ;window:8;storage:390";
foo_params["event_6"] = "name:e6;comparator:\n<=7;window:9;storage:400";
foo_params["event_7"] = "name:e7;comparator:<=8\n;window:10;storage:410";
foo_params["session_rate_impact"] = " test_bar, test_qux ";
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
base::HistogramTester histogram_tester;
std::vector<const base::Feature*> features = {
&kChromeTestFeatureFoo, &kChromeTestFeatureBar, &kChromeTestFeatureQux};
GroupVector groups;
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_TRUE(foo.valid);
FeatureConfig expected_foo;
expected_foo.valid = true;
expected_foo.used = EventConfig("eu", Comparator(ANY, 0), 1, 320);
expected_foo.trigger = EventConfig("et", Comparator(ANY, 0), 2, 330);
expected_foo.event_configs.insert(
EventConfig("e0", Comparator(LESS_THAN, 1), 3, 340));
expected_foo.event_configs.insert(
EventConfig("e1", Comparator(GREATER_THAN, 2), 4, 350));
expected_foo.event_configs.insert(
EventConfig("e2", Comparator(LESS_THAN_OR_EQUAL, 3), 5, 360));
expected_foo.event_configs.insert(
EventConfig("e3", Comparator(LESS_THAN, 4), 6, 370));
expected_foo.event_configs.insert(
EventConfig("e4", Comparator(GREATER_THAN, 5), 7, 380));
expected_foo.event_configs.insert(
EventConfig("e5", Comparator(LESS_THAN_OR_EQUAL, 6), 8, 390));
expected_foo.event_configs.insert(
EventConfig("e6", Comparator(LESS_THAN_OR_EQUAL, 7), 9, 400));
expected_foo.event_configs.insert(
EventConfig("e7", Comparator(LESS_THAN_OR_EQUAL, 8), 10, 410));
expected_foo.session_rate_impact = CreateSessionRateImpactExplicit(
{kChromeTestFeatureBar.name, kChromeTestFeatureQux.name});
EXPECT_EQ(expected_foo, foo);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::SUCCESS), 1);
// bar and qux have no configuration.
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE_NO_FIELD_TRIAL), 2);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 3);
}
TEST_F(ChromeVariationsConfigurationTest, IgnoresInvalidConfigKeys) {
base::HistogramTester histogram_tester;
std::map<std::string, std::string> foo_params;
foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
foo_params["not_there_yet"] = "bogus value"; // Unrecognized.
foo_params["still_not_there"] = "another bogus value"; // Unrecognized.
foo_params["x_this_is_ignored"] = "this value is ignored"; // Ignored.
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
GroupVector groups;
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_TRUE(foo.valid);
FeatureConfig expected_foo;
expected_foo.valid = true;
expected_foo.used = EventConfig("eu", Comparator(ANY, 0), 0, 360);
expected_foo.trigger = EventConfig("et", Comparator(ANY, 0), 0, 360);
EXPECT_EQ(expected_foo, foo);
// Exactly 2 keys should be unrecognized and not ignored.
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE_UNKNOWN_KEY), 2);
}
TEST_F(ChromeVariationsConfigurationTest, IgnoresInvalidEventConfigTokens) {
std::map<std::string, std::string> foo_params;
foo_params["event_used"] =
"name:eu;comparator:any;window:0;storage:360;somethingelse:1";
foo_params["event_trigger"] =
"yesway:0;noway:1;name:et;comparator:any;window:0;storage:360";
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
GroupVector groups;
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_TRUE(foo.valid);
FeatureConfig expected_foo;
expected_foo.valid = true;
expected_foo.used = EventConfig("eu", Comparator(ANY, 0), 0, 360);
expected_foo.trigger = EventConfig("et", Comparator(ANY, 0), 0, 360);
EXPECT_EQ(expected_foo, foo);
}
TEST_F(ChromeVariationsConfigurationTest,
MissingAllEventConfigParamsIsInvalid) {
VerifyInvalid("a:1;b:2;c:3;d:4");
}
TEST_F(ChromeVariationsConfigurationTest,
MissingEventEventConfigParamIsInvalid) {
VerifyInvalid("foobar:eu;comparator:any;window:1;storage:360");
}
TEST_F(ChromeVariationsConfigurationTest,
MissingComparatorEventConfigParamIsInvalid) {
VerifyInvalid("name:eu;foobar:any;window:1;storage:360");
}
TEST_F(ChromeVariationsConfigurationTest,
MissingWindowEventConfigParamIsInvalid) {
VerifyInvalid("name:eu;comparator:any;foobar:1;storage:360");
}
TEST_F(ChromeVariationsConfigurationTest,
MissingStorageEventConfigParamIsInvalid) {
VerifyInvalid("name:eu;comparator:any;window:1;foobar:360");
}
TEST_F(ChromeVariationsConfigurationTest,
EventSpecifiedMultipleTimesIsInvalid) {
VerifyInvalid("name:eu;name:eu;comparator:any;window:1;storage:360");
}
TEST_F(ChromeVariationsConfigurationTest,
ComparatorSpecifiedMultipleTimesIsInvalid) {
VerifyInvalid("name:eu;comparator:any;comparator:any;window:1;storage:360");
}
TEST_F(ChromeVariationsConfigurationTest,
WindowSpecifiedMultipleTimesIsInvalid) {
VerifyInvalid("name:eu;comparator:any;window:1;window:2;storage:360");
}
TEST_F(ChromeVariationsConfigurationTest,
StorageSpecifiedMultipleTimesIsInvalid) {
VerifyInvalid("name:eu;comparator:any;window:1;storage:360;storage:10");
}
TEST_F(ChromeVariationsConfigurationTest,
InvalidSessionRateCausesInvalidConfig) {
std::map<std::string, std::string> foo_params;
foo_params["event_used"] = "name:eu;comparator:any;window:1;storage:360";
foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
foo_params["session_rate"] = "bogus value";
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
base::HistogramTester histogram_tester;
std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
GroupVector groups;
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_FALSE(foo.valid);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE_SESSION_RATE_PARSE),
1);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE), 1);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 2);
}
TEST_F(ChromeVariationsConfigurationTest,
InvalidAvailabilityCausesInvalidConfig) {
std::map<std::string, std::string> foo_params;
foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
foo_params["availability"] = "bogus value";
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
base::HistogramTester histogram_tester;
std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
GroupVector groups;
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_FALSE(foo.valid);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE_AVAILABILITY_PARSE),
1);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE), 1);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 2);
}
TEST_F(ChromeVariationsConfigurationTest, InvalidUsedCausesInvalidConfig) {
std::map<std::string, std::string> foo_params;
foo_params["event_used"] = "bogus value";
foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
base::HistogramTester histogram_tester;
std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
GroupVector groups;
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_FALSE(foo.valid);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE_USED_EVENT_PARSE), 1);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE_USED_EVENT_MISSING),
1);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE), 1);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 3);
}
TEST_F(ChromeVariationsConfigurationTest, InvalidTriggerCausesInvalidConfig) {
std::map<std::string, std::string> foo_params;
foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
foo_params["event_trigger"] = "bogus value";
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
base::HistogramTester histogram_tester;
std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
GroupVector groups;
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_FALSE(foo.valid);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE_TRIGGER_EVENT_PARSE),
1);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(
stats::ConfigParsingEvent::FAILURE_TRIGGER_EVENT_MISSING),
1);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE), 1);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 3);
}
TEST_F(ChromeVariationsConfigurationTest,
InvalidEventConfigCausesInvalidConfig) {
std::map<std::string, std::string> foo_params;
foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
foo_params["event_used_0"] = "bogus value";
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
GroupVector groups;
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_FALSE(foo.valid);
}
TEST_F(ChromeVariationsConfigurationTest,
InvalidTrackingOnlyCausesInvalidConfig) {
std::map<std::string, std::string> foo_params;
foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
foo_params["tracking_only"] = "bogus value";
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
base::HistogramTester histogram_tester;
std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
GroupVector groups;
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_FALSE(foo.valid);
EXPECT_FALSE(foo.tracking_only);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE_TRACKING_ONLY_PARSE),
1);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE), 1);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 2);
}
void RunTrackingOnlyTest(ChromeVariationsConfigurationTest* test,
ChromeVariationsConfiguration* configuration,
std::vector<const base::Feature*> features,
std::string tracking_only_definition,
bool expected_value,
bool is_valid) {
std::map<std::string, std::string> foo_params;
foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
foo_params["tracking_only"] = tracking_only_definition;
test->SetFeatureParams(kChromeTestFeatureFoo, foo_params);
GroupVector groups;
configuration->LoadConfigs(Tracker::GetDefaultConfigurationProviders(),
features, groups);
FeatureConfig foo = configuration->GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_EQ(is_valid, foo.valid);
FeatureConfig expected_foo;
expected_foo.valid = is_valid;
expected_foo.used = EventConfig("eu", Comparator(ANY, 0), 0, 360);
expected_foo.trigger = EventConfig("et", Comparator(ANY, 0), 0, 360);
expected_foo.tracking_only = expected_value;
EXPECT_EQ(expected_foo, foo);
}
TEST_F(ChromeVariationsConfigurationTest, TrackingOnlyReturnsTrue) {
base::HistogramTester histogram_tester;
RunTrackingOnlyTest(this, &configuration_, {&kChromeTestFeatureFoo}, "true",
true /* expected_value */, true /* is_valid */);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::SUCCESS), 1);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 1);
}
TEST_F(ChromeVariationsConfigurationTest,
TrackingOnlyReturnsTrueCaseInsensitive) {
base::HistogramTester histogram_tester;
RunTrackingOnlyTest(this, &configuration_, {&kChromeTestFeatureFoo}, "tRUe",
true /* expected_value */, true /* is_valid */);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::SUCCESS), 1);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 1);
}
TEST_F(ChromeVariationsConfigurationTest, TrackingOnlyReturnsFalse) {
base::HistogramTester histogram_tester;
RunTrackingOnlyTest(this, &configuration_, {&kChromeTestFeatureFoo}, "false",
false /* expected_value */, true /* is_valid */);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::SUCCESS), 1);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 1);
}
TEST_F(ChromeVariationsConfigurationTest,
TrackingOnlyReturnsFalseCaseInsensitive) {
base::HistogramTester histogram_tester;
RunTrackingOnlyTest(this, &configuration_, {&kChromeTestFeatureFoo}, "fALSe",
false /* expected_value */, true /* is_valid */);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::SUCCESS), 1);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 1);
}
TEST_F(ChromeVariationsConfigurationTest, AllComparatorTypesWork) {
std::map<std::string, std::string> foo_params;
foo_params["event_used"] = "name:e0;comparator:any;window:20;storage:30";
foo_params["event_trigger"] = "name:e1;comparator:<1;window:21;storage:31";
foo_params["event_2"] = "name:e2;comparator:>2;window:22;storage:32";
foo_params["event_3"] = "name:e3;comparator:<=3;window:23;storage:33";
foo_params["event_4"] = "name:e4;comparator:>=4;window:24;storage:34";
foo_params["event_5"] = "name:e5;comparator:==5;window:25;storage:35";
foo_params["event_6"] = "name:e6;comparator:!=6;window:26;storage:36";
foo_params["session_rate"] = "!=6";
foo_params["availability"] = ">=1";
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
GroupVector groups;
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_TRUE(foo.valid);
FeatureConfig expected_foo;
expected_foo.valid = true;
expected_foo.used = EventConfig("e0", Comparator(ANY, 0), 20, 30);
expected_foo.trigger = EventConfig("e1", Comparator(LESS_THAN, 1), 21, 31);
expected_foo.event_configs.insert(
EventConfig("e2", Comparator(GREATER_THAN, 2), 22, 32));
expected_foo.event_configs.insert(
EventConfig("e3", Comparator(LESS_THAN_OR_EQUAL, 3), 23, 33));
expected_foo.event_configs.insert(
EventConfig("e4", Comparator(GREATER_THAN_OR_EQUAL, 4), 24, 34));
expected_foo.event_configs.insert(
EventConfig("e5", Comparator(EQUAL, 5), 25, 35));
expected_foo.event_configs.insert(
EventConfig("e6", Comparator(NOT_EQUAL, 6), 26, 36));
expected_foo.session_rate = Comparator(NOT_EQUAL, 6);
expected_foo.availability = Comparator(GREATER_THAN_OR_EQUAL, 1);
EXPECT_EQ(expected_foo, foo);
}
TEST_F(ChromeVariationsConfigurationTest, MultipleEventsWithSameName) {
std::map<std::string, std::string> foo_params;
foo_params["event_used"] = "name:foo;comparator:any;window:20;storage:30";
foo_params["event_trigger"] = "name:foo;comparator:<1;window:21;storage:31";
foo_params["event_2"] = "name:foo;comparator:>2;window:22;storage:32";
foo_params["event_3"] = "name:foo;comparator:<=3;window:23;storage:33";
foo_params["session_rate"] = "any";
foo_params["availability"] = ">1";
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
GroupVector groups;
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_TRUE(foo.valid);
FeatureConfig expected_foo;
expected_foo.valid = true;
expected_foo.used = EventConfig("foo", Comparator(ANY, 0), 20, 30);
expected_foo.trigger = EventConfig("foo", Comparator(LESS_THAN, 1), 21, 31);
expected_foo.event_configs.insert(
EventConfig("foo", Comparator(GREATER_THAN, 2), 22, 32));
expected_foo.event_configs.insert(
EventConfig("foo", Comparator(LESS_THAN_OR_EQUAL, 3), 23, 33));
expected_foo.session_rate = Comparator(ANY, 0);
expected_foo.availability = Comparator(GREATER_THAN, 1);
EXPECT_EQ(expected_foo, foo);
}
TEST_F(ChromeVariationsConfigurationTest, ParseMultipleFeatures) {
std::map<std::string, std::string> foo_params;
foo_params["event_used"] =
"name:foo_used;comparator:any;window:20;storage:30";
foo_params["event_trigger"] =
"name:foo_trigger;comparator:<1;window:21;storage:31";
foo_params["session_rate"] = "==10";
foo_params["availability"] = "<0";
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
std::map<std::string, std::string> bar_params;
bar_params["event_used"] = "name:bar_used;comparator:ANY;window:0;storage:0";
SetFeatureParams(kChromeTestFeatureBar, bar_params);
std::map<std::string, std::string> qux_params;
qux_params["event_used"] =
"name:qux_used;comparator:>=2;window:99;storage:42";
qux_params["event_trigger"] =
"name:qux_trigger;comparator:ANY;window:103;storage:104";
qux_params["event_0"] = "name:q0;comparator:<10;window:20;storage:30";
qux_params["event_1"] = "name:q1;comparator:>11;window:21;storage:31";
qux_params["event_2"] = "name:q2;comparator:<=12;window:22;storage:32";
qux_params["event_3"] = "name:q3;comparator:>=13;window:23;storage:33";
qux_params["event_4"] = "name:q4;comparator:==14;window:24;storage:34";
qux_params["event_5"] = "name:q5;comparator:!=15;window:25;storage:35";
qux_params["session_rate"] = "!=13";
qux_params["availability"] = "==0";
SetFeatureParams(kChromeTestFeatureQux, qux_params);
std::vector<const base::Feature*> features = {
&kChromeTestFeatureFoo, &kChromeTestFeatureBar, &kChromeTestFeatureQux};
GroupVector groups;
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_TRUE(foo.valid);
FeatureConfig expected_foo;
expected_foo.valid = true;
expected_foo.used = EventConfig("foo_used", Comparator(ANY, 0), 20, 30);
expected_foo.trigger =
EventConfig("foo_trigger", Comparator(LESS_THAN, 1), 21, 31);
expected_foo.session_rate = Comparator(EQUAL, 10);
expected_foo.availability = Comparator(LESS_THAN, 0);
EXPECT_EQ(expected_foo, foo);
FeatureConfig bar = configuration_.GetFeatureConfig(kChromeTestFeatureBar);
EXPECT_FALSE(bar.valid);
FeatureConfig qux = configuration_.GetFeatureConfig(kChromeTestFeatureQux);
EXPECT_TRUE(qux.valid);
FeatureConfig expected_qux;
expected_qux.valid = true;
expected_qux.used =
EventConfig("qux_used", Comparator(GREATER_THAN_OR_EQUAL, 2), 99, 42);
expected_qux.trigger =
EventConfig("qux_trigger", Comparator(ANY, 0), 103, 104);
expected_qux.event_configs.insert(
EventConfig("q0", Comparator(LESS_THAN, 10), 20, 30));
expected_qux.event_configs.insert(
EventConfig("q1", Comparator(GREATER_THAN, 11), 21, 31));
expected_qux.event_configs.insert(
EventConfig("q2", Comparator(LESS_THAN_OR_EQUAL, 12), 22, 32));
expected_qux.event_configs.insert(
EventConfig("q3", Comparator(GREATER_THAN_OR_EQUAL, 13), 23, 33));
expected_qux.event_configs.insert(
EventConfig("q4", Comparator(EQUAL, 14), 24, 34));
expected_qux.event_configs.insert(
EventConfig("q5", Comparator(NOT_EQUAL, 15), 25, 35));
expected_qux.session_rate = Comparator(NOT_EQUAL, 13);
expected_qux.availability = Comparator(EQUAL, 0);
EXPECT_EQ(expected_qux, qux);
}
TEST_F(ChromeVariationsConfigurationTest, CheckedInConfigIsReadable) {
base::test::ScopedFeatureList local_feature_list;
local_feature_list.InitWithFeatureState(kIPHDummyFeature, true);
base::HistogramTester histogram_tester;
FeatureVector features;
features.push_back(&kIPHDummyFeature);
GroupVector groups;
LoadConfigs(features, groups);
FeatureConfig expected;
expected.valid = true;
expected.availability = Comparator(LESS_THAN, 0);
expected.session_rate = Comparator(LESS_THAN, 0);
expected.trigger =
EventConfig("dummy_feature_iph_trigger", Comparator(LESS_THAN, 0), 1, 1);
expected.used =
EventConfig("dummy_feature_action", Comparator(LESS_THAN, 0), 1, 1);
const FeatureConfig& config =
configuration_.GetFeatureConfig(kIPHDummyFeature);
EXPECT_EQ(expected, config);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::SUCCESS_FROM_SOURCE), 1);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 1);
}
TEST_F(ChromeVariationsConfigurationTest,
CheckedInConfigButDisabledFeatureIsInvalid) {
base::test::ScopedFeatureList local_feature_list;
local_feature_list.InitWithFeatureState(kIPHDummyFeature, false);
base::HistogramTester histogram_tester;
FeatureVector features;
features.push_back(&kIPHDummyFeature);
GroupVector groups;
LoadConfigs(features, groups);
FeatureConfig expected;
expected.valid = false;
const FeatureConfig& config =
configuration_.GetFeatureConfig(kIPHDummyFeature);
EXPECT_EQ(expected, config);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE_NO_FIELD_TRIAL), 1);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 1);
}
TEST_F(ChromeVariationsConfigurationTest, NonExistingConfigIsInvalid) {
base::HistogramTester histogram_tester;
FeatureVector features;
features.push_back(&kChromeTestFeatureFoo);
GroupVector groups;
LoadConfigs(features, groups);
FeatureConfig expected;
expected.valid = false;
const FeatureConfig& config =
configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_EQ(expected, config);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE_NO_FIELD_TRIAL), 1);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 1);
}
TEST_F(ChromeVariationsConfigurationTest, ParseValidSnoozeParams) {
std::map<std::string, std::string> foo_params;
foo_params["snooze_params"] = "max_limit:5, snooze_interval:3";
foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
GroupVector groups;
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_EQ(foo.snooze_params.max_limit, 5u);
EXPECT_EQ(foo.snooze_params.snooze_interval, 3u);
EXPECT_TRUE(foo.valid);
}
TEST_F(ChromeVariationsConfigurationTest, UnorderedSnoozeParams) {
std::map<std::string, std::string> foo_params;
foo_params["snooze_params"] = "snooze_interval:3, max_limit:3";
foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
GroupVector groups;
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_EQ(foo.snooze_params.max_limit, 3u);
EXPECT_EQ(foo.snooze_params.snooze_interval, 3u);
EXPECT_TRUE(foo.valid);
}
TEST_F(ChromeVariationsConfigurationTest, InvalidMaxLimitSnoozeParams) {
std::map<std::string, std::string> foo_params;
foo_params["snooze_params"] = "max_limit:e, snooze_interval:3";
foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
GroupVector groups;
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_EQ(foo.snooze_params.max_limit, 0u);
EXPECT_EQ(foo.snooze_params.snooze_interval, 0u);
EXPECT_FALSE(foo.valid);
}
TEST_F(ChromeVariationsConfigurationTest, InvalidIntervalSnoozeParams) {
std::map<std::string, std::string> foo_params;
foo_params["snooze_params"] = "max_limit:3, snooze_interval:e";
foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
GroupVector groups;
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_EQ(foo.snooze_params.max_limit, 0u);
EXPECT_EQ(foo.snooze_params.snooze_interval, 0u);
EXPECT_FALSE(foo.valid);
}
TEST_F(ChromeVariationsConfigurationTest, IncompleteSnoozeParams) {
std::map<std::string, std::string> foo_params;
foo_params["snooze_params"] = "max_limit:3";
foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
GroupVector groups;
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_EQ(foo.snooze_params.max_limit, 0u);
EXPECT_EQ(foo.snooze_params.snooze_interval, 0u);
EXPECT_FALSE(foo.valid);
}
TEST_F(ChromeVariationsConfigurationTest,
DisabledGroupShouldHaveInvalidConfig) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitWithFeatures(
{} /* enabled_features */, {kChromeTestGroupOne} /* disabled_features */);
base::HistogramTester histogram_tester;
FeatureVector features;
GroupVector groups = {&kChromeTestGroupOne};
LoadConfigs(features, groups);
GroupConfig group_one_config =
configuration_.GetGroupConfig(kChromeTestGroupOne);
EXPECT_FALSE(group_one_config.valid);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE_NO_FIELD_TRIAL), 1);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 1);
}
TEST_F(ChromeVariationsConfigurationTest, ParseSingleGroup) {
std::map<std::string, std::string> group_one_params;
group_one_params["event_trigger"] =
"name:opened_chrome_home;comparator:any;window:0;storage:360";
group_one_params["event_1"] =
"name:user_has_seen_dino;comparator:>=1;window:120;storage:180";
group_one_params["event_2"] =
"name:user_opened_app_menu;comparator:<=0;window:120;storage:180";
group_one_params["event_3"] =
"name:user_opened_downloads_home;comparator:any;window:0;storage:360";
SetFeatureParams(kChromeTestGroupOne, group_one_params);
base::HistogramTester histogram_tester;
FeatureVector features;
GroupVector groups = {&kChromeTestGroupOne};
LoadConfigs(features, groups);
GroupConfig group_one = configuration_.GetGroupConfig(kChromeTestGroupOne);
EXPECT_TRUE(group_one.valid);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::SUCCESS), 1);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 1);
GroupConfig expected_group_one;
expected_group_one.valid = true;
expected_group_one.trigger =
EventConfig("opened_chrome_home", Comparator(ANY, 0), 0, 360);
expected_group_one.event_configs.insert(EventConfig(
"user_has_seen_dino", Comparator(GREATER_THAN_OR_EQUAL, 1), 120, 180));
expected_group_one.event_configs.insert(EventConfig(
"user_opened_app_menu", Comparator(LESS_THAN_OR_EQUAL, 0), 120, 180));
expected_group_one.event_configs.insert(
EventConfig("user_opened_downloads_home", Comparator(ANY, 0), 0, 360));
EXPECT_EQ(expected_group_one, group_one);
}
TEST_F(ChromeVariationsConfigurationTest, EmptyGroupIsInvalid) {
std::map<std::string, std::string> group_one_params;
SetFeatureParams(kChromeTestGroupOne, group_one_params);
base::HistogramTester histogram_tester;
FeatureVector features;
GroupVector groups = {&kChromeTestGroupOne};
LoadConfigs(features, groups);
GroupConfig group_one = configuration_.GetGroupConfig(kChromeTestGroupOne);
EXPECT_FALSE(group_one.valid);
GroupConfig expected_group_one;
expected_group_one.valid = false;
EXPECT_EQ(expected_group_one, group_one);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE_NO_FIELD_TRIAL), 1);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 1);
}
TEST_F(ChromeVariationsConfigurationTest, GroupOnlyTriggerIsValid) {
std::map<std::string, std::string> group_one_params;
group_one_params["event_trigger"] =
"name:et;comparator:any;window:0;storage:360";
SetFeatureParams(kChromeTestGroupOne, group_one_params);
base::HistogramTester histogram_tester;
FeatureVector features;
GroupVector groups = {&kChromeTestGroupOne};
LoadConfigs(features, groups);
GroupConfig group_one = configuration_.GetGroupConfig(kChromeTestGroupOne);
EXPECT_TRUE(group_one.valid);
GroupConfig expected_group_one;
expected_group_one.valid = true;
expected_group_one.trigger = EventConfig("et", Comparator(ANY, 0), 0, 360);
EXPECT_EQ(expected_group_one, group_one);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::SUCCESS), 1);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 1);
}
TEST_F(ChromeVariationsConfigurationTest, GroupIgnoresInvalidConfigKeys) {
base::HistogramTester histogram_tester;
std::map<std::string, std::string> group_one_params;
group_one_params["event_trigger"] =
"name:et;comparator:any;window:0;storage:360";
group_one_params["not_there_yet"] = "bogus value"; // Unrecognized.
group_one_params["still_not_there"] = "another bogus value"; // Unrecognized.
group_one_params["x_this_is_ignored"] = "this value is ignored"; // Ignored.
SetFeatureParams(kChromeTestGroupOne, group_one_params);
FeatureVector features;
GroupVector groups = {&kChromeTestGroupOne};
LoadConfigs(features, groups);
GroupConfig group_one = configuration_.GetGroupConfig(kChromeTestGroupOne);
EXPECT_TRUE(group_one.valid);
GroupConfig expected_group_one;
expected_group_one.valid = true;
expected_group_one.trigger = EventConfig("et", Comparator(ANY, 0), 0, 360);
EXPECT_EQ(expected_group_one, group_one);
// Exactly 2 keys should be unrecognized and not ignored.
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE_UNKNOWN_KEY), 2);
}
TEST_F(ChromeVariationsConfigurationTest,
GroupInvalidSessionRateCausesInvalidConfig) {
std::map<std::string, std::string> group_one_params;
group_one_params["event_used"] =
"name:eu;comparator:any;window:1;storage:360";
group_one_params["event_trigger"] =
"name:et;comparator:any;window:0;storage:360";
group_one_params["session_rate"] = "bogus value";
SetFeatureParams(kChromeTestGroupOne, group_one_params);
base::HistogramTester histogram_tester;
FeatureVector features;
GroupVector groups = {&kChromeTestGroupOne};
LoadConfigs(features, groups);
GroupConfig group_one = configuration_.GetGroupConfig(kChromeTestGroupOne);
EXPECT_FALSE(group_one.valid);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE_SESSION_RATE_PARSE),
1);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE), 1);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 2);
}
TEST_F(ChromeVariationsConfigurationTest,
GroupInvalidTriggerCausesInvalidConfig) {
std::map<std::string, std::string> group_one_params;
group_one_params["event_1"] = "name:eu;comparator:any;window:0;storage:360";
group_one_params["event_trigger"] = "bogus value";
SetFeatureParams(kChromeTestGroupOne, group_one_params);
base::HistogramTester histogram_tester;
FeatureVector features;
GroupVector groups = {&kChromeTestGroupOne};
LoadConfigs(features, groups);
GroupConfig group_one = configuration_.GetGroupConfig(kChromeTestGroupOne);
EXPECT_FALSE(group_one.valid);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE_TRIGGER_EVENT_PARSE),
1);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE), 1);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(
stats::ConfigParsingEvent::FAILURE_TRIGGER_EVENT_MISSING),
1);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 3);
}
TEST_F(ChromeVariationsConfigurationTest,
GroupInvalidEventConfigCausesInvalidConfig) {
std::map<std::string, std::string> group_one_params;
group_one_params["event_used"] =
"name:eu;comparator:any;window:0;storage:360";
group_one_params["event_trigger"] =
"name:et;comparator:any;window:0;storage:360";
group_one_params["event_used_0"] = "bogus value";
SetFeatureParams(kChromeTestGroupOne, group_one_params);
FeatureVector features;
GroupVector groups = {&kChromeTestGroupOne};
LoadConfigs(features, groups);
GroupConfig group_one = configuration_.GetGroupConfig(kChromeTestGroupOne);
EXPECT_FALSE(group_one.valid);
}
TEST_F(ChromeVariationsConfigurationTest, GroupMultipleEventsWithSameName) {
std::map<std::string, std::string> group_one_params;
group_one_params["event_trigger"] =
"name:foo;comparator:<1;window:21;storage:31";
group_one_params["event_2"] = "name:foo;comparator:>2;window:22;storage:32";
group_one_params["event_3"] = "name:foo;comparator:<=3;window:23;storage:33";
group_one_params["session_rate"] = "any";
SetFeatureParams(kChromeTestGroupOne, group_one_params);
FeatureVector features;
GroupVector groups = {&kChromeTestGroupOne};
LoadConfigs(features, groups);
GroupConfig group_one = configuration_.GetGroupConfig(kChromeTestGroupOne);
EXPECT_TRUE(group_one.valid);
GroupConfig expected_group_one;
expected_group_one.valid = true;
expected_group_one.trigger =
EventConfig("foo", Comparator(LESS_THAN, 1), 21, 31);
expected_group_one.event_configs.insert(
EventConfig("foo", Comparator(GREATER_THAN, 2), 22, 32));
expected_group_one.event_configs.insert(
EventConfig("foo", Comparator(LESS_THAN_OR_EQUAL, 3), 23, 33));
expected_group_one.session_rate = Comparator(ANY, 0);
EXPECT_EQ(expected_group_one, group_one);
}
TEST_F(ChromeVariationsConfigurationTest, ParseMultipleGroups) {
std::map<std::string, std::string> group_one_params;
group_one_params["event_trigger"] =
"name:foo_trigger;comparator:<1;window:21;storage:31";
group_one_params["session_rate"] = "==10";
SetFeatureParams(kChromeTestGroupOne, group_one_params);
std::map<std::string, std::string> group_two_params;
group_two_params["event_trigger"] = "bogus value";
SetFeatureParams(kChromeTestGroupTwo, group_two_params);
std::map<std::string, std::string> group_three_params;
group_three_params["event_trigger"] =
"name:qux_trigger;comparator:ANY;window:103;storage:104";
group_three_params["event_0"] = "name:q0;comparator:<10;window:20;storage:30";
group_three_params["event_1"] = "name:q1;comparator:>11;window:21;storage:31";
group_three_params["event_2"] =
"name:q2;comparator:<=12;window:22;storage:32";
group_three_params["event_3"] =
"name:q3;comparator:>=13;window:23;storage:33";
group_three_params["event_4"] =
"name:q4;comparator:==14;window:24;storage:34";
group_three_params["event_5"] =
"name:q5;comparator:!=15;window:25;storage:35";
group_three_params["session_rate"] = "!=13";
SetFeatureParams(kChromeTestGroupThree, group_three_params);
FeatureVector features;
GroupVector groups = {&kChromeTestGroupOne, &kChromeTestGroupTwo,
&kChromeTestGroupThree};
LoadConfigs(features, groups);
GroupConfig group_one = configuration_.GetGroupConfig(kChromeTestGroupOne);
EXPECT_TRUE(group_one.valid);
GroupConfig expected_group_one;
expected_group_one.valid = true;
expected_group_one.trigger =
EventConfig("foo_trigger", Comparator(LESS_THAN, 1), 21, 31);
expected_group_one.session_rate = Comparator(EQUAL, 10);
EXPECT_EQ(expected_group_one, group_one);
GroupConfig group_two = configuration_.GetGroupConfig(kChromeTestGroupTwo);
EXPECT_FALSE(group_two.valid);
GroupConfig group_three =
configuration_.GetGroupConfig(kChromeTestGroupThree);
EXPECT_TRUE(group_three.valid);
GroupConfig expected_group_three;
expected_group_three.valid = true;
expected_group_three.trigger =
EventConfig("qux_trigger", Comparator(ANY, 0), 103, 104);
expected_group_three.event_configs.insert(
EventConfig("q0", Comparator(LESS_THAN, 10), 20, 30));
expected_group_three.event_configs.insert(
EventConfig("q1", Comparator(GREATER_THAN, 11), 21, 31));
expected_group_three.event_configs.insert(
EventConfig("q2", Comparator(LESS_THAN_OR_EQUAL, 12), 22, 32));
expected_group_three.event_configs.insert(
EventConfig("q3", Comparator(GREATER_THAN_OR_EQUAL, 13), 23, 33));
expected_group_three.event_configs.insert(
EventConfig("q4", Comparator(EQUAL, 14), 24, 34));
expected_group_three.event_configs.insert(
EventConfig("q5", Comparator(NOT_EQUAL, 15), 25, 35));
expected_group_three.session_rate = Comparator(NOT_EQUAL, 13);
EXPECT_EQ(expected_group_three, group_three);
}
TEST_F(ChromeVariationsConfigurationTest, CheckedInGroupConfigIsReadable) {
base::test::ScopedFeatureList local_feature_list;
local_feature_list.InitWithFeatureState(kIPHDummyGroup, true);
base::HistogramTester histogram_tester;
FeatureVector features;
GroupVector groups = {&kIPHDummyGroup};
LoadConfigs(features, groups);
GroupConfig expected;
expected.valid = true;
expected.session_rate = Comparator(LESS_THAN, 0);
expected.trigger =
EventConfig("dummy_group_iph_trigger", Comparator(LESS_THAN, 0), 1, 1);
const GroupConfig& config = configuration_.GetGroupConfig(kIPHDummyGroup);
EXPECT_EQ(expected, config);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::SUCCESS_FROM_SOURCE), 1);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 1);
}
TEST_F(ChromeVariationsConfigurationTest,
CheckedInGroupConfigButDisabledGroupIsInvalid) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitWithFeatures(
{} /* enabled_features */, {kIPHDummyGroup} /* disabled_features */);
base::HistogramTester histogram_tester;
FeatureVector features;
GroupVector groups = {&kIPHDummyGroup};
LoadConfigs(features, groups);
GroupConfig expected;
expected.valid = false;
const GroupConfig& config = configuration_.GetGroupConfig(kIPHDummyGroup);
EXPECT_EQ(expected, config);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE_NO_FIELD_TRIAL), 1);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 1);
}
TEST_F(ChromeVariationsConfigurationTest, NonExistingGroupConfigIsInvalid) {
base::HistogramTester histogram_tester;
FeatureVector features;
GroupVector groups = {&kIPHDummyGroup};
LoadConfigs(features, groups);
GroupConfig expected;
expected.valid = false;
const GroupConfig& config = configuration_.GetGroupConfig(kIPHDummyGroup);
EXPECT_EQ(expected, config);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::FAILURE_NO_FIELD_TRIAL), 1);
histogram_tester.ExpectTotalCount(kConfigParseEventName, 1);
}
TEST_F(ChromeVariationsConfigurationTest,
ParseExpandsBlockedByGroupNameIntoFeatures) {
base::test::ScopedFeatureList scoped_feature_list;
base::HistogramTester histogram_tester;
std::map<std::string, std::string> foo_params;
foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
foo_params["blocked_by"] = "test_group_one";
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
std::map<std::string, std::string> bar_params;
bar_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
bar_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
bar_params["groups"] = "test_group_one";
SetFeatureParams(kChromeTestFeatureBar, bar_params);
FeatureVector features = {&kChromeTestFeatureFoo, &kChromeTestFeatureBar};
GroupVector groups = {&kChromeTestGroupOne};
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_EQ(true, foo.valid);
FeatureConfig expected_foo;
expected_foo.valid = true;
expected_foo.used = EventConfig("eu", Comparator(ANY, 0), 0, 360);
expected_foo.trigger = EventConfig("et", Comparator(ANY, 0), 0, 360);
expected_foo.blocked_by =
CreateBlockedByExplicit({kChromeTestFeatureBar.name});
EXPECT_EQ(expected_foo, foo);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::SUCCESS), 2);
}
TEST_F(ChromeVariationsConfigurationTest,
ParseExpandsBlockedByEmptyGroupIntoEmptyList) {
base::HistogramTester histogram_tester;
std::map<std::string, std::string> foo_params;
foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
foo_params["blocked_by"] = "test_group_one";
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
FeatureVector features = {&kChromeTestFeatureFoo};
GroupVector groups = {&kChromeTestGroupOne};
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_EQ(true, foo.valid);
FeatureConfig expected_foo;
expected_foo.valid = true;
expected_foo.used = EventConfig("eu", Comparator(ANY, 0), 0, 360);
expected_foo.trigger = EventConfig("et", Comparator(ANY, 0), 0, 360);
expected_foo.blocked_by = CreateBlockedByExplicit({});
EXPECT_EQ(expected_foo, foo);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::SUCCESS), 1);
}
TEST_F(ChromeVariationsConfigurationTest,
ParseExpandsBlockedByGroupAndFeature) {
base::HistogramTester histogram_tester;
std::map<std::string, std::string> foo_params;
foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
foo_params["blocked_by"] = "test_group_one,test_qux";
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
std::map<std::string, std::string> bar_params;
bar_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
bar_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
bar_params["groups"] = "test_group_one";
SetFeatureParams(kChromeTestFeatureBar, bar_params);
std::map<std::string, std::string> qux_params;
qux_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
qux_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
SetFeatureParams(kChromeTestFeatureQux, qux_params);
FeatureVector features = {&kChromeTestFeatureFoo, &kChromeTestFeatureBar,
&kChromeTestFeatureQux};
GroupVector groups = {&kChromeTestGroupOne};
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_EQ(true, foo.valid);
FeatureConfig expected_foo;
expected_foo.valid = true;
expected_foo.used = EventConfig("eu", Comparator(ANY, 0), 0, 360);
expected_foo.trigger = EventConfig("et", Comparator(ANY, 0), 0, 360);
expected_foo.blocked_by = CreateBlockedByExplicit(
{kChromeTestFeatureBar.name, kChromeTestFeatureQux.name});
EXPECT_EQ(expected_foo, foo);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::SUCCESS), 3);
}
TEST_F(ChromeVariationsConfigurationTest, ParseExpandsBlockedByMultipleGroups) {
base::HistogramTester histogram_tester;
std::map<std::string, std::string> foo_params;
foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
foo_params["blocked_by"] = "test_group_one,test_group_two";
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
std::map<std::string, std::string> bar_params;
bar_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
bar_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
bar_params["groups"] = "test_group_one";
SetFeatureParams(kChromeTestFeatureBar, bar_params);
std::map<std::string, std::string> qux_params;
qux_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
qux_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
qux_params["groups"] = "test_group_two";
SetFeatureParams(kChromeTestFeatureQux, qux_params);
FeatureVector features = {&kChromeTestFeatureFoo, &kChromeTestFeatureBar,
&kChromeTestFeatureQux};
GroupVector groups = {&kChromeTestGroupOne, &kChromeTestGroupTwo};
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_EQ(true, foo.valid);
FeatureConfig expected_foo;
expected_foo.valid = true;
expected_foo.used = EventConfig("eu", Comparator(ANY, 0), 0, 360);
expected_foo.trigger = EventConfig("et", Comparator(ANY, 0), 0, 360);
expected_foo.blocked_by = CreateBlockedByExplicit(
{kChromeTestFeatureBar.name, kChromeTestFeatureQux.name});
EXPECT_EQ(expected_foo, foo);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::SUCCESS), 3);
}
TEST_F(ChromeVariationsConfigurationTest,
ParseExpandsBlockedByFeatureAppearsMultipleTimes) {
base::HistogramTester histogram_tester;
std::map<std::string, std::string> foo_params;
foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
foo_params["blocked_by"] = "test_bar,test_group_one,test_group_two";
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
std::map<std::string, std::string> bar_params;
bar_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
bar_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
bar_params["groups"] = "test_group_one,test_group_two";
SetFeatureParams(kChromeTestFeatureBar, bar_params);
FeatureVector features = {&kChromeTestFeatureFoo, &kChromeTestFeatureBar};
GroupVector groups = {&kChromeTestGroupOne, &kChromeTestGroupTwo};
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_EQ(true, foo.valid);
// Even though test_bar is in the original foo blocked_by and is in group one
// and group two, it should only show up in the flattened list once.
EXPECT_EQ(1u, foo.blocked_by.affected_features->size());
FeatureConfig expected_foo;
expected_foo.valid = true;
expected_foo.used = EventConfig("eu", Comparator(ANY, 0), 0, 360);
expected_foo.trigger = EventConfig("et", Comparator(ANY, 0), 0, 360);
expected_foo.blocked_by =
CreateBlockedByExplicit({kChromeTestFeatureBar.name});
EXPECT_EQ(expected_foo, foo);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::SUCCESS), 2);
}
TEST_F(ChromeVariationsConfigurationTest,
ParseExpandsSessionRateImpactGroupNameIntoFeatures) {
base::HistogramTester histogram_tester;
std::map<std::string, std::string> foo_params;
foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
foo_params["session_rate_impact"] = "test_group_one";
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
std::map<std::string, std::string> bar_params;
bar_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
bar_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
bar_params["groups"] = "test_group_one";
SetFeatureParams(kChromeTestFeatureBar, bar_params);
FeatureVector features = {&kChromeTestFeatureFoo, &kChromeTestFeatureBar};
GroupVector groups = {&kChromeTestGroupOne};
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_EQ(true, foo.valid);
FeatureConfig expected_foo;
expected_foo.valid = true;
expected_foo.used = EventConfig("eu", Comparator(ANY, 0), 0, 360);
expected_foo.trigger = EventConfig("et", Comparator(ANY, 0), 0, 360);
expected_foo.session_rate_impact =
CreateSessionRateImpactExplicit({kChromeTestFeatureBar.name});
EXPECT_EQ(expected_foo, foo);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::SUCCESS), 2);
}
TEST_F(ChromeVariationsConfigurationTest,
ParseExpandsSessionRateEmptyGroupIntoEmptyList) {
base::HistogramTester histogram_tester;
std::map<std::string, std::string> foo_params;
foo_params["event_used"] = "name:eu;comparator:any;window:0;storage:360";
foo_params["event_trigger"] = "name:et;comparator:any;window:0;storage:360";
foo_params["session_rate_impact"] = "test_group_one";
SetFeatureParams(kChromeTestFeatureFoo, foo_params);
FeatureVector features = {&kChromeTestFeatureFoo};
GroupVector groups = {&kChromeTestGroupOne};
LoadConfigs(features, groups);
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_EQ(true, foo.valid);
FeatureConfig expected_foo;
expected_foo.valid = true;
expected_foo.used = EventConfig("eu", Comparator(ANY, 0), 0, 360);
expected_foo.trigger = EventConfig("et", Comparator(ANY, 0), 0, 360);
expected_foo.session_rate_impact = CreateSessionRateImpactExplicit({});
EXPECT_EQ(expected_foo, foo);
histogram_tester.ExpectBucketCount(
kConfigParseEventName,
static_cast<int>(stats::ConfigParsingEvent::SUCCESS), 1);
}
#if BUILDFLAG(IS_CHROMEOS)
TEST_F(ChromeVariationsConfigurationTest, UpdateConfigs) {
FeatureConfig expected_foo;
expected_foo.valid = true;
expected_foo.used =
EventConfig("page_download_started", Comparator(ANY, 0), 0, 360);
expected_foo.trigger =
EventConfig("opened_chrome_home", Comparator(ANY, 0), 0, 360);
expected_foo.event_configs.insert(EventConfig(
"user_has_seen_dino", Comparator(GREATER_THAN_OR_EQUAL, 1), 120, 180));
expected_foo.event_configs.insert(EventConfig(
"user_opened_app_menu", Comparator(LESS_THAN_OR_EQUAL, 0), 120, 180));
expected_foo.event_configs.insert(
EventConfig("user_opened_downloads_home", Comparator(ANY, 0), 0, 360));
auto provider = std::make_unique<TestConfigurationProvider>();
provider->SetConfig(expected_foo);
configuration_.UpdateConfig(kChromeTestFeatureFoo, provider.get());
FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_EQ(expected_foo, foo);
// Update config, removing `event_1` and `event_3`.
expected_foo = FeatureConfig();
expected_foo.valid = true;
expected_foo.used =
EventConfig("page_download_started", Comparator(ANY, 0), 0, 360);
expected_foo.trigger =
EventConfig("opened_chrome_home", Comparator(ANY, 0), 0, 360);
expected_foo.event_configs.insert(EventConfig(
"user_opened_app_menu", Comparator(LESS_THAN_OR_EQUAL, 0), 120, 180));
EXPECT_NE(expected_foo, foo);
provider->SetConfig(expected_foo);
configuration_.UpdateConfig(kChromeTestFeatureFoo, provider.get());
foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
EXPECT_EQ(expected_foo, foo);
}
TEST_F(ChromeVariationsConfigurationTest, GetEventPrefixes) {
ConfigurationProviderList providers;
providers.emplace_back(std::make_unique<TestConfigurationProvider>());
configuration_.LoadConfigs(providers, /*features=*/{&kChromeTestFeatureFoo},
/*groups=*/{});
const auto& prefixes = configuration_.GetRegisteredAllowedEventPrefixes();
EXPECT_EQ(1u, prefixes.size());
EXPECT_TRUE(prefixes.contains("TestEventPrefix"));
}
#endif
} // namespace feature_engagement