Home | History | Annotate | Download | only in variations
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/common/metrics/variations/variations_associated_data.h"
      6 
      7 #include "base/metrics/field_trial.h"
      8 #include "testing/gtest/include/gtest/gtest.h"
      9 
     10 namespace chrome_variations {
     11 
     12 namespace {
     13 
     14 // Convenience helper to retrieve the chrome_variations::VariationID for a
     15 // FieldTrial. Note that this will do the group assignment in |trial| if not
     16 // already done.
     17 VariationID GetIDForTrial(IDCollectionKey key, base::FieldTrial* trial) {
     18   return GetGoogleVariationID(key, trial->trial_name(), trial->group_name());
     19 }
     20 
     21 // Tests whether a field trial is active (i.e. group() has been called on it).
     22 bool IsFieldTrialActive(const std::string& trial_name) {
     23   base::FieldTrial::ActiveGroups active_groups;
     24   base::FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
     25   for (size_t i = 0; i < active_groups.size(); ++i) {
     26     if (active_groups[i].trial_name == trial_name)
     27       return true;
     28   }
     29   return false;
     30 }
     31 
     32 // Call FieldTrialList::FactoryGetFieldTrial() with a future expiry date.
     33 scoped_refptr<base::FieldTrial> CreateFieldTrial(
     34     const std::string& trial_name,
     35     int total_probability,
     36     const std::string& default_group_name,
     37     int* default_group_number) {
     38   return base::FieldTrialList::FactoryGetFieldTrial(
     39       trial_name, total_probability, default_group_name,
     40       base::FieldTrialList::kNoExpirationYear, 1, 1,
     41       base::FieldTrial::SESSION_RANDOMIZED, default_group_number);
     42 }
     43 
     44 }  // namespace
     45 
     46 class VariationsAssociatedDataTest : public ::testing::Test {
     47  public:
     48   VariationsAssociatedDataTest() : field_trial_list_(NULL) {
     49   }
     50 
     51   virtual ~VariationsAssociatedDataTest() {
     52     // Ensure that the maps are cleared between tests, since they are stored as
     53     // process singletons.
     54     testing::ClearAllVariationIDs();
     55   }
     56 
     57  private:
     58   base::FieldTrialList field_trial_list_;
     59 
     60   DISALLOW_COPY_AND_ASSIGN(VariationsAssociatedDataTest);
     61 };
     62 
     63 // Test that if the trial is immediately disabled, GetGoogleVariationID just
     64 // returns the empty ID.
     65 TEST_F(VariationsAssociatedDataTest, DisableImmediately) {
     66   int default_group_number = -1;
     67   scoped_refptr<base::FieldTrial> trial(
     68       CreateFieldTrial("trial", 100, "default", &default_group_number));
     69 
     70   ASSERT_EQ(default_group_number, trial->group());
     71   ASSERT_EQ(EMPTY_ID, GetIDForTrial(GOOGLE_WEB_PROPERTIES, trial.get()));
     72 }
     73 
     74 // Test that successfully associating the FieldTrial with some ID, and then
     75 // disabling the FieldTrial actually makes GetGoogleVariationID correctly
     76 // return the empty ID.
     77 TEST_F(VariationsAssociatedDataTest, DisableAfterInitialization) {
     78   const std::string default_name = "default";
     79   const std::string non_default_name = "non_default";
     80 
     81   scoped_refptr<base::FieldTrial> trial(
     82       CreateFieldTrial("trial", 100, default_name, NULL));
     83 
     84   trial->AppendGroup(non_default_name, 100);
     85   AssociateGoogleVariationID(GOOGLE_WEB_PROPERTIES, trial->trial_name(),
     86       default_name, TEST_VALUE_A);
     87   AssociateGoogleVariationID(GOOGLE_WEB_PROPERTIES, trial->trial_name(),
     88       non_default_name, TEST_VALUE_B);
     89   trial->Disable();
     90   ASSERT_EQ(default_name, trial->group_name());
     91   ASSERT_EQ(TEST_VALUE_A, GetIDForTrial(GOOGLE_WEB_PROPERTIES, trial.get()));
     92 }
     93 
     94 // Test various successful association cases.
     95 TEST_F(VariationsAssociatedDataTest, AssociateGoogleVariationID) {
     96   const std::string default_name1 = "default";
     97   scoped_refptr<base::FieldTrial> trial_true(
     98       CreateFieldTrial("d1", 10, default_name1, NULL));
     99   const std::string winner = "TheWinner";
    100   int winner_group = trial_true->AppendGroup(winner, 10);
    101 
    102   // Set GoogleVariationIDs so we can verify that they were chosen correctly.
    103   AssociateGoogleVariationID(GOOGLE_WEB_PROPERTIES, trial_true->trial_name(),
    104       default_name1, TEST_VALUE_A);
    105   AssociateGoogleVariationID(GOOGLE_WEB_PROPERTIES, trial_true->trial_name(),
    106       winner, TEST_VALUE_B);
    107 
    108   EXPECT_EQ(winner_group, trial_true->group());
    109   EXPECT_EQ(winner, trial_true->group_name());
    110   EXPECT_EQ(TEST_VALUE_B,
    111             GetIDForTrial(GOOGLE_WEB_PROPERTIES, trial_true.get()));
    112 
    113   const std::string default_name2 = "default2";
    114   scoped_refptr<base::FieldTrial> trial_false(
    115       CreateFieldTrial("d2", 10, default_name2, NULL));
    116   const std::string loser = "ALoser";
    117   const int loser_group = trial_false->AppendGroup(loser, 0);
    118 
    119   AssociateGoogleVariationID(GOOGLE_WEB_PROPERTIES, trial_false->trial_name(),
    120       default_name2, TEST_VALUE_A);
    121   AssociateGoogleVariationID(GOOGLE_WEB_PROPERTIES, trial_false->trial_name(),
    122       loser, TEST_VALUE_B);
    123 
    124   EXPECT_NE(loser_group, trial_false->group());
    125   EXPECT_EQ(TEST_VALUE_A,
    126             GetIDForTrial(GOOGLE_WEB_PROPERTIES, trial_false.get()));
    127 }
    128 
    129 // Test that not associating a FieldTrial with any IDs ensure that the empty ID
    130 // will be returned.
    131 TEST_F(VariationsAssociatedDataTest, NoAssociation) {
    132   const std::string default_name = "default";
    133   scoped_refptr<base::FieldTrial> no_id_trial(
    134       CreateFieldTrial("d3", 10, default_name, NULL));
    135 
    136   const std::string winner = "TheWinner";
    137   const int winner_group = no_id_trial->AppendGroup(winner, 10);
    138 
    139   // Ensure that despite the fact that a normal winner is elected, it does not
    140   // have a valid VariationID associated with it.
    141   EXPECT_EQ(winner_group, no_id_trial->group());
    142   EXPECT_EQ(winner, no_id_trial->group_name());
    143   EXPECT_EQ(EMPTY_ID, GetIDForTrial(GOOGLE_WEB_PROPERTIES, no_id_trial.get()));
    144 }
    145 
    146 // Ensure that the AssociateGoogleVariationIDForce works as expected.
    147 TEST_F(VariationsAssociatedDataTest, ForceAssociation) {
    148   EXPECT_EQ(EMPTY_ID,
    149             GetGoogleVariationID(GOOGLE_WEB_PROPERTIES, "trial", "group"));
    150   AssociateGoogleVariationID(GOOGLE_WEB_PROPERTIES, "trial", "group",
    151                              TEST_VALUE_A);
    152   EXPECT_EQ(TEST_VALUE_A,
    153             GetGoogleVariationID(GOOGLE_WEB_PROPERTIES, "trial", "group"));
    154   AssociateGoogleVariationID(GOOGLE_WEB_PROPERTIES, "trial", "group",
    155                              TEST_VALUE_B);
    156   EXPECT_EQ(TEST_VALUE_A,
    157             GetGoogleVariationID(GOOGLE_WEB_PROPERTIES, "trial", "group"));
    158   AssociateGoogleVariationIDForce(GOOGLE_WEB_PROPERTIES, "trial", "group",
    159                                   TEST_VALUE_B);
    160   EXPECT_EQ(TEST_VALUE_B,
    161             GetGoogleVariationID(GOOGLE_WEB_PROPERTIES, "trial", "group"));
    162 }
    163 
    164 // Ensure that two collections can coexist without affecting each other.
    165 TEST_F(VariationsAssociatedDataTest, CollectionsCoexist) {
    166   const std::string default_name = "default";
    167   int default_group_number = -1;
    168   scoped_refptr<base::FieldTrial> trial_true(
    169       CreateFieldTrial("d1", 10, default_name, &default_group_number));
    170   ASSERT_EQ(default_group_number, trial_true->group());
    171   ASSERT_EQ(default_name, trial_true->group_name());
    172 
    173   EXPECT_EQ(EMPTY_ID,
    174             GetIDForTrial(GOOGLE_WEB_PROPERTIES, trial_true.get()));
    175   EXPECT_EQ(EMPTY_ID,
    176             GetIDForTrial(GOOGLE_UPDATE_SERVICE, trial_true.get()));
    177 
    178   AssociateGoogleVariationID(GOOGLE_WEB_PROPERTIES, trial_true->trial_name(),
    179       default_name, TEST_VALUE_A);
    180   EXPECT_EQ(TEST_VALUE_A,
    181             GetIDForTrial(GOOGLE_WEB_PROPERTIES, trial_true.get()));
    182   EXPECT_EQ(EMPTY_ID,
    183             GetIDForTrial(GOOGLE_UPDATE_SERVICE, trial_true.get()));
    184 
    185   AssociateGoogleVariationID(GOOGLE_UPDATE_SERVICE, trial_true->trial_name(),
    186       default_name, TEST_VALUE_A);
    187   EXPECT_EQ(TEST_VALUE_A,
    188             GetIDForTrial(GOOGLE_WEB_PROPERTIES, trial_true.get()));
    189   EXPECT_EQ(TEST_VALUE_A,
    190             GetIDForTrial(GOOGLE_UPDATE_SERVICE, trial_true.get()));
    191 }
    192 
    193 TEST_F(VariationsAssociatedDataTest, AssociateVariationParams) {
    194   const std::string kTrialName = "AssociateVariationParams";
    195 
    196   {
    197     std::map<std::string, std::string> params;
    198     params["a"] = "10";
    199     params["b"] = "test";
    200     ASSERT_TRUE(AssociateVariationParams(kTrialName, "A", params));
    201   }
    202   {
    203     std::map<std::string, std::string> params;
    204     params["a"] = "5";
    205     ASSERT_TRUE(AssociateVariationParams(kTrialName, "B", params));
    206   }
    207 
    208   base::FieldTrialList::CreateFieldTrial(kTrialName, "B");
    209   EXPECT_EQ("5", GetVariationParamValue(kTrialName, "a"));
    210   EXPECT_EQ(std::string(), GetVariationParamValue(kTrialName, "b"));
    211   EXPECT_EQ(std::string(), GetVariationParamValue(kTrialName, "x"));
    212 
    213   std::map<std::string, std::string> params;
    214   EXPECT_TRUE(GetVariationParams(kTrialName, &params));
    215   EXPECT_EQ(1U, params.size());
    216   EXPECT_EQ("5", params["a"]);
    217 }
    218 
    219 TEST_F(VariationsAssociatedDataTest, AssociateVariationParams_Fail) {
    220   const std::string kTrialName = "AssociateVariationParams_Fail";
    221   const std::string kGroupName = "A";
    222 
    223   std::map<std::string, std::string> params;
    224   params["a"] = "10";
    225   ASSERT_TRUE(AssociateVariationParams(kTrialName, kGroupName, params));
    226   params["a"] = "1";
    227   params["b"] = "2";
    228   ASSERT_FALSE(AssociateVariationParams(kTrialName, kGroupName, params));
    229 
    230   base::FieldTrialList::CreateFieldTrial(kTrialName, kGroupName);
    231   EXPECT_EQ("10", GetVariationParamValue(kTrialName, "a"));
    232   EXPECT_EQ(std::string(), GetVariationParamValue(kTrialName, "b"));
    233 }
    234 
    235 TEST_F(VariationsAssociatedDataTest, AssociateVariationParams_TrialActiveFail) {
    236   const std::string kTrialName = "AssociateVariationParams_TrialActiveFail";
    237   base::FieldTrialList::CreateFieldTrial(kTrialName, "A");
    238   ASSERT_EQ("A", base::FieldTrialList::FindFullName(kTrialName));
    239 
    240   std::map<std::string, std::string> params;
    241   params["a"] = "10";
    242   EXPECT_FALSE(AssociateVariationParams(kTrialName, "B", params));
    243   EXPECT_FALSE(AssociateVariationParams(kTrialName, "A", params));
    244 }
    245 
    246 TEST_F(VariationsAssociatedDataTest,
    247        AssociateVariationParams_DoesntActivateTrial) {
    248   const std::string kTrialName = "AssociateVariationParams_DoesntActivateTrial";
    249 
    250   ASSERT_FALSE(IsFieldTrialActive(kTrialName));
    251   scoped_refptr<base::FieldTrial> trial(
    252       CreateFieldTrial(kTrialName, 100, "A", NULL));
    253   ASSERT_FALSE(IsFieldTrialActive(kTrialName));
    254 
    255   std::map<std::string, std::string> params;
    256   params["a"] = "10";
    257   EXPECT_TRUE(AssociateVariationParams(kTrialName, "A", params));
    258   ASSERT_FALSE(IsFieldTrialActive(kTrialName));
    259 }
    260 
    261 TEST_F(VariationsAssociatedDataTest, GetVariationParams_NoTrial) {
    262   const std::string kTrialName = "GetVariationParams_NoParams";
    263 
    264   std::map<std::string, std::string> params;
    265   EXPECT_FALSE(GetVariationParams(kTrialName, &params));
    266   EXPECT_EQ(std::string(), GetVariationParamValue(kTrialName, "x"));
    267   EXPECT_EQ(std::string(), GetVariationParamValue(kTrialName, "y"));
    268 }
    269 
    270 TEST_F(VariationsAssociatedDataTest, GetVariationParams_NoParams) {
    271   const std::string kTrialName = "GetVariationParams_NoParams";
    272 
    273   base::FieldTrialList::CreateFieldTrial(kTrialName, "A");
    274 
    275   std::map<std::string, std::string> params;
    276   EXPECT_FALSE(GetVariationParams(kTrialName, &params));
    277   EXPECT_EQ(std::string(), GetVariationParamValue(kTrialName, "x"));
    278   EXPECT_EQ(std::string(), GetVariationParamValue(kTrialName, "y"));
    279 }
    280 
    281 TEST_F(VariationsAssociatedDataTest, GetVariationParams_ActivatesTrial) {
    282   const std::string kTrialName = "GetVariationParams_ActivatesTrial";
    283 
    284   ASSERT_FALSE(IsFieldTrialActive(kTrialName));
    285   scoped_refptr<base::FieldTrial> trial(
    286       CreateFieldTrial(kTrialName, 100, "A", NULL));
    287   ASSERT_FALSE(IsFieldTrialActive(kTrialName));
    288 
    289   std::map<std::string, std::string> params;
    290   EXPECT_FALSE(GetVariationParams(kTrialName, &params));
    291   ASSERT_TRUE(IsFieldTrialActive(kTrialName));
    292 }
    293 
    294 TEST_F(VariationsAssociatedDataTest, GetVariationParamValue_ActivatesTrial) {
    295   const std::string kTrialName = "GetVariationParamValue_ActivatesTrial";
    296 
    297   ASSERT_FALSE(IsFieldTrialActive(kTrialName));
    298   scoped_refptr<base::FieldTrial> trial(
    299       CreateFieldTrial(kTrialName, 100, "A", NULL));
    300   ASSERT_FALSE(IsFieldTrialActive(kTrialName));
    301 
    302   std::map<std::string, std::string> params;
    303   EXPECT_EQ(std::string(), GetVariationParamValue(kTrialName, "x"));
    304   ASSERT_TRUE(IsFieldTrialActive(kTrialName));
    305 }
    306 
    307 }  // namespace chrome_variations
    308