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

Side by Side Diff: components/variations/study_filtering_unittest.cc

Issue 2924983003: [Variations] Refactor all state used for study filtering into a container struct. (Closed)
Patch Set: A bit more cleanup Created 3 years, 6 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/variations/study_filtering.h" 5 #include "components/variations/study_filtering.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 #include <string.h> 9 #include <string.h>
10 10
11 #include <vector> 11 #include <vector>
12 12
13 #include "base/macros.h" 13 #include "base/macros.h"
14 #include "base/strings/string_split.h" 14 #include "base/strings/string_split.h"
15 #include "components/variations/client_filterable_state.h"
15 #include "components/variations/processed_study.h" 16 #include "components/variations/processed_study.h"
16 #include "testing/gtest/include/gtest/gtest.h" 17 #include "testing/gtest/include/gtest/gtest.h"
17 18
18 namespace variations { 19 namespace variations {
19 20
20 namespace { 21 namespace {
21 22
22 // Converts |time| to Study proto format. 23 // Converts |time| to Study proto format.
23 int64_t TimeToProtoTime(const base::Time& time) { 24 int64_t TimeToProtoTime(const base::Time& time) {
24 return (time - base::Time::UnixEpoch()).InSeconds(); 25 return (time - base::Time::UnixEpoch()).InSeconds();
25 } 26 }
26 27
27 // Adds an experiment to |study| with the specified |name| and |probability|. 28 // Adds an experiment to |study| with the specified |name| and |probability|.
28 Study_Experiment* AddExperiment(const std::string& name, int probability, 29 Study::Experiment* AddExperiment(const std::string& name,
29 Study* study) { 30 int probability,
30 Study_Experiment* experiment = study->add_experiment(); 31 Study* study) {
32 Study::Experiment* experiment = study->add_experiment();
31 experiment->set_name(name); 33 experiment->set_name(name);
32 experiment->set_probability_weight(probability); 34 experiment->set_probability_weight(probability);
33 return experiment; 35 return experiment;
34 } 36 }
35 37
36 } // namespace 38 } // namespace
37 39
38 TEST(VariationsStudyFilteringTest, CheckStudyChannel) { 40 TEST(VariationsStudyFilteringTest, CheckStudyChannel) {
39 const Study_Channel channels[] = { 41 const Study::Channel channels[] = {
40 Study_Channel_CANARY, 42 Study::CANARY, Study::DEV, Study::BETA, Study::STABLE,
41 Study_Channel_DEV,
42 Study_Channel_BETA,
43 Study_Channel_STABLE,
44 }; 43 };
45 bool channel_added[arraysize(channels)] = { 0 }; 44 bool channel_added[arraysize(channels)] = { 0 };
46 45
47 Study_Filter filter; 46 Study::Filter filter;
48 47
49 // Check in the forwarded order. The loop cond is <= arraysize(channels) 48 // Check in the forwarded order. The loop cond is <= arraysize(channels)
50 // instead of < so that the result of adding the last channel gets checked. 49 // instead of < so that the result of adding the last channel gets checked.
51 for (size_t i = 0; i <= arraysize(channels); ++i) { 50 for (size_t i = 0; i <= arraysize(channels); ++i) {
52 for (size_t j = 0; j < arraysize(channels); ++j) { 51 for (size_t j = 0; j < arraysize(channels); ++j) {
53 const bool expected = channel_added[j] || filter.channel_size() == 0; 52 const bool expected = channel_added[j] || filter.channel_size() == 0;
54 const bool result = internal::CheckStudyChannel(filter, channels[j]); 53 const bool result = internal::CheckStudyChannel(filter, channels[j]);
55 EXPECT_EQ(expected, result) << "Case " << i << "," << j << " failed!"; 54 EXPECT_EQ(expected, result) << "Case " << i << "," << j << " failed!";
56 } 55 }
57 56
(...skipping 15 matching lines...) Expand all
73 72
74 if (i < arraysize(channels)) { 73 if (i < arraysize(channels)) {
75 const int index = arraysize(channels) - i - 1; 74 const int index = arraysize(channels) - i - 1;
76 filter.add_channel(channels[index]); 75 filter.add_channel(channels[index]);
77 channel_added[index] = true; 76 channel_added[index] = true;
78 } 77 }
79 } 78 }
80 } 79 }
81 80
82 TEST(VariationsStudyFilteringTest, CheckStudyFormFactor) { 81 TEST(VariationsStudyFilteringTest, CheckStudyFormFactor) {
83 const Study_FormFactor form_factors[] = { 82 const Study::FormFactor form_factors[] = {
84 Study_FormFactor_DESKTOP, 83 Study::DESKTOP, Study::PHONE, Study::TABLET, Study::KIOSK,
85 Study_FormFactor_PHONE,
86 Study_FormFactor_TABLET,
87 Study_FormFactor_KIOSK,
88 }; 84 };
89 85
90 ASSERT_EQ(Study_FormFactor_FormFactor_ARRAYSIZE, 86 ASSERT_EQ(Study::FormFactor_ARRAYSIZE,
91 static_cast<int>(arraysize(form_factors))); 87 static_cast<int>(arraysize(form_factors)));
92 88
93 bool form_factor_added[arraysize(form_factors)] = { 0 }; 89 bool form_factor_added[arraysize(form_factors)] = { 0 };
94 Study_Filter filter; 90 Study::Filter filter;
95 91
96 for (size_t i = 0; i <= arraysize(form_factors); ++i) { 92 for (size_t i = 0; i <= arraysize(form_factors); ++i) {
97 for (size_t j = 0; j < arraysize(form_factors); ++j) { 93 for (size_t j = 0; j < arraysize(form_factors); ++j) {
98 const bool expected = form_factor_added[j] || 94 const bool expected = form_factor_added[j] ||
99 filter.form_factor_size() == 0; 95 filter.form_factor_size() == 0;
100 const bool result = internal::CheckStudyFormFactor(filter, 96 const bool result = internal::CheckStudyFormFactor(filter,
101 form_factors[j]); 97 form_factors[j]);
102 EXPECT_EQ(expected, result) << "form_factor: case " << i << "," << j 98 EXPECT_EQ(expected, result) << "form_factor: case " << i << "," << j
103 << " failed!"; 99 << " failed!";
104 } 100 }
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 {"", "", true, true, true}, 185 {"", "", true, true, true},
190 {"", "en-US", false, true, true}, 186 {"", "en-US", false, true, true},
191 {"", "en-US,en-CA,fr", false, false, false}, 187 {"", "en-US,en-CA,fr", false, false, false},
192 {"", "en-US,en-CA,en-GB", false, false, true}, 188 {"", "en-US,en-CA,en-GB", false, false, true},
193 {"", "en-GB,en-CA,en-US", false, false, true}, 189 {"", "en-GB,en-CA,en-US", false, false, true},
194 {"", "ja,kr,vi", true, true, true}, 190 {"", "ja,kr,vi", true, true, true},
195 {"", "fr-CA", true, true, true}, 191 {"", "fr-CA", true, true, true},
196 }; 192 };
197 193
198 for (size_t i = 0; i < arraysize(test_cases); ++i) { 194 for (size_t i = 0; i < arraysize(test_cases); ++i) {
199 Study_Filter filter; 195 Study::Filter filter;
200 for (const std::string& locale : base::SplitString( 196 for (const std::string& locale : base::SplitString(
201 test_cases[i].filter_locales, ",", 197 test_cases[i].filter_locales, ",",
202 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) 198 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL))
203 filter.add_locale(locale); 199 filter.add_locale(locale);
204 for (const std::string& exclude_locale : 200 for (const std::string& exclude_locale :
205 base::SplitString(test_cases[i].exclude_locales, ",", 201 base::SplitString(test_cases[i].exclude_locales, ",",
206 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) 202 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL))
207 filter.add_exclude_locale(exclude_locale); 203 filter.add_exclude_locale(exclude_locale);
208 EXPECT_EQ(test_cases[i].en_us_result, 204 EXPECT_EQ(test_cases[i].en_us_result,
209 internal::CheckStudyLocale(filter, "en-US")); 205 internal::CheckStudyLocale(filter, "en-US"));
210 EXPECT_EQ(test_cases[i].en_ca_result, 206 EXPECT_EQ(test_cases[i].en_ca_result,
211 internal::CheckStudyLocale(filter, "en-CA")); 207 internal::CheckStudyLocale(filter, "en-CA"));
212 EXPECT_EQ(test_cases[i].fr_result, 208 EXPECT_EQ(test_cases[i].fr_result,
213 internal::CheckStudyLocale(filter, "fr")); 209 internal::CheckStudyLocale(filter, "fr"));
214 } 210 }
215 } 211 }
216 212
217 TEST(VariationsStudyFilteringTest, CheckStudyPlatform) { 213 TEST(VariationsStudyFilteringTest, CheckStudyPlatform) {
218 const Study_Platform platforms[] = { 214 const Study::Platform platforms[] = {
219 Study_Platform_PLATFORM_WINDOWS, 215 Study::PLATFORM_WINDOWS, Study::PLATFORM_MAC, Study::PLATFORM_LINUX,
220 Study_Platform_PLATFORM_MAC, 216 Study::PLATFORM_CHROMEOS, Study::PLATFORM_ANDROID, Study::PLATFORM_IOS,
221 Study_Platform_PLATFORM_LINUX,
222 Study_Platform_PLATFORM_CHROMEOS,
223 Study_Platform_PLATFORM_ANDROID,
224 Study_Platform_PLATFORM_IOS,
225 }; 217 };
226 ASSERT_EQ(Study_Platform_Platform_ARRAYSIZE, 218 ASSERT_EQ(Study::Platform_ARRAYSIZE, static_cast<int>(arraysize(platforms)));
227 static_cast<int>(arraysize(platforms)));
228 bool platform_added[arraysize(platforms)] = { 0 }; 219 bool platform_added[arraysize(platforms)] = { 0 };
229 220
230 Study_Filter filter; 221 Study::Filter filter;
231 222
232 // Check in the forwarded order. The loop cond is <= arraysize(platforms) 223 // Check in the forwarded order. The loop cond is <= arraysize(platforms)
233 // instead of < so that the result of adding the last channel gets checked. 224 // instead of < so that the result of adding the last channel gets checked.
234 for (size_t i = 0; i <= arraysize(platforms); ++i) { 225 for (size_t i = 0; i <= arraysize(platforms); ++i) {
235 for (size_t j = 0; j < arraysize(platforms); ++j) { 226 for (size_t j = 0; j < arraysize(platforms); ++j) {
236 const bool expected = platform_added[j] || filter.platform_size() == 0; 227 const bool expected = platform_added[j] || filter.platform_size() == 0;
237 const bool result = internal::CheckStudyPlatform(filter, platforms[j]); 228 const bool result = internal::CheckStudyPlatform(filter, platforms[j]);
238 EXPECT_EQ(expected, result) << "Case " << i << "," << j << " failed!"; 229 EXPECT_EQ(expected, result) << "Case " << i << "," << j << " failed!";
239 } 230 }
240 231
(...skipping 28 matching lines...) Expand all
269 const base::Time start_date; 260 const base::Time start_date;
270 bool expected_result; 261 bool expected_result;
271 } start_test_cases[] = { 262 } start_test_cases[] = {
272 {now - delta, true}, 263 {now - delta, true},
273 // Note, the proto start_date is truncated to seconds, but the reference 264 // Note, the proto start_date is truncated to seconds, but the reference
274 // date isn't. 265 // date isn't.
275 {now, true}, 266 {now, true},
276 {now + delta, false}, 267 {now + delta, false},
277 }; 268 };
278 269
279 Study_Filter filter; 270 Study::Filter filter;
280 271
281 // Start date not set should result in true. 272 // Start date not set should result in true.
282 EXPECT_TRUE(internal::CheckStudyStartDate(filter, now)); 273 EXPECT_TRUE(internal::CheckStudyStartDate(filter, now));
283 274
284 for (size_t i = 0; i < arraysize(start_test_cases); ++i) { 275 for (size_t i = 0; i < arraysize(start_test_cases); ++i) {
285 filter.set_start_date(TimeToProtoTime(start_test_cases[i].start_date)); 276 filter.set_start_date(TimeToProtoTime(start_test_cases[i].start_date));
286 const bool result = internal::CheckStudyStartDate(filter, now); 277 const bool result = internal::CheckStudyStartDate(filter, now);
287 EXPECT_EQ(start_test_cases[i].expected_result, result) 278 EXPECT_EQ(start_test_cases[i].expected_result, result)
288 << "Case " << i << " failed!"; 279 << "Case " << i << " failed!";
289 } 280 }
290 } 281 }
291 282
292 TEST(VariationsStudyFilteringTest, CheckStudyEndDate) { 283 TEST(VariationsStudyFilteringTest, CheckStudyEndDate) {
293 const base::Time now = base::Time::Now(); 284 const base::Time now = base::Time::Now();
294 const base::TimeDelta delta = base::TimeDelta::FromHours(1); 285 const base::TimeDelta delta = base::TimeDelta::FromHours(1);
295 const struct { 286 const struct {
296 const base::Time end_date; 287 const base::Time end_date;
297 bool expected_result; 288 bool expected_result;
298 } start_test_cases[] = { 289 } start_test_cases[] = {
299 {now - delta, false}, {now + delta, true}, 290 {now - delta, false}, {now + delta, true},
300 }; 291 };
301 292
302 Study_Filter filter; 293 Study::Filter filter;
303 294
304 // End date not set should result in true. 295 // End date not set should result in true.
305 EXPECT_TRUE(internal::CheckStudyEndDate(filter, now)); 296 EXPECT_TRUE(internal::CheckStudyEndDate(filter, now));
306 297
307 for (size_t i = 0; i < arraysize(start_test_cases); ++i) { 298 for (size_t i = 0; i < arraysize(start_test_cases); ++i) {
308 filter.set_end_date(TimeToProtoTime(start_test_cases[i].end_date)); 299 filter.set_end_date(TimeToProtoTime(start_test_cases[i].end_date));
309 const bool result = internal::CheckStudyEndDate(filter, now); 300 const bool result = internal::CheckStudyEndDate(filter, now);
310 EXPECT_EQ(start_test_cases[i].expected_result, result) << "Case " << i 301 EXPECT_EQ(start_test_cases[i].expected_result, result) << "Case " << i
311 << " failed!"; 302 << " failed!";
312 } 303 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 { "2.1.*", "2.3.4", false }, 338 { "2.1.*", "2.3.4", false },
348 { "2.*", "2.3.4", true }, 339 { "2.*", "2.3.4", true },
349 { "2.3.*", "2.3.4", true }, 340 { "2.3.*", "2.3.4", true },
350 { "2.3.4.*", "2.3.4", true }, 341 { "2.3.4.*", "2.3.4", true },
351 { "2.3.4.0.*", "2.3.4", true }, 342 { "2.3.4.0.*", "2.3.4", true },
352 { "2.4.*", "2.3.4", true }, 343 { "2.4.*", "2.3.4", true },
353 { "1.3.*", "2.3.4", false }, 344 { "1.3.*", "2.3.4", false },
354 { "1.*", "2.3.4", false }, 345 { "1.*", "2.3.4", false },
355 }; 346 };
356 347
357 Study_Filter filter; 348 Study::Filter filter;
358 349
359 // Min/max version not set should result in true. 350 // Min/max version not set should result in true.
360 EXPECT_TRUE(internal::CheckStudyVersion(filter, base::Version("1.2.3"))); 351 EXPECT_TRUE(internal::CheckStudyVersion(filter, base::Version("1.2.3")));
361 352
362 for (size_t i = 0; i < arraysize(min_test_cases); ++i) { 353 for (size_t i = 0; i < arraysize(min_test_cases); ++i) {
363 filter.set_min_version(min_test_cases[i].min_version); 354 filter.set_min_version(min_test_cases[i].min_version);
364 const bool result = internal::CheckStudyVersion( 355 const bool result = internal::CheckStudyVersion(
365 filter, base::Version(min_test_cases[i].version)); 356 filter, base::Version(min_test_cases[i].version));
366 EXPECT_EQ(min_test_cases[i].expected_result, result) << 357 EXPECT_EQ(min_test_cases[i].expected_result, result) <<
367 "Min. version case " << i << " failed!"; 358 "Min. version case " << i << " failed!";
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 // Substring, so still invalid. 422 // Substring, so still invalid.
432 {"", "apple,pear,orange", "fancy INTEL SNapple device", false}, 423 {"", "apple,pear,orange", "fancy INTEL SNapple device", false},
433 // Empty. 424 // Empty.
434 {"", "apple,pear,orange", "", true}, 425 {"", "apple,pear,orange", "", true},
435 426
436 // Not testing when both are set as it should never occur and should be 427 // Not testing when both are set as it should never occur and should be
437 // considered undefined. 428 // considered undefined.
438 }; 429 };
439 430
440 for (size_t i = 0; i < arraysize(test_cases); ++i) { 431 for (size_t i = 0; i < arraysize(test_cases); ++i) {
441 Study_Filter filter; 432 Study::Filter filter;
442 for (const std::string& cur : base::SplitString( 433 for (const std::string& cur : base::SplitString(
443 test_cases[i].hardware_class, ",", 434 test_cases[i].hardware_class, ",",
444 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) 435 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL))
445 filter.add_hardware_class(cur); 436 filter.add_hardware_class(cur);
446 437
447 for (const std::string& cur : base::SplitString( 438 for (const std::string& cur : base::SplitString(
448 test_cases[i].exclude_hardware_class, ",", 439 test_cases[i].exclude_hardware_class, ",",
449 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) 440 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL))
450 filter.add_exclude_hardware_class(cur); 441 filter.add_exclude_hardware_class(cur);
451 442
(...skipping 29 matching lines...) Expand all
481 {"", "br,ca,us", "in", true}, 472 {"", "br,ca,us", "in", true},
482 // Empty, which is what would happen if no country was returned from the 473 // Empty, which is what would happen if no country was returned from the
483 // server. 474 // server.
484 {"", "br,ca,us", "", true}, 475 {"", "br,ca,us", "", true},
485 476
486 // Not testing when both are set as it should never occur and should be 477 // Not testing when both are set as it should never occur and should be
487 // considered undefined. 478 // considered undefined.
488 }; 479 };
489 480
490 for (const auto& test : test_cases) { 481 for (const auto& test : test_cases) {
491 Study_Filter filter; 482 Study::Filter filter;
492 for (const std::string& country : base::SplitString( 483 for (const std::string& country : base::SplitString(
493 test.country, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) 484 test.country, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL))
494 filter.add_country(country); 485 filter.add_country(country);
495 486
496 for (const std::string& exclude_country : base::SplitString( 487 for (const std::string& exclude_country : base::SplitString(
497 test.exclude_country, ",", 488 test.exclude_country, ",",
498 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) 489 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL))
499 filter.add_exclude_country(exclude_country); 490 filter.add_exclude_country(exclude_country);
500 491
501 EXPECT_EQ(test.expected_result, 492 EXPECT_EQ(test.expected_result,
(...skipping 17 matching lines...) Expand all
519 *study2 = *study1; 510 *study2 = *study1;
520 study2->mutable_experiment(0)->set_name("Bam"); 511 study2->mutable_experiment(0)->set_name("Bam");
521 ASSERT_EQ(seed.study(0).name(), seed.study(1).name()); 512 ASSERT_EQ(seed.study(0).name(), seed.study(1).name());
522 513
523 Study* study3 = seed.add_study(); 514 Study* study3 = seed.add_study();
524 study3->set_name(kTrial3Name); 515 study3->set_name(kTrial3Name);
525 study3->set_default_experiment_name("Default"); 516 study3->set_default_experiment_name("Default");
526 AddExperiment("A", 10, study3); 517 AddExperiment("A", 10, study3);
527 AddExperiment("Default", 25, study3); 518 AddExperiment("Default", 25, study3);
528 519
520 ClientFilterableState client_state;
521 client_state.locale = "en-CA";
522 client_state.reference_date = base::Time::Now();
523 client_state.version = base::Version("20.0.0.0");
524 client_state.channel = Study::STABLE;
525 client_state.form_factor = Study::DESKTOP;
526 client_state.platform = Study::PLATFORM_ANDROID;
527
529 std::vector<ProcessedStudy> processed_studies; 528 std::vector<ProcessedStudy> processed_studies;
530 FilterAndValidateStudies(seed, "en-CA", base::Time::Now(), 529 FilterAndValidateStudies(seed, client_state, &processed_studies);
531 base::Version("20.0.0.0"), Study_Channel_STABLE,
532 Study_FormFactor_DESKTOP, "", "", "",
533 &processed_studies);
534 530
535 // Check that only the first kTrial1Name study was kept. 531 // Check that only the first kTrial1Name study was kept.
536 ASSERT_EQ(2U, processed_studies.size()); 532 ASSERT_EQ(2U, processed_studies.size());
537 EXPECT_EQ(kTrial1Name, processed_studies[0].study()->name()); 533 EXPECT_EQ(kTrial1Name, processed_studies[0].study()->name());
538 EXPECT_EQ(kGroup1Name, processed_studies[0].study()->experiment(0).name()); 534 EXPECT_EQ(kGroup1Name, processed_studies[0].study()->experiment(0).name());
539 EXPECT_EQ(kTrial3Name, processed_studies[1].study()->name()); 535 EXPECT_EQ(kTrial3Name, processed_studies[1].study()->name());
540 } 536 }
541 537
542 TEST(VariationsStudyFilteringTest, FilterAndValidateStudiesWithCountry) { 538 TEST(VariationsStudyFilteringTest, FilterAndValidateStudiesWithCountry) {
543 const char kSessionCountry[] = "ca"; 539 const char kSessionCountry[] = "ca";
544 const char kPermanentCountry[] = "us"; 540 const char kPermanentCountry[] = "us";
545 541
546 struct { 542 struct {
547 Study_Consistency consistency; 543 Study::Consistency consistency;
548 const char* filter_country; 544 const char* filter_country;
549 const char* filter_exclude_country; 545 const char* filter_exclude_country;
550 bool expect_study_kept; 546 bool expect_study_kept;
551 } test_cases[] = { 547 } test_cases[] = {
552 // Country-agnostic studies should be kept regardless of country. 548 // Country-agnostic studies should be kept regardless of country.
553 {Study_Consistency_SESSION, nullptr, nullptr, true}, 549 {Study::SESSION, nullptr, nullptr, true},
554 {Study_Consistency_PERMANENT, nullptr, nullptr, true}, 550 {Study::PERMANENT, nullptr, nullptr, true},
555 551
556 // Session-consistency studies should obey the country code in the seed. 552 // Session-consistency studies should obey the country code in the seed.
557 {Study_Consistency_SESSION, kSessionCountry, nullptr, true}, 553 {Study::SESSION, kSessionCountry, nullptr, true},
558 {Study_Consistency_SESSION, nullptr, kSessionCountry, false}, 554 {Study::SESSION, nullptr, kSessionCountry, false},
559 {Study_Consistency_SESSION, kPermanentCountry, nullptr, false}, 555 {Study::SESSION, kPermanentCountry, nullptr, false},
560 {Study_Consistency_SESSION, nullptr, kPermanentCountry, true}, 556 {Study::SESSION, nullptr, kPermanentCountry, true},
561 557
562 // Permanent-consistency studies should obey the permanent-consistency 558 // Permanent-consistency studies should obey the permanent-consistency
563 // country code. 559 // country code.
564 {Study_Consistency_PERMANENT, kPermanentCountry, nullptr, true}, 560 {Study::PERMANENT, kPermanentCountry, nullptr, true},
565 {Study_Consistency_PERMANENT, nullptr, kPermanentCountry, false}, 561 {Study::PERMANENT, nullptr, kPermanentCountry, false},
566 {Study_Consistency_PERMANENT, kSessionCountry, nullptr, false}, 562 {Study::PERMANENT, kSessionCountry, nullptr, false},
567 {Study_Consistency_PERMANENT, nullptr, kSessionCountry, true}, 563 {Study::PERMANENT, nullptr, kSessionCountry, true},
568 }; 564 };
569 565
570 for (const auto& test : test_cases) { 566 for (const auto& test : test_cases) {
571 VariationsSeed seed; 567 VariationsSeed seed;
572 Study* study = seed.add_study(); 568 Study* study = seed.add_study();
573 study->set_name("study"); 569 study->set_name("study");
574 study->set_default_experiment_name("Default"); 570 study->set_default_experiment_name("Default");
575 AddExperiment("Default", 100, study); 571 AddExperiment("Default", 100, study);
576 study->set_consistency(test.consistency); 572 study->set_consistency(test.consistency);
577 if (test.filter_country) 573 if (test.filter_country)
578 study->mutable_filter()->add_country(test.filter_country); 574 study->mutable_filter()->add_country(test.filter_country);
579 if (test.filter_exclude_country) 575 if (test.filter_exclude_country)
580 study->mutable_filter()->add_exclude_country(test.filter_exclude_country); 576 study->mutable_filter()->add_exclude_country(test.filter_exclude_country);
581 577
578 ClientFilterableState client_state;
579 client_state.locale = "en-CA";
580 client_state.reference_date = base::Time::Now();
581 client_state.version = base::Version("20.0.0.0");
582 client_state.channel = Study::STABLE;
583 client_state.form_factor = Study::DESKTOP;
584 client_state.platform = Study::PLATFORM_ANDROID;
585 client_state.session_consistency_country = kSessionCountry;
586 client_state.permanent_consistency_country = kPermanentCountry;
587
582 std::vector<ProcessedStudy> processed_studies; 588 std::vector<ProcessedStudy> processed_studies;
583 FilterAndValidateStudies(seed, "en-CA", base::Time::Now(), 589 FilterAndValidateStudies(seed, client_state, &processed_studies);
584 base::Version("20.0.0.0"), Study_Channel_STABLE,
585 Study_FormFactor_DESKTOP, "", kSessionCountry,
586 kPermanentCountry, &processed_studies);
587 590
588 EXPECT_EQ(test.expect_study_kept, !processed_studies.empty()); 591 EXPECT_EQ(test.expect_study_kept, !processed_studies.empty());
589 } 592 }
590 } 593 }
591 594
595 TEST(VariationsStudyFilteringTest, GetClientCountryForStudy_Session) {
596 ClientFilterableState client_state;
597 client_state.session_consistency_country = "session_country";
598 client_state.permanent_consistency_country = "permanent_country";
599
600 Study study;
601 study.set_consistency(Study::SESSION);
602 EXPECT_EQ("session_country",
603 internal::GetClientCountryForStudy(study, client_state));
604 }
605
606 TEST(VariationsStudyFilteringTest, GetClientCountryForStudy_Permanent) {
607 ClientFilterableState client_state;
608 client_state.session_consistency_country = "session_country";
609 client_state.permanent_consistency_country = "permanent_country";
610
611 Study study;
612 study.set_consistency(Study::PERMANENT);
613 EXPECT_EQ("permanent_country",
614 internal::GetClientCountryForStudy(study, client_state));
615 }
616
592 TEST(VariationsStudyFilteringTest, IsStudyExpired) { 617 TEST(VariationsStudyFilteringTest, IsStudyExpired) {
593 const base::Time now = base::Time::Now(); 618 const base::Time now = base::Time::Now();
594 const base::TimeDelta delta = base::TimeDelta::FromHours(1); 619 const base::TimeDelta delta = base::TimeDelta::FromHours(1);
595 const struct { 620 const struct {
596 const base::Time expiry_date; 621 const base::Time expiry_date;
597 bool expected_result; 622 bool expected_result;
598 } expiry_test_cases[] = { 623 } expiry_test_cases[] = {
599 { now - delta, true }, 624 { now - delta, true },
600 { now, true }, 625 { now, true },
601 { now + delta, false }, 626 { now + delta, false },
602 }; 627 };
603 628
604 Study study; 629 Study study;
605 630
606 // Expiry date not set should result in false. 631 // Expiry date not set should result in false.
607 EXPECT_FALSE(internal::IsStudyExpired(study, now)); 632 EXPECT_FALSE(internal::IsStudyExpired(study, now));
608 633
609 for (size_t i = 0; i < arraysize(expiry_test_cases); ++i) { 634 for (size_t i = 0; i < arraysize(expiry_test_cases); ++i) {
610 study.set_expiry_date(TimeToProtoTime(expiry_test_cases[i].expiry_date)); 635 study.set_expiry_date(TimeToProtoTime(expiry_test_cases[i].expiry_date));
611 const bool result = internal::IsStudyExpired(study, now); 636 const bool result = internal::IsStudyExpired(study, now);
612 EXPECT_EQ(expiry_test_cases[i].expected_result, result) 637 EXPECT_EQ(expiry_test_cases[i].expected_result, result)
613 << "Case " << i << " failed!"; 638 << "Case " << i << " failed!";
614 } 639 }
615 } 640 }
616 641
617 TEST(VariationsStudyFilteringTest, ValidateStudy) { 642 TEST(VariationsStudyFilteringTest, ValidateStudy) {
618 Study study; 643 Study study;
619 study.set_default_experiment_name("def"); 644 study.set_default_experiment_name("def");
620 AddExperiment("abc", 100, &study); 645 AddExperiment("abc", 100, &study);
621 Study_Experiment* default_group = AddExperiment("def", 200, &study); 646 Study::Experiment* default_group = AddExperiment("def", 200, &study);
622 647
623 ProcessedStudy processed_study; 648 ProcessedStudy processed_study;
624 EXPECT_TRUE(processed_study.Init(&study, false)); 649 EXPECT_TRUE(processed_study.Init(&study, false));
625 EXPECT_EQ(300, processed_study.total_probability()); 650 EXPECT_EQ(300, processed_study.total_probability());
626 651
627 // Min version checks. 652 // Min version checks.
628 study.mutable_filter()->set_min_version("1.2.3.*"); 653 study.mutable_filter()->set_min_version("1.2.3.*");
629 EXPECT_TRUE(processed_study.Init(&study, false)); 654 EXPECT_TRUE(processed_study.Init(&study, false));
630 study.mutable_filter()->set_min_version("1.*.3"); 655 study.mutable_filter()->set_min_version("1.*.3");
631 EXPECT_FALSE(processed_study.Init(&study, false)); 656 EXPECT_FALSE(processed_study.Init(&study, false));
(...skipping 14 matching lines...) Expand all
646 671
647 study.set_default_experiment_name("xyz"); 672 study.set_default_experiment_name("xyz");
648 EXPECT_FALSE(processed_study.Init(&study, false)); 673 EXPECT_FALSE(processed_study.Init(&study, false));
649 674
650 study.set_default_experiment_name("def"); 675 study.set_default_experiment_name("def");
651 default_group->clear_name(); 676 default_group->clear_name();
652 EXPECT_FALSE(processed_study.Init(&study, false)); 677 EXPECT_FALSE(processed_study.Init(&study, false));
653 678
654 default_group->set_name("def"); 679 default_group->set_name("def");
655 EXPECT_TRUE(processed_study.Init(&study, false)); 680 EXPECT_TRUE(processed_study.Init(&study, false));
656 Study_Experiment* repeated_group = study.add_experiment(); 681 Study::Experiment* repeated_group = study.add_experiment();
657 repeated_group->set_name("abc"); 682 repeated_group->set_name("abc");
658 repeated_group->set_probability_weight(1); 683 repeated_group->set_probability_weight(1);
659 EXPECT_FALSE(processed_study.Init(&study, false)); 684 EXPECT_FALSE(processed_study.Init(&study, false));
660 } 685 }
661 686
662 } // namespace variations 687 } // namespace variations
OLDNEW
« no previous file with comments | « components/variations/study_filtering.cc ('k') | components/variations/variations_seed_processor.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698