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.
5 #include "components/variations/variations_associated_data.h"
7 #include "base/metrics/field_trial.h"
8 #include "testing/gtest/include/gtest/gtest.h"
10 namespace variations
{
14 const VariationID TEST_VALUE_A
= 3300200;
15 const VariationID TEST_VALUE_B
= 3300201;
17 // Convenience helper to retrieve the variations::VariationID for a FieldTrial.
18 // Note that this will do the group assignment in |trial| if not already done.
19 VariationID
GetIDForTrial(IDCollectionKey key
, base::FieldTrial
* trial
) {
20 return GetGoogleVariationID(key
, trial
->trial_name(), trial
->group_name());
23 // Tests whether a field trial is active (i.e. group() has been called on it).
24 bool IsFieldTrialActive(const std::string
& trial_name
) {
25 base::FieldTrial::ActiveGroups active_groups
;
26 base::FieldTrialList::GetActiveFieldTrialGroups(&active_groups
);
27 for (size_t i
= 0; i
< active_groups
.size(); ++i
) {
28 if (active_groups
[i
].trial_name
== trial_name
)
34 // Call FieldTrialList::FactoryGetFieldTrial() with a future expiry date.
35 scoped_refptr
<base::FieldTrial
> CreateFieldTrial(
36 const std::string
& trial_name
,
37 int total_probability
,
38 const std::string
& default_group_name
,
39 int* default_group_number
) {
40 return base::FieldTrialList::FactoryGetFieldTrial(
41 trial_name
, total_probability
, default_group_name
,
42 base::FieldTrialList::kNoExpirationYear
, 1, 1,
43 base::FieldTrial::SESSION_RANDOMIZED
, default_group_number
);
48 class VariationsAssociatedDataTest
: public ::testing::Test
{
50 VariationsAssociatedDataTest() : field_trial_list_(NULL
) {
53 ~VariationsAssociatedDataTest() override
{
54 // Ensure that the maps are cleared between tests, since they are stored as
55 // process singletons.
56 testing::ClearAllVariationIDs();
57 testing::ClearAllVariationParams();
61 base::FieldTrialList field_trial_list_
;
63 DISALLOW_COPY_AND_ASSIGN(VariationsAssociatedDataTest
);
66 // Test that if the trial is immediately disabled, GetGoogleVariationID just
67 // returns the empty ID.
68 TEST_F(VariationsAssociatedDataTest
, DisableImmediately
) {
69 int default_group_number
= -1;
70 scoped_refptr
<base::FieldTrial
> trial(
71 CreateFieldTrial("trial", 100, "default", &default_group_number
));
73 ASSERT_EQ(default_group_number
, trial
->group());
74 ASSERT_EQ(EMPTY_ID
, GetIDForTrial(GOOGLE_WEB_PROPERTIES
, trial
.get()));
77 // Test that successfully associating the FieldTrial with some ID, and then
78 // disabling the FieldTrial actually makes GetGoogleVariationID correctly
79 // return the empty ID.
80 TEST_F(VariationsAssociatedDataTest
, DisableAfterInitialization
) {
81 const std::string default_name
= "default";
82 const std::string non_default_name
= "non_default";
84 scoped_refptr
<base::FieldTrial
> trial(
85 CreateFieldTrial("trial", 100, default_name
, NULL
));
87 trial
->AppendGroup(non_default_name
, 100);
88 AssociateGoogleVariationID(GOOGLE_WEB_PROPERTIES
, trial
->trial_name(),
89 default_name
, TEST_VALUE_A
);
90 AssociateGoogleVariationID(GOOGLE_WEB_PROPERTIES
, trial
->trial_name(),
91 non_default_name
, TEST_VALUE_B
);
93 ASSERT_EQ(default_name
, trial
->group_name());
94 ASSERT_EQ(TEST_VALUE_A
, GetIDForTrial(GOOGLE_WEB_PROPERTIES
, trial
.get()));
97 // Test various successful association cases.
98 TEST_F(VariationsAssociatedDataTest
, AssociateGoogleVariationID
) {
99 const std::string default_name1
= "default";
100 scoped_refptr
<base::FieldTrial
> trial_true(
101 CreateFieldTrial("d1", 10, default_name1
, NULL
));
102 const std::string winner
= "TheWinner";
103 int winner_group
= trial_true
->AppendGroup(winner
, 10);
105 // Set GoogleVariationIDs so we can verify that they were chosen correctly.
106 AssociateGoogleVariationID(GOOGLE_WEB_PROPERTIES
, trial_true
->trial_name(),
107 default_name1
, TEST_VALUE_A
);
108 AssociateGoogleVariationID(GOOGLE_WEB_PROPERTIES
, trial_true
->trial_name(),
109 winner
, TEST_VALUE_B
);
111 EXPECT_EQ(winner_group
, trial_true
->group());
112 EXPECT_EQ(winner
, trial_true
->group_name());
113 EXPECT_EQ(TEST_VALUE_B
,
114 GetIDForTrial(GOOGLE_WEB_PROPERTIES
, trial_true
.get()));
116 const std::string default_name2
= "default2";
117 scoped_refptr
<base::FieldTrial
> trial_false(
118 CreateFieldTrial("d2", 10, default_name2
, NULL
));
119 const std::string loser
= "ALoser";
120 const int loser_group
= trial_false
->AppendGroup(loser
, 0);
122 AssociateGoogleVariationID(GOOGLE_WEB_PROPERTIES
, trial_false
->trial_name(),
123 default_name2
, TEST_VALUE_A
);
124 AssociateGoogleVariationID(GOOGLE_WEB_PROPERTIES
, trial_false
->trial_name(),
125 loser
, TEST_VALUE_B
);
127 EXPECT_NE(loser_group
, trial_false
->group());
128 EXPECT_EQ(TEST_VALUE_A
,
129 GetIDForTrial(GOOGLE_WEB_PROPERTIES
, trial_false
.get()));
132 // Test that not associating a FieldTrial with any IDs ensure that the empty ID
134 TEST_F(VariationsAssociatedDataTest
, NoAssociation
) {
135 const std::string default_name
= "default";
136 scoped_refptr
<base::FieldTrial
> no_id_trial(
137 CreateFieldTrial("d3", 10, default_name
, NULL
));
139 const std::string winner
= "TheWinner";
140 const int winner_group
= no_id_trial
->AppendGroup(winner
, 10);
142 // Ensure that despite the fact that a normal winner is elected, it does not
143 // have a valid VariationID associated with it.
144 EXPECT_EQ(winner_group
, no_id_trial
->group());
145 EXPECT_EQ(winner
, no_id_trial
->group_name());
146 EXPECT_EQ(EMPTY_ID
, GetIDForTrial(GOOGLE_WEB_PROPERTIES
, no_id_trial
.get()));
149 // Ensure that the AssociateGoogleVariationIDForce works as expected.
150 TEST_F(VariationsAssociatedDataTest
, ForceAssociation
) {
152 GetGoogleVariationID(GOOGLE_WEB_PROPERTIES
, "trial", "group"));
153 AssociateGoogleVariationID(GOOGLE_WEB_PROPERTIES
, "trial", "group",
155 EXPECT_EQ(TEST_VALUE_A
,
156 GetGoogleVariationID(GOOGLE_WEB_PROPERTIES
, "trial", "group"));
157 AssociateGoogleVariationID(GOOGLE_WEB_PROPERTIES
, "trial", "group",
159 EXPECT_EQ(TEST_VALUE_A
,
160 GetGoogleVariationID(GOOGLE_WEB_PROPERTIES
, "trial", "group"));
161 AssociateGoogleVariationIDForce(GOOGLE_WEB_PROPERTIES
, "trial", "group",
163 EXPECT_EQ(TEST_VALUE_B
,
164 GetGoogleVariationID(GOOGLE_WEB_PROPERTIES
, "trial", "group"));
167 // Ensure that two collections can coexist without affecting each other.
168 TEST_F(VariationsAssociatedDataTest
, CollectionsCoexist
) {
169 const std::string default_name
= "default";
170 int default_group_number
= -1;
171 scoped_refptr
<base::FieldTrial
> trial_true(
172 CreateFieldTrial("d1", 10, default_name
, &default_group_number
));
173 ASSERT_EQ(default_group_number
, trial_true
->group());
174 ASSERT_EQ(default_name
, trial_true
->group_name());
177 GetIDForTrial(GOOGLE_WEB_PROPERTIES
, trial_true
.get()));
179 GetIDForTrial(GOOGLE_WEB_PROPERTIES_TRIGGER
, trial_true
.get()));
181 GetIDForTrial(GOOGLE_UPDATE_SERVICE
, trial_true
.get()));
183 GetIDForTrial(CHROME_SYNC_SERVICE
, trial_true
.get()));
185 AssociateGoogleVariationID(GOOGLE_WEB_PROPERTIES
, trial_true
->trial_name(),
186 default_name
, TEST_VALUE_A
);
187 EXPECT_EQ(TEST_VALUE_A
,
188 GetIDForTrial(GOOGLE_WEB_PROPERTIES
, trial_true
.get()));
190 GetIDForTrial(GOOGLE_UPDATE_SERVICE
, trial_true
.get()));
192 GetIDForTrial(CHROME_SYNC_SERVICE
, trial_true
.get()));
194 AssociateGoogleVariationID(GOOGLE_UPDATE_SERVICE
, trial_true
->trial_name(),
195 default_name
, TEST_VALUE_A
);
196 EXPECT_EQ(TEST_VALUE_A
,
197 GetIDForTrial(GOOGLE_WEB_PROPERTIES
, trial_true
.get()));
198 EXPECT_EQ(TEST_VALUE_A
,
199 GetIDForTrial(GOOGLE_UPDATE_SERVICE
, trial_true
.get()));
201 GetIDForTrial(CHROME_SYNC_SERVICE
, trial_true
.get()));
203 AssociateGoogleVariationID(CHROME_SYNC_SERVICE
, trial_true
->trial_name(),
204 default_name
, TEST_VALUE_A
);
205 EXPECT_EQ(TEST_VALUE_A
,
206 GetIDForTrial(GOOGLE_WEB_PROPERTIES
, trial_true
.get()));
207 EXPECT_EQ(TEST_VALUE_A
,
208 GetIDForTrial(GOOGLE_UPDATE_SERVICE
, trial_true
.get()));
209 EXPECT_EQ(TEST_VALUE_A
,
210 GetIDForTrial(CHROME_SYNC_SERVICE
, trial_true
.get()));
212 trial_true
= CreateFieldTrial("d2", 10, default_name
, &default_group_number
);
213 ASSERT_EQ(default_group_number
, trial_true
->group());
214 ASSERT_EQ(default_name
, trial_true
->group_name());
216 AssociateGoogleVariationID(GOOGLE_WEB_PROPERTIES_TRIGGER
,
217 trial_true
->trial_name(), default_name
,
219 EXPECT_EQ(TEST_VALUE_A
,
220 GetIDForTrial(GOOGLE_WEB_PROPERTIES_TRIGGER
, trial_true
.get()));
222 GetIDForTrial(GOOGLE_UPDATE_SERVICE
, trial_true
.get()));
224 GetIDForTrial(CHROME_SYNC_SERVICE
, trial_true
.get()));
226 AssociateGoogleVariationID(GOOGLE_UPDATE_SERVICE
, trial_true
->trial_name(),
227 default_name
, TEST_VALUE_A
);
228 EXPECT_EQ(TEST_VALUE_A
,
229 GetIDForTrial(GOOGLE_WEB_PROPERTIES_TRIGGER
, trial_true
.get()));
230 EXPECT_EQ(TEST_VALUE_A
,
231 GetIDForTrial(GOOGLE_UPDATE_SERVICE
, trial_true
.get()));
233 GetIDForTrial(CHROME_SYNC_SERVICE
, trial_true
.get()));
235 AssociateGoogleVariationID(CHROME_SYNC_SERVICE
, trial_true
->trial_name(),
236 default_name
, TEST_VALUE_A
);
237 EXPECT_EQ(TEST_VALUE_A
,
238 GetIDForTrial(GOOGLE_WEB_PROPERTIES_TRIGGER
, trial_true
.get()));
239 EXPECT_EQ(TEST_VALUE_A
,
240 GetIDForTrial(GOOGLE_UPDATE_SERVICE
, trial_true
.get()));
241 EXPECT_EQ(TEST_VALUE_A
,
242 GetIDForTrial(CHROME_SYNC_SERVICE
, trial_true
.get()));
245 TEST_F(VariationsAssociatedDataTest
, AssociateVariationParams
) {
246 const std::string kTrialName
= "AssociateVariationParams";
249 std::map
<std::string
, std::string
> params
;
251 params
["b"] = "test";
252 ASSERT_TRUE(AssociateVariationParams(kTrialName
, "A", params
));
255 std::map
<std::string
, std::string
> params
;
257 ASSERT_TRUE(AssociateVariationParams(kTrialName
, "B", params
));
260 base::FieldTrialList::CreateFieldTrial(kTrialName
, "B");
261 EXPECT_EQ("5", GetVariationParamValue(kTrialName
, "a"));
262 EXPECT_EQ(std::string(), GetVariationParamValue(kTrialName
, "b"));
263 EXPECT_EQ(std::string(), GetVariationParamValue(kTrialName
, "x"));
265 std::map
<std::string
, std::string
> params
;
266 EXPECT_TRUE(GetVariationParams(kTrialName
, ¶ms
));
267 EXPECT_EQ(1U, params
.size());
268 EXPECT_EQ("5", params
["a"]);
271 TEST_F(VariationsAssociatedDataTest
, AssociateVariationParams_Fail
) {
272 const std::string kTrialName
= "AssociateVariationParams_Fail";
273 const std::string kGroupName
= "A";
275 std::map
<std::string
, std::string
> params
;
277 ASSERT_TRUE(AssociateVariationParams(kTrialName
, kGroupName
, params
));
280 ASSERT_FALSE(AssociateVariationParams(kTrialName
, kGroupName
, params
));
282 base::FieldTrialList::CreateFieldTrial(kTrialName
, kGroupName
);
283 EXPECT_EQ("10", GetVariationParamValue(kTrialName
, "a"));
284 EXPECT_EQ(std::string(), GetVariationParamValue(kTrialName
, "b"));
287 TEST_F(VariationsAssociatedDataTest
, AssociateVariationParams_TrialActiveFail
) {
288 const std::string kTrialName
= "AssociateVariationParams_TrialActiveFail";
289 base::FieldTrialList::CreateFieldTrial(kTrialName
, "A");
290 ASSERT_EQ("A", base::FieldTrialList::FindFullName(kTrialName
));
292 std::map
<std::string
, std::string
> params
;
294 EXPECT_FALSE(AssociateVariationParams(kTrialName
, "B", params
));
295 EXPECT_FALSE(AssociateVariationParams(kTrialName
, "A", params
));
298 TEST_F(VariationsAssociatedDataTest
,
299 AssociateVariationParams_DoesntActivateTrial
) {
300 const std::string kTrialName
= "AssociateVariationParams_DoesntActivateTrial";
302 ASSERT_FALSE(IsFieldTrialActive(kTrialName
));
303 scoped_refptr
<base::FieldTrial
> trial(
304 CreateFieldTrial(kTrialName
, 100, "A", NULL
));
305 ASSERT_FALSE(IsFieldTrialActive(kTrialName
));
307 std::map
<std::string
, std::string
> params
;
309 EXPECT_TRUE(AssociateVariationParams(kTrialName
, "A", params
));
310 ASSERT_FALSE(IsFieldTrialActive(kTrialName
));
313 TEST_F(VariationsAssociatedDataTest
, GetVariationParams_NoTrial
) {
314 const std::string kTrialName
= "GetVariationParams_NoParams";
316 std::map
<std::string
, std::string
> params
;
317 EXPECT_FALSE(GetVariationParams(kTrialName
, ¶ms
));
318 EXPECT_EQ(std::string(), GetVariationParamValue(kTrialName
, "x"));
319 EXPECT_EQ(std::string(), GetVariationParamValue(kTrialName
, "y"));
322 TEST_F(VariationsAssociatedDataTest
, GetVariationParams_NoParams
) {
323 const std::string kTrialName
= "GetVariationParams_NoParams";
325 base::FieldTrialList::CreateFieldTrial(kTrialName
, "A");
327 std::map
<std::string
, std::string
> params
;
328 EXPECT_FALSE(GetVariationParams(kTrialName
, ¶ms
));
329 EXPECT_EQ(std::string(), GetVariationParamValue(kTrialName
, "x"));
330 EXPECT_EQ(std::string(), GetVariationParamValue(kTrialName
, "y"));
333 TEST_F(VariationsAssociatedDataTest
, GetVariationParams_ActivatesTrial
) {
334 const std::string kTrialName
= "GetVariationParams_ActivatesTrial";
336 ASSERT_FALSE(IsFieldTrialActive(kTrialName
));
337 scoped_refptr
<base::FieldTrial
> trial(
338 CreateFieldTrial(kTrialName
, 100, "A", NULL
));
339 ASSERT_FALSE(IsFieldTrialActive(kTrialName
));
341 std::map
<std::string
, std::string
> params
;
342 EXPECT_FALSE(GetVariationParams(kTrialName
, ¶ms
));
343 ASSERT_TRUE(IsFieldTrialActive(kTrialName
));
346 TEST_F(VariationsAssociatedDataTest
, GetVariationParamValue_ActivatesTrial
) {
347 const std::string kTrialName
= "GetVariationParamValue_ActivatesTrial";
349 ASSERT_FALSE(IsFieldTrialActive(kTrialName
));
350 scoped_refptr
<base::FieldTrial
> trial(
351 CreateFieldTrial(kTrialName
, 100, "A", NULL
));
352 ASSERT_FALSE(IsFieldTrialActive(kTrialName
));
354 std::map
<std::string
, std::string
> params
;
355 EXPECT_EQ(std::string(), GetVariationParamValue(kTrialName
, "x"));
356 ASSERT_TRUE(IsFieldTrialActive(kTrialName
));
359 } // namespace variations