[content shell] implement testRunner.overridePreference
[chromium-blink-merge.git] / webkit / appcache / appcache_database_unittest.cc
blobd84d451870529467e4c614464250d18d9949c456
1 // Copyright (c) 2012 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 "testing/gtest/include/gtest/gtest.h"
7 #include "base/file_util.h"
8 #include "base/files/scoped_temp_dir.h"
9 #include "base/stringprintf.h"
10 #include "sql/connection.h"
11 #include "sql/meta_table.h"
12 #include "sql/statement.h"
13 #include "sql/transaction.h"
14 #include "webkit/appcache/appcache_database.h"
15 #include "webkit/appcache/appcache_entry.h"
17 namespace {
19 const base::Time kZeroTime;
21 class TestErrorDelegate : public sql::ErrorDelegate {
22 public:
23 TestErrorDelegate() {}
24 virtual ~TestErrorDelegate() {}
26 virtual int OnError(int error,
27 sql::Connection* connection,
28 sql::Statement* stmt) OVERRIDE {
29 return error;
32 private:
33 DISALLOW_COPY_AND_ASSIGN(TestErrorDelegate);
36 } // namespace
38 namespace appcache {
40 class AppCacheDatabaseTest {};
42 TEST(AppCacheDatabaseTest, LazyOpen) {
43 // Use an empty file path to use an in-memory sqlite database.
44 const FilePath kEmptyPath;
45 AppCacheDatabase db(kEmptyPath);
47 EXPECT_FALSE(db.LazyOpen(false));
48 EXPECT_TRUE(db.LazyOpen(true));
50 int64 group_id, cache_id, response_id, deleteable_response_rowid;
51 group_id = cache_id = response_id = deleteable_response_rowid = 0;
52 EXPECT_TRUE(db.FindLastStorageIds(&group_id, &cache_id, &response_id,
53 &deleteable_response_rowid));
54 EXPECT_EQ(0, group_id);
55 EXPECT_EQ(0, cache_id);
56 EXPECT_EQ(0, response_id);
57 EXPECT_EQ(0, deleteable_response_rowid);
59 std::set<GURL> origins;
60 EXPECT_TRUE(db.FindOriginsWithGroups(&origins));
61 EXPECT_TRUE(origins.empty());
64 TEST(AppCacheDatabaseTest, ReCreate) {
65 // Real files on disk for this test.
66 base::ScopedTempDir temp_dir;
67 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
68 const FilePath kDbFile = temp_dir.path().AppendASCII("appcache.db");
69 const FilePath kNestedDir = temp_dir.path().AppendASCII("nested");
70 const FilePath kOtherFile = kNestedDir.AppendASCII("other_file");
71 EXPECT_TRUE(file_util::CreateDirectory(kNestedDir));
72 EXPECT_EQ(3, file_util::WriteFile(kOtherFile, "foo", 3));
74 AppCacheDatabase db(kDbFile);
75 EXPECT_FALSE(db.LazyOpen(false));
76 EXPECT_TRUE(db.LazyOpen(true));
78 EXPECT_TRUE(file_util::PathExists(kDbFile));
79 EXPECT_TRUE(file_util::DirectoryExists(kNestedDir));
80 EXPECT_TRUE(file_util::PathExists(kOtherFile));
82 EXPECT_TRUE(db.DeleteExistingAndCreateNewDatabase());
84 EXPECT_TRUE(file_util::PathExists(kDbFile));
85 EXPECT_FALSE(file_util::DirectoryExists(kNestedDir));
86 EXPECT_FALSE(file_util::PathExists(kOtherFile));
89 TEST(AppCacheDatabaseTest, EntryRecords) {
90 const FilePath kEmptyPath;
91 AppCacheDatabase db(kEmptyPath);
92 EXPECT_TRUE(db.LazyOpen(true));
94 // Set an error delegate that will make all operations return false on error.
95 db.db_->set_error_delegate(new TestErrorDelegate());
97 AppCacheDatabase::EntryRecord entry;
99 entry.cache_id = 1;
100 entry.url = GURL("http://blah/1");
101 entry.flags = AppCacheEntry::MASTER;
102 entry.response_id = 1;
103 entry.response_size = 100;
104 EXPECT_TRUE(db.InsertEntry(&entry));
105 EXPECT_FALSE(db.InsertEntry(&entry));
107 entry.cache_id = 2;
108 entry.url = GURL("http://blah/2");
109 entry.flags = AppCacheEntry::EXPLICIT;
110 entry.response_id = 2;
111 entry.response_size = 200;
112 EXPECT_TRUE(db.InsertEntry(&entry));
114 entry.cache_id = 2;
115 entry.url = GURL("http://blah/3");
116 entry.flags = AppCacheEntry::MANIFEST;
117 entry.response_id = 3;
118 entry.response_size = 300;
119 EXPECT_TRUE(db.InsertEntry(&entry));
121 std::vector<AppCacheDatabase::EntryRecord> found;
123 EXPECT_TRUE(db.FindEntriesForCache(1, &found));
124 EXPECT_EQ(1U, found.size());
125 EXPECT_EQ(1, found[0].cache_id);
126 EXPECT_EQ(GURL("http://blah/1"), found[0].url);
127 EXPECT_EQ(AppCacheEntry::MASTER, found[0].flags);
128 EXPECT_EQ(1, found[0].response_id);
129 EXPECT_EQ(100, found[0].response_size);
130 found.clear();
132 EXPECT_TRUE(db.AddEntryFlags(GURL("http://blah/1"), 1,
133 AppCacheEntry::FOREIGN));
134 EXPECT_TRUE(db.FindEntriesForCache(1, &found));
135 EXPECT_EQ(1U, found.size());
136 EXPECT_EQ(AppCacheEntry::MASTER | AppCacheEntry::FOREIGN, found[0].flags);
137 found.clear();
139 EXPECT_TRUE(db.FindEntriesForCache(2, &found));
140 EXPECT_EQ(2U, found.size());
141 EXPECT_EQ(2, found[0].cache_id);
142 EXPECT_EQ(GURL("http://blah/2"), found[0].url);
143 EXPECT_EQ(AppCacheEntry::EXPLICIT, found[0].flags);
144 EXPECT_EQ(2, found[0].response_id);
145 EXPECT_EQ(200, found[0].response_size);
146 EXPECT_EQ(2, found[1].cache_id);
147 EXPECT_EQ(GURL("http://blah/3"), found[1].url);
148 EXPECT_EQ(AppCacheEntry::MANIFEST, found[1].flags);
149 EXPECT_EQ(3, found[1].response_id);
150 EXPECT_EQ(300, found[1].response_size);
151 found.clear();
153 EXPECT_TRUE(db.DeleteEntriesForCache(2));
154 EXPECT_TRUE(db.FindEntriesForCache(2, &found));
155 EXPECT_TRUE(found.empty());
156 found.clear();
158 EXPECT_TRUE(db.DeleteEntriesForCache(1));
159 EXPECT_FALSE(db.AddEntryFlags(GURL("http://blah/1"), 1,
160 AppCacheEntry::FOREIGN));
163 TEST(AppCacheDatabaseTest, CacheRecords) {
164 const FilePath kEmptyPath;
165 AppCacheDatabase db(kEmptyPath);
166 EXPECT_TRUE(db.LazyOpen(true));
168 db.db_->set_error_delegate(new TestErrorDelegate());
170 const AppCacheDatabase::CacheRecord kZeroRecord;
171 AppCacheDatabase::CacheRecord record;
172 EXPECT_FALSE(db.FindCache(1, &record));
174 record.cache_id = 1;
175 record.group_id = 1;
176 record.online_wildcard = true;
177 record.update_time = kZeroTime;
178 record.cache_size = 100;
179 EXPECT_TRUE(db.InsertCache(&record));
180 EXPECT_FALSE(db.InsertCache(&record));
182 record = kZeroRecord;
183 EXPECT_TRUE(db.FindCache(1, &record));
184 EXPECT_EQ(1, record.cache_id);
185 EXPECT_EQ(1, record.group_id);
186 EXPECT_TRUE(record.online_wildcard);
187 EXPECT_TRUE(kZeroTime == record.update_time);
188 EXPECT_EQ(100, record.cache_size);
190 record = kZeroRecord;
191 EXPECT_TRUE(db.FindCacheForGroup(1, &record));
192 EXPECT_EQ(1, record.cache_id);
193 EXPECT_EQ(1, record.group_id);
194 EXPECT_TRUE(record.online_wildcard);
195 EXPECT_TRUE(kZeroTime == record.update_time);
196 EXPECT_EQ(100, record.cache_size);
198 EXPECT_TRUE(db.DeleteCache(1));
199 EXPECT_FALSE(db.FindCache(1, &record));
200 EXPECT_FALSE(db.FindCacheForGroup(1, &record));
202 EXPECT_TRUE(db.DeleteCache(1));
205 TEST(AppCacheDatabaseTest, GroupRecords) {
206 const FilePath kEmptyPath;
207 AppCacheDatabase db(kEmptyPath);
208 EXPECT_TRUE(db.LazyOpen(true));
210 db.db_->set_error_delegate(new TestErrorDelegate());
212 const GURL kManifestUrl("http://blah/manifest");
213 const GURL kOrigin(kManifestUrl.GetOrigin());
214 const base::Time kLastAccessTime = base::Time::Now();
215 const base::Time kCreationTime =
216 kLastAccessTime - base::TimeDelta::FromDays(7);
218 const AppCacheDatabase::GroupRecord kZeroRecord;
219 AppCacheDatabase::GroupRecord record;
220 std::vector<AppCacheDatabase::GroupRecord> records;
222 // Behavior with an empty table
223 EXPECT_FALSE(db.FindGroup(1, &record));
224 EXPECT_FALSE(db.FindGroupForManifestUrl(kManifestUrl, &record));
225 EXPECT_TRUE(db.DeleteGroup(1));
226 EXPECT_TRUE(db.FindGroupsForOrigin(kOrigin, &records));
227 EXPECT_TRUE(records.empty());
228 EXPECT_FALSE(db.FindGroupForCache(1, &record));
230 record.group_id = 1;
231 record.manifest_url = kManifestUrl;
232 record.origin = kOrigin;
233 record.last_access_time = kLastAccessTime;
234 record.creation_time = kCreationTime;
235 EXPECT_TRUE(db.InsertGroup(&record));
236 EXPECT_FALSE(db.InsertGroup(&record));
238 record.group_id = 2;
239 EXPECT_FALSE(db.InsertGroup(&record));
241 record = kZeroRecord;
242 EXPECT_TRUE(db.FindGroup(1, &record));
243 EXPECT_EQ(1, record.group_id);
244 EXPECT_EQ(kManifestUrl, record.manifest_url);
245 EXPECT_EQ(kOrigin, record.origin);
246 EXPECT_EQ(kCreationTime.ToInternalValue(),
247 record.creation_time.ToInternalValue());
248 EXPECT_EQ(kLastAccessTime.ToInternalValue(),
249 record.last_access_time.ToInternalValue());
251 record = kZeroRecord;
252 EXPECT_TRUE(db.FindGroupForManifestUrl(kManifestUrl, &record));
253 EXPECT_EQ(1, record.group_id);
254 EXPECT_EQ(kManifestUrl, record.manifest_url);
255 EXPECT_EQ(kOrigin, record.origin);
256 EXPECT_EQ(kCreationTime.ToInternalValue(),
257 record.creation_time.ToInternalValue());
258 EXPECT_EQ(kLastAccessTime.ToInternalValue(),
259 record.last_access_time.ToInternalValue());
261 record.group_id = 2;
262 record.manifest_url = kOrigin;
263 record.origin = kOrigin;
264 record.last_access_time = kLastAccessTime;
265 record.creation_time = kCreationTime;
266 EXPECT_TRUE(db.InsertGroup(&record));
268 record = kZeroRecord;
269 EXPECT_TRUE(db.FindGroupForManifestUrl(kOrigin, &record));
270 EXPECT_EQ(2, record.group_id);
271 EXPECT_EQ(kOrigin, record.manifest_url);
272 EXPECT_EQ(kOrigin, record.origin);
273 EXPECT_EQ(kCreationTime.ToInternalValue(),
274 record.creation_time.ToInternalValue());
275 EXPECT_EQ(kLastAccessTime.ToInternalValue(),
276 record.last_access_time.ToInternalValue());
278 EXPECT_TRUE(db.FindGroupsForOrigin(kOrigin, &records));
279 EXPECT_EQ(2U, records.size());
280 EXPECT_EQ(1, records[0].group_id);
281 EXPECT_EQ(kManifestUrl, records[0].manifest_url);
282 EXPECT_EQ(kOrigin, records[0].origin);
283 EXPECT_EQ(2, records[1].group_id);
284 EXPECT_EQ(kOrigin, records[1].manifest_url);
285 EXPECT_EQ(kOrigin, records[1].origin);
287 EXPECT_TRUE(db.DeleteGroup(1));
289 records.clear();
290 EXPECT_TRUE(db.FindGroupsForOrigin(kOrigin, &records));
291 EXPECT_EQ(1U, records.size());
292 EXPECT_EQ(2, records[0].group_id);
293 EXPECT_EQ(kOrigin, records[0].manifest_url);
294 EXPECT_EQ(kOrigin, records[0].origin);
295 EXPECT_EQ(kCreationTime.ToInternalValue(),
296 record.creation_time.ToInternalValue());
297 EXPECT_EQ(kLastAccessTime.ToInternalValue(),
298 record.last_access_time.ToInternalValue());
300 std::set<GURL> origins;
301 EXPECT_TRUE(db.FindOriginsWithGroups(&origins));
302 EXPECT_EQ(1U, origins.size());
303 EXPECT_EQ(kOrigin, *(origins.begin()));
305 const GURL kManifest2("http://blah2/manifest");
306 const GURL kOrigin2(kManifest2.GetOrigin());
307 record.group_id = 1;
308 record.manifest_url = kManifest2;
309 record.origin = kOrigin2;
310 EXPECT_TRUE(db.InsertGroup(&record));
312 origins.clear();
313 EXPECT_TRUE(db.FindOriginsWithGroups(&origins));
314 EXPECT_EQ(2U, origins.size());
315 EXPECT_TRUE(origins.end() != origins.find(kOrigin));
316 EXPECT_TRUE(origins.end() != origins.find(kOrigin2));
318 AppCacheDatabase::CacheRecord cache_record;
319 cache_record.cache_id = 1;
320 cache_record.group_id = 1;
321 cache_record.online_wildcard = true;
322 cache_record.update_time = kZeroTime;
323 EXPECT_TRUE(db.InsertCache(&cache_record));
325 record = kZeroRecord;
326 EXPECT_TRUE(db.FindGroupForCache(1, &record));
327 EXPECT_EQ(1, record.group_id);
328 EXPECT_EQ(kManifest2, record.manifest_url);
329 EXPECT_EQ(kOrigin2, record.origin);
332 TEST(AppCacheDatabaseTest, NamespaceRecords) {
333 const FilePath kEmptyPath;
334 AppCacheDatabase db(kEmptyPath);
335 EXPECT_TRUE(db.LazyOpen(true));
337 db.db_->set_error_delegate(new TestErrorDelegate());
339 const GURL kFooNameSpace1("http://foo/namespace1");
340 const GURL kFooNameSpace2("http://foo/namespace2");
341 const GURL kFooFallbackEntry("http://foo/entry");
342 const GURL kFooOrigin(kFooNameSpace1.GetOrigin());
343 const GURL kBarNameSpace1("http://bar/namespace1");
344 const GURL kBarNameSpace2("http://bar/namespace2");
345 const GURL kBarFallbackEntry("http://bar/entry");
346 const GURL kBarOrigin(kBarNameSpace1.GetOrigin());
348 const AppCacheDatabase::NamespaceRecord kZeroRecord;
349 AppCacheDatabase::NamespaceRecord record;
350 std::vector<AppCacheDatabase::NamespaceRecord> intercepts;
351 std::vector<AppCacheDatabase::NamespaceRecord> fallbacks;
353 // Behavior with an empty table
354 EXPECT_TRUE(db.FindNamespacesForCache(1, &intercepts, &fallbacks));
355 EXPECT_TRUE(fallbacks.empty());
356 EXPECT_TRUE(db.FindNamespacesForOrigin(kFooOrigin, &intercepts, &fallbacks));
357 EXPECT_TRUE(fallbacks.empty());
358 EXPECT_TRUE(db.DeleteNamespacesForCache(1));
360 // Two records for two differenent caches in the Foo origin.
361 record.cache_id = 1;
362 record.origin = kFooOrigin;
363 record.namespace_url = kFooNameSpace1;
364 record.target_url = kFooFallbackEntry;
365 EXPECT_TRUE(db.InsertNamespace(&record));
366 EXPECT_FALSE(db.InsertNamespace(&record));
368 record.cache_id = 2;
369 record.origin = kFooOrigin;
370 record.namespace_url = kFooNameSpace2;
371 record.target_url = kFooFallbackEntry;
372 EXPECT_TRUE(db.InsertNamespace(&record));
374 fallbacks.clear();
375 EXPECT_TRUE(db.FindNamespacesForCache(1, &intercepts, &fallbacks));
376 EXPECT_EQ(1U, fallbacks.size());
377 EXPECT_EQ(1, fallbacks[0].cache_id);
378 EXPECT_EQ(kFooOrigin, fallbacks[0].origin);
379 EXPECT_EQ(kFooNameSpace1, fallbacks[0].namespace_url);
380 EXPECT_EQ(kFooFallbackEntry, fallbacks[0].target_url);
382 fallbacks.clear();
383 EXPECT_TRUE(db.FindNamespacesForCache(2, &intercepts, &fallbacks));
384 EXPECT_EQ(1U, fallbacks.size());
385 EXPECT_EQ(2, fallbacks[0].cache_id);
386 EXPECT_EQ(kFooOrigin, fallbacks[0].origin);
387 EXPECT_EQ(kFooNameSpace2, fallbacks[0].namespace_url);
388 EXPECT_EQ(kFooFallbackEntry, fallbacks[0].target_url);
390 fallbacks.clear();
391 EXPECT_TRUE(db.FindNamespacesForOrigin(kFooOrigin, &intercepts, &fallbacks));
392 EXPECT_EQ(2U, fallbacks.size());
393 EXPECT_EQ(1, fallbacks[0].cache_id);
394 EXPECT_EQ(kFooOrigin, fallbacks[0].origin);
395 EXPECT_EQ(kFooNameSpace1, fallbacks[0].namespace_url);
396 EXPECT_EQ(kFooFallbackEntry, fallbacks[0].target_url);
397 EXPECT_EQ(2, fallbacks[1].cache_id);
398 EXPECT_EQ(kFooOrigin, fallbacks[1].origin);
399 EXPECT_EQ(kFooNameSpace2, fallbacks[1].namespace_url);
400 EXPECT_EQ(kFooFallbackEntry, fallbacks[1].target_url);
402 EXPECT_TRUE(db.DeleteNamespacesForCache(1));
403 fallbacks.clear();
404 EXPECT_TRUE(db.FindNamespacesForOrigin(kFooOrigin, &intercepts, &fallbacks));
405 EXPECT_EQ(1U, fallbacks.size());
406 EXPECT_EQ(2, fallbacks[0].cache_id);
407 EXPECT_EQ(kFooOrigin, fallbacks[0].origin);
408 EXPECT_EQ(kFooNameSpace2, fallbacks[0].namespace_url);
409 EXPECT_EQ(kFooFallbackEntry, fallbacks[0].target_url);
411 // Two more records for the same cache in the Bar origin.
412 record.cache_id = 3;
413 record.origin = kBarOrigin;
414 record.namespace_url = kBarNameSpace1;
415 record.target_url = kBarFallbackEntry;
416 EXPECT_TRUE(db.InsertNamespace(&record));
418 record.cache_id = 3;
419 record.origin = kBarOrigin;
420 record.namespace_url = kBarNameSpace2;
421 record.target_url = kBarFallbackEntry;
422 EXPECT_TRUE(db.InsertNamespace(&record));
424 fallbacks.clear();
425 EXPECT_TRUE(db.FindNamespacesForCache(3, &intercepts, &fallbacks));
426 EXPECT_EQ(2U, fallbacks.size());
427 fallbacks.clear();
428 EXPECT_TRUE(db.FindNamespacesForOrigin(kBarOrigin, &intercepts, &fallbacks));
429 EXPECT_EQ(2U, fallbacks.size());
432 TEST(AppCacheDatabaseTest, OnlineWhiteListRecords) {
433 const FilePath kEmptyPath;
434 AppCacheDatabase db(kEmptyPath);
435 EXPECT_TRUE(db.LazyOpen(true));
437 db.db_->set_error_delegate(new TestErrorDelegate());
439 const GURL kFooNameSpace1("http://foo/namespace1");
440 const GURL kFooNameSpace2("http://foo/namespace2");
441 const GURL kBarNameSpace1("http://bar/namespace1");
443 const AppCacheDatabase::OnlineWhiteListRecord kZeroRecord;
444 AppCacheDatabase::OnlineWhiteListRecord record;
445 std::vector<AppCacheDatabase::OnlineWhiteListRecord> records;
447 // Behavior with an empty table
448 EXPECT_TRUE(db.FindOnlineWhiteListForCache(1, &records));
449 EXPECT_TRUE(records.empty());
450 EXPECT_TRUE(db.DeleteOnlineWhiteListForCache(1));
452 record.cache_id = 1;
453 record.namespace_url = kFooNameSpace1;
454 EXPECT_TRUE(db.InsertOnlineWhiteList(&record));
455 record.namespace_url = kFooNameSpace2;
456 EXPECT_TRUE(db.InsertOnlineWhiteList(&record));
457 records.clear();
458 EXPECT_TRUE(db.FindOnlineWhiteListForCache(1, &records));
459 EXPECT_EQ(2U, records.size());
460 EXPECT_EQ(1, records[0].cache_id);
461 EXPECT_EQ(kFooNameSpace1, records[0].namespace_url);
462 EXPECT_EQ(1, records[1].cache_id);
463 EXPECT_EQ(kFooNameSpace2, records[1].namespace_url);
465 record.cache_id = 2;
466 record.namespace_url = kBarNameSpace1;
467 EXPECT_TRUE(db.InsertOnlineWhiteList(&record));
468 records.clear();
469 EXPECT_TRUE(db.FindOnlineWhiteListForCache(2, &records));
470 EXPECT_EQ(1U, records.size());
472 EXPECT_TRUE(db.DeleteOnlineWhiteListForCache(1));
473 records.clear();
474 EXPECT_TRUE(db.FindOnlineWhiteListForCache(1, &records));
475 EXPECT_TRUE(records.empty());
478 TEST(AppCacheDatabaseTest, DeletableResponseIds) {
479 const FilePath kEmptyPath;
480 AppCacheDatabase db(kEmptyPath);
481 EXPECT_TRUE(db.LazyOpen(true));
483 db.db_->set_error_delegate(new TestErrorDelegate());
485 std::vector<int64> ids;
487 EXPECT_TRUE(db.GetDeletableResponseIds(&ids, kint64max, 100));
488 EXPECT_TRUE(ids.empty());
489 ids.push_back(0);
490 EXPECT_TRUE(db.DeleteDeletableResponseIds(ids));
491 EXPECT_TRUE(db.InsertDeletableResponseIds(ids));
493 ids.clear();
494 EXPECT_TRUE(db.GetDeletableResponseIds(&ids, kint64max, 100));
495 EXPECT_EQ(1U, ids.size());
496 EXPECT_EQ(0, ids[0]);
498 int64 unused, deleteable_response_rowid;
499 unused = deleteable_response_rowid = 0;
500 EXPECT_TRUE(db.FindLastStorageIds(&unused, &unused, &unused,
501 &deleteable_response_rowid));
502 EXPECT_EQ(1, deleteable_response_rowid);
505 // Expected to fail due to the duplicate id, 0 is already in the table.
506 ids.clear();
507 ids.push_back(0);
508 ids.push_back(1);
509 EXPECT_FALSE(db.InsertDeletableResponseIds(ids));
511 ids.clear();
512 for (int i = 1; i < 10; ++i)
513 ids.push_back(i);
514 EXPECT_TRUE(db.InsertDeletableResponseIds(ids));
515 EXPECT_TRUE(db.FindLastStorageIds(&unused, &unused, &unused,
516 &deleteable_response_rowid));
517 EXPECT_EQ(10, deleteable_response_rowid);
519 ids.clear();
520 EXPECT_TRUE(db.GetDeletableResponseIds(&ids, kint64max, 100));
521 EXPECT_EQ(10U, ids.size());
522 for (int i = 0; i < 10; ++i)
523 EXPECT_EQ(i, ids[i]);
525 // Ensure the limit is respected.
526 ids.clear();
527 EXPECT_TRUE(db.GetDeletableResponseIds(&ids, kint64max, 5));
528 EXPECT_EQ(5U, ids.size());
529 for (int i = 0; i < static_cast<int>(ids.size()); ++i)
530 EXPECT_EQ(i, ids[i]);
532 // Ensure the max_rowid is respected (the first rowid is 1).
533 ids.clear();
534 EXPECT_TRUE(db.GetDeletableResponseIds(&ids, 5, 100));
535 EXPECT_EQ(5U, ids.size());
536 for (int i = 0; i < static_cast<int>(ids.size()); ++i)
537 EXPECT_EQ(i, ids[i]);
539 // Ensure that we can delete from the table.
540 EXPECT_TRUE(db.DeleteDeletableResponseIds(ids));
541 ids.clear();
542 EXPECT_TRUE(db.GetDeletableResponseIds(&ids, kint64max, 100));
543 EXPECT_EQ(5U, ids.size());
544 for (int i = 0; i < static_cast<int>(ids.size()); ++i)
545 EXPECT_EQ(i + 5, ids[i]);
548 TEST(AppCacheDatabaseTest, OriginUsage) {
549 const GURL kManifestUrl("http://blah/manifest");
550 const GURL kManifestUrl2("http://blah/manifest2");
551 const GURL kOrigin(kManifestUrl.GetOrigin());
552 const GURL kOtherOriginManifestUrl("http://other/manifest");
553 const GURL kOtherOrigin(kOtherOriginManifestUrl.GetOrigin());
555 const FilePath kEmptyPath;
556 AppCacheDatabase db(kEmptyPath);
557 EXPECT_TRUE(db.LazyOpen(true));
559 db.db_->set_error_delegate(new TestErrorDelegate());
561 std::vector<AppCacheDatabase::CacheRecord> cache_records;
562 EXPECT_EQ(0, db.GetOriginUsage(kOrigin));
563 EXPECT_TRUE(db.FindCachesForOrigin(kOrigin, &cache_records));
564 EXPECT_TRUE(cache_records.empty());
566 AppCacheDatabase::GroupRecord group_record;
567 group_record.group_id = 1;
568 group_record.manifest_url = kManifestUrl;
569 group_record.origin = kOrigin;
570 EXPECT_TRUE(db.InsertGroup(&group_record));
571 AppCacheDatabase::CacheRecord cache_record;
572 cache_record.cache_id = 1;
573 cache_record.group_id = 1;
574 cache_record.online_wildcard = true;
575 cache_record.update_time = kZeroTime;
576 cache_record.cache_size = 100;
577 EXPECT_TRUE(db.InsertCache(&cache_record));
579 EXPECT_EQ(100, db.GetOriginUsage(kOrigin));
581 group_record.group_id = 2;
582 group_record.manifest_url = kManifestUrl2;
583 group_record.origin = kOrigin;
584 EXPECT_TRUE(db.InsertGroup(&group_record));
585 cache_record.cache_id = 2;
586 cache_record.group_id = 2;
587 cache_record.online_wildcard = true;
588 cache_record.update_time = kZeroTime;
589 cache_record.cache_size = 1000;
590 EXPECT_TRUE(db.InsertCache(&cache_record));
592 EXPECT_EQ(1100, db.GetOriginUsage(kOrigin));
594 group_record.group_id = 3;
595 group_record.manifest_url = kOtherOriginManifestUrl;
596 group_record.origin = kOtherOrigin;
597 EXPECT_TRUE(db.InsertGroup(&group_record));
598 cache_record.cache_id = 3;
599 cache_record.group_id = 3;
600 cache_record.online_wildcard = true;
601 cache_record.update_time = kZeroTime;
602 cache_record.cache_size = 5000;
603 EXPECT_TRUE(db.InsertCache(&cache_record));
605 EXPECT_EQ(5000, db.GetOriginUsage(kOtherOrigin));
607 EXPECT_TRUE(db.FindCachesForOrigin(kOrigin, &cache_records));
608 EXPECT_EQ(2U, cache_records.size());
609 cache_records.clear();
610 EXPECT_TRUE(db.FindCachesForOrigin(kOtherOrigin, &cache_records));
611 EXPECT_EQ(1U, cache_records.size());
613 std::map<GURL, int64> usage_map;
614 EXPECT_TRUE(db.GetAllOriginUsage(&usage_map));
615 EXPECT_EQ(2U, usage_map.size());
616 EXPECT_EQ(1100, usage_map[kOrigin]);
617 EXPECT_EQ(5000, usage_map[kOtherOrigin]);
620 TEST(AppCacheDatabaseTest, UpgradeSchema3to4) {
621 // Real file on disk for this test.
622 base::ScopedTempDir temp_dir;
623 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
624 const FilePath kDbFile = temp_dir.path().AppendASCII("upgrade.db");
626 const GURL kMockOrigin("http://mockorigin/");
627 const char kNamespaceUrlFormat[] = "namespace%d";
628 const char kTargetUrlFormat[] = "target%d";
629 const int kNumNamespaces = 10;
631 // Create a v3 schema based database containing some fallback records.
633 const int kVersion3 = 3;
634 const char kGroupsTable[] = "Groups";
635 const char kCachesTable[] = "Caches";
636 const char kEntriesTable[] = "Entries";
637 const char kFallbackNameSpacesTable[] = "FallbackNameSpaces";
638 const char kOnlineWhiteListsTable[] = "OnlineWhiteLists";
639 const char kDeletableResponseIdsTable[] = "DeletableResponseIds";
641 const struct {
642 const char* table_name;
643 const char* columns;
644 } kTables3[] = {
645 { kGroupsTable,
646 "(group_id INTEGER PRIMARY KEY,"
647 " origin TEXT,"
648 " manifest_url TEXT,"
649 " creation_time INTEGER,"
650 " last_access_time INTEGER)" },
652 { kCachesTable,
653 "(cache_id INTEGER PRIMARY KEY,"
654 " group_id INTEGER,"
655 " online_wildcard INTEGER CHECK(online_wildcard IN (0, 1)),"
656 " update_time INTEGER,"
657 " cache_size INTEGER)" }, // intentionally not normalized
659 { kEntriesTable,
660 "(cache_id INTEGER,"
661 " url TEXT,"
662 " flags INTEGER,"
663 " response_id INTEGER,"
664 " response_size INTEGER)" },
666 { kFallbackNameSpacesTable,
667 "(cache_id INTEGER,"
668 " origin TEXT," // intentionally not normalized
669 " namespace_url TEXT,"
670 " fallback_entry_url TEXT)" },
672 { kOnlineWhiteListsTable,
673 "(cache_id INTEGER,"
674 " namespace_url TEXT)" },
676 { kDeletableResponseIdsTable,
677 "(response_id INTEGER NOT NULL)" },
680 const struct {
681 const char* index_name;
682 const char* table_name;
683 const char* columns;
684 bool unique;
685 } kIndexes3[] = {
686 { "GroupsOriginIndex",
687 kGroupsTable,
688 "(origin)",
689 false },
691 { "GroupsManifestIndex",
692 kGroupsTable,
693 "(manifest_url)",
694 true },
696 { "CachesGroupIndex",
697 kCachesTable,
698 "(group_id)",
699 false },
701 { "EntriesCacheIndex",
702 kEntriesTable,
703 "(cache_id)",
704 false },
706 { "EntriesCacheAndUrlIndex",
707 kEntriesTable,
708 "(cache_id, url)",
709 true },
711 { "EntriesResponseIdIndex",
712 kEntriesTable,
713 "(response_id)",
714 true },
716 { "FallbackNameSpacesCacheIndex",
717 kFallbackNameSpacesTable,
718 "(cache_id)",
719 false },
721 { "FallbackNameSpacesOriginIndex",
722 kFallbackNameSpacesTable,
723 "(origin)",
724 false },
726 { "FallbackNameSpacesCacheAndUrlIndex",
727 kFallbackNameSpacesTable,
728 "(cache_id, namespace_url)",
729 true },
731 { "OnlineWhiteListCacheIndex",
732 kOnlineWhiteListsTable,
733 "(cache_id)",
734 false },
736 { "DeletableResponsesIdIndex",
737 kDeletableResponseIdsTable,
738 "(response_id)",
739 true },
742 const int kTableCount3 = ARRAYSIZE_UNSAFE(kTables3);
743 const int kIndexCount3 = ARRAYSIZE_UNSAFE(kIndexes3);
745 sql::Connection connection;
746 EXPECT_TRUE(connection.Open(kDbFile));
748 sql::Transaction transaction(&connection);
749 EXPECT_TRUE(transaction.Begin());
751 sql::MetaTable meta_table;
752 EXPECT_TRUE(meta_table.Init(&connection, kVersion3, kVersion3));
754 for (int i = 0; i < kTableCount3; ++i) {
755 std::string sql("CREATE TABLE ");
756 sql += kTables3[i].table_name;
757 sql += kTables3[i].columns;
758 EXPECT_TRUE(connection.Execute(sql.c_str()));
761 for (int i = 0; i < kIndexCount3; ++i) {
762 std::string sql;
763 if (kIndexes3[i].unique)
764 sql += "CREATE UNIQUE INDEX ";
765 else
766 sql += "CREATE INDEX ";
767 sql += kIndexes3[i].index_name;
768 sql += " ON ";
769 sql += kIndexes3[i].table_name;
770 sql += kIndexes3[i].columns;
771 EXPECT_TRUE(connection.Execute(sql.c_str()));
774 const char* kSql =
775 "INSERT INTO FallbackNameSpaces"
776 " (cache_id, origin, namespace_url, fallback_entry_url)"
777 " VALUES (?, ?, ?, ?)";
779 sql::Statement statement;
780 statement.Assign(connection.GetUniqueStatement(kSql));
781 EXPECT_TRUE(statement.is_valid());
782 for (int i = 0; i < kNumNamespaces; ++i) {
783 GURL namespace_url(
784 kMockOrigin.Resolve(base::StringPrintf(kNamespaceUrlFormat, i)));
785 GURL target_url(
786 kMockOrigin.Resolve(base::StringPrintf(kTargetUrlFormat, i)));
787 statement.BindInt64(0, i);
788 statement.BindString(1, kMockOrigin.spec().c_str());
789 statement.BindString(2, namespace_url.spec().c_str());
790 statement.BindString(3, target_url.spec().c_str());
791 ASSERT_TRUE(statement.Run());
792 statement.Reset(true);
795 EXPECT_TRUE(transaction.Commit());
798 // Open that database and verify that it got updated.
799 AppCacheDatabase db(kDbFile);
800 EXPECT_TRUE(db.LazyOpen(true));
802 EXPECT_FALSE(db.db_->DoesTableExist("FallbackNameSpaces"));
803 EXPECT_FALSE(db.db_->DoesIndexExist("FallbackNamesSpacesCacheIndex"));
804 EXPECT_FALSE(db.db_->DoesIndexExist("FallbackNameSpacesOriginIndex"));
805 EXPECT_FALSE(db.db_->DoesIndexExist("FallbackNameSpacesCacheAndUrlIndex"));
807 EXPECT_TRUE(db.db_->DoesTableExist("Namespaces"));
808 EXPECT_TRUE(db.db_->DoesIndexExist("NamespacesCacheIndex"));
809 EXPECT_TRUE(db.db_->DoesIndexExist("NamespacesOriginIndex"));
810 EXPECT_TRUE(db.db_->DoesIndexExist("NamespacesCacheAndUrlIndex"));
812 EXPECT_EQ(4, db.meta_table_->GetVersionNumber());
813 EXPECT_EQ(4, db.meta_table_->GetCompatibleVersionNumber());
815 std::vector<AppCacheDatabase::NamespaceRecord> intercepts;
816 std::vector<AppCacheDatabase::NamespaceRecord> fallbacks;
817 EXPECT_TRUE(db.FindNamespacesForOrigin(kMockOrigin, &intercepts,
818 &fallbacks));
819 EXPECT_TRUE(intercepts.empty());
820 EXPECT_EQ(kNumNamespaces, static_cast<int>(fallbacks.size()));
822 for (int i = 0; i < kNumNamespaces; ++i) {
823 GURL expected_namespace_url(
824 kMockOrigin.Resolve(base::StringPrintf(kNamespaceUrlFormat, i)));
825 GURL expected_target_url(
826 kMockOrigin.Resolve(base::StringPrintf(kTargetUrlFormat, i)));
828 EXPECT_EQ(i, fallbacks[i].cache_id);
829 EXPECT_EQ(FALLBACK_NAMESPACE, fallbacks[i].type);
830 EXPECT_EQ(kMockOrigin, fallbacks[i].origin);
831 EXPECT_EQ(expected_namespace_url, fallbacks[i].namespace_url);
832 EXPECT_EQ(expected_target_url, fallbacks[i].target_url);
836 } // namespace appcache