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"
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"
22 typedef ServiceWorkerDatabase::RegistrationData RegistrationData
;
23 typedef ServiceWorkerDatabase::ResourceRecord Resource
;
30 AvailableIds() : reg_id(-1), res_id(-1), ver_id(-1) {}
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());
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
);
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
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
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.
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.
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.
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;
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};
239 ServiceWorkerDatabase::STATUS_OK
,
240 database
->WriteUncommittedResourceIds(std::set
<int64
>(
241 kUncommittedIds
, kUncommittedIds
+ arraysize(kUncommittedIds
))));
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
))));
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;
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;
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;
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;
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;
341 ServiceWorkerDatabase::STATUS_OK
,
342 database
->WriteRegistration(
343 data4
, resources
, &deleted_version
, &newly_purgeable_resources
));
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
,
359 &newly_purgeable_resources
));
360 EXPECT_EQ(data4
.registration_id
, deleted_version
.registration_id
);
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
,
375 &newly_purgeable_resources
));
376 EXPECT_EQ(data3
.registration_id
, deleted_version
.registration_id
);
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
, ®istrations
));
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;
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;
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;
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;
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
, ®istrations
));
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(®istrations
));
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;
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;
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;
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;
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(®istrations
));
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
);
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
,
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());
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
,
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"),
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
;
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
,
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));
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));
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
);
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
);
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
,
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());
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
);
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());
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
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
;
961 ServiceWorkerDatabase::STATUS_OK
,
962 database
->WriteRegistration(
963 data1
, resources
, &deleted_version
, &newly_purgeable_resources
));
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
;
1049 ServiceWorkerDatabase::STATUS_OK
,
1050 database
->WriteRegistration(
1051 data1
, resources
, &deleted_version
, &newly_purgeable_resources
));
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
>(),
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
,
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
>(),
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
,
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());
1259 std::set
<int64
> ids1
;
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
);
1272 std::set
<int64
> ids2
;
1275 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1276 database
->WriteUncommittedResourceIds(ids2
));
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
);
1285 std::set
<int64
> ids3
;
1288 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1289 database
->ClearUncommittedResourceIds(ids3
));
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());
1302 std::set
<int64
> ids1
;
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
);
1315 std::set
<int64
> ids2
;
1318 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1319 database
->WritePurgeableResourceIds(ids2
));
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
);
1328 std::set
<int64
> ids3
;
1331 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1332 database
->ClearPurgeableResourceIds(ids3
));
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));
1362 ServiceWorkerDatabase::STATUS_OK
,
1363 database
->WriteRegistration(
1364 data1
, resources1
, &deleted_version
, &newly_purgeable_resources
));
1366 ServiceWorkerDatabase::STATUS_OK
,
1367 database
->WriteUserData(
1368 data1
.registration_id
, origin1
, "key1", "data1"));
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));
1385 ServiceWorkerDatabase::STATUS_OK
,
1386 database
->WriteRegistration(
1387 data2
, resources2
, &deleted_version
, &newly_purgeable_resources
));
1389 ServiceWorkerDatabase::STATUS_OK
,
1390 database
->WriteUserData(
1391 data2
.registration_id
, origin1
, "key3", "data3"));
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));
1409 ServiceWorkerDatabase::STATUS_OK
,
1410 database
->WriteRegistration(
1411 data3
, resources3
, &deleted_version
, &newly_purgeable_resources
));
1413 ServiceWorkerDatabase::STATUS_OK
,
1414 database
->WriteUserData(
1415 data3
.registration_id
, origin2
, "key5", "data5"));
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
, ®istrations
));
1438 EXPECT_TRUE(registrations
.empty());
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
);
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