Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Side by Side Diff: content/browser/database_tracker_unittest.cc

Issue 2820143005: Move a browser-side WebSQL unittest next to the file it covers. (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | content/test/BUILD.gn » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <stddef.h>
6 #include <stdint.h>
7
8 #include <memory>
9
10 #include "base/files/file.h"
11 #include "base/files/file_path.h"
12 #include "base/files/file_util.h"
13 #include "base/files/scoped_temp_dir.h"
14 #include "base/message_loop/message_loop.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "base/threading/thread_task_runner_handle.h"
17 #include "base/time/time.h"
18 #include "net/base/net_errors.h"
19 #include "net/base/test_completion_callback.h"
20 #include "storage/browser/database/database_tracker.h"
21 #include "storage/browser/quota/quota_manager_proxy.h"
22 #include "storage/browser/test/mock_special_storage_policy.h"
23 #include "storage/common/database/database_identifier.h"
24 #include "testing/gtest/include/gtest/gtest.h"
25 #include "third_party/sqlite/sqlite3.h"
26
27 using base::ASCIIToUTF16;
28 using storage::DatabaseConnections;
29 using storage::DatabaseTracker;
30 using storage::OriginInfo;
31
32 namespace {
33
34 const char kOrigin1Url[] = "http://origin1";
35 const char kOrigin2Url[] = "http://protected_origin2";
36
37 class TestObserver : public storage::DatabaseTracker::Observer {
38 public:
39 TestObserver()
40 : new_notification_received_(false),
41 observe_size_changes_(true),
42 observe_scheduled_deletions_(true) {
43 }
44 TestObserver(bool observe_size_changes, bool observe_scheduled_deletions)
45 : new_notification_received_(false),
46 observe_size_changes_(observe_size_changes),
47 observe_scheduled_deletions_(observe_scheduled_deletions) {
48 }
49
50 ~TestObserver() override {}
51 void OnDatabaseSizeChanged(const std::string& origin_identifier,
52 const base::string16& database_name,
53 int64_t database_size) override {
54 if (!observe_size_changes_)
55 return;
56 new_notification_received_ = true;
57 origin_identifier_ = origin_identifier;
58 database_name_ = database_name;
59 database_size_ = database_size;
60 }
61 void OnDatabaseScheduledForDeletion(
62 const std::string& origin_identifier,
63 const base::string16& database_name) override {
64 if (!observe_scheduled_deletions_)
65 return;
66 new_notification_received_ = true;
67 origin_identifier_ = origin_identifier;
68 database_name_ = database_name;
69 }
70 bool DidReceiveNewNotification() {
71 bool temp_new_notification_received = new_notification_received_;
72 new_notification_received_ = false;
73 return temp_new_notification_received;
74 }
75 std::string GetNotificationOriginIdentifier() {
76 return origin_identifier_;
77 }
78 base::string16 GetNotificationDatabaseName() { return database_name_; }
79 int64_t GetNotificationDatabaseSize() { return database_size_; }
80
81 private:
82 bool new_notification_received_;
83 bool observe_size_changes_;
84 bool observe_scheduled_deletions_;
85 std::string origin_identifier_;
86 base::string16 database_name_;
87 int64_t database_size_;
88 };
89
90 void CheckNotificationReceived(TestObserver* observer,
91 const std::string& expected_origin_identifier,
92 const base::string16& expected_database_name,
93 int64_t expected_database_size) {
94 EXPECT_TRUE(observer->DidReceiveNewNotification());
95 EXPECT_EQ(expected_origin_identifier,
96 observer->GetNotificationOriginIdentifier());
97 EXPECT_EQ(expected_database_name,
98 observer->GetNotificationDatabaseName());
99 EXPECT_EQ(expected_database_size,
100 observer->GetNotificationDatabaseSize());
101 }
102
103 class TestQuotaManagerProxy : public storage::QuotaManagerProxy {
104 public:
105 TestQuotaManagerProxy()
106 : QuotaManagerProxy(NULL, NULL),
107 registered_client_(NULL) {
108 }
109
110 void RegisterClient(storage::QuotaClient* client) override {
111 EXPECT_FALSE(registered_client_);
112 registered_client_ = client;
113 }
114
115 void NotifyStorageAccessed(storage::QuotaClient::ID client_id,
116 const GURL& origin,
117 storage::StorageType type) override {
118 EXPECT_EQ(storage::QuotaClient::kDatabase, client_id);
119 EXPECT_EQ(storage::kStorageTypeTemporary, type);
120 accesses_[origin] += 1;
121 }
122
123 void NotifyStorageModified(storage::QuotaClient::ID client_id,
124 const GURL& origin,
125 storage::StorageType type,
126 int64_t delta) override {
127 EXPECT_EQ(storage::QuotaClient::kDatabase, client_id);
128 EXPECT_EQ(storage::kStorageTypeTemporary, type);
129 modifications_[origin].first += 1;
130 modifications_[origin].second += delta;
131 }
132
133 // Not needed for our tests.
134 void NotifyOriginInUse(const GURL& origin) override {}
135 void NotifyOriginNoLongerInUse(const GURL& origin) override {}
136 void SetUsageCacheEnabled(storage::QuotaClient::ID client_id,
137 const GURL& origin,
138 storage::StorageType type,
139 bool enabled) override {}
140 void GetUsageAndQuota(base::SequencedTaskRunner* original_task_runner,
141 const GURL& origin,
142 storage::StorageType type,
143 const UsageAndQuotaCallback& callback) override {}
144
145 void SimulateQuotaManagerDestroyed() {
146 if (registered_client_) {
147 registered_client_->OnQuotaManagerDestroyed();
148 registered_client_ = NULL;
149 }
150 }
151
152 bool WasAccessNotified(const GURL& origin) {
153 return accesses_[origin] != 0;
154 }
155
156 bool WasModificationNotified(const GURL& origin, int64_t amount) {
157 return modifications_[origin].first != 0 &&
158 modifications_[origin].second == amount;
159 }
160
161 void reset() {
162 accesses_.clear();
163 modifications_.clear();
164 }
165
166 storage::QuotaClient* registered_client_;
167
168 // Map from origin to count of access notifications.
169 std::map<GURL, int> accesses_;
170
171 // Map from origin to <count, sum of deltas>
172 std::map<GURL, std::pair<int, int64_t>> modifications_;
173
174 protected:
175 ~TestQuotaManagerProxy() override { EXPECT_FALSE(registered_client_); }
176 };
177
178 bool EnsureFileOfSize(const base::FilePath& file_path, int64_t length) {
179 base::File file(file_path,
180 base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_WRITE);
181 if (!file.IsValid())
182 return false;
183 return file.SetLength(length);
184 }
185
186 } // namespace
187
188 namespace content {
189
190 // We declare a helper class, and make it a friend of DatabaseTracker using
191 // the FORWARD_DECLARE_TEST macro, and we implement all tests we want to run as
192 // static methods of this class. Then we make our TEST() targets call these
193 // static functions. This allows us to run each test in normal mode and
194 // incognito mode without writing the same code twice.
195 class DatabaseTracker_TestHelper_Test {
196 public:
197 static void TestDeleteOpenDatabase(bool incognito_mode) {
198 // Initialize the tracker database.
199 base::ScopedTempDir temp_dir;
200 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
201 scoped_refptr<MockSpecialStoragePolicy> special_storage_policy =
202 new MockSpecialStoragePolicy;
203 special_storage_policy->AddProtected(GURL(kOrigin2Url));
204 scoped_refptr<DatabaseTracker> tracker(
205 new DatabaseTracker(temp_dir.GetPath(), incognito_mode,
206 special_storage_policy.get(), NULL, NULL));
207
208 // Create and open three databases.
209 int64_t database_size = 0;
210 const std::string kOrigin1 =
211 storage::GetIdentifierFromOrigin(GURL(kOrigin1Url));
212 const std::string kOrigin2 =
213 storage::GetIdentifierFromOrigin(GURL(kOrigin2Url));
214 const base::string16 kDB1 = ASCIIToUTF16("db1");
215 const base::string16 kDB2 = ASCIIToUTF16("db2");
216 const base::string16 kDB3 = ASCIIToUTF16("db3");
217 const base::string16 kDescription = ASCIIToUTF16("database_description");
218
219 tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0,
220 &database_size);
221 tracker->DatabaseOpened(kOrigin2, kDB2, kDescription, 0,
222 &database_size);
223 tracker->DatabaseOpened(kOrigin2, kDB3, kDescription, 0,
224 &database_size);
225
226 EXPECT_TRUE(base::CreateDirectory(
227 tracker->DatabaseDirectory().Append(base::FilePath::FromUTF16Unsafe(
228 tracker->GetOriginDirectory(kOrigin1)))));
229 EXPECT_TRUE(base::CreateDirectory(
230 tracker->DatabaseDirectory().Append(base::FilePath::FromUTF16Unsafe(
231 tracker->GetOriginDirectory(kOrigin2)))));
232 EXPECT_EQ(1, base::WriteFile(
233 tracker->GetFullDBFilePath(kOrigin1, kDB1), "a", 1));
234 EXPECT_EQ(2, base::WriteFile(
235 tracker->GetFullDBFilePath(kOrigin2, kDB2), "aa", 2));
236 EXPECT_EQ(3, base::WriteFile(
237 tracker->GetFullDBFilePath(kOrigin2, kDB3), "aaa", 3));
238 tracker->DatabaseModified(kOrigin1, kDB1);
239 tracker->DatabaseModified(kOrigin2, kDB2);
240 tracker->DatabaseModified(kOrigin2, kDB3);
241
242 // Delete db1. Should also delete origin1.
243 TestObserver observer;
244 tracker->AddObserver(&observer);
245 net::TestCompletionCallback callback;
246 int result = tracker->DeleteDatabase(kOrigin1, kDB1, callback.callback());
247 EXPECT_EQ(net::ERR_IO_PENDING, result);
248 ASSERT_FALSE(callback.have_result());
249 EXPECT_TRUE(observer.DidReceiveNewNotification());
250 EXPECT_EQ(kOrigin1, observer.GetNotificationOriginIdentifier());
251 EXPECT_EQ(kDB1, observer.GetNotificationDatabaseName());
252 tracker->DatabaseClosed(kOrigin1, kDB1);
253 result = callback.GetResult(result);
254 EXPECT_EQ(net::OK, result);
255 EXPECT_FALSE(base::PathExists(
256 tracker->DatabaseDirectory().AppendASCII(kOrigin1)));
257
258 // Recreate db1.
259 tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0,
260 &database_size);
261 EXPECT_TRUE(base::CreateDirectory(
262 tracker->DatabaseDirectory().Append(base::FilePath::FromUTF16Unsafe(
263 tracker->GetOriginDirectory(kOrigin1)))));
264 EXPECT_EQ(1, base::WriteFile(
265 tracker->GetFullDBFilePath(kOrigin1, kDB1), "a", 1));
266 tracker->DatabaseModified(kOrigin1, kDB1);
267
268 // Setup file modification times. db1 and db2 are modified now, db3 three
269 // days ago.
270 base::Time now = base::Time::Now();
271 EXPECT_TRUE(base::TouchFile(tracker->GetFullDBFilePath(kOrigin1, kDB1),
272 now, now));
273 EXPECT_TRUE(base::TouchFile(tracker->GetFullDBFilePath(kOrigin2, kDB2),
274 now, now));
275 base::Time three_days_ago = now - base::TimeDelta::FromDays(3);
276 EXPECT_TRUE(base::TouchFile(tracker->GetFullDBFilePath(kOrigin2, kDB3),
277 three_days_ago, three_days_ago));
278
279 // Delete databases modified since yesterday. db2 is whitelisted.
280 base::Time yesterday = base::Time::Now();
281 yesterday -= base::TimeDelta::FromDays(1);
282 result = tracker->DeleteDataModifiedSince(
283 yesterday, callback.callback());
284 EXPECT_EQ(net::ERR_IO_PENDING, result);
285 ASSERT_FALSE(callback.have_result());
286 EXPECT_TRUE(observer.DidReceiveNewNotification());
287 tracker->DatabaseClosed(kOrigin1, kDB1);
288 tracker->DatabaseClosed(kOrigin2, kDB2);
289 result = callback.GetResult(result);
290 EXPECT_EQ(net::OK, result);
291 EXPECT_FALSE(base::PathExists(
292 tracker->DatabaseDirectory().AppendASCII(kOrigin1)));
293 EXPECT_TRUE(
294 base::PathExists(tracker->GetFullDBFilePath(kOrigin2, kDB2)));
295 EXPECT_TRUE(
296 base::PathExists(tracker->GetFullDBFilePath(kOrigin2, kDB3)));
297
298 tracker->DatabaseClosed(kOrigin2, kDB3);
299 tracker->RemoveObserver(&observer);
300 }
301
302 static void TestDatabaseTracker(bool incognito_mode) {
303 // Initialize the tracker database.
304 base::ScopedTempDir temp_dir;
305 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
306 scoped_refptr<MockSpecialStoragePolicy> special_storage_policy =
307 new MockSpecialStoragePolicy;
308 special_storage_policy->AddProtected(GURL(kOrigin2Url));
309 scoped_refptr<DatabaseTracker> tracker(
310 new DatabaseTracker(temp_dir.GetPath(), incognito_mode,
311 special_storage_policy.get(), NULL, NULL));
312
313 // Add two observers.
314 TestObserver observer1;
315 TestObserver observer2;
316 tracker->AddObserver(&observer1);
317 tracker->AddObserver(&observer2);
318
319 // Open three new databases.
320 int64_t database_size = 0;
321 const std::string kOrigin1 =
322 storage::GetIdentifierFromOrigin(GURL(kOrigin1Url));
323 const std::string kOrigin2 =
324 storage::GetIdentifierFromOrigin(GURL(kOrigin2Url));
325 const base::string16 kDB1 = ASCIIToUTF16("db1");
326 const base::string16 kDB2 = ASCIIToUTF16("db2");
327 const base::string16 kDB3 = ASCIIToUTF16("db3");
328 const base::string16 kDescription = ASCIIToUTF16("database_description");
329
330 // Get the info for kOrigin1 and kOrigin2
331 DatabaseTracker::CachedOriginInfo* origin1_info =
332 tracker->GetCachedOriginInfo(kOrigin1);
333 DatabaseTracker::CachedOriginInfo* origin2_info =
334 tracker->GetCachedOriginInfo(kOrigin1);
335 EXPECT_TRUE(origin1_info);
336 EXPECT_TRUE(origin2_info);
337
338
339 tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0,
340 &database_size);
341 EXPECT_EQ(0, database_size);
342 tracker->DatabaseOpened(kOrigin2, kDB2, kDescription, 0,
343 &database_size);
344 EXPECT_EQ(0, database_size);
345 tracker->DatabaseOpened(kOrigin1, kDB3, kDescription, 0,
346 &database_size);
347 EXPECT_EQ(0, database_size);
348
349 // Write some data to each file and check that the listeners are
350 // called with the appropriate values.
351 EXPECT_TRUE(base::CreateDirectory(
352 tracker->DatabaseDirectory().Append(base::FilePath::FromUTF16Unsafe(
353 tracker->GetOriginDirectory(kOrigin1)))));
354 EXPECT_TRUE(base::CreateDirectory(
355 tracker->DatabaseDirectory().Append(base::FilePath::FromUTF16Unsafe(
356 tracker->GetOriginDirectory(kOrigin2)))));
357 EXPECT_EQ(1, base::WriteFile(
358 tracker->GetFullDBFilePath(kOrigin1, kDB1), "a", 1));
359 EXPECT_EQ(2, base::WriteFile(
360 tracker->GetFullDBFilePath(kOrigin2, kDB2), "aa", 2));
361 EXPECT_EQ(4, base::WriteFile(
362 tracker->GetFullDBFilePath(kOrigin1, kDB3), "aaaa", 4));
363 tracker->DatabaseModified(kOrigin1, kDB1);
364 CheckNotificationReceived(&observer1, kOrigin1, kDB1, 1);
365 CheckNotificationReceived(&observer2, kOrigin1, kDB1, 1);
366 tracker->DatabaseModified(kOrigin2, kDB2);
367 CheckNotificationReceived(&observer1, kOrigin2, kDB2, 2);
368 CheckNotificationReceived(&observer2, kOrigin2, kDB2, 2);
369 tracker->DatabaseModified(kOrigin1, kDB3);
370 CheckNotificationReceived(&observer1, kOrigin1, kDB3, 4);
371 CheckNotificationReceived(&observer2, kOrigin1, kDB3, 4);
372
373 // Close all databases
374 tracker->DatabaseClosed(kOrigin1, kDB1);
375 tracker->DatabaseClosed(kOrigin2, kDB2);
376 tracker->DatabaseClosed(kOrigin1, kDB3);
377
378 // Open an existing database and check the reported size
379 tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0,
380 &database_size);
381 EXPECT_EQ(1, database_size);
382 tracker->DatabaseClosed(kOrigin1, kDB1);
383
384 // Remove an observer; this should clear all caches.
385 tracker->RemoveObserver(&observer2);
386
387 // Close the tracker database and clear all caches.
388 // Then make sure that DatabaseOpened() still returns the correct result.
389 tracker->CloseTrackerDatabaseAndClearCaches();
390 tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0,
391 &database_size);
392 EXPECT_EQ(1, database_size);
393 tracker->DatabaseClosed(kOrigin1, kDB1);
394
395 // Remove all observers.
396 tracker->RemoveObserver(&observer1);
397
398 // Trying to delete a database in use should fail
399 tracker->DatabaseOpened(kOrigin1, kDB3, kDescription, 0,
400 &database_size);
401 EXPECT_FALSE(tracker->DeleteClosedDatabase(kOrigin1, kDB3));
402 origin1_info = tracker->GetCachedOriginInfo(kOrigin1);
403 EXPECT_TRUE(origin1_info);
404 EXPECT_EQ(4, origin1_info->GetDatabaseSize(kDB3));
405 tracker->DatabaseClosed(kOrigin1, kDB3);
406
407 // Delete a database and make sure the space used by that origin is updated
408 EXPECT_TRUE(tracker->DeleteClosedDatabase(kOrigin1, kDB3));
409 origin1_info = tracker->GetCachedOriginInfo(kOrigin1);
410 EXPECT_TRUE(origin1_info);
411 EXPECT_EQ(1, origin1_info->GetDatabaseSize(kDB1));
412 EXPECT_EQ(0, origin1_info->GetDatabaseSize(kDB3));
413
414 // Get all data for all origins
415 std::vector<OriginInfo> origins_info;
416 EXPECT_TRUE(tracker->GetAllOriginsInfo(&origins_info));
417 EXPECT_EQ(size_t(2), origins_info.size());
418 EXPECT_EQ(kOrigin1, origins_info[0].GetOriginIdentifier());
419 EXPECT_EQ(1, origins_info[0].TotalSize());
420 EXPECT_EQ(1, origins_info[0].GetDatabaseSize(kDB1));
421 EXPECT_EQ(0, origins_info[0].GetDatabaseSize(kDB3));
422
423 EXPECT_EQ(kOrigin2, origins_info[1].GetOriginIdentifier());
424 EXPECT_EQ(2, origins_info[1].TotalSize());
425
426 // Trying to delete an origin with databases in use should fail
427 tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0,
428 &database_size);
429 EXPECT_FALSE(tracker->DeleteOrigin(kOrigin1, false));
430 origin1_info = tracker->GetCachedOriginInfo(kOrigin1);
431 EXPECT_TRUE(origin1_info);
432 EXPECT_EQ(1, origin1_info->GetDatabaseSize(kDB1));
433 tracker->DatabaseClosed(kOrigin1, kDB1);
434
435 // Delete an origin that doesn't have any database in use
436 EXPECT_TRUE(tracker->DeleteOrigin(kOrigin1, false));
437 origins_info.clear();
438 EXPECT_TRUE(tracker->GetAllOriginsInfo(&origins_info));
439 EXPECT_EQ(size_t(1), origins_info.size());
440 EXPECT_EQ(kOrigin2, origins_info[0].GetOriginIdentifier());
441
442 origin1_info = tracker->GetCachedOriginInfo(kOrigin1);
443 EXPECT_TRUE(origin1_info);
444 EXPECT_EQ(0, origin1_info->TotalSize());
445 }
446
447 static void DatabaseTrackerQuotaIntegration() {
448 const GURL kOrigin(kOrigin1Url);
449 const std::string kOriginId = storage::GetIdentifierFromOrigin(kOrigin);
450 const base::string16 kName = ASCIIToUTF16("name");
451 const base::string16 kDescription = ASCIIToUTF16("description");
452
453 base::ScopedTempDir temp_dir;
454 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
455
456 // Initialize the tracker with a QuotaManagerProxy
457 scoped_refptr<TestQuotaManagerProxy> test_quota_proxy(
458 new TestQuotaManagerProxy);
459 scoped_refptr<DatabaseTracker> tracker(
460 new DatabaseTracker(temp_dir.GetPath(), false /* incognito */, NULL,
461 test_quota_proxy.get(), NULL));
462 EXPECT_TRUE(test_quota_proxy->registered_client_);
463
464 // Create a database and modify it a couple of times, close it,
465 // then delete it. Observe the tracker notifies accordingly.
466
467 int64_t database_size = 0;
468 tracker->DatabaseOpened(kOriginId, kName, kDescription, 0,
469 &database_size);
470 EXPECT_TRUE(test_quota_proxy->WasAccessNotified(kOrigin));
471 test_quota_proxy->reset();
472
473 base::FilePath db_file(tracker->GetFullDBFilePath(kOriginId, kName));
474 EXPECT_TRUE(base::CreateDirectory(db_file.DirName()));
475 EXPECT_TRUE(EnsureFileOfSize(db_file, 10));
476 tracker->DatabaseModified(kOriginId, kName);
477 EXPECT_TRUE(test_quota_proxy->WasModificationNotified(kOrigin, 10));
478 test_quota_proxy->reset();
479
480 EXPECT_TRUE(EnsureFileOfSize(db_file, 100));
481 tracker->DatabaseModified(kOriginId, kName);
482 EXPECT_TRUE(test_quota_proxy->WasModificationNotified(kOrigin, 90));
483 test_quota_proxy->reset();
484
485 tracker->DatabaseClosed(kOriginId, kName);
486 EXPECT_TRUE(test_quota_proxy->WasAccessNotified(kOrigin));
487 EXPECT_EQ(net::OK, tracker->DeleteDatabase(
488 kOriginId, kName, net::CompletionCallback()));
489 EXPECT_TRUE(test_quota_proxy->WasModificationNotified(kOrigin, -100));
490 test_quota_proxy->reset();
491
492 // Create a database and modify it, try to delete it while open,
493 // then close it (at which time deletion will actually occur).
494 // Observe the tracker notifies accordingly.
495
496 tracker->DatabaseOpened(kOriginId, kName, kDescription, 0,
497 &database_size);
498 EXPECT_TRUE(test_quota_proxy->WasAccessNotified(kOrigin));
499 test_quota_proxy->reset();
500
501 db_file = tracker->GetFullDBFilePath(kOriginId, kName);
502 EXPECT_TRUE(base::CreateDirectory(db_file.DirName()));
503 EXPECT_TRUE(EnsureFileOfSize(db_file, 100));
504 tracker->DatabaseModified(kOriginId, kName);
505 EXPECT_TRUE(test_quota_proxy->WasModificationNotified(kOrigin, 100));
506 test_quota_proxy->reset();
507
508 EXPECT_EQ(net::ERR_IO_PENDING,
509 tracker->DeleteDatabase(kOriginId, kName,
510 net::CompletionCallback()));
511 EXPECT_FALSE(test_quota_proxy->WasModificationNotified(kOrigin, -100));
512
513 tracker->DatabaseClosed(kOriginId, kName);
514 EXPECT_TRUE(test_quota_proxy->WasAccessNotified(kOrigin));
515 EXPECT_TRUE(test_quota_proxy->WasModificationNotified(kOrigin, -100));
516 test_quota_proxy->reset();
517
518 // Create a database and up the file size without telling
519 // the tracker about the modification, than simulate a
520 // a renderer crash.
521 // Observe the tracker notifies accordingly.
522
523 tracker->DatabaseOpened(kOriginId, kName, kDescription, 0,
524 &database_size);
525 EXPECT_TRUE(test_quota_proxy->WasAccessNotified(kOrigin));
526 test_quota_proxy->reset();
527 db_file = tracker->GetFullDBFilePath(kOriginId, kName);
528 EXPECT_TRUE(base::CreateDirectory(db_file.DirName()));
529 EXPECT_TRUE(EnsureFileOfSize(db_file, 100));
530 DatabaseConnections crashed_renderer_connections;
531 crashed_renderer_connections.AddConnection(kOriginId, kName);
532 EXPECT_FALSE(test_quota_proxy->WasModificationNotified(kOrigin, 100));
533 tracker->CloseDatabases(crashed_renderer_connections);
534 EXPECT_TRUE(test_quota_proxy->WasModificationNotified(kOrigin, 100));
535
536 // Cleanup.
537 crashed_renderer_connections.RemoveAllConnections();
538 test_quota_proxy->SimulateQuotaManagerDestroyed();
539 }
540
541 static void DatabaseTrackerClearSessionOnlyDatabasesOnExit() {
542 int64_t database_size = 0;
543 const std::string kOrigin1 =
544 storage::GetIdentifierFromOrigin(GURL(kOrigin1Url));
545 const std::string kOrigin2 =
546 storage::GetIdentifierFromOrigin(GURL(kOrigin2Url));
547 const base::string16 kDB1 = ASCIIToUTF16("db1");
548 const base::string16 kDB2 = ASCIIToUTF16("db2");
549 const base::string16 kDescription = ASCIIToUTF16("database_description");
550
551 // Initialize the tracker database.
552 base::MessageLoop message_loop;
553 base::ScopedTempDir temp_dir;
554 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
555 base::FilePath origin1_db_dir;
556 base::FilePath origin2_db_dir;
557 {
558 scoped_refptr<MockSpecialStoragePolicy> special_storage_policy =
559 new MockSpecialStoragePolicy;
560 special_storage_policy->AddSessionOnly(GURL(kOrigin2Url));
561 scoped_refptr<DatabaseTracker> tracker(new DatabaseTracker(
562 temp_dir.GetPath(), false, special_storage_policy.get(), NULL,
563 base::ThreadTaskRunnerHandle::Get().get()));
564
565 // Open two new databases.
566 tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0,
567 &database_size);
568 EXPECT_EQ(0, database_size);
569 tracker->DatabaseOpened(kOrigin2, kDB2, kDescription, 0,
570 &database_size);
571 EXPECT_EQ(0, database_size);
572
573 // Write some data to each file.
574 base::FilePath db_file;
575 db_file = tracker->GetFullDBFilePath(kOrigin1, kDB1);
576 EXPECT_TRUE(base::CreateDirectory(db_file.DirName()));
577 EXPECT_TRUE(EnsureFileOfSize(db_file, 1));
578
579 db_file = tracker->GetFullDBFilePath(kOrigin2, kDB2);
580 EXPECT_TRUE(base::CreateDirectory(db_file.DirName()));
581 EXPECT_TRUE(EnsureFileOfSize(db_file, 2));
582
583 // Store the origin database directories as long as they still exist.
584 origin1_db_dir = tracker->GetFullDBFilePath(kOrigin1, kDB1).DirName();
585 origin2_db_dir = tracker->GetFullDBFilePath(kOrigin2, kDB2).DirName();
586
587 tracker->DatabaseModified(kOrigin1, kDB1);
588 tracker->DatabaseModified(kOrigin2, kDB2);
589
590 // Close all databases.
591 tracker->DatabaseClosed(kOrigin1, kDB1);
592 tracker->DatabaseClosed(kOrigin2, kDB2);
593
594 tracker->Shutdown();
595 }
596
597 // At this point, the database tracker should be gone. Create a new one.
598 scoped_refptr<DatabaseTracker> tracker(
599 new DatabaseTracker(temp_dir.GetPath(), false, NULL, NULL, NULL));
600
601 // Get all data for all origins.
602 std::vector<OriginInfo> origins_info;
603 EXPECT_TRUE(tracker->GetAllOriginsInfo(&origins_info));
604 // kOrigin1 was not session-only, so it survived. kOrigin2 was session-only
605 // and it got deleted.
606 EXPECT_EQ(size_t(1), origins_info.size());
607 EXPECT_EQ(kOrigin1, origins_info[0].GetOriginIdentifier());
608 EXPECT_TRUE(
609 base::PathExists(tracker->GetFullDBFilePath(kOrigin1, kDB1)));
610 EXPECT_EQ(base::FilePath(), tracker->GetFullDBFilePath(kOrigin2, kDB2));
611
612 // The origin directory of kOrigin1 remains, but the origin directory of
613 // kOrigin2 is deleted.
614 EXPECT_TRUE(base::PathExists(origin1_db_dir));
615 EXPECT_FALSE(base::PathExists(origin2_db_dir));
616 }
617
618 static void DatabaseTrackerSetForceKeepSessionState() {
619 int64_t database_size = 0;
620 const std::string kOrigin1 =
621 storage::GetIdentifierFromOrigin(GURL(kOrigin1Url));
622 const std::string kOrigin2 =
623 storage::GetIdentifierFromOrigin(GURL(kOrigin2Url));
624 const base::string16 kDB1 = ASCIIToUTF16("db1");
625 const base::string16 kDB2 = ASCIIToUTF16("db2");
626 const base::string16 kDescription = ASCIIToUTF16("database_description");
627
628 // Initialize the tracker database.
629 base::MessageLoop message_loop;
630 base::ScopedTempDir temp_dir;
631 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
632 base::FilePath origin1_db_dir;
633 base::FilePath origin2_db_dir;
634 {
635 scoped_refptr<MockSpecialStoragePolicy> special_storage_policy =
636 new MockSpecialStoragePolicy;
637 special_storage_policy->AddSessionOnly(GURL(kOrigin2Url));
638 scoped_refptr<DatabaseTracker> tracker(new DatabaseTracker(
639 temp_dir.GetPath(), false, special_storage_policy.get(), NULL,
640 base::ThreadTaskRunnerHandle::Get().get()));
641 tracker->SetForceKeepSessionState();
642
643 // Open two new databases.
644 tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0,
645 &database_size);
646 EXPECT_EQ(0, database_size);
647 tracker->DatabaseOpened(kOrigin2, kDB2, kDescription, 0,
648 &database_size);
649 EXPECT_EQ(0, database_size);
650
651 // Write some data to each file.
652 base::FilePath db_file;
653 db_file = tracker->GetFullDBFilePath(kOrigin1, kDB1);
654 EXPECT_TRUE(base::CreateDirectory(db_file.DirName()));
655 EXPECT_TRUE(EnsureFileOfSize(db_file, 1));
656
657 db_file = tracker->GetFullDBFilePath(kOrigin2, kDB2);
658 EXPECT_TRUE(base::CreateDirectory(db_file.DirName()));
659 EXPECT_TRUE(EnsureFileOfSize(db_file, 2));
660
661 // Store the origin database directories as long as they still exist.
662 origin1_db_dir = tracker->GetFullDBFilePath(kOrigin1, kDB1).DirName();
663 origin2_db_dir = tracker->GetFullDBFilePath(kOrigin2, kDB2).DirName();
664
665 tracker->DatabaseModified(kOrigin1, kDB1);
666 tracker->DatabaseModified(kOrigin2, kDB2);
667
668 // Close all databases.
669 tracker->DatabaseClosed(kOrigin1, kDB1);
670 tracker->DatabaseClosed(kOrigin2, kDB2);
671
672 tracker->Shutdown();
673 }
674
675 // At this point, the database tracker should be gone. Create a new one.
676 scoped_refptr<DatabaseTracker> tracker(
677 new DatabaseTracker(temp_dir.GetPath(), false, NULL, NULL, NULL));
678
679 // Get all data for all origins.
680 std::vector<OriginInfo> origins_info;
681 EXPECT_TRUE(tracker->GetAllOriginsInfo(&origins_info));
682 // No origins were deleted.
683 EXPECT_EQ(size_t(2), origins_info.size());
684 EXPECT_TRUE(
685 base::PathExists(tracker->GetFullDBFilePath(kOrigin1, kDB1)));
686 EXPECT_TRUE(
687 base::PathExists(tracker->GetFullDBFilePath(kOrigin2, kDB2)));
688
689 EXPECT_TRUE(base::PathExists(origin1_db_dir));
690 EXPECT_TRUE(base::PathExists(origin2_db_dir));
691 }
692
693 static void EmptyDatabaseNameIsValid() {
694 const GURL kOrigin(kOrigin1Url);
695 const std::string kOriginId = storage::GetIdentifierFromOrigin(kOrigin);
696 const base::string16 kEmptyName;
697 const base::string16 kDescription(ASCIIToUTF16("description"));
698 const base::string16 kChangedDescription(
699 ASCIIToUTF16("changed_description"));
700
701 // Initialize a tracker database, no need to put it on disk.
702 const bool kUseInMemoryTrackerDatabase = true;
703 base::ScopedTempDir temp_dir;
704 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
705 scoped_refptr<DatabaseTracker> tracker(new DatabaseTracker(
706 temp_dir.GetPath(), kUseInMemoryTrackerDatabase, NULL, NULL, NULL));
707
708 // Starts off with no databases.
709 std::vector<OriginInfo> infos;
710 EXPECT_TRUE(tracker->GetAllOriginsInfo(&infos));
711 EXPECT_TRUE(infos.empty());
712
713 // Create a db with an empty name.
714 int64_t database_size = -1;
715 tracker->DatabaseOpened(kOriginId, kEmptyName, kDescription, 0,
716 &database_size);
717 EXPECT_EQ(0, database_size);
718 tracker->DatabaseModified(kOriginId, kEmptyName);
719 EXPECT_TRUE(tracker->GetAllOriginsInfo(&infos));
720 EXPECT_EQ(1u, infos.size());
721 EXPECT_EQ(kDescription, infos[0].GetDatabaseDescription(kEmptyName));
722 EXPECT_FALSE(tracker->GetFullDBFilePath(kOriginId, kEmptyName).empty());
723 tracker->DatabaseOpened(kOriginId, kEmptyName, kChangedDescription, 0,
724 &database_size);
725 infos.clear();
726 EXPECT_TRUE(tracker->GetAllOriginsInfo(&infos));
727 EXPECT_EQ(1u, infos.size());
728 EXPECT_EQ(kChangedDescription, infos[0].GetDatabaseDescription(kEmptyName));
729 tracker->DatabaseClosed(kOriginId, kEmptyName);
730 tracker->DatabaseClosed(kOriginId, kEmptyName);
731
732 // Deleting it should return to the initial state.
733 EXPECT_EQ(net::OK, tracker->DeleteDatabase(kOriginId, kEmptyName,
734 net::CompletionCallback()));
735 infos.clear();
736 EXPECT_TRUE(tracker->GetAllOriginsInfo(&infos));
737 EXPECT_TRUE(infos.empty());
738 }
739
740 static void HandleSqliteError() {
741 const GURL kOrigin(kOrigin1Url);
742 const std::string kOriginId = storage::GetIdentifierFromOrigin(kOrigin);
743 const base::string16 kName(ASCIIToUTF16("name"));
744 const base::string16 kDescription(ASCIIToUTF16("description"));
745
746 // Initialize a tracker database, no need to put it on disk.
747 const bool kUseInMemoryTrackerDatabase = true;
748 base::ScopedTempDir temp_dir;
749 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
750 scoped_refptr<DatabaseTracker> tracker(new DatabaseTracker(
751 temp_dir.GetPath(), kUseInMemoryTrackerDatabase, NULL, NULL, NULL));
752
753 // Setup to observe OnScheduledForDelete notifications.
754 TestObserver observer(false, true);
755 tracker->AddObserver(&observer);
756
757 // Verify does no harm when there is no such database.
758 tracker->HandleSqliteError(kOriginId, kName, SQLITE_CORRUPT);
759 EXPECT_FALSE(tracker->IsDatabaseScheduledForDeletion(kOriginId, kName));
760 EXPECT_FALSE(observer.DidReceiveNewNotification());
761
762 // --------------------------------------------------------
763 // Create a record of a database in the tracker db and create
764 // a spoof_db_file on disk in the expected location.
765 int64_t database_size = 0;
766 tracker->DatabaseOpened(kOriginId, kName, kDescription, 0,
767 &database_size);
768 base::FilePath spoof_db_file = tracker->GetFullDBFilePath(kOriginId, kName);
769 EXPECT_FALSE(tracker->GetFullDBFilePath(kOriginId, kName).empty());
770 EXPECT_TRUE(base::CreateDirectory(spoof_db_file.DirName()));
771 EXPECT_TRUE(EnsureFileOfSize(spoof_db_file, 1));
772
773 // Verify does no harm with a non-error is reported.
774 tracker->HandleSqliteError(kOriginId, kName, SQLITE_OK);
775 EXPECT_FALSE(tracker->IsDatabaseScheduledForDeletion(kOriginId, kName));
776 EXPECT_FALSE(observer.DidReceiveNewNotification());
777
778 // Verify that with a connection open, the db is scheduled for deletion,
779 // but that the file still exists.
780 tracker->HandleSqliteError(kOriginId, kName, SQLITE_CORRUPT);
781 EXPECT_TRUE(tracker->IsDatabaseScheduledForDeletion(kOriginId, kName));
782 EXPECT_TRUE(observer.DidReceiveNewNotification());
783 EXPECT_TRUE(base::PathExists(spoof_db_file));
784
785 // Verify that once closed, the file is deleted and the record in the
786 // tracker db is removed.
787 tracker->DatabaseClosed(kOriginId, kName);
788 EXPECT_FALSE(base::PathExists(spoof_db_file));
789 EXPECT_TRUE(tracker->GetFullDBFilePath(kOriginId, kName).empty());
790
791 // --------------------------------------------------------
792 // Create another record of a database in the tracker db and create
793 // a spoof_db_file on disk in the expected location.
794 tracker->DatabaseOpened(kOriginId, kName, kDescription, 0,
795 &database_size);
796 base::FilePath spoof_db_file2 = tracker->GetFullDBFilePath(kOriginId,
797 kName);
798 EXPECT_FALSE(tracker->GetFullDBFilePath(kOriginId, kName).empty());
799 EXPECT_NE(spoof_db_file, spoof_db_file2);
800 EXPECT_TRUE(base::CreateDirectory(spoof_db_file2.DirName()));
801 EXPECT_TRUE(EnsureFileOfSize(spoof_db_file2, 1));
802
803 // Verify that with no connection open, the db is deleted immediately.
804 tracker->DatabaseClosed(kOriginId, kName);
805 tracker->HandleSqliteError(kOriginId, kName, SQLITE_CORRUPT);
806 EXPECT_FALSE(tracker->IsDatabaseScheduledForDeletion(kOriginId, kName));
807 EXPECT_FALSE(observer.DidReceiveNewNotification());
808 EXPECT_TRUE(tracker->GetFullDBFilePath(kOriginId, kName).empty());
809 EXPECT_FALSE(base::PathExists(spoof_db_file2));
810
811 tracker->RemoveObserver(&observer);
812 }
813 };
814
815 TEST(DatabaseTrackerTest, DeleteOpenDatabase) {
816 DatabaseTracker_TestHelper_Test::TestDeleteOpenDatabase(false);
817 }
818
819 TEST(DatabaseTrackerTest, DeleteOpenDatabaseIncognitoMode) {
820 DatabaseTracker_TestHelper_Test::TestDeleteOpenDatabase(true);
821 }
822
823 TEST(DatabaseTrackerTest, DatabaseTracker) {
824 DatabaseTracker_TestHelper_Test::TestDatabaseTracker(false);
825 }
826
827 TEST(DatabaseTrackerTest, DatabaseTrackerIncognitoMode) {
828 DatabaseTracker_TestHelper_Test::TestDatabaseTracker(true);
829 }
830
831 TEST(DatabaseTrackerTest, DatabaseTrackerQuotaIntegration) {
832 // There is no difference in behavior between incognito and not.
833 DatabaseTracker_TestHelper_Test::DatabaseTrackerQuotaIntegration();
834 }
835
836 TEST(DatabaseTrackerTest, DatabaseTrackerClearSessionOnlyDatabasesOnExit) {
837 // Only works for regular mode.
838 DatabaseTracker_TestHelper_Test::
839 DatabaseTrackerClearSessionOnlyDatabasesOnExit();
840 }
841
842 TEST(DatabaseTrackerTest, DatabaseTrackerSetForceKeepSessionState) {
843 // Only works for regular mode.
844 DatabaseTracker_TestHelper_Test::DatabaseTrackerSetForceKeepSessionState();
845 }
846
847 TEST(DatabaseTrackerTest, EmptyDatabaseNameIsValid) {
848 DatabaseTracker_TestHelper_Test::EmptyDatabaseNameIsValid();
849 }
850
851 TEST(DatabaseTrackerTest, HandleSqliteError) {
852 DatabaseTracker_TestHelper_Test::HandleSqliteError();
853 }
854
855 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | content/test/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698