Blink roll 25b6bd3a7a131ffe68d809546ad1a20707915cdc:3a503f41ae42e5b79cfcd2ff10e65afde...
[chromium-blink-merge.git] / content / browser / service_worker / service_worker_database_unittest.cc
blob0e052f5ff20771838693c2a46183335ec0021e88
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
3 // found in the LICENSE file.
5 #include "content/browser/service_worker/service_worker_database.h"
7 #include <string>
9 #include "base/files/file_util.h"
10 #include "base/files/scoped_temp_dir.h"
11 #include "base/stl_util.h"
12 #include "content/browser/service_worker/service_worker_database.pb.h"
13 #include "content/common/service_worker/service_worker_types.h"
14 #include "testing/gtest/include/gtest/gtest.h"
16 namespace content {
18 namespace {
20 typedef ServiceWorkerDatabase::RegistrationData RegistrationData;
21 typedef ServiceWorkerDatabase::ResourceRecord Resource;
23 struct AvailableIds {
24 int64 reg_id;
25 int64 res_id;
26 int64 ver_id;
28 AvailableIds() : reg_id(-1), res_id(-1), ver_id(-1) {}
29 ~AvailableIds() {}
32 GURL URL(const GURL& origin, const std::string& path) {
33 EXPECT_TRUE(origin.is_valid());
34 EXPECT_EQ(origin, origin.GetOrigin());
35 GURL out(origin.spec() + path);
36 EXPECT_TRUE(out.is_valid());
37 return out;
40 Resource CreateResource(int64 resource_id, const GURL& url, uint64 size_bytes) {
41 EXPECT_TRUE(url.is_valid());
42 return Resource(resource_id, url, size_bytes);
45 ServiceWorkerDatabase* CreateDatabase(const base::FilePath& path) {
46 return new ServiceWorkerDatabase(path);
49 ServiceWorkerDatabase* CreateDatabaseInMemory() {
50 return new ServiceWorkerDatabase(base::FilePath());
53 void VerifyRegistrationData(const RegistrationData& expected,
54 const RegistrationData& actual) {
55 EXPECT_EQ(expected.registration_id, actual.registration_id);
56 EXPECT_EQ(expected.scope, actual.scope);
57 EXPECT_EQ(expected.script, actual.script);
58 EXPECT_EQ(expected.version_id, actual.version_id);
59 EXPECT_EQ(expected.is_active, actual.is_active);
60 EXPECT_EQ(expected.has_fetch_handler, actual.has_fetch_handler);
61 EXPECT_EQ(expected.last_update_check, actual.last_update_check);
62 EXPECT_EQ(expected.resources_total_size_bytes,
63 actual.resources_total_size_bytes);
66 void VerifyResourceRecords(const std::vector<Resource>& expected,
67 const std::vector<Resource>& actual) {
68 ASSERT_EQ(expected.size(), actual.size());
69 for (size_t i = 0; i < expected.size(); ++i) {
70 EXPECT_EQ(expected[i].resource_id, actual[i].resource_id);
71 EXPECT_EQ(expected[i].url, actual[i].url);
72 EXPECT_EQ(expected[i].size_bytes, actual[i].size_bytes);
76 } // namespace
78 TEST(ServiceWorkerDatabaseTest, OpenDatabase) {
79 base::ScopedTempDir database_dir;
80 ASSERT_TRUE(database_dir.CreateUniqueTempDir());
81 scoped_ptr<ServiceWorkerDatabase> database(
82 CreateDatabase(database_dir.path()));
84 // Should be false because the database does not exist at the path.
85 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
86 database->LazyOpen(false));
88 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->LazyOpen(true));
90 database.reset(CreateDatabase(database_dir.path()));
91 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->LazyOpen(false));
94 TEST(ServiceWorkerDatabaseTest, OpenDatabase_InMemory) {
95 scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
97 // Should be false because the database does not exist in memory.
98 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
99 database->LazyOpen(false));
101 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->LazyOpen(true));
102 database.reset(CreateDatabaseInMemory());
104 // Should be false because the database is not persistent.
105 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
106 database->LazyOpen(false));
109 TEST(ServiceWorkerDatabaseTest, DatabaseVersion) {
110 scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
111 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->LazyOpen(true));
113 // Opening a new database does not write anything, so its schema version
114 // should be 0.
115 int64 db_version = -1;
116 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
117 database->ReadDatabaseVersion(&db_version));
118 EXPECT_EQ(0u, db_version);
120 // First writing triggers database initialization and bumps the schema
121 // version.
122 std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
123 ServiceWorkerDatabase::RegistrationData deleted_version;
124 std::vector<int64> newly_purgeable_resources;
125 ServiceWorkerDatabase::RegistrationData data;
126 ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
127 database->WriteRegistration(
128 data, resources, &deleted_version, &newly_purgeable_resources));
130 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
131 database->ReadDatabaseVersion(&db_version));
132 EXPECT_LT(0, db_version);
135 TEST(ServiceWorkerDatabaseTest, GetNextAvailableIds) {
136 base::ScopedTempDir database_dir;
137 ASSERT_TRUE(database_dir.CreateUniqueTempDir());
138 scoped_ptr<ServiceWorkerDatabase> database(
139 CreateDatabase(database_dir.path()));
141 GURL origin("http://example.com");
143 // The database has never been used, so returns initial values.
144 AvailableIds ids;
145 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->GetNextAvailableIds(
146 &ids.reg_id, &ids.ver_id, &ids.res_id));
147 EXPECT_EQ(0, ids.reg_id);
148 EXPECT_EQ(0, ids.ver_id);
149 EXPECT_EQ(0, ids.res_id);
151 ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK, database->LazyOpen(true));
152 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->GetNextAvailableIds(
153 &ids.reg_id, &ids.ver_id, &ids.res_id));
154 EXPECT_EQ(0, ids.reg_id);
155 EXPECT_EQ(0, ids.ver_id);
156 EXPECT_EQ(0, ids.res_id);
158 // Writing a registration bumps the next available ids.
159 std::vector<Resource> resources;
160 RegistrationData data1;
161 ServiceWorkerDatabase::RegistrationData deleted_version;
162 std::vector<int64> newly_purgeable_resources;
163 data1.registration_id = 100;
164 data1.scope = URL(origin, "/foo");
165 data1.script = URL(origin, "/script1.js");
166 data1.version_id = 200;
167 ASSERT_EQ(
168 ServiceWorkerDatabase::STATUS_OK,
169 database->WriteRegistration(
170 data1, resources, &deleted_version, &newly_purgeable_resources));
172 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->GetNextAvailableIds(
173 &ids.reg_id, &ids.ver_id, &ids.res_id));
174 EXPECT_EQ(101, ids.reg_id);
175 EXPECT_EQ(201, ids.ver_id);
176 EXPECT_EQ(0, ids.res_id);
178 // Writing uncommitted resources bumps the next available id.
179 const int64 kUncommittedIds[] = {0, 1, 3, 5, 6, 10};
180 EXPECT_EQ(
181 ServiceWorkerDatabase::STATUS_OK,
182 database->WriteUncommittedResourceIds(std::set<int64>(
183 kUncommittedIds, kUncommittedIds + arraysize(kUncommittedIds))));
184 EXPECT_EQ(
185 ServiceWorkerDatabase::STATUS_OK,
186 database->GetNextAvailableIds(&ids.reg_id, &ids.ver_id, &ids.res_id));
187 EXPECT_EQ(101, ids.reg_id);
188 EXPECT_EQ(201, ids.ver_id);
189 EXPECT_EQ(11, ids.res_id);
191 // Writing purgeable resources bumps the next available id.
192 const int64 kPurgeableIds[] = {4, 12, 16, 17, 20};
193 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
194 database->WriteUncommittedResourceIds(std::set<int64>(
195 kPurgeableIds, kPurgeableIds + arraysize(kPurgeableIds))));
196 EXPECT_EQ(
197 ServiceWorkerDatabase::STATUS_OK,
198 database->GetNextAvailableIds(&ids.reg_id, &ids.ver_id, &ids.res_id));
199 EXPECT_EQ(101, ids.reg_id);
200 EXPECT_EQ(201, ids.ver_id);
201 EXPECT_EQ(21, ids.res_id);
203 // Writing a registration whose ids are lower than the stored ones should not
204 // bump the next available ids.
205 RegistrationData data2;
206 data2.registration_id = 10;
207 data2.scope = URL(origin, "/bar");
208 data2.script = URL(origin, "/script2.js");
209 data2.version_id = 20;
210 ASSERT_EQ(
211 ServiceWorkerDatabase::STATUS_OK,
212 database->WriteRegistration(
213 data2, resources, &deleted_version, &newly_purgeable_resources));
215 // Same with resources.
216 int64 kLowResourceId = 15;
217 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
218 database->WriteUncommittedResourceIds(
219 std::set<int64>(&kLowResourceId, &kLowResourceId + 1)));
221 // Close and reopen the database to verify the stored values.
222 database.reset(CreateDatabase(database_dir.path()));
224 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->GetNextAvailableIds(
225 &ids.reg_id, &ids.ver_id, &ids.res_id));
226 EXPECT_EQ(101, ids.reg_id);
227 EXPECT_EQ(201, ids.ver_id);
228 EXPECT_EQ(21, ids.res_id);
231 TEST(ServiceWorkerDatabaseTest, GetOriginsWithRegistrations) {
232 scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
234 std::set<GURL> origins;
235 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
236 database->GetOriginsWithRegistrations(&origins));
237 EXPECT_TRUE(origins.empty());
239 std::vector<Resource> resources;
240 ServiceWorkerDatabase::RegistrationData deleted_version;
241 std::vector<int64> newly_purgeable_resources;
243 GURL origin1("http://example.com");
244 RegistrationData data1;
245 data1.registration_id = 123;
246 data1.scope = URL(origin1, "/foo");
247 data1.script = URL(origin1, "/script1.js");
248 data1.version_id = 456;
249 ASSERT_EQ(
250 ServiceWorkerDatabase::STATUS_OK,
251 database->WriteRegistration(
252 data1, resources, &deleted_version, &newly_purgeable_resources));
254 GURL origin2("https://www.example.com");
255 RegistrationData data2;
256 data2.registration_id = 234;
257 data2.scope = URL(origin2, "/bar");
258 data2.script = URL(origin2, "/script2.js");
259 data2.version_id = 567;
260 ASSERT_EQ(
261 ServiceWorkerDatabase::STATUS_OK,
262 database->WriteRegistration(
263 data2, resources, &deleted_version, &newly_purgeable_resources));
265 GURL origin3("https://example.org");
266 RegistrationData data3;
267 data3.registration_id = 345;
268 data3.scope = URL(origin3, "/hoge");
269 data3.script = URL(origin3, "/script3.js");
270 data3.version_id = 678;
271 ASSERT_EQ(
272 ServiceWorkerDatabase::STATUS_OK,
273 database->WriteRegistration(
274 data3, resources, &deleted_version, &newly_purgeable_resources));
276 // |origin3| has two registrations.
277 RegistrationData data4;
278 data4.registration_id = 456;
279 data4.scope = URL(origin3, "/fuga");
280 data4.script = URL(origin3, "/script4.js");
281 data4.version_id = 789;
282 ASSERT_EQ(
283 ServiceWorkerDatabase::STATUS_OK,
284 database->WriteRegistration(
285 data4, resources, &deleted_version, &newly_purgeable_resources));
287 origins.clear();
288 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
289 database->GetOriginsWithRegistrations(&origins));
290 EXPECT_EQ(3U, origins.size());
291 EXPECT_TRUE(ContainsKey(origins, origin1));
292 EXPECT_TRUE(ContainsKey(origins, origin2));
293 EXPECT_TRUE(ContainsKey(origins, origin3));
295 // |origin3| has another registration, so should not remove it from the
296 // unique origin list.
297 ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
298 database->DeleteRegistration(data4.registration_id,
299 origin3,
300 &deleted_version,
301 &newly_purgeable_resources));
302 EXPECT_EQ(data4.registration_id, deleted_version.registration_id);
304 origins.clear();
305 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
306 database->GetOriginsWithRegistrations(&origins));
307 EXPECT_EQ(3U, origins.size());
308 EXPECT_TRUE(ContainsKey(origins, origin1));
309 EXPECT_TRUE(ContainsKey(origins, origin2));
310 EXPECT_TRUE(ContainsKey(origins, origin3));
312 // |origin3| should be removed from the unique origin list.
313 ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
314 database->DeleteRegistration(data3.registration_id,
315 origin3,
316 &deleted_version,
317 &newly_purgeable_resources));
318 EXPECT_EQ(data3.registration_id, deleted_version.registration_id);
320 origins.clear();
321 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
322 database->GetOriginsWithRegistrations(&origins));
323 EXPECT_EQ(2U, origins.size());
324 EXPECT_TRUE(ContainsKey(origins, origin1));
325 EXPECT_TRUE(ContainsKey(origins, origin2));
328 TEST(ServiceWorkerDatabaseTest, GetRegistrationsForOrigin) {
329 scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
331 GURL origin1("http://example.com");
332 GURL origin2("https://www.example.com");
333 GURL origin3("https://example.org");
335 std::vector<RegistrationData> registrations;
336 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
337 database->GetRegistrationsForOrigin(origin1, &registrations));
338 EXPECT_TRUE(registrations.empty());
340 std::vector<Resource> resources;
341 ServiceWorkerDatabase::RegistrationData deleted_version;
342 std::vector<int64> newly_purgeable_resources;
344 RegistrationData data1;
345 data1.registration_id = 100;
346 data1.scope = URL(origin1, "/foo");
347 data1.script = URL(origin1, "/script1.js");
348 data1.version_id = 1000;
349 ASSERT_EQ(
350 ServiceWorkerDatabase::STATUS_OK,
351 database->WriteRegistration(
352 data1, resources, &deleted_version, &newly_purgeable_resources));
354 RegistrationData data2;
355 data2.registration_id = 200;
356 data2.scope = URL(origin2, "/bar");
357 data2.script = URL(origin2, "/script2.js");
358 data2.version_id = 2000;
359 ASSERT_EQ(
360 ServiceWorkerDatabase::STATUS_OK,
361 database->WriteRegistration(
362 data2, resources, &deleted_version, &newly_purgeable_resources));
364 RegistrationData data3;
365 data3.registration_id = 300;
366 data3.scope = URL(origin3, "/hoge");
367 data3.script = URL(origin3, "/script3.js");
368 data3.version_id = 3000;
369 ASSERT_EQ(
370 ServiceWorkerDatabase::STATUS_OK,
371 database->WriteRegistration(
372 data3, resources, &deleted_version, &newly_purgeable_resources));
374 // |origin3| has two registrations.
375 RegistrationData data4;
376 data4.registration_id = 400;
377 data4.scope = URL(origin3, "/fuga");
378 data4.script = URL(origin3, "/script4.js");
379 data4.version_id = 4000;
380 ASSERT_EQ(
381 ServiceWorkerDatabase::STATUS_OK,
382 database->WriteRegistration(
383 data4, resources, &deleted_version, &newly_purgeable_resources));
385 registrations.clear();
386 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
387 database->GetRegistrationsForOrigin(origin3, &registrations));
388 EXPECT_EQ(2U, registrations.size());
389 VerifyRegistrationData(data3, registrations[0]);
390 VerifyRegistrationData(data4, registrations[1]);
393 TEST(ServiceWorkerDatabaseTest, GetAllRegistrations) {
394 scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
396 std::vector<RegistrationData> registrations;
397 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
398 database->GetAllRegistrations(&registrations));
399 EXPECT_TRUE(registrations.empty());
401 std::vector<Resource> resources;
402 ServiceWorkerDatabase::RegistrationData deleted_version;
403 std::vector<int64> newly_purgeable_resources;
405 GURL origin1("http://www1.example.com");
406 RegistrationData data1;
407 data1.registration_id = 100;
408 data1.scope = URL(origin1, "/foo");
409 data1.script = URL(origin1, "/script1.js");
410 data1.version_id = 1000;
411 ASSERT_EQ(
412 ServiceWorkerDatabase::STATUS_OK,
413 database->WriteRegistration(
414 data1, resources, &deleted_version, &newly_purgeable_resources));
416 GURL origin2("http://www2.example.com");
417 RegistrationData data2;
418 data2.registration_id = 200;
419 data2.scope = URL(origin2, "/bar");
420 data2.script = URL(origin2, "/script2.js");
421 data2.version_id = 2000;
422 ASSERT_EQ(
423 ServiceWorkerDatabase::STATUS_OK,
424 database->WriteRegistration(
425 data2, resources, &deleted_version, &newly_purgeable_resources));
427 GURL origin3("http://www3.example.com");
428 RegistrationData data3;
429 data3.registration_id = 300;
430 data3.scope = URL(origin3, "/hoge");
431 data3.script = URL(origin3, "/script3.js");
432 data3.version_id = 3000;
433 ASSERT_EQ(
434 ServiceWorkerDatabase::STATUS_OK,
435 database->WriteRegistration(
436 data3, resources, &deleted_version, &newly_purgeable_resources));
438 // |origin3| has two registrations.
439 RegistrationData data4;
440 data4.registration_id = 400;
441 data4.scope = URL(origin3, "/fuga");
442 data4.script = URL(origin3, "/script4.js");
443 data4.version_id = 4000;
444 ASSERT_EQ(
445 ServiceWorkerDatabase::STATUS_OK,
446 database->WriteRegistration(
447 data4, resources, &deleted_version, &newly_purgeable_resources));
449 registrations.clear();
450 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
451 database->GetAllRegistrations(&registrations));
452 EXPECT_EQ(4U, registrations.size());
453 VerifyRegistrationData(data1, registrations[0]);
454 VerifyRegistrationData(data2, registrations[1]);
455 VerifyRegistrationData(data3, registrations[2]);
456 VerifyRegistrationData(data4, registrations[3]);
459 TEST(ServiceWorkerDatabaseTest, Registration_Basic) {
460 scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
462 GURL origin("http://example.com");
463 RegistrationData data;
464 data.registration_id = 100;
465 data.scope = URL(origin, "/foo");
466 data.script = URL(origin, "/script.js");
467 data.version_id = 200;
468 data.resources_total_size_bytes = 10939 + 200;
470 std::vector<Resource> resources;
471 resources.push_back(CreateResource(1, URL(origin, "/resource1"), 10939));
472 resources.push_back(CreateResource(2, URL(origin, "/resource2"), 200));
474 // Write a resource to the uncommitted list to make sure that writing
475 // registration removes resource ids associated with the registration from
476 // the uncommitted list.
477 std::set<int64> uncommitted_ids;
478 uncommitted_ids.insert(resources[0].resource_id);
479 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
480 database->WriteUncommittedResourceIds(uncommitted_ids));
481 std::set<int64> uncommitted_ids_out;
482 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
483 database->GetUncommittedResourceIds(&uncommitted_ids_out));
484 EXPECT_EQ(uncommitted_ids, uncommitted_ids_out);
486 ServiceWorkerDatabase::RegistrationData deleted_version;
487 deleted_version.version_id = 222; // Dummy initial value
488 std::vector<int64> newly_purgeable_resources;
490 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
491 database->WriteRegistration(
492 data, resources, &deleted_version, &newly_purgeable_resources));
493 EXPECT_EQ(kInvalidServiceWorkerVersionId, deleted_version.version_id);
494 EXPECT_TRUE(newly_purgeable_resources.empty());
496 // Make sure that the registration and resource records are stored.
497 RegistrationData data_out;
498 std::vector<Resource> resources_out;
499 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
500 database->ReadRegistration(
501 data.registration_id, origin, &data_out, &resources_out));
502 VerifyRegistrationData(data, data_out);
503 VerifyResourceRecords(resources, resources_out);
505 // Make sure that the resource is removed from the uncommitted list.
506 uncommitted_ids_out.clear();
507 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
508 database->GetUncommittedResourceIds(&uncommitted_ids_out));
509 EXPECT_TRUE(uncommitted_ids_out.empty());
511 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
512 database->DeleteRegistration(data.registration_id,
513 origin,
514 &deleted_version,
515 &newly_purgeable_resources));
516 EXPECT_EQ(data.version_id, deleted_version.version_id);
517 ASSERT_EQ(resources.size(), newly_purgeable_resources.size());
518 for (size_t i = 0; i < resources.size(); ++i)
519 EXPECT_EQ(newly_purgeable_resources[i], resources[i].resource_id);
521 // Make sure that the registration and resource records are gone.
522 resources_out.clear();
523 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
524 database->ReadRegistration(
525 data.registration_id, origin, &data_out, &resources_out));
526 EXPECT_TRUE(resources_out.empty());
528 // Resources should be purgeable because these are no longer referred.
529 std::set<int64> purgeable_ids_out;
530 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
531 database->GetPurgeableResourceIds(&purgeable_ids_out));
532 EXPECT_EQ(2u, purgeable_ids_out.size());
533 EXPECT_TRUE(ContainsKey(purgeable_ids_out, resources[0].resource_id));
534 EXPECT_TRUE(ContainsKey(purgeable_ids_out, resources[1].resource_id));
537 TEST(ServiceWorkerDatabaseTest, DeleteNonExistentRegistration) {
538 scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
540 GURL origin("http://example.com");
541 RegistrationData data;
542 data.registration_id = 100;
543 data.scope = URL(origin, "/foo");
544 data.script = URL(origin, "/script.js");
545 data.version_id = 200;
546 data.resources_total_size_bytes = 19 + 29129;
548 std::vector<Resource> resources;
549 resources.push_back(CreateResource(1, URL(origin, "/resource1"), 19));
550 resources.push_back(CreateResource(2, URL(origin, "/resource2"), 29129));
552 const int64 kNonExistentRegistrationId = 999;
553 const int64 kArbitraryVersionId = 222; // Used as a dummy initial value
555 ServiceWorkerDatabase::RegistrationData deleted_version;
556 deleted_version.version_id = kArbitraryVersionId;
557 std::vector<int64> newly_purgeable_resources;
558 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
559 database->WriteRegistration(
560 data, resources, &deleted_version, &newly_purgeable_resources));
561 EXPECT_EQ(kInvalidServiceWorkerVersionId, deleted_version.version_id);
562 EXPECT_TRUE(newly_purgeable_resources.empty());
564 // Delete from an origin that has a registration.
565 deleted_version.version_id = kArbitraryVersionId;
566 newly_purgeable_resources.clear();
567 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
568 database->DeleteRegistration(kNonExistentRegistrationId,
569 origin,
570 &deleted_version,
571 &newly_purgeable_resources));
572 EXPECT_EQ(kInvalidServiceWorkerVersionId, deleted_version.version_id);
573 EXPECT_TRUE(newly_purgeable_resources.empty());
575 // Delete from an origin that has no registration.
576 deleted_version.version_id = kArbitraryVersionId;
577 newly_purgeable_resources.clear();
578 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
579 database->DeleteRegistration(kNonExistentRegistrationId,
580 GURL("http://example.net"),
581 &deleted_version,
582 &newly_purgeable_resources));
583 EXPECT_EQ(kInvalidServiceWorkerVersionId, deleted_version.version_id);
584 EXPECT_TRUE(newly_purgeable_resources.empty());
587 TEST(ServiceWorkerDatabaseTest, Registration_Overwrite) {
588 scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
590 GURL origin("http://example.com");
591 RegistrationData data;
592 data.registration_id = 100;
593 data.scope = URL(origin, "/foo");
594 data.script = URL(origin, "/script.js");
595 data.version_id = 200;
596 data.resources_total_size_bytes = 10 + 11;
598 std::vector<Resource> resources1;
599 resources1.push_back(CreateResource(1, URL(origin, "/resource1"), 10));
600 resources1.push_back(CreateResource(2, URL(origin, "/resource2"), 11));
602 ServiceWorkerDatabase::RegistrationData deleted_version;
603 deleted_version.version_id = 222; // Dummy inital value
604 std::vector<int64> newly_purgeable_resources;
606 EXPECT_EQ(
607 ServiceWorkerDatabase::STATUS_OK,
608 database->WriteRegistration(
609 data, resources1, &deleted_version, &newly_purgeable_resources));
610 EXPECT_EQ(kInvalidServiceWorkerVersionId, deleted_version.version_id);
611 EXPECT_TRUE(newly_purgeable_resources.empty());
613 // Make sure that the registration and resource records are stored.
614 RegistrationData data_out;
615 std::vector<Resource> resources_out;
616 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->ReadRegistration(
617 data.registration_id, origin, &data_out, &resources_out));
618 VerifyRegistrationData(data, data_out);
619 VerifyResourceRecords(resources1, resources_out);
621 // Update the registration.
622 RegistrationData updated_data = data;
623 updated_data.version_id = data.version_id + 1;
624 updated_data.resources_total_size_bytes = 12 + 13;
625 std::vector<Resource> resources2;
626 resources2.push_back(CreateResource(3, URL(origin, "/resource3"), 12));
627 resources2.push_back(CreateResource(4, URL(origin, "/resource4"), 13));
629 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
630 database->WriteRegistration(updated_data,
631 resources2,
632 &deleted_version,
633 &newly_purgeable_resources));
634 EXPECT_EQ(data.version_id, deleted_version.version_id);
635 ASSERT_EQ(resources1.size(), newly_purgeable_resources.size());
636 for (size_t i = 0; i < resources1.size(); ++i)
637 EXPECT_EQ(newly_purgeable_resources[i], resources1[i].resource_id);
639 // Make sure that |updated_data| is stored and resources referred from |data|
640 // is moved to the purgeable list.
641 resources_out.clear();
642 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->ReadRegistration(
643 updated_data.registration_id, origin, &data_out, &resources_out));
644 VerifyRegistrationData(updated_data, data_out);
645 VerifyResourceRecords(resources2, resources_out);
647 std::set<int64> purgeable_ids_out;
648 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
649 database->GetPurgeableResourceIds(&purgeable_ids_out));
650 EXPECT_EQ(2u, purgeable_ids_out.size());
651 EXPECT_TRUE(ContainsKey(purgeable_ids_out, resources1[0].resource_id));
652 EXPECT_TRUE(ContainsKey(purgeable_ids_out, resources1[1].resource_id));
655 TEST(ServiceWorkerDatabaseTest, Registration_Multiple) {
656 scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
657 GURL origin("http://example.com");
659 ServiceWorkerDatabase::RegistrationData deleted_version;
660 std::vector<int64> newly_purgeable_resources;
662 // Add registration1.
663 RegistrationData data1;
664 data1.registration_id = 100;
665 data1.scope = URL(origin, "/foo");
666 data1.script = URL(origin, "/script1.js");
667 data1.version_id = 200;
668 data1.resources_total_size_bytes = 1451 + 15234;
670 std::vector<Resource> resources1;
671 resources1.push_back(CreateResource(1, URL(origin, "/resource1"), 1451));
672 resources1.push_back(CreateResource(2, URL(origin, "/resource2"), 15234));
673 EXPECT_EQ(
674 ServiceWorkerDatabase::STATUS_OK,
675 database->WriteRegistration(
676 data1, resources1, &deleted_version, &newly_purgeable_resources));
678 // Add registration2.
679 RegistrationData data2;
680 data2.registration_id = 101;
681 data2.scope = URL(origin, "/bar");
682 data2.script = URL(origin, "/script2.js");
683 data2.version_id = 201;
684 data2.resources_total_size_bytes = 5 + 6;
686 std::vector<Resource> resources2;
687 resources2.push_back(CreateResource(3, URL(origin, "/resource3"), 5));
688 resources2.push_back(CreateResource(4, URL(origin, "/resource4"), 6));
689 EXPECT_EQ(
690 ServiceWorkerDatabase::STATUS_OK,
691 database->WriteRegistration(
692 data2, resources2, &deleted_version, &newly_purgeable_resources));
694 // Make sure that registration1 is stored.
695 RegistrationData data_out;
696 std::vector<Resource> resources_out;
697 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->ReadRegistration(
698 data1.registration_id, origin, &data_out, &resources_out));
699 VerifyRegistrationData(data1, data_out);
700 VerifyResourceRecords(resources1, resources_out);
702 // Make sure that registration2 is also stored.
703 resources_out.clear();
704 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->ReadRegistration(
705 data2.registration_id, origin, &data_out, &resources_out));
706 VerifyRegistrationData(data2, data_out);
707 VerifyResourceRecords(resources2, resources_out);
709 std::set<int64> purgeable_ids_out;
710 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
711 database->GetPurgeableResourceIds(&purgeable_ids_out));
712 EXPECT_TRUE(purgeable_ids_out.empty());
714 // Delete registration1.
715 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
716 database->DeleteRegistration(data1.registration_id,
717 origin,
718 &deleted_version,
719 &newly_purgeable_resources));
720 EXPECT_EQ(data1.registration_id, deleted_version.registration_id);
722 // Make sure that registration1 is gone.
723 resources_out.clear();
724 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
725 database->ReadRegistration(
726 data1.registration_id, origin, &data_out, &resources_out));
727 EXPECT_TRUE(resources_out.empty());
729 purgeable_ids_out.clear();
730 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
731 database->GetPurgeableResourceIds(&purgeable_ids_out));
732 EXPECT_EQ(2u, purgeable_ids_out.size());
733 EXPECT_TRUE(ContainsKey(purgeable_ids_out, resources1[0].resource_id));
734 EXPECT_TRUE(ContainsKey(purgeable_ids_out, resources1[1].resource_id));
736 // Make sure that registration2 is still alive.
737 resources_out.clear();
738 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->ReadRegistration(
739 data2.registration_id, origin, &data_out, &resources_out));
740 VerifyRegistrationData(data2, data_out);
741 VerifyResourceRecords(resources2, resources_out);
744 TEST(ServiceWorkerDatabaseTest, UpdateVersionToActive) {
745 scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
746 GURL origin("http://example.com");
748 ServiceWorkerDatabase::RegistrationData deleted_version;
749 std::vector<int64> newly_purgeable_resources;
751 // Should be false because a registration does not exist.
752 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
753 database->UpdateVersionToActive(0, origin));
755 // Add a registration.
756 RegistrationData data;
757 data.registration_id = 100;
758 data.scope = URL(origin, "/foo");
759 data.script = URL(origin, "/script.js");
760 data.version_id = 200;
761 data.is_active = false;
762 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
763 database->WriteRegistration(data,
764 std::vector<Resource>(),
765 &deleted_version,
766 &newly_purgeable_resources));
768 // Make sure that the registration is stored.
769 RegistrationData data_out;
770 std::vector<Resource> resources_out;
771 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
772 database->ReadRegistration(
773 data.registration_id, origin, &data_out, &resources_out));
774 VerifyRegistrationData(data, data_out);
775 EXPECT_TRUE(resources_out.empty());
777 // Activate the registration.
778 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
779 database->UpdateVersionToActive(data.registration_id, origin));
781 // Make sure that the registration is activated.
782 resources_out.clear();
783 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
784 database->ReadRegistration(
785 data.registration_id, origin, &data_out, &resources_out));
786 RegistrationData expected_data = data;
787 expected_data.is_active = true;
788 VerifyRegistrationData(expected_data, data_out);
789 EXPECT_TRUE(resources_out.empty());
791 // Delete the registration.
792 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
793 database->DeleteRegistration(data.registration_id,
794 origin,
795 &deleted_version,
796 &newly_purgeable_resources));
797 EXPECT_EQ(data.registration_id, deleted_version.registration_id);
799 // Should be false because the registration is gone.
800 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
801 database->UpdateVersionToActive(data.registration_id, origin));
804 TEST(ServiceWorkerDatabaseTest, UpdateLastCheckTime) {
805 scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
806 GURL origin("http://example.com");
807 ServiceWorkerDatabase::RegistrationData deleted_version;
808 std::vector<int64> newly_purgeable_resources;
810 // Should be false because a registration does not exist.
811 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
812 database->UpdateLastCheckTime(0, origin, base::Time::Now()));
814 // Add a registration.
815 RegistrationData data;
816 data.registration_id = 100;
817 data.scope = URL(origin, "/foo");
818 data.script = URL(origin, "/script.js");
819 data.version_id = 200;
820 data.last_update_check = base::Time::Now();
821 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
822 database->WriteRegistration(data,
823 std::vector<Resource>(),
824 &deleted_version,
825 &newly_purgeable_resources));
827 // Make sure that the registration is stored.
828 RegistrationData data_out;
829 std::vector<Resource> resources_out;
830 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
831 database->ReadRegistration(
832 data.registration_id, origin, &data_out, &resources_out));
833 VerifyRegistrationData(data, data_out);
834 EXPECT_TRUE(resources_out.empty());
836 // Update the last check time.
837 base::Time updated_time = base::Time::Now();
838 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
839 database->UpdateLastCheckTime(
840 data.registration_id, origin, updated_time));
842 // Make sure that the registration is updated.
843 resources_out.clear();
844 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
845 database->ReadRegistration(
846 data.registration_id, origin, &data_out, &resources_out));
847 RegistrationData expected_data = data;
848 expected_data.last_update_check = updated_time;
849 VerifyRegistrationData(expected_data, data_out);
850 EXPECT_TRUE(resources_out.empty());
852 // Delete the registration.
853 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
854 database->DeleteRegistration(data.registration_id,
855 origin,
856 &deleted_version,
857 &newly_purgeable_resources));
858 EXPECT_EQ(data.registration_id, deleted_version.registration_id);
860 // Should be false because the registration is gone.
861 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
862 database->UpdateLastCheckTime(
863 data.registration_id, origin, base::Time::Now()));
866 TEST(ServiceWorkerDatabaseTest, UncommittedResourceIds) {
867 scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
869 // Write {1, 2, 3}.
870 std::set<int64> ids1;
871 ids1.insert(1);
872 ids1.insert(2);
873 ids1.insert(3);
874 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
875 database->WriteUncommittedResourceIds(ids1));
877 std::set<int64> ids_out;
878 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
879 database->GetUncommittedResourceIds(&ids_out));
880 EXPECT_EQ(ids1, ids_out);
882 // Write {2, 4}.
883 std::set<int64> ids2;
884 ids2.insert(2);
885 ids2.insert(4);
886 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
887 database->WriteUncommittedResourceIds(ids2));
889 ids_out.clear();
890 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
891 database->GetUncommittedResourceIds(&ids_out));
892 std::set<int64> expected = base::STLSetUnion<std::set<int64> >(ids1, ids2);
893 EXPECT_EQ(expected, ids_out);
895 // Delete {2, 3}.
896 std::set<int64> ids3;
897 ids3.insert(2);
898 ids3.insert(3);
899 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
900 database->ClearUncommittedResourceIds(ids3));
902 ids_out.clear();
903 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
904 database->GetUncommittedResourceIds(&ids_out));
905 expected = base::STLSetDifference<std::set<int64> >(expected, ids3);
906 EXPECT_EQ(expected, ids_out);
909 TEST(ServiceWorkerDatabaseTest, PurgeableResourceIds) {
910 scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
912 // Write {1, 2, 3}.
913 std::set<int64> ids1;
914 ids1.insert(1);
915 ids1.insert(2);
916 ids1.insert(3);
917 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
918 database->WritePurgeableResourceIds(ids1));
920 std::set<int64> ids_out;
921 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
922 database->GetPurgeableResourceIds(&ids_out));
923 EXPECT_EQ(ids1, ids_out);
925 // Write {2, 4}.
926 std::set<int64> ids2;
927 ids2.insert(2);
928 ids2.insert(4);
929 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
930 database->WritePurgeableResourceIds(ids2));
932 ids_out.clear();
933 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
934 database->GetPurgeableResourceIds(&ids_out));
935 std::set<int64> expected = base::STLSetUnion<std::set<int64> >(ids1, ids2);
936 EXPECT_EQ(expected, ids_out);
938 // Delete {2, 3}.
939 std::set<int64> ids3;
940 ids3.insert(2);
941 ids3.insert(3);
942 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
943 database->ClearPurgeableResourceIds(ids3));
945 ids_out.clear();
946 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
947 database->GetPurgeableResourceIds(&ids_out));
948 expected = base::STLSetDifference<std::set<int64> >(expected, ids3);
949 EXPECT_EQ(expected, ids_out);
952 TEST(ServiceWorkerDatabaseTest, DeleteAllDataForOrigin) {
953 scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
954 ServiceWorkerDatabase::RegistrationData deleted_version;
955 std::vector<int64> newly_purgeable_resources;
957 // Data associated with |origin1| will be removed.
958 GURL origin1("http://example.com");
959 GURL origin2("http://example.org");
961 // |origin1| has two registrations.
962 RegistrationData data1;
963 data1.registration_id = 10;
964 data1.scope = URL(origin1, "/foo");
965 data1.script = URL(origin1, "/script1.js");
966 data1.version_id = 100;
967 data1.resources_total_size_bytes = 2013 + 512;
969 std::vector<Resource> resources1;
970 resources1.push_back(CreateResource(1, URL(origin1, "/resource1"), 2013));
971 resources1.push_back(CreateResource(2, URL(origin1, "/resource2"), 512));
972 ASSERT_EQ(
973 ServiceWorkerDatabase::STATUS_OK,
974 database->WriteRegistration(
975 data1, resources1, &deleted_version, &newly_purgeable_resources));
977 RegistrationData data2;
978 data2.registration_id = 11;
979 data2.scope = URL(origin1, "/bar");
980 data2.script = URL(origin1, "/script2.js");
981 data2.version_id = 101;
982 data2.resources_total_size_bytes = 4 + 5;
984 std::vector<Resource> resources2;
985 resources2.push_back(CreateResource(3, URL(origin1, "/resource3"), 4));
986 resources2.push_back(CreateResource(4, URL(origin1, "/resource4"), 5));
987 ASSERT_EQ(
988 ServiceWorkerDatabase::STATUS_OK,
989 database->WriteRegistration(
990 data2, resources2, &deleted_version, &newly_purgeable_resources));
992 // |origin2| has one registration.
993 RegistrationData data3;
994 data3.registration_id = 12;
995 data3.scope = URL(origin2, "/hoge");
996 data3.script = URL(origin2, "/script3.js");
997 data3.version_id = 102;
998 data3.resources_total_size_bytes = 6 + 7;
1000 std::vector<Resource> resources3;
1001 resources3.push_back(CreateResource(5, URL(origin2, "/resource5"), 6));
1002 resources3.push_back(CreateResource(6, URL(origin2, "/resource6"), 7));
1003 ASSERT_EQ(
1004 ServiceWorkerDatabase::STATUS_OK,
1005 database->WriteRegistration(
1006 data3, resources3, &deleted_version, &newly_purgeable_resources));
1008 std::set<GURL> origins_to_delete;
1009 origins_to_delete.insert(origin1);
1010 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1011 database->DeleteAllDataForOrigins(origins_to_delete,
1012 &newly_purgeable_resources));
1014 // |origin1| should be removed from the unique origin list.
1015 std::set<GURL> unique_origins;
1016 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1017 database->GetOriginsWithRegistrations(&unique_origins));
1018 EXPECT_EQ(1u, unique_origins.size());
1019 EXPECT_TRUE(ContainsKey(unique_origins, origin2));
1021 // The registrations for |origin1| should be removed.
1022 std::vector<RegistrationData> registrations;
1023 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1024 database->GetRegistrationsForOrigin(origin1, &registrations));
1025 EXPECT_TRUE(registrations.empty());
1027 // The registration for |origin2| should not be removed.
1028 RegistrationData data_out;
1029 std::vector<Resource> resources_out;
1030 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->ReadRegistration(
1031 data3.registration_id, origin2, &data_out, &resources_out));
1032 VerifyRegistrationData(data3, data_out);
1033 VerifyResourceRecords(resources3, resources_out);
1035 // The resources associated with |origin1| should be purgeable.
1036 std::set<int64> purgeable_ids_out;
1037 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1038 database->GetPurgeableResourceIds(&purgeable_ids_out));
1039 EXPECT_EQ(4u, purgeable_ids_out.size());
1040 EXPECT_TRUE(ContainsKey(purgeable_ids_out, 1));
1041 EXPECT_TRUE(ContainsKey(purgeable_ids_out, 2));
1042 EXPECT_TRUE(ContainsKey(purgeable_ids_out, 3));
1043 EXPECT_TRUE(ContainsKey(purgeable_ids_out, 4));
1046 TEST(ServiceWorkerDatabaseTest, DestroyDatabase) {
1047 base::ScopedTempDir database_dir;
1048 ASSERT_TRUE(database_dir.CreateUniqueTempDir());
1049 scoped_ptr<ServiceWorkerDatabase> database(
1050 CreateDatabase(database_dir.path()));
1052 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->LazyOpen(true));
1053 ASSERT_TRUE(base::DirectoryExists(database_dir.path()));
1055 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->DestroyDatabase());
1056 ASSERT_FALSE(base::DirectoryExists(database_dir.path()));
1059 } // namespace content