Index: content/browser/indexed_db/indexed_db_factory_unittest.cc |
diff --git a/content/browser/indexed_db/indexed_db_factory_unittest.cc b/content/browser/indexed_db/indexed_db_factory_unittest.cc |
index 5dae53c3f2314eca34006b3d4f6d6c92cc597922..14adfa55ce7f7761a69012a43438c123318b86c0 100644 |
--- a/content/browser/indexed_db/indexed_db_factory_unittest.cc |
+++ b/content/browser/indexed_db/indexed_db_factory_unittest.cc |
@@ -43,9 +43,9 @@ class MockIDBFactory : public IndexedDBFactoryImpl { |
IndexedDBDataLossInfo data_loss_info; |
bool disk_full; |
leveldb::Status s; |
- scoped_refptr<IndexedDBBackingStore> backing_store = |
- OpenBackingStore(origin, data_directory, nullptr /* request_context */, |
- &data_loss_info, &disk_full, &s); |
+ scoped_refptr<IndexedDBBackingStore> backing_store = OpenBackingStore( |
+ origin, data_directory, IndexedDBDataFormatVersion(), |
+ nullptr /* request_context */, &data_loss_info, &disk_full, &s); |
EXPECT_EQ(blink::WebIDBDataLossNone, data_loss_info.status); |
return backing_store; |
} |
@@ -69,24 +69,28 @@ class MockIDBFactory : public IndexedDBFactoryImpl { |
class IndexedDBFactoryTest : public testing::Test { |
public: |
- IndexedDBFactoryTest() { |
+ void SetUp() override { |
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
task_runner_ = new base::TestSimpleTaskRunner(); |
quota_manager_proxy_ = new MockQuotaManagerProxy(nullptr, nullptr); |
context_ = new IndexedDBContextImpl( |
- base::FilePath(), nullptr /* special_storage_policy */, |
+ temp_dir_.GetPath(), nullptr /* special_storage_policy */, |
quota_manager_proxy_.get(), task_runner_.get()); |
idb_factory_ = new MockIDBFactory(context_.get()); |
} |
- ~IndexedDBFactoryTest() override { |
+ |
+ void TearDown() override { |
quota_manager_proxy_->SimulateQuotaManagerDestroyed(); |
} |
protected: |
+ IndexedDBFactoryTest() {} |
MockIDBFactory* factory() const { return idb_factory_.get(); } |
void clear_factory() { idb_factory_ = nullptr; } |
IndexedDBContextImpl* context() const { return context_.get(); } |
private: |
+ base::ScopedTempDir temp_dir_; |
scoped_refptr<base::TestSimpleTaskRunner> task_runner_; |
scoped_refptr<IndexedDBContextImpl> context_; |
scoped_refptr<MockIDBFactory> idb_factory_; |
@@ -213,6 +217,7 @@ class DiskFullFactory : public IndexedDBFactoryImpl { |
scoped_refptr<IndexedDBBackingStore> OpenBackingStore( |
const Origin& origin, |
const base::FilePath& data_directory, |
+ const IndexedDBDataFormatVersion& data_format_version, |
scoped_refptr<net::URLRequestContextGetter> request_context_getter, |
IndexedDBDataLossInfo* data_loss_info, |
bool* disk_full, |
@@ -259,7 +264,7 @@ TEST_F(IndexedDBFactoryTest, QuotaErrorOnDiskFull) { |
callbacks, dummy_database_callbacks, 0 /* child_process_id */, |
2 /* transaction_id */, 1 /* version */)); |
factory->Open(name, std::move(connection), nullptr /* request_context */, |
- origin, temp_directory.GetPath()); |
+ origin, temp_directory.GetPath(), IndexedDBDataFormatVersion()); |
EXPECT_TRUE(callbacks->error_called()); |
} |
@@ -279,7 +284,7 @@ TEST_F(IndexedDBFactoryTest, BackingStoreReleasedOnForcedClose) { |
IndexedDBDatabaseMetadata::DEFAULT_VERSION)); |
factory()->Open(ASCIIToUTF16("db"), std::move(connection), |
nullptr /* request_context */, origin, |
- temp_directory.GetPath()); |
+ temp_directory.GetPath(), IndexedDBDataFormatVersion()); |
EXPECT_TRUE(callbacks->connection()); |
@@ -308,7 +313,7 @@ TEST_F(IndexedDBFactoryTest, BackingStoreReleaseDelayedOnClose) { |
IndexedDBDatabaseMetadata::DEFAULT_VERSION)); |
factory()->Open(ASCIIToUTF16("db"), std::move(connection), |
nullptr /* request_context */, origin, |
- temp_directory.GetPath()); |
+ temp_directory.GetPath(), IndexedDBDataFormatVersion()); |
EXPECT_TRUE(callbacks->connection()); |
IndexedDBBackingStore* store = |
@@ -345,6 +350,7 @@ TEST_F(IndexedDBFactoryTest, DeleteDatabaseClosesBackingStore) { |
new MockIndexedDBCallbacks(expect_connection)); |
factory()->DeleteDatabase(ASCIIToUTF16("db"), nullptr /* request_context */, |
callbacks, origin, temp_directory.GetPath(), |
+ IndexedDBDataFormatVersion(), |
false /* force_close */); |
EXPECT_TRUE(factory()->IsBackingStoreOpen(origin)); |
@@ -369,6 +375,7 @@ TEST_F(IndexedDBFactoryTest, GetDatabaseNamesClosesBackingStore) { |
scoped_refptr<MockIndexedDBCallbacks> callbacks( |
new MockIndexedDBCallbacks(expect_connection)); |
factory()->GetDatabaseNames(callbacks, origin, temp_directory.GetPath(), |
+ IndexedDBDataFormatVersion(), |
nullptr /* request_context */); |
EXPECT_TRUE(factory()->IsBackingStoreOpen(origin)); |
@@ -397,7 +404,7 @@ TEST_F(IndexedDBFactoryTest, ForceCloseReleasesBackingStore) { |
IndexedDBDatabaseMetadata::DEFAULT_VERSION)); |
factory()->Open(ASCIIToUTF16("db"), std::move(connection), |
nullptr /* request_context */, origin, |
- temp_directory.GetPath()); |
+ temp_directory.GetPath(), IndexedDBDataFormatVersion()); |
EXPECT_TRUE(callbacks->connection()); |
EXPECT_TRUE(factory()->IsBackingStoreOpen(origin)); |
@@ -479,7 +486,7 @@ TEST_F(IndexedDBFactoryTest, DatabaseFailedOpen) { |
db_version)); |
factory()->Open(db_name, std::move(connection), |
nullptr /* request_context */, origin, |
- temp_directory.GetPath()); |
+ temp_directory.GetPath(), IndexedDBDataFormatVersion()); |
EXPECT_TRUE(factory()->IsDatabaseOpen(origin, db_name)); |
// Pump the message loop so the upgrade transaction can run. |
@@ -502,7 +509,7 @@ TEST_F(IndexedDBFactoryTest, DatabaseFailedOpen) { |
db_version - 1)); |
factory()->Open(db_name, std::move(connection), |
nullptr /* request_context */, origin, |
- temp_directory.GetPath()); |
+ temp_directory.GetPath(), IndexedDBDataFormatVersion()); |
EXPECT_TRUE(callbacks->saw_error()); |
EXPECT_FALSE(factory()->IsDatabaseOpen(origin, db_name)); |
} |
@@ -510,5 +517,79 @@ TEST_F(IndexedDBFactoryTest, DatabaseFailedOpen) { |
// Terminate all pending-close timers. |
factory()->ForceClose(origin); |
} |
+namespace { |
+ |
+class DataLossCallbacks final : public MockIndexedDBCallbacks { |
+ public: |
+ blink::WebIDBDataLoss data_loss() const { return data_loss_; } |
+ void OnSuccess(std::unique_ptr<IndexedDBConnection> connection, |
+ const IndexedDBDatabaseMetadata& metadata) override { |
+ if (!connection_) |
+ connection_ = std::move(connection); |
+ } |
+ void OnError(const IndexedDBDatabaseError& error) final { |
+ ADD_FAILURE() << "Unexpected IDB error: " << error.message(); |
+ } |
+ void OnUpgradeNeeded(int64_t old_version, |
+ std::unique_ptr<IndexedDBConnection> connection, |
+ const content::IndexedDBDatabaseMetadata& metadata, |
+ const IndexedDBDataLossInfo& data_loss) final { |
+ connection_ = std::move(connection); |
+ data_loss_ = data_loss.status; |
+ } |
+ |
+ private: |
+ ~DataLossCallbacks() final {} |
+ blink::WebIDBDataLoss data_loss_ = blink::WebIDBDataLossNone; |
+}; |
+ |
+TEST_F(IndexedDBFactoryTest, DataFormatVersion) { |
+ auto try_open = [this](const Origin& origin, |
+ const IndexedDBDataFormatVersion& version) { |
+ auto db_callbacks = make_scoped_refptr(new MockIndexedDBDatabaseCallbacks); |
+ auto callbacks = make_scoped_refptr(new DataLossCallbacks); |
+ const int64_t transaction_id = 1; |
+ factory()->Open(ASCIIToUTF16("test_db"), |
+ base::MakeUnique<IndexedDBPendingConnection>( |
+ callbacks, db_callbacks, 0 /* child_process_id */, |
+ transaction_id, 1 /* version */), |
+ nullptr /* request_context */, origin, |
+ context()->data_path(), version); |
+ base::RunLoop().RunUntilIdle(); |
+ auto* connection = callbacks->connection(); |
+ EXPECT_TRUE(connection); |
+ connection->database()->Commit(connection->GetTransaction(transaction_id)); |
+ connection->Close(); |
+ factory()->ForceClose(origin); |
+ return callbacks->data_loss(); |
+ }; |
+ |
+ using blink::WebIDBDataLossNone; |
+ using blink::WebIDBDataLossTotal; |
+ const struct { |
+ const char* origin; |
+ IndexedDBDataFormatVersion open_version_1; |
+ IndexedDBDataFormatVersion open_version_2; |
+ blink::WebIDBDataLoss expected_data_loss; |
+ } kTestCases[] = { |
+ {"http://same-version.com/", {3, 4}, {3, 4}, WebIDBDataLossNone}, |
+ {"http://blink-upgrade.com/", {3, 4}, {3, 5}, WebIDBDataLossNone}, |
+ {"http://v8-upgrade.com/", {3, 4}, {4, 4}, WebIDBDataLossNone}, |
+ {"http://both-upgrade.com/", {3, 4}, {4, 5}, WebIDBDataLossNone}, |
+ {"http://blink-downgrade.com/", {3, 4}, {3, 3}, WebIDBDataLossTotal}, |
+ {"http://v8-downgrade.com/", {3, 4}, {2, 4}, WebIDBDataLossTotal}, |
+ {"http://both-downgrade.com/", {3, 4}, {2, 3}, WebIDBDataLossTotal}, |
+ {"http://v8-up-blink-down.com/", {3, 4}, {4, 2}, WebIDBDataLossTotal}, |
+ {"http://v8-down-blink-up.com/", {3, 4}, {2, 5}, WebIDBDataLossTotal}, |
+ }; |
+ for (const auto& test : kTestCases) { |
+ SCOPED_TRACE(test.origin); |
+ const Origin origin(GURL(test.origin)); |
+ ASSERT_EQ(WebIDBDataLossNone, try_open(origin, test.open_version_1)); |
+ EXPECT_EQ(test.expected_data_loss, try_open(origin, test.open_version_2)); |
+ } |
+} |
+ |
+} // namespace |
} // namespace content |