OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <algorithm> | 5 #include <algorithm> |
6 #include <iterator> | 6 #include <iterator> |
7 #include <set> | 7 #include <set> |
8 | 8 |
9 #include "app/sql/connection.h" | 9 #include "app/sql/connection.h" |
| 10 #include "app/sql/meta_table.h" |
10 #include "app/sql/statement.h" | 11 #include "app/sql/statement.h" |
11 #include "app/sql/transaction.h" | 12 #include "app/sql/transaction.h" |
12 #include "base/bind.h" | 13 #include "base/bind.h" |
13 #include "base/callback.h" | 14 #include "base/callback.h" |
14 #include "base/file_util.h" | 15 #include "base/file_util.h" |
15 #include "base/scoped_temp_dir.h" | 16 #include "base/scoped_temp_dir.h" |
16 #include "googleurl/src/gurl.h" | 17 #include "googleurl/src/gurl.h" |
17 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
18 #include "webkit/quota/mock_special_storage_policy.h" | 19 #include "webkit/quota/mock_special_storage_policy.h" |
19 #include "webkit/quota/quota_database.h" | 20 #include "webkit/quota/quota_database.h" |
20 | 21 |
| 22 namespace quota { |
21 namespace { | 23 namespace { |
22 | 24 |
23 const base::Time kZeroTime; | 25 const base::Time kZeroTime; |
24 | 26 |
25 class TestErrorDelegate : public sql::ErrorDelegate { | 27 class TestErrorDelegate : public sql::ErrorDelegate { |
26 public: | 28 public: |
27 virtual ~TestErrorDelegate() { } | 29 virtual ~TestErrorDelegate() { } |
28 virtual int OnError( | 30 virtual int OnError( |
29 int error, sql::Connection* connection, sql::Statement* stmt) { | 31 int error, sql::Connection* connection, sql::Statement* stmt) { |
30 return error; | 32 return error; |
31 } | 33 } |
32 }; | 34 }; |
| 35 |
33 } // namespace | 36 } // namespace |
34 | 37 |
35 namespace quota { | |
36 | |
37 class QuotaDatabaseTest : public testing::Test { | 38 class QuotaDatabaseTest : public testing::Test { |
38 protected: | 39 protected: |
39 typedef QuotaDatabase::QuotaTableEntry QuotaTableEntry; | 40 typedef QuotaDatabase::QuotaTableEntry QuotaTableEntry; |
40 typedef QuotaDatabase::QuotaTableCallback QuotaTableCallback; | 41 typedef QuotaDatabase::QuotaTableCallback QuotaTableCallback; |
41 typedef QuotaDatabase::LastAccessTimeTableEntry LastAccessTimeTableEntry; | 42 typedef QuotaDatabase::OriginInfoTableEntry OriginInfoTableEntry; |
42 typedef QuotaDatabase::LastAccessTimeTableCallback | 43 typedef QuotaDatabase::OriginInfoTableCallback |
43 LastAccessTimeTableCallback; | 44 OriginInfoTableCallback; |
44 | |
45 template <typename Iterator> | |
46 bool AssignQuotaTable( | |
47 QuotaDatabase* quota_database, Iterator itr, Iterator end) { | |
48 if (!quota_database->LazyOpen(true)) | |
49 return false; | |
50 | |
51 for (; itr != end; ++itr) { | |
52 const char* kSql = | |
53 "INSERT INTO HostQuotaTable" | |
54 " (host, type, quota)" | |
55 " VALUES (?, ?, ?)"; | |
56 sql::Statement statement; | |
57 statement.Assign( | |
58 quota_database->db_->GetCachedStatement( | |
59 SQL_FROM_HERE, kSql)); | |
60 EXPECT_TRUE(statement.is_valid()); | |
61 | |
62 statement.BindString(0, itr->host); | |
63 statement.BindInt(1, static_cast<int>(itr->type)); | |
64 statement.BindInt64(2, itr->quota); | |
65 if (!statement.Run()) | |
66 return false; | |
67 } | |
68 | |
69 quota_database->Commit(); | |
70 return true; | |
71 } | |
72 | |
73 template <typename Iterator> | |
74 bool AssignLastAccessTimeTable( | |
75 QuotaDatabase* quota_database, Iterator itr, Iterator end) { | |
76 if (!quota_database->LazyOpen(true)) | |
77 return false; | |
78 | |
79 for (; itr != end; ++itr) { | |
80 const char* kSql = | |
81 "INSERT INTO OriginLastAccessTable" | |
82 " (origin, type, used_count, last_access_time)" | |
83 " VALUES (?, ?, ?, ?)"; | |
84 sql::Statement statement; | |
85 statement.Assign( | |
86 quota_database->db_->GetCachedStatement( | |
87 SQL_FROM_HERE, kSql)); | |
88 EXPECT_TRUE(statement.is_valid()); | |
89 | |
90 statement.BindString(0, itr->origin.spec()); | |
91 statement.BindInt(1, static_cast<int>(itr->type)); | |
92 statement.BindInt(2, itr->used_count); | |
93 statement.BindInt64(3, itr->last_access_time.ToInternalValue()); | |
94 if (!statement.Run()) | |
95 return false; | |
96 } | |
97 | |
98 quota_database->Commit(); | |
99 return true; | |
100 } | |
101 | 45 |
102 void LazyOpen(const FilePath& kDbFile) { | 46 void LazyOpen(const FilePath& kDbFile) { |
103 QuotaDatabase db(kDbFile); | 47 QuotaDatabase db(kDbFile); |
104 EXPECT_FALSE(db.LazyOpen(false)); | 48 EXPECT_FALSE(db.LazyOpen(false)); |
105 ASSERT_TRUE(db.LazyOpen(true)); | 49 ASSERT_TRUE(db.LazyOpen(true)); |
106 EXPECT_TRUE(db.db_.get()); | 50 EXPECT_TRUE(db.db_.get()); |
107 EXPECT_TRUE(kDbFile.empty() || file_util::PathExists(kDbFile)); | 51 EXPECT_TRUE(kDbFile.empty() || file_util::PathExists(kDbFile)); |
108 } | 52 } |
109 | 53 |
| 54 void UpgradeSchemaV2toV3(const FilePath& kDbFile) { |
| 55 const QuotaTableEntry entries[] = { |
| 56 { "a", kStorageTypeTemporary, 1 }, |
| 57 { "b", kStorageTypeTemporary, 2 }, |
| 58 { "c", kStorageTypePersistent, 3 }, |
| 59 }; |
| 60 |
| 61 CreateV2Database(kDbFile, entries, ARRAYSIZE_UNSAFE(entries)); |
| 62 |
| 63 QuotaDatabase db(kDbFile); |
| 64 EXPECT_TRUE(db.LazyOpen(true)); |
| 65 EXPECT_TRUE(db.db_.get()); |
| 66 |
| 67 typedef EntryVerifier<QuotaTableEntry> Verifier; |
| 68 Verifier verifier(entries, entries + ARRAYSIZE_UNSAFE(entries)); |
| 69 EXPECT_TRUE(db.DumpQuotaTable( |
| 70 new QuotaTableCallback( |
| 71 base::Bind(&Verifier::Run, |
| 72 base::Unretained(&verifier))))); |
| 73 EXPECT_TRUE(verifier.table.empty()); |
| 74 } |
| 75 |
110 void HostQuota(const FilePath& kDbFile) { | 76 void HostQuota(const FilePath& kDbFile) { |
111 QuotaDatabase db(kDbFile); | 77 QuotaDatabase db(kDbFile); |
112 ASSERT_TRUE(db.LazyOpen(true)); | 78 ASSERT_TRUE(db.LazyOpen(true)); |
113 | 79 |
114 const char* kHost = "foo.com"; | 80 const char* kHost = "foo.com"; |
115 const int kQuota1 = 13579; | 81 const int kQuota1 = 13579; |
116 const int kQuota2 = kQuota1 + 1024; | 82 const int kQuota2 = kQuota1 + 1024; |
117 | 83 |
118 int64 quota = -1; | 84 int64 quota = -1; |
119 EXPECT_FALSE(db.GetHostQuota(kHost, kStorageTypeTemporary, "a)); | 85 EXPECT_FALSE(db.GetHostQuota(kHost, kStorageTypeTemporary, "a)); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 | 182 |
217 exceptions.insert(kOrigin3); | 183 exceptions.insert(kOrigin3); |
218 EXPECT_TRUE(db.GetLRUOrigin(kStorageTypeTemporary, exceptions, | 184 EXPECT_TRUE(db.GetLRUOrigin(kStorageTypeTemporary, exceptions, |
219 NULL, &origin)); | 185 NULL, &origin)); |
220 EXPECT_TRUE(origin.is_empty()); | 186 EXPECT_TRUE(origin.is_empty()); |
221 | 187 |
222 EXPECT_TRUE(db.SetOriginLastAccessTime( | 188 EXPECT_TRUE(db.SetOriginLastAccessTime( |
223 kOrigin1, kStorageTypeTemporary, base::Time::Now())); | 189 kOrigin1, kStorageTypeTemporary, base::Time::Now())); |
224 | 190 |
225 // Delete origin/type last access time information. | 191 // Delete origin/type last access time information. |
226 EXPECT_TRUE(db.DeleteOriginLastAccessTime(kOrigin3, kStorageTypeTemporary)); | 192 EXPECT_TRUE(db.DeleteOriginInfo(kOrigin3, kStorageTypeTemporary)); |
227 | 193 |
228 // Querying again to see if the deletion has worked. | 194 // Querying again to see if the deletion has worked. |
229 exceptions.clear(); | 195 exceptions.clear(); |
230 EXPECT_TRUE(db.GetLRUOrigin(kStorageTypeTemporary, exceptions, | 196 EXPECT_TRUE(db.GetLRUOrigin(kStorageTypeTemporary, exceptions, |
231 NULL, &origin)); | 197 NULL, &origin)); |
232 EXPECT_EQ(kOrigin2.spec(), origin.spec()); | 198 EXPECT_EQ(kOrigin2.spec(), origin.spec()); |
233 | 199 |
234 exceptions.insert(kOrigin1); | 200 exceptions.insert(kOrigin1); |
235 exceptions.insert(kOrigin2); | 201 exceptions.insert(kOrigin2); |
236 EXPECT_TRUE(db.GetLRUOrigin(kStorageTypeTemporary, exceptions, | 202 EXPECT_TRUE(db.GetLRUOrigin(kStorageTypeTemporary, exceptions, |
237 NULL, &origin)); | 203 NULL, &origin)); |
238 EXPECT_TRUE(origin.is_empty()); | 204 EXPECT_TRUE(origin.is_empty()); |
239 } | 205 } |
240 | 206 |
241 void RegisterOrigins(const FilePath& kDbFile) { | 207 void OriginLastModifiedSince(const FilePath& kDbFile) { |
| 208 QuotaDatabase db(kDbFile); |
| 209 ASSERT_TRUE(db.LazyOpen(true)); |
| 210 |
| 211 std::set<GURL> origins; |
| 212 EXPECT_TRUE(db.GetOriginsModifiedSince( |
| 213 kStorageTypeTemporary, &origins, base::Time())); |
| 214 EXPECT_TRUE(origins.empty()); |
| 215 |
| 216 const GURL kOrigin1("http://a/"); |
| 217 const GURL kOrigin2("http://b/"); |
| 218 const GURL kOrigin3("http://c/"); |
| 219 |
| 220 // Report last mod time for the test origins. |
| 221 EXPECT_TRUE(db.SetOriginLastModifiedTime( |
| 222 kOrigin1, kStorageTypeTemporary, base::Time::FromInternalValue(10))); |
| 223 EXPECT_TRUE(db.SetOriginLastModifiedTime( |
| 224 kOrigin2, kStorageTypeTemporary, base::Time::FromInternalValue(20))); |
| 225 EXPECT_TRUE(db.SetOriginLastModifiedTime( |
| 226 kOrigin3, kStorageTypeTemporary, base::Time::FromInternalValue(30))); |
| 227 |
| 228 EXPECT_TRUE(db.GetOriginsModifiedSince( |
| 229 kStorageTypeTemporary, &origins, base::Time::FromInternalValue(15))); |
| 230 EXPECT_EQ(2U, origins.size()); |
| 231 EXPECT_EQ(0U, origins.count(kOrigin1)); |
| 232 EXPECT_EQ(1U, origins.count(kOrigin2)); |
| 233 EXPECT_EQ(1U, origins.count(kOrigin3)); |
| 234 |
| 235 EXPECT_TRUE(db.GetOriginsModifiedSince( |
| 236 kStorageTypeTemporary, &origins, base::Time::FromInternalValue(25))); |
| 237 EXPECT_EQ(1U, origins.size()); |
| 238 EXPECT_EQ(0U, origins.count(kOrigin1)); |
| 239 EXPECT_EQ(0U, origins.count(kOrigin2)); |
| 240 EXPECT_EQ(1U, origins.count(kOrigin3)); |
| 241 |
| 242 EXPECT_TRUE(db.GetOriginsModifiedSince( |
| 243 kStorageTypeTemporary, &origins, base::Time::FromInternalValue(35))); |
| 244 EXPECT_TRUE(origins.empty()); |
| 245 |
| 246 // Update origin1's mod time but for persistent storage. |
| 247 EXPECT_TRUE(db.SetOriginLastModifiedTime( |
| 248 kOrigin1, kStorageTypePersistent, base::Time::FromInternalValue(40))); |
| 249 |
| 250 // Must have no effects on temporary origins info. |
| 251 EXPECT_TRUE(db.GetOriginsModifiedSince( |
| 252 kStorageTypeTemporary, &origins, base::Time::FromInternalValue(15))); |
| 253 EXPECT_EQ(2U, origins.size()); |
| 254 EXPECT_EQ(0U, origins.count(kOrigin1)); |
| 255 EXPECT_EQ(1U, origins.count(kOrigin2)); |
| 256 EXPECT_EQ(1U, origins.count(kOrigin3)); |
| 257 |
| 258 // One more update for persistent origin2. |
| 259 EXPECT_TRUE(db.SetOriginLastModifiedTime( |
| 260 kOrigin2, kStorageTypePersistent, base::Time::FromInternalValue(50))); |
| 261 |
| 262 EXPECT_TRUE(db.GetOriginsModifiedSince( |
| 263 kStorageTypePersistent, &origins, base::Time::FromInternalValue(35))); |
| 264 EXPECT_EQ(2U, origins.size()); |
| 265 EXPECT_EQ(1U, origins.count(kOrigin1)); |
| 266 EXPECT_EQ(1U, origins.count(kOrigin2)); |
| 267 EXPECT_EQ(0U, origins.count(kOrigin3)); |
| 268 |
| 269 EXPECT_TRUE(db.GetOriginsModifiedSince( |
| 270 kStorageTypePersistent, &origins, base::Time::FromInternalValue(45))); |
| 271 EXPECT_EQ(1U, origins.size()); |
| 272 EXPECT_EQ(0U, origins.count(kOrigin1)); |
| 273 EXPECT_EQ(1U, origins.count(kOrigin2)); |
| 274 EXPECT_EQ(0U, origins.count(kOrigin3)); |
| 275 } |
| 276 |
| 277 void RegisterInitialOriginInfo(const FilePath& kDbFile) { |
242 QuotaDatabase db(kDbFile); | 278 QuotaDatabase db(kDbFile); |
243 | 279 |
244 const GURL kOrigins[] = { | 280 const GURL kOrigins[] = { |
245 GURL("http://a/"), | 281 GURL("http://a/"), |
246 GURL("http://b/"), | 282 GURL("http://b/"), |
247 GURL("http://c/") }; | 283 GURL("http://c/") }; |
248 std::set<GURL> origins(kOrigins, kOrigins + ARRAYSIZE_UNSAFE(kOrigins)); | 284 std::set<GURL> origins(kOrigins, kOrigins + ARRAYSIZE_UNSAFE(kOrigins)); |
249 | 285 |
250 EXPECT_TRUE(db.RegisterOrigins(origins, | 286 EXPECT_TRUE(db.RegisterInitialOriginInfo(origins, kStorageTypeTemporary)); |
251 kStorageTypeTemporary, | |
252 base::Time())); | |
253 | 287 |
254 int used_count = -1; | 288 int used_count = -1; |
255 EXPECT_TRUE(db.FindOriginUsedCount(GURL("http://a/"), | 289 EXPECT_TRUE(db.FindOriginUsedCount(GURL("http://a/"), |
256 kStorageTypeTemporary, | 290 kStorageTypeTemporary, |
257 &used_count)); | 291 &used_count)); |
258 EXPECT_EQ(0, used_count); | 292 EXPECT_EQ(0, used_count); |
259 | 293 |
260 EXPECT_TRUE(db.SetOriginLastAccessTime( | 294 EXPECT_TRUE(db.SetOriginLastAccessTime( |
261 GURL("http://a/"), kStorageTypeTemporary, | 295 GURL("http://a/"), kStorageTypeTemporary, |
262 base::Time::FromDoubleT(1.0))); | 296 base::Time::FromDoubleT(1.0))); |
263 used_count = -1; | 297 used_count = -1; |
264 EXPECT_TRUE(db.FindOriginUsedCount(GURL("http://a/"), | 298 EXPECT_TRUE(db.FindOriginUsedCount(GURL("http://a/"), |
265 kStorageTypeTemporary, | 299 kStorageTypeTemporary, |
266 &used_count)); | 300 &used_count)); |
267 EXPECT_EQ(1, used_count); | 301 EXPECT_EQ(1, used_count); |
268 | 302 |
269 EXPECT_TRUE(db.RegisterOrigins(origins, | 303 EXPECT_TRUE(db.RegisterInitialOriginInfo(origins, kStorageTypeTemporary)); |
270 kStorageTypeTemporary, | |
271 base::Time())); | |
272 | 304 |
273 used_count = -1; | 305 used_count = -1; |
274 EXPECT_TRUE(db.FindOriginUsedCount(GURL("http://a/"), | 306 EXPECT_TRUE(db.FindOriginUsedCount(GURL("http://a/"), |
275 kStorageTypeTemporary, | 307 kStorageTypeTemporary, |
276 &used_count)); | 308 &used_count)); |
277 EXPECT_EQ(1, used_count); | 309 EXPECT_EQ(1, used_count); |
278 } | 310 } |
279 | 311 |
280 template <typename EntryType> | 312 template <typename EntryType> |
281 struct EntryVerifier { | 313 struct EntryVerifier { |
(...skipping 12 matching lines...) Expand all Loading... |
294 void DumpQuotaTable(const FilePath& kDbFile) { | 326 void DumpQuotaTable(const FilePath& kDbFile) { |
295 QuotaTableEntry kTableEntries[] = { | 327 QuotaTableEntry kTableEntries[] = { |
296 {"http://go/", kStorageTypeTemporary, 1}, | 328 {"http://go/", kStorageTypeTemporary, 1}, |
297 {"http://oo/", kStorageTypeTemporary, 2}, | 329 {"http://oo/", kStorageTypeTemporary, 2}, |
298 {"http://gle/", kStorageTypePersistent, 3} | 330 {"http://gle/", kStorageTypePersistent, 3} |
299 }; | 331 }; |
300 QuotaTableEntry* begin = kTableEntries; | 332 QuotaTableEntry* begin = kTableEntries; |
301 QuotaTableEntry* end = kTableEntries + ARRAYSIZE_UNSAFE(kTableEntries); | 333 QuotaTableEntry* end = kTableEntries + ARRAYSIZE_UNSAFE(kTableEntries); |
302 | 334 |
303 QuotaDatabase db(kDbFile); | 335 QuotaDatabase db(kDbFile); |
304 EXPECT_TRUE(AssignQuotaTable(&db, begin, end)); | 336 EXPECT_TRUE(db.LazyOpen(true)); |
| 337 AssignQuotaTable(db.db_.get(), begin, end); |
| 338 db.Commit(); |
305 | 339 |
306 typedef EntryVerifier<QuotaTableEntry> Verifier; | 340 typedef EntryVerifier<QuotaTableEntry> Verifier; |
307 Verifier verifier(begin, end); | 341 Verifier verifier(begin, end); |
308 EXPECT_TRUE(db.DumpQuotaTable( | 342 EXPECT_TRUE(db.DumpQuotaTable( |
309 new QuotaTableCallback( | 343 new QuotaTableCallback( |
310 base::Bind(&Verifier::Run, | 344 base::Bind(&Verifier::Run, |
311 base::Unretained(&verifier))))); | 345 base::Unretained(&verifier))))); |
312 EXPECT_TRUE(verifier.table.empty()); | 346 EXPECT_TRUE(verifier.table.empty()); |
313 } | 347 } |
314 | 348 |
315 void DumpLastAccessTimeTable(const FilePath& kDbFile) { | 349 void DumpOriginInfoTable(const FilePath& kDbFile) { |
316 base::Time now(base::Time::Now()); | 350 base::Time now(base::Time::Now()); |
317 LastAccessTimeTableEntry kTableEntries[] = { | 351 OriginInfoTableEntry kTableEntries[] = { |
318 {GURL("http://go/"), kStorageTypeTemporary, 2147483647, now}, | 352 {GURL("http://go/"), kStorageTypeTemporary, 2147483647, now, now}, |
319 {GURL("http://oo/"), kStorageTypeTemporary, 0, now}, | 353 {GURL("http://oo/"), kStorageTypeTemporary, 0, now, now}, |
320 {GURL("http://gle/"), kStorageTypeTemporary, 1, now}, | 354 {GURL("http://gle/"), kStorageTypeTemporary, 1, now, now}, |
321 }; | 355 }; |
322 LastAccessTimeTableEntry* begin = kTableEntries; | 356 OriginInfoTableEntry* begin = kTableEntries; |
323 LastAccessTimeTableEntry* end = kTableEntries + | 357 OriginInfoTableEntry* end = kTableEntries + ARRAYSIZE_UNSAFE(kTableEntries); |
324 ARRAYSIZE_UNSAFE(kTableEntries); | |
325 | 358 |
326 QuotaDatabase db(kDbFile); | 359 QuotaDatabase db(kDbFile); |
327 EXPECT_TRUE(AssignLastAccessTimeTable(&db, begin, end)); | 360 EXPECT_TRUE(db.LazyOpen(true)); |
| 361 AssignOriginInfoTable(db.db_.get(), begin, end); |
| 362 db.Commit(); |
328 | 363 |
329 typedef EntryVerifier<LastAccessTimeTableEntry> Verifier; | 364 typedef EntryVerifier<OriginInfoTableEntry> Verifier; |
330 Verifier verifier(begin, end); | 365 Verifier verifier(begin, end); |
331 EXPECT_TRUE(db.DumpLastAccessTimeTable( | 366 EXPECT_TRUE(db.DumpOriginInfoTable( |
332 new LastAccessTimeTableCallback( | 367 new OriginInfoTableCallback( |
333 base::Bind(&Verifier::Run, | 368 base::Bind(&Verifier::Run, |
334 base::Unretained(&verifier))))); | 369 base::Unretained(&verifier))))); |
335 EXPECT_TRUE(verifier.table.empty()); | 370 EXPECT_TRUE(verifier.table.empty()); |
336 } | 371 } |
| 372 |
| 373 private: |
| 374 template <typename Iterator> |
| 375 void AssignQuotaTable(sql::Connection* db, Iterator itr, Iterator end) { |
| 376 ASSERT_NE(db, (sql::Connection*)NULL); |
| 377 for (; itr != end; ++itr) { |
| 378 const char* kSql = |
| 379 "INSERT INTO HostQuotaTable" |
| 380 " (host, type, quota)" |
| 381 " VALUES (?, ?, ?)"; |
| 382 sql::Statement statement; |
| 383 statement.Assign(db->GetCachedStatement(SQL_FROM_HERE, kSql)); |
| 384 ASSERT_TRUE(statement.is_valid()); |
| 385 |
| 386 statement.BindString(0, itr->host); |
| 387 statement.BindInt(1, static_cast<int>(itr->type)); |
| 388 statement.BindInt64(2, itr->quota); |
| 389 EXPECT_TRUE(statement.Run()); |
| 390 } |
| 391 } |
| 392 |
| 393 template <typename Iterator> |
| 394 void AssignOriginInfoTable(sql::Connection* db, Iterator itr, Iterator end) { |
| 395 ASSERT_NE(db, (sql::Connection*)NULL); |
| 396 for (; itr != end; ++itr) { |
| 397 const char* kSql = |
| 398 "INSERT INTO OriginInfoTable" |
| 399 " (origin, type, used_count, last_access_time, last_modified_time)" |
| 400 " VALUES (?, ?, ?, ?, ?)"; |
| 401 sql::Statement statement; |
| 402 statement.Assign(db->GetCachedStatement(SQL_FROM_HERE, kSql)); |
| 403 ASSERT_TRUE(statement.is_valid()); |
| 404 |
| 405 statement.BindString(0, itr->origin.spec()); |
| 406 statement.BindInt(1, static_cast<int>(itr->type)); |
| 407 statement.BindInt(2, itr->used_count); |
| 408 statement.BindInt64(3, itr->last_access_time.ToInternalValue()); |
| 409 statement.BindInt64(4, itr->last_modified_time.ToInternalValue()); |
| 410 EXPECT_TRUE(statement.Run()); |
| 411 } |
| 412 } |
| 413 |
| 414 bool OpenDatabase(sql::Connection* db, const FilePath& kDbFile) { |
| 415 if (kDbFile.empty()) { |
| 416 db->OpenInMemory(); |
| 417 return true; |
| 418 } |
| 419 if (!file_util::CreateDirectory(kDbFile.DirName())) |
| 420 return false; |
| 421 if (!db->Open(kDbFile)) |
| 422 return false; |
| 423 db->Preload(); |
| 424 return true; |
| 425 } |
| 426 |
| 427 // Create V2 database and populate some data. |
| 428 void CreateV2Database( |
| 429 const FilePath& kDbFile, |
| 430 const QuotaTableEntry* entries, |
| 431 size_t entries_size) { |
| 432 scoped_ptr<sql::Connection> db(new sql::Connection); |
| 433 scoped_ptr<sql::MetaTable> meta_table(new sql::MetaTable); |
| 434 |
| 435 // V2 schema definitions. |
| 436 static const int kCurrentVersion = 2; |
| 437 static const int kCompatibleVersion = 2; |
| 438 static const char kHostQuotaTable[] = "HostQuotaTable"; |
| 439 static const char kOriginLastAccessTable[] = "OriginLastAccessTable"; |
| 440 static const QuotaDatabase::TableSchema kTables[] = { |
| 441 { kHostQuotaTable, |
| 442 "(host TEXT NOT NULL," |
| 443 " type INTEGER NOT NULL," |
| 444 " quota INTEGER," |
| 445 " UNIQUE(host, type))" }, |
| 446 { kOriginLastAccessTable, |
| 447 "(origin TEXT NOT NULL," |
| 448 " type INTEGER NOT NULL," |
| 449 " used_count INTEGER," |
| 450 " last_access_time INTEGER," |
| 451 " UNIQUE(origin, type))" }, |
| 452 }; |
| 453 static const QuotaDatabase::IndexSchema kIndexes[] = { |
| 454 { "HostIndex", |
| 455 kHostQuotaTable, |
| 456 "(host)", |
| 457 false }, |
| 458 { "OriginLastAccessIndex", |
| 459 kOriginLastAccessTable, |
| 460 "(origin, last_access_time)", |
| 461 false }, |
| 462 }; |
| 463 |
| 464 ASSERT_TRUE(OpenDatabase(db.get(), kDbFile)); |
| 465 EXPECT_TRUE(QuotaDatabase::CreateSchema( |
| 466 db.get(), meta_table.get(), |
| 467 kCurrentVersion, kCompatibleVersion, |
| 468 kTables, ARRAYSIZE_UNSAFE(kTables), |
| 469 kIndexes, ARRAYSIZE_UNSAFE(kIndexes))); |
| 470 |
| 471 // V2 and V3 QuotaTable are compatible, so we can simply use |
| 472 // AssignQuotaTable to poplulate v2 database here. |
| 473 db->BeginTransaction(); |
| 474 AssignQuotaTable(db.get(), entries, entries + entries_size); |
| 475 db->CommitTransaction(); |
| 476 } |
337 }; | 477 }; |
338 | 478 |
339 TEST_F(QuotaDatabaseTest, LazyOpen) { | 479 TEST_F(QuotaDatabaseTest, LazyOpen) { |
340 ScopedTempDir data_dir; | 480 ScopedTempDir data_dir; |
341 ASSERT_TRUE(data_dir.CreateUniqueTempDir()); | 481 ASSERT_TRUE(data_dir.CreateUniqueTempDir()); |
342 const FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db"); | 482 const FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db"); |
343 LazyOpen(kDbFile); | 483 LazyOpen(kDbFile); |
344 LazyOpen(FilePath()); | 484 LazyOpen(FilePath()); |
345 } | 485 } |
346 | 486 |
| 487 TEST_F(QuotaDatabaseTest, UpgradeSchema) { |
| 488 ScopedTempDir data_dir; |
| 489 ASSERT_TRUE(data_dir.CreateUniqueTempDir()); |
| 490 const FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db"); |
| 491 UpgradeSchemaV2toV3(kDbFile); |
| 492 } |
| 493 |
347 TEST_F(QuotaDatabaseTest, HostQuota) { | 494 TEST_F(QuotaDatabaseTest, HostQuota) { |
348 ScopedTempDir data_dir; | 495 ScopedTempDir data_dir; |
349 ASSERT_TRUE(data_dir.CreateUniqueTempDir()); | 496 ASSERT_TRUE(data_dir.CreateUniqueTempDir()); |
350 const FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db"); | 497 const FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db"); |
351 HostQuota(kDbFile); | 498 HostQuota(kDbFile); |
352 HostQuota(FilePath()); | 499 HostQuota(FilePath()); |
353 } | 500 } |
354 | 501 |
355 TEST_F(QuotaDatabaseTest, GlobalQuota) { | 502 TEST_F(QuotaDatabaseTest, GlobalQuota) { |
356 ScopedTempDir data_dir; | 503 ScopedTempDir data_dir; |
357 ASSERT_TRUE(data_dir.CreateUniqueTempDir()); | 504 ASSERT_TRUE(data_dir.CreateUniqueTempDir()); |
358 const FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db"); | 505 const FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db"); |
359 GlobalQuota(kDbFile); | 506 GlobalQuota(kDbFile); |
360 GlobalQuota(FilePath()); | 507 GlobalQuota(FilePath()); |
361 } | 508 } |
362 | 509 |
363 TEST_F(QuotaDatabaseTest, OriginLastAccessTimeLRU) { | 510 TEST_F(QuotaDatabaseTest, OriginLastAccessTimeLRU) { |
364 ScopedTempDir data_dir; | 511 ScopedTempDir data_dir; |
365 ASSERT_TRUE(data_dir.CreateUniqueTempDir()); | 512 ASSERT_TRUE(data_dir.CreateUniqueTempDir()); |
366 const FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db"); | 513 const FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db"); |
367 OriginLastAccessTimeLRU(kDbFile); | 514 OriginLastAccessTimeLRU(kDbFile); |
368 OriginLastAccessTimeLRU(FilePath()); | 515 OriginLastAccessTimeLRU(FilePath()); |
369 } | 516 } |
370 | 517 |
| 518 TEST_F(QuotaDatabaseTest, OriginLastModifiedSince) { |
| 519 ScopedTempDir data_dir; |
| 520 ASSERT_TRUE(data_dir.CreateUniqueTempDir()); |
| 521 const FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db"); |
| 522 OriginLastModifiedSince(kDbFile); |
| 523 OriginLastModifiedSince(FilePath()); |
| 524 } |
| 525 |
371 TEST_F(QuotaDatabaseTest, BootstrapFlag) { | 526 TEST_F(QuotaDatabaseTest, BootstrapFlag) { |
372 ScopedTempDir data_dir; | 527 ScopedTempDir data_dir; |
373 ASSERT_TRUE(data_dir.CreateUniqueTempDir()); | 528 ASSERT_TRUE(data_dir.CreateUniqueTempDir()); |
374 | 529 |
375 const FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db"); | 530 const FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db"); |
376 QuotaDatabase db(kDbFile); | 531 QuotaDatabase db(kDbFile); |
377 | 532 |
378 EXPECT_FALSE(db.IsOriginDatabaseBootstrapped()); | 533 EXPECT_FALSE(db.IsOriginDatabaseBootstrapped()); |
379 EXPECT_TRUE(db.SetOriginDatabaseBootstrapped(true)); | 534 EXPECT_TRUE(db.SetOriginDatabaseBootstrapped(true)); |
380 EXPECT_TRUE(db.IsOriginDatabaseBootstrapped()); | 535 EXPECT_TRUE(db.IsOriginDatabaseBootstrapped()); |
381 EXPECT_TRUE(db.SetOriginDatabaseBootstrapped(false)); | 536 EXPECT_TRUE(db.SetOriginDatabaseBootstrapped(false)); |
382 EXPECT_FALSE(db.IsOriginDatabaseBootstrapped()); | 537 EXPECT_FALSE(db.IsOriginDatabaseBootstrapped()); |
383 } | 538 } |
384 | 539 |
385 TEST_F(QuotaDatabaseTest, RegisterOrigins) { | 540 TEST_F(QuotaDatabaseTest, RegisterInitialOriginInfo) { |
386 ScopedTempDir data_dir; | 541 ScopedTempDir data_dir; |
387 ASSERT_TRUE(data_dir.CreateUniqueTempDir()); | 542 ASSERT_TRUE(data_dir.CreateUniqueTempDir()); |
388 const FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db"); | 543 const FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db"); |
389 RegisterOrigins(kDbFile); | 544 RegisterInitialOriginInfo(kDbFile); |
390 RegisterOrigins(FilePath()); | 545 RegisterInitialOriginInfo(FilePath()); |
391 } | 546 } |
392 | 547 |
393 TEST_F(QuotaDatabaseTest, DumpQuotaTable) { | 548 TEST_F(QuotaDatabaseTest, DumpQuotaTable) { |
394 ScopedTempDir data_dir; | 549 ScopedTempDir data_dir; |
395 ASSERT_TRUE(data_dir.CreateUniqueTempDir()); | 550 ASSERT_TRUE(data_dir.CreateUniqueTempDir()); |
396 const FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db"); | 551 const FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db"); |
397 DumpQuotaTable(kDbFile); | 552 DumpQuotaTable(kDbFile); |
398 DumpQuotaTable(FilePath()); | 553 DumpQuotaTable(FilePath()); |
399 } | 554 } |
400 | 555 |
401 TEST_F(QuotaDatabaseTest, DumpLastAccessTimeTable) { | 556 TEST_F(QuotaDatabaseTest, DumpOriginInfoTable) { |
402 ScopedTempDir data_dir; | 557 ScopedTempDir data_dir; |
403 ASSERT_TRUE(data_dir.CreateUniqueTempDir()); | 558 ASSERT_TRUE(data_dir.CreateUniqueTempDir()); |
404 const FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db"); | 559 const FilePath kDbFile = data_dir.path().AppendASCII("quota_manager.db"); |
405 DumpLastAccessTimeTable(kDbFile); | 560 DumpOriginInfoTable(kDbFile); |
406 DumpLastAccessTimeTable(FilePath()); | 561 DumpOriginInfoTable(FilePath()); |
407 } | 562 } |
408 } // namespace quota | 563 } // namespace quota |
OLD | NEW |