// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#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"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind_test_util.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_clock.h"
#include "base/test/test_simple_task_runner.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/time/default_clock.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/leveldb/leveldb_env.h"
#include "content/browser/indexed_db/mock_indexed_db_callbacks.h"
#include "content/browser/indexed_db/mock_indexed_db_database_callbacks.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_utils.h"
#include "storage/browser/test/mock_quota_manager_proxy.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/indexeddb/web_idb_types.h"
#include "third_party/blink/public/platform/modules/indexeddb/web_idb_database_exception.h"
#include "url/gurl.h"
#include "url/origin.h"

using base::ASCIIToUTF16;
using blink::IndexedDBDatabaseMetadata;
using url::Origin;

namespace content {

namespace {

class MockIDBFactory : public IndexedDBFactoryImpl {
 public:
  explicit MockIDBFactory(IndexedDBContextImpl* context)
      : MockIDBFactory(context, base::DefaultClock::GetInstance()) {}
  MockIDBFactory(IndexedDBContextImpl* context, base::Clock* clock)
      : IndexedDBFactoryImpl(context,
                             indexed_db::GetDefaultLevelDBFactory(),
                             clock) {}
  scoped_refptr<IndexedDBBackingStore> TestOpenBackingStore(
      const Origin& origin,
      const base::FilePath& data_directory) {
    IndexedDBDataLossInfo data_loss_info;
    bool disk_full;
    leveldb::Status s;
    scoped_refptr<IndexedDBBackingStore> backing_store;
    std::tie(backing_store, s, data_loss_info, disk_full) =
        OpenBackingStore(origin, data_directory);
    EXPECT_EQ(blink::mojom::IDBDataLoss::None, data_loss_info.status);
    return backing_store;
  }

  void TestCloseBackingStore(IndexedDBBackingStore* backing_store) {
    CloseBackingStore(backing_store->origin());
  }

  void TestReleaseBackingStore(IndexedDBBackingStore* backing_store,
                               bool immediate) {
    ReleaseBackingStore(backing_store->origin(), immediate);
  }

 private:
  ~MockIDBFactory() override {}

  DISALLOW_COPY_AND_ASSIGN(MockIDBFactory);
};

}  // namespace

class IndexedDBFactoryTest : public testing::Test {
 public:
  IndexedDBFactoryTest()
      : quota_manager_proxy_(
            base::MakeRefCounted<MockQuotaManagerProxy>(nullptr, nullptr)) {}

  void SetUp() override {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    context_ = base::MakeRefCounted<IndexedDBContextImpl>(
        temp_dir_.GetPath(), /*special_storage_policy=*/nullptr,
        quota_manager_proxy_.get(), indexed_db::GetDefaultLevelDBFactory());
  }

  void TearDown() override {
    quota_manager_proxy_->SimulateQuotaManagerDestroyed();
  }

 protected:
  IndexedDBContextImpl* context() const { return context_.get(); }

 private:
  TestBrowserThreadBundle thread_bundle_;

  base::ScopedTempDir temp_dir_;
  scoped_refptr<MockQuotaManagerProxy> quota_manager_proxy_;
  scoped_refptr<IndexedDBContextImpl> context_;

  DISALLOW_COPY_AND_ASSIGN(IndexedDBFactoryTest);
};

TEST_F(IndexedDBFactoryTest, BackingStoreLifetime) {
  base::RunLoop loop;
  context()->TaskRunner()->PostTask(
      FROM_HERE, base::BindLambdaForTesting([&]() {
        auto factory = base::MakeRefCounted<MockIDBFactory>(context());

        const Origin origin1 = Origin::Create(GURL("http://localhost:81"));
        const Origin origin2 = Origin::Create(GURL("http://localhost:82"));

        auto disk_store1 =
            factory->TestOpenBackingStore(origin1, context()->data_path());

        auto disk_store2 =
            factory->TestOpenBackingStore(origin1, context()->data_path());
        EXPECT_EQ(disk_store1.get(), disk_store2.get());

        auto disk_store3 =
            factory->TestOpenBackingStore(origin2, context()->data_path());

        factory->TestCloseBackingStore(disk_store1.get());
        factory->TestCloseBackingStore(disk_store3.get());

        EXPECT_FALSE(disk_store1->HasOneRef());
        EXPECT_FALSE(disk_store2->HasOneRef());
        EXPECT_TRUE(disk_store3->HasOneRef());

        disk_store2 = nullptr;
        EXPECT_TRUE(disk_store1->HasOneRef());
        loop.Quit();
      }));
  loop.Run();
}

TEST_F(IndexedDBFactoryTest, BackingStoreLazyClose) {
  base::RunLoop loop;
  context()->TaskRunner()->PostTask(
      FROM_HERE, base::BindLambdaForTesting([&]() {
        auto factory = base::MakeRefCounted<MockIDBFactory>(context());

        const Origin origin = Origin::Create(GURL("http://localhost:81"));

        auto store =
            factory->TestOpenBackingStore(origin, context()->data_path());

        // Give up the local refptr so that the factory has the only
        // outstanding reference.
        IndexedDBBackingStore* store_ptr = store.get();
        store = nullptr;
        EXPECT_FALSE(store_ptr->close_timer()->IsRunning());
        factory->TestReleaseBackingStore(store_ptr, false);
        EXPECT_TRUE(store_ptr->close_timer()->IsRunning());

        factory->TestOpenBackingStore(origin, context()->data_path());
        EXPECT_FALSE(store_ptr->close_timer()->IsRunning());
        factory->TestReleaseBackingStore(store_ptr, false);
        EXPECT_TRUE(store_ptr->close_timer()->IsRunning());

        // Take back a ref ptr and ensure that the actual close
        // stops a running timer.
        store = store_ptr;
        factory->TestCloseBackingStore(store_ptr);
        EXPECT_FALSE(store_ptr->close_timer()->IsRunning());
        loop.Quit();
      }));
  loop.Run();
}

TEST_F(IndexedDBFactoryTest, BackingStoreNoSweeping) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitWithFeatures(
      {}, {kIDBTombstoneDeletion, kIDBTombstoneStatistics});
  base::RunLoop loop;
  context()->TaskRunner()->PostTask(
      FROM_HERE, base::BindLambdaForTesting([&]() {
        base::SimpleTestClock clock;
        clock.SetNow(base::Time::Now());

        auto factory = base::MakeRefCounted<MockIDBFactory>(context(), &clock);

        const Origin origin = Origin::Create(GURL("http://localhost:81"));

        auto store =
            factory->TestOpenBackingStore(origin, context()->data_path());

        // Give up the local refptr so that the factory has the only
        // outstanding reference.
        IndexedDBBackingStore* store_ptr = store.get();
        store = nullptr;
        EXPECT_FALSE(store_ptr->close_timer()->IsRunning());
        factory->TestReleaseBackingStore(store_ptr, false);
        EXPECT_TRUE(store_ptr->close_timer()->IsRunning());
        EXPECT_EQ(nullptr, store_ptr->pre_close_task_queue());

        // Reset the timer & stop the closing.
        factory->TestOpenBackingStore(origin, context()->data_path());
        EXPECT_FALSE(store_ptr->close_timer()->IsRunning());
        factory->TestReleaseBackingStore(store_ptr, false);
        EXPECT_TRUE(store_ptr->close_timer()->IsRunning());
        store_ptr->close_timer()->FireNow();

        // Backing store should be totally closed.
        EXPECT_FALSE(factory->IsBackingStoreOpen(origin));

        store = factory->TestOpenBackingStore(origin, context()->data_path());
        store_ptr = store.get();
        store = nullptr;
        EXPECT_FALSE(store_ptr->close_timer()->IsRunning());

        // Move the clock to start the next sweep.
        clock.Advance(IndexedDBFactoryImpl::kMaxEarliestGlobalSweepFromNow);
        factory->TestReleaseBackingStore(store_ptr, false);

        // Sweep should NOT be occurring.
        EXPECT_TRUE(store_ptr->close_timer()->IsRunning());
        store_ptr->close_timer()->FireNow();

        // Backing store should be totally closed.
        EXPECT_FALSE(factory->IsBackingStoreOpen(origin));
        loop.Quit();
      }));
  loop.Run();
}

TEST_F(IndexedDBFactoryTest, BackingStoreRunPreCloseTasks) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitWithFeatures({kIDBTombstoneStatistics},
                                {kIDBTombstoneDeletion});
  base::RunLoop loop;
  context()->TaskRunner()->PostTask(
      FROM_HERE, base::BindLambdaForTesting([&]() {
        base::SimpleTestClock clock;
        clock.SetNow(base::Time::Now());

        auto factory = base::MakeRefCounted<MockIDBFactory>(context(), &clock);

        const Origin origin = Origin::Create(GURL("http://localhost:81"));

        auto store =
            factory->TestOpenBackingStore(origin, context()->data_path());

        // Give up the local refptr so that the factory has the only
        // outstanding reference.
        IndexedDBBackingStore* store_ptr = store.get();
        store = nullptr;
        EXPECT_FALSE(store_ptr->close_timer()->IsRunning());
        factory->TestReleaseBackingStore(store_ptr, false);
        EXPECT_TRUE(store_ptr->close_timer()->IsRunning());
        EXPECT_EQ(nullptr, store_ptr->pre_close_task_queue());

        // Reset the timer & stop the closing.
        factory->TestOpenBackingStore(origin, context()->data_path());
        EXPECT_FALSE(store_ptr->close_timer()->IsRunning());
        factory->TestReleaseBackingStore(store_ptr, false);
        EXPECT_TRUE(store_ptr->close_timer()->IsRunning());
        store_ptr->close_timer()->FireNow();

        // Backing store should be totally closed.
        EXPECT_FALSE(factory->IsBackingStoreOpen(origin));

        store = factory->TestOpenBackingStore(origin, context()->data_path());
        store_ptr = store.get();
        store = nullptr;
        EXPECT_FALSE(store_ptr->close_timer()->IsRunning());

        // Move the clock to start the next sweep.
        clock.Advance(IndexedDBFactoryImpl::kMaxEarliestGlobalSweepFromNow);
        factory->TestReleaseBackingStore(store_ptr, false);

        // Sweep should be occuring.
        EXPECT_TRUE(store_ptr->close_timer()->IsRunning());
        store_ptr->close_timer()->FireNow();
        ASSERT_NE(nullptr, store_ptr->pre_close_task_queue());
        EXPECT_TRUE(store_ptr->pre_close_task_queue()->started());

        // Stop sweep by opening a connection.
        factory->TestOpenBackingStore(origin, context()->data_path());
        EXPECT_EQ(nullptr, store_ptr->pre_close_task_queue());

        // Move clock forward to trigger next sweep, but origin has longer
        // sweep minimum, so nothing happens.
        clock.Advance(IndexedDBFactoryImpl::kMaxEarliestGlobalSweepFromNow);

        factory->TestReleaseBackingStore(store_ptr, false);
        EXPECT_TRUE(store_ptr->close_timer()->IsRunning());
        EXPECT_EQ(nullptr, store_ptr->pre_close_task_queue());

        // Reset, and move clock forward so the origin should allow a sweep.
        factory->TestOpenBackingStore(origin, context()->data_path());
        EXPECT_EQ(nullptr, store_ptr->pre_close_task_queue());
        clock.Advance(IndexedDBFactoryImpl::kMaxEarliestOriginSweepFromNow);
        factory->TestReleaseBackingStore(store_ptr, false);

        // Sweep should be occuring.
        EXPECT_TRUE(store_ptr->close_timer()->IsRunning());
        store_ptr->close_timer()->FireNow();
        ASSERT_NE(nullptr, store_ptr->pre_close_task_queue());
        EXPECT_TRUE(store_ptr->pre_close_task_queue()->started());

        // Take back a ref ptr and ensure that the actual close
        // stops a running timer.
        store = store_ptr;
        factory->TestCloseBackingStore(store_ptr);
        loop.Quit();
      }));
  loop.Run();
}

TEST_F(IndexedDBFactoryTest, BackingStoreCloseImmediatelySwitch) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitWithFeatures({kIDBTombstoneStatistics},
                                {kIDBTombstoneDeletion});
  base::CommandLine::ForCurrentProcess()->AppendSwitch(
      kIDBCloseImmediatelySwitch);
  base::RunLoop loop;
  context()->TaskRunner()->PostTask(
      FROM_HERE, base::BindLambdaForTesting([&]() {
        base::SimpleTestClock clock;
        clock.SetNow(base::Time::Now());

        auto factory = base::MakeRefCounted<MockIDBFactory>(context(), &clock);

        const Origin origin = Origin::Create(GURL("http://localhost:81"));

        auto store =
            factory->TestOpenBackingStore(origin, context()->data_path());

        // Give up the local refptr so that the factory has the only
        // outstanding reference.
        IndexedDBBackingStore* store_ptr = store.get();
        store = nullptr;
        EXPECT_FALSE(store_ptr->close_timer()->IsRunning());
        factory->TestReleaseBackingStore(store_ptr, false);
        EXPECT_FALSE(factory->IsBackingStoreOpen(origin));
        loop.Quit();
      }));
  loop.Run();
}

TEST_F(IndexedDBFactoryTest, MemoryBackingStoreLifetime) {
  base::RunLoop loop;
  context()->TaskRunner()->PostTask(
      FROM_HERE, base::BindLambdaForTesting([&]() {
        auto factory = base::MakeRefCounted<MockIDBFactory>(context());

        const Origin origin1 = Origin::Create(GURL("http://localhost:81"));
        const Origin origin2 = Origin::Create(GURL("http://localhost:82"));

        auto mem_store1 =
            factory->TestOpenBackingStore(origin1, base::FilePath());

        auto mem_store2 =
            factory->TestOpenBackingStore(origin1, base::FilePath());
        EXPECT_EQ(mem_store1.get(), mem_store2.get());

        auto mem_store3 =
            factory->TestOpenBackingStore(origin2, base::FilePath());

        factory->TestCloseBackingStore(mem_store1.get());
        factory->TestCloseBackingStore(mem_store3.get());

        EXPECT_FALSE(mem_store1->HasOneRef());
        EXPECT_FALSE(mem_store2->HasOneRef());
        EXPECT_FALSE(mem_store3->HasOneRef());

        factory = nullptr;
        EXPECT_FALSE(mem_store1->HasOneRef());  // mem_store1 and 2
        EXPECT_FALSE(mem_store2->HasOneRef());  // mem_store1 and 2
        EXPECT_TRUE(mem_store3->HasOneRef());

        mem_store2 = nullptr;
        EXPECT_TRUE(mem_store1->HasOneRef());
        loop.Quit();
      }));
  loop.Run();
}

TEST_F(IndexedDBFactoryTest, RejectLongOrigins) {
  base::RunLoop loop;
  context()->TaskRunner()->PostTask(
      FROM_HERE, base::BindLambdaForTesting([&]() {
        base::FilePath temp_dir = context()->data_path().DirName();
        int limit = base::GetMaximumPathComponentLength(temp_dir);
        EXPECT_GT(limit, 0);

        auto factory = base::MakeRefCounted<MockIDBFactory>(context());

        std::string origin(limit + 1, 'x');
        Origin too_long_origin =
            Origin::Create(GURL("http://" + origin + ":81/"));
        auto diskStore1 = factory->TestOpenBackingStore(too_long_origin,
                                                        context()->data_path());
        EXPECT_FALSE(diskStore1.get());

        Origin ok_origin = Origin::Create(GURL("http://someorigin.com:82/"));
        auto diskStore2 =
            factory->TestOpenBackingStore(ok_origin, context()->data_path());
        EXPECT_TRUE(diskStore2.get());
        // We need a manual close or Windows can't delete the temp
        // directory.
        factory->TestCloseBackingStore(diskStore2.get());
        loop.Quit();
      }));

  loop.Run();
}

class DiskFullFactory : public IndexedDBFactoryImpl {
 public:
  explicit DiskFullFactory(IndexedDBContextImpl* context)
      : IndexedDBFactoryImpl(context,
                             indexed_db::GetDefaultLevelDBFactory(),
                             base::DefaultClock::GetInstance()) {}

 private:
  ~DiskFullFactory() override {}

  std::tuple<scoped_refptr<IndexedDBBackingStore>,
             leveldb::Status,
             IndexedDBDataLossInfo,
             bool /* disk_full */>
  OpenBackingStore(const url::Origin& origin,
                   const base::FilePath& data_directory) override {
    return std::make_tuple(nullptr, leveldb::Status::IOError("Disk is full"),
                           IndexedDBDataLossInfo(), true);
  }

  DISALLOW_COPY_AND_ASSIGN(DiskFullFactory);
};

class LookingForQuotaErrorMockCallbacks : public IndexedDBCallbacks {
 public:
  LookingForQuotaErrorMockCallbacks()
      : IndexedDBCallbacks(nullptr,
                           url::Origin(),
                           nullptr,
                           base::SequencedTaskRunnerHandle::Get()),
        error_called_(false) {}
  void OnError(const IndexedDBDatabaseError& error) override {
    error_called_ = true;
    EXPECT_EQ(blink::kWebIDBDatabaseExceptionQuotaError, error.code());
  }
  bool error_called() const { return error_called_; }

 private:
  ~LookingForQuotaErrorMockCallbacks() override {}
  bool error_called_;

  DISALLOW_COPY_AND_ASSIGN(LookingForQuotaErrorMockCallbacks);
};

TEST_F(IndexedDBFactoryTest, QuotaErrorOnDiskFull) {
  base::RunLoop loop;
  context()->TaskRunner()->PostTask(
      FROM_HERE, base::BindLambdaForTesting([&]() {
        auto callbacks =
            base::MakeRefCounted<LookingForQuotaErrorMockCallbacks>();
        auto dummy_database_callbacks =
            base::MakeRefCounted<IndexedDBDatabaseCallbacks>(
                nullptr, nullptr, context()->TaskRunner());
        const Origin origin = Origin::Create(GURL("http://localhost:81"));
        auto factory = base::MakeRefCounted<DiskFullFactory>(context());
        const base::string16 name(ASCIIToUTF16("name"));
        auto connection = std::make_unique<IndexedDBPendingConnection>(
            callbacks, dummy_database_callbacks, /*child_process_id=*/0,
            /*transaction_id=*/2, /*version=*/1);
        factory->Open(name, std::move(connection), origin,
                      context()->data_path());
        EXPECT_TRUE(callbacks->error_called());
        loop.Quit();
      }));
  loop.Run();
}

TEST_F(IndexedDBFactoryTest, BackingStoreReleasedOnForcedClose) {
  base::RunLoop loop;
  context()->TaskRunner()->PostTask(
      FROM_HERE, base::BindLambdaForTesting([&]() {
        auto factory = base::MakeRefCounted<MockIDBFactory>(context());
        auto callbacks = base::MakeRefCounted<MockIndexedDBCallbacks>();
        auto db_callbacks =
            base::MakeRefCounted<MockIndexedDBDatabaseCallbacks>();

        const Origin origin = Origin::Create(GURL("http://localhost:81"));
        const int64_t transaction_id = 1;
        auto connection = std::make_unique<IndexedDBPendingConnection>(
            callbacks, db_callbacks, /*child_process_id=*/0, transaction_id,
            IndexedDBDatabaseMetadata::DEFAULT_VERSION);
        factory->Open(ASCIIToUTF16("db"), std::move(connection), origin,
                      context()->data_path());

        EXPECT_TRUE(callbacks->connection());

        EXPECT_TRUE(factory->IsBackingStoreOpen(origin));
        EXPECT_FALSE(factory->IsBackingStorePendingClose(origin));

        callbacks->connection()->ForceClose();

        EXPECT_FALSE(factory->IsBackingStoreOpen(origin));
        EXPECT_FALSE(factory->IsBackingStorePendingClose(origin));
        loop.Quit();
      }));
  loop.Run();
}

TEST_F(IndexedDBFactoryTest, BackingStoreReleaseDelayedOnClose) {
  base::RunLoop loop;
  context()->TaskRunner()->PostTask(
      FROM_HERE, base::BindLambdaForTesting([&]() {
        auto factory = base::MakeRefCounted<MockIDBFactory>(context());
        auto callbacks = base::MakeRefCounted<MockIndexedDBCallbacks>();
        auto db_callbacks =
            base::MakeRefCounted<MockIndexedDBDatabaseCallbacks>();

        const Origin origin = Origin::Create(GURL("http://localhost:81"));
        const int64_t transaction_id = 1;
        auto connection = std::make_unique<IndexedDBPendingConnection>(
            callbacks, db_callbacks, /*child_process_id=*/0, transaction_id,
            IndexedDBDatabaseMetadata::DEFAULT_VERSION);
        factory->Open(ASCIIToUTF16("db"), std::move(connection), origin,
                      context()->data_path());

        EXPECT_TRUE(callbacks->connection());
        IndexedDBBackingStore* store =
            callbacks->connection()->database()->backing_store();
        EXPECT_FALSE(store->HasOneRef());  // Factory and database.

        EXPECT_TRUE(factory->IsBackingStoreOpen(origin));
        callbacks->connection()->Close();
        EXPECT_TRUE(store->HasOneRef());  // Factory.
        EXPECT_TRUE(factory->IsBackingStoreOpen(origin));
        EXPECT_TRUE(factory->IsBackingStorePendingClose(origin));
        EXPECT_TRUE(store->close_timer()->IsRunning());

        // Take a ref so it won't be destroyed out from under the test.
        scoped_refptr<IndexedDBBackingStore> store_ref = store;

        // Now simulate shutdown, which should stop the timer.
        factory->ContextDestroyed();
        EXPECT_TRUE(store->HasOneRef());  // Local.
        EXPECT_FALSE(store->close_timer()->IsRunning());
        EXPECT_FALSE(factory->IsBackingStoreOpen(origin));
        EXPECT_FALSE(factory->IsBackingStorePendingClose(origin));
        loop.Quit();
      }));
  loop.Run();
}

TEST_F(IndexedDBFactoryTest, DeleteDatabaseClosesBackingStore) {
  base::RunLoop loop;
  context()->TaskRunner()->PostTask(
      FROM_HERE, base::BindLambdaForTesting([&]() {
        auto factory = base::MakeRefCounted<MockIDBFactory>(context());
        auto callbacks = base::MakeRefCounted<MockIndexedDBCallbacks>(
            /*expect_connection=*/false);

        const Origin origin = Origin::Create(GURL("http://localhost:81"));
        EXPECT_FALSE(factory->IsBackingStoreOpen(origin));

        factory->DeleteDatabase(ASCIIToUTF16("db"), callbacks, origin,
                                context()->data_path(),
                                /*force_close=*/false);

        EXPECT_TRUE(factory->IsBackingStoreOpen(origin));
        EXPECT_TRUE(factory->IsBackingStorePendingClose(origin));

        // Now simulate shutdown, which should stop the timer.
        factory->ContextDestroyed();

        EXPECT_FALSE(factory->IsBackingStoreOpen(origin));
        EXPECT_FALSE(factory->IsBackingStorePendingClose(origin));

        loop.Quit();
      }));
  loop.Run();
}

TEST_F(IndexedDBFactoryTest, GetDatabaseNamesClosesBackingStore) {
  base::RunLoop loop;
  context()->TaskRunner()->PostTask(
      FROM_HERE, base::BindLambdaForTesting([&]() {
        auto factory = base::MakeRefCounted<MockIDBFactory>(context());
        auto callbacks = base::MakeRefCounted<MockIndexedDBCallbacks>(
            /*expect_connection=*/false);

        const Origin origin = Origin::Create(GURL("http://localhost:81"));
        EXPECT_FALSE(factory->IsBackingStoreOpen(origin));

        factory->GetDatabaseNames(callbacks, origin, context()->data_path());

        EXPECT_TRUE(factory->IsBackingStoreOpen(origin));
        EXPECT_TRUE(factory->IsBackingStorePendingClose(origin));

        // Now simulate shutdown, which should stop the timer.
        factory->ContextDestroyed();

        EXPECT_FALSE(factory->IsBackingStoreOpen(origin));
        EXPECT_FALSE(factory->IsBackingStorePendingClose(origin));

        loop.Quit();
      }));
  loop.Run();
}

TEST_F(IndexedDBFactoryTest, ForceCloseReleasesBackingStore) {
  base::RunLoop loop;
  context()->TaskRunner()->PostTask(
      FROM_HERE, base::BindLambdaForTesting([&]() {
        auto factory = base::MakeRefCounted<MockIDBFactory>(context());
        auto callbacks = base::MakeRefCounted<MockIndexedDBCallbacks>();
        auto db_callbacks =
            base::MakeRefCounted<MockIndexedDBDatabaseCallbacks>();

        const Origin origin = Origin::Create(GURL("http://localhost:81"));
        const int64_t transaction_id = 1;
        auto connection = std::make_unique<IndexedDBPendingConnection>(
            callbacks, db_callbacks, /*child_process_id=*/0, transaction_id,
            IndexedDBDatabaseMetadata::DEFAULT_VERSION);
        factory->Open(ASCIIToUTF16("db"), std::move(connection), origin,
                      context()->data_path());

        EXPECT_TRUE(callbacks->connection());
        EXPECT_TRUE(factory->IsBackingStoreOpen(origin));
        EXPECT_FALSE(factory->IsBackingStorePendingClose(origin));

        callbacks->connection()->Close();

        EXPECT_TRUE(factory->IsBackingStoreOpen(origin));
        EXPECT_TRUE(factory->IsBackingStorePendingClose(origin));

        factory->ForceClose(origin, /*delete_in_memory_store=*/false);

        EXPECT_FALSE(factory->IsBackingStoreOpen(origin));
        EXPECT_FALSE(factory->IsBackingStorePendingClose(origin));

        // Ensure it is safe if the store is not open.
        factory->ForceClose(origin, /*delete_in_memory_store=*/false);

        loop.Quit();
      })),
      loop.Run();
}

class UpgradeNeededCallbacks : public MockIndexedDBCallbacks {
 public:
  UpgradeNeededCallbacks() {}

  void OnSuccess(std::unique_ptr<IndexedDBConnection> connection,
                 const IndexedDBDatabaseMetadata& metadata) override {
    EXPECT_TRUE(connection_.get());
    EXPECT_FALSE(connection.get());
  }

  void OnUpgradeNeeded(int64_t old_version,
                       std::unique_ptr<IndexedDBConnection> connection,
                       const IndexedDBDatabaseMetadata& metadata,
                       const IndexedDBDataLossInfo& data_loss_info) override {
    connection_ = std::move(connection);
  }

 protected:
  ~UpgradeNeededCallbacks() override {}

 private:
  DISALLOW_COPY_AND_ASSIGN(UpgradeNeededCallbacks);
};

class ErrorCallbacks : public MockIndexedDBCallbacks {
 public:
  ErrorCallbacks() : MockIndexedDBCallbacks(false), saw_error_(false) {}

  void OnError(const IndexedDBDatabaseError& error) override {
    saw_error_ = true;
  }
  bool saw_error() const { return saw_error_; }

 private:
  ~ErrorCallbacks() override {}
  bool saw_error_;

  DISALLOW_COPY_AND_ASSIGN(ErrorCallbacks);
};

TEST_F(IndexedDBFactoryTest, DatabaseFailedOpen) {
  const Origin origin = Origin::Create(GURL("http://localhost:81"));
  const base::string16 db_name(ASCIIToUTF16("db"));
  const int64_t transaction_id = 1;

  // These objects are retained across posted tasks, so despite being used
  // exclusively on the IDB sequence.

  // Created and used on IDB sequence.
  scoped_refptr<MockIDBFactory> factory;
  scoped_refptr<UpgradeNeededCallbacks> upgrade_callbacks;
  scoped_refptr<MockIndexedDBDatabaseCallbacks> db_callbacks;
  scoped_refptr<MockIndexedDBDatabaseCallbacks> db_callbacks2;
  scoped_refptr<ErrorCallbacks> failed_open_callbacks;

  {
    base::RunLoop loop;
    context()->TaskRunner()->PostTask(
        FROM_HERE, base::BindLambdaForTesting([&]() {
          factory = base::MakeRefCounted<MockIDBFactory>(context());
          upgrade_callbacks = base::MakeRefCounted<UpgradeNeededCallbacks>();
          db_callbacks = base::MakeRefCounted<MockIndexedDBDatabaseCallbacks>();
          failed_open_callbacks = base::MakeRefCounted<ErrorCallbacks>();
          db_callbacks2 =
              base::MakeRefCounted<MockIndexedDBDatabaseCallbacks>();
          // Open at version 2.
          const int64_t db_version = 2;
          factory->Open(db_name,
                        std::make_unique<IndexedDBPendingConnection>(
                            upgrade_callbacks, db_callbacks,
                            /*child_process_id=*/0, transaction_id, db_version),
                        origin, context()->data_path());
          EXPECT_TRUE(factory->IsDatabaseOpen(origin, db_name));
          loop.Quit();
        }));
    loop.Run();
  }

  {
    base::RunLoop loop;
    context()->TaskRunner()->PostTask(
        FROM_HERE, base::BindLambdaForTesting([&]() {
          // Close the connection.
          {
            EXPECT_TRUE(upgrade_callbacks->connection());
            upgrade_callbacks->connection()->database()->Commit(
                upgrade_callbacks->connection()->GetTransaction(
                    transaction_id));
            upgrade_callbacks->connection()->Close();
            EXPECT_FALSE(factory->IsDatabaseOpen(origin, db_name));
          }

          // Open at version < 2, which will fail; ensure factory doesn't
          // retain the database object.
          {
            const int64_t db_version = 1;
            auto connection = std::make_unique<IndexedDBPendingConnection>(
                failed_open_callbacks, db_callbacks2,
                /*child_process_id=*/0, transaction_id, db_version);
            factory->Open(db_name, std::move(connection), origin,
                          context()->data_path());
            EXPECT_TRUE(failed_open_callbacks->saw_error());
            EXPECT_FALSE(factory->IsDatabaseOpen(origin, db_name));
          }

          // Terminate all pending-close timers.
          factory->ForceClose(origin, /*delete_in_memory_store=*/false);
          loop.Quit();

          // These need to be deleted on the IDB task runner.
          upgrade_callbacks.reset();
          db_callbacks.reset();
          db_callbacks2.reset();
          failed_open_callbacks.reset();
        }));
    loop.Run();
  }
}

namespace {

class DataLossCallbacks final : public MockIndexedDBCallbacks {
 public:
  blink::mojom::IDBDataLoss 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 IndexedDBDatabaseMetadata& metadata,
                       const IndexedDBDataLossInfo& data_loss) final {
    connection_ = std::move(connection);
    data_loss_ = data_loss.status;
  }

 private:
  ~DataLossCallbacks() final {}
  blink::mojom::IDBDataLoss data_loss_ = blink::mojom::IDBDataLoss::None;
};

TEST_F(IndexedDBFactoryTest, DataFormatVersion) {
  auto try_open = [this](const Origin& origin,
                         const IndexedDBDataFormatVersion& version) {
    base::AutoReset<IndexedDBDataFormatVersion> override_version(
        &IndexedDBDataFormatVersion::GetMutableCurrentForTesting(), version);

    // These objects are retained across posted tasks, so despite being used
    // exclusively on the IDB sequence.

    // Created and used on IDB sequence.
    scoped_refptr<MockIDBFactory> factory;
    scoped_refptr<DataLossCallbacks> callbacks;

    const int64_t transaction_id = 1;
    blink::mojom::IDBDataLoss result;

    {
      base::RunLoop loop;
      context()->TaskRunner()->PostTask(
          FROM_HERE, base::BindLambdaForTesting([&]() {
            factory = base::MakeRefCounted<MockIDBFactory>(context());
            callbacks = base::MakeRefCounted<DataLossCallbacks>();
            auto db_callbacks =
                base::MakeRefCounted<MockIndexedDBDatabaseCallbacks>();
            factory->Open(ASCIIToUTF16("test_db"),
                          std::make_unique<IndexedDBPendingConnection>(
                              callbacks, db_callbacks, /*child_process_id=*/0,
                              transaction_id, /*version=*/1),
                          origin, context()->data_path());
            loop.Quit();
          }));
      loop.Run();
    }
    {
      base::RunLoop loop;
      context()->TaskRunner()->PostTask(
          FROM_HERE, base::BindLambdaForTesting([&]() {
            auto* connection = callbacks->connection();
            EXPECT_TRUE(connection);
            connection->database()->Commit(
                connection->GetTransaction(transaction_id));
            connection->Close();
            factory->ForceClose(origin, /*delete_in_memory_store=*/false);
            result = callbacks->data_loss();
            loop.Quit();
            callbacks.reset();
          }));
      loop.Run();
    }
    {
      base::RunLoop loop;
      context()->TaskRunner()->PostTask(FROM_HERE,
                                        base::BindLambdaForTesting([&]() {
                                          callbacks.reset();
                                          factory.reset();
                                          loop.Quit();
                                        }));
      loop.Run();
    }
    return result;
  };

  static const struct {
    const char* origin;
    IndexedDBDataFormatVersion open_version_1;
    IndexedDBDataFormatVersion open_version_2;
    blink::mojom::IDBDataLoss expected_data_loss;
  } kTestCases[] = {
      {"http://same-version.com/",
       {3, 4},
       {3, 4},
       blink::mojom::IDBDataLoss::None},
      {"http://blink-upgrade.com/",
       {3, 4},
       {3, 5},
       blink::mojom::IDBDataLoss::None},
      {"http://v8-upgrade.com/",
       {3, 4},
       {4, 4},
       blink::mojom::IDBDataLoss::None},
      {"http://both-upgrade.com/",
       {3, 4},
       {4, 5},
       blink::mojom::IDBDataLoss::None},
      {"http://blink-downgrade.com/",
       {3, 4},
       {3, 3},
       blink::mojom::IDBDataLoss::Total},
      {"http://v8-downgrade.com/",
       {3, 4},
       {2, 4},
       blink::mojom::IDBDataLoss::Total},
      {"http://both-downgrade.com/",
       {3, 4},
       {2, 3},
       blink::mojom::IDBDataLoss::Total},
      {"http://v8-up-blink-down.com/",
       {3, 4},
       {4, 2},
       blink::mojom::IDBDataLoss::Total},
      {"http://v8-down-blink-up.com/",
       {3, 4},
       {2, 5},
       blink::mojom::IDBDataLoss::Total},
  };
  for (const auto& test : kTestCases) {
    SCOPED_TRACE(test.origin);
    const Origin origin = Origin::Create(GURL(test.origin));
    ASSERT_EQ(blink::mojom::IDBDataLoss::None,
              try_open(origin, test.open_version_1));
    EXPECT_EQ(test.expected_data_loss, try_open(origin, test.open_version_2));
  }
}

}  // namespace

}  // namespace content
