| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "base/file_path.h" | 5 #include "base/file_path.h" |
| 6 #include "base/file_util.h" | 6 #include "base/file_util.h" |
| 7 #include "base/scoped_ptr.h" | 7 #include "base/scoped_ptr.h" |
| 8 #include "base/scoped_temp_dir.h" | 8 #include "base/scoped_temp_dir.h" |
| 9 #include "base/time.h" | 9 #include "base/time.h" |
| 10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 EXPECT_EQ(expected_database_size, | 65 EXPECT_EQ(expected_database_size, |
| 66 observer->GetNotificationDatabaseSize()); | 66 observer->GetNotificationDatabaseSize()); |
| 67 EXPECT_EQ(expected_space_available, | 67 EXPECT_EQ(expected_space_available, |
| 68 observer->GetNotificationSpaceAvailable()); | 68 observer->GetNotificationSpaceAvailable()); |
| 69 } | 69 } |
| 70 | 70 |
| 71 } // namespace | 71 } // namespace |
| 72 | 72 |
| 73 namespace webkit_database { | 73 namespace webkit_database { |
| 74 | 74 |
| 75 // We declare a helper class, and make it a friend of DatabaseTracker using |
| 76 // the FRIEND_TEST() macro, and we implement all tests we want to run as |
| 77 // static methods of this class. Then we make our TEST() targets call these |
| 78 // static functions. This allows us to run each test in normal mode and |
| 79 // incognito mode without writing the same code twice. |
| 80 class DatabaseTracker_TestHelper_Test { |
| 81 public: |
| 82 static void TestDeleteOpenDatabase(bool incognito_mode) { |
| 83 // Initialize the tracker database. |
| 84 ScopedTempDir temp_dir; |
| 85 EXPECT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 86 scoped_refptr<DatabaseTracker> tracker( |
| 87 new DatabaseTracker(temp_dir.path(), incognito_mode)); |
| 88 |
| 89 // Create and open three databases. |
| 90 int64 database_size = 0; |
| 91 int64 space_available = 0; |
| 92 const string16 kOrigin1 = ASCIIToUTF16("origin1"); |
| 93 const string16 kOrigin2 = ASCIIToUTF16("origin2"); |
| 94 const string16 kDB1 = ASCIIToUTF16("db1"); |
| 95 const string16 kDB2 = ASCIIToUTF16("db2"); |
| 96 const string16 kDB3 = ASCIIToUTF16("db3"); |
| 97 const string16 kDescription = ASCIIToUTF16("database_description"); |
| 98 |
| 99 tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, |
| 100 &database_size, &space_available); |
| 101 tracker->DatabaseOpened(kOrigin2, kDB2, kDescription, 0, |
| 102 &database_size, &space_available); |
| 103 tracker->DatabaseOpened(kOrigin2, kDB3, kDescription, 0, |
| 104 &database_size, &space_available); |
| 105 |
| 106 EXPECT_TRUE(file_util::CreateDirectory(tracker->DatabaseDirectory().Append( |
| 107 FilePath::FromWStringHack(UTF16ToWide( |
| 108 tracker->GetOriginDirectory(kOrigin1)))))); |
| 109 EXPECT_TRUE(file_util::CreateDirectory(tracker->DatabaseDirectory().Append( |
| 110 FilePath::FromWStringHack(UTF16ToWide( |
| 111 tracker->GetOriginDirectory(kOrigin2)))))); |
| 112 EXPECT_EQ(1, file_util::WriteFile( |
| 113 tracker->GetFullDBFilePath(kOrigin1, kDB1), "a", 1)); |
| 114 EXPECT_EQ(2, file_util::WriteFile( |
| 115 tracker->GetFullDBFilePath(kOrigin2, kDB2), "aa", 2)); |
| 116 EXPECT_EQ(3, file_util::WriteFile( |
| 117 tracker->GetFullDBFilePath(kOrigin2, kDB3), "aaa", 3)); |
| 118 tracker->DatabaseModified(kOrigin1, kDB1); |
| 119 tracker->DatabaseModified(kOrigin2, kDB2); |
| 120 tracker->DatabaseModified(kOrigin2, kDB3); |
| 121 |
| 122 // Delete db1. Should also delete origin1. |
| 123 TestObserver observer; |
| 124 tracker->AddObserver(&observer); |
| 125 TestCompletionCallback callback; |
| 126 int result = tracker->DeleteDatabase(kOrigin1, kDB1, &callback); |
| 127 EXPECT_EQ(net::ERR_IO_PENDING, result); |
| 128 ASSERT_FALSE(callback.have_result()); |
| 129 EXPECT_TRUE(observer.DidReceiveNewNotification()); |
| 130 EXPECT_EQ(kOrigin1, observer.GetNotificationOriginIdentifier()); |
| 131 EXPECT_EQ(kDB1, observer.GetNotificationDatabaseName()); |
| 132 tracker->DatabaseClosed(kOrigin1, kDB1); |
| 133 result = callback.GetResult(result); |
| 134 EXPECT_EQ(net::OK, result); |
| 135 EXPECT_FALSE(file_util::PathExists(tracker->DatabaseDirectory().Append( |
| 136 FilePath::FromWStringHack(UTF16ToWide(kOrigin1))))); |
| 137 |
| 138 // Recreate db1. |
| 139 tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, |
| 140 &database_size, &space_available); |
| 141 EXPECT_TRUE(file_util::CreateDirectory(tracker->DatabaseDirectory().Append( |
| 142 FilePath::FromWStringHack(UTF16ToWide( |
| 143 tracker->GetOriginDirectory(kOrigin1)))))); |
| 144 EXPECT_EQ(1, file_util::WriteFile( |
| 145 tracker->GetFullDBFilePath(kOrigin1, kDB1), "a", 1)); |
| 146 tracker->DatabaseModified(kOrigin1, kDB1); |
| 147 |
| 148 // Setup file modification times. db1 and db2 are modified now, db3 three |
| 149 // days ago. |
| 150 EXPECT_TRUE(file_util::SetLastModifiedTime( |
| 151 tracker->GetFullDBFilePath(kOrigin1, kDB1), base::Time::Now())); |
| 152 EXPECT_TRUE(file_util::SetLastModifiedTime( |
| 153 tracker->GetFullDBFilePath(kOrigin2, kDB2), base::Time::Now())); |
| 154 base::Time three_days_ago = base::Time::Now(); |
| 155 three_days_ago -= base::TimeDelta::FromDays(3); |
| 156 EXPECT_TRUE(file_util::SetLastModifiedTime( |
| 157 tracker->GetFullDBFilePath(kOrigin2, kDB3), three_days_ago)); |
| 158 |
| 159 // Delete databases modified since yesterday. |
| 160 base::Time yesterday = base::Time::Now(); |
| 161 yesterday -= base::TimeDelta::FromDays(1); |
| 162 result = tracker->DeleteDataModifiedSince(yesterday, &callback); |
| 163 EXPECT_EQ(net::ERR_IO_PENDING, result); |
| 164 ASSERT_FALSE(callback.have_result()); |
| 165 EXPECT_TRUE(observer.DidReceiveNewNotification()); |
| 166 tracker->DatabaseClosed(kOrigin1, kDB1); |
| 167 tracker->DatabaseClosed(kOrigin2, kDB2); |
| 168 result = callback.GetResult(result); |
| 169 EXPECT_EQ(net::OK, result); |
| 170 EXPECT_FALSE(file_util::PathExists(tracker->DatabaseDirectory().Append( |
| 171 FilePath::FromWStringHack(UTF16ToWide(kOrigin1))))); |
| 172 EXPECT_FALSE( |
| 173 file_util::PathExists(tracker->GetFullDBFilePath(kOrigin2, kDB2))); |
| 174 EXPECT_TRUE( |
| 175 file_util::PathExists(tracker->GetFullDBFilePath(kOrigin2, kDB3))); |
| 176 |
| 177 tracker->DatabaseClosed(kOrigin2, kDB3); |
| 178 tracker->RemoveObserver(&observer); |
| 179 } |
| 180 |
| 181 static void TestDatabaseTracker(bool incognito_mode) { |
| 182 // Initialize the tracker database. |
| 183 ScopedTempDir temp_dir; |
| 184 EXPECT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 185 scoped_refptr<DatabaseTracker> tracker( |
| 186 new DatabaseTracker(temp_dir.path(), incognito_mode)); |
| 187 |
| 188 // Add two observers. |
| 189 TestObserver observer1; |
| 190 TestObserver observer2; |
| 191 tracker->AddObserver(&observer1); |
| 192 tracker->AddObserver(&observer2); |
| 193 |
| 194 // Open three new databases. |
| 195 int64 database_size = 0; |
| 196 int64 space_available = 0; |
| 197 const string16 kOrigin1 = ASCIIToUTF16("origin1"); |
| 198 const string16 kOrigin2 = ASCIIToUTF16("origin2"); |
| 199 const string16 kDB1 = ASCIIToUTF16("db1"); |
| 200 const string16 kDB2 = ASCIIToUTF16("db2"); |
| 201 const string16 kDB3 = ASCIIToUTF16("db3"); |
| 202 const string16 kDescription = ASCIIToUTF16("database_description"); |
| 203 |
| 204 // Get the quota for kOrigin1 and kOrigin2 |
| 205 DatabaseTracker::CachedOriginInfo* origin1_info = |
| 206 tracker->GetCachedOriginInfo(kOrigin1); |
| 207 DatabaseTracker::CachedOriginInfo* origin2_info = |
| 208 tracker->GetCachedOriginInfo(kOrigin1); |
| 209 EXPECT_TRUE(origin1_info); |
| 210 EXPECT_TRUE(origin2_info); |
| 211 int64 origin1_quota = origin1_info->Quota(); |
| 212 int64 origin2_quota = origin2_info->Quota(); |
| 213 EXPECT_EQ(origin1_quota, tracker->GetOriginSpaceAvailable(kOrigin1)); |
| 214 EXPECT_EQ(origin2_quota, tracker->GetOriginSpaceAvailable(kOrigin2)); |
| 215 |
| 216 // Set a new quota for kOrigin1 |
| 217 origin1_quota *= 2; |
| 218 tracker->SetOriginQuota(kOrigin1, origin1_quota); |
| 219 origin1_info = tracker->GetCachedOriginInfo(kOrigin1); |
| 220 EXPECT_TRUE(origin1_info); |
| 221 EXPECT_EQ(origin1_quota, origin1_info->Quota()); |
| 222 |
| 223 tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, |
| 224 &database_size, &space_available); |
| 225 EXPECT_EQ(0, database_size); |
| 226 EXPECT_EQ(origin1_quota, space_available); |
| 227 tracker->DatabaseOpened(kOrigin2, kDB2, kDescription, 0, |
| 228 &database_size, &space_available); |
| 229 EXPECT_EQ(0, database_size); |
| 230 EXPECT_EQ(origin2_quota, space_available); |
| 231 tracker->DatabaseOpened(kOrigin1, kDB3, kDescription, 0, |
| 232 &database_size, &space_available); |
| 233 EXPECT_EQ(0, database_size); |
| 234 EXPECT_EQ(origin1_quota, space_available); |
| 235 |
| 236 // Tell the tracker that a database has changed. |
| 237 // Even though nothing has changed, the observers should be notified. |
| 238 tracker->DatabaseModified(kOrigin1, kDB1); |
| 239 CheckNotificationReceived(&observer1, kOrigin1, kDB1, 0, origin1_quota); |
| 240 CheckNotificationReceived(&observer2, kOrigin1, kDB1, 0, origin1_quota); |
| 241 |
| 242 // Write some data to each file and check that the listeners are |
| 243 // called with the appropriate values. |
| 244 EXPECT_TRUE(file_util::CreateDirectory(tracker->DatabaseDirectory().Append( |
| 245 FilePath::FromWStringHack(UTF16ToWide( |
| 246 tracker->GetOriginDirectory(kOrigin1)))))); |
| 247 EXPECT_TRUE(file_util::CreateDirectory(tracker->DatabaseDirectory().Append( |
| 248 FilePath::FromWStringHack(UTF16ToWide( |
| 249 tracker->GetOriginDirectory(kOrigin2)))))); |
| 250 EXPECT_EQ(1, file_util::WriteFile( |
| 251 tracker->GetFullDBFilePath(kOrigin1, kDB1), "a", 1)); |
| 252 EXPECT_EQ(2, file_util::WriteFile( |
| 253 tracker->GetFullDBFilePath(kOrigin2, kDB2), "aa", 2)); |
| 254 EXPECT_EQ(4, file_util::WriteFile( |
| 255 tracker->GetFullDBFilePath(kOrigin1, kDB3), "aaaa", 4)); |
| 256 tracker->DatabaseModified(kOrigin1, kDB1); |
| 257 CheckNotificationReceived(&observer1, kOrigin1, kDB1, 1, origin1_quota - 1); |
| 258 CheckNotificationReceived(&observer2, kOrigin1, kDB1, 1, origin1_quota - 1); |
| 259 tracker->DatabaseModified(kOrigin2, kDB2); |
| 260 CheckNotificationReceived(&observer1, kOrigin2, kDB2, 2, origin2_quota - 2); |
| 261 CheckNotificationReceived(&observer2, kOrigin2, kDB2, 2, origin2_quota - 2); |
| 262 tracker->DatabaseModified(kOrigin1, kDB3); |
| 263 CheckNotificationReceived(&observer1, kOrigin1, kDB3, 4, origin1_quota - 5); |
| 264 CheckNotificationReceived(&observer2, kOrigin1, kDB3, 4, origin1_quota - 5); |
| 265 |
| 266 // Make sure the available space for kOrigin1 and kOrigin2 changed too. |
| 267 EXPECT_EQ(origin1_quota - 5, tracker->GetOriginSpaceAvailable(kOrigin1)); |
| 268 EXPECT_EQ(origin2_quota - 2, tracker->GetOriginSpaceAvailable(kOrigin2)); |
| 269 |
| 270 // Close all databases |
| 271 tracker->DatabaseClosed(kOrigin1, kDB1); |
| 272 tracker->DatabaseClosed(kOrigin2, kDB2); |
| 273 tracker->DatabaseClosed(kOrigin1, kDB3); |
| 274 |
| 275 // Open an existing database and check the reported size |
| 276 tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, |
| 277 &database_size, &space_available); |
| 278 EXPECT_EQ(1, database_size); |
| 279 EXPECT_EQ(origin1_quota - 5, space_available); |
| 280 |
| 281 // Make sure that the observers are notified even if |
| 282 // the size of the database hasn't changed. |
| 283 EXPECT_EQ(1, file_util::WriteFile( |
| 284 tracker->GetFullDBFilePath(kOrigin1, kDB1), "b", 1)); |
| 285 tracker->DatabaseModified(kOrigin1, kDB1); |
| 286 CheckNotificationReceived(&observer1, kOrigin1, kDB1, 1, origin1_quota - 5); |
| 287 CheckNotificationReceived(&observer2, kOrigin1, kDB1, 1, origin1_quota - 5); |
| 288 tracker->DatabaseClosed(kOrigin1, kDB1); |
| 289 |
| 290 // Remove an observer; this should clear all caches. |
| 291 tracker->RemoveObserver(&observer2); |
| 292 |
| 293 // Change kDB1's and kDB3's size and call tracker->DatabaseModified() |
| 294 // for kDB1 only. If the caches were indeed cleared, then calling |
| 295 // tracker->DatabaseModified() should re-populate the cache for |
| 296 // kOrigin1 == kOrigin1, and thus, should pick up kDB3's size change too. |
| 297 EXPECT_EQ(5, file_util::WriteFile( |
| 298 tracker->GetFullDBFilePath(kOrigin1, kDB1), "ccccc", 5)); |
| 299 EXPECT_EQ(6, file_util::WriteFile( |
| 300 tracker->GetFullDBFilePath(kOrigin1, kDB3), "dddddd", 6)); |
| 301 tracker->DatabaseModified(kOrigin1, kDB1); |
| 302 CheckNotificationReceived(&observer1, kOrigin1, kDB1, 5, |
| 303 origin1_quota - 11); |
| 304 EXPECT_FALSE(observer2.DidReceiveNewNotification()); |
| 305 EXPECT_EQ(origin1_quota - 11, tracker->GetOriginSpaceAvailable(kOrigin1)); |
| 306 |
| 307 // Close the tracker database and clear all caches. |
| 308 // Then make sure that DatabaseOpened() still returns the correct result. |
| 309 tracker->CloseTrackerDatabaseAndClearCaches(); |
| 310 tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, |
| 311 &database_size, &space_available); |
| 312 EXPECT_EQ(5, database_size); |
| 313 EXPECT_EQ(origin1_quota - 11, space_available); |
| 314 |
| 315 // Close the tracker database and clear all caches. Then make sure that |
| 316 // DatabaseModified() still calls the observers with correct values. |
| 317 tracker->CloseTrackerDatabaseAndClearCaches(); |
| 318 tracker->DatabaseModified(kOrigin1, kDB3); |
| 319 CheckNotificationReceived(&observer1, kOrigin1, kDB3, 6, |
| 320 origin1_quota - 11); |
| 321 tracker->DatabaseClosed(kOrigin1, kDB1); |
| 322 |
| 323 // Remove all observers. |
| 324 tracker->RemoveObserver(&observer1); |
| 325 |
| 326 // Trying to delete a database in use should fail |
| 327 tracker->DatabaseOpened(kOrigin1, kDB3, kDescription, 0, |
| 328 &database_size, &space_available); |
| 329 EXPECT_FALSE(tracker->DeleteClosedDatabase(kOrigin1, kDB3)); |
| 330 origin1_info = tracker->GetCachedOriginInfo(kOrigin1); |
| 331 EXPECT_TRUE(origin1_info); |
| 332 EXPECT_EQ(6, origin1_info->GetDatabaseSize(kDB3)); |
| 333 tracker->DatabaseClosed(kOrigin1, kDB3); |
| 334 |
| 335 // Delete a database and make sure the space used by that origin is updated |
| 336 EXPECT_TRUE(tracker->DeleteClosedDatabase(kOrigin1, kDB3)); |
| 337 origin1_info = tracker->GetCachedOriginInfo(kOrigin1); |
| 338 EXPECT_TRUE(origin1_info); |
| 339 EXPECT_EQ(origin1_quota - 5, tracker->GetOriginSpaceAvailable(kOrigin1)); |
| 340 EXPECT_EQ(5, origin1_info->GetDatabaseSize(kDB1)); |
| 341 EXPECT_EQ(0, origin1_info->GetDatabaseSize(kDB3)); |
| 342 |
| 343 // Get all data for all origins |
| 344 std::vector<OriginInfo> origins_info; |
| 345 EXPECT_TRUE(tracker->GetAllOriginsInfo(&origins_info)); |
| 346 EXPECT_EQ(size_t(2), origins_info.size()); |
| 347 EXPECT_EQ(kOrigin1, origins_info[0].GetOrigin()); |
| 348 EXPECT_EQ(5, origins_info[0].TotalSize()); |
| 349 EXPECT_EQ(origin1_quota, origins_info[0].Quota()); |
| 350 EXPECT_EQ(5, origins_info[0].GetDatabaseSize(kDB1)); |
| 351 EXPECT_EQ(0, origins_info[0].GetDatabaseSize(kDB3)); |
| 352 |
| 353 EXPECT_EQ(kOrigin2, origins_info[1].GetOrigin()); |
| 354 EXPECT_EQ(2, origins_info[1].TotalSize()); |
| 355 EXPECT_EQ(origin2_quota, origins_info[1].Quota()); |
| 356 |
| 357 // Trying to delete an origin with databases in use should fail |
| 358 tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, |
| 359 &database_size, &space_available); |
| 360 EXPECT_FALSE(tracker->DeleteOrigin(kOrigin1)); |
| 361 origin1_info = tracker->GetCachedOriginInfo(kOrigin1); |
| 362 EXPECT_TRUE(origin1_info); |
| 363 EXPECT_EQ(5, origin1_info->GetDatabaseSize(kDB1)); |
| 364 tracker->DatabaseClosed(kOrigin1, kDB1); |
| 365 |
| 366 // Delete an origin that doesn't have any database in use |
| 367 EXPECT_TRUE(tracker->DeleteOrigin(kOrigin1)); |
| 368 origins_info.clear(); |
| 369 EXPECT_TRUE(tracker->GetAllOriginsInfo(&origins_info)); |
| 370 EXPECT_EQ(size_t(1), origins_info.size()); |
| 371 EXPECT_EQ(kOrigin2, origins_info[0].GetOrigin()); |
| 372 |
| 373 origin1_info = tracker->GetCachedOriginInfo(kOrigin1); |
| 374 EXPECT_TRUE(origin1_info); |
| 375 EXPECT_EQ(origin1_quota, origin1_info->Quota()); |
| 376 EXPECT_EQ(0, origin1_info->TotalSize()); |
| 377 EXPECT_EQ(origin1_quota, tracker->GetOriginSpaceAvailable(kOrigin1)); |
| 378 } |
| 379 }; |
| 380 |
| 75 TEST(DatabaseTrackerTest, DeleteOpenDatabase) { | 381 TEST(DatabaseTrackerTest, DeleteOpenDatabase) { |
| 76 // Initialize the tracker database. | 382 DatabaseTracker_TestHelper_Test::TestDeleteOpenDatabase(false); |
| 77 ScopedTempDir temp_dir; | |
| 78 EXPECT_TRUE(temp_dir.CreateUniqueTempDir()); | |
| 79 scoped_refptr<DatabaseTracker> tracker(new DatabaseTracker(temp_dir.path())); | |
| 80 | |
| 81 // Create and open three databases. | |
| 82 int64 database_size = 0; | |
| 83 int64 space_available = 0; | |
| 84 const string16 kOrigin1 = ASCIIToUTF16("origin1"); | |
| 85 const string16 kOrigin2 = ASCIIToUTF16("origin2"); | |
| 86 const string16 kDB1 = ASCIIToUTF16("db1"); | |
| 87 const string16 kDB2 = ASCIIToUTF16("db2"); | |
| 88 const string16 kDB3 = ASCIIToUTF16("db3"); | |
| 89 const string16 kDescription = ASCIIToUTF16("database_description"); | |
| 90 | |
| 91 tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, | |
| 92 &database_size, &space_available); | |
| 93 tracker->DatabaseOpened(kOrigin2, kDB2, kDescription, 0, | |
| 94 &database_size, &space_available); | |
| 95 tracker->DatabaseOpened(kOrigin2, kDB3, kDescription, 0, | |
| 96 &database_size, &space_available); | |
| 97 | |
| 98 EXPECT_TRUE(file_util::CreateDirectory(tracker->DatabaseDirectory().Append( | |
| 99 FilePath::FromWStringHack(UTF16ToWide(kOrigin1))))); | |
| 100 EXPECT_TRUE(file_util::CreateDirectory(tracker->DatabaseDirectory().Append( | |
| 101 FilePath::FromWStringHack(UTF16ToWide(kOrigin2))))); | |
| 102 EXPECT_EQ(1, file_util::WriteFile( | |
| 103 tracker->GetFullDBFilePath(kOrigin1, kDB1), "a", 1)); | |
| 104 EXPECT_EQ(2, file_util::WriteFile( | |
| 105 tracker->GetFullDBFilePath(kOrigin2, kDB2), "aa", 2)); | |
| 106 EXPECT_EQ(3, file_util::WriteFile( | |
| 107 tracker->GetFullDBFilePath(kOrigin2, kDB3), "aaa", 3)); | |
| 108 tracker->DatabaseModified(kOrigin1, kDB1); | |
| 109 tracker->DatabaseModified(kOrigin2, kDB2); | |
| 110 tracker->DatabaseModified(kOrigin2, kDB3); | |
| 111 | |
| 112 // Delete db1. Should also delete origin1. | |
| 113 TestObserver observer; | |
| 114 tracker->AddObserver(&observer); | |
| 115 TestCompletionCallback callback; | |
| 116 int result = tracker->DeleteDatabase(kOrigin1, kDB1, &callback); | |
| 117 EXPECT_EQ(net::ERR_IO_PENDING, result); | |
| 118 ASSERT_FALSE(callback.have_result()); | |
| 119 EXPECT_TRUE(observer.DidReceiveNewNotification()); | |
| 120 EXPECT_EQ(kOrigin1, observer.GetNotificationOriginIdentifier()); | |
| 121 EXPECT_EQ(kDB1, observer.GetNotificationDatabaseName()); | |
| 122 tracker->DatabaseClosed(kOrigin1, kDB1); | |
| 123 result = callback.GetResult(result); | |
| 124 EXPECT_EQ(net::OK, result); | |
| 125 EXPECT_FALSE(file_util::PathExists(tracker->DatabaseDirectory().Append( | |
| 126 FilePath::FromWStringHack(UTF16ToWide(kOrigin1))))); | |
| 127 | |
| 128 // Recreate db1. | |
| 129 tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, | |
| 130 &database_size, &space_available); | |
| 131 EXPECT_TRUE(file_util::CreateDirectory(tracker->DatabaseDirectory().Append( | |
| 132 FilePath::FromWStringHack(UTF16ToWide(kOrigin1))))); | |
| 133 EXPECT_EQ(1, file_util::WriteFile( | |
| 134 tracker->GetFullDBFilePath(kOrigin1, kDB1), "a", 1)); | |
| 135 tracker->DatabaseModified(kOrigin1, kDB1); | |
| 136 | |
| 137 // Setup file modification times. db1 and db2 are modified now, db3 three | |
| 138 // days ago. | |
| 139 EXPECT_TRUE(file_util::SetLastModifiedTime( | |
| 140 tracker->GetFullDBFilePath(kOrigin1, kDB1), base::Time::Now())); | |
| 141 EXPECT_TRUE(file_util::SetLastModifiedTime( | |
| 142 tracker->GetFullDBFilePath(kOrigin2, kDB2), base::Time::Now())); | |
| 143 base::Time three_days_ago = base::Time::Now(); | |
| 144 three_days_ago -= base::TimeDelta::FromDays(3); | |
| 145 EXPECT_TRUE(file_util::SetLastModifiedTime( | |
| 146 tracker->GetFullDBFilePath(kOrigin2, kDB3), three_days_ago)); | |
| 147 | |
| 148 // Delete databases modified since yesterday. | |
| 149 base::Time yesterday = base::Time::Now(); | |
| 150 yesterday -= base::TimeDelta::FromDays(1); | |
| 151 result = tracker->DeleteDataModifiedSince(yesterday, &callback); | |
| 152 EXPECT_EQ(net::ERR_IO_PENDING, result); | |
| 153 ASSERT_FALSE(callback.have_result()); | |
| 154 EXPECT_TRUE(observer.DidReceiveNewNotification()); | |
| 155 tracker->DatabaseClosed(kOrigin1, kDB1); | |
| 156 tracker->DatabaseClosed(kOrigin2, kDB2); | |
| 157 result = callback.GetResult(result); | |
| 158 EXPECT_EQ(net::OK, result); | |
| 159 EXPECT_FALSE(file_util::PathExists(tracker->DatabaseDirectory().Append( | |
| 160 FilePath::FromWStringHack(UTF16ToWide(kOrigin1))))); | |
| 161 EXPECT_FALSE( | |
| 162 file_util::PathExists(tracker->GetFullDBFilePath(kOrigin2, kDB2))); | |
| 163 EXPECT_TRUE( | |
| 164 file_util::PathExists(tracker->GetFullDBFilePath(kOrigin2, kDB3))); | |
| 165 | |
| 166 tracker->DatabaseClosed(kOrigin2, kDB3); | |
| 167 tracker->RemoveObserver(&observer); | |
| 168 } | 383 } |
| 169 | 384 |
| 385 TEST(DatabaseTrackerTest, DeleteOpenDatabaseIncognitoMode) { |
| 386 DatabaseTracker_TestHelper_Test::TestDeleteOpenDatabase(true); |
| 387 } |
| 388 |
| 170 TEST(DatabaseTrackerTest, DatabaseTracker) { | 389 TEST(DatabaseTrackerTest, DatabaseTracker) { |
| 171 // Initialize the tracker database. | 390 DatabaseTracker_TestHelper_Test::TestDatabaseTracker(false); |
| 172 ScopedTempDir temp_dir; | |
| 173 EXPECT_TRUE(temp_dir.CreateUniqueTempDir()); | |
| 174 scoped_refptr<DatabaseTracker> tracker(new DatabaseTracker(temp_dir.path())); | |
| 175 | |
| 176 // Add two observers. | |
| 177 TestObserver observer1; | |
| 178 TestObserver observer2; | |
| 179 tracker->AddObserver(&observer1); | |
| 180 tracker->AddObserver(&observer2); | |
| 181 | |
| 182 // Open three new databases. | |
| 183 int64 database_size = 0; | |
| 184 int64 space_available = 0; | |
| 185 const string16 kOrigin1 = ASCIIToUTF16("origin1"); | |
| 186 const string16 kOrigin2 = ASCIIToUTF16("origin2"); | |
| 187 const string16 kDB1 = ASCIIToUTF16("db1"); | |
| 188 const string16 kDB2 = ASCIIToUTF16("db2"); | |
| 189 const string16 kDB3 = ASCIIToUTF16("db3"); | |
| 190 const string16 kDescription = ASCIIToUTF16("database_description"); | |
| 191 | |
| 192 // Get the quota for kOrigin1 and kOrigin2 | |
| 193 DatabaseTracker::CachedOriginInfo* origin1_info = | |
| 194 tracker->GetCachedOriginInfo(kOrigin1); | |
| 195 DatabaseTracker::CachedOriginInfo* origin2_info = | |
| 196 tracker->GetCachedOriginInfo(kOrigin1); | |
| 197 EXPECT_TRUE(origin1_info); | |
| 198 EXPECT_TRUE(origin2_info); | |
| 199 int64 origin1_quota = origin1_info->Quota(); | |
| 200 int64 origin2_quota = origin2_info->Quota(); | |
| 201 EXPECT_EQ(origin1_quota, tracker->GetOriginSpaceAvailable(kOrigin1)); | |
| 202 EXPECT_EQ(origin2_quota, tracker->GetOriginSpaceAvailable(kOrigin2)); | |
| 203 | |
| 204 // Set a new quota for kOrigin1 | |
| 205 origin1_quota *= 2; | |
| 206 tracker->SetOriginQuota(kOrigin1, origin1_quota); | |
| 207 origin1_info = tracker->GetCachedOriginInfo(kOrigin1); | |
| 208 EXPECT_TRUE(origin1_info); | |
| 209 EXPECT_EQ(origin1_quota, origin1_info->Quota()); | |
| 210 | |
| 211 tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, | |
| 212 &database_size, &space_available); | |
| 213 EXPECT_EQ(0, database_size); | |
| 214 EXPECT_EQ(origin1_quota, space_available); | |
| 215 tracker->DatabaseOpened(kOrigin2, kDB2, kDescription, 0, | |
| 216 &database_size, &space_available); | |
| 217 EXPECT_EQ(0, database_size); | |
| 218 EXPECT_EQ(origin2_quota, space_available); | |
| 219 tracker->DatabaseOpened(kOrigin1, kDB3, kDescription, 0, | |
| 220 &database_size, &space_available); | |
| 221 EXPECT_EQ(0, database_size); | |
| 222 EXPECT_EQ(origin1_quota, space_available); | |
| 223 | |
| 224 // Tell the tracker that a database has changed. | |
| 225 // Even though nothing has changed, the observers should be notified. | |
| 226 tracker->DatabaseModified(kOrigin1, kDB1); | |
| 227 CheckNotificationReceived(&observer1, kOrigin1, kDB1, 0, origin1_quota); | |
| 228 CheckNotificationReceived(&observer2, kOrigin1, kDB1, 0, origin1_quota); | |
| 229 | |
| 230 // Write some data to each file and check that the listeners are | |
| 231 // called with the appropriate values. | |
| 232 EXPECT_TRUE(file_util::CreateDirectory(tracker->DatabaseDirectory().Append( | |
| 233 FilePath::FromWStringHack(UTF16ToWide(kOrigin1))))); | |
| 234 EXPECT_TRUE(file_util::CreateDirectory(tracker->DatabaseDirectory().Append( | |
| 235 FilePath::FromWStringHack(UTF16ToWide(kOrigin2))))); | |
| 236 EXPECT_EQ(1, file_util::WriteFile( | |
| 237 tracker->GetFullDBFilePath(kOrigin1, kDB1), "a", 1)); | |
| 238 EXPECT_EQ(2, file_util::WriteFile( | |
| 239 tracker->GetFullDBFilePath(kOrigin2, kDB2), "aa", 2)); | |
| 240 EXPECT_EQ(4, file_util::WriteFile( | |
| 241 tracker->GetFullDBFilePath(kOrigin1, kDB3), "aaaa", 4)); | |
| 242 tracker->DatabaseModified(kOrigin1, kDB1); | |
| 243 CheckNotificationReceived(&observer1, kOrigin1, kDB1, 1, origin1_quota - 1); | |
| 244 CheckNotificationReceived(&observer2, kOrigin1, kDB1, 1, origin1_quota - 1); | |
| 245 tracker->DatabaseModified(kOrigin2, kDB2); | |
| 246 CheckNotificationReceived(&observer1, kOrigin2, kDB2, 2, origin2_quota - 2); | |
| 247 CheckNotificationReceived(&observer2, kOrigin2, kDB2, 2, origin2_quota - 2); | |
| 248 tracker->DatabaseModified(kOrigin1, kDB3); | |
| 249 CheckNotificationReceived(&observer1, kOrigin1, kDB3, 4, origin1_quota - 5); | |
| 250 CheckNotificationReceived(&observer2, kOrigin1, kDB3, 4, origin1_quota - 5); | |
| 251 | |
| 252 // Make sure the available space for kOrigin1 and kOrigin2 changed accordingly | |
| 253 EXPECT_EQ(origin1_quota - 5, tracker->GetOriginSpaceAvailable(kOrigin1)); | |
| 254 EXPECT_EQ(origin2_quota - 2, tracker->GetOriginSpaceAvailable(kOrigin2)); | |
| 255 | |
| 256 // Close all databases | |
| 257 tracker->DatabaseClosed(kOrigin1, kDB1); | |
| 258 tracker->DatabaseClosed(kOrigin2, kDB2); | |
| 259 tracker->DatabaseClosed(kOrigin1, kDB3); | |
| 260 | |
| 261 // Open an existing database and check the reported size | |
| 262 tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, | |
| 263 &database_size, &space_available); | |
| 264 EXPECT_EQ(1, database_size); | |
| 265 EXPECT_EQ(origin1_quota - 5, space_available); | |
| 266 | |
| 267 // Make sure that the observers are notified even if | |
| 268 // the size of the database hasn't changed. | |
| 269 EXPECT_EQ(1, file_util::WriteFile( | |
| 270 tracker->GetFullDBFilePath(kOrigin1, kDB1), "b", 1)); | |
| 271 tracker->DatabaseModified(kOrigin1, kDB1); | |
| 272 CheckNotificationReceived(&observer1, kOrigin1, kDB1, 1, origin1_quota - 5); | |
| 273 CheckNotificationReceived(&observer2, kOrigin1, kDB1, 1, origin1_quota - 5); | |
| 274 tracker->DatabaseClosed(kOrigin1, kDB1); | |
| 275 | |
| 276 // Remove an observer; this should clear all caches. | |
| 277 tracker->RemoveObserver(&observer2); | |
| 278 | |
| 279 // Change kDB1's and kDB3's size and call tracker->DatabaseModified() | |
| 280 // for kDB1 only. If the caches were indeed cleared, then calling | |
| 281 // tracker->DatabaseModified() should re-populate the cache for | |
| 282 // kOrigin1 == kOrigin1, and thus, should pick up kDB3's size change too. | |
| 283 EXPECT_EQ(5, file_util::WriteFile( | |
| 284 tracker->GetFullDBFilePath(kOrigin1, kDB1), "ccccc", 5)); | |
| 285 EXPECT_EQ(6, file_util::WriteFile( | |
| 286 tracker->GetFullDBFilePath(kOrigin1, kDB3), "dddddd", 6)); | |
| 287 tracker->DatabaseModified(kOrigin1, kDB1); | |
| 288 CheckNotificationReceived(&observer1, kOrigin1, kDB1, 5, origin1_quota - 11); | |
| 289 EXPECT_FALSE(observer2.DidReceiveNewNotification()); | |
| 290 EXPECT_EQ(origin1_quota - 11, tracker->GetOriginSpaceAvailable(kOrigin1)); | |
| 291 | |
| 292 // Close the tracker database and clear all caches. | |
| 293 // Then make sure that DatabaseOpened() still returns the correct result. | |
| 294 tracker->CloseTrackerDatabaseAndClearCaches(); | |
| 295 tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, | |
| 296 &database_size, &space_available); | |
| 297 EXPECT_EQ(5, database_size); | |
| 298 EXPECT_EQ(origin1_quota - 11, space_available); | |
| 299 | |
| 300 // Close the tracker database and clear all caches. Then make sure that | |
| 301 // DatabaseModified() still calls the observers with correct values. | |
| 302 tracker->CloseTrackerDatabaseAndClearCaches(); | |
| 303 tracker->DatabaseModified(kOrigin1, kDB3); | |
| 304 CheckNotificationReceived(&observer1, kOrigin1, kDB3, 6, origin1_quota - 11); | |
| 305 tracker->DatabaseClosed(kOrigin1, kDB1); | |
| 306 | |
| 307 // Remove all observers. | |
| 308 tracker->RemoveObserver(&observer1); | |
| 309 | |
| 310 // Trying to delete a database in use should fail | |
| 311 tracker->DatabaseOpened(kOrigin1, kDB3, kDescription, 0, | |
| 312 &database_size, &space_available); | |
| 313 EXPECT_FALSE(tracker->DeleteClosedDatabase(kOrigin1, kDB3)); | |
| 314 origin1_info = tracker->GetCachedOriginInfo(kOrigin1); | |
| 315 EXPECT_TRUE(origin1_info); | |
| 316 EXPECT_EQ(6, origin1_info->GetDatabaseSize(kDB3)); | |
| 317 tracker->DatabaseClosed(kOrigin1, kDB3); | |
| 318 | |
| 319 // Delete a database and make sure the space used by that origin is updated | |
| 320 EXPECT_TRUE(tracker->DeleteClosedDatabase(kOrigin1, kDB3)); | |
| 321 origin1_info = tracker->GetCachedOriginInfo(kOrigin1); | |
| 322 EXPECT_TRUE(origin1_info); | |
| 323 EXPECT_EQ(origin1_quota - 5, tracker->GetOriginSpaceAvailable(kOrigin1)); | |
| 324 EXPECT_EQ(5, origin1_info->GetDatabaseSize(kDB1)); | |
| 325 EXPECT_EQ(0, origin1_info->GetDatabaseSize(kDB3)); | |
| 326 | |
| 327 // Get all data for all origins | |
| 328 std::vector<OriginInfo> origins_info; | |
| 329 EXPECT_TRUE(tracker->GetAllOriginsInfo(&origins_info)); | |
| 330 EXPECT_EQ(size_t(2), origins_info.size()); | |
| 331 EXPECT_EQ(kOrigin1, origins_info[0].GetOrigin()); | |
| 332 EXPECT_EQ(5, origins_info[0].TotalSize()); | |
| 333 EXPECT_EQ(origin1_quota, origins_info[0].Quota()); | |
| 334 EXPECT_EQ(5, origins_info[0].GetDatabaseSize(kDB1)); | |
| 335 EXPECT_EQ(0, origins_info[0].GetDatabaseSize(kDB3)); | |
| 336 | |
| 337 EXPECT_EQ(kOrigin2, origins_info[1].GetOrigin()); | |
| 338 EXPECT_EQ(2, origins_info[1].TotalSize()); | |
| 339 EXPECT_EQ(origin2_quota, origins_info[1].Quota()); | |
| 340 | |
| 341 // Trying to delete an origin with databases in use should fail | |
| 342 tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0, | |
| 343 &database_size, &space_available); | |
| 344 EXPECT_FALSE(tracker->DeleteOrigin(kOrigin1)); | |
| 345 origin1_info = tracker->GetCachedOriginInfo(kOrigin1); | |
| 346 EXPECT_TRUE(origin1_info); | |
| 347 EXPECT_EQ(5, origin1_info->GetDatabaseSize(kDB1)); | |
| 348 tracker->DatabaseClosed(kOrigin1, kDB1); | |
| 349 | |
| 350 // Delete an origin that doesn't have any database in use | |
| 351 EXPECT_TRUE(tracker->DeleteOrigin(kOrigin1)); | |
| 352 origins_info.clear(); | |
| 353 EXPECT_TRUE(tracker->GetAllOriginsInfo(&origins_info)); | |
| 354 EXPECT_EQ(size_t(1), origins_info.size()); | |
| 355 EXPECT_EQ(kOrigin2, origins_info[0].GetOrigin()); | |
| 356 | |
| 357 origin1_info = tracker->GetCachedOriginInfo(kOrigin1); | |
| 358 EXPECT_TRUE(origin1_info); | |
| 359 EXPECT_EQ(origin1_quota, origin1_info->Quota()); | |
| 360 EXPECT_EQ(0, origin1_info->TotalSize()); | |
| 361 EXPECT_EQ(origin1_quota, tracker->GetOriginSpaceAvailable(kOrigin1)); | |
| 362 } | 391 } |
| 363 | 392 |
| 364 TEST(DatabaseTrackerTest, NoInitIncognito) { | 393 TEST(DatabaseTrackerTest, DatabaseTrackerIncognitoMode) { |
| 365 const string16 kOrigin = ASCIIToUTF16("origin"); | 394 DatabaseTracker_TestHelper_Test::TestDatabaseTracker(true); |
| 366 const string16 kName = ASCIIToUTF16("name"); | |
| 367 const string16 kDescription = ASCIIToUTF16("description"); | |
| 368 const DatabaseConnections kEmptyCollection; | |
| 369 | |
| 370 std::vector<OriginInfo> infos; | |
| 371 scoped_refptr<DatabaseTracker> tracker(new DatabaseTracker(FilePath())); | |
| 372 EXPECT_TRUE(tracker->is_incognito_); | |
| 373 EXPECT_FALSE(tracker->LazyInit()); | |
| 374 EXPECT_TRUE(tracker->DatabaseDirectory().empty()); | |
| 375 EXPECT_TRUE(tracker->GetFullDBFilePath(kOrigin, kName).empty()); | |
| 376 EXPECT_FALSE(tracker->GetAllOriginsInfo(&infos)); | |
| 377 EXPECT_FALSE(tracker->IsDatabaseScheduledForDeletion(kOrigin, kName)); | |
| 378 EXPECT_EQ(net::ERR_FAILED, | |
| 379 tracker->DeleteDatabase(kOrigin, kName, NULL)); | |
| 380 EXPECT_EQ(net::ERR_FAILED, | |
| 381 tracker->DeleteDataModifiedSince(base::Time(), NULL)); | |
| 382 EXPECT_EQ(net::ERR_FAILED, | |
| 383 tracker->DeleteDataForOrigin(kOrigin, NULL)); | |
| 384 | |
| 385 // These should not assert or crash when called in this state. | |
| 386 int64 size_out(0), space_available_out(0); | |
| 387 tracker->DatabaseOpened(kOrigin, kName, kDescription, 1, | |
| 388 &size_out, &space_available_out); | |
| 389 tracker->DatabaseModified(kOrigin, kName); | |
| 390 tracker->DatabaseClosed(kOrigin, kName); | |
| 391 tracker->CloseDatabases(kEmptyCollection); | |
| 392 tracker->CloseTrackerDatabaseAndClearCaches(); | |
| 393 tracker->SetOriginQuota(kOrigin, 5); | |
| 394 tracker->SetOriginQuotaInMemory(kOrigin, 5); | |
| 395 tracker->ResetOriginQuotaInMemory(kOrigin); | |
| 396 } | 395 } |
| 397 | 396 |
| 398 } // namespace webkit_database | 397 } // namespace webkit_database |
| OLD | NEW |