| Index: components/variations/variations_seed_processor_unittest.cc
|
| diff --git a/components/variations/variations_seed_processor_unittest.cc b/components/variations/variations_seed_processor_unittest.cc
|
| index 437c611fb39878a917a3879dea2189df7b38e69a..dad2406da307bb74a607d344882ba9562fbec035 100644
|
| --- a/components/variations/variations_seed_processor_unittest.cc
|
| +++ b/components/variations/variations_seed_processor_unittest.cc
|
| @@ -9,6 +9,7 @@
|
|
|
| #include "base/bind.h"
|
| #include "base/command_line.h"
|
| +#include "base/feature_list.h"
|
| #include "base/strings/string_split.h"
|
| #include "base/strings/utf_string_conversions.h"
|
| #include "components/variations/processed_study.h"
|
| @@ -119,16 +120,22 @@ class VariationsSeedProcessorTest : public ::testing::Test {
|
| }
|
|
|
| bool CreateTrialFromStudy(const Study* study) {
|
| + return CreateTrialFromStudyWithFeatureList(study, &feature_list_);
|
| + }
|
| +
|
| + bool CreateTrialFromStudyWithFeatureList(const Study* study,
|
| + base::FeatureList* feature_list) {
|
| ProcessedStudy processed_study;
|
| if (processed_study.Init(study, false)) {
|
| VariationsSeedProcessor().CreateTrialFromStudy(
|
| - processed_study, override_callback_.callback());
|
| + processed_study, override_callback_.callback(), feature_list);
|
| return true;
|
| }
|
| return false;
|
| }
|
|
|
| protected:
|
| + base::FeatureList feature_list_;
|
| TestOverrideStringCallback override_callback_;
|
|
|
| private:
|
| @@ -226,23 +233,27 @@ TEST_F(VariationsSeedProcessorTest,
|
| // Check that adding [expired, non-expired] activates the non-expired one.
|
| ASSERT_EQ(std::string(), base::FieldTrialList::FindFullName(kTrialName));
|
| {
|
| + base::FeatureList feature_list;
|
| base::FieldTrialList field_trial_list(NULL);
|
| study1->set_expiry_date(TimeToProtoTime(year_ago));
|
| seed_processor.CreateTrialsFromSeed(
|
| seed, "en-CA", base::Time::Now(), version, Study_Channel_STABLE,
|
| - Study_FormFactor_DESKTOP, "", "", "", override_callback_.callback());
|
| + Study_FormFactor_DESKTOP, "", "", "", override_callback_.callback(),
|
| + &feature_list);
|
| EXPECT_EQ(kGroup1Name, base::FieldTrialList::FindFullName(kTrialName));
|
| }
|
|
|
| // Check that adding [non-expired, expired] activates the non-expired one.
|
| ASSERT_EQ(std::string(), base::FieldTrialList::FindFullName(kTrialName));
|
| {
|
| + base::FeatureList feature_list;
|
| base::FieldTrialList field_trial_list(NULL);
|
| study1->clear_expiry_date();
|
| study2->set_expiry_date(TimeToProtoTime(year_ago));
|
| seed_processor.CreateTrialsFromSeed(
|
| seed, "en-CA", base::Time::Now(), version, Study_Channel_STABLE,
|
| - Study_FormFactor_DESKTOP, "", "", "", override_callback_.callback());
|
| + Study_FormFactor_DESKTOP, "", "", "", override_callback_.callback(),
|
| + &feature_list);
|
| EXPECT_EQ(kGroup1Name, base::FieldTrialList::FindFullName(kTrialName));
|
| }
|
| }
|
| @@ -447,7 +458,7 @@ TEST_F(VariationsSeedProcessorTest, StartsActive) {
|
| seed_processor.CreateTrialsFromSeed(
|
| seed, "en-CA", base::Time::Now(), base::Version("20.0.0.0"),
|
| Study_Channel_STABLE, Study_FormFactor_DESKTOP, "", "", "",
|
| - override_callback_.callback());
|
| + override_callback_.callback(), &feature_list_);
|
|
|
| // Non-specified and ACTIVATION_EXPLICIT should not start active, but
|
| // ACTIVATION_AUTO should.
|
| @@ -504,4 +515,151 @@ TEST_F(VariationsSeedProcessorTest, ForcingFlagAlreadyForced) {
|
| EXPECT_EQ(kExperimentId, id);
|
| }
|
|
|
| +TEST_F(VariationsSeedProcessorTest, FeatureEnabledOrDisableByTrial) {
|
| + struct base::Feature kFeatureOffByDefault {
|
| + "kOff", base::FEATURE_DISABLED_BY_DEFAULT
|
| + };
|
| + struct base::Feature kFeatureOnByDefault {
|
| + "kOn", base::FEATURE_ENABLED_BY_DEFAULT
|
| + };
|
| + struct base::Feature kUnrelatedFeature {
|
| + "kUnrelated", base::FEATURE_DISABLED_BY_DEFAULT
|
| + };
|
| +
|
| + struct {
|
| + const char* enable_feature;
|
| + const char* disable_feature;
|
| + bool expected_feature_off_state;
|
| + bool expected_feature_on_state;
|
| + } test_cases[] = {
|
| + {nullptr, nullptr, false, true},
|
| + {kFeatureOnByDefault.name, nullptr, false, true},
|
| + {kFeatureOffByDefault.name, nullptr, true, true},
|
| + {nullptr, kFeatureOnByDefault.name, false, false},
|
| + {nullptr, kFeatureOffByDefault.name, false, true},
|
| + };
|
| +
|
| + for (size_t i = 0; i < arraysize(test_cases); i++) {
|
| + const auto& test_case = test_cases[i];
|
| +
|
| + base::FieldTrialList field_trial_list(NULL);
|
| + base::FeatureList::ClearInstanceForTesting();
|
| + scoped_ptr<base::FeatureList> feature_list(new base::FeatureList);
|
| +
|
| + Study study;
|
| + study.set_name("Study1");
|
| + study.set_default_experiment_name("B");
|
| + AddExperiment("B", 0, &study);
|
| +
|
| + Study_Experiment* experiment = AddExperiment("A", 1, &study);
|
| + Study_Experiment_FeatureAssociation* association =
|
| + experiment->mutable_feature_association();
|
| + if (test_case.enable_feature)
|
| + association->add_enable_feature(test_case.enable_feature);
|
| + else if (test_case.disable_feature)
|
| + association->add_disable_feature(test_case.disable_feature);
|
| +
|
| + EXPECT_TRUE(
|
| + CreateTrialFromStudyWithFeatureList(&study, feature_list.get()));
|
| + base::FeatureList::SetInstance(feature_list.Pass());
|
| +
|
| + // |kUnrelatedFeature| should not be affected.
|
| + EXPECT_FALSE(base::FeatureList::IsEnabled(kUnrelatedFeature));
|
| +
|
| + // Before the associated feature is queried, the trial shouldn't be active.
|
| + EXPECT_FALSE(IsFieldTrialActive(study.name()));
|
| +
|
| + EXPECT_EQ(test_case.expected_feature_off_state,
|
| + base::FeatureList::IsEnabled(kFeatureOffByDefault));
|
| + EXPECT_EQ(test_case.expected_feature_on_state,
|
| + base::FeatureList::IsEnabled(kFeatureOnByDefault));
|
| +
|
| + // The field trial should get activated if it had a feature association.
|
| + const bool expected_field_trial_active =
|
| + test_case.enable_feature || test_case.disable_feature;
|
| + EXPECT_EQ(expected_field_trial_active, IsFieldTrialActive(study.name()));
|
| + }
|
| +}
|
| +
|
| +TEST_F(VariationsSeedProcessorTest, FeatureForcingTrialReportingGroup) {
|
| + struct base::Feature kFeatureOffByDefault {
|
| + "kOff", base::FEATURE_DISABLED_BY_DEFAULT
|
| + };
|
| + struct base::Feature kFeatureOnByDefault {
|
| + "kOn", base::FEATURE_ENABLED_BY_DEFAULT
|
| + };
|
| +
|
| + struct {
|
| + const base::Feature& feature;
|
| + bool set_forcing_feature_on;
|
| + bool set_forcing_feature_off;
|
| + const char* enable_features_command_line;
|
| + const char* disable_features_command_line;
|
| + bool expected_feature_state;
|
| + bool expected_trial_activated;
|
| + } test_cases[] = {
|
| + {kFeatureOffByDefault, false, false, "", "", false, false},
|
| + {kFeatureOffByDefault, true, false, kFeatureOffByDefault.name, "", true,
|
| + true},
|
| + {kFeatureOffByDefault, false, true, kFeatureOffByDefault.name, "", true,
|
| + false},
|
| + {kFeatureOffByDefault, false, true, "", kFeatureOffByDefault.name, false,
|
| + true},
|
| + {kFeatureOffByDefault, true, false, "", kFeatureOffByDefault.name, false,
|
| + false},
|
| + {kFeatureOnByDefault, false, false, "", "", true, false},
|
| + {kFeatureOnByDefault, true, false, kFeatureOnByDefault.name, "", true,
|
| + true},
|
| + {kFeatureOnByDefault, false, true, kFeatureOnByDefault.name, "", true,
|
| + false},
|
| + {kFeatureOnByDefault, false, true, "", kFeatureOnByDefault.name, false,
|
| + true},
|
| + {kFeatureOnByDefault, true, false, "", kFeatureOnByDefault.name, false,
|
| + false},
|
| + };
|
| +
|
| + for (size_t i = 0; i < arraysize(test_cases); i++) {
|
| + const auto& test_case = test_cases[i];
|
| +
|
| + base::FieldTrialList field_trial_list(NULL);
|
| + base::FeatureList::ClearInstanceForTesting();
|
| + scoped_ptr<base::FeatureList> feature_list(new base::FeatureList);
|
| + feature_list->InitializeFromCommandLine(
|
| + test_case.enable_features_command_line,
|
| + test_case.disable_features_command_line);
|
| +
|
| + Study study;
|
| + study.set_name("Study1");
|
| + study.set_default_experiment_name("B");
|
| + Study_Experiment* experiment_with_probability =
|
| + AddExperiment("B", 1, &study);
|
| +
|
| + Study_Experiment* experiment = AddExperiment("A", 0, &study);
|
| + Study_Experiment_FeatureAssociation* association =
|
| + experiment->mutable_feature_association();
|
| + if (test_case.set_forcing_feature_on)
|
| + association->set_forcing_feature_on(test_case.feature.name);
|
| + else if (test_case.set_forcing_feature_off)
|
| + association->set_forcing_feature_off(test_case.feature.name);
|
| +
|
| + EXPECT_TRUE(
|
| + CreateTrialFromStudyWithFeatureList(&study, feature_list.get()));
|
| + base::FeatureList::SetInstance(feature_list.Pass());
|
| +
|
| + // Trial should not be activated initially.
|
| + EXPECT_FALSE(IsFieldTrialActive(study.name()));
|
| + EXPECT_EQ(test_case.expected_feature_state,
|
| + base::FeatureList::IsEnabled(test_case.feature));
|
| + EXPECT_EQ(test_case.expected_trial_activated,
|
| + IsFieldTrialActive(study.name()));
|
| + if (test_case.expected_trial_activated) {
|
| + EXPECT_EQ(experiment->name(),
|
| + base::FieldTrialList::FindFullName(study.name()));
|
| + } else {
|
| + EXPECT_EQ(experiment_with_probability->name(),
|
| + base::FieldTrialList::FindFullName(study.name()));
|
| + }
|
| + }
|
| +}
|
| +
|
| } // namespace variations
|
|
|