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

Side by Side Diff: components/variations/service/variations_service_unittest.cc

Issue 1404583004: Support gzip-compressed seed data from the variations server. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Resolved comments Created 5 years, 2 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 (c) 2012 The Chromium Authors. All rights reserved. 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 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/service/variations_service.h" 5 #include "components/variations/service/variations_service.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/base64.h" 9 #include "base/base64.h"
10 #include "base/feature_list.h" 10 #include "base/feature_list.h"
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 TestVariationsService( 76 TestVariationsService(
77 scoped_ptr<web_resource::TestRequestAllowedNotifier> test_notifier, 77 scoped_ptr<web_resource::TestRequestAllowedNotifier> test_notifier,
78 PrefService* local_state) 78 PrefService* local_state)
79 : VariationsService(make_scoped_ptr(new TestVariationsServiceClient()), 79 : VariationsService(make_scoped_ptr(new TestVariationsServiceClient()),
80 test_notifier.Pass(), 80 test_notifier.Pass(),
81 local_state, 81 local_state,
82 NULL, 82 NULL,
83 UIStringOverrider()), 83 UIStringOverrider()),
84 intercepts_fetch_(true), 84 intercepts_fetch_(true),
85 fetch_attempted_(false), 85 fetch_attempted_(false),
86 seed_stored_(false) { 86 seed_stored_(false),
87 delta_compressed_seed_(false),
88 gzip_compressed_seed_(false) {
87 // Set this so StartRepeatedVariationsSeedFetch can be called in tests. 89 // Set this so StartRepeatedVariationsSeedFetch can be called in tests.
88 SetCreateTrialsFromSeedCalledForTesting(true); 90 SetCreateTrialsFromSeedCalledForTesting(true);
91 set_variations_server_url(
92 GetVariationsServerURL(local_state, std::string()));
89 } 93 }
90 94
91 ~TestVariationsService() override {} 95 ~TestVariationsService() override {}
92 96
93 void set_intercepts_fetch(bool value) { 97 void set_intercepts_fetch(bool value) {
94 intercepts_fetch_ = value; 98 intercepts_fetch_ = value;
95 } 99 }
96 100
97 bool fetch_attempted() const { return fetch_attempted_; } 101 bool fetch_attempted() const { return fetch_attempted_; }
98 bool seed_stored() const { return seed_stored_; } 102 bool seed_stored() const { return seed_stored_; }
99 const std::string& stored_country() const { return stored_country_; } 103 const std::string& stored_country() const { return stored_country_; }
104 bool delta_compressed_seed() const { return delta_compressed_seed_; }
105 bool gzip_compressed_seed() const { return gzip_compressed_seed_; }
100 106
101 void DoActualFetch() override { 107 void DoActualFetch() override {
102 if (intercepts_fetch_) { 108 if (intercepts_fetch_) {
103 fetch_attempted_ = true; 109 fetch_attempted_ = true;
104 return; 110 return;
105 } 111 }
106 112
107 VariationsService::DoActualFetch(); 113 VariationsService::DoActualFetch();
108 } 114 }
109 115
110 bool StoreSeed(const std::string& seed_data, 116 bool StoreSeed(const std::string& seed_data,
111 const std::string& seed_signature, 117 const std::string& seed_signature,
112 const std::string& country_code, 118 const std::string& country_code,
113 const base::Time& date_fetched, 119 const base::Time& date_fetched,
114 bool is_delta_compressed) override { 120 bool is_delta_compressed,
121 bool is_gzip_compressed) override {
115 seed_stored_ = true; 122 seed_stored_ = true;
116 stored_seed_data_ = seed_data; 123 stored_seed_data_ = seed_data;
117 stored_country_ = country_code; 124 stored_country_ = country_code;
125 delta_compressed_seed_ = is_delta_compressed;
126 gzip_compressed_seed_ = is_gzip_compressed;
118 return true; 127 return true;
119 } 128 }
120 129
121 private: 130 private:
122 bool LoadSeed(VariationsSeed* seed) override { 131 bool LoadSeed(VariationsSeed* seed) override {
123 if (!seed_stored_) 132 if (!seed_stored_)
124 return false; 133 return false;
125 return seed->ParseFromString(stored_seed_data_); 134 return seed->ParseFromString(stored_seed_data_);
126 } 135 }
127 136
128 bool intercepts_fetch_; 137 bool intercepts_fetch_;
129 bool fetch_attempted_; 138 bool fetch_attempted_;
130 bool seed_stored_; 139 bool seed_stored_;
131 std::string stored_seed_data_; 140 std::string stored_seed_data_;
132 std::string stored_country_; 141 std::string stored_country_;
142 bool delta_compressed_seed_;
143 bool gzip_compressed_seed_;
133 144
134 DISALLOW_COPY_AND_ASSIGN(TestVariationsService); 145 DISALLOW_COPY_AND_ASSIGN(TestVariationsService);
135 }; 146 };
136 147
137 class TestVariationsServiceObserver : public VariationsService::Observer { 148 class TestVariationsServiceObserver : public VariationsService::Observer {
138 public: 149 public:
139 TestVariationsServiceObserver() 150 TestVariationsServiceObserver()
140 : best_effort_changes_notified_(0), 151 : best_effort_changes_notified_(0),
141 crticial_changes_notified_(0) { 152 crticial_changes_notified_(0) {
142 } 153 }
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 } 205 }
195 206
196 // Serializes |seed| to protobuf binary format. 207 // Serializes |seed| to protobuf binary format.
197 std::string SerializeSeed(const variations::VariationsSeed& seed) { 208 std::string SerializeSeed(const variations::VariationsSeed& seed) {
198 std::string serialized_seed; 209 std::string serialized_seed;
199 seed.SerializeToString(&serialized_seed); 210 seed.SerializeToString(&serialized_seed);
200 return serialized_seed; 211 return serialized_seed;
201 } 212 }
202 213
203 // Simulates a variations service response by setting a date header and the 214 // Simulates a variations service response by setting a date header and the
215 // specified HTTP |response_code| on |fetcher|. Sets additional header |header|
216 // if it is not null.
217 scoped_refptr<net::HttpResponseHeaders> SimulateServerResponseWithHeader(
218 int response_code,
219 net::TestURLFetcher* fetcher,
220 const std::string* header) {
221 EXPECT_TRUE(fetcher);
222 scoped_refptr<net::HttpResponseHeaders> headers(
223 new net::HttpResponseHeaders("date:Wed, 13 Feb 2013 00:25:24 GMT\0\0"));
224 if (header)
225 headers->AddHeader(*header);
226 fetcher->set_response_headers(headers);
227 fetcher->set_response_code(response_code);
228 return headers;
229 }
230
231 // Simulates a variations service response by setting a date header and the
204 // specified HTTP |response_code| on |fetcher|. 232 // specified HTTP |response_code| on |fetcher|.
205 scoped_refptr<net::HttpResponseHeaders> SimulateServerResponse( 233 scoped_refptr<net::HttpResponseHeaders> SimulateServerResponse(
206 int response_code, 234 int response_code,
207 net::TestURLFetcher* fetcher) { 235 net::TestURLFetcher* fetcher) {
208 EXPECT_TRUE(fetcher); 236 return SimulateServerResponseWithHeader(response_code, fetcher, nullptr);
209 scoped_refptr<net::HttpResponseHeaders> headers(
210 new net::HttpResponseHeaders("date:Wed, 13 Feb 2013 00:25:24 GMT\0\0"));
211 fetcher->set_response_headers(headers);
212 fetcher->set_response_code(response_code);
213 return headers;
214 } 237 }
215 238
216 // Converts |list_value| to a string, to make it easier for debugging. 239 // Converts |list_value| to a string, to make it easier for debugging.
217 std::string ListValueToString(const base::ListValue& list_value) { 240 std::string ListValueToString(const base::ListValue& list_value) {
218 std::string json; 241 std::string json;
219 JSONStringValueSerializer serializer(&json); 242 JSONStringValueSerializer serializer(&json);
220 serializer.set_pretty_print(true); 243 serializer.set_pretty_print(true);
221 serializer.Serialize(list_value); 244 serializer.Serialize(list_value);
222 return json; 245 return json;
223 } 246 }
(...skipping 22 matching lines...) Expand all
246 // this test. 269 // this test.
247 base::FieldTrialList field_trial_list(nullptr); 270 base::FieldTrialList field_trial_list(nullptr);
248 271
249 // Create a variations service. 272 // Create a variations service.
250 TestVariationsService service( 273 TestVariationsService service(
251 make_scoped_ptr(new web_resource::TestRequestAllowedNotifier(&prefs)), 274 make_scoped_ptr(new web_resource::TestRequestAllowedNotifier(&prefs)),
252 &prefs); 275 &prefs);
253 276
254 // Store a seed. 277 // Store a seed.
255 service.StoreSeed(SerializeSeed(CreateTestSeed()), std::string(), 278 service.StoreSeed(SerializeSeed(CreateTestSeed()), std::string(),
256 std::string(), base::Time::Now(), false); 279 std::string(), base::Time::Now(), false, false);
257 prefs.SetInt64(prefs::kVariationsLastFetchTime, 280 prefs.SetInt64(prefs::kVariationsLastFetchTime,
258 base::Time::Now().ToInternalValue()); 281 base::Time::Now().ToInternalValue());
259 282
260 // Check that field trials are created from the seed. Since the test study has 283 // Check that field trials are created from the seed. Since the test study has
261 // only 1 experiment with 100% probability weight, we must be part of it. 284 // only 1 experiment with 100% probability weight, we must be part of it.
262 EXPECT_TRUE(service.CreateTrialsFromSeed(base::FeatureList::GetInstance())); 285 EXPECT_TRUE(service.CreateTrialsFromSeed(base::FeatureList::GetInstance()));
263 EXPECT_EQ(base::FieldTrialList::FindFullName(kTestSeedStudyName), 286 EXPECT_EQ(base::FieldTrialList::FindFullName(kTestSeedStudyName),
264 kTestSeedExperimentName); 287 kTestSeedExperimentName);
265 } 288 }
266 289
(...skipping 10 matching lines...) Expand all
277 base::FieldTrialList field_trial_list(nullptr); 300 base::FieldTrialList field_trial_list(nullptr);
278 301
279 // Create a variations service 302 // Create a variations service
280 TestVariationsService service( 303 TestVariationsService service(
281 make_scoped_ptr(new web_resource::TestRequestAllowedNotifier(&prefs)), 304 make_scoped_ptr(new web_resource::TestRequestAllowedNotifier(&prefs)),
282 &prefs); 305 &prefs);
283 306
284 // Store a seed. To simulate a first run, |prefs::kVariationsLastFetchTime| 307 // Store a seed. To simulate a first run, |prefs::kVariationsLastFetchTime|
285 // is left empty. 308 // is left empty.
286 service.StoreSeed(SerializeSeed(CreateTestSeed()), std::string(), 309 service.StoreSeed(SerializeSeed(CreateTestSeed()), std::string(),
287 std::string(), base::Time::Now(), false); 310 std::string(), base::Time::Now(), false, false);
288 EXPECT_EQ(0, prefs.GetInt64(prefs::kVariationsLastFetchTime)); 311 EXPECT_EQ(0, prefs.GetInt64(prefs::kVariationsLastFetchTime));
289 312
290 // Check that field trials are created from the seed. Since the test study has 313 // Check that field trials are created from the seed. Since the test study has
291 // only 1 experiment with 100% probability weight, we must be part of it. 314 // only 1 experiment with 100% probability weight, we must be part of it.
292 EXPECT_TRUE(service.CreateTrialsFromSeed(base::FeatureList::GetInstance())); 315 EXPECT_TRUE(service.CreateTrialsFromSeed(base::FeatureList::GetInstance()));
293 EXPECT_EQ(base::FieldTrialList::FindFullName(kTestSeedStudyName), 316 EXPECT_EQ(base::FieldTrialList::FindFullName(kTestSeedStudyName),
294 kTestSeedExperimentName); 317 kTestSeedExperimentName);
295 } 318 }
296 319
297 TEST_F(VariationsServiceTest, CreateTrialsFromOutdatedSeed) { 320 TEST_F(VariationsServiceTest, CreateTrialsFromOutdatedSeed) {
(...skipping 10 matching lines...) Expand all
308 331
309 // Create a variations service. 332 // Create a variations service.
310 TestVariationsService service( 333 TestVariationsService service(
311 make_scoped_ptr(new web_resource::TestRequestAllowedNotifier(&prefs)), 334 make_scoped_ptr(new web_resource::TestRequestAllowedNotifier(&prefs)),
312 &prefs); 335 &prefs);
313 336
314 // Store a seed, with a fetch time 31 days in the past. 337 // Store a seed, with a fetch time 31 days in the past.
315 const base::Time seed_date = 338 const base::Time seed_date =
316 base::Time::Now() - base::TimeDelta::FromDays(31); 339 base::Time::Now() - base::TimeDelta::FromDays(31);
317 service.StoreSeed(SerializeSeed(CreateTestSeed()), std::string(), 340 service.StoreSeed(SerializeSeed(CreateTestSeed()), std::string(),
318 std::string(), seed_date, false); 341 std::string(), seed_date, false, false);
319 prefs.SetInt64(prefs::kVariationsLastFetchTime, seed_date.ToInternalValue()); 342 prefs.SetInt64(prefs::kVariationsLastFetchTime, seed_date.ToInternalValue());
320 343
321 // Check that field trials are not created from the seed. 344 // Check that field trials are not created from the seed.
322 EXPECT_FALSE(service.CreateTrialsFromSeed(base::FeatureList::GetInstance())); 345 EXPECT_FALSE(service.CreateTrialsFromSeed(base::FeatureList::GetInstance()));
323 EXPECT_TRUE(base::FieldTrialList::FindFullName(kTestSeedStudyName).empty()); 346 EXPECT_TRUE(base::FieldTrialList::FindFullName(kTestSeedStudyName).empty());
324 } 347 }
325 348
326 TEST_F(VariationsServiceTest, GetVariationsServerURL) { 349 TEST_F(VariationsServiceTest, GetVariationsServerURL) {
327 TestingPrefServiceSimple prefs; 350 TestingPrefServiceSimple prefs;
328 VariationsService::RegisterPrefs(prefs.registry()); 351 VariationsService::RegisterPrefs(prefs.registry());
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 EXPECT_TRUE(test_service.fetch_attempted()); 438 EXPECT_TRUE(test_service.fetch_attempted());
416 } 439 }
417 440
418 TEST_F(VariationsServiceTest, SeedStoredWhenOKStatus) { 441 TEST_F(VariationsServiceTest, SeedStoredWhenOKStatus) {
419 TestingPrefServiceSimple prefs; 442 TestingPrefServiceSimple prefs;
420 VariationsService::RegisterPrefs(prefs.registry()); 443 VariationsService::RegisterPrefs(prefs.registry());
421 444
422 TestVariationsService service( 445 TestVariationsService service(
423 make_scoped_ptr(new web_resource::TestRequestAllowedNotifier(&prefs)), 446 make_scoped_ptr(new web_resource::TestRequestAllowedNotifier(&prefs)),
424 &prefs); 447 &prefs);
425 service.variations_server_url_ =
426 service.GetVariationsServerURL(&prefs, std::string());
427 service.set_intercepts_fetch(false); 448 service.set_intercepts_fetch(false);
428 449
429 net::TestURLFetcherFactory factory; 450 net::TestURLFetcherFactory factory;
430 service.DoActualFetch(); 451 service.DoActualFetch();
431 452
432 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); 453 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
433 SimulateServerResponse(net::HTTP_OK, fetcher); 454 SimulateServerResponse(net::HTTP_OK, fetcher);
434 fetcher->SetResponseString(SerializeSeed(CreateTestSeed())); 455 fetcher->SetResponseString(SerializeSeed(CreateTestSeed()));
435 456
436 EXPECT_FALSE(service.seed_stored()); 457 EXPECT_FALSE(service.seed_stored());
437 service.OnURLFetchComplete(fetcher); 458 service.OnURLFetchComplete(fetcher);
438 EXPECT_TRUE(service.seed_stored()); 459 EXPECT_TRUE(service.seed_stored());
439 } 460 }
440 461
441 TEST_F(VariationsServiceTest, SeedNotStoredWhenNonOKStatus) { 462 TEST_F(VariationsServiceTest, SeedNotStoredWhenNonOKStatus) {
442 const int non_ok_status_codes[] = { 463 const int non_ok_status_codes[] = {
443 net::HTTP_NO_CONTENT, 464 net::HTTP_NO_CONTENT,
444 net::HTTP_NOT_MODIFIED, 465 net::HTTP_NOT_MODIFIED,
445 net::HTTP_NOT_FOUND, 466 net::HTTP_NOT_FOUND,
446 net::HTTP_INTERNAL_SERVER_ERROR, 467 net::HTTP_INTERNAL_SERVER_ERROR,
447 net::HTTP_SERVICE_UNAVAILABLE, 468 net::HTTP_SERVICE_UNAVAILABLE,
448 }; 469 };
449 470
450 TestingPrefServiceSimple prefs; 471 TestingPrefServiceSimple prefs;
451 VariationsService::RegisterPrefs(prefs.registry()); 472 VariationsService::RegisterPrefs(prefs.registry());
452 473
453 VariationsService service( 474 TestVariationsService service(
454 make_scoped_ptr(new TestVariationsServiceClient()),
455 make_scoped_ptr(new web_resource::TestRequestAllowedNotifier(&prefs)), 475 make_scoped_ptr(new web_resource::TestRequestAllowedNotifier(&prefs)),
456 &prefs, NULL, UIStringOverrider()); 476 &prefs);
457 service.variations_server_url_ = 477 service.set_intercepts_fetch(false);
458 service.GetVariationsServerURL(&prefs, std::string());
459 for (size_t i = 0; i < arraysize(non_ok_status_codes); ++i) { 478 for (size_t i = 0; i < arraysize(non_ok_status_codes); ++i) {
460 net::TestURLFetcherFactory factory; 479 net::TestURLFetcherFactory factory;
461 service.DoActualFetch(); 480 service.DoActualFetch();
462 EXPECT_TRUE(prefs.FindPreference(prefs::kVariationsSeed)->IsDefaultValue()); 481 EXPECT_TRUE(prefs.FindPreference(prefs::kVariationsSeed)->IsDefaultValue());
463 482
464 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); 483 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
465 SimulateServerResponse(non_ok_status_codes[i], fetcher); 484 SimulateServerResponse(non_ok_status_codes[i], fetcher);
466 service.OnURLFetchComplete(fetcher); 485 service.OnURLFetchComplete(fetcher);
467 486
468 EXPECT_TRUE(prefs.FindPreference(prefs::kVariationsSeed)->IsDefaultValue()); 487 EXPECT_TRUE(prefs.FindPreference(prefs::kVariationsSeed)->IsDefaultValue());
469 } 488 }
470 } 489 }
471 490
491 TEST_F(VariationsServiceTest, RequestGzipCompressedSeed) {
492 TestingPrefServiceSimple prefs;
493 VariationsService::RegisterPrefs(prefs.registry());
494 net::TestURLFetcherFactory factory;
495
496 TestVariationsService service(
497 make_scoped_ptr(new web_resource::TestRequestAllowedNotifier(&prefs)),
498 &prefs);
499 service.set_intercepts_fetch(false);
Alexei Svitkine (slow) 2015/10/16 15:16:44 Nit: If more places call this than not, suggest in
veranika 2015/10/16 21:01:00 There are 11 uses of TestVariationsService and onl
500 service.DoActualFetch();
501
502 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
503 net::HttpRequestHeaders headers;
504 fetcher->GetExtraRequestHeaders(&headers);
505 std::string field;
506 ASSERT_TRUE(headers.GetHeader("A-IM", &field));
507 EXPECT_EQ("gzip", field);
508 }
509
510 TEST_F(VariationsServiceTest, InstanceManipulations) {
511 struct {
512 std::string im;
513 bool delta_compressed;
514 bool gzip_compressed;
515 bool seed_stored;
516 } cases[] = {
517 {"", false, false, true},
518 {"IM:gzip", false, true, true},
519 {"IM:x-bm", true, false, true},
520 {"IM:x-bm,gzip", true, true, true},
521 {"IM: x-bm, gzip", true, true, true},
522 {"IM:gzip,x-bm", false, false, false},
523 {"IM:deflate,x-bm,gzip", false, false, false},
524 };
525
526 TestingPrefServiceSimple prefs;
527 VariationsService::RegisterPrefs(prefs.registry());
528 std::string serialized_seed = SerializeSeed(CreateTestSeed());
529 net::TestURLFetcherFactory factory;
530
531 for (size_t i = 0; i < arraysize(cases); ++i) {
532 TestVariationsService service(
533 make_scoped_ptr(new web_resource::TestRequestAllowedNotifier(&prefs)),
534 &prefs);
535 service.set_intercepts_fetch(false);
536 service.DoActualFetch();
537 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
538
539 if (cases[i].im.empty())
540 SimulateServerResponse(net::HTTP_OK, fetcher);
541 else
542 SimulateServerResponseWithHeader(net::HTTP_OK, fetcher, &cases[i].im);
543 fetcher->SetResponseString(serialized_seed);
544 service.OnURLFetchComplete(fetcher);
545
546 EXPECT_EQ(cases[i].seed_stored, service.seed_stored());
547 EXPECT_EQ(cases[i].delta_compressed, service.delta_compressed_seed());
548 EXPECT_EQ(cases[i].gzip_compressed, service.gzip_compressed_seed());
549 }
550 }
551
472 TEST_F(VariationsServiceTest, CountryHeader) { 552 TEST_F(VariationsServiceTest, CountryHeader) {
473 TestingPrefServiceSimple prefs; 553 TestingPrefServiceSimple prefs;
474 VariationsService::RegisterPrefs(prefs.registry()); 554 VariationsService::RegisterPrefs(prefs.registry());
475 555
476 TestVariationsService service( 556 TestVariationsService service(
477 make_scoped_ptr(new web_resource::TestRequestAllowedNotifier(&prefs)), 557 make_scoped_ptr(new web_resource::TestRequestAllowedNotifier(&prefs)),
478 &prefs); 558 &prefs);
479 service.variations_server_url_ =
480 service.GetVariationsServerURL(&prefs, std::string());
481 service.set_intercepts_fetch(false); 559 service.set_intercepts_fetch(false);
482 560
483 net::TestURLFetcherFactory factory; 561 net::TestURLFetcherFactory factory;
484 service.DoActualFetch(); 562 service.DoActualFetch();
485 563
486 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); 564 net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
487 scoped_refptr<net::HttpResponseHeaders> headers = 565 scoped_refptr<net::HttpResponseHeaders> headers =
488 SimulateServerResponse(net::HTTP_OK, fetcher); 566 SimulateServerResponse(net::HTTP_OK, fetcher);
489 headers->AddHeader("X-Country: test"); 567 headers->AddHeader("X-Country: test");
490 fetcher->SetResponseString(SerializeSeed(CreateTestSeed())); 568 fetcher->SetResponseString(SerializeSeed(CreateTestSeed()));
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 << test.pref_value_before << ", " << test.version << ", " 716 << test.pref_value_before << ", " << test.version << ", "
639 << test.latest_country_code; 717 << test.latest_country_code;
640 718
641 histogram_tester.ExpectUniqueSample( 719 histogram_tester.ExpectUniqueSample(
642 "Variations.LoadPermanentConsistencyCountryResult", 720 "Variations.LoadPermanentConsistencyCountryResult",
643 test.expected_result, 1); 721 test.expected_result, 1);
644 } 722 }
645 } 723 }
646 724
647 } // namespace variations 725 } // namespace variations
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698