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

Side by Side Diff: components/doodle/doodle_service_unittest.cc

Issue 2772313002: [Doodle] Don't refresh more than once per 15 mins (Closed)
Patch Set: metrics Created 3 years, 8 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 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 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/doodle/doodle_service.h" 5 #include "components/doodle/doodle_service.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <utility> 8 #include <utility>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 DoodleServiceTest() 68 DoodleServiceTest()
69 : task_runner_(new base::TestMockTimeTaskRunner()), 69 : task_runner_(new base::TestMockTimeTaskRunner()),
70 task_runner_handle_(task_runner_), 70 task_runner_handle_(task_runner_),
71 tick_clock_(task_runner_->GetMockTickClock()), 71 tick_clock_(task_runner_->GetMockTickClock()),
72 fetcher_(nullptr), 72 fetcher_(nullptr),
73 expiry_timer_(nullptr) { 73 expiry_timer_(nullptr) {
74 DoodleService::RegisterProfilePrefs(pref_service_.registry()); 74 DoodleService::RegisterProfilePrefs(pref_service_.registry());
75 75
76 task_runner_->FastForwardBy(base::TimeDelta::FromHours(12345)); 76 task_runner_->FastForwardBy(base::TimeDelta::FromHours(12345));
77 77
78 RecreateService(); 78 // Set the minimum refresh interval to 0 by default, so tests don't have to
79 // worry about it. The tests that care set it explicitly.
80 RecreateServiceWithZeroRefreshInterval();
79 } 81 }
80 82
81 void DestroyService() { service_ = nullptr; } 83 void DestroyService() { service_ = nullptr; }
82 84
83 void RecreateService() { 85 void RecreateServiceWithZeroRefreshInterval() {
86 RecreateService(/*min_refresh_interval=*/base::TimeDelta());
87 }
88
89 void RecreateService(base::Optional<base::TimeDelta> refresh_interval) {
84 auto expiry_timer = base::MakeUnique<base::OneShotTimer>(tick_clock_.get()); 90 auto expiry_timer = base::MakeUnique<base::OneShotTimer>(tick_clock_.get());
85 expiry_timer->SetTaskRunner(task_runner_); 91 expiry_timer->SetTaskRunner(task_runner_);
86 expiry_timer_ = expiry_timer.get(); 92 expiry_timer_ = expiry_timer.get();
87 93
88 auto fetcher = base::MakeUnique<FakeDoodleFetcher>(); 94 auto fetcher = base::MakeUnique<FakeDoodleFetcher>();
89 fetcher_ = fetcher.get(); 95 fetcher_ = fetcher.get();
90 96
91 service_ = base::MakeUnique<DoodleService>( 97 service_ = base::MakeUnique<DoodleService>(
92 &pref_service_, std::move(fetcher), std::move(expiry_timer), 98 &pref_service_, std::move(fetcher), std::move(expiry_timer),
93 task_runner_->GetMockClock(), task_runner_->GetMockTickClock()); 99 task_runner_->GetMockClock(), task_runner_->GetMockTickClock(),
100 refresh_interval);
94 } 101 }
95 102
96 DoodleService* service() { return service_.get(); } 103 DoodleService* service() { return service_.get(); }
97 FakeDoodleFetcher* fetcher() { return fetcher_; } 104 FakeDoodleFetcher* fetcher() { return fetcher_; }
98 105
99 base::TestMockTimeTaskRunner* task_runner() { return task_runner_.get(); } 106 base::TestMockTimeTaskRunner* task_runner() { return task_runner_.get(); }
100 107
101 private: 108 private:
102 TestingPrefServiceSimple pref_service_; 109 TestingPrefServiceSimple pref_service_;
103 110
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 // Load some doodle config. 154 // Load some doodle config.
148 service()->Refresh(); 155 service()->Refresh();
149 DoodleConfig config = CreateConfig(DoodleType::SIMPLE); 156 DoodleConfig config = CreateConfig(DoodleType::SIMPLE);
150 config.large_image.url = GURL("https://doodle.com/doodle.jpg"); 157 config.large_image.url = GURL("https://doodle.com/doodle.jpg");
151 fetcher()->ServeAllCallbacks(DoodleState::AVAILABLE, 158 fetcher()->ServeAllCallbacks(DoodleState::AVAILABLE,
152 base::TimeDelta::FromHours(1), config); 159 base::TimeDelta::FromHours(1), config);
153 ASSERT_THAT(service()->config(), Eq(config)); 160 ASSERT_THAT(service()->config(), Eq(config));
154 161
155 // Re-create the service. It should have persisted the config, and load it 162 // Re-create the service. It should have persisted the config, and load it
156 // again automatically. 163 // again automatically.
157 RecreateService(); 164 RecreateServiceWithZeroRefreshInterval();
158 EXPECT_THAT(service()->config(), Eq(config)); 165 EXPECT_THAT(service()->config(), Eq(config));
159 } 166 }
160 167
161 TEST_F(DoodleServiceTest, PersistsExpiryDate) { 168 TEST_F(DoodleServiceTest, PersistsExpiryDate) {
162 // Load some doodle config. 169 // Load some doodle config.
163 service()->Refresh(); 170 service()->Refresh();
164 DoodleConfig config = CreateConfig(DoodleType::SIMPLE); 171 DoodleConfig config = CreateConfig(DoodleType::SIMPLE);
165 config.large_image.url = GURL("https://doodle.com/doodle.jpg"); 172 config.large_image.url = GURL("https://doodle.com/doodle.jpg");
166 fetcher()->ServeAllCallbacks(DoodleState::AVAILABLE, 173 fetcher()->ServeAllCallbacks(DoodleState::AVAILABLE,
167 base::TimeDelta::FromHours(1), config); 174 base::TimeDelta::FromHours(1), config);
168 ASSERT_THAT(service()->config(), Eq(config)); 175 ASSERT_THAT(service()->config(), Eq(config));
169 176
170 // Destroy the service, and let some time pass. 177 // Destroy the service, and let some time pass.
171 DestroyService(); 178 DestroyService();
172 task_runner()->FastForwardBy(base::TimeDelta::FromMinutes(15)); 179 task_runner()->FastForwardBy(base::TimeDelta::FromMinutes(15));
173 180
174 // Remove the abandoned expiry task from the task runner. 181 // Remove the abandoned expiry task from the task runner.
175 ASSERT_THAT(task_runner()->GetPendingTaskCount(), Eq(1u)); 182 ASSERT_THAT(task_runner()->GetPendingTaskCount(), Eq(1u));
176 task_runner()->ClearPendingTasks(); 183 task_runner()->ClearPendingTasks();
177 184
178 // Re-create the service. The persisted config should have been loaded again. 185 // Re-create the service. The persisted config should have been loaded again.
179 RecreateService(); 186 RecreateServiceWithZeroRefreshInterval();
180 EXPECT_THAT(service()->config(), Eq(config)); 187 EXPECT_THAT(service()->config(), Eq(config));
181 188
182 // Its time-to-live should have been updated. 189 // Its time-to-live should have been updated.
183 EXPECT_THAT(task_runner()->GetPendingTaskCount(), Eq(1u)); 190 EXPECT_THAT(task_runner()->GetPendingTaskCount(), Eq(1u));
184 EXPECT_THAT(task_runner()->NextPendingTaskDelay(), 191 EXPECT_THAT(task_runner()->NextPendingTaskDelay(),
185 Eq(base::TimeDelta::FromMinutes(45))); 192 Eq(base::TimeDelta::FromMinutes(45)));
186 } 193 }
187 194
188 TEST_F(DoodleServiceTest, PersistedConfigExpires) { 195 TEST_F(DoodleServiceTest, PersistedConfigExpires) {
189 // Load some doodle config. 196 // Load some doodle config.
190 service()->Refresh(); 197 service()->Refresh();
191 DoodleConfig config = CreateConfig(DoodleType::SIMPLE); 198 DoodleConfig config = CreateConfig(DoodleType::SIMPLE);
192 config.large_image.url = GURL("https://doodle.com/doodle.jpg"); 199 config.large_image.url = GURL("https://doodle.com/doodle.jpg");
193 fetcher()->ServeAllCallbacks(DoodleState::AVAILABLE, 200 fetcher()->ServeAllCallbacks(DoodleState::AVAILABLE,
194 base::TimeDelta::FromHours(1), config); 201 base::TimeDelta::FromHours(1), config);
195 ASSERT_THAT(service()->config(), Eq(config)); 202 ASSERT_THAT(service()->config(), Eq(config));
196 203
197 // Destroy the service, and let enough time pass so that the config expires. 204 // Destroy the service, and let enough time pass so that the config expires.
198 DestroyService(); 205 DestroyService();
199 task_runner()->FastForwardBy(base::TimeDelta::FromHours(1)); 206 task_runner()->FastForwardBy(base::TimeDelta::FromHours(1));
200 207
201 // Re-create the service. The persisted config should have been discarded 208 // Re-create the service. The persisted config should have been discarded
202 // because it is expired. 209 // because it is expired.
203 RecreateService(); 210 RecreateServiceWithZeroRefreshInterval();
204 EXPECT_THAT(service()->config(), Eq(base::nullopt)); 211 EXPECT_THAT(service()->config(), Eq(base::nullopt));
205 } 212 }
206 213
214 TEST_F(DoodleServiceTest, RespectsMinRefreshInterval) {
215 // Create a service with the default refresh interval.
216 RecreateService(/*min_refresh_interval=*/base::nullopt);
217
218 // Load some doodle config.
219 service()->Refresh();
220 DoodleConfig config = CreateConfig(DoodleType::SIMPLE);
221 config.large_image.url = GURL("https://doodle.com/doodle.jpg");
222 fetcher()->ServeAllCallbacks(DoodleState::AVAILABLE,
223 base::TimeDelta::FromHours(1), config);
224 ASSERT_THAT(service()->config(), Eq(config));
225
226 // Let some time pass (less than the refresh interval).
227 task_runner()->FastForwardBy(base::TimeDelta::FromMinutes(10));
228
229 // Request a refresh. This should get ignored.
230 service()->Refresh();
231 EXPECT_THAT(fetcher()->num_pending_callbacks(), Eq(0u));
232
233 // Let more time pass, so we get past the refresh interval.
234 task_runner()->FastForwardBy(base::TimeDelta::FromMinutes(6));
235
236 // Now the refresh request should be honored again.
237 service()->Refresh();
238 EXPECT_THAT(fetcher()->num_pending_callbacks(), Eq(1u));
239 }
240
207 TEST_F(DoodleServiceTest, CallsObserverOnConfigReceived) { 241 TEST_F(DoodleServiceTest, CallsObserverOnConfigReceived) {
208 StrictMock<MockDoodleObserver> observer; 242 StrictMock<MockDoodleObserver> observer;
209 service()->AddObserver(&observer); 243 service()->AddObserver(&observer);
210 244
211 ASSERT_THAT(service()->config(), Eq(base::nullopt)); 245 ASSERT_THAT(service()->config(), Eq(base::nullopt));
212 246
213 // Request a refresh of the doodle config. 247 // Request a refresh of the doodle config.
214 service()->Refresh(); 248 service()->Refresh();
215 // The request should have arrived at the fetcher. 249 // The request should have arrived at the fetcher.
216 ASSERT_THAT(fetcher()->num_pending_callbacks(), Eq(1u)); 250 ASSERT_THAT(fetcher()->num_pending_callbacks(), Eq(1u));
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 ASSERT_THAT(service()->config(), Eq(base::nullopt)); 455 ASSERT_THAT(service()->config(), Eq(base::nullopt));
422 456
423 // The outcome should have been recorded, but not the time - we only record 457 // The outcome should have been recorded, but not the time - we only record
424 // that for successful downloads. 458 // that for successful downloads.
425 histograms.ExpectUniqueSample("Doodle.ConfigDownloadOutcome", 459 histograms.ExpectUniqueSample("Doodle.ConfigDownloadOutcome",
426 5, // OUTCOME_DOWNLOAD_ERROR 460 5, // OUTCOME_DOWNLOAD_ERROR
427 1); 461 1);
428 histograms.ExpectTotalCount("Doodle.ConfigDownloadTime", 0); 462 histograms.ExpectTotalCount("Doodle.ConfigDownloadTime", 0);
429 } 463 }
430 464
465 TEST_F(DoodleServiceTest, RecordsMetricsForEarlyRefreshRequest) {
466 // Create a service with the default refresh interval.
467 RecreateService(/*min_refresh_interval=*/base::nullopt);
fhorschig 2017/03/27 15:45:05 nit: Can you please set some arbitrary value here?
Marc Treib 2017/03/27 16:02:22 Done.
468
469 // Load a doodle config as usual.
470 service()->Refresh();
471 DoodleConfig config = CreateConfig(DoodleType::SIMPLE);
472 fetcher()->ServeAllCallbacks(DoodleState::AVAILABLE,
473 base::TimeDelta::FromHours(1), config);
474 ASSERT_THAT(service()->config(), Eq(config));
475
476 base::HistogramTester histograms;
477
478 // Request a refresh before the min refresh interval has passed.
479 task_runner()->FastForwardBy(base::TimeDelta::FromMinutes(5));
480 service()->Refresh();
481
482 // This should not have resulted in a request.
483 ASSERT_THAT(fetcher()->num_pending_callbacks(), Eq(0u));
484
485 // The outcome should still have been recorded, but not the time - we only
486 // record that for successful downloads.
487 histograms.ExpectUniqueSample("Doodle.ConfigDownloadOutcome",
488 7, // OUTCOME_REFRESH_INTERVAL_NOT_PASSED
489 1);
490 histograms.ExpectTotalCount("Doodle.ConfigDownloadTime", 0);
491 }
492
431 TEST_F(DoodleServiceTest, DoesNotRecordMetricsAtStartup) { 493 TEST_F(DoodleServiceTest, DoesNotRecordMetricsAtStartup) {
432 // Creating the service should not emit any histogram samples. 494 // Creating the service should not emit any histogram samples.
433 base::HistogramTester histograms; 495 base::HistogramTester histograms;
434 RecreateService(); 496 RecreateServiceWithZeroRefreshInterval();
435 ASSERT_THAT(service()->config(), Eq(base::nullopt)); 497 ASSERT_THAT(service()->config(), Eq(base::nullopt));
436 histograms.ExpectTotalCount("Doodle.ConfigDownloadOutcome", 0); 498 histograms.ExpectTotalCount("Doodle.ConfigDownloadOutcome", 0);
437 histograms.ExpectTotalCount("Doodle.ConfigDownloadTime", 0); 499 histograms.ExpectTotalCount("Doodle.ConfigDownloadTime", 0);
438 } 500 }
439 501
440 TEST_F(DoodleServiceTest, DoesNotRecordMetricsAtStartupWithConfig) { 502 TEST_F(DoodleServiceTest, DoesNotRecordMetricsAtStartupWithConfig) {
441 // Load a doodle config as usual. 503 // Load a doodle config as usual.
442 service()->Refresh(); 504 service()->Refresh();
443 DoodleConfig config = CreateConfig(DoodleType::SIMPLE); 505 DoodleConfig config = CreateConfig(DoodleType::SIMPLE);
444 fetcher()->ServeAllCallbacks(DoodleState::AVAILABLE, 506 fetcher()->ServeAllCallbacks(DoodleState::AVAILABLE,
445 base::TimeDelta::FromHours(1), config); 507 base::TimeDelta::FromHours(1), config);
446 ASSERT_THAT(service()->config(), Eq(config)); 508 ASSERT_THAT(service()->config(), Eq(config));
447 509
448 // Recreating the service should not emit any histogram samples, even though 510 // Recreating the service should not emit any histogram samples, even though
449 // a config gets loaded. 511 // a config gets loaded.
450 base::HistogramTester histograms; 512 base::HistogramTester histograms;
451 RecreateService(); 513 RecreateServiceWithZeroRefreshInterval();
452 ASSERT_THAT(service()->config(), Eq(config)); 514 ASSERT_THAT(service()->config(), Eq(config));
453 histograms.ExpectTotalCount("Doodle.ConfigDownloadOutcome", 0); 515 histograms.ExpectTotalCount("Doodle.ConfigDownloadOutcome", 0);
454 histograms.ExpectTotalCount("Doodle.ConfigDownloadTime", 0); 516 histograms.ExpectTotalCount("Doodle.ConfigDownloadTime", 0);
455 } 517 }
456 518
457 TEST_F(DoodleServiceTest, DoesNotRecordMetricsWhenConfigExpires) { 519 TEST_F(DoodleServiceTest, DoesNotRecordMetricsWhenConfigExpires) {
458 // Load some doodle config. 520 // Load some doodle config.
459 service()->Refresh(); 521 service()->Refresh();
460 DoodleConfig config = CreateConfig(DoodleType::SIMPLE); 522 DoodleConfig config = CreateConfig(DoodleType::SIMPLE);
461 fetcher()->ServeAllCallbacks(DoodleState::AVAILABLE, 523 fetcher()->ServeAllCallbacks(DoodleState::AVAILABLE,
462 base::TimeDelta::FromHours(1), config); 524 base::TimeDelta::FromHours(1), config);
463 ASSERT_THAT(service()->config(), Eq(config)); 525 ASSERT_THAT(service()->config(), Eq(config));
464 526
465 base::HistogramTester histograms; 527 base::HistogramTester histograms;
466 528
467 // Fast-forward time so that the config expires. 529 // Fast-forward time so that the config expires.
468 task_runner()->FastForwardBy(base::TimeDelta::FromHours(1)); 530 task_runner()->FastForwardBy(base::TimeDelta::FromHours(1));
469 ASSERT_THAT(service()->config(), Eq(base::nullopt)); 531 ASSERT_THAT(service()->config(), Eq(base::nullopt));
470 532
471 // This should not have resulted in any metrics being emitted. 533 // This should not have resulted in any metrics being emitted.
472 histograms.ExpectTotalCount("Doodle.ConfigDownloadOutcome", 0); 534 histograms.ExpectTotalCount("Doodle.ConfigDownloadOutcome", 0);
473 histograms.ExpectTotalCount("Doodle.ConfigDownloadTime", 0); 535 histograms.ExpectTotalCount("Doodle.ConfigDownloadTime", 0);
474 } 536 }
475 537
476 } // namespace doodle 538 } // namespace doodle
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698