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.
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"
21 const base::Time kZeroTime
;
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
));
94 EXPECT_TRUE(db
.meta_table_
->GetValue(kExperimentFlagsKey
, &flags
));
95 EXPECT_EQ(kInjectedFlags
, flags
);
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
;
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
));
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
));
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
);
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
);
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
);
175 EXPECT_TRUE(db
.DeleteEntriesForCache(2));
176 EXPECT_TRUE(db
.FindEntriesForCache(2, &found
));
177 EXPECT_TRUE(found
.empty());
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
));
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
));
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
));
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());
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));
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());
338 record
.manifest_url
= kManifest2
;
339 record
.origin
= kOrigin2
;
340 EXPECT_TRUE(db
.InsertGroup(&record
));
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.
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
));
403 record
.origin
= kFooOrigin
;
404 record
.namespace_
.namespace_url
= kFooNameSpace2
;
405 record
.namespace_
.target_url
= kFooFallbackEntry
;
406 EXPECT_TRUE(db
.InsertNamespace(&record
));
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
);
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
);
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));
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.
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
));
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
));
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
);
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));
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
));
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
);
515 record
.namespace_url
= kBarNameSpace1
;
516 EXPECT_TRUE(db
.InsertOnlineWhiteList(&record
));
518 EXPECT_TRUE(db
.FindOnlineWhiteListForCache(2, &records
));
519 EXPECT_EQ(1U, records
.size());
521 EXPECT_TRUE(db
.DeleteOnlineWhiteListForCache(1));
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());
541 EXPECT_TRUE(db
.DeleteDeletableResponseIds(ids
));
542 EXPECT_TRUE(db
.InsertDeletableResponseIds(ids
));
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.
560 EXPECT_FALSE(db
.InsertDeletableResponseIds(ids
));
563 for (int i
= 1; i
< 10; ++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
);
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.
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).
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
));
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";
693 const char* table_name
;
697 "(group_id INTEGER PRIMARY KEY,"
699 " manifest_url TEXT,"
700 " creation_time INTEGER,"
701 " last_access_time INTEGER)" },
704 "(cache_id INTEGER PRIMARY KEY,"
706 " online_wildcard INTEGER CHECK(online_wildcard IN (0, 1)),"
707 " update_time INTEGER,"
708 " cache_size INTEGER)" }, // intentionally not normalized
714 " response_id INTEGER,"
715 " response_size INTEGER)" },
717 { kFallbackNameSpacesTable
,
719 " origin TEXT," // intentionally not normalized
720 " namespace_url TEXT,"
721 " fallback_entry_url TEXT)" },
723 { kOnlineWhiteListsTable
,
725 " namespace_url TEXT)" },
727 { kDeletableResponseIdsTable
,
728 "(response_id INTEGER NOT NULL)" },
732 const char* index_name
;
733 const char* table_name
;
737 { "GroupsOriginIndex",
742 { "GroupsManifestIndex",
747 { "CachesGroupIndex",
752 { "EntriesCacheIndex",
757 { "EntriesCacheAndUrlIndex",
762 { "EntriesResponseIdIndex",
767 { "FallbackNameSpacesCacheIndex",
768 kFallbackNameSpacesTable
,
772 { "FallbackNameSpacesOriginIndex",
773 kFallbackNameSpacesTable
,
777 { "FallbackNameSpacesCacheAndUrlIndex",
778 kFallbackNameSpacesTable
,
779 "(cache_id, namespace_url)",
782 { "OnlineWhiteListCacheIndex",
783 kOnlineWhiteListsTable
,
787 { "DeletableResponsesIdIndex",
788 kDeletableResponseIdsTable
,
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
) {
814 if (kIndexes3
[i
].unique
)
815 sql
+= "CREATE UNIQUE INDEX ";
817 sql
+= "CREATE INDEX ";
818 sql
+= kIndexes3
[i
].index_name
;
820 sql
+= kIndexes3
[i
].table_name
;
821 sql
+= kIndexes3
[i
].columns
;
822 EXPECT_TRUE(connection
.Execute(sql
.c_str()));
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
) {
835 kMockOrigin
.Resolve(base::StringPrintf(kNamespaceUrlFormat
, i
)));
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
,
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";
914 const char* table_name
;
919 const char* index_name
;
920 const char* table_name
;
925 const TableInfo kTables4
[] = {
927 "(group_id INTEGER PRIMARY KEY,"
929 " manifest_url TEXT,"
930 " creation_time INTEGER,"
931 " last_access_time INTEGER)" },
934 "(cache_id INTEGER PRIMARY KEY,"
936 " online_wildcard INTEGER CHECK(online_wildcard IN (0, 1)),"
937 " update_time INTEGER,"
938 " cache_size INTEGER)" }, // intentionally not normalized
944 " response_id INTEGER,"
945 " response_size INTEGER)" },
949 " origin TEXT," // intentionally not normalized
951 " namespace_url TEXT,"
952 " target_url TEXT)" },
954 { kOnlineWhiteListsTable
,
956 " namespace_url TEXT)" },
958 { kDeletableResponseIdsTable
,
959 "(response_id INTEGER NOT NULL)" },
962 const IndexInfo kIndexes4
[] = {
963 { "GroupsOriginIndex",
968 { "GroupsManifestIndex",
973 { "CachesGroupIndex",
978 { "EntriesCacheIndex",
983 { "EntriesCacheAndUrlIndex",
988 { "EntriesResponseIdIndex",
993 { "NamespacesCacheIndex",
998 { "NamespacesOriginIndex",
1003 { "NamespacesCacheAndUrlIndex",
1005 "(cache_id, namespace_url)",
1008 { "OnlineWhiteListCacheIndex",
1009 kOnlineWhiteListsTable
,
1013 { "DeletableResponsesIdIndex",
1014 kDeletableResponseIdsTable
,
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
) {
1040 if (kIndexes4
[i
].unique
)
1041 sql
+= "CREATE UNIQUE INDEX ";
1043 sql
+= "CREATE INDEX ";
1044 sql
+= kIndexes4
[i
].index_name
;
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
) {
1060 kMockOrigin
.Resolve(base::StringPrintf(kNamespaceUrlFormat
, i
)));
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)"
1076 statement
.Assign(connection
.GetUniqueStatement(kWhitelistsSql
));
1077 EXPECT_TRUE(statement
.is_valid());
1078 for (int i
= 0; i
< kNumNamespaces
; ++i
) {
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
,
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