| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "content/browser/indexed_db/indexed_db_factory.h" | 5 #include "content/browser/indexed_db/indexed_db_factory.h" |
| 6 | 6 |
| 7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
| 8 #include "base/files/scoped_temp_dir.h" | 8 #include "base/files/scoped_temp_dir.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| 11 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
| 12 #include "base/test/test_simple_task_runner.h" |
| 12 #include "content/browser/indexed_db/indexed_db_connection.h" | 13 #include "content/browser/indexed_db/indexed_db_connection.h" |
| 14 #include "content/browser/indexed_db/indexed_db_context_impl.h" |
| 13 #include "content/browser/indexed_db/mock_indexed_db_callbacks.h" | 15 #include "content/browser/indexed_db/mock_indexed_db_callbacks.h" |
| 14 #include "content/browser/indexed_db/mock_indexed_db_database_callbacks.h" | 16 #include "content/browser/indexed_db/mock_indexed_db_database_callbacks.h" |
| 15 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
| 16 #include "third_party/WebKit/public/platform/WebIDBDatabaseException.h" | 18 #include "third_party/WebKit/public/platform/WebIDBDatabaseException.h" |
| 17 #include "third_party/WebKit/public/platform/WebIDBTypes.h" | 19 #include "third_party/WebKit/public/platform/WebIDBTypes.h" |
| 18 #include "url/gurl.h" | 20 #include "url/gurl.h" |
| 19 #include "webkit/common/database/database_identifier.h" | 21 #include "webkit/common/database/database_identifier.h" |
| 20 | 22 |
| 21 using base::ASCIIToUTF16; | 23 using base::ASCIIToUTF16; |
| 22 | 24 |
| 23 namespace content { | 25 namespace content { |
| 24 | 26 |
| 25 class IndexedDBFactoryTest : public testing::Test { | 27 namespace { |
| 26 public: | |
| 27 IndexedDBFactoryTest() {} | |
| 28 | |
| 29 protected: | |
| 30 // For timers to post events. | |
| 31 base::MessageLoop loop_; | |
| 32 | |
| 33 private: | |
| 34 DISALLOW_COPY_AND_ASSIGN(IndexedDBFactoryTest); | |
| 35 }; | |
| 36 | 28 |
| 37 class MockIDBFactory : public IndexedDBFactory { | 29 class MockIDBFactory : public IndexedDBFactory { |
| 38 public: | 30 public: |
| 39 MockIDBFactory() : IndexedDBFactory(NULL) {} | 31 MockIDBFactory(IndexedDBContextImpl* context) : IndexedDBFactory(context) {} |
| 40 scoped_refptr<IndexedDBBackingStore> TestOpenBackingStore( | 32 scoped_refptr<IndexedDBBackingStore> TestOpenBackingStore( |
| 41 const GURL& origin, | 33 const GURL& origin, |
| 42 const base::FilePath& data_directory) { | 34 const base::FilePath& data_directory) { |
| 43 blink::WebIDBDataLoss data_loss = | 35 blink::WebIDBDataLoss data_loss = |
| 44 blink::WebIDBDataLossNone; | 36 blink::WebIDBDataLossNone; |
| 45 std::string data_loss_message; | 37 std::string data_loss_message; |
| 46 bool disk_full; | 38 bool disk_full; |
| 47 scoped_refptr<IndexedDBBackingStore> backing_store = | 39 scoped_refptr<IndexedDBBackingStore> backing_store = |
| 48 OpenBackingStore(origin, | 40 OpenBackingStore(origin, |
| 49 data_directory, | 41 data_directory, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 60 | 52 |
| 61 void TestReleaseBackingStore(IndexedDBBackingStore* backing_store, | 53 void TestReleaseBackingStore(IndexedDBBackingStore* backing_store, |
| 62 bool immediate) { | 54 bool immediate) { |
| 63 ReleaseBackingStore(backing_store->origin_url(), immediate); | 55 ReleaseBackingStore(backing_store->origin_url(), immediate); |
| 64 } | 56 } |
| 65 | 57 |
| 66 private: | 58 private: |
| 67 virtual ~MockIDBFactory() {} | 59 virtual ~MockIDBFactory() {} |
| 68 }; | 60 }; |
| 69 | 61 |
| 62 } // namespace |
| 63 |
| 64 class IndexedDBFactoryTest : public testing::Test { |
| 65 public: |
| 66 IndexedDBFactoryTest() { |
| 67 task_runner_ = new base::TestSimpleTaskRunner(); |
| 68 context_ = new IndexedDBContextImpl(base::FilePath(), |
| 69 NULL /* special_storage_policy */, |
| 70 NULL /* quota_manager_proxy */, |
| 71 task_runner_.get()); |
| 72 idb_factory_ = new MockIDBFactory(context_.get()); |
| 73 } |
| 74 |
| 75 protected: |
| 76 // For timers to post events. |
| 77 base::MessageLoop loop_; |
| 78 |
| 79 MockIDBFactory* factory() const { return idb_factory_.get(); } |
| 80 void clear_factory() { idb_factory_ = NULL; } |
| 81 IndexedDBContextImpl* context() const { return context_.get(); } |
| 82 |
| 83 private: |
| 84 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; |
| 85 scoped_refptr<IndexedDBContextImpl> context_; |
| 86 scoped_refptr<MockIDBFactory> idb_factory_; |
| 87 |
| 88 DISALLOW_COPY_AND_ASSIGN(IndexedDBFactoryTest); |
| 89 }; |
| 90 |
| 70 TEST_F(IndexedDBFactoryTest, BackingStoreLifetime) { | 91 TEST_F(IndexedDBFactoryTest, BackingStoreLifetime) { |
| 71 GURL origin1("http://localhost:81"); | 92 GURL origin1("http://localhost:81"); |
| 72 GURL origin2("http://localhost:82"); | 93 GURL origin2("http://localhost:82"); |
| 73 | 94 |
| 74 scoped_refptr<MockIDBFactory> factory = new MockIDBFactory(); | |
| 75 | |
| 76 base::ScopedTempDir temp_directory; | 95 base::ScopedTempDir temp_directory; |
| 77 ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); | 96 ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); |
| 78 scoped_refptr<IndexedDBBackingStore> disk_store1 = | 97 scoped_refptr<IndexedDBBackingStore> disk_store1 = |
| 79 factory->TestOpenBackingStore(origin1, temp_directory.path()); | 98 factory()->TestOpenBackingStore(origin1, temp_directory.path()); |
| 80 | 99 |
| 81 scoped_refptr<IndexedDBBackingStore> disk_store2 = | 100 scoped_refptr<IndexedDBBackingStore> disk_store2 = |
| 82 factory->TestOpenBackingStore(origin1, temp_directory.path()); | 101 factory()->TestOpenBackingStore(origin1, temp_directory.path()); |
| 83 EXPECT_EQ(disk_store1.get(), disk_store2.get()); | 102 EXPECT_EQ(disk_store1.get(), disk_store2.get()); |
| 84 | 103 |
| 85 scoped_refptr<IndexedDBBackingStore> disk_store3 = | 104 scoped_refptr<IndexedDBBackingStore> disk_store3 = |
| 86 factory->TestOpenBackingStore(origin2, temp_directory.path()); | 105 factory()->TestOpenBackingStore(origin2, temp_directory.path()); |
| 87 | 106 |
| 88 factory->TestCloseBackingStore(disk_store1); | 107 factory()->TestCloseBackingStore(disk_store1); |
| 89 factory->TestCloseBackingStore(disk_store3); | 108 factory()->TestCloseBackingStore(disk_store3); |
| 90 | 109 |
| 91 EXPECT_FALSE(disk_store1->HasOneRef()); | 110 EXPECT_FALSE(disk_store1->HasOneRef()); |
| 92 EXPECT_FALSE(disk_store2->HasOneRef()); | 111 EXPECT_FALSE(disk_store2->HasOneRef()); |
| 93 EXPECT_TRUE(disk_store3->HasOneRef()); | 112 EXPECT_TRUE(disk_store3->HasOneRef()); |
| 94 | 113 |
| 95 disk_store2 = NULL; | 114 disk_store2 = NULL; |
| 96 EXPECT_TRUE(disk_store1->HasOneRef()); | 115 EXPECT_TRUE(disk_store1->HasOneRef()); |
| 97 } | 116 } |
| 98 | 117 |
| 99 TEST_F(IndexedDBFactoryTest, BackingStoreLazyClose) { | 118 TEST_F(IndexedDBFactoryTest, BackingStoreLazyClose) { |
| 100 GURL origin("http://localhost:81"); | 119 GURL origin("http://localhost:81"); |
| 101 | 120 |
| 102 scoped_refptr<MockIDBFactory> factory = new MockIDBFactory(); | |
| 103 | |
| 104 base::ScopedTempDir temp_directory; | 121 base::ScopedTempDir temp_directory; |
| 105 ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); | 122 ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); |
| 106 scoped_refptr<IndexedDBBackingStore> store = | 123 scoped_refptr<IndexedDBBackingStore> store = |
| 107 factory->TestOpenBackingStore(origin, temp_directory.path()); | 124 factory()->TestOpenBackingStore(origin, temp_directory.path()); |
| 108 | 125 |
| 109 // Give up the local refptr so that the factory has the only | 126 // Give up the local refptr so that the factory has the only |
| 110 // outstanding reference. | 127 // outstanding reference. |
| 111 IndexedDBBackingStore* store_ptr = store.get(); | 128 IndexedDBBackingStore* store_ptr = store.get(); |
| 112 store = NULL; | 129 store = NULL; |
| 113 EXPECT_FALSE(store_ptr->close_timer()->IsRunning()); | 130 EXPECT_FALSE(store_ptr->close_timer()->IsRunning()); |
| 114 factory->TestReleaseBackingStore(store_ptr, false); | 131 factory()->TestReleaseBackingStore(store_ptr, false); |
| 115 EXPECT_TRUE(store_ptr->close_timer()->IsRunning()); | 132 EXPECT_TRUE(store_ptr->close_timer()->IsRunning()); |
| 116 | 133 |
| 117 factory->TestOpenBackingStore(origin, temp_directory.path()); | 134 factory()->TestOpenBackingStore(origin, temp_directory.path()); |
| 118 EXPECT_FALSE(store_ptr->close_timer()->IsRunning()); | 135 EXPECT_FALSE(store_ptr->close_timer()->IsRunning()); |
| 119 factory->TestReleaseBackingStore(store_ptr, false); | 136 factory()->TestReleaseBackingStore(store_ptr, false); |
| 120 EXPECT_TRUE(store_ptr->close_timer()->IsRunning()); | 137 EXPECT_TRUE(store_ptr->close_timer()->IsRunning()); |
| 121 | 138 |
| 122 // Take back a ref ptr and ensure that the actual close | 139 // Take back a ref ptr and ensure that the actual close |
| 123 // stops a running timer. | 140 // stops a running timer. |
| 124 store = store_ptr; | 141 store = store_ptr; |
| 125 factory->TestCloseBackingStore(store_ptr); | 142 factory()->TestCloseBackingStore(store_ptr); |
| 126 EXPECT_FALSE(store_ptr->close_timer()->IsRunning()); | 143 EXPECT_FALSE(store_ptr->close_timer()->IsRunning()); |
| 127 } | 144 } |
| 128 | 145 |
| 129 TEST_F(IndexedDBFactoryTest, MemoryBackingStoreLifetime) { | 146 TEST_F(IndexedDBFactoryTest, MemoryBackingStoreLifetime) { |
| 130 GURL origin1("http://localhost:81"); | 147 GURL origin1("http://localhost:81"); |
| 131 GURL origin2("http://localhost:82"); | 148 GURL origin2("http://localhost:82"); |
| 132 | 149 |
| 133 scoped_refptr<MockIDBFactory> factory = new MockIDBFactory(); | |
| 134 scoped_refptr<IndexedDBBackingStore> mem_store1 = | 150 scoped_refptr<IndexedDBBackingStore> mem_store1 = |
| 135 factory->TestOpenBackingStore(origin1, base::FilePath()); | 151 factory()->TestOpenBackingStore(origin1, base::FilePath()); |
| 136 | 152 |
| 137 scoped_refptr<IndexedDBBackingStore> mem_store2 = | 153 scoped_refptr<IndexedDBBackingStore> mem_store2 = |
| 138 factory->TestOpenBackingStore(origin1, base::FilePath()); | 154 factory()->TestOpenBackingStore(origin1, base::FilePath()); |
| 139 EXPECT_EQ(mem_store1.get(), mem_store2.get()); | 155 EXPECT_EQ(mem_store1.get(), mem_store2.get()); |
| 140 | 156 |
| 141 scoped_refptr<IndexedDBBackingStore> mem_store3 = | 157 scoped_refptr<IndexedDBBackingStore> mem_store3 = |
| 142 factory->TestOpenBackingStore(origin2, base::FilePath()); | 158 factory()->TestOpenBackingStore(origin2, base::FilePath()); |
| 143 | 159 |
| 144 factory->TestCloseBackingStore(mem_store1); | 160 factory()->TestCloseBackingStore(mem_store1); |
| 145 factory->TestCloseBackingStore(mem_store3); | 161 factory()->TestCloseBackingStore(mem_store3); |
| 146 | 162 |
| 147 EXPECT_FALSE(mem_store1->HasOneRef()); | 163 EXPECT_FALSE(mem_store1->HasOneRef()); |
| 148 EXPECT_FALSE(mem_store2->HasOneRef()); | 164 EXPECT_FALSE(mem_store2->HasOneRef()); |
| 149 EXPECT_FALSE(mem_store3->HasOneRef()); | 165 EXPECT_FALSE(mem_store3->HasOneRef()); |
| 150 | 166 |
| 151 factory = NULL; | 167 clear_factory(); |
| 152 EXPECT_FALSE(mem_store1->HasOneRef()); // mem_store1 and 2 | 168 EXPECT_FALSE(mem_store1->HasOneRef()); // mem_store1 and 2 |
| 153 EXPECT_FALSE(mem_store2->HasOneRef()); // mem_store1 and 2 | 169 EXPECT_FALSE(mem_store2->HasOneRef()); // mem_store1 and 2 |
| 154 EXPECT_TRUE(mem_store3->HasOneRef()); | 170 EXPECT_TRUE(mem_store3->HasOneRef()); |
| 155 | 171 |
| 156 mem_store2 = NULL; | 172 mem_store2 = NULL; |
| 157 EXPECT_TRUE(mem_store1->HasOneRef()); | 173 EXPECT_TRUE(mem_store1->HasOneRef()); |
| 158 } | 174 } |
| 159 | 175 |
| 160 TEST_F(IndexedDBFactoryTest, RejectLongOrigins) { | 176 TEST_F(IndexedDBFactoryTest, RejectLongOrigins) { |
| 161 base::ScopedTempDir temp_directory; | 177 base::ScopedTempDir temp_directory; |
| 162 ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); | 178 ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); |
| 163 const base::FilePath base_path = temp_directory.path(); | 179 const base::FilePath base_path = temp_directory.path(); |
| 164 scoped_refptr<MockIDBFactory> factory = new MockIDBFactory(); | |
| 165 | 180 |
| 166 int limit = base::GetMaximumPathComponentLength(base_path); | 181 int limit = base::GetMaximumPathComponentLength(base_path); |
| 167 EXPECT_GT(limit, 0); | 182 EXPECT_GT(limit, 0); |
| 168 | 183 |
| 169 std::string origin(limit + 1, 'x'); | 184 std::string origin(limit + 1, 'x'); |
| 170 GURL too_long_origin("http://" + origin + ":81/"); | 185 GURL too_long_origin("http://" + origin + ":81/"); |
| 171 scoped_refptr<IndexedDBBackingStore> diskStore1 = | 186 scoped_refptr<IndexedDBBackingStore> diskStore1 = |
| 172 factory->TestOpenBackingStore(too_long_origin, base_path); | 187 factory()->TestOpenBackingStore(too_long_origin, base_path); |
| 173 EXPECT_FALSE(diskStore1); | 188 EXPECT_FALSE(diskStore1); |
| 174 | 189 |
| 175 GURL ok_origin("http://someorigin.com:82/"); | 190 GURL ok_origin("http://someorigin.com:82/"); |
| 176 scoped_refptr<IndexedDBBackingStore> diskStore2 = | 191 scoped_refptr<IndexedDBBackingStore> diskStore2 = |
| 177 factory->TestOpenBackingStore(ok_origin, base_path); | 192 factory()->TestOpenBackingStore(ok_origin, base_path); |
| 178 EXPECT_TRUE(diskStore2); | 193 EXPECT_TRUE(diskStore2); |
| 179 } | 194 } |
| 180 | 195 |
| 181 class DiskFullFactory : public IndexedDBFactory { | 196 class DiskFullFactory : public IndexedDBFactory { |
| 182 public: | 197 public: |
| 183 DiskFullFactory() : IndexedDBFactory(NULL) {} | 198 DiskFullFactory(IndexedDBContextImpl* context) : IndexedDBFactory(context) {} |
| 184 | 199 |
| 185 private: | 200 private: |
| 186 virtual ~DiskFullFactory() {} | 201 virtual ~DiskFullFactory() {} |
| 187 virtual scoped_refptr<IndexedDBBackingStore> OpenBackingStore( | 202 virtual scoped_refptr<IndexedDBBackingStore> OpenBackingStore( |
| 188 const GURL& origin_url, | 203 const GURL& origin_url, |
| 189 const base::FilePath& data_directory, | 204 const base::FilePath& data_directory, |
| 190 blink::WebIDBDataLoss* data_loss, | 205 blink::WebIDBDataLoss* data_loss, |
| 191 std::string* data_loss_message, | 206 std::string* data_loss_message, |
| 192 bool* disk_full) OVERRIDE { | 207 bool* disk_full) OVERRIDE { |
| 193 *disk_full = true; | 208 *disk_full = true; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 204 EXPECT_EQ(blink::WebIDBDatabaseExceptionQuotaError, error.code()); | 219 EXPECT_EQ(blink::WebIDBDatabaseExceptionQuotaError, error.code()); |
| 205 } | 220 } |
| 206 | 221 |
| 207 private: | 222 private: |
| 208 virtual ~LookingForQuotaErrorMockCallbacks() { EXPECT_TRUE(error_called_); } | 223 virtual ~LookingForQuotaErrorMockCallbacks() { EXPECT_TRUE(error_called_); } |
| 209 bool error_called_; | 224 bool error_called_; |
| 210 }; | 225 }; |
| 211 | 226 |
| 212 TEST_F(IndexedDBFactoryTest, QuotaErrorOnDiskFull) { | 227 TEST_F(IndexedDBFactoryTest, QuotaErrorOnDiskFull) { |
| 213 const GURL origin("http://localhost:81"); | 228 const GURL origin("http://localhost:81"); |
| 229 base::ScopedTempDir temp_directory; |
| 230 ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); |
| 214 | 231 |
| 215 scoped_refptr<DiskFullFactory> factory = new DiskFullFactory; | 232 scoped_refptr<DiskFullFactory> factory = new DiskFullFactory(context()); |
| 216 scoped_refptr<LookingForQuotaErrorMockCallbacks> callbacks = | 233 scoped_refptr<LookingForQuotaErrorMockCallbacks> callbacks = |
| 217 new LookingForQuotaErrorMockCallbacks; | 234 new LookingForQuotaErrorMockCallbacks; |
| 218 scoped_refptr<IndexedDBDatabaseCallbacks> dummy_database_callbacks = | 235 scoped_refptr<IndexedDBDatabaseCallbacks> dummy_database_callbacks = |
| 219 new IndexedDBDatabaseCallbacks(NULL, 0, 0); | 236 new IndexedDBDatabaseCallbacks(NULL, 0, 0); |
| 220 const base::string16 name(ASCIIToUTF16("name")); | 237 const base::string16 name(ASCIIToUTF16("name")); |
| 221 IndexedDBPendingConnection connection(callbacks, | 238 IndexedDBPendingConnection connection(callbacks, |
| 222 dummy_database_callbacks, | 239 dummy_database_callbacks, |
| 223 0, /* child_process_id */ | 240 0, /* child_process_id */ |
| 224 2, /* transaction_id */ | 241 2, /* transaction_id */ |
| 225 1 /* version */); | 242 1 /* version */); |
| 226 factory->Open( | 243 factory->Open(name, connection, origin, temp_directory.path()); |
| 227 name, connection, origin, base::FilePath(FILE_PATH_LITERAL("/dummy"))); | |
| 228 } | 244 } |
| 229 | 245 |
| 230 TEST_F(IndexedDBFactoryTest, BackingStoreReleasedOnForcedClose) { | 246 TEST_F(IndexedDBFactoryTest, BackingStoreReleasedOnForcedClose) { |
| 231 GURL origin("http://localhost:81"); | 247 GURL origin("http://localhost:81"); |
| 232 | 248 |
| 233 base::ScopedTempDir temp_directory; | 249 base::ScopedTempDir temp_directory; |
| 234 ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); | 250 ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); |
| 235 | 251 |
| 236 scoped_refptr<IndexedDBFactory> factory = new IndexedDBFactory(NULL); | |
| 237 | |
| 238 scoped_refptr<MockIndexedDBCallbacks> callbacks(new MockIndexedDBCallbacks()); | 252 scoped_refptr<MockIndexedDBCallbacks> callbacks(new MockIndexedDBCallbacks()); |
| 239 scoped_refptr<MockIndexedDBDatabaseCallbacks> db_callbacks( | 253 scoped_refptr<MockIndexedDBDatabaseCallbacks> db_callbacks( |
| 240 new MockIndexedDBDatabaseCallbacks()); | 254 new MockIndexedDBDatabaseCallbacks()); |
| 241 const int64 transaction_id = 1; | 255 const int64 transaction_id = 1; |
| 242 IndexedDBPendingConnection connection( | 256 IndexedDBPendingConnection connection( |
| 243 callbacks, | 257 callbacks, |
| 244 db_callbacks, | 258 db_callbacks, |
| 245 0, /* child_process_id */ | 259 0, /* child_process_id */ |
| 246 transaction_id, | 260 transaction_id, |
| 247 IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION); | 261 IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION); |
| 248 factory->Open(ASCIIToUTF16("db"), connection, origin, temp_directory.path()); | 262 factory()->Open( |
| 263 ASCIIToUTF16("db"), connection, origin, temp_directory.path()); |
| 249 | 264 |
| 250 EXPECT_TRUE(callbacks->connection()); | 265 EXPECT_TRUE(callbacks->connection()); |
| 251 | 266 |
| 252 EXPECT_TRUE(factory->IsBackingStoreOpen(origin)); | 267 EXPECT_TRUE(factory()->IsBackingStoreOpen(origin)); |
| 253 EXPECT_FALSE(factory->IsBackingStorePendingClose(origin)); | 268 EXPECT_FALSE(factory()->IsBackingStorePendingClose(origin)); |
| 254 | 269 |
| 255 callbacks->connection()->ForceClose(); | 270 callbacks->connection()->ForceClose(); |
| 256 | 271 |
| 257 EXPECT_FALSE(factory->IsBackingStoreOpen(origin)); | 272 EXPECT_FALSE(factory()->IsBackingStoreOpen(origin)); |
| 258 EXPECT_FALSE(factory->IsBackingStorePendingClose(origin)); | 273 EXPECT_FALSE(factory()->IsBackingStorePendingClose(origin)); |
| 259 } | 274 } |
| 260 | 275 |
| 261 TEST_F(IndexedDBFactoryTest, BackingStoreReleaseDelayedOnClose) { | 276 TEST_F(IndexedDBFactoryTest, BackingStoreReleaseDelayedOnClose) { |
| 262 GURL origin("http://localhost:81"); | 277 GURL origin("http://localhost:81"); |
| 263 | 278 |
| 264 base::ScopedTempDir temp_directory; | 279 base::ScopedTempDir temp_directory; |
| 265 ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); | 280 ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); |
| 266 | 281 |
| 267 scoped_refptr<IndexedDBFactory> factory = new IndexedDBFactory(NULL); | |
| 268 | |
| 269 scoped_refptr<MockIndexedDBCallbacks> callbacks(new MockIndexedDBCallbacks()); | 282 scoped_refptr<MockIndexedDBCallbacks> callbacks(new MockIndexedDBCallbacks()); |
| 270 scoped_refptr<MockIndexedDBDatabaseCallbacks> db_callbacks( | 283 scoped_refptr<MockIndexedDBDatabaseCallbacks> db_callbacks( |
| 271 new MockIndexedDBDatabaseCallbacks()); | 284 new MockIndexedDBDatabaseCallbacks()); |
| 272 const int64 transaction_id = 1; | 285 const int64 transaction_id = 1; |
| 273 IndexedDBPendingConnection connection( | 286 IndexedDBPendingConnection connection( |
| 274 callbacks, | 287 callbacks, |
| 275 db_callbacks, | 288 db_callbacks, |
| 276 0, /* child_process_id */ | 289 0, /* child_process_id */ |
| 277 transaction_id, | 290 transaction_id, |
| 278 IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION); | 291 IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION); |
| 279 factory->Open(ASCIIToUTF16("db"), connection, origin, temp_directory.path()); | 292 factory()->Open( |
| 293 ASCIIToUTF16("db"), connection, origin, temp_directory.path()); |
| 280 | 294 |
| 281 EXPECT_TRUE(callbacks->connection()); | 295 EXPECT_TRUE(callbacks->connection()); |
| 282 IndexedDBBackingStore* store = | 296 IndexedDBBackingStore* store = |
| 283 callbacks->connection()->database()->backing_store(); | 297 callbacks->connection()->database()->backing_store(); |
| 284 EXPECT_FALSE(store->HasOneRef()); // Factory and database. | 298 EXPECT_FALSE(store->HasOneRef()); // Factory and database. |
| 285 | 299 |
| 286 EXPECT_TRUE(factory->IsBackingStoreOpen(origin)); | 300 EXPECT_TRUE(factory()->IsBackingStoreOpen(origin)); |
| 287 callbacks->connection()->Close(); | 301 callbacks->connection()->Close(); |
| 288 EXPECT_TRUE(store->HasOneRef()); // Factory. | 302 EXPECT_TRUE(store->HasOneRef()); // Factory. |
| 289 EXPECT_TRUE(factory->IsBackingStoreOpen(origin)); | 303 EXPECT_TRUE(factory()->IsBackingStoreOpen(origin)); |
| 290 EXPECT_TRUE(factory->IsBackingStorePendingClose(origin)); | 304 EXPECT_TRUE(factory()->IsBackingStorePendingClose(origin)); |
| 291 EXPECT_TRUE(store->close_timer()->IsRunning()); | 305 EXPECT_TRUE(store->close_timer()->IsRunning()); |
| 292 | 306 |
| 293 // Take a ref so it won't be destroyed out from under the test. | 307 // Take a ref so it won't be destroyed out from under the test. |
| 294 scoped_refptr<IndexedDBBackingStore> store_ref = store; | 308 scoped_refptr<IndexedDBBackingStore> store_ref = store; |
| 295 // Now simulate shutdown, which should stop the timer. | 309 // Now simulate shutdown, which should stop the timer. |
| 296 factory->ContextDestroyed(); | 310 factory()->ContextDestroyed(); |
| 297 EXPECT_TRUE(store->HasOneRef()); // Local. | 311 EXPECT_TRUE(store->HasOneRef()); // Local. |
| 298 EXPECT_FALSE(store->close_timer()->IsRunning()); | 312 EXPECT_FALSE(store->close_timer()->IsRunning()); |
| 299 EXPECT_FALSE(factory->IsBackingStoreOpen(origin)); | 313 EXPECT_FALSE(factory()->IsBackingStoreOpen(origin)); |
| 300 EXPECT_FALSE(factory->IsBackingStorePendingClose(origin)); | 314 EXPECT_FALSE(factory()->IsBackingStorePendingClose(origin)); |
| 301 } | 315 } |
| 302 | 316 |
| 303 TEST_F(IndexedDBFactoryTest, DeleteDatabaseClosesBackingStore) { | 317 TEST_F(IndexedDBFactoryTest, DeleteDatabaseClosesBackingStore) { |
| 304 GURL origin("http://localhost:81"); | 318 GURL origin("http://localhost:81"); |
| 305 | 319 |
| 306 base::ScopedTempDir temp_directory; | 320 base::ScopedTempDir temp_directory; |
| 307 ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); | 321 ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); |
| 308 | 322 |
| 309 scoped_refptr<IndexedDBFactory> factory = new IndexedDBFactory(NULL); | 323 EXPECT_FALSE(factory()->IsBackingStoreOpen(origin)); |
| 310 EXPECT_FALSE(factory->IsBackingStoreOpen(origin)); | |
| 311 | 324 |
| 312 const bool expect_connection = false; | 325 const bool expect_connection = false; |
| 313 scoped_refptr<MockIndexedDBCallbacks> callbacks( | 326 scoped_refptr<MockIndexedDBCallbacks> callbacks( |
| 314 new MockIndexedDBCallbacks(expect_connection)); | 327 new MockIndexedDBCallbacks(expect_connection)); |
| 315 factory->DeleteDatabase(ASCIIToUTF16("db"), | 328 factory()->DeleteDatabase( |
| 316 callbacks, | 329 ASCIIToUTF16("db"), callbacks, origin, temp_directory.path()); |
| 317 origin, | |
| 318 temp_directory.path()); | |
| 319 | 330 |
| 320 EXPECT_TRUE(factory->IsBackingStoreOpen(origin)); | 331 EXPECT_TRUE(factory()->IsBackingStoreOpen(origin)); |
| 321 EXPECT_TRUE(factory->IsBackingStorePendingClose(origin)); | 332 EXPECT_TRUE(factory()->IsBackingStorePendingClose(origin)); |
| 322 | 333 |
| 323 // Now simulate shutdown, which should stop the timer. | 334 // Now simulate shutdown, which should stop the timer. |
| 324 factory->ContextDestroyed(); | 335 factory()->ContextDestroyed(); |
| 325 | 336 |
| 326 EXPECT_FALSE(factory->IsBackingStoreOpen(origin)); | 337 EXPECT_FALSE(factory()->IsBackingStoreOpen(origin)); |
| 327 EXPECT_FALSE(factory->IsBackingStorePendingClose(origin)); | 338 EXPECT_FALSE(factory()->IsBackingStorePendingClose(origin)); |
| 328 } | 339 } |
| 329 | 340 |
| 330 TEST_F(IndexedDBFactoryTest, GetDatabaseNamesClosesBackingStore) { | 341 TEST_F(IndexedDBFactoryTest, GetDatabaseNamesClosesBackingStore) { |
| 331 GURL origin("http://localhost:81"); | 342 GURL origin("http://localhost:81"); |
| 332 | 343 |
| 333 base::ScopedTempDir temp_directory; | 344 base::ScopedTempDir temp_directory; |
| 334 ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); | 345 ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); |
| 335 | 346 |
| 336 scoped_refptr<IndexedDBFactory> factory = new IndexedDBFactory(NULL); | 347 EXPECT_FALSE(factory()->IsBackingStoreOpen(origin)); |
| 337 EXPECT_FALSE(factory->IsBackingStoreOpen(origin)); | |
| 338 | 348 |
| 339 const bool expect_connection = false; | 349 const bool expect_connection = false; |
| 340 scoped_refptr<MockIndexedDBCallbacks> callbacks( | 350 scoped_refptr<MockIndexedDBCallbacks> callbacks( |
| 341 new MockIndexedDBCallbacks(expect_connection)); | 351 new MockIndexedDBCallbacks(expect_connection)); |
| 342 factory->GetDatabaseNames(callbacks, | 352 factory()->GetDatabaseNames(callbacks, origin, temp_directory.path()); |
| 343 origin, | |
| 344 temp_directory.path()); | |
| 345 | 353 |
| 346 EXPECT_TRUE(factory->IsBackingStoreOpen(origin)); | 354 EXPECT_TRUE(factory()->IsBackingStoreOpen(origin)); |
| 347 EXPECT_TRUE(factory->IsBackingStorePendingClose(origin)); | 355 EXPECT_TRUE(factory()->IsBackingStorePendingClose(origin)); |
| 348 | 356 |
| 349 // Now simulate shutdown, which should stop the timer. | 357 // Now simulate shutdown, which should stop the timer. |
| 350 factory->ContextDestroyed(); | 358 factory()->ContextDestroyed(); |
| 351 | 359 |
| 352 EXPECT_FALSE(factory->IsBackingStoreOpen(origin)); | 360 EXPECT_FALSE(factory()->IsBackingStoreOpen(origin)); |
| 353 EXPECT_FALSE(factory->IsBackingStorePendingClose(origin)); | 361 EXPECT_FALSE(factory()->IsBackingStorePendingClose(origin)); |
| 354 } | 362 } |
| 355 | 363 |
| 356 TEST_F(IndexedDBFactoryTest, ForceCloseReleasesBackingStore) { | 364 TEST_F(IndexedDBFactoryTest, ForceCloseReleasesBackingStore) { |
| 357 GURL origin("http://localhost:81"); | 365 GURL origin("http://localhost:81"); |
| 358 | 366 |
| 359 base::ScopedTempDir temp_directory; | 367 base::ScopedTempDir temp_directory; |
| 360 ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); | 368 ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); |
| 361 | 369 |
| 362 scoped_refptr<IndexedDBFactory> factory = new IndexedDBFactory(NULL); | |
| 363 | |
| 364 scoped_refptr<MockIndexedDBCallbacks> callbacks(new MockIndexedDBCallbacks()); | 370 scoped_refptr<MockIndexedDBCallbacks> callbacks(new MockIndexedDBCallbacks()); |
| 365 scoped_refptr<MockIndexedDBDatabaseCallbacks> db_callbacks( | 371 scoped_refptr<MockIndexedDBDatabaseCallbacks> db_callbacks( |
| 366 new MockIndexedDBDatabaseCallbacks()); | 372 new MockIndexedDBDatabaseCallbacks()); |
| 367 const int64 transaction_id = 1; | 373 const int64 transaction_id = 1; |
| 368 IndexedDBPendingConnection connection( | 374 IndexedDBPendingConnection connection( |
| 369 callbacks, | 375 callbacks, |
| 370 db_callbacks, | 376 db_callbacks, |
| 371 0, /* child_process_id */ | 377 0, /* child_process_id */ |
| 372 transaction_id, | 378 transaction_id, |
| 373 IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION); | 379 IndexedDBDatabaseMetadata::DEFAULT_INT_VERSION); |
| 374 factory->Open(ASCIIToUTF16("db"), connection, origin, temp_directory.path()); | 380 factory()->Open( |
| 381 ASCIIToUTF16("db"), connection, origin, temp_directory.path()); |
| 375 | 382 |
| 376 EXPECT_TRUE(callbacks->connection()); | 383 EXPECT_TRUE(callbacks->connection()); |
| 377 EXPECT_TRUE(factory->IsBackingStoreOpen(origin)); | 384 EXPECT_TRUE(factory()->IsBackingStoreOpen(origin)); |
| 378 EXPECT_FALSE(factory->IsBackingStorePendingClose(origin)); | 385 EXPECT_FALSE(factory()->IsBackingStorePendingClose(origin)); |
| 379 | 386 |
| 380 callbacks->connection()->Close(); | 387 callbacks->connection()->Close(); |
| 381 | 388 |
| 382 EXPECT_TRUE(factory->IsBackingStoreOpen(origin)); | 389 EXPECT_TRUE(factory()->IsBackingStoreOpen(origin)); |
| 383 EXPECT_TRUE(factory->IsBackingStorePendingClose(origin)); | 390 EXPECT_TRUE(factory()->IsBackingStorePendingClose(origin)); |
| 384 | 391 |
| 385 factory->ForceClose(origin); | 392 factory()->ForceClose(origin); |
| 386 | 393 |
| 387 EXPECT_FALSE(factory->IsBackingStoreOpen(origin)); | 394 EXPECT_FALSE(factory()->IsBackingStoreOpen(origin)); |
| 388 EXPECT_FALSE(factory->IsBackingStorePendingClose(origin)); | 395 EXPECT_FALSE(factory()->IsBackingStorePendingClose(origin)); |
| 389 | 396 |
| 390 // Ensure it is safe if the store is not open. | 397 // Ensure it is safe if the store is not open. |
| 391 factory->ForceClose(origin); | 398 factory()->ForceClose(origin); |
| 392 } | 399 } |
| 393 | 400 |
| 394 class UpgradeNeededCallbacks : public MockIndexedDBCallbacks { | 401 class UpgradeNeededCallbacks : public MockIndexedDBCallbacks { |
| 395 public: | 402 public: |
| 396 virtual void OnSuccess(scoped_ptr<IndexedDBConnection> connection, | 403 virtual void OnSuccess(scoped_ptr<IndexedDBConnection> connection, |
| 397 const IndexedDBDatabaseMetadata& metadata) OVERRIDE { | 404 const IndexedDBDatabaseMetadata& metadata) OVERRIDE { |
| 398 EXPECT_TRUE(connection_.get()); | 405 EXPECT_TRUE(connection_.get()); |
| 399 EXPECT_FALSE(connection.get()); | 406 EXPECT_FALSE(connection.get()); |
| 400 } | 407 } |
| 401 | 408 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 424 private: | 431 private: |
| 425 bool saw_error_; | 432 bool saw_error_; |
| 426 }; | 433 }; |
| 427 | 434 |
| 428 TEST_F(IndexedDBFactoryTest, DatabaseFailedOpen) { | 435 TEST_F(IndexedDBFactoryTest, DatabaseFailedOpen) { |
| 429 GURL origin("http://localhost:81"); | 436 GURL origin("http://localhost:81"); |
| 430 | 437 |
| 431 base::ScopedTempDir temp_directory; | 438 base::ScopedTempDir temp_directory; |
| 432 ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); | 439 ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); |
| 433 | 440 |
| 434 scoped_refptr<IndexedDBFactory> factory = new IndexedDBFactory(NULL); | |
| 435 const base::string16 db_name(ASCIIToUTF16("db")); | 441 const base::string16 db_name(ASCIIToUTF16("db")); |
| 436 const int64 db_version = 2; | 442 const int64 db_version = 2; |
| 437 const int64 transaction_id = 1; | 443 const int64 transaction_id = 1; |
| 438 scoped_refptr<IndexedDBDatabaseCallbacks> db_callbacks( | 444 scoped_refptr<IndexedDBDatabaseCallbacks> db_callbacks( |
| 439 new MockIndexedDBDatabaseCallbacks()); | 445 new MockIndexedDBDatabaseCallbacks()); |
| 440 | 446 |
| 441 // Open at version 2, then close. | 447 // Open at version 2, then close. |
| 442 { | 448 { |
| 443 scoped_refptr<MockIndexedDBCallbacks> callbacks( | 449 scoped_refptr<MockIndexedDBCallbacks> callbacks( |
| 444 new UpgradeNeededCallbacks()); | 450 new UpgradeNeededCallbacks()); |
| 445 IndexedDBPendingConnection connection(callbacks, | 451 IndexedDBPendingConnection connection(callbacks, |
| 446 db_callbacks, | 452 db_callbacks, |
| 447 0, /* child_process_id */ | 453 0, /* child_process_id */ |
| 448 transaction_id, | 454 transaction_id, |
| 449 db_version); | 455 db_version); |
| 450 factory->Open(db_name, connection, origin, temp_directory.path()); | 456 factory()->Open(db_name, connection, origin, temp_directory.path()); |
| 451 EXPECT_TRUE(factory->IsDatabaseOpen(origin, db_name)); | 457 EXPECT_TRUE(factory()->IsDatabaseOpen(origin, db_name)); |
| 452 | 458 |
| 453 // Pump the message loop so the upgrade transaction can run. | 459 // Pump the message loop so the upgrade transaction can run. |
| 454 base::MessageLoop::current()->RunUntilIdle(); | 460 base::MessageLoop::current()->RunUntilIdle(); |
| 455 EXPECT_TRUE(callbacks->connection()); | 461 EXPECT_TRUE(callbacks->connection()); |
| 456 callbacks->connection()->database()->Commit(transaction_id); | 462 callbacks->connection()->database()->Commit(transaction_id); |
| 457 | 463 |
| 458 callbacks->connection()->Close(); | 464 callbacks->connection()->Close(); |
| 459 EXPECT_FALSE(factory->IsDatabaseOpen(origin, db_name)); | 465 EXPECT_FALSE(factory()->IsDatabaseOpen(origin, db_name)); |
| 460 } | 466 } |
| 461 | 467 |
| 462 // Open at version < 2, which will fail; ensure factory doesn't retain | 468 // Open at version < 2, which will fail; ensure factory doesn't retain |
| 463 // the database object. | 469 // the database object. |
| 464 { | 470 { |
| 465 scoped_refptr<IndexedDBCallbacks> callbacks(new ErrorCallbacks()); | 471 scoped_refptr<IndexedDBCallbacks> callbacks(new ErrorCallbacks()); |
| 466 IndexedDBPendingConnection connection(callbacks, | 472 IndexedDBPendingConnection connection(callbacks, |
| 467 db_callbacks, | 473 db_callbacks, |
| 468 0, /* child_process_id */ | 474 0, /* child_process_id */ |
| 469 transaction_id, | 475 transaction_id, |
| 470 db_version - 1); | 476 db_version - 1); |
| 471 factory->Open(db_name, connection, origin, temp_directory.path()); | 477 factory()->Open(db_name, connection, origin, temp_directory.path()); |
| 472 EXPECT_FALSE(factory->IsDatabaseOpen(origin, db_name)); | 478 EXPECT_FALSE(factory()->IsDatabaseOpen(origin, db_name)); |
| 473 } | 479 } |
| 474 | 480 |
| 475 // Terminate all pending-close timers. | 481 // Terminate all pending-close timers. |
| 476 factory->ForceClose(origin); | 482 factory()->ForceClose(origin); |
| 477 } | 483 } |
| 478 | 484 |
| 479 } // namespace content | 485 } // namespace content |
| OLD | NEW |