Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(180)

Side by Side Diff: chrome/browser/metrics/variations_service_unittest.cc

Issue 10828314: Move Variations stuff into variations/ directories and add OWNERS files for the variations client t… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Add OWNERS files Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/metrics/variations_service.cc ('k') | chrome/browser/prefs/browser_prefs.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 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 "base/base64.h"
6 #include "base/string_split.h"
7 #include "chrome/browser/metrics/proto/study.pb.h"
8 #include "chrome/browser/metrics/variations_service.h"
9 #include "chrome/common/chrome_version_info.h"
10 #include "chrome/common/pref_names.h"
11 #include "chrome/test/base/testing_pref_service.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 namespace chrome_variations {
15
16 namespace {
17
18 // Converts |time| to Study proto format.
19 int64 TimeToProtoTime(const base::Time& time) {
20 return (time - base::Time::UnixEpoch()).InSeconds();
21 }
22
23 // Populates |seed| with simple test data. The resulting seed will contain one
24 // study called "test", which contains one experiment called "abc" with
25 // probability weight 100. |seed|'s study field will be cleared before adding
26 // the new study.
27 TrialsSeed CreateTestSeed() {
28 TrialsSeed seed;
29 Study* study = seed.add_study();
30 study->set_name("test");
31 study->set_default_experiment_name("abc");
32 Study_Experiment* experiment = study->add_experiment();
33 experiment->set_name("abc");
34 experiment->set_probability_weight(100);
35 return seed;
36 }
37
38 } // namespace
39
40 TEST(VariationsServiceTest, CheckStudyChannel) {
41 const chrome::VersionInfo::Channel channels[] = {
42 chrome::VersionInfo::CHANNEL_CANARY,
43 chrome::VersionInfo::CHANNEL_DEV,
44 chrome::VersionInfo::CHANNEL_BETA,
45 chrome::VersionInfo::CHANNEL_STABLE,
46 };
47 const Study_Channel study_channels[] = {
48 Study_Channel_CANARY,
49 Study_Channel_DEV,
50 Study_Channel_BETA,
51 Study_Channel_STABLE,
52 };
53 ASSERT_EQ(arraysize(channels), arraysize(study_channels));
54 bool channel_added[arraysize(channels)] = { 0 };
55
56 Study_Filter filter;
57
58 // Check in the forwarded order. The loop cond is <= arraysize(study_channels)
59 // instead of < so that the result of adding the last channel gets checked.
60 for (size_t i = 0; i <= arraysize(study_channels); ++i) {
61 for (size_t j = 0; j < arraysize(channels); ++j) {
62 const bool expected = channel_added[j] || filter.channel_size() == 0;
63 const bool result = VariationsService::CheckStudyChannel(filter,
64 channels[j]);
65 EXPECT_EQ(expected, result) << "Case " << i << "," << j << " failed!";
66 }
67
68 if (i < arraysize(study_channels)) {
69 filter.add_channel(study_channels[i]);
70 channel_added[i] = true;
71 }
72 }
73
74 // Do the same check in the reverse order.
75 filter.clear_channel();
76 memset(&channel_added, 0, sizeof(channel_added));
77 for (size_t i = 0; i <= arraysize(study_channels); ++i) {
78 for (size_t j = 0; j < arraysize(channels); ++j) {
79 const bool expected = channel_added[j] || filter.channel_size() == 0;
80 const bool result = VariationsService::CheckStudyChannel(filter,
81 channels[j]);
82 EXPECT_EQ(expected, result) << "Case " << i << "," << j << " failed!";
83 }
84
85 if (i < arraysize(study_channels)) {
86 const int index = arraysize(study_channels) - i - 1;
87 filter.add_channel(study_channels[index]);
88 channel_added[index] = true;
89 }
90 }
91 }
92
93 TEST(VariationsServiceTest, CheckStudyLocale) {
94 struct {
95 const char* filter_locales;
96 bool en_us_result;
97 bool en_ca_result;
98 bool fr_result;
99 } test_cases[] = {
100 {"en-US", true, false, false},
101 {"en-US,en-CA,fr", true, true, true},
102 {"en-US,en-CA,en-GB", true, true, false},
103 {"en-GB,en-CA,en-US", true, true, false},
104 {"ja,kr,vi", false, false, false},
105 {"fr-CA", false, false, false},
106 {"", true, true, true},
107 };
108
109 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
110 std::vector<std::string> filter_locales;
111 Study_Filter filter;
112 base::SplitString(test_cases[i].filter_locales, ',', &filter_locales);
113 for (size_t j = 0; j < filter_locales.size(); ++j)
114 filter.add_locale(filter_locales[j]);
115 EXPECT_EQ(test_cases[i].en_us_result,
116 VariationsService::CheckStudyLocale(filter, "en-US"));
117 EXPECT_EQ(test_cases[i].en_ca_result,
118 VariationsService::CheckStudyLocale(filter, "en-CA"));
119 EXPECT_EQ(test_cases[i].fr_result,
120 VariationsService::CheckStudyLocale(filter, "fr"));
121 }
122 }
123
124 TEST(VariationsServiceTest, CheckStudyPlatform) {
125 const Study_Platform platforms[] = {
126 Study_Platform_PLATFORM_WINDOWS,
127 Study_Platform_PLATFORM_MAC,
128 Study_Platform_PLATFORM_LINUX,
129 Study_Platform_PLATFORM_CHROMEOS,
130 Study_Platform_PLATFORM_ANDROID,
131 Study_Platform_PLATFORM_IOS,
132 };
133 ASSERT_EQ(Study_Platform_Platform_ARRAYSIZE,
134 static_cast<int>(arraysize(platforms)));
135 bool platform_added[arraysize(platforms)] = { 0 };
136
137 Study_Filter filter;
138
139 // Check in the forwarded order. The loop cond is <= arraysize(platforms)
140 // instead of < so that the result of adding the last channel gets checked.
141 for (size_t i = 0; i <= arraysize(platforms); ++i) {
142 for (size_t j = 0; j < arraysize(platforms); ++j) {
143 const bool expected = platform_added[j] || filter.platform_size() == 0;
144 const bool result = VariationsService::CheckStudyPlatform(filter,
145 platforms[j]);
146 EXPECT_EQ(expected, result) << "Case " << i << "," << j << " failed!";
147 }
148
149 if (i < arraysize(platforms)) {
150 filter.add_platform(platforms[i]);
151 platform_added[i] = true;
152 }
153 }
154
155 // Do the same check in the reverse order.
156 filter.clear_platform();
157 memset(&platform_added, 0, sizeof(platform_added));
158 for (size_t i = 0; i <= arraysize(platforms); ++i) {
159 for (size_t j = 0; j < arraysize(platforms); ++j) {
160 const bool expected = platform_added[j] || filter.platform_size() == 0;
161 const bool result = VariationsService::CheckStudyPlatform(filter,
162 platforms[j]);
163 EXPECT_EQ(expected, result) << "Case " << i << "," << j << " failed!";
164 }
165
166 if (i < arraysize(platforms)) {
167 const int index = arraysize(platforms) - i - 1;
168 filter.add_platform(platforms[index]);
169 platform_added[index] = true;
170 }
171 }
172 }
173
174 TEST(VariationsServiceTest, CheckStudyVersion) {
175 const struct {
176 const char* min_version;
177 const char* version;
178 bool expected_result;
179 } min_test_cases[] = {
180 { "1.2.2", "1.2.3", true },
181 { "1.2.3", "1.2.3", true },
182 { "1.2.4", "1.2.3", false },
183 { "1.3.2", "1.2.3", false },
184 { "2.1.2", "1.2.3", false },
185 { "0.3.4", "1.2.3", true },
186 // Wildcards.
187 { "1.*", "1.2.3", true },
188 { "1.2.*", "1.2.3", true },
189 { "1.2.3.*", "1.2.3", true },
190 { "1.2.4.*", "1.2.3", false },
191 { "2.*", "1.2.3", false },
192 { "0.3.*", "1.2.3", true },
193 };
194
195 const struct {
196 const char* max_version;
197 const char* version;
198 bool expected_result;
199 } max_test_cases[] = {
200 { "1.2.2", "1.2.3", false },
201 { "1.2.3", "1.2.3", true },
202 { "1.2.4", "1.2.3", true },
203 { "2.1.1", "1.2.3", true },
204 { "2.1.1", "2.3.4", false },
205 // Wildcards
206 { "2.1.*", "2.3.4", false },
207 { "2.*", "2.3.4", true },
208 { "2.3.*", "2.3.4", true },
209 { "2.3.4.*", "2.3.4", true },
210 { "2.3.4.0.*", "2.3.4", true },
211 { "2.4.*", "2.3.4", true },
212 { "1.3.*", "2.3.4", false },
213 { "1.*", "2.3.4", false },
214 };
215
216 Study_Filter filter;
217
218 // Min/max version not set should result in true.
219 EXPECT_TRUE(VariationsService::CheckStudyVersion(filter, "1.2.3"));
220
221 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(min_test_cases); ++i) {
222 filter.set_min_version(min_test_cases[i].min_version);
223 const bool result =
224 VariationsService::CheckStudyVersion(filter, min_test_cases[i].version);
225 EXPECT_EQ(min_test_cases[i].expected_result, result) <<
226 "Min. version case " << i << " failed!";
227 }
228 filter.clear_min_version();
229
230 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(max_test_cases); ++i) {
231 filter.set_max_version(max_test_cases[i].max_version);
232 const bool result =
233 VariationsService::CheckStudyVersion(filter, max_test_cases[i].version);
234 EXPECT_EQ(max_test_cases[i].expected_result, result) <<
235 "Max version case " << i << " failed!";
236 }
237
238 // Check intersection semantics.
239 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(min_test_cases); ++i) {
240 for (size_t j = 0; j < ARRAYSIZE_UNSAFE(max_test_cases); ++j) {
241 filter.set_min_version(min_test_cases[i].min_version);
242 filter.set_max_version(max_test_cases[j].max_version);
243
244 if (!min_test_cases[i].expected_result) {
245 const bool result =
246 VariationsService::CheckStudyVersion(filter,
247 min_test_cases[i].version);
248 EXPECT_FALSE(result) << "Case " << i << "," << j << " failed!";
249 }
250
251 if (!max_test_cases[j].expected_result) {
252 const bool result =
253 VariationsService::CheckStudyVersion(filter,
254 max_test_cases[j].version);
255 EXPECT_FALSE(result) << "Case " << i << "," << j << " failed!";
256 }
257 }
258 }
259 }
260
261 TEST(VariationsServiceTest, CheckStudyStartDate) {
262 const base::Time now = base::Time::Now();
263 const base::TimeDelta delta = base::TimeDelta::FromHours(1);
264 const struct {
265 const base::Time start_date;
266 bool expected_result;
267 } start_test_cases[] = {
268 { now - delta, true },
269 { now, true },
270 { now + delta, false },
271 };
272
273 Study_Filter filter;
274
275 // Start date not set should result in true.
276 EXPECT_TRUE(VariationsService::CheckStudyStartDate(filter, now));
277
278 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(start_test_cases); ++i) {
279 filter.set_start_date(TimeToProtoTime(start_test_cases[i].start_date));
280 const bool result = VariationsService::CheckStudyStartDate(filter, now);
281 EXPECT_EQ(start_test_cases[i].expected_result, result)
282 << "Case " << i << " failed!";
283 }
284 }
285
286 TEST(VariationsServiceTest, IsStudyExpired) {
287 const base::Time now = base::Time::Now();
288 const base::TimeDelta delta = base::TimeDelta::FromHours(1);
289 const struct {
290 const base::Time expiry_date;
291 bool expected_result;
292 } expiry_test_cases[] = {
293 { now - delta, true },
294 { now, true },
295 { now + delta, false },
296 };
297
298 Study study;
299
300 // Expiry date not set should result in false.
301 EXPECT_FALSE(VariationsService::IsStudyExpired(study, now));
302
303 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(expiry_test_cases); ++i) {
304 study.set_expiry_date(TimeToProtoTime(expiry_test_cases[i].expiry_date));
305 const bool result = VariationsService::IsStudyExpired(study, now);
306 EXPECT_EQ(expiry_test_cases[i].expected_result, result)
307 << "Case " << i << " failed!";
308 }
309 }
310
311 TEST(VariationsServiceTest, LoadSeed) {
312 TestingPrefService pref_service;
313
314 VariationsService::RegisterPrefs(&pref_service);
315
316 // Store good seed data to test if loading from prefs works.
317 TrialsSeed seed = CreateTestSeed();
318
319 std::string serialized_seed;
320 seed.SerializeToString(&serialized_seed);
321 std::string base64_serialized_seed;
322 ASSERT_TRUE(base::Base64Encode(serialized_seed, &base64_serialized_seed));
323 pref_service.SetString(prefs::kVariationsSeed, base64_serialized_seed);
324
325 VariationsService variations_service;
326 TrialsSeed loaded_seed;
327 EXPECT_TRUE(
328 variations_service.LoadTrialsSeedFromPref(&pref_service, &loaded_seed));
329
330 std::string serialized_loaded_seed;
331 loaded_seed.SerializeToString(&serialized_loaded_seed);
332 // Check that the loaded data is the same as the original.
333 EXPECT_EQ(serialized_seed, serialized_loaded_seed);
334 // Make sure the pref hasn't been changed.
335 EXPECT_FALSE(
336 pref_service.FindPreference(prefs::kVariationsSeed)->IsDefaultValue());
337 EXPECT_EQ(base64_serialized_seed,
338 pref_service.GetString(prefs::kVariationsSeed));
339
340 // Check that loading a bad seed returns false and clears the pref.
341 pref_service.ClearPref(prefs::kVariationsSeed);
342 pref_service.SetString(prefs::kVariationsSeed, "this should fail");
343 EXPECT_FALSE(
344 pref_service.FindPreference(prefs::kVariationsSeed)->IsDefaultValue());
345 EXPECT_FALSE(
346 variations_service.LoadTrialsSeedFromPref(&pref_service, &loaded_seed));
347 EXPECT_TRUE(
348 pref_service.FindPreference(prefs::kVariationsSeed)->IsDefaultValue());
349 }
350
351 TEST(VariationsServiceTest, StoreSeed) {
352 TestingPrefService pref_service;
353
354 VariationsService::RegisterPrefs(&pref_service);
355 const base::Time now = base::Time::Now();
356
357 TrialsSeed seed = CreateTestSeed();
358
359 VariationsService variations_service;
360 std::string serialized_seed;
361 seed.SerializeToString(&serialized_seed);
362 EXPECT_TRUE(
363 variations_service.StoreSeedData(serialized_seed, now, &pref_service));
364 // Make sure the pref was actually set.
365 EXPECT_FALSE(
366 pref_service.FindPreference(prefs::kVariationsSeed)->IsDefaultValue());
367
368 std::string loaded_serialized_seed =
369 pref_service.GetString(prefs::kVariationsSeed);
370 std::string decoded_serialized_seed;
371 ASSERT_TRUE(base::Base64Decode(loaded_serialized_seed,
372 &decoded_serialized_seed));
373 // Make sure the stored seed from pref is the same as the seed we created.
374 EXPECT_EQ(serialized_seed, decoded_serialized_seed);
375
376 // Check if trying to store a bad seed leaves the pref unchanged.
377 pref_service.ClearPref(prefs::kVariationsSeed);
378 EXPECT_FALSE(
379 variations_service.StoreSeedData("this should fail", now, &pref_service));
380 EXPECT_TRUE(
381 pref_service.FindPreference(prefs::kVariationsSeed)->IsDefaultValue());
382 }
383
384 TEST(VariationsServiceTest, ValidateStudy) {
385 Study study;
386 study.set_default_experiment_name("def");
387
388 Study_Experiment* experiment = study.add_experiment();
389 experiment->set_name("abc");
390 experiment->set_probability_weight(100);
391
392 Study_Experiment* default_group = study.add_experiment();
393 default_group->set_name("def");
394 default_group->set_probability_weight(200);
395
396 base::FieldTrial::Probability total_probability = 0;
397 bool valid = VariationsService::ValidateStudyAndComputeTotalProbability(
398 study, &total_probability);
399 EXPECT_TRUE(valid);
400 EXPECT_EQ(300, total_probability);
401
402 // Min version checks.
403 study.mutable_filter()->set_min_version("1.2.3.*");
404 valid = VariationsService::ValidateStudyAndComputeTotalProbability(
405 study, &total_probability);
406 EXPECT_TRUE(valid);
407 study.mutable_filter()->set_min_version("1.*.3");
408 valid = VariationsService::ValidateStudyAndComputeTotalProbability(
409 study, &total_probability);
410 EXPECT_FALSE(valid);
411 study.mutable_filter()->set_min_version("1.2.3");
412 valid = VariationsService::ValidateStudyAndComputeTotalProbability(
413 study, &total_probability);
414 EXPECT_TRUE(valid);
415
416 // Max version checks.
417 study.mutable_filter()->set_max_version("2.3.4.*");
418 valid = VariationsService::ValidateStudyAndComputeTotalProbability(
419 study, &total_probability);
420 EXPECT_TRUE(valid);
421 study.mutable_filter()->set_max_version("*.3");
422 valid = VariationsService::ValidateStudyAndComputeTotalProbability(
423 study, &total_probability);
424 EXPECT_FALSE(valid);
425 study.mutable_filter()->set_max_version("2.3.4");
426 valid = VariationsService::ValidateStudyAndComputeTotalProbability(
427 study, &total_probability);
428 EXPECT_TRUE(valid);
429
430 study.clear_default_experiment_name();
431 valid = VariationsService::ValidateStudyAndComputeTotalProbability(study,
432 &total_probability);
433 EXPECT_FALSE(valid);
434
435 study.set_default_experiment_name("xyz");
436 valid = VariationsService::ValidateStudyAndComputeTotalProbability(study,
437 &total_probability);
438 EXPECT_FALSE(valid);
439
440 study.set_default_experiment_name("def");
441 default_group->clear_name();
442 valid = VariationsService::ValidateStudyAndComputeTotalProbability(study,
443 &total_probability);
444 EXPECT_FALSE(valid);
445
446 default_group->set_name("def");
447 valid = VariationsService::ValidateStudyAndComputeTotalProbability(study,
448 &total_probability);
449 ASSERT_TRUE(valid);
450 Study_Experiment* repeated_group = study.add_experiment();
451 repeated_group->set_name("abc");
452 repeated_group->set_probability_weight(1);
453 valid = VariationsService::ValidateStudyAndComputeTotalProbability(study,
454 &total_probability);
455 EXPECT_FALSE(valid);
456 }
457
458 } // namespace chrome_variations
OLDNEW
« no previous file with comments | « chrome/browser/metrics/variations_service.cc ('k') | chrome/browser/prefs/browser_prefs.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698