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

#include "content/browser/indexed_db/instance/transaction.h"

#include <stdint.h>

#include <memory>

#include "base/files/scoped_temp_dir.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/scoped_refptr.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/single_thread_task_runner.h"
#include "base/task/updateable_sequenced_task_runner.h"
#include "base/test/run_until.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "base/test/test_future.h"
#include "components/services/storage/indexed_db/locks/partitioned_lock_manager.h"
#include "content/browser/indexed_db/indexed_db_database_error.h"
#include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
#include "content/browser/indexed_db/instance/bucket_context.h"
#include "content/browser/indexed_db/instance/connection.h"
#include "content/browser/indexed_db/instance/database_callbacks.h"
#include "content/browser/indexed_db/instance/fake_transaction.h"
#include "content/public/common/content_features.h"
#include "storage/browser/quota/quota_manager_proxy.h"
#include "storage/browser/test/mock_quota_manager.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h"

namespace content::indexed_db {
namespace {

void SetToTrue(bool* value) {
  *value = true;
}

}  // namespace

class AbortObserver {
 public:
  AbortObserver() = default;

  AbortObserver(const AbortObserver&) = delete;
  AbortObserver& operator=(const AbortObserver&) = delete;

  void AbortTask() { abort_task_called_ = true; }

  bool abort_task_called() const { return abort_task_called_; }

 private:
  bool abort_task_called_ = false;
};

class TransactionTest : public testing::Test {
 public:
  TransactionTest()
      : task_environment_(std::make_unique<base::test::TaskEnvironment>()) {}

  TransactionTest(const TransactionTest&) = delete;
  TransactionTest& operator=(const TransactionTest&) = delete;

  void SetUp() override {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    quota_manager_ = base::MakeRefCounted<storage::MockQuotaManager>(
        /*is_incognito=*/false, temp_dir_.GetPath(),
        base::SingleThreadTaskRunner::GetCurrentDefault(),
        /*special_storage_policy=*/nullptr);

    BucketContext::Delegate delegate;
    delegate.on_ready_for_destruction = base::BindOnce(
        &TransactionTest::OnDbReadyForDestruction, base::Unretained(this));

    const blink::StorageKey storage_key =
        blink::StorageKey::CreateFromStringForTesting("http://localhost:81");
    bucket_context_ = std::make_unique<BucketContext>(
        GetOrCreateBucket(
            storage::BucketInitParams::ForDefaultBucket(storage_key)),
        temp_dir_.GetPath(), std::move(delegate),
        scoped_refptr<base::UpdateableSequencedTaskRunner>(),
        quota_manager_->proxy(),
        /*blob_storage_context=*/mojo::NullRemote(),
        /*file_system_access_context=*/mojo::NullRemote());

    bucket_context_->InitBackingStoreIfNeeded(true);
    SetDatabaseUnderTest(u"db");
  }

  void TearDown() override { db_ = nullptr; }

  void SetDatabaseUnderTest(std::u16string name) {
    db_ = bucket_context_->CreateAndAddDatabase(name);
  }

  storage::BucketInfo GetOrCreateBucket(
      const storage::BucketInitParams& params) {
    base::test::TestFuture<storage::QuotaErrorOr<storage::BucketInfo>> future;
    quota_manager_->proxy()->UpdateOrCreateBucket(
        params, base::SingleThreadTaskRunner::GetCurrentDefault(),
        future.GetCallback());
    return future.Take().value();
  }

  void OnDbReadyForDestruction() { bucket_context_.reset(); }

  void RunPostedTasks() { base::RunLoop().RunUntilIdle(); }

  Status DummyOperation(Status result, Transaction* transaction) {
    return result;
  }

  std::unique_ptr<Connection> CreateConnection(int priority = 0) {
    mojo::Remote<storage::mojom::IndexedDBClientStateChecker> remote;
    auto connection = std::make_unique<Connection>(
        *bucket_context_, db_->AsWeakPtr(), base::DoNothing(),
        base::DoNothing(),
        std::make_unique<DatabaseCallbacks>(mojo::NullAssociatedRemote()),
        std::move(remote), base::UnguessableToken::Create(), priority);
    db_->AddConnectionForTesting(connection.get());
    return connection;
  }

  Transaction* CreateTransaction(Connection* connection,
                                 const int64_t id,
                                 const std::vector<int64_t>& object_store_ids,
                                 blink::mojom::IDBTransactionMode mode) {
    connection->CreateTransaction(
        mojo::NullAssociatedReceiver(), id, object_store_ids, mode,
        blink::mojom::IDBTransactionDurability::Relaxed);

    Transaction* transaction = connection->GetTransaction(id);

    // `CreateTransaction()` must not fail in this unit test environment.
    CHECK_NE(transaction, nullptr);
    return transaction;
  }

  // Creates a new transaction and adds it to `connection` using
  // Connection private members.  This enables the use of a fake
  // backing transaction to simulate errors.  Prefer CreateConnection() above
  // for tests that do not need to simulate errors because it uses
  // publicly exposed functionality.
  Transaction* CreateFakeTransactionWithCommitPhaseTwoError(
      Connection* connection,
      const int64_t id,
      const std::set<int64_t>& object_store_ids,
      blink::mojom::IDBTransactionMode mode,
      Status commit_phase_two_error_status) {
    // Use fake transactions to simulate errors only.
    CHECK(!commit_phase_two_error_status.ok());

    std::unique_ptr<Transaction> transaction = std::make_unique<Transaction>(
        id, connection, object_store_ids, mode,
        blink::mojom::IDBTransactionDurability::Relaxed,
        BucketContextHandle(*bucket_context_),
        std::make_unique<FakeTransaction>(
            commit_phase_two_error_status,
            db_->backing_store_db()->CreateTransaction(
                blink::mojom::IDBTransactionDurability::Relaxed, mode)));

    Transaction* transaction_reference = transaction.get();
    connection->transactions_[id] = std::move(transaction);

    db_->RegisterAndScheduleTransaction(transaction_reference);
    return transaction_reference;
  }

  PartitionedLockManager& lock_manager() {
    return bucket_context_->lock_manager();
  }

 protected:
  base::ScopedTempDir temp_dir_;
  std::unique_ptr<base::test::TaskEnvironment> task_environment_;
  std::unique_ptr<BucketContext> bucket_context_;
  raw_ptr<Database> db_;
  scoped_refptr<storage::MockQuotaManager> quota_manager_;
};

class TransactionTestMode
    : public TransactionTest,
      public testing::WithParamInterface<blink::mojom::IDBTransactionMode> {
 public:
  TransactionTestMode() = default;

  TransactionTestMode(const TransactionTestMode&) = delete;
  TransactionTestMode& operator=(const TransactionTestMode&) = delete;
};

TEST_F(TransactionTest, Timeout) {
  const std::vector<int64_t> object_store_ids{1};
  std::unique_ptr<Connection> connection = CreateConnection();
  Transaction* transaction =
      CreateTransaction(connection.get(), /*id=*/0, object_store_ids,
                        blink::mojom::IDBTransactionMode::ReadWrite);

  // No conflicting transactions, so coordinator will start it immediately:
  EXPECT_EQ(Transaction::STARTED, transaction->state());
  EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
  EXPECT_EQ(0, transaction->diagnostics().tasks_scheduled);
  EXPECT_EQ(0, transaction->diagnostics().tasks_completed);

  // Schedule a task - timer won't be started until it's processed.
  transaction->ScheduleTask(base::BindOnce(
      &TransactionTest::DummyOperation, base::Unretained(this), Status::OK()));
  EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
  EXPECT_EQ(1, transaction->diagnostics().tasks_scheduled);
  EXPECT_EQ(0, transaction->diagnostics().tasks_completed);

  RunPostedTasks();
  EXPECT_TRUE(transaction->IsTimeoutTimerRunning());

  // Since the transaction isn't blocking another transaction, it's expected to
  // do nothing when the timeout fires.
  transaction->TimeoutFired();
  EXPECT_EQ(0, transaction->timeout_strikes_);
  EXPECT_EQ(Transaction::STARTED, transaction->state());

  // Create a second transaction that's blocked on the first.
  std::unique_ptr<Connection> connection2 = CreateConnection();
  CreateTransaction(connection2.get(),
                    /*id=*/1, object_store_ids,
                    blink::mojom::IDBTransactionMode::ReadWrite);

  // Now firing the timeout starts racking up strikes.
  for (int i = 1; i < Transaction::kMaxTimeoutStrikes; ++i) {
    transaction->TimeoutFired();
    EXPECT_EQ(Transaction::STARTED, transaction->state());
    EXPECT_EQ(i, transaction->timeout_strikes_);
  }

  // ... and eventually causes the transaction to abort.
  transaction->TimeoutFired();
  EXPECT_EQ(Transaction::FINISHED, transaction->state());
  EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
  EXPECT_EQ(1, transaction->diagnostics().tasks_scheduled);
  EXPECT_EQ(1, transaction->diagnostics().tasks_completed);

  // This task will be ignored.
  transaction->ScheduleTask(base::BindOnce(
      &TransactionTest::DummyOperation, base::Unretained(this), Status::OK()));
  EXPECT_EQ(Transaction::FINISHED, transaction->state());
  EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
  EXPECT_EQ(1, transaction->diagnostics().tasks_scheduled);
  EXPECT_EQ(1, transaction->diagnostics().tasks_completed);
}

TEST_F(TransactionTest, TimeoutPreemptive) {
  std::unique_ptr<Connection> connection = CreateConnection();
  Transaction* transaction =
      CreateTransaction(connection.get(), /*id=*/0, /*object_store_ids=*/{},
                        blink::mojom::IDBTransactionMode::ReadWrite);

  // No conflicting transactions, so coordinator will start it immediately:
  EXPECT_EQ(Transaction::STARTED, transaction->state());
  EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
  EXPECT_EQ(0, transaction->diagnostics().tasks_scheduled);
  EXPECT_EQ(0, transaction->diagnostics().tasks_completed);

  // Add a preemptive task.
  transaction->ScheduleTask(
      blink::mojom::IDBTaskType::Preemptive,
      base::BindOnce(&TransactionTest::DummyOperation, base::Unretained(this),
                     Status::OK()));
  transaction->AddPreemptiveEvent();

  EXPECT_TRUE(transaction->HasPendingTasks());
  EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
  EXPECT_TRUE(transaction->task_queue_.empty());
  EXPECT_FALSE(transaction->preemptive_task_queue_.empty());

  // Pump the message loop so that the transaction completes all pending tasks,
  // otherwise it will defer the commit.
  RunPostedTasks();
  EXPECT_TRUE(transaction->HasPendingTasks());
  EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
  EXPECT_TRUE(transaction->task_queue_.empty());
  EXPECT_TRUE(transaction->preemptive_task_queue_.empty());

  // Schedule a task - timer won't be started until preemptive tasks are done.
  transaction->ScheduleTask(base::BindOnce(
      &TransactionTest::DummyOperation, base::Unretained(this), Status::OK()));
  EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
  EXPECT_EQ(1, transaction->diagnostics().tasks_scheduled);
  EXPECT_EQ(0, transaction->diagnostics().tasks_completed);

  // This shouldn't do anything - the preemptive task is still lurking.
  RunPostedTasks();
  EXPECT_TRUE(transaction->HasPendingTasks());
  EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
  EXPECT_EQ(1, transaction->diagnostics().tasks_scheduled);
  EXPECT_EQ(0, transaction->diagnostics().tasks_completed);

  // Finish the preemptive task, which unblocks regular tasks.
  transaction->DidCompletePreemptiveEvent();
  // TODO(dmurph): Should this explicit call be necessary?
  EXPECT_TRUE(transaction->RunTasks().has_value());

  // The task's completion should start the timer.
  EXPECT_FALSE(transaction->HasPendingTasks());
  EXPECT_TRUE(transaction->IsTimeoutTimerRunning());
  EXPECT_EQ(1, transaction->diagnostics().tasks_scheduled);
  EXPECT_EQ(1, transaction->diagnostics().tasks_completed);
}

TEST_F(TransactionTest, TimeoutWithPriorities) {
  struct {
    int pri_1;         // The priority of a running transaction.
    int pri_2;         // The priority of a transaction blocked on the running
                       // transaction.
    bool can_timeout;  // Whether the running transaction is a candidate for
                       // timeout.
  } const test_cases[] = {
      {0, 0, true}, {0, 1, true}, {1, 1, false}, {1, 0, true}, {2, 1, true}};

  const std::vector<int64_t> object_store_ids{1};
  int txn_id = 0;

  int i = 0;
  for (auto test_case : test_cases) {
    SetDatabaseUnderTest(base::ASCIIToUTF16(base::StringPrintf("db_%d", i++)));

    std::unique_ptr<Connection> connection = CreateConnection(test_case.pri_1);
    Transaction* transaction =
        CreateTransaction(connection.get(), txn_id++, object_store_ids,
                          blink::mojom::IDBTransactionMode::ReadWrite);

    EXPECT_EQ(Transaction::STARTED, transaction->state());
    EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
    // Schedule a task - timer won't be started until it's processed.
    transaction->ScheduleTask(base::BindOnce(&TransactionTest::DummyOperation,
                                             base::Unretained(this),
                                             Status::OK()));
    EXPECT_TRUE(base::test::RunUntil(
        [&]() { return transaction->IsTimeoutTimerRunning(); }));

    // Since the transaction isn't blocking another transaction, it's expected
    // to do nothing when the timeout fires.
    transaction->TimeoutFired();
    EXPECT_EQ(0, transaction->timeout_strikes_);
    EXPECT_EQ(Transaction::STARTED, transaction->state());

    // Create a second transaction that's blocked on the first.
    std::unique_ptr<Connection> connection2 = CreateConnection(test_case.pri_2);
    CreateTransaction(connection2.get(),
                      /*id=*/txn_id++, object_store_ids,
                      blink::mojom::IDBTransactionMode::ReadWrite);

    // Now firing the timeout starts racking up strikes.
    transaction->TimeoutFired();
    EXPECT_EQ(test_case.can_timeout ? 1 : 0, transaction->timeout_strikes_);

    // Clean up for the next iteration.
    db_->ForceCloseAndRunTasks("The database is force-closed for testing.");
  }
}

TEST_F(TransactionTest, WithoutPrioritization) {
  base::test::ScopedFeatureList scoped_feature_list;
  scoped_feature_list.InitAndDisableFeature(
      features::kIdbPrioritizeForegroundClients);

  const std::vector<int64_t> object_store_ids{1};
  std::unique_ptr<Connection> low_pri_connection = CreateConnection(1);
  std::unique_ptr<Connection> high_pri_connection = CreateConnection(0);

  // Create transaction that is incidentally low priority.
  // No conflicting transactions, so coordinator will start it immediately:
  Transaction* low_pri_transaction =
      CreateTransaction(low_pri_connection.get(), /*id=*/0, object_store_ids,
                        blink::mojom::IDBTransactionMode::ReadWrite);
  EXPECT_EQ(Transaction::STARTED, low_pri_transaction->state());

  // Create second transaction, which is blocked.
  Transaction* low_pri_transaction2 =
      CreateTransaction(low_pri_connection.get(), /*id=*/1, object_store_ids,
                        blink::mojom::IDBTransactionMode::ReadWrite);
  EXPECT_EQ(Transaction::CREATED, low_pri_transaction2->state());

  // Create a high priority transaction, which also queues up.
  Transaction* high_pri_transaction =
      CreateTransaction(high_pri_connection.get(), /*id=*/2, object_store_ids,
                        blink::mojom::IDBTransactionMode::ReadWrite);
  EXPECT_EQ(Transaction::CREATED, high_pri_transaction->state());

  // Finish the first low priority transaction. Verify the order of queueing of
  // other transactions.
  low_pri_transaction->Abort(DatabaseError(
      blink::mojom::IDBException::kAbortError, "Transaction aborted by user."));
  EXPECT_EQ(Transaction::FINISHED, low_pri_transaction->state());

  ASSERT_TRUE(base::test::RunUntil(
      [&]() { return Transaction::STARTED == low_pri_transaction2->state(); }));
  EXPECT_EQ(Transaction::CREATED, high_pri_transaction->state());
}

TEST_F(TransactionTest, WithPrioritization) {
  base::test::ScopedFeatureList scoped_feature_list{
      features::kIdbPrioritizeForegroundClients};

  const std::vector<int64_t> object_store_ids{1};
  std::unique_ptr<Connection> low_pri_connection = CreateConnection(1);
  std::unique_ptr<Connection> high_pri_connection = CreateConnection(0);

  // Create transaction that is incidentally low priority.
  // No conflicting transactions, so coordinator will start it immediately:
  Transaction* low_pri_transaction =
      CreateTransaction(low_pri_connection.get(), /*id=*/0, object_store_ids,
                        blink::mojom::IDBTransactionMode::ReadWrite);
  EXPECT_EQ(Transaction::STARTED, low_pri_transaction->state());

  // Create second transaction, which is blocked.
  Transaction* low_pri_transaction2 =
      CreateTransaction(low_pri_connection.get(), /*id=*/1, object_store_ids,
                        blink::mojom::IDBTransactionMode::ReadWrite);
  EXPECT_EQ(Transaction::CREATED, low_pri_transaction2->state());

  // Create a couple high priority transactions, which skip ahead in the queue.
  Transaction* high_pri_transaction =
      CreateTransaction(high_pri_connection.get(), /*id=*/2, object_store_ids,
                        blink::mojom::IDBTransactionMode::ReadWrite);
  EXPECT_EQ(Transaction::CREATED, high_pri_transaction->state());
  Transaction* high_pri_transaction2 =
      CreateTransaction(high_pri_connection.get(), /*id=*/3, object_store_ids,
                        blink::mojom::IDBTransactionMode::ReadWrite);
  EXPECT_EQ(Transaction::CREATED, high_pri_transaction2->state());

  // Finish the first low priority transaction. Verify the order of queueing of
  // other transactions.
  low_pri_transaction->Abort(DatabaseError(
      blink::mojom::IDBException::kAbortError, "Transaction aborted by user."));
  EXPECT_EQ(Transaction::FINISHED, low_pri_transaction->state());

  ASSERT_TRUE(base::test::RunUntil(
      [&]() { return Transaction::STARTED == high_pri_transaction->state(); }));
  EXPECT_EQ(Transaction::CREATED, high_pri_transaction2->state());
  EXPECT_EQ(Transaction::CREATED, low_pri_transaction2->state());

  high_pri_transaction->Abort(DatabaseError(
      blink::mojom::IDBException::kAbortError, "Transaction aborted by user."));
  EXPECT_EQ(Transaction::FINISHED, high_pri_transaction->state());

  ASSERT_TRUE(base::test::RunUntil([&]() {
    return Transaction::STARTED == high_pri_transaction2->state();
  }));
  EXPECT_EQ(Transaction::CREATED, low_pri_transaction2->state());

  high_pri_transaction2->Abort(DatabaseError(
      blink::mojom::IDBException::kAbortError, "Transaction aborted by user."));
  EXPECT_EQ(Transaction::FINISHED, high_pri_transaction2->state());

  ASSERT_TRUE(base::test::RunUntil(
      [&]() { return Transaction::STARTED == low_pri_transaction2->state(); }));
}

TEST_P(TransactionTestMode, ScheduleNormalTask) {
  std::unique_ptr<Connection> connection = CreateConnection();
  Transaction* transaction =
      CreateTransaction(connection.get(), /*id=*/0, /*object_store_ids=*/{},
                        /*mode=*/GetParam());

  EXPECT_FALSE(transaction->HasPendingTasks());
  EXPECT_TRUE(transaction->IsTaskQueueEmpty());
  EXPECT_TRUE(transaction->task_queue_.empty());
  EXPECT_TRUE(transaction->preemptive_task_queue_.empty());
  EXPECT_EQ(0, transaction->diagnostics().tasks_scheduled);
  EXPECT_EQ(0, transaction->diagnostics().tasks_completed);

  transaction->ScheduleTask(
      blink::mojom::IDBTaskType::Normal,
      base::BindOnce(&TransactionTest::DummyOperation, base::Unretained(this),
                     Status::OK()));

  EXPECT_EQ(1, transaction->diagnostics().tasks_scheduled);
  EXPECT_EQ(0, transaction->diagnostics().tasks_completed);

  EXPECT_TRUE(transaction->HasPendingTasks());
  EXPECT_FALSE(transaction->IsTaskQueueEmpty());
  EXPECT_FALSE(transaction->task_queue_.empty());
  EXPECT_TRUE(transaction->preemptive_task_queue_.empty());

  // Pump the message loop so that the transaction completes all pending tasks,
  // otherwise it will defer the commit.
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(transaction->HasPendingTasks());
  EXPECT_TRUE(transaction->IsTaskQueueEmpty());
  EXPECT_TRUE(transaction->task_queue_.empty());
  EXPECT_TRUE(transaction->preemptive_task_queue_.empty());
  EXPECT_EQ(Transaction::STARTED, transaction->state());
  EXPECT_EQ(1, transaction->diagnostics().tasks_scheduled);
  EXPECT_EQ(1, transaction->diagnostics().tasks_completed);

  transaction->SetCommitFlag();
  RunPostedTasks();
  EXPECT_EQ(0UL, connection->transactions().size());
}

TEST_P(TransactionTestMode, TaskFails) {
  std::unique_ptr<Connection> connection = CreateConnection();
  Transaction* transaction =
      CreateTransaction(connection.get(), /*id=*/0, /*object_store_ids=*/{},
                        /*mode=*/GetParam());

  EXPECT_FALSE(transaction->HasPendingTasks());
  EXPECT_TRUE(transaction->IsTaskQueueEmpty());
  EXPECT_TRUE(transaction->task_queue_.empty());
  EXPECT_TRUE(transaction->preemptive_task_queue_.empty());
  EXPECT_EQ(0, transaction->diagnostics().tasks_scheduled);
  EXPECT_EQ(0, transaction->diagnostics().tasks_completed);
  db_ = nullptr;

  transaction->ScheduleTask(
      blink::mojom::IDBTaskType::Normal,
      base::BindOnce(&TransactionTest::DummyOperation, base::Unretained(this),
                     Status::IOError("error")));

  EXPECT_EQ(1, transaction->diagnostics().tasks_scheduled);
  EXPECT_EQ(0, transaction->diagnostics().tasks_completed);

  EXPECT_TRUE(transaction->HasPendingTasks());
  EXPECT_FALSE(transaction->IsTaskQueueEmpty());
  EXPECT_FALSE(transaction->task_queue_.empty());
  EXPECT_TRUE(transaction->preemptive_task_queue_.empty());

  // Pump the message loop so that the transaction completes all pending tasks,
  // otherwise it will defer the commit.
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(transaction->HasPendingTasks());
  EXPECT_TRUE(transaction->IsTaskQueueEmpty());
  EXPECT_TRUE(transaction->task_queue_.empty());
  EXPECT_TRUE(transaction->preemptive_task_queue_.empty());
  /// Transaction aborted due to the error.
  EXPECT_EQ(Transaction::FINISHED, transaction->state());
  transaction->SetCommitFlag();
  EXPECT_EQ(1, transaction->diagnostics().tasks_scheduled);
  EXPECT_EQ(1, transaction->diagnostics().tasks_completed);

  // An error was reported which deletes the bucket context.
  EXPECT_FALSE(bucket_context_);
}

TEST_F(TransactionTest, SchedulePreemptiveTask) {
  std::unique_ptr<Connection> connection = CreateConnection();
  Transaction* transaction = CreateFakeTransactionWithCommitPhaseTwoError(
      connection.get(), /*id=*/0, /*object_store_ids=*/{},
      blink::mojom::IDBTransactionMode::ReadWrite, Status::Corruption("Ouch."));
  db_ = nullptr;

  EXPECT_FALSE(transaction->HasPendingTasks());
  EXPECT_TRUE(transaction->IsTaskQueueEmpty());
  EXPECT_TRUE(transaction->task_queue_.empty());
  EXPECT_TRUE(transaction->preemptive_task_queue_.empty());
  EXPECT_EQ(0, transaction->diagnostics().tasks_scheduled);
  EXPECT_EQ(0, transaction->diagnostics().tasks_completed);

  transaction->ScheduleTask(
      blink::mojom::IDBTaskType::Preemptive,
      base::BindOnce(&TransactionTest::DummyOperation, base::Unretained(this),
                     Status::OK()));
  transaction->AddPreemptiveEvent();

  EXPECT_TRUE(transaction->HasPendingTasks());
  EXPECT_FALSE(transaction->IsTaskQueueEmpty());
  EXPECT_TRUE(transaction->task_queue_.empty());
  EXPECT_FALSE(transaction->preemptive_task_queue_.empty());

  // Pump the message loop so that the transaction completes all pending tasks,
  // otherwise it will defer the commit.
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(transaction->HasPendingTasks());
  EXPECT_TRUE(transaction->IsTaskQueueEmpty());
  EXPECT_TRUE(transaction->task_queue_.empty());
  EXPECT_TRUE(transaction->preemptive_task_queue_.empty());
  EXPECT_EQ(Transaction::STARTED, transaction->state());
  EXPECT_EQ(0, transaction->diagnostics().tasks_scheduled);
  EXPECT_EQ(0, transaction->diagnostics().tasks_completed);

  transaction->DidCompletePreemptiveEvent();
  transaction->SetCommitFlag();
  RunPostedTasks();
  // The bucket context should have been destroyed via
  // `OnDbReadyForDestruction`.
  EXPECT_FALSE(bucket_context_);
}

TEST_P(TransactionTestMode, AbortPreemptive) {
  std::unique_ptr<Connection> connection = CreateConnection();
  Transaction* transaction =
      CreateTransaction(connection.get(), /*id=*/0, /*object_store_ids=*/{},
                        /*mode=*/GetParam());

  // No conflicting transactions, so coordinator will start it immediately:
  EXPECT_EQ(Transaction::STARTED, transaction->state());
  EXPECT_FALSE(transaction->IsTimeoutTimerRunning());

  transaction->ScheduleTask(
      blink::mojom::IDBTaskType::Preemptive,
      base::BindOnce(&TransactionTest::DummyOperation, base::Unretained(this),
                     Status::OK()));
  EXPECT_EQ(0, transaction->pending_preemptive_events_);
  transaction->AddPreemptiveEvent();
  EXPECT_EQ(1, transaction->pending_preemptive_events_);

  RunPostedTasks();

  transaction->Abort(DatabaseError(blink::mojom::IDBException::kAbortError,
                                   "Transaction aborted by user."));
  EXPECT_EQ(Transaction::FINISHED, transaction->state());
  EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
  EXPECT_EQ(0, transaction->pending_preemptive_events_);
  EXPECT_TRUE(transaction->preemptive_task_queue_.empty());
  EXPECT_TRUE(transaction->task_queue_.empty());
  EXPECT_FALSE(transaction->HasPendingTasks());
  EXPECT_EQ(transaction->diagnostics().tasks_completed,
            transaction->diagnostics().tasks_scheduled);
  EXPECT_TRUE(transaction->backing_store_transaction_begun_);
  EXPECT_TRUE(transaction->used_);
  EXPECT_FALSE(transaction->is_commit_pending_);

  // This task will be ignored.
  transaction->ScheduleTask(base::BindOnce(
      &TransactionTest::DummyOperation, base::Unretained(this), Status::OK()));
  EXPECT_EQ(Transaction::FINISHED, transaction->state());
  EXPECT_FALSE(transaction->IsTimeoutTimerRunning());
  EXPECT_FALSE(transaction->HasPendingTasks());
  EXPECT_EQ(transaction->diagnostics().tasks_completed,
            transaction->diagnostics().tasks_scheduled);
}

static const blink::mojom::IDBTransactionMode kTestModes[] = {
    blink::mojom::IDBTransactionMode::ReadOnly,
    blink::mojom::IDBTransactionMode::ReadWrite};

INSTANTIATE_TEST_SUITE_P(Transactions,
                         TransactionTestMode,
                         ::testing::ValuesIn(kTestModes));

TEST_F(TransactionTest, AbortCancelsLockRequest) {
  std::unique_ptr<Connection> connection = CreateConnection();

  const int64_t object_store_id = 1ll;

  // Acquire a lock to block the transaction's lock acquisition.
  std::vector<PartitionedLockManager::PartitionedLockRequest> lock_requests =
      connection->database()->BuildLockRequestsForTransaction(
          blink::mojom::IDBTransactionMode::ReadWrite, {object_store_id});
  bool locks_received = false;
  PartitionedLockHolder temp_lock_receiver;
  lock_manager().AcquireLocks(lock_requests, temp_lock_receiver,
                              base::BindOnce(SetToTrue, &locks_received));
  EXPECT_TRUE(locks_received);

  // Create and register the transaction, which should request locks and wait
  // for `temp_lock_receiver` to release the locks.
  Transaction* transaction = CreateTransaction(
      connection.get(), /*transaction_id=*/0, {object_store_id},
      blink::mojom::IDBTransactionMode::ReadWrite);
  EXPECT_EQ(transaction->state(), Transaction::CREATED);

  // Abort the transaction, which should cancel the
  // RegisterAndScheduleTransaction() pending lock request.
  transaction->Abort(DatabaseError(blink::mojom::IDBException::kUnknownError));
  EXPECT_EQ(transaction->state(), Transaction::FINISHED);

  // Clear `temp_lock_receiver` so we can test later that all locks have
  // cleared.
  temp_lock_receiver.locks.clear();

  // Verify that the locks are available for acquisition again, as the
  // transaction should have cancelled its lock request.
  locks_received = false;
  lock_manager().AcquireLocks(lock_requests, temp_lock_receiver,
                              base::BindOnce(SetToTrue, &locks_received));
  EXPECT_TRUE(locks_received);
}

TEST_F(TransactionTest, PostedStartTaskRunAfterAbort) {
  std::unique_ptr<Connection> connection = CreateConnection();

  int64_t id = 0;
  const std::vector<int64_t> object_store_ids = {1ll};
  Transaction* transaction1 =
      CreateTransaction(connection.get(), id, object_store_ids,
                        blink::mojom::IDBTransactionMode::ReadWrite);
  EXPECT_EQ(transaction1->state(), Transaction::STARTED);

  // Register another transaction, which will block on the first transaction.
  Transaction* transaction2 =
      CreateTransaction(connection.get(), ++id, object_store_ids,
                        blink::mojom::IDBTransactionMode::ReadWrite);
  EXPECT_EQ(transaction2->state(), Transaction::CREATED);

  // Flush posted tasks before making the Abort calls since there are
  // posted RunTasksForDatabase() tasks which, if we waited to run them
  // until after Abort is called, would destroy our transactions and mask
  // a potential race condition.
  RunPostedTasks();

  // Abort all of the transactions, which should cause the second transaction's
  // posted Start() task to run.
  connection->AbortAllTransactions(
      DatabaseError(blink::mojom::IDBException::kUnknownError));

  EXPECT_EQ(transaction2->state(), Transaction::FINISHED);

  // Run tasks to ensure Start() is called but does not DCHECK.
  RunPostedTasks();

  // It's not safe to check the state of the transaction at this point since it
  // is freed when the Database::RunTasks call happens via the posted
  // RunTasksForDatabase task.
}

TEST_F(TransactionTest, IsTransactionBlockingOtherClients) {
  std::unique_ptr<Connection> connection = CreateConnection();

  const std::vector<int64_t> object_store_ids = {1ll};
  Transaction* transaction = CreateTransaction(
      connection.get(),
      /*id=*/0, object_store_ids, blink::mojom::IDBTransactionMode::ReadWrite);

  // Register a transaction with ReadWrite mode to object store 1.
  // The transaction should be started and it's not blocking any others.
  EXPECT_EQ(transaction->state(), Transaction::STARTED);
  EXPECT_FALSE(transaction->IsTransactionBlockingOtherClients());

  Transaction* transaction2 = CreateTransaction(
      connection.get(),
      /*id=*/1, object_store_ids, blink::mojom::IDBTransactionMode::ReadWrite);

  // Register another transaction with ReadWrite mode to the same object store.
  // The transaction should be blocked in `CREATED` state, but the previous
  // transaction is *not* blocking other clients because it's the same client.
  EXPECT_EQ(transaction2->state(), Transaction::CREATED);
  EXPECT_FALSE(transaction->IsTransactionBlockingOtherClients());

  // Register a very similar connection, but with a *different* client. Now this
  // one is blocking and `IsTransactionBlockingOtherClients` should be true.
  auto connection2 = CreateConnection();
  Transaction* transaction3 = CreateTransaction(
      connection2.get(),
      /*id=*/1, object_store_ids, blink::mojom::IDBTransactionMode::ReadWrite);

  RunPostedTasks();

  // Abort the blocked transaction, and the previous transaction should not be
  // blocking others anymore.
  transaction3->Abort(DatabaseError(blink::mojom::IDBException::kUnknownError));
  EXPECT_EQ(transaction3->state(), Transaction::FINISHED);
  RunPostedTasks();
  EXPECT_FALSE(transaction->IsTransactionBlockingOtherClients());
}

}  // namespace content::indexed_db
