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..48dfc66bbd4911ba3cf46b26b343b039f25f6a4e 100644 |
--- a/content/browser/indexed_db/indexed_db_factory_unittest.cc |
+++ b/content/browser/indexed_db/indexed_db_factory_unittest.cc |
@@ -5,6 +5,7 @@ |
#include <stdint.h> |
#include <utility> |
+#include "base/auto_reset.h" |
#include "base/files/file_util.h" |
#include "base/files/scoped_temp_dir.h" |
#include "base/logging.h" |
@@ -15,6 +16,7 @@ |
#include "base/test/test_simple_task_runner.h" |
#include "content/browser/indexed_db/indexed_db_connection.h" |
#include "content/browser/indexed_db/indexed_db_context_impl.h" |
+#include "content/browser/indexed_db/indexed_db_data_format_version.h" |
#include "content/browser/indexed_db/indexed_db_factory_impl.h" |
#include "content/browser/indexed_db/mock_indexed_db_callbacks.h" |
#include "content/browser/indexed_db/mock_indexed_db_database_callbacks.h" |
@@ -69,24 +71,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_; |
@@ -511,4 +517,81 @@ TEST_F(IndexedDBFactoryTest, DatabaseFailedOpen) { |
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) { |
+ base::AutoReset<IndexedDBDataFormatVersion> override_version( |
+ &IndexedDBDataFormatVersion::GetMutableCurrentForTesting(), version); |
+ auto db_callbacks = base::MakeShared<MockIndexedDBDatabaseCallbacks>(); |
+ auto callbacks = base::MakeShared<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()); |
+ 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; |
+ static 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 |