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/file_util.h"
10 #include "base/files/scoped_temp_dir.h"
11 #include "base/stl_util.h"
12 #include "content/browser/service_worker/service_worker_database.pb.h"
13 #include "content/common/service_worker/service_worker_types.h"
14 #include "testing/gtest/include/gtest/gtest.h"
20 typedef ServiceWorkerDatabase::RegistrationData RegistrationData
;
21 typedef ServiceWorkerDatabase::ResourceRecord Resource
;
28 AvailableIds() : reg_id(-1), res_id(-1), ver_id(-1) {}
32 GURL
URL(const GURL
& origin
, const std::string
& path
) {
33 EXPECT_TRUE(origin
.is_valid());
34 EXPECT_EQ(origin
, origin
.GetOrigin());
35 GURL
out(origin
.spec() + path
);
36 EXPECT_TRUE(out
.is_valid());
40 Resource
CreateResource(int64 resource_id
, const GURL
& url
) {
41 EXPECT_TRUE(url
.is_valid());
43 resource
.resource_id
= resource_id
;
48 ServiceWorkerDatabase
* CreateDatabase(const base::FilePath
& path
) {
49 return new ServiceWorkerDatabase(path
);
52 ServiceWorkerDatabase
* CreateDatabaseInMemory() {
53 return new ServiceWorkerDatabase(base::FilePath());
56 void VerifyRegistrationData(const RegistrationData
& expected
,
57 const RegistrationData
& actual
) {
58 EXPECT_EQ(expected
.registration_id
, actual
.registration_id
);
59 EXPECT_EQ(expected
.scope
, actual
.scope
);
60 EXPECT_EQ(expected
.script
, actual
.script
);
61 EXPECT_EQ(expected
.version_id
, actual
.version_id
);
62 EXPECT_EQ(expected
.is_active
, actual
.is_active
);
63 EXPECT_EQ(expected
.has_fetch_handler
, actual
.has_fetch_handler
);
64 EXPECT_EQ(expected
.last_update_check
, actual
.last_update_check
);
67 void VerifyResourceRecords(const std::vector
<Resource
>& expected
,
68 const std::vector
<Resource
>& actual
) {
69 ASSERT_EQ(expected
.size(), actual
.size());
70 for (size_t i
= 0; i
< expected
.size(); ++i
) {
71 EXPECT_EQ(expected
[i
].resource_id
, actual
[i
].resource_id
);
72 EXPECT_EQ(expected
[i
].url
, actual
[i
].url
);
78 TEST(ServiceWorkerDatabaseTest
, OpenDatabase
) {
79 base::ScopedTempDir database_dir
;
80 ASSERT_TRUE(database_dir
.CreateUniqueTempDir());
81 scoped_ptr
<ServiceWorkerDatabase
> database(
82 CreateDatabase(database_dir
.path()));
84 // Should be false because the database does not exist at the path.
85 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND
,
86 database
->LazyOpen(false));
88 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
, database
->LazyOpen(true));
90 database
.reset(CreateDatabase(database_dir
.path()));
91 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
, database
->LazyOpen(false));
94 TEST(ServiceWorkerDatabaseTest
, OpenDatabase_InMemory
) {
95 scoped_ptr
<ServiceWorkerDatabase
> database(CreateDatabaseInMemory());
97 // Should be false because the database does not exist in memory.
98 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND
,
99 database
->LazyOpen(false));
101 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
, database
->LazyOpen(true));
102 database
.reset(CreateDatabaseInMemory());
104 // Should be false because the database is not persistent.
105 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND
,
106 database
->LazyOpen(false));
109 TEST(ServiceWorkerDatabaseTest
, DatabaseVersion
) {
110 scoped_ptr
<ServiceWorkerDatabase
> database(CreateDatabaseInMemory());
111 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
, database
->LazyOpen(true));
113 // Opening a new database does not write anything, so its schema version
115 int64 db_version
= -1;
116 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
117 database
->ReadDatabaseVersion(&db_version
));
118 EXPECT_EQ(0u, db_version
);
120 // First writing triggers database initialization and bumps the schema
122 std::vector
<ServiceWorkerDatabase::ResourceRecord
> resources
;
123 int64 deleted_version_id
;
124 std::vector
<int64
> newly_purgeable_resources
;
125 ServiceWorkerDatabase::RegistrationData data
;
127 ServiceWorkerDatabase::STATUS_OK
,
128 database
->WriteRegistration(
129 data
, resources
, &deleted_version_id
, &newly_purgeable_resources
));
131 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
132 database
->ReadDatabaseVersion(&db_version
));
133 EXPECT_LT(0, db_version
);
136 TEST(ServiceWorkerDatabaseTest
, GetNextAvailableIds
) {
137 base::ScopedTempDir database_dir
;
138 ASSERT_TRUE(database_dir
.CreateUniqueTempDir());
139 scoped_ptr
<ServiceWorkerDatabase
> database(
140 CreateDatabase(database_dir
.path()));
142 GURL
origin("http://example.com");
144 // The database has never been used, so returns initial values.
146 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
, database
->GetNextAvailableIds(
147 &ids
.reg_id
, &ids
.ver_id
, &ids
.res_id
));
148 EXPECT_EQ(0, ids
.reg_id
);
149 EXPECT_EQ(0, ids
.ver_id
);
150 EXPECT_EQ(0, ids
.res_id
);
152 ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK
, database
->LazyOpen(true));
153 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
, database
->GetNextAvailableIds(
154 &ids
.reg_id
, &ids
.ver_id
, &ids
.res_id
));
155 EXPECT_EQ(0, ids
.reg_id
);
156 EXPECT_EQ(0, ids
.ver_id
);
157 EXPECT_EQ(0, ids
.res_id
);
159 // Writing a registration bumps the next available ids.
160 std::vector
<Resource
> resources
;
161 RegistrationData data1
;
162 int64 deleted_version_id
;
163 std::vector
<int64
> newly_purgeable_resources
;
164 data1
.registration_id
= 100;
165 data1
.scope
= URL(origin
, "/foo");
166 data1
.script
= URL(origin
, "/script1.js");
167 data1
.version_id
= 200;
169 ServiceWorkerDatabase::STATUS_OK
,
170 database
->WriteRegistration(
171 data1
, resources
, &deleted_version_id
, &newly_purgeable_resources
));
173 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
, database
->GetNextAvailableIds(
174 &ids
.reg_id
, &ids
.ver_id
, &ids
.res_id
));
175 EXPECT_EQ(101, ids
.reg_id
);
176 EXPECT_EQ(201, ids
.ver_id
);
177 EXPECT_EQ(0, ids
.res_id
);
179 // Writing uncommitted resources bumps the next available id.
180 const int64 kUncommittedIds
[] = {0, 1, 3, 5, 6, 10};
182 ServiceWorkerDatabase::STATUS_OK
,
183 database
->WriteUncommittedResourceIds(std::set
<int64
>(
184 kUncommittedIds
, kUncommittedIds
+ arraysize(kUncommittedIds
))));
186 ServiceWorkerDatabase::STATUS_OK
,
187 database
->GetNextAvailableIds(&ids
.reg_id
, &ids
.ver_id
, &ids
.res_id
));
188 EXPECT_EQ(101, ids
.reg_id
);
189 EXPECT_EQ(201, ids
.ver_id
);
190 EXPECT_EQ(11, ids
.res_id
);
192 // Writing purgeable resources bumps the next available id.
193 const int64 kPurgeableIds
[] = {4, 12, 16, 17, 20};
194 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
195 database
->WriteUncommittedResourceIds(std::set
<int64
>(
196 kPurgeableIds
, kPurgeableIds
+ arraysize(kPurgeableIds
))));
198 ServiceWorkerDatabase::STATUS_OK
,
199 database
->GetNextAvailableIds(&ids
.reg_id
, &ids
.ver_id
, &ids
.res_id
));
200 EXPECT_EQ(101, ids
.reg_id
);
201 EXPECT_EQ(201, ids
.ver_id
);
202 EXPECT_EQ(21, ids
.res_id
);
204 // Writing a registration whose ids are lower than the stored ones should not
205 // bump the next available ids.
206 RegistrationData data2
;
207 data2
.registration_id
= 10;
208 data2
.scope
= URL(origin
, "/bar");
209 data2
.script
= URL(origin
, "/script2.js");
210 data2
.version_id
= 20;
212 ServiceWorkerDatabase::STATUS_OK
,
213 database
->WriteRegistration(
214 data2
, resources
, &deleted_version_id
, &newly_purgeable_resources
));
216 // Same with resources.
217 int64 kLowResourceId
= 15;
218 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
219 database
->WriteUncommittedResourceIds(
220 std::set
<int64
>(&kLowResourceId
, &kLowResourceId
+ 1)));
222 // Close and reopen the database to verify the stored values.
223 database
.reset(CreateDatabase(database_dir
.path()));
225 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
, database
->GetNextAvailableIds(
226 &ids
.reg_id
, &ids
.ver_id
, &ids
.res_id
));
227 EXPECT_EQ(101, ids
.reg_id
);
228 EXPECT_EQ(201, ids
.ver_id
);
229 EXPECT_EQ(21, ids
.res_id
);
232 TEST(ServiceWorkerDatabaseTest
, GetOriginsWithRegistrations
) {
233 scoped_ptr
<ServiceWorkerDatabase
> database(CreateDatabaseInMemory());
235 std::set
<GURL
> origins
;
236 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
237 database
->GetOriginsWithRegistrations(&origins
));
238 EXPECT_TRUE(origins
.empty());
240 std::vector
<Resource
> resources
;
241 int64 deleted_version_id
;
242 std::vector
<int64
> newly_purgeable_resources
;
244 GURL
origin1("http://example.com");
245 RegistrationData data1
;
246 data1
.registration_id
= 123;
247 data1
.scope
= URL(origin1
, "/foo");
248 data1
.script
= URL(origin1
, "/script1.js");
249 data1
.version_id
= 456;
251 ServiceWorkerDatabase::STATUS_OK
,
252 database
->WriteRegistration(
253 data1
, resources
, &deleted_version_id
, &newly_purgeable_resources
));
255 GURL
origin2("https://www.example.com");
256 RegistrationData data2
;
257 data2
.registration_id
= 234;
258 data2
.scope
= URL(origin2
, "/bar");
259 data2
.script
= URL(origin2
, "/script2.js");
260 data2
.version_id
= 567;
262 ServiceWorkerDatabase::STATUS_OK
,
263 database
->WriteRegistration(
264 data2
, resources
, &deleted_version_id
, &newly_purgeable_resources
));
266 GURL
origin3("https://example.org");
267 RegistrationData data3
;
268 data3
.registration_id
= 345;
269 data3
.scope
= URL(origin3
, "/hoge");
270 data3
.script
= URL(origin3
, "/script3.js");
271 data3
.version_id
= 678;
273 ServiceWorkerDatabase::STATUS_OK
,
274 database
->WriteRegistration(
275 data3
, resources
, &deleted_version_id
, &newly_purgeable_resources
));
277 // |origin3| has two registrations.
278 RegistrationData data4
;
279 data4
.registration_id
= 456;
280 data4
.scope
= URL(origin3
, "/fuga");
281 data4
.script
= URL(origin3
, "/script4.js");
282 data4
.version_id
= 789;
284 ServiceWorkerDatabase::STATUS_OK
,
285 database
->WriteRegistration(
286 data4
, resources
, &deleted_version_id
, &newly_purgeable_resources
));
289 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
290 database
->GetOriginsWithRegistrations(&origins
));
291 EXPECT_EQ(3U, origins
.size());
292 EXPECT_TRUE(ContainsKey(origins
, origin1
));
293 EXPECT_TRUE(ContainsKey(origins
, origin2
));
294 EXPECT_TRUE(ContainsKey(origins
, origin3
));
296 // |origin3| has another registration, so should not remove it from the
297 // unique origin list.
299 ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK
,
300 database
->DeleteRegistration(data4
.registration_id
,
303 &newly_purgeable_resources
));
306 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
307 database
->GetOriginsWithRegistrations(&origins
));
308 EXPECT_EQ(3U, origins
.size());
309 EXPECT_TRUE(ContainsKey(origins
, origin1
));
310 EXPECT_TRUE(ContainsKey(origins
, origin2
));
311 EXPECT_TRUE(ContainsKey(origins
, origin3
));
313 // |origin3| should be removed from the unique origin list.
314 ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK
,
315 database
->DeleteRegistration(data3
.registration_id
,
318 &newly_purgeable_resources
));
321 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
322 database
->GetOriginsWithRegistrations(&origins
));
323 EXPECT_EQ(2U, origins
.size());
324 EXPECT_TRUE(ContainsKey(origins
, origin1
));
325 EXPECT_TRUE(ContainsKey(origins
, origin2
));
328 TEST(ServiceWorkerDatabaseTest
, GetRegistrationsForOrigin
) {
329 scoped_ptr
<ServiceWorkerDatabase
> database(CreateDatabaseInMemory());
331 GURL
origin1("http://example.com");
332 GURL
origin2("https://www.example.com");
333 GURL
origin3("https://example.org");
335 std::vector
<RegistrationData
> registrations
;
336 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
337 database
->GetRegistrationsForOrigin(origin1
, ®istrations
));
338 EXPECT_TRUE(registrations
.empty());
340 std::vector
<Resource
> resources
;
341 int64 deleted_version_id
;
342 std::vector
<int64
> newly_purgeable_resources
;
344 RegistrationData data1
;
345 data1
.registration_id
= 100;
346 data1
.scope
= URL(origin1
, "/foo");
347 data1
.script
= URL(origin1
, "/script1.js");
348 data1
.version_id
= 1000;
350 ServiceWorkerDatabase::STATUS_OK
,
351 database
->WriteRegistration(
352 data1
, resources
, &deleted_version_id
, &newly_purgeable_resources
));
354 RegistrationData data2
;
355 data2
.registration_id
= 200;
356 data2
.scope
= URL(origin2
, "/bar");
357 data2
.script
= URL(origin2
, "/script2.js");
358 data2
.version_id
= 2000;
360 ServiceWorkerDatabase::STATUS_OK
,
361 database
->WriteRegistration(
362 data2
, resources
, &deleted_version_id
, &newly_purgeable_resources
));
364 RegistrationData data3
;
365 data3
.registration_id
= 300;
366 data3
.scope
= URL(origin3
, "/hoge");
367 data3
.script
= URL(origin3
, "/script3.js");
368 data3
.version_id
= 3000;
370 ServiceWorkerDatabase::STATUS_OK
,
371 database
->WriteRegistration(
372 data3
, resources
, &deleted_version_id
, &newly_purgeable_resources
));
374 // |origin3| has two registrations.
375 RegistrationData data4
;
376 data4
.registration_id
= 400;
377 data4
.scope
= URL(origin3
, "/fuga");
378 data4
.script
= URL(origin3
, "/script4.js");
379 data4
.version_id
= 4000;
381 ServiceWorkerDatabase::STATUS_OK
,
382 database
->WriteRegistration(
383 data4
, resources
, &deleted_version_id
, &newly_purgeable_resources
));
385 registrations
.clear();
386 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
387 database
->GetRegistrationsForOrigin(origin3
, ®istrations
));
388 EXPECT_EQ(2U, registrations
.size());
389 VerifyRegistrationData(data3
, registrations
[0]);
390 VerifyRegistrationData(data4
, registrations
[1]);
393 TEST(ServiceWorkerDatabaseTest
, GetAllRegistrations
) {
394 scoped_ptr
<ServiceWorkerDatabase
> database(CreateDatabaseInMemory());
396 std::vector
<RegistrationData
> registrations
;
397 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
398 database
->GetAllRegistrations(®istrations
));
399 EXPECT_TRUE(registrations
.empty());
401 std::vector
<Resource
> resources
;
402 int64 deleted_version_id
;
403 std::vector
<int64
> newly_purgeable_resources
;
405 GURL
origin1("http://www1.example.com");
406 RegistrationData data1
;
407 data1
.registration_id
= 100;
408 data1
.scope
= URL(origin1
, "/foo");
409 data1
.script
= URL(origin1
, "/script1.js");
410 data1
.version_id
= 1000;
412 ServiceWorkerDatabase::STATUS_OK
,
413 database
->WriteRegistration(
414 data1
, resources
, &deleted_version_id
, &newly_purgeable_resources
));
416 GURL
origin2("http://www2.example.com");
417 RegistrationData data2
;
418 data2
.registration_id
= 200;
419 data2
.scope
= URL(origin2
, "/bar");
420 data2
.script
= URL(origin2
, "/script2.js");
421 data2
.version_id
= 2000;
423 ServiceWorkerDatabase::STATUS_OK
,
424 database
->WriteRegistration(
425 data2
, resources
, &deleted_version_id
, &newly_purgeable_resources
));
427 GURL
origin3("http://www3.example.com");
428 RegistrationData data3
;
429 data3
.registration_id
= 300;
430 data3
.scope
= URL(origin3
, "/hoge");
431 data3
.script
= URL(origin3
, "/script3.js");
432 data3
.version_id
= 3000;
434 ServiceWorkerDatabase::STATUS_OK
,
435 database
->WriteRegistration(
436 data3
, resources
, &deleted_version_id
, &newly_purgeable_resources
));
438 // |origin3| has two registrations.
439 RegistrationData data4
;
440 data4
.registration_id
= 400;
441 data4
.scope
= URL(origin3
, "/fuga");
442 data4
.script
= URL(origin3
, "/script4.js");
443 data4
.version_id
= 4000;
445 ServiceWorkerDatabase::STATUS_OK
,
446 database
->WriteRegistration(
447 data4
, resources
, &deleted_version_id
, &newly_purgeable_resources
));
449 registrations
.clear();
450 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
451 database
->GetAllRegistrations(®istrations
));
452 EXPECT_EQ(4U, registrations
.size());
453 VerifyRegistrationData(data1
, registrations
[0]);
454 VerifyRegistrationData(data2
, registrations
[1]);
455 VerifyRegistrationData(data3
, registrations
[2]);
456 VerifyRegistrationData(data4
, registrations
[3]);
459 TEST(ServiceWorkerDatabaseTest
, Registration_Basic
) {
460 scoped_ptr
<ServiceWorkerDatabase
> database(CreateDatabaseInMemory());
462 GURL
origin("http://example.com");
463 RegistrationData data
;
464 data
.registration_id
= 100;
465 data
.scope
= URL(origin
, "/foo");
466 data
.script
= URL(origin
, "/script.js");
467 data
.version_id
= 200;
469 std::vector
<Resource
> resources
;
470 resources
.push_back(CreateResource(1, URL(origin
, "/resource1")));
471 resources
.push_back(CreateResource(2, URL(origin
, "/resource2")));
473 // Write a resource to the uncommitted list to make sure that writing
474 // registration removes resource ids associated with the registration from
475 // the uncommitted list.
476 std::set
<int64
> uncommitted_ids
;
477 uncommitted_ids
.insert(resources
[0].resource_id
);
478 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
479 database
->WriteUncommittedResourceIds(uncommitted_ids
));
480 std::set
<int64
> uncommitted_ids_out
;
481 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
482 database
->GetUncommittedResourceIds(&uncommitted_ids_out
));
483 EXPECT_EQ(uncommitted_ids
, uncommitted_ids_out
);
485 int64 deleted_version_id
= 222; // Dummy initial value
486 std::vector
<int64
> newly_purgeable_resources
;
489 ServiceWorkerDatabase::STATUS_OK
,
490 database
->WriteRegistration(
491 data
, resources
, &deleted_version_id
, &newly_purgeable_resources
));
492 EXPECT_EQ(kInvalidServiceWorkerVersionId
, deleted_version_id
);
493 EXPECT_TRUE(newly_purgeable_resources
.empty());
495 // Make sure that the registration and resource records are stored.
496 RegistrationData data_out
;
497 std::vector
<Resource
> resources_out
;
498 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
499 database
->ReadRegistration(
500 data
.registration_id
, origin
, &data_out
, &resources_out
));
501 VerifyRegistrationData(data
, data_out
);
502 VerifyResourceRecords(resources
, resources_out
);
504 // Make sure that the resource is removed from the uncommitted list.
505 uncommitted_ids_out
.clear();
506 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
507 database
->GetUncommittedResourceIds(&uncommitted_ids_out
));
508 EXPECT_TRUE(uncommitted_ids_out
.empty());
510 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
511 database
->DeleteRegistration(data
.registration_id
,
514 &newly_purgeable_resources
));
515 EXPECT_EQ(data
.version_id
, deleted_version_id
);
516 ASSERT_EQ(resources
.size(), newly_purgeable_resources
.size());
517 for (size_t i
= 0; i
< resources
.size(); ++i
)
518 EXPECT_EQ(newly_purgeable_resources
[i
], resources
[i
].resource_id
);
520 // Make sure that the registration and resource records are gone.
521 resources_out
.clear();
522 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND
,
523 database
->ReadRegistration(
524 data
.registration_id
, origin
, &data_out
, &resources_out
));
525 EXPECT_TRUE(resources_out
.empty());
527 // Resources should be purgeable because these are no longer referred.
528 std::set
<int64
> purgeable_ids_out
;
529 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
530 database
->GetPurgeableResourceIds(&purgeable_ids_out
));
531 EXPECT_EQ(2u, purgeable_ids_out
.size());
532 EXPECT_TRUE(ContainsKey(purgeable_ids_out
, resources
[0].resource_id
));
533 EXPECT_TRUE(ContainsKey(purgeable_ids_out
, resources
[1].resource_id
));
536 TEST(ServiceWorkerDatabaseTest
, DeleteNonExistentRegistration
) {
537 scoped_ptr
<ServiceWorkerDatabase
> database(CreateDatabaseInMemory());
539 GURL
origin("http://example.com");
540 RegistrationData data
;
541 data
.registration_id
= 100;
542 data
.scope
= URL(origin
, "/foo");
543 data
.script
= URL(origin
, "/script.js");
544 data
.version_id
= 200;
546 std::vector
<Resource
> resources
;
547 resources
.push_back(CreateResource(1, URL(origin
, "/resource1")));
548 resources
.push_back(CreateResource(2, URL(origin
, "/resource2")));
550 const int64 kNonExistentRegistrationId
= 999;
551 const int64 kArbitraryVersionId
= 222; // Used as a dummy initial value
553 int64 deleted_version_id
= kArbitraryVersionId
;
554 std::vector
<int64
> newly_purgeable_resources
;
556 ServiceWorkerDatabase::STATUS_OK
,
557 database
->WriteRegistration(
558 data
, resources
, &deleted_version_id
, &newly_purgeable_resources
));
559 EXPECT_EQ(kInvalidServiceWorkerVersionId
, deleted_version_id
);
560 EXPECT_TRUE(newly_purgeable_resources
.empty());
562 // Delete from an origin that has a registration.
563 deleted_version_id
= kArbitraryVersionId
;
564 newly_purgeable_resources
.clear();
565 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
566 database
->DeleteRegistration(kNonExistentRegistrationId
,
569 &newly_purgeable_resources
));
570 EXPECT_EQ(kInvalidServiceWorkerVersionId
, deleted_version_id
);
571 EXPECT_TRUE(newly_purgeable_resources
.empty());
573 // Delete from an origin that has no registration.
574 deleted_version_id
= kArbitraryVersionId
;
575 newly_purgeable_resources
.clear();
576 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
577 database
->DeleteRegistration(kNonExistentRegistrationId
,
578 GURL("http://example.net"),
580 &newly_purgeable_resources
));
581 EXPECT_EQ(kInvalidServiceWorkerVersionId
, deleted_version_id
);
582 EXPECT_TRUE(newly_purgeable_resources
.empty());
585 TEST(ServiceWorkerDatabaseTest
, Registration_Overwrite
) {
586 scoped_ptr
<ServiceWorkerDatabase
> database(CreateDatabaseInMemory());
588 GURL
origin("http://example.com");
589 RegistrationData data
;
590 data
.registration_id
= 100;
591 data
.scope
= URL(origin
, "/foo");
592 data
.script
= URL(origin
, "/script.js");
593 data
.version_id
= 200;
595 std::vector
<Resource
> resources1
;
596 resources1
.push_back(CreateResource(1, URL(origin
, "/resource1")));
597 resources1
.push_back(CreateResource(2, URL(origin
, "/resource2")));
599 int64 deleted_version_id
= 222; // Dummy inital value
600 std::vector
<int64
> newly_purgeable_resources
;
603 ServiceWorkerDatabase::STATUS_OK
,
604 database
->WriteRegistration(
605 data
, resources1
, &deleted_version_id
, &newly_purgeable_resources
));
606 EXPECT_EQ(kInvalidServiceWorkerVersionId
, deleted_version_id
);
607 EXPECT_TRUE(newly_purgeable_resources
.empty());
609 // Make sure that the registration and resource records are stored.
610 RegistrationData data_out
;
611 std::vector
<Resource
> resources_out
;
612 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
, database
->ReadRegistration(
613 data
.registration_id
, origin
, &data_out
, &resources_out
));
614 VerifyRegistrationData(data
, data_out
);
615 VerifyResourceRecords(resources1
, resources_out
);
617 // Update the registration.
618 RegistrationData updated_data
= data
;
619 updated_data
.version_id
= data
.version_id
+ 1;
620 std::vector
<Resource
> resources2
;
621 resources2
.push_back(CreateResource(3, URL(origin
, "/resource3")));
622 resources2
.push_back(CreateResource(4, URL(origin
, "/resource4")));
624 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
625 database
->WriteRegistration(updated_data
,
628 &newly_purgeable_resources
));
629 EXPECT_EQ(data
.version_id
, deleted_version_id
);
630 ASSERT_EQ(resources1
.size(), newly_purgeable_resources
.size());
631 for (size_t i
= 0; i
< resources1
.size(); ++i
)
632 EXPECT_EQ(newly_purgeable_resources
[i
], resources1
[i
].resource_id
);
634 // Make sure that |updated_data| is stored and resources referred from |data|
635 // is moved to the purgeable list.
636 resources_out
.clear();
637 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
, database
->ReadRegistration(
638 updated_data
.registration_id
, origin
, &data_out
, &resources_out
));
639 VerifyRegistrationData(updated_data
, data_out
);
640 VerifyResourceRecords(resources2
, resources_out
);
642 std::set
<int64
> purgeable_ids_out
;
643 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
644 database
->GetPurgeableResourceIds(&purgeable_ids_out
));
645 EXPECT_EQ(2u, purgeable_ids_out
.size());
646 EXPECT_TRUE(ContainsKey(purgeable_ids_out
, resources1
[0].resource_id
));
647 EXPECT_TRUE(ContainsKey(purgeable_ids_out
, resources1
[1].resource_id
));
650 TEST(ServiceWorkerDatabaseTest
, Registration_Multiple
) {
651 scoped_ptr
<ServiceWorkerDatabase
> database(CreateDatabaseInMemory());
652 GURL
origin("http://example.com");
654 int64 deleted_version_id
;
655 std::vector
<int64
> newly_purgeable_resources
;
657 // Add registration1.
658 RegistrationData data1
;
659 data1
.registration_id
= 100;
660 data1
.scope
= URL(origin
, "/foo");
661 data1
.script
= URL(origin
, "/script1.js");
662 data1
.version_id
= 200;
664 std::vector
<Resource
> resources1
;
665 resources1
.push_back(CreateResource(1, URL(origin
, "/resource1")));
666 resources1
.push_back(CreateResource(2, URL(origin
, "/resource2")));
668 ServiceWorkerDatabase::STATUS_OK
,
669 database
->WriteRegistration(
670 data1
, resources1
, &deleted_version_id
, &newly_purgeable_resources
));
672 // Add registration2.
673 RegistrationData data2
;
674 data2
.registration_id
= 101;
675 data2
.scope
= URL(origin
, "/bar");
676 data2
.script
= URL(origin
, "/script2.js");
677 data2
.version_id
= 201;
679 std::vector
<Resource
> resources2
;
680 resources2
.push_back(CreateResource(3, URL(origin
, "/resource3")));
681 resources2
.push_back(CreateResource(4, URL(origin
, "/resource4")));
683 ServiceWorkerDatabase::STATUS_OK
,
684 database
->WriteRegistration(
685 data2
, resources2
, &deleted_version_id
, &newly_purgeable_resources
));
687 // Make sure that registration1 is stored.
688 RegistrationData data_out
;
689 std::vector
<Resource
> resources_out
;
690 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
, database
->ReadRegistration(
691 data1
.registration_id
, origin
, &data_out
, &resources_out
));
692 VerifyRegistrationData(data1
, data_out
);
693 VerifyResourceRecords(resources1
, resources_out
);
695 // Make sure that registration2 is also stored.
696 resources_out
.clear();
697 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
, database
->ReadRegistration(
698 data2
.registration_id
, origin
, &data_out
, &resources_out
));
699 VerifyRegistrationData(data2
, data_out
);
700 VerifyResourceRecords(resources2
, resources_out
);
702 std::set
<int64
> purgeable_ids_out
;
703 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
704 database
->GetPurgeableResourceIds(&purgeable_ids_out
));
705 EXPECT_TRUE(purgeable_ids_out
.empty());
707 // Delete registration1.
709 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
710 database
->DeleteRegistration(data1
.registration_id
,
713 &newly_purgeable_resources
));
715 // Make sure that registration1 is gone.
716 resources_out
.clear();
717 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND
,
718 database
->ReadRegistration(
719 data1
.registration_id
, origin
, &data_out
, &resources_out
));
720 EXPECT_TRUE(resources_out
.empty());
722 purgeable_ids_out
.clear();
723 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
724 database
->GetPurgeableResourceIds(&purgeable_ids_out
));
725 EXPECT_EQ(2u, purgeable_ids_out
.size());
726 EXPECT_TRUE(ContainsKey(purgeable_ids_out
, resources1
[0].resource_id
));
727 EXPECT_TRUE(ContainsKey(purgeable_ids_out
, resources1
[1].resource_id
));
729 // Make sure that registration2 is still alive.
730 resources_out
.clear();
731 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
, database
->ReadRegistration(
732 data2
.registration_id
, origin
, &data_out
, &resources_out
));
733 VerifyRegistrationData(data2
, data_out
);
734 VerifyResourceRecords(resources2
, resources_out
);
737 TEST(ServiceWorkerDatabaseTest
, UpdateVersionToActive
) {
738 scoped_ptr
<ServiceWorkerDatabase
> database(CreateDatabaseInMemory());
739 GURL
origin("http://example.com");
741 int64 deleted_version_id
;
742 std::vector
<int64
> newly_purgeable_resources
;
744 // Should be false because a registration does not exist.
745 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND
,
746 database
->UpdateVersionToActive(0, origin
));
748 // Add a registration.
749 RegistrationData data
;
750 data
.registration_id
= 100;
751 data
.scope
= URL(origin
, "/foo");
752 data
.script
= URL(origin
, "/script.js");
753 data
.version_id
= 200;
754 data
.is_active
= false;
755 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
756 database
->WriteRegistration(data
,
757 std::vector
<Resource
>(),
759 &newly_purgeable_resources
));
761 // Make sure that the registration is stored.
762 RegistrationData data_out
;
763 std::vector
<Resource
> resources_out
;
764 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
765 database
->ReadRegistration(
766 data
.registration_id
, origin
, &data_out
, &resources_out
));
767 VerifyRegistrationData(data
, data_out
);
768 EXPECT_TRUE(resources_out
.empty());
770 // Activate the registration.
771 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
772 database
->UpdateVersionToActive(data
.registration_id
, origin
));
774 // Make sure that the registration is activated.
775 resources_out
.clear();
776 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
777 database
->ReadRegistration(
778 data
.registration_id
, origin
, &data_out
, &resources_out
));
779 RegistrationData expected_data
= data
;
780 expected_data
.is_active
= true;
781 VerifyRegistrationData(expected_data
, data_out
);
782 EXPECT_TRUE(resources_out
.empty());
784 // Delete the registration.
786 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
787 database
->DeleteRegistration(data
.registration_id
,
790 &newly_purgeable_resources
));
792 // Should be false because the registration is gone.
793 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND
,
794 database
->UpdateVersionToActive(data
.registration_id
, origin
));
797 TEST(ServiceWorkerDatabaseTest
, UpdateLastCheckTime
) {
798 scoped_ptr
<ServiceWorkerDatabase
> database(CreateDatabaseInMemory());
799 GURL
origin("http://example.com");
800 int64 deleted_version_id
;
801 std::vector
<int64
> newly_purgeable_resources
;
803 // Should be false because a registration does not exist.
804 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND
,
805 database
->UpdateLastCheckTime(0, origin
, base::Time::Now()));
807 // Add a registration.
808 RegistrationData data
;
809 data
.registration_id
= 100;
810 data
.scope
= URL(origin
, "/foo");
811 data
.script
= URL(origin
, "/script.js");
812 data
.version_id
= 200;
813 data
.last_update_check
= base::Time::Now();
814 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
815 database
->WriteRegistration(data
,
816 std::vector
<Resource
>(),
818 &newly_purgeable_resources
));
820 // Make sure that the registration is stored.
821 RegistrationData data_out
;
822 std::vector
<Resource
> resources_out
;
823 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
824 database
->ReadRegistration(
825 data
.registration_id
, origin
, &data_out
, &resources_out
));
826 VerifyRegistrationData(data
, data_out
);
827 EXPECT_TRUE(resources_out
.empty());
829 // Update the last check time.
830 base::Time updated_time
= base::Time::Now();
831 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
832 database
->UpdateLastCheckTime(
833 data
.registration_id
, origin
, updated_time
));
835 // Make sure that the registration is updated.
836 resources_out
.clear();
837 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
838 database
->ReadRegistration(
839 data
.registration_id
, origin
, &data_out
, &resources_out
));
840 RegistrationData expected_data
= data
;
841 expected_data
.last_update_check
= updated_time
;
842 VerifyRegistrationData(expected_data
, data_out
);
843 EXPECT_TRUE(resources_out
.empty());
845 // Delete the registration.
847 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
848 database
->DeleteRegistration(data
.registration_id
,
851 &newly_purgeable_resources
));
853 // Should be false because the registration is gone.
854 EXPECT_EQ(ServiceWorkerDatabase::STATUS_ERROR_NOT_FOUND
,
855 database
->UpdateLastCheckTime(
856 data
.registration_id
, origin
, base::Time::Now()));
859 TEST(ServiceWorkerDatabaseTest
, UncommittedResourceIds
) {
860 scoped_ptr
<ServiceWorkerDatabase
> database(CreateDatabaseInMemory());
863 std::set
<int64
> ids1
;
867 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
868 database
->WriteUncommittedResourceIds(ids1
));
870 std::set
<int64
> ids_out
;
871 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
872 database
->GetUncommittedResourceIds(&ids_out
));
873 EXPECT_EQ(ids1
, ids_out
);
876 std::set
<int64
> ids2
;
879 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
880 database
->WriteUncommittedResourceIds(ids2
));
883 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
884 database
->GetUncommittedResourceIds(&ids_out
));
885 std::set
<int64
> expected
= base::STLSetUnion
<std::set
<int64
> >(ids1
, ids2
);
886 EXPECT_EQ(expected
, ids_out
);
889 std::set
<int64
> ids3
;
892 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
893 database
->ClearUncommittedResourceIds(ids3
));
896 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
897 database
->GetUncommittedResourceIds(&ids_out
));
898 expected
= base::STLSetDifference
<std::set
<int64
> >(expected
, ids3
);
899 EXPECT_EQ(expected
, ids_out
);
902 TEST(ServiceWorkerDatabaseTest
, PurgeableResourceIds
) {
903 scoped_ptr
<ServiceWorkerDatabase
> database(CreateDatabaseInMemory());
906 std::set
<int64
> ids1
;
910 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
911 database
->WritePurgeableResourceIds(ids1
));
913 std::set
<int64
> ids_out
;
914 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
915 database
->GetPurgeableResourceIds(&ids_out
));
916 EXPECT_EQ(ids1
, ids_out
);
919 std::set
<int64
> ids2
;
922 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
923 database
->WritePurgeableResourceIds(ids2
));
926 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
927 database
->GetPurgeableResourceIds(&ids_out
));
928 std::set
<int64
> expected
= base::STLSetUnion
<std::set
<int64
> >(ids1
, ids2
);
929 EXPECT_EQ(expected
, ids_out
);
932 std::set
<int64
> ids3
;
935 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
936 database
->ClearPurgeableResourceIds(ids3
));
939 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
940 database
->GetPurgeableResourceIds(&ids_out
));
941 expected
= base::STLSetDifference
<std::set
<int64
> >(expected
, ids3
);
942 EXPECT_EQ(expected
, ids_out
);
945 TEST(ServiceWorkerDatabaseTest
, DeleteAllDataForOrigin
) {
946 scoped_ptr
<ServiceWorkerDatabase
> database(CreateDatabaseInMemory());
947 int64 deleted_version_id
;
948 std::vector
<int64
> newly_purgeable_resources
;
950 // Data associated with |origin1| will be removed.
951 GURL
origin1("http://example.com");
952 GURL
origin2("http://example.org");
954 // |origin1| has two registrations.
955 RegistrationData data1
;
956 data1
.registration_id
= 10;
957 data1
.scope
= URL(origin1
, "/foo");
958 data1
.script
= URL(origin1
, "/script1.js");
959 data1
.version_id
= 100;
961 std::vector
<Resource
> resources1
;
962 resources1
.push_back(CreateResource(1, URL(origin1
, "/resource1")));
963 resources1
.push_back(CreateResource(2, URL(origin1
, "/resource2")));
965 ServiceWorkerDatabase::STATUS_OK
,
966 database
->WriteRegistration(
967 data1
, resources1
, &deleted_version_id
, &newly_purgeable_resources
));
969 RegistrationData data2
;
970 data2
.registration_id
= 11;
971 data2
.scope
= URL(origin1
, "/bar");
972 data2
.script
= URL(origin1
, "/script2.js");
973 data2
.version_id
= 101;
975 std::vector
<Resource
> resources2
;
976 resources2
.push_back(CreateResource(3, URL(origin1
, "/resource3")));
977 resources2
.push_back(CreateResource(4, URL(origin1
, "/resource4")));
979 ServiceWorkerDatabase::STATUS_OK
,
980 database
->WriteRegistration(
981 data2
, resources2
, &deleted_version_id
, &newly_purgeable_resources
));
983 // |origin2| has one registration.
984 RegistrationData data3
;
985 data3
.registration_id
= 12;
986 data3
.scope
= URL(origin2
, "/hoge");
987 data3
.script
= URL(origin2
, "/script3.js");
988 data3
.version_id
= 102;
990 std::vector
<Resource
> resources3
;
991 resources3
.push_back(CreateResource(5, URL(origin2
, "/resource5")));
992 resources3
.push_back(CreateResource(6, URL(origin2
, "/resource6")));
994 ServiceWorkerDatabase::STATUS_OK
,
995 database
->WriteRegistration(
996 data3
, resources3
, &deleted_version_id
, &newly_purgeable_resources
));
998 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
999 database
->DeleteAllDataForOrigin(origin1
,
1000 &newly_purgeable_resources
));
1002 // |origin1| should be removed from the unique origin list.
1003 std::set
<GURL
> unique_origins
;
1004 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1005 database
->GetOriginsWithRegistrations(&unique_origins
));
1006 EXPECT_EQ(1u, unique_origins
.size());
1007 EXPECT_TRUE(ContainsKey(unique_origins
, origin2
));
1009 // The registrations for |origin1| should be removed.
1010 std::vector
<RegistrationData
> registrations
;
1011 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1012 database
->GetRegistrationsForOrigin(origin1
, ®istrations
));
1013 EXPECT_TRUE(registrations
.empty());
1015 // The registration for |origin2| should not be removed.
1016 RegistrationData data_out
;
1017 std::vector
<Resource
> resources_out
;
1018 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
, database
->ReadRegistration(
1019 data3
.registration_id
, origin2
, &data_out
, &resources_out
));
1020 VerifyRegistrationData(data3
, data_out
);
1021 VerifyResourceRecords(resources3
, resources_out
);
1023 // The resources associated with |origin1| should be purgeable.
1024 std::set
<int64
> purgeable_ids_out
;
1025 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1026 database
->GetPurgeableResourceIds(&purgeable_ids_out
));
1027 EXPECT_EQ(4u, purgeable_ids_out
.size());
1028 EXPECT_TRUE(ContainsKey(purgeable_ids_out
, 1));
1029 EXPECT_TRUE(ContainsKey(purgeable_ids_out
, 2));
1030 EXPECT_TRUE(ContainsKey(purgeable_ids_out
, 3));
1031 EXPECT_TRUE(ContainsKey(purgeable_ids_out
, 4));
1034 TEST(ServiceWorkerDatabaseTest
, DestroyDatabase
) {
1035 base::ScopedTempDir database_dir
;
1036 ASSERT_TRUE(database_dir
.CreateUniqueTempDir());
1037 scoped_ptr
<ServiceWorkerDatabase
> database(
1038 CreateDatabase(database_dir
.path()));
1040 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
, database
->LazyOpen(true));
1041 ASSERT_TRUE(base::DirectoryExists(database_dir
.path()));
1043 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
, database
->DestroyDatabase());
1044 ASSERT_FALSE(base::DirectoryExists(database_dir
.path()));
1047 } // namespace content