[Storage] Blob Storage Refactoring pt 1:
[chromium-blink-merge.git] / content / browser / service_worker / service_worker_database_unittest.cc
blobe67a5ba916278e79dd2345577f59190bb06ab4f8
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 "base/strings/string_number_conversions.h"
13 #include "content/browser/service_worker/service_worker_database.pb.h"
14 #include "content/common/service_worker/service_worker_types.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
18 namespace content {
20 namespace {
22 typedef ServiceWorkerDatabase::RegistrationData RegistrationData;
23 typedef ServiceWorkerDatabase::ResourceRecord Resource;
25 struct AvailableIds {
26 int64 reg_id;
27 int64 res_id;
28 int64 ver_id;
30 AvailableIds() : reg_id(-1), res_id(-1), ver_id(-1) {}
31 ~AvailableIds() {}
34 GURL URL(const GURL& origin, const std::string& path) {
35 EXPECT_TRUE(origin.is_valid());
36 EXPECT_EQ(origin, origin.GetOrigin());
37 GURL out(origin.spec() + path);
38 EXPECT_TRUE(out.is_valid());
39 return out;
42 Resource CreateResource(int64 resource_id, const GURL& url, uint64 size_bytes) {
43 EXPECT_TRUE(url.is_valid());
44 return Resource(resource_id, url, size_bytes);
47 ServiceWorkerDatabase* CreateDatabase(const base::FilePath& path) {
48 return new ServiceWorkerDatabase(path);
51 ServiceWorkerDatabase* CreateDatabaseInMemory() {
52 return new ServiceWorkerDatabase(base::FilePath());
55 void VerifyRegistrationData(const RegistrationData& expected,
56 const RegistrationData& actual) {
57 EXPECT_EQ(expected.registration_id, actual.registration_id);
58 EXPECT_EQ(expected.scope, actual.scope);
59 EXPECT_EQ(expected.script, actual.script);
60 EXPECT_EQ(expected.version_id, actual.version_id);
61 EXPECT_EQ(expected.is_active, actual.is_active);
62 EXPECT_EQ(expected.has_fetch_handler, actual.has_fetch_handler);
63 EXPECT_EQ(expected.last_update_check, actual.last_update_check);
64 EXPECT_EQ(expected.resources_total_size_bytes,
65 actual.resources_total_size_bytes);
68 void VerifyResourceRecords(const std::vector<Resource>& expected,
69 const std::vector<Resource>& actual) {
70 ASSERT_EQ(expected.size(), actual.size());
71 for (size_t i = 0; i < expected.size(); ++i) {
72 EXPECT_EQ(expected[i].resource_id, actual[i].resource_id);
73 EXPECT_EQ(expected[i].url, actual[i].url);
74 EXPECT_EQ(expected[i].size_bytes, actual[i].size_bytes);
78 } // namespace
80 TEST(ServiceWorkerDatabaseTest, OpenDatabase) {
81 base::ScopedTempDir database_dir;
82 ASSERT_TRUE(database_dir.CreateUniqueTempDir());
83 scoped_ptr<ServiceWorkerDatabase> database(
84 CreateDatabase(database_dir.path()));
86 // Should be false because the database does not exist at the path.
87 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
88 database->LazyOpen(false));
90 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->LazyOpen(true));
92 database.reset(CreateDatabase(database_dir.path()));
93 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->LazyOpen(false));
96 TEST(ServiceWorkerDatabaseTest, OpenDatabase_InMemory) {
97 scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
99 // Should be false because the database does not exist in memory.
100 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
101 database->LazyOpen(false));
103 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->LazyOpen(true));
104 database.reset(CreateDatabaseInMemory());
106 // Should be false because the database is not persistent.
107 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
108 database->LazyOpen(false));
111 TEST(ServiceWorkerDatabaseTest, DatabaseVersion) {
112 scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
113 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->LazyOpen(true));
115 // Opening a new database does not write anything, so its schema version
116 // should be 0.
117 int64 db_version = -1;
118 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
119 database->ReadDatabaseVersion(&db_version));
120 EXPECT_EQ(0u, db_version);
122 // First writing triggers database initialization and bumps the schema
123 // version.
124 std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
125 ServiceWorkerDatabase::RegistrationData deleted_version;
126 std::vector<int64> newly_purgeable_resources;
127 ServiceWorkerDatabase::RegistrationData data;
128 ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
129 database->WriteRegistration(
130 data, resources, &deleted_version, &newly_purgeable_resources));
132 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
133 database->ReadDatabaseVersion(&db_version));
134 EXPECT_LT(0, db_version);
137 TEST(ServiceWorkerDatabaseTest, UpgradeSchemaToVersion2) {
138 base::ScopedTempDir database_dir;
139 ASSERT_TRUE(database_dir.CreateUniqueTempDir());
140 scoped_ptr<ServiceWorkerDatabase> database(
141 CreateDatabase(database_dir.path()));
143 GURL origin("http://example.com");
145 // Add a registration to the database.
146 std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
147 ServiceWorkerDatabase::RegistrationData deleted_version;
148 std::vector<int64> newly_purgeable_resources;
149 ServiceWorkerDatabase::RegistrationData data;
150 data.registration_id = 100;
151 data.scope = URL(origin, "/foo");
152 data.script = URL(origin, "/script1.js");
153 data.version_id = 200;
154 ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
155 database->WriteRegistration(data, resources, &deleted_version,
156 &newly_purgeable_resources));
158 // Sanity check on current version.
159 int64 db_version = -1;
160 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
161 database->ReadDatabaseVersion(&db_version));
162 EXPECT_LE(2, db_version);
164 // Now delete the data that will be created in an upgrade to schema version 2,
165 // and reset the schema version to 1.
166 leveldb::WriteBatch batch;
167 batch.Delete("REGID_TO_ORIGIN:" + base::Int64ToString(data.registration_id));
168 batch.Put("INITDATA_DB_VERSION", base::Int64ToString(1));
169 ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK, database->WriteBatch(&batch));
171 // Make sure correct data got deleted.
172 GURL origin_out;
173 EXPECT_EQ(
174 ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
175 database->ReadRegistrationOrigin(data.registration_id, &origin_out));
177 // Close and reopen the database to verify the schema got updated.
178 database.reset(CreateDatabase(database_dir.path()));
179 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->LazyOpen(true));
181 // Verify version number.
182 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
183 database->ReadDatabaseVersion(&db_version));
184 EXPECT_LE(2, db_version);
186 // And check that looking up origin for registration works.
187 EXPECT_EQ(
188 ServiceWorkerDatabase::STATUS_OK,
189 database->ReadRegistrationOrigin(data.registration_id, &origin_out));
190 EXPECT_EQ(origin, origin_out);
193 TEST(ServiceWorkerDatabaseTest, GetNextAvailableIds) {
194 base::ScopedTempDir database_dir;
195 ASSERT_TRUE(database_dir.CreateUniqueTempDir());
196 scoped_ptr<ServiceWorkerDatabase> database(
197 CreateDatabase(database_dir.path()));
199 GURL origin("http://example.com");
201 // The database has never been used, so returns initial values.
202 AvailableIds ids;
203 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->GetNextAvailableIds(
204 &ids.reg_id, &ids.ver_id, &ids.res_id));
205 EXPECT_EQ(0, ids.reg_id);
206 EXPECT_EQ(0, ids.ver_id);
207 EXPECT_EQ(0, ids.res_id);
209 ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK, database->LazyOpen(true));
210 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->GetNextAvailableIds(
211 &ids.reg_id, &ids.ver_id, &ids.res_id));
212 EXPECT_EQ(0, ids.reg_id);
213 EXPECT_EQ(0, ids.ver_id);
214 EXPECT_EQ(0, ids.res_id);
216 // Writing a registration bumps the next available ids.
217 std::vector<Resource> resources;
218 RegistrationData data1;
219 ServiceWorkerDatabase::RegistrationData deleted_version;
220 std::vector<int64> newly_purgeable_resources;
221 data1.registration_id = 100;
222 data1.scope = URL(origin, "/foo");
223 data1.script = URL(origin, "/script1.js");
224 data1.version_id = 200;
225 ASSERT_EQ(
226 ServiceWorkerDatabase::STATUS_OK,
227 database->WriteRegistration(
228 data1, resources, &deleted_version, &newly_purgeable_resources));
230 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->GetNextAvailableIds(
231 &ids.reg_id, &ids.ver_id, &ids.res_id));
232 EXPECT_EQ(101, ids.reg_id);
233 EXPECT_EQ(201, ids.ver_id);
234 EXPECT_EQ(0, ids.res_id);
236 // Writing uncommitted resources bumps the next available id.
237 const int64 kUncommittedIds[] = {0, 1, 3, 5, 6, 10};
238 EXPECT_EQ(
239 ServiceWorkerDatabase::STATUS_OK,
240 database->WriteUncommittedResourceIds(std::set<int64>(
241 kUncommittedIds, kUncommittedIds + arraysize(kUncommittedIds))));
242 EXPECT_EQ(
243 ServiceWorkerDatabase::STATUS_OK,
244 database->GetNextAvailableIds(&ids.reg_id, &ids.ver_id, &ids.res_id));
245 EXPECT_EQ(101, ids.reg_id);
246 EXPECT_EQ(201, ids.ver_id);
247 EXPECT_EQ(11, ids.res_id);
249 // Writing purgeable resources bumps the next available id.
250 const int64 kPurgeableIds[] = {4, 12, 16, 17, 20};
251 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
252 database->WriteUncommittedResourceIds(std::set<int64>(
253 kPurgeableIds, kPurgeableIds + arraysize(kPurgeableIds))));
254 EXPECT_EQ(
255 ServiceWorkerDatabase::STATUS_OK,
256 database->GetNextAvailableIds(&ids.reg_id, &ids.ver_id, &ids.res_id));
257 EXPECT_EQ(101, ids.reg_id);
258 EXPECT_EQ(201, ids.ver_id);
259 EXPECT_EQ(21, ids.res_id);
261 // Writing a registration whose ids are lower than the stored ones should not
262 // bump the next available ids.
263 RegistrationData data2;
264 data2.registration_id = 10;
265 data2.scope = URL(origin, "/bar");
266 data2.script = URL(origin, "/script2.js");
267 data2.version_id = 20;
268 ASSERT_EQ(
269 ServiceWorkerDatabase::STATUS_OK,
270 database->WriteRegistration(
271 data2, resources, &deleted_version, &newly_purgeable_resources));
273 // Same with resources.
274 int64 kLowResourceId = 15;
275 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
276 database->WriteUncommittedResourceIds(
277 std::set<int64>(&kLowResourceId, &kLowResourceId + 1)));
279 // Close and reopen the database to verify the stored values.
280 database.reset(CreateDatabase(database_dir.path()));
282 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->GetNextAvailableIds(
283 &ids.reg_id, &ids.ver_id, &ids.res_id));
284 EXPECT_EQ(101, ids.reg_id);
285 EXPECT_EQ(201, ids.ver_id);
286 EXPECT_EQ(21, ids.res_id);
289 TEST(ServiceWorkerDatabaseTest, GetOriginsWithRegistrations) {
290 scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
292 std::set<GURL> origins;
293 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
294 database->GetOriginsWithRegistrations(&origins));
295 EXPECT_TRUE(origins.empty());
297 std::vector<Resource> resources;
298 ServiceWorkerDatabase::RegistrationData deleted_version;
299 std::vector<int64> newly_purgeable_resources;
301 GURL origin1("http://example.com");
302 RegistrationData data1;
303 data1.registration_id = 123;
304 data1.scope = URL(origin1, "/foo");
305 data1.script = URL(origin1, "/script1.js");
306 data1.version_id = 456;
307 ASSERT_EQ(
308 ServiceWorkerDatabase::STATUS_OK,
309 database->WriteRegistration(
310 data1, resources, &deleted_version, &newly_purgeable_resources));
312 GURL origin2("https://www.example.com");
313 RegistrationData data2;
314 data2.registration_id = 234;
315 data2.scope = URL(origin2, "/bar");
316 data2.script = URL(origin2, "/script2.js");
317 data2.version_id = 567;
318 ASSERT_EQ(
319 ServiceWorkerDatabase::STATUS_OK,
320 database->WriteRegistration(
321 data2, resources, &deleted_version, &newly_purgeable_resources));
323 GURL origin3("https://example.org");
324 RegistrationData data3;
325 data3.registration_id = 345;
326 data3.scope = URL(origin3, "/hoge");
327 data3.script = URL(origin3, "/script3.js");
328 data3.version_id = 678;
329 ASSERT_EQ(
330 ServiceWorkerDatabase::STATUS_OK,
331 database->WriteRegistration(
332 data3, resources, &deleted_version, &newly_purgeable_resources));
334 // |origin3| has two registrations.
335 RegistrationData data4;
336 data4.registration_id = 456;
337 data4.scope = URL(origin3, "/fuga");
338 data4.script = URL(origin3, "/script4.js");
339 data4.version_id = 789;
340 ASSERT_EQ(
341 ServiceWorkerDatabase::STATUS_OK,
342 database->WriteRegistration(
343 data4, resources, &deleted_version, &newly_purgeable_resources));
345 origins.clear();
346 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
347 database->GetOriginsWithRegistrations(&origins));
348 EXPECT_EQ(3U, origins.size());
349 EXPECT_TRUE(ContainsKey(origins, origin1));
350 EXPECT_TRUE(ContainsKey(origins, origin2));
351 EXPECT_TRUE(ContainsKey(origins, origin3));
353 // |origin3| has another registration, so should not remove it from the
354 // unique origin list.
355 ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
356 database->DeleteRegistration(data4.registration_id,
357 origin3,
358 &deleted_version,
359 &newly_purgeable_resources));
360 EXPECT_EQ(data4.registration_id, deleted_version.registration_id);
362 origins.clear();
363 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
364 database->GetOriginsWithRegistrations(&origins));
365 EXPECT_EQ(3U, origins.size());
366 EXPECT_TRUE(ContainsKey(origins, origin1));
367 EXPECT_TRUE(ContainsKey(origins, origin2));
368 EXPECT_TRUE(ContainsKey(origins, origin3));
370 // |origin3| should be removed from the unique origin list.
371 ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
372 database->DeleteRegistration(data3.registration_id,
373 origin3,
374 &deleted_version,
375 &newly_purgeable_resources));
376 EXPECT_EQ(data3.registration_id, deleted_version.registration_id);
378 origins.clear();
379 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
380 database->GetOriginsWithRegistrations(&origins));
381 EXPECT_EQ(2U, origins.size());
382 EXPECT_TRUE(ContainsKey(origins, origin1));
383 EXPECT_TRUE(ContainsKey(origins, origin2));
386 TEST(ServiceWorkerDatabaseTest, GetRegistrationsForOrigin) {
387 scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
389 GURL origin1("http://example.com");
390 GURL origin2("https://www.example.com");
391 GURL origin3("https://example.org");
393 std::vector<RegistrationData> registrations;
394 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
395 database->GetRegistrationsForOrigin(origin1, &registrations));
396 EXPECT_TRUE(registrations.empty());
398 std::vector<Resource> resources;
399 ServiceWorkerDatabase::RegistrationData deleted_version;
400 std::vector<int64> newly_purgeable_resources;
402 RegistrationData data1;
403 data1.registration_id = 100;
404 data1.scope = URL(origin1, "/foo");
405 data1.script = URL(origin1, "/script1.js");
406 data1.version_id = 1000;
407 ASSERT_EQ(
408 ServiceWorkerDatabase::STATUS_OK,
409 database->WriteRegistration(
410 data1, resources, &deleted_version, &newly_purgeable_resources));
412 RegistrationData data2;
413 data2.registration_id = 200;
414 data2.scope = URL(origin2, "/bar");
415 data2.script = URL(origin2, "/script2.js");
416 data2.version_id = 2000;
417 ASSERT_EQ(
418 ServiceWorkerDatabase::STATUS_OK,
419 database->WriteRegistration(
420 data2, resources, &deleted_version, &newly_purgeable_resources));
422 RegistrationData data3;
423 data3.registration_id = 300;
424 data3.scope = URL(origin3, "/hoge");
425 data3.script = URL(origin3, "/script3.js");
426 data3.version_id = 3000;
427 ASSERT_EQ(
428 ServiceWorkerDatabase::STATUS_OK,
429 database->WriteRegistration(
430 data3, resources, &deleted_version, &newly_purgeable_resources));
432 // |origin3| has two registrations.
433 RegistrationData data4;
434 data4.registration_id = 400;
435 data4.scope = URL(origin3, "/fuga");
436 data4.script = URL(origin3, "/script4.js");
437 data4.version_id = 4000;
438 ASSERT_EQ(
439 ServiceWorkerDatabase::STATUS_OK,
440 database->WriteRegistration(
441 data4, resources, &deleted_version, &newly_purgeable_resources));
443 registrations.clear();
444 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
445 database->GetRegistrationsForOrigin(origin3, &registrations));
446 EXPECT_EQ(2U, registrations.size());
447 VerifyRegistrationData(data3, registrations[0]);
448 VerifyRegistrationData(data4, registrations[1]);
451 TEST(ServiceWorkerDatabaseTest, GetAllRegistrations) {
452 scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
454 std::vector<RegistrationData> registrations;
455 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
456 database->GetAllRegistrations(&registrations));
457 EXPECT_TRUE(registrations.empty());
459 std::vector<Resource> resources;
460 ServiceWorkerDatabase::RegistrationData deleted_version;
461 std::vector<int64> newly_purgeable_resources;
463 GURL origin1("http://www1.example.com");
464 RegistrationData data1;
465 data1.registration_id = 100;
466 data1.scope = URL(origin1, "/foo");
467 data1.script = URL(origin1, "/script1.js");
468 data1.version_id = 1000;
469 ASSERT_EQ(
470 ServiceWorkerDatabase::STATUS_OK,
471 database->WriteRegistration(
472 data1, resources, &deleted_version, &newly_purgeable_resources));
474 GURL origin2("http://www2.example.com");
475 RegistrationData data2;
476 data2.registration_id = 200;
477 data2.scope = URL(origin2, "/bar");
478 data2.script = URL(origin2, "/script2.js");
479 data2.version_id = 2000;
480 ASSERT_EQ(
481 ServiceWorkerDatabase::STATUS_OK,
482 database->WriteRegistration(
483 data2, resources, &deleted_version, &newly_purgeable_resources));
485 GURL origin3("http://www3.example.com");
486 RegistrationData data3;
487 data3.registration_id = 300;
488 data3.scope = URL(origin3, "/hoge");
489 data3.script = URL(origin3, "/script3.js");
490 data3.version_id = 3000;
491 ASSERT_EQ(
492 ServiceWorkerDatabase::STATUS_OK,
493 database->WriteRegistration(
494 data3, resources, &deleted_version, &newly_purgeable_resources));
496 // |origin3| has two registrations.
497 RegistrationData data4;
498 data4.registration_id = 400;
499 data4.scope = URL(origin3, "/fuga");
500 data4.script = URL(origin3, "/script4.js");
501 data4.version_id = 4000;
502 ASSERT_EQ(
503 ServiceWorkerDatabase::STATUS_OK,
504 database->WriteRegistration(
505 data4, resources, &deleted_version, &newly_purgeable_resources));
507 registrations.clear();
508 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
509 database->GetAllRegistrations(&registrations));
510 EXPECT_EQ(4U, registrations.size());
511 VerifyRegistrationData(data1, registrations[0]);
512 VerifyRegistrationData(data2, registrations[1]);
513 VerifyRegistrationData(data3, registrations[2]);
514 VerifyRegistrationData(data4, registrations[3]);
517 TEST(ServiceWorkerDatabaseTest, Registration_Basic) {
518 scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
520 GURL origin("http://example.com");
521 RegistrationData data;
522 data.registration_id = 100;
523 data.scope = URL(origin, "/foo");
524 data.script = URL(origin, "/script.js");
525 data.version_id = 200;
526 data.resources_total_size_bytes = 10939 + 200;
528 std::vector<Resource> resources;
529 resources.push_back(CreateResource(1, URL(origin, "/resource1"), 10939));
530 resources.push_back(CreateResource(2, URL(origin, "/resource2"), 200));
532 // Write a resource to the uncommitted list to make sure that writing
533 // registration removes resource ids associated with the registration from
534 // the uncommitted list.
535 std::set<int64> uncommitted_ids;
536 uncommitted_ids.insert(resources[0].resource_id);
537 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
538 database->WriteUncommittedResourceIds(uncommitted_ids));
539 std::set<int64> uncommitted_ids_out;
540 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
541 database->GetUncommittedResourceIds(&uncommitted_ids_out));
542 EXPECT_EQ(uncommitted_ids, uncommitted_ids_out);
544 ServiceWorkerDatabase::RegistrationData deleted_version;
545 deleted_version.version_id = 222; // Dummy initial value
546 std::vector<int64> newly_purgeable_resources;
548 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
549 database->WriteRegistration(
550 data, resources, &deleted_version, &newly_purgeable_resources));
551 EXPECT_EQ(kInvalidServiceWorkerVersionId, deleted_version.version_id);
552 EXPECT_TRUE(newly_purgeable_resources.empty());
554 // Make sure that the registration and resource records are stored.
555 RegistrationData data_out;
556 std::vector<Resource> resources_out;
557 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
558 database->ReadRegistration(
559 data.registration_id, origin, &data_out, &resources_out));
560 VerifyRegistrationData(data, data_out);
561 VerifyResourceRecords(resources, resources_out);
562 GURL origin_out;
563 EXPECT_EQ(
564 ServiceWorkerDatabase::STATUS_OK,
565 database->ReadRegistrationOrigin(data.registration_id, &origin_out));
566 EXPECT_EQ(origin, origin_out);
568 // Make sure that the resource is removed from the uncommitted list.
569 uncommitted_ids_out.clear();
570 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
571 database->GetUncommittedResourceIds(&uncommitted_ids_out));
572 EXPECT_TRUE(uncommitted_ids_out.empty());
574 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
575 database->DeleteRegistration(data.registration_id,
576 origin,
577 &deleted_version,
578 &newly_purgeable_resources));
579 EXPECT_EQ(data.version_id, deleted_version.version_id);
580 ASSERT_EQ(resources.size(), newly_purgeable_resources.size());
581 for (size_t i = 0; i < resources.size(); ++i)
582 EXPECT_EQ(newly_purgeable_resources[i], resources[i].resource_id);
584 // Make sure that the registration and resource records are gone.
585 resources_out.clear();
586 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
587 database->ReadRegistration(
588 data.registration_id, origin, &data_out, &resources_out));
589 EXPECT_TRUE(resources_out.empty());
590 EXPECT_EQ(
591 ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
592 database->ReadRegistrationOrigin(data.registration_id, &origin_out));
594 // Resources should be purgeable because these are no longer referred.
595 std::set<int64> purgeable_ids_out;
596 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
597 database->GetPurgeableResourceIds(&purgeable_ids_out));
598 EXPECT_EQ(2u, purgeable_ids_out.size());
599 EXPECT_TRUE(ContainsKey(purgeable_ids_out, resources[0].resource_id));
600 EXPECT_TRUE(ContainsKey(purgeable_ids_out, resources[1].resource_id));
603 TEST(ServiceWorkerDatabaseTest, DeleteNonExistentRegistration) {
604 scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
606 GURL origin("http://example.com");
607 RegistrationData data;
608 data.registration_id = 100;
609 data.scope = URL(origin, "/foo");
610 data.script = URL(origin, "/script.js");
611 data.version_id = 200;
612 data.resources_total_size_bytes = 19 + 29129;
614 std::vector<Resource> resources;
615 resources.push_back(CreateResource(1, URL(origin, "/resource1"), 19));
616 resources.push_back(CreateResource(2, URL(origin, "/resource2"), 29129));
618 const int64 kNonExistentRegistrationId = 999;
619 const int64 kArbitraryVersionId = 222; // Used as a dummy initial value
621 ServiceWorkerDatabase::RegistrationData deleted_version;
622 deleted_version.version_id = kArbitraryVersionId;
623 std::vector<int64> newly_purgeable_resources;
624 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
625 database->WriteRegistration(
626 data, resources, &deleted_version, &newly_purgeable_resources));
627 EXPECT_EQ(kInvalidServiceWorkerVersionId, deleted_version.version_id);
628 EXPECT_TRUE(newly_purgeable_resources.empty());
630 // Delete from an origin that has a registration.
631 deleted_version.version_id = kArbitraryVersionId;
632 newly_purgeable_resources.clear();
633 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
634 database->DeleteRegistration(kNonExistentRegistrationId,
635 origin,
636 &deleted_version,
637 &newly_purgeable_resources));
638 EXPECT_EQ(kInvalidServiceWorkerVersionId, deleted_version.version_id);
639 EXPECT_TRUE(newly_purgeable_resources.empty());
641 // Delete from an origin that has no registration.
642 deleted_version.version_id = kArbitraryVersionId;
643 newly_purgeable_resources.clear();
644 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
645 database->DeleteRegistration(kNonExistentRegistrationId,
646 GURL("http://example.net"),
647 &deleted_version,
648 &newly_purgeable_resources));
649 EXPECT_EQ(kInvalidServiceWorkerVersionId, deleted_version.version_id);
650 EXPECT_TRUE(newly_purgeable_resources.empty());
653 TEST(ServiceWorkerDatabaseTest, Registration_Overwrite) {
654 scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
656 GURL origin("http://example.com");
657 RegistrationData data;
658 data.registration_id = 100;
659 data.scope = URL(origin, "/foo");
660 data.script = URL(origin, "/script.js");
661 data.version_id = 200;
662 data.resources_total_size_bytes = 10 + 11;
664 std::vector<Resource> resources1;
665 resources1.push_back(CreateResource(1, URL(origin, "/resource1"), 10));
666 resources1.push_back(CreateResource(2, URL(origin, "/resource2"), 11));
668 ServiceWorkerDatabase::RegistrationData deleted_version;
669 deleted_version.version_id = 222; // Dummy inital value
670 std::vector<int64> newly_purgeable_resources;
672 EXPECT_EQ(
673 ServiceWorkerDatabase::STATUS_OK,
674 database->WriteRegistration(
675 data, resources1, &deleted_version, &newly_purgeable_resources));
676 EXPECT_EQ(kInvalidServiceWorkerVersionId, deleted_version.version_id);
677 EXPECT_TRUE(newly_purgeable_resources.empty());
679 // Make sure that the registration and resource records are stored.
680 RegistrationData data_out;
681 std::vector<Resource> resources_out;
682 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->ReadRegistration(
683 data.registration_id, origin, &data_out, &resources_out));
684 VerifyRegistrationData(data, data_out);
685 VerifyResourceRecords(resources1, resources_out);
687 // Update the registration.
688 RegistrationData updated_data = data;
689 updated_data.version_id = data.version_id + 1;
690 updated_data.resources_total_size_bytes = 12 + 13;
691 std::vector<Resource> resources2;
692 resources2.push_back(CreateResource(3, URL(origin, "/resource3"), 12));
693 resources2.push_back(CreateResource(4, URL(origin, "/resource4"), 13));
695 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
696 database->WriteRegistration(updated_data,
697 resources2,
698 &deleted_version,
699 &newly_purgeable_resources));
700 EXPECT_EQ(data.version_id, deleted_version.version_id);
701 ASSERT_EQ(resources1.size(), newly_purgeable_resources.size());
702 for (size_t i = 0; i < resources1.size(); ++i)
703 EXPECT_EQ(newly_purgeable_resources[i], resources1[i].resource_id);
705 // Make sure that |updated_data| is stored and resources referred from |data|
706 // is moved to the purgeable list.
707 resources_out.clear();
708 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->ReadRegistration(
709 updated_data.registration_id, origin, &data_out, &resources_out));
710 VerifyRegistrationData(updated_data, data_out);
711 VerifyResourceRecords(resources2, resources_out);
713 std::set<int64> purgeable_ids_out;
714 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
715 database->GetPurgeableResourceIds(&purgeable_ids_out));
716 EXPECT_EQ(2u, purgeable_ids_out.size());
717 EXPECT_TRUE(ContainsKey(purgeable_ids_out, resources1[0].resource_id));
718 EXPECT_TRUE(ContainsKey(purgeable_ids_out, resources1[1].resource_id));
721 TEST(ServiceWorkerDatabaseTest, Registration_Multiple) {
722 scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
723 GURL origin("http://example.com");
725 ServiceWorkerDatabase::RegistrationData deleted_version;
726 std::vector<int64> newly_purgeable_resources;
728 // Add registration1.
729 RegistrationData data1;
730 data1.registration_id = 100;
731 data1.scope = URL(origin, "/foo");
732 data1.script = URL(origin, "/script1.js");
733 data1.version_id = 200;
734 data1.resources_total_size_bytes = 1451 + 15234;
736 std::vector<Resource> resources1;
737 resources1.push_back(CreateResource(1, URL(origin, "/resource1"), 1451));
738 resources1.push_back(CreateResource(2, URL(origin, "/resource2"), 15234));
739 EXPECT_EQ(
740 ServiceWorkerDatabase::STATUS_OK,
741 database->WriteRegistration(
742 data1, resources1, &deleted_version, &newly_purgeable_resources));
744 // Add registration2.
745 RegistrationData data2;
746 data2.registration_id = 101;
747 data2.scope = URL(origin, "/bar");
748 data2.script = URL(origin, "/script2.js");
749 data2.version_id = 201;
750 data2.resources_total_size_bytes = 5 + 6;
752 std::vector<Resource> resources2;
753 resources2.push_back(CreateResource(3, URL(origin, "/resource3"), 5));
754 resources2.push_back(CreateResource(4, URL(origin, "/resource4"), 6));
755 EXPECT_EQ(
756 ServiceWorkerDatabase::STATUS_OK,
757 database->WriteRegistration(
758 data2, resources2, &deleted_version, &newly_purgeable_resources));
760 // Make sure that registration1 is stored.
761 RegistrationData data_out;
762 std::vector<Resource> resources_out;
763 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->ReadRegistration(
764 data1.registration_id, origin, &data_out, &resources_out));
765 VerifyRegistrationData(data1, data_out);
766 VerifyResourceRecords(resources1, resources_out);
767 GURL origin_out;
768 EXPECT_EQ(
769 ServiceWorkerDatabase::STATUS_OK,
770 database->ReadRegistrationOrigin(data1.registration_id, &origin_out));
771 EXPECT_EQ(origin, origin_out);
773 // Make sure that registration2 is also stored.
774 resources_out.clear();
775 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->ReadRegistration(
776 data2.registration_id, origin, &data_out, &resources_out));
777 VerifyRegistrationData(data2, data_out);
778 VerifyResourceRecords(resources2, resources_out);
779 EXPECT_EQ(
780 ServiceWorkerDatabase::STATUS_OK,
781 database->ReadRegistrationOrigin(data2.registration_id, &origin_out));
782 EXPECT_EQ(origin, origin_out);
784 std::set<int64> purgeable_ids_out;
785 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
786 database->GetPurgeableResourceIds(&purgeable_ids_out));
787 EXPECT_TRUE(purgeable_ids_out.empty());
789 // Delete registration1.
790 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
791 database->DeleteRegistration(data1.registration_id,
792 origin,
793 &deleted_version,
794 &newly_purgeable_resources));
795 EXPECT_EQ(data1.registration_id, deleted_version.registration_id);
797 // Make sure that registration1 is gone.
798 resources_out.clear();
799 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
800 database->ReadRegistration(
801 data1.registration_id, origin, &data_out, &resources_out));
802 EXPECT_TRUE(resources_out.empty());
803 EXPECT_EQ(
804 ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
805 database->ReadRegistrationOrigin(data1.registration_id, &origin_out));
807 purgeable_ids_out.clear();
808 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
809 database->GetPurgeableResourceIds(&purgeable_ids_out));
810 EXPECT_EQ(2u, purgeable_ids_out.size());
811 EXPECT_TRUE(ContainsKey(purgeable_ids_out, resources1[0].resource_id));
812 EXPECT_TRUE(ContainsKey(purgeable_ids_out, resources1[1].resource_id));
814 // Make sure that registration2 is still alive.
815 resources_out.clear();
816 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->ReadRegistration(
817 data2.registration_id, origin, &data_out, &resources_out));
818 VerifyRegistrationData(data2, data_out);
819 VerifyResourceRecords(resources2, resources_out);
820 EXPECT_EQ(
821 ServiceWorkerDatabase::STATUS_OK,
822 database->ReadRegistrationOrigin(data2.registration_id, &origin_out));
823 EXPECT_EQ(origin, origin_out);
826 TEST(ServiceWorkerDatabaseTest, Registration_UninitializedDatabase) {
827 scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
828 const GURL origin("http://example.com");
830 // Should be failed because the database does not exist.
831 RegistrationData data_out;
832 std::vector<Resource> resources_out;
833 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
834 database->ReadRegistration(
835 100, origin, &data_out, &resources_out));
836 EXPECT_EQ(kInvalidServiceWorkerRegistrationId, data_out.registration_id);
837 EXPECT_TRUE(resources_out.empty());
838 GURL origin_out;
839 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
840 database->ReadRegistrationOrigin(100, &origin_out));
842 // Deleting non-existent registration should succeed.
843 RegistrationData deleted_version;
844 std::vector<int64> newly_purgeable_resources;
845 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
846 database->DeleteRegistration(
847 100, origin, &deleted_version, &newly_purgeable_resources));
848 EXPECT_EQ(kInvalidServiceWorkerVersionId, deleted_version.version_id);
849 EXPECT_TRUE(newly_purgeable_resources.empty());
851 // Actually create a new database, but not initialized yet.
852 database->LazyOpen(true);
854 // Should be failed because the database is not initialized.
855 ASSERT_EQ(ServiceWorkerDatabase::UNINITIALIZED, database->state_);
856 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
857 database->ReadRegistration(
858 100, origin, &data_out, &resources_out));
859 EXPECT_EQ(kInvalidServiceWorkerRegistrationId, data_out.registration_id);
860 EXPECT_TRUE(resources_out.empty());
861 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
862 database->ReadRegistrationOrigin(100, &origin_out));
864 // Deleting non-existent registration should succeed.
865 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
866 database->DeleteRegistration(
867 100, origin, &deleted_version, &newly_purgeable_resources));
868 EXPECT_EQ(kInvalidServiceWorkerVersionId, deleted_version.version_id);
869 EXPECT_TRUE(newly_purgeable_resources.empty());
872 TEST(ServiceWorkerDatabaseTest, UserData_Basic) {
873 scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
874 const GURL kOrigin("http://example.com");
876 // Add a registration.
877 RegistrationData data;
878 data.registration_id = 100;
879 data.scope = URL(kOrigin, "/foo");
880 data.script = URL(kOrigin, "/script.js");
881 data.version_id = 200;
883 std::vector<Resource> resources;
884 ServiceWorkerDatabase::RegistrationData deleted_version;
885 std::vector<int64> newly_purgeable_resources;
886 ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
887 database->WriteRegistration(
888 data, resources, &deleted_version, &newly_purgeable_resources));
890 // Write user data associated with the stored registration.
891 std::string user_data_out;
892 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
893 database->WriteUserData(
894 data.registration_id, kOrigin, "key1", "data"));
895 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
896 database->ReadUserData(
897 data.registration_id, "key1", &user_data_out));
898 EXPECT_EQ("data", user_data_out);
900 // Writing user data not associated with the stored registration should be
901 // failed.
902 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
903 database->WriteUserData(300, kOrigin, "key1", "data"));
905 // Write empty user data for a different key.
906 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
907 database->WriteUserData(
908 data.registration_id, kOrigin, "key2", std::string()));
909 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
910 database->ReadUserData(
911 data.registration_id, "key2", &user_data_out));
912 EXPECT_EQ(std::string(), user_data_out);
913 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
914 database->ReadUserData(
915 data.registration_id, "key1", &user_data_out));
916 EXPECT_EQ("data", user_data_out);
918 // Overwrite the existing user data.
919 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
920 database->WriteUserData(
921 data.registration_id, kOrigin, "key1", "overwrite"));
922 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
923 database->ReadUserData(
924 data.registration_id, "key1", &user_data_out));
925 EXPECT_EQ("overwrite", user_data_out);
927 // Delete the user data.
928 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
929 database->DeleteUserData(data.registration_id, "key1"));
930 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
931 database->ReadUserData(
932 data.registration_id, "key1", &user_data_out));
933 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
934 database->ReadUserData(
935 data.registration_id, "key2", &user_data_out));
936 EXPECT_EQ(std::string(), user_data_out);
939 TEST(ServiceWorkerDatabaseTest, UserData_DataIsolation) {
940 scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
941 const GURL kOrigin("http://example.com");
943 // Add registration 1.
944 RegistrationData data1;
945 data1.registration_id = 100;
946 data1.scope = URL(kOrigin, "/foo");
947 data1.script = URL(kOrigin, "/script1.js");
948 data1.version_id = 200;
950 // Add registration 2.
951 RegistrationData data2;
952 data2.registration_id = 101;
953 data2.scope = URL(kOrigin, "/bar");
954 data2.script = URL(kOrigin, "/script2.js");
955 data2.version_id = 201;
957 std::vector<Resource> resources;
958 ServiceWorkerDatabase::RegistrationData deleted_version;
959 std::vector<int64> newly_purgeable_resources;
960 ASSERT_EQ(
961 ServiceWorkerDatabase::STATUS_OK,
962 database->WriteRegistration(
963 data1, resources, &deleted_version, &newly_purgeable_resources));
964 ASSERT_EQ(
965 ServiceWorkerDatabase::STATUS_OK,
966 database->WriteRegistration(
967 data2, resources, &deleted_version, &newly_purgeable_resources));
969 // Write user data associated with the registration1.
970 std::string user_data_out;
971 ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
972 database->WriteUserData(
973 data1.registration_id, kOrigin, "key", "data1"));
974 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
975 database->ReadUserData(
976 data1.registration_id, "key", &user_data_out));
977 EXPECT_EQ("data1", user_data_out);
978 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
979 database->ReadUserData(
980 data2.registration_id, "key", &user_data_out));
982 // Write user data associated with the registration2. This shouldn't overwrite
983 // the data associated with registration1.
984 ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
985 database->WriteUserData(
986 data2.registration_id, kOrigin, "key", "data2"));
987 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
988 database->ReadUserData(
989 data1.registration_id, "key", &user_data_out));
990 EXPECT_EQ("data1", user_data_out);
991 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
992 database->ReadUserData(
993 data2.registration_id, "key", &user_data_out));
994 EXPECT_EQ("data2", user_data_out);
996 // Get all registrations with user data.
997 std::vector<std::pair<int64, std::string>> user_data_list;
998 ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
999 database->ReadUserDataForAllRegistrations("key", &user_data_list));
1000 EXPECT_EQ(2u, user_data_list.size());
1001 EXPECT_EQ(data1.registration_id, user_data_list[0].first);
1002 EXPECT_EQ("data1", user_data_list[0].second);
1003 EXPECT_EQ(data2.registration_id, user_data_list[1].first);
1004 EXPECT_EQ("data2", user_data_list[1].second);
1006 // Delete the data associated with the registration2. This shouldn't delete
1007 // the data associated with registration1.
1008 ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
1009 database->DeleteUserData(data2.registration_id, "key"));
1010 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1011 database->ReadUserData(
1012 data1.registration_id, "key", &user_data_out));
1013 EXPECT_EQ("data1", user_data_out);
1014 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
1015 database->ReadUserData(
1016 data2.registration_id, "key", &user_data_out));
1018 // And again get all registrations with user data.
1019 user_data_list.clear();
1020 ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
1021 database->ReadUserDataForAllRegistrations("key", &user_data_list));
1022 EXPECT_EQ(1u, user_data_list.size());
1023 EXPECT_EQ(data1.registration_id, user_data_list[0].first);
1024 EXPECT_EQ("data1", user_data_list[0].second);
1027 TEST(ServiceWorkerDatabaseTest, UserData_DeleteRegistration) {
1028 scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
1029 const GURL kOrigin("http://example.com");
1031 // Add registration 1.
1032 RegistrationData data1;
1033 data1.registration_id = 100;
1034 data1.scope = URL(kOrigin, "/foo");
1035 data1.script = URL(kOrigin, "/script1.js");
1036 data1.version_id = 200;
1038 // Add registration 2.
1039 RegistrationData data2;
1040 data2.registration_id = 101;
1041 data2.scope = URL(kOrigin, "/bar");
1042 data2.script = URL(kOrigin, "/script2.js");
1043 data2.version_id = 201;
1045 std::vector<Resource> resources;
1046 ServiceWorkerDatabase::RegistrationData deleted_version;
1047 std::vector<int64> newly_purgeable_resources;
1048 ASSERT_EQ(
1049 ServiceWorkerDatabase::STATUS_OK,
1050 database->WriteRegistration(
1051 data1, resources, &deleted_version, &newly_purgeable_resources));
1052 ASSERT_EQ(
1053 ServiceWorkerDatabase::STATUS_OK,
1054 database->WriteRegistration(
1055 data2, resources, &deleted_version, &newly_purgeable_resources));
1057 // Write user data associated with the registration1.
1058 std::string user_data_out;
1059 ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
1060 database->WriteUserData(
1061 data1.registration_id, kOrigin, "key1", "data1"));
1062 ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
1063 database->WriteUserData(
1064 data1.registration_id, kOrigin, "key2", "data2"));
1065 ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
1066 database->ReadUserData(
1067 data1.registration_id, "key1", &user_data_out));
1068 ASSERT_EQ("data1", user_data_out);
1069 ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
1070 database->ReadUserData(
1071 data1.registration_id, "key2", &user_data_out));
1072 ASSERT_EQ("data2", user_data_out);
1074 // Write user data associated with the registration2.
1075 ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
1076 database->WriteUserData(
1077 data2.registration_id, kOrigin, "key3", "data3"));
1078 ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
1079 database->ReadUserData(
1080 data2.registration_id, "key3", &user_data_out));
1081 ASSERT_EQ("data3", user_data_out);
1083 // Delete all data associated with the registration1. This shouldn't delete
1084 // the data associated with registration2.
1085 ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
1086 database->DeleteRegistration(
1087 data1.registration_id, kOrigin,
1088 &deleted_version, &newly_purgeable_resources));
1089 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
1090 database->ReadUserData(
1091 data1.registration_id, "key1", &user_data_out));
1092 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
1093 database->ReadUserData(
1094 data1.registration_id, "key2", &user_data_out));
1095 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1096 database->ReadUserData(
1097 data2.registration_id, "key3", &user_data_out));
1098 EXPECT_EQ("data3", user_data_out);
1101 TEST(ServiceWorkerDatabaseTest, UserData_UninitializedDatabase) {
1102 scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
1103 const GURL kOrigin("http://example.com");
1105 // Should be failed because the database does not exist.
1106 std::string user_data_out;
1107 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
1108 database->ReadUserData(100, "key", &user_data_out));
1110 // Should be failed because the associated registration does not exist.
1111 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
1112 database->WriteUserData(100, kOrigin, "key", "data"));
1114 // Deleting non-existent entry should succeed.
1115 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1116 database->DeleteUserData(100, "key"));
1118 // Actually create a new database, but not initialized yet.
1119 database->LazyOpen(true);
1121 // Should be failed because the database is not initialized.
1122 ASSERT_EQ(ServiceWorkerDatabase::UNINITIALIZED, database->state_);
1123 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
1124 database->ReadUserData(100, "key", &user_data_out));
1125 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
1126 database->WriteUserData(100, kOrigin, "key", "data"));
1128 // Deleting non-existent entry should succeed.
1129 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1130 database->DeleteUserData(100, "key"));
1133 TEST(ServiceWorkerDatabaseTest, UpdateVersionToActive) {
1134 scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
1135 GURL origin("http://example.com");
1137 ServiceWorkerDatabase::RegistrationData deleted_version;
1138 std::vector<int64> newly_purgeable_resources;
1140 // Should be false because a registration does not exist.
1141 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
1142 database->UpdateVersionToActive(0, origin));
1144 // Add a registration.
1145 RegistrationData data;
1146 data.registration_id = 100;
1147 data.scope = URL(origin, "/foo");
1148 data.script = URL(origin, "/script.js");
1149 data.version_id = 200;
1150 data.is_active = false;
1151 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1152 database->WriteRegistration(data,
1153 std::vector<Resource>(),
1154 &deleted_version,
1155 &newly_purgeable_resources));
1157 // Make sure that the registration is stored.
1158 RegistrationData data_out;
1159 std::vector<Resource> resources_out;
1160 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1161 database->ReadRegistration(
1162 data.registration_id, origin, &data_out, &resources_out));
1163 VerifyRegistrationData(data, data_out);
1164 EXPECT_TRUE(resources_out.empty());
1166 // Activate the registration.
1167 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1168 database->UpdateVersionToActive(data.registration_id, origin));
1170 // Make sure that the registration is activated.
1171 resources_out.clear();
1172 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1173 database->ReadRegistration(
1174 data.registration_id, origin, &data_out, &resources_out));
1175 RegistrationData expected_data = data;
1176 expected_data.is_active = true;
1177 VerifyRegistrationData(expected_data, data_out);
1178 EXPECT_TRUE(resources_out.empty());
1180 // Delete the registration.
1181 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1182 database->DeleteRegistration(data.registration_id,
1183 origin,
1184 &deleted_version,
1185 &newly_purgeable_resources));
1186 EXPECT_EQ(data.registration_id, deleted_version.registration_id);
1188 // Should be false because the registration is gone.
1189 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
1190 database->UpdateVersionToActive(data.registration_id, origin));
1193 TEST(ServiceWorkerDatabaseTest, UpdateLastCheckTime) {
1194 scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
1195 GURL origin("http://example.com");
1196 ServiceWorkerDatabase::RegistrationData deleted_version;
1197 std::vector<int64> newly_purgeable_resources;
1199 // Should be false because a registration does not exist.
1200 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
1201 database->UpdateLastCheckTime(0, origin, base::Time::Now()));
1203 // Add a registration.
1204 RegistrationData data;
1205 data.registration_id = 100;
1206 data.scope = URL(origin, "/foo");
1207 data.script = URL(origin, "/script.js");
1208 data.version_id = 200;
1209 data.last_update_check = base::Time::Now();
1210 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1211 database->WriteRegistration(data,
1212 std::vector<Resource>(),
1213 &deleted_version,
1214 &newly_purgeable_resources));
1216 // Make sure that the registration is stored.
1217 RegistrationData data_out;
1218 std::vector<Resource> resources_out;
1219 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1220 database->ReadRegistration(
1221 data.registration_id, origin, &data_out, &resources_out));
1222 VerifyRegistrationData(data, data_out);
1223 EXPECT_TRUE(resources_out.empty());
1225 // Update the last check time.
1226 base::Time updated_time = base::Time::Now();
1227 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1228 database->UpdateLastCheckTime(
1229 data.registration_id, origin, updated_time));
1231 // Make sure that the registration is updated.
1232 resources_out.clear();
1233 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1234 database->ReadRegistration(
1235 data.registration_id, origin, &data_out, &resources_out));
1236 RegistrationData expected_data = data;
1237 expected_data.last_update_check = updated_time;
1238 VerifyRegistrationData(expected_data, data_out);
1239 EXPECT_TRUE(resources_out.empty());
1241 // Delete the registration.
1242 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1243 database->DeleteRegistration(data.registration_id,
1244 origin,
1245 &deleted_version,
1246 &newly_purgeable_resources));
1247 EXPECT_EQ(data.registration_id, deleted_version.registration_id);
1249 // Should be false because the registration is gone.
1250 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
1251 database->UpdateLastCheckTime(
1252 data.registration_id, origin, base::Time::Now()));
1255 TEST(ServiceWorkerDatabaseTest, UncommittedResourceIds) {
1256 scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
1258 // Write {1, 2, 3}.
1259 std::set<int64> ids1;
1260 ids1.insert(1);
1261 ids1.insert(2);
1262 ids1.insert(3);
1263 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1264 database->WriteUncommittedResourceIds(ids1));
1266 std::set<int64> ids_out;
1267 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1268 database->GetUncommittedResourceIds(&ids_out));
1269 EXPECT_EQ(ids1, ids_out);
1271 // Write {2, 4}.
1272 std::set<int64> ids2;
1273 ids2.insert(2);
1274 ids2.insert(4);
1275 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1276 database->WriteUncommittedResourceIds(ids2));
1278 ids_out.clear();
1279 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1280 database->GetUncommittedResourceIds(&ids_out));
1281 std::set<int64> expected = base::STLSetUnion<std::set<int64> >(ids1, ids2);
1282 EXPECT_EQ(expected, ids_out);
1284 // Delete {2, 3}.
1285 std::set<int64> ids3;
1286 ids3.insert(2);
1287 ids3.insert(3);
1288 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1289 database->ClearUncommittedResourceIds(ids3));
1291 ids_out.clear();
1292 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1293 database->GetUncommittedResourceIds(&ids_out));
1294 expected = base::STLSetDifference<std::set<int64> >(expected, ids3);
1295 EXPECT_EQ(expected, ids_out);
1298 TEST(ServiceWorkerDatabaseTest, PurgeableResourceIds) {
1299 scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
1301 // Write {1, 2, 3}.
1302 std::set<int64> ids1;
1303 ids1.insert(1);
1304 ids1.insert(2);
1305 ids1.insert(3);
1306 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1307 database->WritePurgeableResourceIds(ids1));
1309 std::set<int64> ids_out;
1310 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1311 database->GetPurgeableResourceIds(&ids_out));
1312 EXPECT_EQ(ids1, ids_out);
1314 // Write {2, 4}.
1315 std::set<int64> ids2;
1316 ids2.insert(2);
1317 ids2.insert(4);
1318 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1319 database->WritePurgeableResourceIds(ids2));
1321 ids_out.clear();
1322 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1323 database->GetPurgeableResourceIds(&ids_out));
1324 std::set<int64> expected = base::STLSetUnion<std::set<int64> >(ids1, ids2);
1325 EXPECT_EQ(expected, ids_out);
1327 // Delete {2, 3}.
1328 std::set<int64> ids3;
1329 ids3.insert(2);
1330 ids3.insert(3);
1331 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1332 database->ClearPurgeableResourceIds(ids3));
1334 ids_out.clear();
1335 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1336 database->GetPurgeableResourceIds(&ids_out));
1337 expected = base::STLSetDifference<std::set<int64> >(expected, ids3);
1338 EXPECT_EQ(expected, ids_out);
1341 TEST(ServiceWorkerDatabaseTest, DeleteAllDataForOrigin) {
1342 scoped_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
1343 ServiceWorkerDatabase::RegistrationData deleted_version;
1344 std::vector<int64> newly_purgeable_resources;
1346 // Data associated with |origin1| will be removed.
1347 GURL origin1("http://example.com");
1348 GURL origin2("http://example.org");
1350 // |origin1| has two registrations (registration1 and registration2).
1351 RegistrationData data1;
1352 data1.registration_id = 10;
1353 data1.scope = URL(origin1, "/foo");
1354 data1.script = URL(origin1, "/script1.js");
1355 data1.version_id = 100;
1356 data1.resources_total_size_bytes = 2013 + 512;
1358 std::vector<Resource> resources1;
1359 resources1.push_back(CreateResource(1, URL(origin1, "/resource1"), 2013));
1360 resources1.push_back(CreateResource(2, URL(origin1, "/resource2"), 512));
1361 ASSERT_EQ(
1362 ServiceWorkerDatabase::STATUS_OK,
1363 database->WriteRegistration(
1364 data1, resources1, &deleted_version, &newly_purgeable_resources));
1365 ASSERT_EQ(
1366 ServiceWorkerDatabase::STATUS_OK,
1367 database->WriteUserData(
1368 data1.registration_id, origin1, "key1", "data1"));
1369 ASSERT_EQ(
1370 ServiceWorkerDatabase::STATUS_OK,
1371 database->WriteUserData(
1372 data1.registration_id, origin1, "key2", "data2"));
1374 RegistrationData data2;
1375 data2.registration_id = 11;
1376 data2.scope = URL(origin1, "/bar");
1377 data2.script = URL(origin1, "/script2.js");
1378 data2.version_id = 101;
1379 data2.resources_total_size_bytes = 4 + 5;
1381 std::vector<Resource> resources2;
1382 resources2.push_back(CreateResource(3, URL(origin1, "/resource3"), 4));
1383 resources2.push_back(CreateResource(4, URL(origin1, "/resource4"), 5));
1384 ASSERT_EQ(
1385 ServiceWorkerDatabase::STATUS_OK,
1386 database->WriteRegistration(
1387 data2, resources2, &deleted_version, &newly_purgeable_resources));
1388 ASSERT_EQ(
1389 ServiceWorkerDatabase::STATUS_OK,
1390 database->WriteUserData(
1391 data2.registration_id, origin1, "key3", "data3"));
1392 ASSERT_EQ(
1393 ServiceWorkerDatabase::STATUS_OK,
1394 database->WriteUserData(
1395 data2.registration_id, origin1, "key4", "data4"));
1397 // |origin2| has one registration (registration3).
1398 RegistrationData data3;
1399 data3.registration_id = 12;
1400 data3.scope = URL(origin2, "/hoge");
1401 data3.script = URL(origin2, "/script3.js");
1402 data3.version_id = 102;
1403 data3.resources_total_size_bytes = 6 + 7;
1405 std::vector<Resource> resources3;
1406 resources3.push_back(CreateResource(5, URL(origin2, "/resource5"), 6));
1407 resources3.push_back(CreateResource(6, URL(origin2, "/resource6"), 7));
1408 ASSERT_EQ(
1409 ServiceWorkerDatabase::STATUS_OK,
1410 database->WriteRegistration(
1411 data3, resources3, &deleted_version, &newly_purgeable_resources));
1412 ASSERT_EQ(
1413 ServiceWorkerDatabase::STATUS_OK,
1414 database->WriteUserData(
1415 data3.registration_id, origin2, "key5", "data5"));
1416 ASSERT_EQ(
1417 ServiceWorkerDatabase::STATUS_OK,
1418 database->WriteUserData(
1419 data3.registration_id, origin2, "key6", "data6"));
1421 std::set<GURL> origins_to_delete;
1422 origins_to_delete.insert(origin1);
1423 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1424 database->DeleteAllDataForOrigins(origins_to_delete,
1425 &newly_purgeable_resources));
1427 // |origin1| should be removed from the unique origin list.
1428 std::set<GURL> unique_origins;
1429 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1430 database->GetOriginsWithRegistrations(&unique_origins));
1431 EXPECT_EQ(1u, unique_origins.size());
1432 EXPECT_TRUE(ContainsKey(unique_origins, origin2));
1434 // The registrations for |origin1| should be removed.
1435 std::vector<RegistrationData> registrations;
1436 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1437 database->GetRegistrationsForOrigin(origin1, &registrations));
1438 EXPECT_TRUE(registrations.empty());
1439 GURL origin_out;
1440 EXPECT_EQ(
1441 ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
1442 database->ReadRegistrationOrigin(data1.registration_id, &origin_out));
1444 // The registration for |origin2| should not be removed.
1445 RegistrationData data_out;
1446 std::vector<Resource> resources_out;
1447 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->ReadRegistration(
1448 data3.registration_id, origin2, &data_out, &resources_out));
1449 VerifyRegistrationData(data3, data_out);
1450 VerifyResourceRecords(resources3, resources_out);
1451 EXPECT_EQ(
1452 ServiceWorkerDatabase::STATUS_OK,
1453 database->ReadRegistrationOrigin(data3.registration_id, &origin_out));
1454 EXPECT_EQ(origin2, origin_out);
1456 // The resources associated with |origin1| should be purgeable.
1457 std::set<int64> purgeable_ids_out;
1458 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1459 database->GetPurgeableResourceIds(&purgeable_ids_out));
1460 EXPECT_EQ(4u, purgeable_ids_out.size());
1461 EXPECT_TRUE(ContainsKey(purgeable_ids_out, 1));
1462 EXPECT_TRUE(ContainsKey(purgeable_ids_out, 2));
1463 EXPECT_TRUE(ContainsKey(purgeable_ids_out, 3));
1464 EXPECT_TRUE(ContainsKey(purgeable_ids_out, 4));
1466 // The user data associated with |origin1| should be removed.
1467 std::string user_data_out;
1468 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
1469 database->ReadUserData(
1470 data1.registration_id, "key1", &user_data_out));
1471 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
1472 database->ReadUserData(
1473 data1.registration_id, "key2", &user_data_out));
1474 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
1475 database->ReadUserData(
1476 data2.registration_id, "key3", &user_data_out));
1477 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND,
1478 database->ReadUserData(
1479 data2.registration_id, "key4", &user_data_out));
1481 // The user data associated with |origin2| should not be removed.
1482 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1483 database->ReadUserData(
1484 data3.registration_id, "key5", &user_data_out));
1485 EXPECT_EQ("data5", user_data_out);
1486 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
1487 database->ReadUserData(
1488 data3.registration_id, "key6", &user_data_out));
1489 EXPECT_EQ("data6", user_data_out);
1492 TEST(ServiceWorkerDatabaseTest, DestroyDatabase) {
1493 base::ScopedTempDir database_dir;
1494 ASSERT_TRUE(database_dir.CreateUniqueTempDir());
1495 scoped_ptr<ServiceWorkerDatabase> database(
1496 CreateDatabase(database_dir.path()));
1498 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->LazyOpen(true));
1499 ASSERT_TRUE(base::DirectoryExists(database_dir.path()));
1501 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->DestroyDatabase());
1502 ASSERT_FALSE(base::DirectoryExists(database_dir.path()));
1505 } // namespace content