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

Side by Side Diff: content/browser/background_sync/background_sync_manager_unittest.cc

Issue 950343006: [BackgroundSync] Initial land of the BackgroundSyncManager (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address issues from PS15 Created 5 years, 9 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
(Empty)
1 // Copyright 2015 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 "content/browser/background_sync/background_sync_manager.h"
6
7 #include "base/files/scoped_temp_dir.h"
8 #include "base/logging.h"
9 #include "base/run_loop.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "content/browser/browser_thread_impl.h"
12 #include "content/browser/service_worker/service_worker_context_wrapper.h"
13 #include "content/browser/service_worker/service_worker_storage.h"
14 #include "content/public/test/test_browser_thread_bundle.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 namespace {
18 const char kOriginUrl[] = "https://example.com";
19 const int64 kServiceWorkerVersionId = 0;
20 const int64 kServiceWorkerId1 = 1;
21 const int64 kServiceWorkerId2 = 2;
22 }
23
24 namespace content {
25
26 // A BackgroundSyncManager that can simulate delaying and corrupting the
27 // backend. This class assumes (and verifies) that only one operation runs at a
28 // time.
29 class TestBackgroundSyncManager : public BackgroundSyncManager {
30 public:
31 explicit TestBackgroundSyncManager(
32 const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context)
33 : BackgroundSyncManager(service_worker_context) {}
34
35 void DoInit() { Init(); }
36
37 void StoreDataInBackendContinue(
38 int64 sw_registration_id,
39 const GURL& origin,
40 const std::string& key,
41 const std::string& data,
42 const ServiceWorkerStorage::StatusCallback& callback) {
43 BackgroundSyncManager::StoreDataInBackend(sw_registration_id, origin, key,
44 data, callback);
45 }
46
47 void GetDataFromBackendContinue(
48 const std::string& key,
49 const ServiceWorkerStorage::GetUserDataForAllRegistrationsCallback&
50 callback) {
51 BackgroundSyncManager::GetDataFromBackend(key, callback);
52 }
53
54 void Continue() {
55 continuation_.Run();
56 continuation_.Reset();
57 }
58
59 void set_corrupt_backend(bool corrupt_backend) {
60 corrupt_backend_ = corrupt_backend;
61 }
62 void set_delay_backend(bool delay_backend) { delay_backend_ = delay_backend; }
63
64 protected:
65 void StoreDataInBackend(
66 int64 sw_registration_id,
67 const GURL& origin,
68 const std::string& key,
69 const std::string& data,
70 const ServiceWorkerStorage::StatusCallback& callback) override {
71 EXPECT_TRUE(continuation_.is_null());
72 if (corrupt_backend_) {
73 base::MessageLoop::current()->PostTask(
74 FROM_HERE, base::Bind(callback, SERVICE_WORKER_ERROR_FAILED));
75 return;
76 }
77 continuation_ =
78 base::Bind(&TestBackgroundSyncManager::StoreDataInBackendContinue,
79 base::Unretained(this), sw_registration_id, origin, key,
80 data, callback);
81 if (delay_backend_)
82 return;
83
84 Continue();
85 }
86
87 void GetDataFromBackend(
88 const std::string& key,
89 const ServiceWorkerStorage::GetUserDataForAllRegistrationsCallback&
90 callback) override {
91 EXPECT_TRUE(continuation_.is_null());
92 if (corrupt_backend_) {
93 base::MessageLoop::current()->PostTask(
94 FROM_HERE,
95 base::Bind(callback, std::vector<std::pair<int64, std::string>>(),
96 SERVICE_WORKER_ERROR_FAILED));
97 return;
98 }
99 continuation_ =
100 base::Bind(&TestBackgroundSyncManager::GetDataFromBackendContinue,
101 base::Unretained(this), key, callback);
102 if (delay_backend_)
103 return;
104
105 Continue();
106 }
107
108 private:
109 bool corrupt_backend_ = false;
110 bool delay_backend_ = false;
111 base::Closure continuation_;
112 };
113
114 class BackgroundSyncManagerTest : public testing::Test {
115 public:
116 BackgroundSyncManagerTest()
117 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
118 service_worker_context_(new ServiceWorkerContextWrapper(NULL)),
119 origin_(kOriginUrl),
120 sync_reg_1_(BackgroundSyncManager::BackgroundSyncRegistration("foo")),
121 sync_reg_2_(BackgroundSyncManager::BackgroundSyncRegistration("bar")),
122 callback_error_(BackgroundSyncManager::ERROR_TYPE_OK),
123 callback_sw_status_code_(SERVICE_WORKER_OK) {}
124
125 void SetUp() override {
126 scoped_ptr<ServiceWorkerDatabaseTaskManager> database_task_manager(
127 new MockServiceWorkerDatabaseTaskManager(
128 base::ThreadTaskRunnerHandle::Get()));
129
130 service_worker_context_->InitInternal(
131 base::FilePath(), base::ThreadTaskRunnerHandle::Get(),
132 database_task_manager.Pass(), base::ThreadTaskRunnerHandle::Get(), NULL,
133 NULL);
134 context_ptr_ = service_worker_context_->context()->AsWeakPtr();
135
136 background_sync_manager_ =
137 BackgroundSyncManager::Create(service_worker_context_);
138
139 // Wait for storage to finish initializing before registering service
140 // workers.
141 base::RunLoop().RunUntilIdle();
142
143 RegisterServiceWorker(kServiceWorkerId1);
144 RegisterServiceWorker(kServiceWorkerId2);
145 }
146
147 void StatusAndRegistrationCallback(
148 bool* was_called,
149 BackgroundSyncManager::ErrorType error,
150 const BackgroundSyncManager::BackgroundSyncRegistration& registration) {
151 *was_called = true;
152 callback_error_ = error;
153 callback_registration_ = registration;
154 }
155
156 void StatusCallback(bool* was_called,
157 BackgroundSyncManager::ErrorType error) {
158 *was_called = true;
159 callback_error_ = error;
160 }
161
162 protected:
163 TestBackgroundSyncManager* UseTestBackgroundSyncManager() {
164 TestBackgroundSyncManager* manager =
165 new TestBackgroundSyncManager(service_worker_context_);
166 background_sync_manager_.reset(manager);
167 manager->DoInit();
168 return manager;
169 }
170
171 bool Register(const BackgroundSyncManager::BackgroundSyncRegistration&
172 sync_registration) {
173 return RegisterWithServiceWorkerId(kServiceWorkerId1, sync_registration);
174 }
175
176 bool RegisterWithServiceWorkerId(
177 int64 sw_registration_id,
178 const BackgroundSyncManager::BackgroundSyncRegistration&
179 sync_registration) {
180 bool was_called = false;
181 background_sync_manager_->Register(
182 origin_, sw_registration_id, sync_registration,
183 base::Bind(&BackgroundSyncManagerTest::StatusAndRegistrationCallback,
184 base::Unretained(this), &was_called));
185 base::RunLoop().RunUntilIdle();
186 EXPECT_TRUE(was_called);
187 return callback_error_ == BackgroundSyncManager::ERROR_TYPE_OK;
188 }
189
190 bool Unregister(const BackgroundSyncManager::BackgroundSyncRegistration&
191 sync_registration) {
192 return UnregisterWithServiceWorkerId(kServiceWorkerId1, sync_registration);
193 }
194
195 bool UnregisterWithServiceWorkerId(
196 int64 sw_registration_id,
197 const BackgroundSyncManager::BackgroundSyncRegistration&
198 sync_registration) {
199 bool was_called = false;
200 background_sync_manager_->Unregister(
201 origin_, sw_registration_id, sync_registration.name,
202 sync_registration.id,
203 base::Bind(&BackgroundSyncManagerTest::StatusCallback,
204 base::Unretained(this), &was_called));
205 base::RunLoop().RunUntilIdle();
206 EXPECT_TRUE(was_called);
207 return callback_error_ == BackgroundSyncManager::ERROR_TYPE_OK;
208 }
209
210 bool GetRegistration(const std::string& sync_registration_name) {
211 return GetRegistrationWithServiceWorkerId(kServiceWorkerId1,
212 sync_registration_name);
213 }
214
215 bool GetRegistrationWithServiceWorkerId(
216 int64 sw_registration_id,
217 const std::string& sync_registration_name) {
218 bool was_called = false;
219 background_sync_manager_->GetRegistration(
220 origin_, sw_registration_id, sync_registration_name,
221 base::Bind(&BackgroundSyncManagerTest::StatusAndRegistrationCallback,
222 base::Unretained(this), &was_called));
223 base::RunLoop().RunUntilIdle();
224 EXPECT_TRUE(was_called);
225
226 if (callback_error_ == BackgroundSyncManager::ERROR_TYPE_OK)
227 EXPECT_TRUE(sync_registration_name == callback_registration_.name);
228
229 return callback_error_ == BackgroundSyncManager::ERROR_TYPE_OK;
230 }
231
232 void StorageRegistrationCallback(ServiceWorkerStatusCode result) {
233 callback_sw_status_code_ = result;
234 }
235
236 void RegisterServiceWorker(uint64 sw_registration_id) {
237 scoped_refptr<ServiceWorkerRegistration> live_registration =
238 new ServiceWorkerRegistration(origin_, sw_registration_id,
239 context_ptr_);
240
241 scoped_refptr<ServiceWorkerVersion> live_version = new ServiceWorkerVersion(
242 live_registration.get(), GURL(std::string(kOriginUrl) + "/script.js"),
243 kServiceWorkerVersionId, context_ptr_);
244 live_version->SetStatus(ServiceWorkerVersion::INSTALLED);
245 live_registration->SetWaitingVersion(live_version.get());
246
247 service_worker_context_->context()->storage()->StoreRegistration(
248 live_registration.get(), live_version.get(),
249 base::Bind(&BackgroundSyncManagerTest::StorageRegistrationCallback,
250 base::Unretained(this)));
251
252 base::RunLoop().RunUntilIdle();
253 EXPECT_EQ(SERVICE_WORKER_OK, callback_sw_status_code_);
254 }
255
256 TestBrowserThreadBundle browser_thread_bundle_;
257 scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_;
258 scoped_ptr<BackgroundSyncManager> background_sync_manager_;
259 base::WeakPtr<ServiceWorkerContextCore> context_ptr_;
260
261 const GURL origin_;
262 BackgroundSyncManager::BackgroundSyncRegistration sync_reg_1_;
263 BackgroundSyncManager::BackgroundSyncRegistration sync_reg_2_;
264
265 // Callback values.
266 BackgroundSyncManager::ErrorType callback_error_;
267 BackgroundSyncManager::BackgroundSyncRegistration callback_registration_;
268 ServiceWorkerStatusCode callback_sw_status_code_;
269 };
270
271 TEST_F(BackgroundSyncManagerTest, Register) {
272 EXPECT_TRUE(Register(sync_reg_1_));
273 }
274
275 TEST_F(BackgroundSyncManagerTest, RegistractionIntact) {
276 EXPECT_TRUE(Register(sync_reg_1_));
277 EXPECT_STREQ(sync_reg_1_.name.c_str(), callback_registration_.name.c_str());
278 EXPECT_NE(
279 BackgroundSyncManager::BackgroundSyncRegistration::kInvalidRegistrationId,
280 callback_registration_.id);
281 }
282
283 TEST_F(BackgroundSyncManagerTest, RegisterExistingKeepsId) {
284 EXPECT_TRUE(Register(sync_reg_1_));
285 BackgroundSyncManager::BackgroundSyncRegistration first_registration =
286 callback_registration_;
287 EXPECT_TRUE(Register(sync_reg_1_));
288 EXPECT_TRUE(callback_registration_.Equals(first_registration));
289 EXPECT_EQ(first_registration.id, callback_registration_.id);
290 }
291
292 TEST_F(BackgroundSyncManagerTest, RegisterOverwrites) {
293 EXPECT_TRUE(Register(sync_reg_1_));
294 BackgroundSyncManager::BackgroundSyncRegistration first_registration =
295 callback_registration_;
296
297 sync_reg_1_.min_period = 100;
298 EXPECT_TRUE(Register(sync_reg_1_));
299 EXPECT_LT(first_registration.id, callback_registration_.id);
300 EXPECT_FALSE(callback_registration_.Equals(first_registration));
301 }
302
303 TEST_F(BackgroundSyncManagerTest, RegisterBadBackend) {
304 TestBackgroundSyncManager* manager = UseTestBackgroundSyncManager();
305 manager->set_corrupt_backend(true);
306 EXPECT_FALSE(Register(sync_reg_1_));
307 manager->set_corrupt_backend(false);
308 EXPECT_FALSE(GetRegistration(sync_reg_1_.name));
309 }
310
311 TEST_F(BackgroundSyncManagerTest, RegisterOverwriteBadBackend) {
312 TestBackgroundSyncManager* manager = UseTestBackgroundSyncManager();
313 EXPECT_TRUE(Register(sync_reg_1_));
314 BackgroundSyncManager::BackgroundSyncRegistration first_registration =
315 callback_registration_;
316
317 sync_reg_1_.min_period = 100;
318
319 manager->set_corrupt_backend(true);
320 EXPECT_FALSE(Register(sync_reg_1_));
321 EXPECT_TRUE(GetRegistration(sync_reg_1_.name));
322 EXPECT_EQ(callback_registration_.id, first_registration.id);
323 EXPECT_TRUE(callback_registration_.Equals(first_registration));
324 }
325
326 TEST_F(BackgroundSyncManagerTest, TwoRegistrations) {
327 EXPECT_TRUE(Register(sync_reg_1_));
328 EXPECT_TRUE(Register(sync_reg_2_));
329 }
330
331 TEST_F(BackgroundSyncManagerTest, GetRegistrationNonExisting) {
332 EXPECT_FALSE(GetRegistration(sync_reg_1_.name));
333 }
334
335 TEST_F(BackgroundSyncManagerTest, GetRegistrationExisting) {
336 EXPECT_TRUE(Register(sync_reg_1_));
337 EXPECT_TRUE(GetRegistration(sync_reg_1_.name));
338 EXPECT_FALSE(GetRegistration(sync_reg_2_.name));
339 }
340
341 TEST_F(BackgroundSyncManagerTest, GetRegistrationBadBackend) {
342 TestBackgroundSyncManager* manager = UseTestBackgroundSyncManager();
343 EXPECT_TRUE(Register(sync_reg_1_));
344 manager->set_corrupt_backend(true);
345 EXPECT_TRUE(GetRegistration(sync_reg_1_.name));
346 EXPECT_FALSE(GetRegistration(sync_reg_2_.name));
347 manager->set_corrupt_backend(false);
348 EXPECT_TRUE(GetRegistration(sync_reg_1_.name));
349 EXPECT_FALSE(GetRegistration(sync_reg_2_.name));
350 }
351
352 TEST_F(BackgroundSyncManagerTest, Unregister) {
353 EXPECT_TRUE(Register(sync_reg_1_));
354 EXPECT_TRUE(Unregister(callback_registration_));
355 EXPECT_FALSE(GetRegistration(sync_reg_1_.name));
356 }
357
358 TEST_F(BackgroundSyncManagerTest, UnregisterWrongId) {
359 EXPECT_TRUE(Register(sync_reg_1_));
360 callback_registration_.id += 1;
361 EXPECT_FALSE(Unregister(callback_registration_));
362 }
363
364 TEST_F(BackgroundSyncManagerTest, Reregister) {
365 EXPECT_TRUE(Register(sync_reg_1_));
366 EXPECT_TRUE(Unregister(callback_registration_));
367 EXPECT_TRUE(Register(sync_reg_1_));
368 }
369
370 TEST_F(BackgroundSyncManagerTest, UnregisterNonExisting) {
371 EXPECT_FALSE(Unregister(sync_reg_1_));
372 EXPECT_EQ(BackgroundSyncManager::ERROR_TYPE_NOT_FOUND, callback_error_);
373 }
374
375 TEST_F(BackgroundSyncManagerTest, UnregisterSecond) {
376 EXPECT_TRUE(Register(sync_reg_1_));
377 EXPECT_TRUE(Register(sync_reg_2_));
378 EXPECT_TRUE(Unregister(callback_registration_));
379 EXPECT_TRUE(GetRegistration(sync_reg_1_.name));
380 EXPECT_TRUE(Register(sync_reg_2_));
381 }
382
383 TEST_F(BackgroundSyncManagerTest, UnregisterBadBackend) {
384 TestBackgroundSyncManager* manager = UseTestBackgroundSyncManager();
385 sync_reg_1_.min_period += 1;
386 EXPECT_TRUE(Register(sync_reg_1_));
387 manager->set_corrupt_backend(true);
388 EXPECT_FALSE(Unregister(callback_registration_));
389 manager->set_corrupt_backend(false);
390 EXPECT_TRUE(GetRegistration(sync_reg_1_.name));
391 EXPECT_TRUE(callback_registration_.Equals(sync_reg_1_));
392 }
393
394 TEST_F(BackgroundSyncManagerTest, RegistrationIncreasesId) {
395 EXPECT_TRUE(Register(sync_reg_1_));
396 BackgroundSyncManager::BackgroundSyncRegistration registered_sync =
397 callback_registration_;
398 BackgroundSyncManager::BackgroundSyncRegistration::RegistrationId cur_id =
399 callback_registration_.id;
400
401 EXPECT_TRUE(GetRegistration(sync_reg_1_.name));
402 EXPECT_TRUE(Register(sync_reg_2_));
403 EXPECT_LT(cur_id, callback_registration_.id);
404 cur_id = callback_registration_.id;
405
406 EXPECT_TRUE(Unregister(registered_sync));
407 EXPECT_TRUE(Register(sync_reg_1_));
408 EXPECT_LT(cur_id, callback_registration_.id);
409 }
410
411 TEST_F(BackgroundSyncManagerTest, RebootRecovery) {
412 EXPECT_TRUE(Register(sync_reg_1_));
413
414 background_sync_manager_ =
415 BackgroundSyncManager::Create(service_worker_context_);
416
417 EXPECT_TRUE(GetRegistration(sync_reg_1_.name));
418 EXPECT_FALSE(GetRegistration(sync_reg_2_.name));
419 }
420
421 TEST_F(BackgroundSyncManagerTest, RebootRecoveryTwoServiceWorkers) {
422 EXPECT_TRUE(RegisterWithServiceWorkerId(kServiceWorkerId1, sync_reg_1_));
423 EXPECT_TRUE(RegisterWithServiceWorkerId(kServiceWorkerId2, sync_reg_2_));
424
425 background_sync_manager_ =
426 BackgroundSyncManager::Create(service_worker_context_);
427
428 EXPECT_TRUE(
429 GetRegistrationWithServiceWorkerId(kServiceWorkerId1, sync_reg_1_.name));
430 EXPECT_FALSE(
431 GetRegistrationWithServiceWorkerId(kServiceWorkerId1, sync_reg_2_.name));
432 EXPECT_FALSE(
433 GetRegistrationWithServiceWorkerId(kServiceWorkerId2, sync_reg_1_.name));
434 EXPECT_TRUE(
435 GetRegistrationWithServiceWorkerId(kServiceWorkerId2, sync_reg_2_.name));
436
437 EXPECT_TRUE(
438 GetRegistrationWithServiceWorkerId(kServiceWorkerId1, sync_reg_1_.name));
439 EXPECT_TRUE(
440 GetRegistrationWithServiceWorkerId(kServiceWorkerId2, sync_reg_2_.name));
441
442 EXPECT_TRUE(RegisterWithServiceWorkerId(kServiceWorkerId1, sync_reg_2_));
443 EXPECT_TRUE(RegisterWithServiceWorkerId(kServiceWorkerId2, sync_reg_1_));
444 }
445
446 TEST_F(BackgroundSyncManagerTest, InitWithCorruptBackend) {
447 TestBackgroundSyncManager* manager =
448 new TestBackgroundSyncManager(service_worker_context_);
449 background_sync_manager_.reset(manager);
450 manager->set_corrupt_backend(true);
451 manager->DoInit();
452
453 EXPECT_FALSE(Register(sync_reg_1_));
454 EXPECT_FALSE(GetRegistration(sync_reg_1_.name));
455 }
456
457 TEST_F(BackgroundSyncManagerTest, SequentialOperations) {
458 // Schedule Init and all of the operations on a delayed backend. Verify that
459 // the operations complete sequentially.
460 TestBackgroundSyncManager* manager =
461 new TestBackgroundSyncManager(service_worker_context_);
462 background_sync_manager_.reset(manager);
463 manager->set_delay_backend(true);
464 manager->DoInit();
465
466 const int64 kExpectedInitialId =
467 BackgroundSyncManager::BackgroundSyncRegistrations::kInitialId;
468
469 bool register_called = false;
470 bool unregister_called = false;
471 bool get_registration_called = false;
472 manager->Register(
473 origin_, kServiceWorkerId1, sync_reg_1_,
474 base::Bind(&BackgroundSyncManagerTest::StatusAndRegistrationCallback,
475 base::Unretained(this), &register_called));
476 manager->Unregister(origin_, kServiceWorkerId1, sync_reg_1_.name,
477 kExpectedInitialId,
478 base::Bind(&BackgroundSyncManagerTest::StatusCallback,
479 base::Unretained(this), &unregister_called));
480 manager->GetRegistration(
481 origin_, kServiceWorkerId1, sync_reg_1_.name,
482 base::Bind(&BackgroundSyncManagerTest::StatusAndRegistrationCallback,
483 base::Unretained(this), &get_registration_called));
484
485 base::RunLoop().RunUntilIdle();
486 // Init should be blocked while loading from the backend.
487 EXPECT_FALSE(register_called);
488 EXPECT_FALSE(unregister_called);
489 EXPECT_FALSE(get_registration_called);
490
491 manager->Continue();
492 base::RunLoop().RunUntilIdle();
493 // Register should be blocked while storing to the backend.
494 EXPECT_FALSE(register_called);
495 EXPECT_FALSE(unregister_called);
496 EXPECT_FALSE(get_registration_called);
497
498 manager->Continue();
499 base::RunLoop().RunUntilIdle();
500 EXPECT_TRUE(register_called);
501 EXPECT_EQ(kExpectedInitialId, callback_registration_.id);
502 EXPECT_EQ(BackgroundSyncManager::ERROR_TYPE_OK, callback_error_);
503 // Unregister should be blocked while storing to the backend.
504 EXPECT_FALSE(unregister_called);
505 EXPECT_FALSE(get_registration_called);
506
507 manager->Continue();
508 base::RunLoop().RunUntilIdle();
509 // Unregister should be done and since GetRegistration doesn't require the
510 // backend it should be done too.
511 EXPECT_EQ(BackgroundSyncManager::ERROR_TYPE_NOT_FOUND, callback_error_);
512 EXPECT_TRUE(unregister_called);
513 EXPECT_TRUE(get_registration_called);
514 }
515
516 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698