Dismiss autofill popup on screen orientation change.
[chromium-blink-merge.git] / webkit / browser / appcache / appcache_database_unittest.cc
blobe67a68dafdbb8e6ba2de23688770dd8f08f9dc9d
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 "base/bind.h"
6 #include "base/file_util.h"
7 #include "base/files/scoped_temp_dir.h"
8 #include "base/strings/stringprintf.h"
9 #include "sql/connection.h"
10 #include "sql/meta_table.h"
11 #include "sql/statement.h"
12 #include "sql/test/scoped_error_ignorer.h"
13 #include "sql/transaction.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "third_party/sqlite/sqlite3.h"
16 #include "webkit/browser/appcache/appcache_database.h"
17 #include "webkit/browser/appcache/appcache_entry.h"
19 namespace {
21 const base::Time kZeroTime;
23 } // namespace
25 namespace appcache {
27 class AppCacheDatabaseTest {};
29 TEST(AppCacheDatabaseTest, LazyOpen) {
30 // Use an empty file path to use an in-memory sqlite database.
31 const base::FilePath kEmptyPath;
32 AppCacheDatabase db(kEmptyPath);
34 EXPECT_FALSE(db.LazyOpen(false));
35 EXPECT_TRUE(db.LazyOpen(true));
37 int64 group_id, cache_id, response_id, deleteable_response_rowid;
38 group_id = cache_id = response_id = deleteable_response_rowid = 0;
39 EXPECT_TRUE(db.FindLastStorageIds(&group_id, &cache_id, &response_id,
40 &deleteable_response_rowid));
41 EXPECT_EQ(0, group_id);
42 EXPECT_EQ(0, cache_id);
43 EXPECT_EQ(0, response_id);
44 EXPECT_EQ(0, deleteable_response_rowid);
46 std::set<GURL> origins;
47 EXPECT_TRUE(db.FindOriginsWithGroups(&origins));
48 EXPECT_TRUE(origins.empty());
51 TEST(AppCacheDatabaseTest, ReCreate) {
52 // Real files on disk for this test.
53 base::ScopedTempDir temp_dir;
54 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
55 const base::FilePath kDbFile = temp_dir.path().AppendASCII("appcache.db");
56 const base::FilePath kNestedDir = temp_dir.path().AppendASCII("nested");
57 const base::FilePath kOtherFile = kNestedDir.AppendASCII("other_file");
58 EXPECT_TRUE(file_util::CreateDirectory(kNestedDir));
59 EXPECT_EQ(3, file_util::WriteFile(kOtherFile, "foo", 3));
61 AppCacheDatabase db(kDbFile);
62 EXPECT_FALSE(db.LazyOpen(false));
63 EXPECT_TRUE(db.LazyOpen(true));
65 EXPECT_TRUE(base::PathExists(kDbFile));
66 EXPECT_TRUE(base::DirectoryExists(kNestedDir));
67 EXPECT_TRUE(base::PathExists(kOtherFile));
69 EXPECT_TRUE(db.DeleteExistingAndCreateNewDatabase());
71 EXPECT_TRUE(base::PathExists(kDbFile));
72 EXPECT_FALSE(base::DirectoryExists(kNestedDir));
73 EXPECT_FALSE(base::PathExists(kOtherFile));
76 TEST(AppCacheDatabaseTest, ExperimentalFlags) {
77 const char kExperimentFlagsKey[] = "ExperimentFlags";
78 std::string kInjectedFlags("exp1,exp2");
80 // Real files on disk for this test.
81 base::ScopedTempDir temp_dir;
82 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
83 const base::FilePath kDbFile = temp_dir.path().AppendASCII("appcache.db");
84 const base::FilePath kOtherFile = temp_dir.path().AppendASCII("other_file");
85 EXPECT_EQ(3, file_util::WriteFile(kOtherFile, "foo", 3));
86 EXPECT_TRUE(base::PathExists(kOtherFile));
88 AppCacheDatabase db(kDbFile);
89 EXPECT_TRUE(db.LazyOpen(true));
91 // Inject a non empty flags value, and verify it got there.
92 EXPECT_TRUE(db.meta_table_->SetValue(kExperimentFlagsKey, kInjectedFlags));
93 std::string flags;
94 EXPECT_TRUE(db.meta_table_->GetValue(kExperimentFlagsKey, &flags));
95 EXPECT_EQ(kInjectedFlags, flags);
96 db.CloseConnection();
98 // If flags don't match the expected value, empty string by default,
99 // the database should be recreated and other files should be cleared out.
100 EXPECT_TRUE(db.LazyOpen(false));
101 EXPECT_TRUE(db.meta_table_->GetValue(kExperimentFlagsKey, &flags));
102 EXPECT_TRUE(flags.empty());
103 EXPECT_FALSE(base::PathExists(kOtherFile));
106 TEST(AppCacheDatabaseTest, EntryRecords) {
107 const base::FilePath kEmptyPath;
108 AppCacheDatabase db(kEmptyPath);
109 EXPECT_TRUE(db.LazyOpen(true));
111 sql::ScopedErrorIgnorer ignore_errors;
112 // TODO(shess): Suppressing SQLITE_CONSTRAINT because the code
113 // expects that and handles the resulting error. Consider revising
114 // the code to use INSERT OR IGNORE (which would not throw
115 // SQLITE_CONSTRAINT) and then check ChangeCount() to see if any
116 // changes were made.
117 ignore_errors.IgnoreError(SQLITE_CONSTRAINT);
119 AppCacheDatabase::EntryRecord entry;
121 entry.cache_id = 1;
122 entry.url = GURL("http://blah/1");
123 entry.flags = AppCacheEntry::MASTER;
124 entry.response_id = 1;
125 entry.response_size = 100;
126 EXPECT_TRUE(db.InsertEntry(&entry));
127 EXPECT_FALSE(db.InsertEntry(&entry));
129 entry.cache_id = 2;
130 entry.url = GURL("http://blah/2");
131 entry.flags = AppCacheEntry::EXPLICIT;
132 entry.response_id = 2;
133 entry.response_size = 200;
134 EXPECT_TRUE(db.InsertEntry(&entry));
136 entry.cache_id = 2;
137 entry.url = GURL("http://blah/3");
138 entry.flags = AppCacheEntry::MANIFEST;
139 entry.response_id = 3;
140 entry.response_size = 300;
141 EXPECT_TRUE(db.InsertEntry(&entry));
143 std::vector<AppCacheDatabase::EntryRecord> found;
145 EXPECT_TRUE(db.FindEntriesForCache(1, &found));
146 EXPECT_EQ(1U, found.size());
147 EXPECT_EQ(1, found[0].cache_id);
148 EXPECT_EQ(GURL("http://blah/1"), found[0].url);
149 EXPECT_EQ(AppCacheEntry::MASTER, found[0].flags);
150 EXPECT_EQ(1, found[0].response_id);
151 EXPECT_EQ(100, found[0].response_size);
152 found.clear();
154 EXPECT_TRUE(db.AddEntryFlags(GURL("http://blah/1"), 1,
155 AppCacheEntry::FOREIGN));
156 EXPECT_TRUE(db.FindEntriesForCache(1, &found));
157 EXPECT_EQ(1U, found.size());
158 EXPECT_EQ(AppCacheEntry::MASTER | AppCacheEntry::FOREIGN, found[0].flags);
159 found.clear();
161 EXPECT_TRUE(db.FindEntriesForCache(2, &found));
162 EXPECT_EQ(2U, found.size());
163 EXPECT_EQ(2, found[0].cache_id);
164 EXPECT_EQ(GURL("http://blah/2"), found[0].url);
165 EXPECT_EQ(AppCacheEntry::EXPLICIT, found[0].flags);
166 EXPECT_EQ(2, found[0].response_id);
167 EXPECT_EQ(200, found[0].response_size);
168 EXPECT_EQ(2, found[1].cache_id);
169 EXPECT_EQ(GURL("http://blah/3"), found[1].url);
170 EXPECT_EQ(AppCacheEntry::MANIFEST, found[1].flags);
171 EXPECT_EQ(3, found[1].response_id);
172 EXPECT_EQ(300, found[1].response_size);
173 found.clear();
175 EXPECT_TRUE(db.DeleteEntriesForCache(2));
176 EXPECT_TRUE(db.FindEntriesForCache(2, &found));
177 EXPECT_TRUE(found.empty());
178 found.clear();
180 EXPECT_TRUE(db.DeleteEntriesForCache(1));
181 EXPECT_FALSE(db.AddEntryFlags(GURL("http://blah/1"), 1,
182 AppCacheEntry::FOREIGN));
184 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
187 TEST(AppCacheDatabaseTest, CacheRecords) {
188 const base::FilePath kEmptyPath;
189 AppCacheDatabase db(kEmptyPath);
190 EXPECT_TRUE(db.LazyOpen(true));
192 sql::ScopedErrorIgnorer ignore_errors;
193 // TODO(shess): See EntryRecords test.
194 ignore_errors.IgnoreError(SQLITE_CONSTRAINT);
196 const AppCacheDatabase::CacheRecord kZeroRecord;
197 AppCacheDatabase::CacheRecord record;
198 EXPECT_FALSE(db.FindCache(1, &record));
200 record.cache_id = 1;
201 record.group_id = 1;
202 record.online_wildcard = true;
203 record.update_time = kZeroTime;
204 record.cache_size = 100;
205 EXPECT_TRUE(db.InsertCache(&record));
206 EXPECT_FALSE(db.InsertCache(&record));
208 record = kZeroRecord;
209 EXPECT_TRUE(db.FindCache(1, &record));
210 EXPECT_EQ(1, record.cache_id);
211 EXPECT_EQ(1, record.group_id);
212 EXPECT_TRUE(record.online_wildcard);
213 EXPECT_TRUE(kZeroTime == record.update_time);
214 EXPECT_EQ(100, record.cache_size);
216 record = kZeroRecord;
217 EXPECT_TRUE(db.FindCacheForGroup(1, &record));
218 EXPECT_EQ(1, record.cache_id);
219 EXPECT_EQ(1, record.group_id);
220 EXPECT_TRUE(record.online_wildcard);
221 EXPECT_TRUE(kZeroTime == record.update_time);
222 EXPECT_EQ(100, record.cache_size);
224 EXPECT_TRUE(db.DeleteCache(1));
225 EXPECT_FALSE(db.FindCache(1, &record));
226 EXPECT_FALSE(db.FindCacheForGroup(1, &record));
228 EXPECT_TRUE(db.DeleteCache(1));
230 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
233 TEST(AppCacheDatabaseTest, GroupRecords) {
234 const base::FilePath kEmptyPath;
235 AppCacheDatabase db(kEmptyPath);
236 EXPECT_TRUE(db.LazyOpen(true));
238 sql::ScopedErrorIgnorer ignore_errors;
239 // TODO(shess): See EntryRecords test.
240 ignore_errors.IgnoreError(SQLITE_CONSTRAINT);
242 const GURL kManifestUrl("http://blah/manifest");
243 const GURL kOrigin(kManifestUrl.GetOrigin());
244 const base::Time kLastAccessTime = base::Time::Now();
245 const base::Time kCreationTime =
246 kLastAccessTime - base::TimeDelta::FromDays(7);
248 const AppCacheDatabase::GroupRecord kZeroRecord;
249 AppCacheDatabase::GroupRecord record;
250 std::vector<AppCacheDatabase::GroupRecord> records;
252 // Behavior with an empty table
253 EXPECT_FALSE(db.FindGroup(1, &record));
254 EXPECT_FALSE(db.FindGroupForManifestUrl(kManifestUrl, &record));
255 EXPECT_TRUE(db.DeleteGroup(1));
256 EXPECT_TRUE(db.FindGroupsForOrigin(kOrigin, &records));
257 EXPECT_TRUE(records.empty());
258 EXPECT_FALSE(db.FindGroupForCache(1, &record));
260 record.group_id = 1;
261 record.manifest_url = kManifestUrl;
262 record.origin = kOrigin;
263 record.last_access_time = kLastAccessTime;
264 record.creation_time = kCreationTime;
265 EXPECT_TRUE(db.InsertGroup(&record));
266 EXPECT_FALSE(db.InsertGroup(&record));
268 record.group_id = 2;
269 EXPECT_FALSE(db.InsertGroup(&record));
271 record = kZeroRecord;
272 EXPECT_TRUE(db.FindGroup(1, &record));
273 EXPECT_EQ(1, record.group_id);
274 EXPECT_EQ(kManifestUrl, record.manifest_url);
275 EXPECT_EQ(kOrigin, record.origin);
276 EXPECT_EQ(kCreationTime.ToInternalValue(),
277 record.creation_time.ToInternalValue());
278 EXPECT_EQ(kLastAccessTime.ToInternalValue(),
279 record.last_access_time.ToInternalValue());
281 record = kZeroRecord;
282 EXPECT_TRUE(db.FindGroupForManifestUrl(kManifestUrl, &record));
283 EXPECT_EQ(1, record.group_id);
284 EXPECT_EQ(kManifestUrl, record.manifest_url);
285 EXPECT_EQ(kOrigin, record.origin);
286 EXPECT_EQ(kCreationTime.ToInternalValue(),
287 record.creation_time.ToInternalValue());
288 EXPECT_EQ(kLastAccessTime.ToInternalValue(),
289 record.last_access_time.ToInternalValue());
291 record.group_id = 2;
292 record.manifest_url = kOrigin;
293 record.origin = kOrigin;
294 record.last_access_time = kLastAccessTime;
295 record.creation_time = kCreationTime;
296 EXPECT_TRUE(db.InsertGroup(&record));
298 record = kZeroRecord;
299 EXPECT_TRUE(db.FindGroupForManifestUrl(kOrigin, &record));
300 EXPECT_EQ(2, record.group_id);
301 EXPECT_EQ(kOrigin, record.manifest_url);
302 EXPECT_EQ(kOrigin, record.origin);
303 EXPECT_EQ(kCreationTime.ToInternalValue(),
304 record.creation_time.ToInternalValue());
305 EXPECT_EQ(kLastAccessTime.ToInternalValue(),
306 record.last_access_time.ToInternalValue());
308 EXPECT_TRUE(db.FindGroupsForOrigin(kOrigin, &records));
309 EXPECT_EQ(2U, records.size());
310 EXPECT_EQ(1, records[0].group_id);
311 EXPECT_EQ(kManifestUrl, records[0].manifest_url);
312 EXPECT_EQ(kOrigin, records[0].origin);
313 EXPECT_EQ(2, records[1].group_id);
314 EXPECT_EQ(kOrigin, records[1].manifest_url);
315 EXPECT_EQ(kOrigin, records[1].origin);
317 EXPECT_TRUE(db.DeleteGroup(1));
319 records.clear();
320 EXPECT_TRUE(db.FindGroupsForOrigin(kOrigin, &records));
321 EXPECT_EQ(1U, records.size());
322 EXPECT_EQ(2, records[0].group_id);
323 EXPECT_EQ(kOrigin, records[0].manifest_url);
324 EXPECT_EQ(kOrigin, records[0].origin);
325 EXPECT_EQ(kCreationTime.ToInternalValue(),
326 record.creation_time.ToInternalValue());
327 EXPECT_EQ(kLastAccessTime.ToInternalValue(),
328 record.last_access_time.ToInternalValue());
330 std::set<GURL> origins;
331 EXPECT_TRUE(db.FindOriginsWithGroups(&origins));
332 EXPECT_EQ(1U, origins.size());
333 EXPECT_EQ(kOrigin, *(origins.begin()));
335 const GURL kManifest2("http://blah2/manifest");
336 const GURL kOrigin2(kManifest2.GetOrigin());
337 record.group_id = 1;
338 record.manifest_url = kManifest2;
339 record.origin = kOrigin2;
340 EXPECT_TRUE(db.InsertGroup(&record));
342 origins.clear();
343 EXPECT_TRUE(db.FindOriginsWithGroups(&origins));
344 EXPECT_EQ(2U, origins.size());
345 EXPECT_TRUE(origins.end() != origins.find(kOrigin));
346 EXPECT_TRUE(origins.end() != origins.find(kOrigin2));
348 AppCacheDatabase::CacheRecord cache_record;
349 cache_record.cache_id = 1;
350 cache_record.group_id = 1;
351 cache_record.online_wildcard = true;
352 cache_record.update_time = kZeroTime;
353 EXPECT_TRUE(db.InsertCache(&cache_record));
355 record = kZeroRecord;
356 EXPECT_TRUE(db.FindGroupForCache(1, &record));
357 EXPECT_EQ(1, record.group_id);
358 EXPECT_EQ(kManifest2, record.manifest_url);
359 EXPECT_EQ(kOrigin2, record.origin);
361 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
364 TEST(AppCacheDatabaseTest, NamespaceRecords) {
365 const base::FilePath kEmptyPath;
366 AppCacheDatabase db(kEmptyPath);
367 EXPECT_TRUE(db.LazyOpen(true));
369 sql::ScopedErrorIgnorer ignore_errors;
370 // TODO(shess): See EntryRecords test.
371 ignore_errors.IgnoreError(SQLITE_CONSTRAINT);
373 const GURL kFooNameSpace1("http://foo/namespace1");
374 const GURL kFooNameSpace2("http://foo/namespace2");
375 const GURL kFooFallbackEntry("http://foo/entry");
376 const GURL kFooOrigin(kFooNameSpace1.GetOrigin());
377 const GURL kBarNameSpace1("http://bar/namespace1");
378 const GURL kBarNameSpace2("http://bar/namespace2");
379 const GURL kBarFallbackEntry("http://bar/entry");
380 const GURL kBarOrigin(kBarNameSpace1.GetOrigin());
382 const AppCacheDatabase::NamespaceRecord kZeroRecord;
383 AppCacheDatabase::NamespaceRecord record;
384 std::vector<AppCacheDatabase::NamespaceRecord> intercepts;
385 std::vector<AppCacheDatabase::NamespaceRecord> fallbacks;
387 // Behavior with an empty table
388 EXPECT_TRUE(db.FindNamespacesForCache(1, &intercepts, &fallbacks));
389 EXPECT_TRUE(fallbacks.empty());
390 EXPECT_TRUE(db.FindNamespacesForOrigin(kFooOrigin, &intercepts, &fallbacks));
391 EXPECT_TRUE(fallbacks.empty());
392 EXPECT_TRUE(db.DeleteNamespacesForCache(1));
394 // Two records for two differenent caches in the Foo origin.
395 record.cache_id = 1;
396 record.origin = kFooOrigin;
397 record.namespace_.namespace_url = kFooNameSpace1;
398 record.namespace_.target_url = kFooFallbackEntry;
399 EXPECT_TRUE(db.InsertNamespace(&record));
400 EXPECT_FALSE(db.InsertNamespace(&record));
402 record.cache_id = 2;
403 record.origin = kFooOrigin;
404 record.namespace_.namespace_url = kFooNameSpace2;
405 record.namespace_.target_url = kFooFallbackEntry;
406 EXPECT_TRUE(db.InsertNamespace(&record));
408 fallbacks.clear();
409 EXPECT_TRUE(db.FindNamespacesForCache(1, &intercepts, &fallbacks));
410 EXPECT_EQ(1U, fallbacks.size());
411 EXPECT_EQ(1, fallbacks[0].cache_id);
412 EXPECT_EQ(kFooOrigin, fallbacks[0].origin);
413 EXPECT_EQ(kFooNameSpace1, fallbacks[0].namespace_.namespace_url);
414 EXPECT_EQ(kFooFallbackEntry, fallbacks[0].namespace_.target_url);
415 EXPECT_FALSE(fallbacks[0].namespace_.is_pattern);
417 fallbacks.clear();
418 EXPECT_TRUE(db.FindNamespacesForCache(2, &intercepts, &fallbacks));
419 EXPECT_EQ(1U, fallbacks.size());
420 EXPECT_EQ(2, fallbacks[0].cache_id);
421 EXPECT_EQ(kFooOrigin, fallbacks[0].origin);
422 EXPECT_EQ(kFooNameSpace2, fallbacks[0].namespace_.namespace_url);
423 EXPECT_EQ(kFooFallbackEntry, fallbacks[0].namespace_.target_url);
424 EXPECT_FALSE(fallbacks[0].namespace_.is_pattern);
426 fallbacks.clear();
427 EXPECT_TRUE(db.FindNamespacesForOrigin(kFooOrigin, &intercepts, &fallbacks));
428 EXPECT_EQ(2U, fallbacks.size());
429 EXPECT_EQ(1, fallbacks[0].cache_id);
430 EXPECT_EQ(kFooOrigin, fallbacks[0].origin);
431 EXPECT_EQ(kFooNameSpace1, fallbacks[0].namespace_.namespace_url);
432 EXPECT_EQ(kFooFallbackEntry, fallbacks[0].namespace_.target_url);
433 EXPECT_FALSE(fallbacks[0].namespace_.is_pattern);
434 EXPECT_EQ(2, fallbacks[1].cache_id);
435 EXPECT_EQ(kFooOrigin, fallbacks[1].origin);
436 EXPECT_EQ(kFooNameSpace2, fallbacks[1].namespace_.namespace_url);
437 EXPECT_EQ(kFooFallbackEntry, fallbacks[1].namespace_.target_url);
438 EXPECT_FALSE(fallbacks[1].namespace_.is_pattern);
440 EXPECT_TRUE(db.DeleteNamespacesForCache(1));
441 fallbacks.clear();
442 EXPECT_TRUE(db.FindNamespacesForOrigin(kFooOrigin, &intercepts, &fallbacks));
443 EXPECT_EQ(1U, fallbacks.size());
444 EXPECT_EQ(2, fallbacks[0].cache_id);
445 EXPECT_EQ(kFooOrigin, fallbacks[0].origin);
446 EXPECT_EQ(kFooNameSpace2, fallbacks[0].namespace_.namespace_url);
447 EXPECT_EQ(kFooFallbackEntry, fallbacks[0].namespace_.target_url);
448 EXPECT_FALSE(fallbacks[0].namespace_.is_pattern);
450 // Two more records for the same cache in the Bar origin.
451 record.cache_id = 3;
452 record.origin = kBarOrigin;
453 record.namespace_.namespace_url = kBarNameSpace1;
454 record.namespace_.target_url = kBarFallbackEntry;
455 record.namespace_.is_pattern = true;
456 EXPECT_TRUE(db.InsertNamespace(&record));
458 record.cache_id = 3;
459 record.origin = kBarOrigin;
460 record.namespace_.namespace_url = kBarNameSpace2;
461 record.namespace_.target_url = kBarFallbackEntry;
462 record.namespace_.is_pattern = true;
463 EXPECT_TRUE(db.InsertNamespace(&record));
465 fallbacks.clear();
466 EXPECT_TRUE(db.FindNamespacesForCache(3, &intercepts, &fallbacks));
467 EXPECT_EQ(2U, fallbacks.size());
468 EXPECT_TRUE(fallbacks[0].namespace_.is_pattern);
469 EXPECT_TRUE(fallbacks[1].namespace_.is_pattern);
471 fallbacks.clear();
472 EXPECT_TRUE(db.FindNamespacesForOrigin(kBarOrigin, &intercepts, &fallbacks));
473 EXPECT_EQ(2U, fallbacks.size());
474 EXPECT_TRUE(fallbacks[0].namespace_.is_pattern);
475 EXPECT_TRUE(fallbacks[1].namespace_.is_pattern);
477 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
480 TEST(AppCacheDatabaseTest, OnlineWhiteListRecords) {
481 const base::FilePath kEmptyPath;
482 AppCacheDatabase db(kEmptyPath);
483 EXPECT_TRUE(db.LazyOpen(true));
485 const GURL kFooNameSpace1("http://foo/namespace1");
486 const GURL kFooNameSpace2("http://foo/namespace2");
487 const GURL kBarNameSpace1("http://bar/namespace1");
489 const AppCacheDatabase::OnlineWhiteListRecord kZeroRecord;
490 AppCacheDatabase::OnlineWhiteListRecord record;
491 std::vector<AppCacheDatabase::OnlineWhiteListRecord> records;
493 // Behavior with an empty table
494 EXPECT_TRUE(db.FindOnlineWhiteListForCache(1, &records));
495 EXPECT_TRUE(records.empty());
496 EXPECT_TRUE(db.DeleteOnlineWhiteListForCache(1));
498 record.cache_id = 1;
499 record.namespace_url = kFooNameSpace1;
500 EXPECT_TRUE(db.InsertOnlineWhiteList(&record));
501 record.namespace_url = kFooNameSpace2;
502 record.is_pattern = true;
503 EXPECT_TRUE(db.InsertOnlineWhiteList(&record));
504 records.clear();
505 EXPECT_TRUE(db.FindOnlineWhiteListForCache(1, &records));
506 EXPECT_EQ(2U, records.size());
507 EXPECT_EQ(1, records[0].cache_id);
508 EXPECT_EQ(kFooNameSpace1, records[0].namespace_url);
509 EXPECT_FALSE(records[0].is_pattern);
510 EXPECT_EQ(1, records[1].cache_id);
511 EXPECT_EQ(kFooNameSpace2, records[1].namespace_url);
512 EXPECT_TRUE(records[1].is_pattern);
514 record.cache_id = 2;
515 record.namespace_url = kBarNameSpace1;
516 EXPECT_TRUE(db.InsertOnlineWhiteList(&record));
517 records.clear();
518 EXPECT_TRUE(db.FindOnlineWhiteListForCache(2, &records));
519 EXPECT_EQ(1U, records.size());
521 EXPECT_TRUE(db.DeleteOnlineWhiteListForCache(1));
522 records.clear();
523 EXPECT_TRUE(db.FindOnlineWhiteListForCache(1, &records));
524 EXPECT_TRUE(records.empty());
527 TEST(AppCacheDatabaseTest, DeletableResponseIds) {
528 const base::FilePath kEmptyPath;
529 AppCacheDatabase db(kEmptyPath);
530 EXPECT_TRUE(db.LazyOpen(true));
532 sql::ScopedErrorIgnorer ignore_errors;
533 // TODO(shess): See EntryRecords test.
534 ignore_errors.IgnoreError(SQLITE_CONSTRAINT);
536 std::vector<int64> ids;
538 EXPECT_TRUE(db.GetDeletableResponseIds(&ids, kint64max, 100));
539 EXPECT_TRUE(ids.empty());
540 ids.push_back(0);
541 EXPECT_TRUE(db.DeleteDeletableResponseIds(ids));
542 EXPECT_TRUE(db.InsertDeletableResponseIds(ids));
544 ids.clear();
545 EXPECT_TRUE(db.GetDeletableResponseIds(&ids, kint64max, 100));
546 EXPECT_EQ(1U, ids.size());
547 EXPECT_EQ(0, ids[0]);
549 int64 unused, deleteable_response_rowid;
550 unused = deleteable_response_rowid = 0;
551 EXPECT_TRUE(db.FindLastStorageIds(&unused, &unused, &unused,
552 &deleteable_response_rowid));
553 EXPECT_EQ(1, deleteable_response_rowid);
556 // Expected to fail due to the duplicate id, 0 is already in the table.
557 ids.clear();
558 ids.push_back(0);
559 ids.push_back(1);
560 EXPECT_FALSE(db.InsertDeletableResponseIds(ids));
562 ids.clear();
563 for (int i = 1; i < 10; ++i)
564 ids.push_back(i);
565 EXPECT_TRUE(db.InsertDeletableResponseIds(ids));
566 EXPECT_TRUE(db.FindLastStorageIds(&unused, &unused, &unused,
567 &deleteable_response_rowid));
568 EXPECT_EQ(10, deleteable_response_rowid);
570 ids.clear();
571 EXPECT_TRUE(db.GetDeletableResponseIds(&ids, kint64max, 100));
572 EXPECT_EQ(10U, ids.size());
573 for (int i = 0; i < 10; ++i)
574 EXPECT_EQ(i, ids[i]);
576 // Ensure the limit is respected.
577 ids.clear();
578 EXPECT_TRUE(db.GetDeletableResponseIds(&ids, kint64max, 5));
579 EXPECT_EQ(5U, ids.size());
580 for (int i = 0; i < static_cast<int>(ids.size()); ++i)
581 EXPECT_EQ(i, ids[i]);
583 // Ensure the max_rowid is respected (the first rowid is 1).
584 ids.clear();
585 EXPECT_TRUE(db.GetDeletableResponseIds(&ids, 5, 100));
586 EXPECT_EQ(5U, ids.size());
587 for (int i = 0; i < static_cast<int>(ids.size()); ++i)
588 EXPECT_EQ(i, ids[i]);
590 // Ensure that we can delete from the table.
591 EXPECT_TRUE(db.DeleteDeletableResponseIds(ids));
592 ids.clear();
593 EXPECT_TRUE(db.GetDeletableResponseIds(&ids, kint64max, 100));
594 EXPECT_EQ(5U, ids.size());
595 for (int i = 0; i < static_cast<int>(ids.size()); ++i)
596 EXPECT_EQ(i + 5, ids[i]);
598 ASSERT_TRUE(ignore_errors.CheckIgnoredErrors());
601 TEST(AppCacheDatabaseTest, OriginUsage) {
602 const GURL kManifestUrl("http://blah/manifest");
603 const GURL kManifestUrl2("http://blah/manifest2");
604 const GURL kOrigin(kManifestUrl.GetOrigin());
605 const GURL kOtherOriginManifestUrl("http://other/manifest");
606 const GURL kOtherOrigin(kOtherOriginManifestUrl.GetOrigin());
608 const base::FilePath kEmptyPath;
609 AppCacheDatabase db(kEmptyPath);
610 EXPECT_TRUE(db.LazyOpen(true));
612 std::vector<AppCacheDatabase::CacheRecord> cache_records;
613 EXPECT_EQ(0, db.GetOriginUsage(kOrigin));
614 EXPECT_TRUE(db.FindCachesForOrigin(kOrigin, &cache_records));
615 EXPECT_TRUE(cache_records.empty());
617 AppCacheDatabase::GroupRecord group_record;
618 group_record.group_id = 1;
619 group_record.manifest_url = kManifestUrl;
620 group_record.origin = kOrigin;
621 EXPECT_TRUE(db.InsertGroup(&group_record));
622 AppCacheDatabase::CacheRecord cache_record;
623 cache_record.cache_id = 1;
624 cache_record.group_id = 1;
625 cache_record.online_wildcard = true;
626 cache_record.update_time = kZeroTime;
627 cache_record.cache_size = 100;
628 EXPECT_TRUE(db.InsertCache(&cache_record));
630 EXPECT_EQ(100, db.GetOriginUsage(kOrigin));
632 group_record.group_id = 2;
633 group_record.manifest_url = kManifestUrl2;
634 group_record.origin = kOrigin;
635 EXPECT_TRUE(db.InsertGroup(&group_record));
636 cache_record.cache_id = 2;
637 cache_record.group_id = 2;
638 cache_record.online_wildcard = true;
639 cache_record.update_time = kZeroTime;
640 cache_record.cache_size = 1000;
641 EXPECT_TRUE(db.InsertCache(&cache_record));
643 EXPECT_EQ(1100, db.GetOriginUsage(kOrigin));
645 group_record.group_id = 3;
646 group_record.manifest_url = kOtherOriginManifestUrl;
647 group_record.origin = kOtherOrigin;
648 EXPECT_TRUE(db.InsertGroup(&group_record));
649 cache_record.cache_id = 3;
650 cache_record.group_id = 3;
651 cache_record.online_wildcard = true;
652 cache_record.update_time = kZeroTime;
653 cache_record.cache_size = 5000;
654 EXPECT_TRUE(db.InsertCache(&cache_record));
656 EXPECT_EQ(5000, db.GetOriginUsage(kOtherOrigin));
658 EXPECT_TRUE(db.FindCachesForOrigin(kOrigin, &cache_records));
659 EXPECT_EQ(2U, cache_records.size());
660 cache_records.clear();
661 EXPECT_TRUE(db.FindCachesForOrigin(kOtherOrigin, &cache_records));
662 EXPECT_EQ(1U, cache_records.size());
664 std::map<GURL, int64> usage_map;
665 EXPECT_TRUE(db.GetAllOriginUsage(&usage_map));
666 EXPECT_EQ(2U, usage_map.size());
667 EXPECT_EQ(1100, usage_map[kOrigin]);
668 EXPECT_EQ(5000, usage_map[kOtherOrigin]);
671 TEST(AppCacheDatabaseTest, UpgradeSchema3to5) {
672 // Real file on disk for this test.
673 base::ScopedTempDir temp_dir;
674 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
675 const base::FilePath kDbFile = temp_dir.path().AppendASCII("upgrade3.db");
677 const GURL kMockOrigin("http://mockorigin/");
678 const char kNamespaceUrlFormat[] = "namespace%d";
679 const char kTargetUrlFormat[] = "target%d";
680 const int kNumNamespaces = 10;
682 // Create a v3 schema based database containing some fallback records.
684 const int kVersion3 = 3;
685 const char kGroupsTable[] = "Groups";
686 const char kCachesTable[] = "Caches";
687 const char kEntriesTable[] = "Entries";
688 const char kFallbackNameSpacesTable[] = "FallbackNameSpaces";
689 const char kOnlineWhiteListsTable[] = "OnlineWhiteLists";
690 const char kDeletableResponseIdsTable[] = "DeletableResponseIds";
692 const struct {
693 const char* table_name;
694 const char* columns;
695 } kTables3[] = {
696 { kGroupsTable,
697 "(group_id INTEGER PRIMARY KEY,"
698 " origin TEXT,"
699 " manifest_url TEXT,"
700 " creation_time INTEGER,"
701 " last_access_time INTEGER)" },
703 { kCachesTable,
704 "(cache_id INTEGER PRIMARY KEY,"
705 " group_id INTEGER,"
706 " online_wildcard INTEGER CHECK(online_wildcard IN (0, 1)),"
707 " update_time INTEGER,"
708 " cache_size INTEGER)" }, // intentionally not normalized
710 { kEntriesTable,
711 "(cache_id INTEGER,"
712 " url TEXT,"
713 " flags INTEGER,"
714 " response_id INTEGER,"
715 " response_size INTEGER)" },
717 { kFallbackNameSpacesTable,
718 "(cache_id INTEGER,"
719 " origin TEXT," // intentionally not normalized
720 " namespace_url TEXT,"
721 " fallback_entry_url TEXT)" },
723 { kOnlineWhiteListsTable,
724 "(cache_id INTEGER,"
725 " namespace_url TEXT)" },
727 { kDeletableResponseIdsTable,
728 "(response_id INTEGER NOT NULL)" },
731 const struct {
732 const char* index_name;
733 const char* table_name;
734 const char* columns;
735 bool unique;
736 } kIndexes3[] = {
737 { "GroupsOriginIndex",
738 kGroupsTable,
739 "(origin)",
740 false },
742 { "GroupsManifestIndex",
743 kGroupsTable,
744 "(manifest_url)",
745 true },
747 { "CachesGroupIndex",
748 kCachesTable,
749 "(group_id)",
750 false },
752 { "EntriesCacheIndex",
753 kEntriesTable,
754 "(cache_id)",
755 false },
757 { "EntriesCacheAndUrlIndex",
758 kEntriesTable,
759 "(cache_id, url)",
760 true },
762 { "EntriesResponseIdIndex",
763 kEntriesTable,
764 "(response_id)",
765 true },
767 { "FallbackNameSpacesCacheIndex",
768 kFallbackNameSpacesTable,
769 "(cache_id)",
770 false },
772 { "FallbackNameSpacesOriginIndex",
773 kFallbackNameSpacesTable,
774 "(origin)",
775 false },
777 { "FallbackNameSpacesCacheAndUrlIndex",
778 kFallbackNameSpacesTable,
779 "(cache_id, namespace_url)",
780 true },
782 { "OnlineWhiteListCacheIndex",
783 kOnlineWhiteListsTable,
784 "(cache_id)",
785 false },
787 { "DeletableResponsesIdIndex",
788 kDeletableResponseIdsTable,
789 "(response_id)",
790 true },
793 const int kTableCount3 = ARRAYSIZE_UNSAFE(kTables3);
794 const int kIndexCount3 = ARRAYSIZE_UNSAFE(kIndexes3);
796 sql::Connection connection;
797 EXPECT_TRUE(connection.Open(kDbFile));
799 sql::Transaction transaction(&connection);
800 EXPECT_TRUE(transaction.Begin());
802 sql::MetaTable meta_table;
803 EXPECT_TRUE(meta_table.Init(&connection, kVersion3, kVersion3));
805 for (int i = 0; i < kTableCount3; ++i) {
806 std::string sql("CREATE TABLE ");
807 sql += kTables3[i].table_name;
808 sql += kTables3[i].columns;
809 EXPECT_TRUE(connection.Execute(sql.c_str()));
812 for (int i = 0; i < kIndexCount3; ++i) {
813 std::string sql;
814 if (kIndexes3[i].unique)
815 sql += "CREATE UNIQUE INDEX ";
816 else
817 sql += "CREATE INDEX ";
818 sql += kIndexes3[i].index_name;
819 sql += " ON ";
820 sql += kIndexes3[i].table_name;
821 sql += kIndexes3[i].columns;
822 EXPECT_TRUE(connection.Execute(sql.c_str()));
825 const char* kSql =
826 "INSERT INTO FallbackNameSpaces"
827 " (cache_id, origin, namespace_url, fallback_entry_url)"
828 " VALUES (?, ?, ?, ?)";
830 sql::Statement statement;
831 statement.Assign(connection.GetUniqueStatement(kSql));
832 EXPECT_TRUE(statement.is_valid());
833 for (int i = 0; i < kNumNamespaces; ++i) {
834 GURL namespace_url(
835 kMockOrigin.Resolve(base::StringPrintf(kNamespaceUrlFormat, i)));
836 GURL target_url(
837 kMockOrigin.Resolve(base::StringPrintf(kTargetUrlFormat, i)));
838 statement.BindInt64(0, i);
839 statement.BindString(1, kMockOrigin.spec().c_str());
840 statement.BindString(2, namespace_url.spec().c_str());
841 statement.BindString(3, target_url.spec().c_str());
842 ASSERT_TRUE(statement.Run());
843 statement.Reset(true);
846 EXPECT_TRUE(transaction.Commit());
849 // Open that database and verify that it got updated.
850 AppCacheDatabase db(kDbFile);
851 EXPECT_TRUE(db.LazyOpen(true));
853 EXPECT_FALSE(db.db_->DoesTableExist("FallbackNameSpaces"));
854 EXPECT_FALSE(db.db_->DoesIndexExist("FallbackNamesSpacesCacheIndex"));
855 EXPECT_FALSE(db.db_->DoesIndexExist("FallbackNameSpacesOriginIndex"));
856 EXPECT_FALSE(db.db_->DoesIndexExist("FallbackNameSpacesCacheAndUrlIndex"));
858 EXPECT_TRUE(db.db_->DoesTableExist("Namespaces"));
859 EXPECT_TRUE(db.db_->DoesIndexExist("NamespacesCacheIndex"));
860 EXPECT_TRUE(db.db_->DoesIndexExist("NamespacesOriginIndex"));
861 EXPECT_TRUE(db.db_->DoesIndexExist("NamespacesCacheAndUrlIndex"));
862 EXPECT_TRUE(db.db_->DoesColumnExist("Namespaces", "is_pattern"));
863 EXPECT_TRUE(db.db_->DoesColumnExist("OnlineWhiteLists", "is_pattern"));
865 EXPECT_EQ(5, db.meta_table_->GetVersionNumber());
866 EXPECT_EQ(5, db.meta_table_->GetCompatibleVersionNumber());
868 std::vector<AppCacheDatabase::NamespaceRecord> intercepts;
869 std::vector<AppCacheDatabase::NamespaceRecord> fallbacks;
870 EXPECT_TRUE(db.FindNamespacesForOrigin(kMockOrigin, &intercepts,
871 &fallbacks));
872 EXPECT_TRUE(intercepts.empty());
873 EXPECT_EQ(kNumNamespaces, static_cast<int>(fallbacks.size()));
875 for (int i = 0; i < kNumNamespaces; ++i) {
876 GURL expected_namespace_url(
877 kMockOrigin.Resolve(base::StringPrintf(kNamespaceUrlFormat, i)));
878 GURL expected_target_url(
879 kMockOrigin.Resolve(base::StringPrintf(kTargetUrlFormat, i)));
881 EXPECT_EQ(i, fallbacks[i].cache_id);
882 EXPECT_EQ(FALLBACK_NAMESPACE, fallbacks[i].namespace_.type);
883 EXPECT_EQ(kMockOrigin, fallbacks[i].origin);
884 EXPECT_EQ(expected_namespace_url, fallbacks[i].namespace_.namespace_url);
885 EXPECT_EQ(expected_target_url, fallbacks[i].namespace_.target_url);
886 EXPECT_FALSE(fallbacks[i].namespace_.is_pattern);
890 TEST(AppCacheDatabaseTest, UpgradeSchema4to5) {
891 // Real file on disk for this test.
892 base::ScopedTempDir temp_dir;
893 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
894 const base::FilePath kDbFile = temp_dir.path().AppendASCII("upgrade4.db");
896 const GURL kMockOrigin("http://mockorigin/");
897 const char kNamespaceUrlFormat[] = "namespace%d";
898 const char kWhitelistUrlFormat[] = "whitelist%d";
899 const char kTargetUrlFormat[] = "target%d";
900 const int kNumNamespaces = 10;
901 const int kWhitelistCacheId = 1;
903 // Create a v4 schema based database containing some fallback records.
905 const int kVersion4 = 4;
906 const char kGroupsTable[] = "Groups";
907 const char kCachesTable[] = "Caches";
908 const char kEntriesTable[] = "Entries";
909 const char kNamespacesTable[] = "Namespaces";
910 const char kOnlineWhiteListsTable[] = "OnlineWhiteLists";
911 const char kDeletableResponseIdsTable[] = "DeletableResponseIds";
913 struct TableInfo {
914 const char* table_name;
915 const char* columns;
918 struct IndexInfo {
919 const char* index_name;
920 const char* table_name;
921 const char* columns;
922 bool unique;
925 const TableInfo kTables4[] = {
926 { kGroupsTable,
927 "(group_id INTEGER PRIMARY KEY,"
928 " origin TEXT,"
929 " manifest_url TEXT,"
930 " creation_time INTEGER,"
931 " last_access_time INTEGER)" },
933 { kCachesTable,
934 "(cache_id INTEGER PRIMARY KEY,"
935 " group_id INTEGER,"
936 " online_wildcard INTEGER CHECK(online_wildcard IN (0, 1)),"
937 " update_time INTEGER,"
938 " cache_size INTEGER)" }, // intentionally not normalized
940 { kEntriesTable,
941 "(cache_id INTEGER,"
942 " url TEXT,"
943 " flags INTEGER,"
944 " response_id INTEGER,"
945 " response_size INTEGER)" },
947 { kNamespacesTable,
948 "(cache_id INTEGER,"
949 " origin TEXT," // intentionally not normalized
950 " type INTEGER,"
951 " namespace_url TEXT,"
952 " target_url TEXT)" },
954 { kOnlineWhiteListsTable,
955 "(cache_id INTEGER,"
956 " namespace_url TEXT)" },
958 { kDeletableResponseIdsTable,
959 "(response_id INTEGER NOT NULL)" },
962 const IndexInfo kIndexes4[] = {
963 { "GroupsOriginIndex",
964 kGroupsTable,
965 "(origin)",
966 false },
968 { "GroupsManifestIndex",
969 kGroupsTable,
970 "(manifest_url)",
971 true },
973 { "CachesGroupIndex",
974 kCachesTable,
975 "(group_id)",
976 false },
978 { "EntriesCacheIndex",
979 kEntriesTable,
980 "(cache_id)",
981 false },
983 { "EntriesCacheAndUrlIndex",
984 kEntriesTable,
985 "(cache_id, url)",
986 true },
988 { "EntriesResponseIdIndex",
989 kEntriesTable,
990 "(response_id)",
991 true },
993 { "NamespacesCacheIndex",
994 kNamespacesTable,
995 "(cache_id)",
996 false },
998 { "NamespacesOriginIndex",
999 kNamespacesTable,
1000 "(origin)",
1001 false },
1003 { "NamespacesCacheAndUrlIndex",
1004 kNamespacesTable,
1005 "(cache_id, namespace_url)",
1006 true },
1008 { "OnlineWhiteListCacheIndex",
1009 kOnlineWhiteListsTable,
1010 "(cache_id)",
1011 false },
1013 { "DeletableResponsesIdIndex",
1014 kDeletableResponseIdsTable,
1015 "(response_id)",
1016 true },
1019 const int kTableCount4 = ARRAYSIZE_UNSAFE(kTables4);
1020 const int kIndexCount4 = ARRAYSIZE_UNSAFE(kIndexes4);
1022 sql::Connection connection;
1023 EXPECT_TRUE(connection.Open(kDbFile));
1025 sql::Transaction transaction(&connection);
1026 EXPECT_TRUE(transaction.Begin());
1028 sql::MetaTable meta_table;
1029 EXPECT_TRUE(meta_table.Init(&connection, kVersion4, kVersion4));
1031 for (int i = 0; i < kTableCount4; ++i) {
1032 std::string sql("CREATE TABLE ");
1033 sql += kTables4[i].table_name;
1034 sql += kTables4[i].columns;
1035 EXPECT_TRUE(connection.Execute(sql.c_str()));
1038 for (int i = 0; i < kIndexCount4; ++i) {
1039 std::string sql;
1040 if (kIndexes4[i].unique)
1041 sql += "CREATE UNIQUE INDEX ";
1042 else
1043 sql += "CREATE INDEX ";
1044 sql += kIndexes4[i].index_name;
1045 sql += " ON ";
1046 sql += kIndexes4[i].table_name;
1047 sql += kIndexes4[i].columns;
1048 EXPECT_TRUE(connection.Execute(sql.c_str()));
1051 const char* kNamespacesSql =
1052 "INSERT INTO Namespaces"
1053 " (cache_id, origin, type, namespace_url, target_url)"
1054 " VALUES (?, ?, ?, ?, ?)";
1055 sql::Statement statement;
1056 statement.Assign(connection.GetUniqueStatement(kNamespacesSql));
1057 EXPECT_TRUE(statement.is_valid());
1058 for (int i = 0; i < kNumNamespaces; ++i) {
1059 GURL namespace_url(
1060 kMockOrigin.Resolve(base::StringPrintf(kNamespaceUrlFormat, i)));
1061 GURL target_url(
1062 kMockOrigin.Resolve(base::StringPrintf(kTargetUrlFormat, i)));
1063 statement.BindInt64(0, i);
1064 statement.BindString(1, kMockOrigin.spec().c_str());
1065 statement.BindInt(2, FALLBACK_NAMESPACE);
1066 statement.BindString(3, namespace_url.spec().c_str());
1067 statement.BindString(4, target_url.spec().c_str());
1068 ASSERT_TRUE(statement.Run());
1069 statement.Reset(true);
1072 const char* kWhitelistsSql =
1073 "INSERT INTO OnlineWhiteLists"
1074 " (cache_id, namespace_url)"
1075 " VALUES (?, ?)";
1076 statement.Assign(connection.GetUniqueStatement(kWhitelistsSql));
1077 EXPECT_TRUE(statement.is_valid());
1078 for (int i = 0; i < kNumNamespaces; ++i) {
1079 GURL namespace_url(
1080 kMockOrigin.Resolve(base::StringPrintf(kWhitelistUrlFormat, i)));
1081 statement.BindInt64(0, kWhitelistCacheId);
1082 statement.BindString(1, namespace_url.spec().c_str());
1083 ASSERT_TRUE(statement.Run());
1084 statement.Reset(true);
1087 EXPECT_TRUE(transaction.Commit());
1090 // Open that database and verify that it got upgraded to v5.
1091 AppCacheDatabase db(kDbFile);
1092 EXPECT_TRUE(db.LazyOpen(true));
1093 EXPECT_TRUE(db.db_->DoesColumnExist("Namespaces", "is_pattern"));
1094 EXPECT_TRUE(db.db_->DoesColumnExist("OnlineWhiteLists", "is_pattern"));
1095 EXPECT_EQ(5, db.meta_table_->GetVersionNumber());
1096 EXPECT_EQ(5, db.meta_table_->GetCompatibleVersionNumber());
1098 std::vector<AppCacheDatabase::NamespaceRecord> intercepts;
1099 std::vector<AppCacheDatabase::NamespaceRecord> fallbacks;
1100 EXPECT_TRUE(db.FindNamespacesForOrigin(kMockOrigin, &intercepts,
1101 &fallbacks));
1102 EXPECT_TRUE(intercepts.empty());
1103 EXPECT_EQ(kNumNamespaces, static_cast<int>(fallbacks.size()));
1105 std::vector<AppCacheDatabase::OnlineWhiteListRecord> whitelists;
1106 EXPECT_TRUE(db.FindOnlineWhiteListForCache(kWhitelistCacheId, &whitelists));
1107 EXPECT_EQ(kNumNamespaces, static_cast<int>(whitelists.size()));
1109 for (int i = 0; i < kNumNamespaces; ++i) {
1110 GURL expected_namespace_url(
1111 kMockOrigin.Resolve(base::StringPrintf(kNamespaceUrlFormat, i)));
1112 GURL expected_target_url(
1113 kMockOrigin.Resolve(base::StringPrintf(kTargetUrlFormat, i)));
1114 GURL expected_whitelist_url(
1115 kMockOrigin.Resolve(base::StringPrintf(kWhitelistUrlFormat, i)));
1117 EXPECT_EQ(i, fallbacks[i].cache_id);
1118 EXPECT_EQ(FALLBACK_NAMESPACE, fallbacks[i].namespace_.type);
1119 EXPECT_EQ(kMockOrigin, fallbacks[i].origin);
1120 EXPECT_EQ(expected_namespace_url, fallbacks[i].namespace_.namespace_url);
1121 EXPECT_EQ(expected_target_url, fallbacks[i].namespace_.target_url);
1122 EXPECT_FALSE(fallbacks[i].namespace_.is_pattern);
1123 EXPECT_EQ(expected_whitelist_url, whitelists[i].namespace_url);
1124 EXPECT_FALSE(whitelists[i].is_pattern);
1128 } // namespace appcache