// Copyright 2014 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 "storage/browser/database/database_tracker.h"

#include <stddef.h>
#include <stdint.h>

#include <memory>

#include "base/callback_helpers.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/gtest_prod_util.h"
#include "base/memory/ptr_util.h"
#include "base/memory/scoped_refptr.h"
#include "base/run_loop.h"
#include "base/task/sequenced_task_runner.h"
#include "base/test/bind.h"
#include "base/test/task_environment.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/time/time.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "storage/browser/quota/quota_client_type.h"
#include "storage/browser/quota/quota_manager_proxy.h"
#include "storage/browser/test/mock_special_storage_policy.h"
#include "storage/common/database/database_identifier.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/sqlite/sqlite3.h"

namespace storage {

const char kOrigin1Url[] = "http://origin1";
const char kOrigin2Url[] = "http://protected_origin2";

class TestObserver : public DatabaseTracker::Observer {
 public:
  TestObserver()
      : new_notification_received_(false),
        observe_size_changes_(true),
        observe_scheduled_deletions_(true) {}
  TestObserver(bool observe_size_changes, bool observe_scheduled_deletions)
      : new_notification_received_(false),
        observe_size_changes_(observe_size_changes),
        observe_scheduled_deletions_(observe_scheduled_deletions) {}

  ~TestObserver() override = default;
  void OnDatabaseSizeChanged(const std::string& origin_identifier,
                             const std::u16string& database_name,
                             int64_t database_size) override {
    if (!observe_size_changes_)
      return;
    new_notification_received_ = true;
    origin_identifier_ = origin_identifier;
    database_name_ = database_name;
    database_size_ = database_size;
  }
  void OnDatabaseScheduledForDeletion(
      const std::string& origin_identifier,
      const std::u16string& database_name) override {
    if (!observe_scheduled_deletions_)
      return;
    new_notification_received_ = true;
    origin_identifier_ = origin_identifier;
    database_name_ = database_name;
  }
  bool DidReceiveNewNotification() {
    bool temp_new_notification_received = new_notification_received_;
    new_notification_received_ = false;
    return temp_new_notification_received;
  }
  std::string GetNotificationOriginIdentifier() { return origin_identifier_; }
  std::u16string GetNotificationDatabaseName() { return database_name_; }
  int64_t GetNotificationDatabaseSize() { return database_size_; }

 private:
  bool new_notification_received_;
  bool observe_size_changes_;
  bool observe_scheduled_deletions_;
  std::string origin_identifier_;
  std::u16string database_name_;
  int64_t database_size_;
};

void CheckNotificationReceived(TestObserver* observer,
                               const std::string& expected_origin_identifier,
                               const std::u16string& expected_database_name,
                               int64_t expected_database_size) {
  EXPECT_TRUE(observer->DidReceiveNewNotification());
  EXPECT_EQ(expected_origin_identifier,
            observer->GetNotificationOriginIdentifier());
  EXPECT_EQ(expected_database_name, observer->GetNotificationDatabaseName());
  EXPECT_EQ(expected_database_size, observer->GetNotificationDatabaseSize());
}

// Must be destroyed on the sequence that called RegisterClient() most recently.
class TestQuotaManagerProxy : public QuotaManagerProxy {
 public:
  TestQuotaManagerProxy()
      : QuotaManagerProxy(
            /*quota_manager_impl=*/nullptr,
            base::SequencedTaskRunnerHandle::Get(),
            /*profile_path=*/base::FilePath()) {}

  void RegisterClient(
      mojo::PendingRemote<mojom::QuotaClient> client,
      QuotaClientType client_type,
      const std::vector<blink::mojom::StorageType>& storage_types) override {
    EXPECT_FALSE(registered_client_);
    registered_client_.Bind(std::move(client));
  }

  void NotifyStorageAccessed(const blink::StorageKey& storage_key,
                             blink::mojom::StorageType type,
                             base::Time access_time) override {
    EXPECT_EQ(blink::mojom::StorageType::kTemporary, type);
    accesses_[storage_key] += 1;
  }

  void NotifyStorageModified(
      QuotaClientType client_id,
      const blink::StorageKey& storage_key,
      blink::mojom::StorageType type,
      int64_t delta,
      base::Time modification_time,
      scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
      base::OnceClosure callback) override {
    EXPECT_EQ(QuotaClientType::kDatabase, client_id);
    EXPECT_EQ(blink::mojom::StorageType::kTemporary, type);
    modifications_[storage_key].first += 1;
    modifications_[storage_key].second += delta;
    if (callback)
      callback_task_runner->PostTask(FROM_HERE, std::move(callback));
  }

  // Not needed for our tests.
  void SetUsageCacheEnabled(QuotaClientType client_id,
                            const blink::StorageKey& storage_key,
                            blink::mojom::StorageType type,
                            bool enabled) override {}
  void GetUsageAndQuota(
      const blink::StorageKey& storage_key,
      blink::mojom::StorageType type,
      scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
      UsageAndQuotaCallback callback) override {}

  bool WasAccessNotified(const blink::StorageKey& storage_key) {
    return accesses_[storage_key] != 0;
  }

  bool WasModificationNotified(const blink::StorageKey& storage_key,
                               int64_t amount) {
    return modifications_[storage_key].first != 0 &&
           modifications_[storage_key].second == amount;
  }

  void ResetRecordedTestState() {
    accesses_.clear();
    modifications_.clear();
  }

  mojo::Remote<mojom::QuotaClient> registered_client_;

  // Map from storage key to count of access notifications.
  std::map<blink::StorageKey, int> accesses_;

  // Map from storage key to <count, sum of deltas>
  std::map<blink::StorageKey, std::pair<int, int64_t>> modifications_;

 protected:
  ~TestQuotaManagerProxy() override = default;
};

bool EnsureFileOfSize(const base::FilePath& file_path, int64_t length) {
  base::File file(file_path,
                  base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_WRITE);
  if (!file.IsValid())
    return false;
  return file.SetLength(length);
}

// We declare a helper class, and make it a friend of DatabaseTracker using
// the FORWARD_DECLARE_TEST macro, and we implement all tests we want to run as
// static methods of this class. Then we make our TEST() targets call these
// static functions. This allows us to run each test in normal mode and
// incognito mode without writing the same code twice.
class DatabaseTracker_TestHelper_Test {
 public:
  static void TestDeleteOpenDatabase(bool incognito_mode) {
    // Initialize the tracker database.
    base::test::TaskEnvironment task_environment;
    base::ScopedTempDir temp_dir;
    ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
    auto special_storage_policy =
        base::MakeRefCounted<MockSpecialStoragePolicy>();
    special_storage_policy->AddProtected(GURL(kOrigin2Url));
    scoped_refptr<DatabaseTracker> tracker = DatabaseTracker::Create(
        temp_dir.GetPath(), incognito_mode, std::move(special_storage_policy),
        /*quota_manager_proxy=*/nullptr);

    base::RunLoop run_loop;
    tracker->task_runner()->PostTask(
        FROM_HERE, base::BindLambdaForTesting([&]() {
          base::ScopedClosureRunner quit_runner(
              base::BindLambdaForTesting([&]() { run_loop.Quit(); }));

          // Create and open three databases.
          int64_t database_size = 0;
          const std::string kOrigin1 =
              GetIdentifierFromOrigin(GURL(kOrigin1Url));
          const std::string kOrigin2 =
              GetIdentifierFromOrigin(GURL(kOrigin2Url));
          const std::u16string kDB1 = u"db1";
          const std::u16string kDB2 = u"db2";
          const std::u16string kDB3 = u"db3";
          const std::u16string kDescription = u"database_description";

          tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, &database_size);
          tracker->DatabaseOpened(kOrigin2, kDB2, kDescription, &database_size);
          tracker->DatabaseOpened(kOrigin2, kDB3, kDescription, &database_size);

          EXPECT_TRUE(
              base::CreateDirectory(tracker->GetOriginDirectory(kOrigin1)));
          EXPECT_TRUE(
              base::CreateDirectory(tracker->GetOriginDirectory(kOrigin2)));
          EXPECT_TRUE(
              base::WriteFile(tracker->GetFullDBFilePath(kOrigin1, kDB1), "a"));
          EXPECT_TRUE(base::WriteFile(
              tracker->GetFullDBFilePath(kOrigin2, kDB2), "aa"));
          EXPECT_TRUE(base::WriteFile(
              tracker->GetFullDBFilePath(kOrigin2, kDB3), "aaa"));
          tracker->DatabaseModified(kOrigin1, kDB1);
          tracker->DatabaseModified(kOrigin2, kDB2);
          tracker->DatabaseModified(kOrigin2, kDB3);

          // Delete db1. Should also delete origin1.
          TestObserver observer;
          tracker->AddObserver(&observer);
          net::TestCompletionCallback delete_database_callback;
          tracker->DeleteDatabase(kOrigin1, kDB1,
                                  delete_database_callback.callback());
          EXPECT_FALSE(delete_database_callback.have_result());
          EXPECT_TRUE(observer.DidReceiveNewNotification());
          EXPECT_EQ(kOrigin1, observer.GetNotificationOriginIdentifier());
          EXPECT_EQ(kDB1, observer.GetNotificationDatabaseName());
          tracker->DatabaseClosed(kOrigin1, kDB1);
          EXPECT_EQ(net::OK, delete_database_callback.WaitForResult());
          EXPECT_FALSE(base::PathExists(tracker->GetOriginDirectory(kOrigin1)));

          // Recreate db1.
          tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, &database_size);
          EXPECT_TRUE(
              base::CreateDirectory(tracker->GetOriginDirectory(kOrigin1)));
          EXPECT_TRUE(
              base::WriteFile(tracker->GetFullDBFilePath(kOrigin1, kDB1), "a"));
          tracker->DatabaseModified(kOrigin1, kDB1);

          // Setup file modification times.  db1 and db2 are modified now, db3
          // three days ago.
          base::Time now = base::Time::Now();
          EXPECT_TRUE(base::TouchFile(
              tracker->GetFullDBFilePath(kOrigin1, kDB1), now, now));
          EXPECT_TRUE(base::TouchFile(
              tracker->GetFullDBFilePath(kOrigin2, kDB2), now, now));
          base::Time three_days_ago = now - base::Days(3);
          EXPECT_TRUE(
              base::TouchFile(tracker->GetFullDBFilePath(kOrigin2, kDB3),
                              three_days_ago, three_days_ago));

          // Delete databases modified since yesterday. db2 is in the allowlist.
          base::Time yesterday = base::Time::Now();
          yesterday -= base::Days(1);

          net::TestCompletionCallback delete_data_modified_since_callback;
          tracker->DeleteDataModifiedSince(
              yesterday, delete_data_modified_since_callback.callback());
          EXPECT_FALSE(delete_data_modified_since_callback.have_result());
          EXPECT_TRUE(observer.DidReceiveNewNotification());
          tracker->DatabaseClosed(kOrigin1, kDB1);
          tracker->DatabaseClosed(kOrigin2, kDB2);
          EXPECT_EQ(net::OK,
                    delete_data_modified_since_callback.WaitForResult());
          EXPECT_FALSE(base::PathExists(tracker->GetOriginDirectory(kOrigin1)));
          EXPECT_TRUE(
              base::PathExists(tracker->GetFullDBFilePath(kOrigin2, kDB2)));
          EXPECT_TRUE(
              base::PathExists(tracker->GetFullDBFilePath(kOrigin2, kDB3)));

          tracker->DatabaseClosed(kOrigin2, kDB3);
          tracker->RemoveObserver(&observer);

          tracker->Shutdown();
        }));
    run_loop.Run();
  }

  static void TestDatabaseTracker(bool incognito_mode) {
    // Initialize the tracker database.
    base::test::TaskEnvironment task_environment;
    base::ScopedTempDir temp_dir;
    ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
    auto special_storage_policy =
        base::MakeRefCounted<MockSpecialStoragePolicy>();
    special_storage_policy->AddProtected(GURL(kOrigin2Url));
    scoped_refptr<DatabaseTracker> tracker = DatabaseTracker::Create(
        temp_dir.GetPath(), incognito_mode, std::move(special_storage_policy),
        /*quota_manager_proxy=*/nullptr);

    base::RunLoop run_loop;
    tracker->task_runner()->PostTask(
        FROM_HERE, base::BindLambdaForTesting([&]() {
          base::ScopedClosureRunner quit_runner(
              base::BindLambdaForTesting([&]() { run_loop.Quit(); }));

          // Add two observers.
          TestObserver observer1;
          TestObserver observer2;
          tracker->AddObserver(&observer1);
          tracker->AddObserver(&observer2);

          // Open three new databases.
          int64_t database_size = 0;
          const std::string kOrigin1 =
              GetIdentifierFromOrigin(GURL(kOrigin1Url));
          const std::string kOrigin2 =
              GetIdentifierFromOrigin(GURL(kOrigin2Url));
          const std::u16string kDB1 = u"db1";
          const std::u16string kDB2 = u"db2";
          const std::u16string kDB3 = u"db3";
          const std::u16string kDescription = u"database_description";

          // Get the info for kOrigin1 and kOrigin2
          DatabaseTracker::CachedOriginInfo* origin1_info =
              tracker->GetCachedOriginInfo(kOrigin1);
          DatabaseTracker::CachedOriginInfo* origin2_info =
              tracker->GetCachedOriginInfo(kOrigin1);
          EXPECT_TRUE(origin1_info);
          EXPECT_TRUE(origin2_info);

          tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, &database_size);
          EXPECT_EQ(0, database_size);
          tracker->DatabaseOpened(kOrigin2, kDB2, kDescription, &database_size);
          EXPECT_EQ(0, database_size);
          tracker->DatabaseOpened(kOrigin1, kDB3, kDescription, &database_size);
          EXPECT_EQ(0, database_size);

          // Write some data to each file and check that the listeners are
          // called with the appropriate values.
          EXPECT_TRUE(
              base::CreateDirectory(tracker->GetOriginDirectory(kOrigin1)));
          EXPECT_TRUE(
              base::CreateDirectory(tracker->GetOriginDirectory(kOrigin2)));
          EXPECT_TRUE(
              base::WriteFile(tracker->GetFullDBFilePath(kOrigin1, kDB1), "a"));
          EXPECT_TRUE(base::WriteFile(
              tracker->GetFullDBFilePath(kOrigin2, kDB2), "aa"));
          EXPECT_TRUE(base::WriteFile(
              tracker->GetFullDBFilePath(kOrigin1, kDB3), "aaaa"));
          tracker->DatabaseModified(kOrigin1, kDB1);
          CheckNotificationReceived(&observer1, kOrigin1, kDB1, 1);
          CheckNotificationReceived(&observer2, kOrigin1, kDB1, 1);
          tracker->DatabaseModified(kOrigin2, kDB2);
          CheckNotificationReceived(&observer1, kOrigin2, kDB2, 2);
          CheckNotificationReceived(&observer2, kOrigin2, kDB2, 2);
          tracker->DatabaseModified(kOrigin1, kDB3);
          CheckNotificationReceived(&observer1, kOrigin1, kDB3, 4);
          CheckNotificationReceived(&observer2, kOrigin1, kDB3, 4);

          // Close all databases
          tracker->DatabaseClosed(kOrigin1, kDB1);
          tracker->DatabaseClosed(kOrigin2, kDB2);
          tracker->DatabaseClosed(kOrigin1, kDB3);

          // Open an existing database and check the reported size
          tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, &database_size);
          EXPECT_EQ(1, database_size);
          tracker->DatabaseClosed(kOrigin1, kDB1);

          // Remove an observer; this should clear all caches.
          tracker->RemoveObserver(&observer2);

          // Close the tracker database and clear all caches.
          // Then make sure that DatabaseOpened() still returns the correct
          // result.
          tracker->CloseTrackerDatabaseAndClearCaches();
          tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, &database_size);
          EXPECT_EQ(1, database_size);
          tracker->DatabaseClosed(kOrigin1, kDB1);

          // Remove all observers.
          tracker->RemoveObserver(&observer1);

          // Trying to delete a database in use should fail
          tracker->DatabaseOpened(kOrigin1, kDB3, kDescription, &database_size);
          EXPECT_FALSE(tracker->DeleteClosedDatabase(kOrigin1, kDB3));
          origin1_info = tracker->GetCachedOriginInfo(kOrigin1);
          EXPECT_TRUE(origin1_info);
          EXPECT_EQ(4, origin1_info->GetDatabaseSize(kDB3));
          tracker->DatabaseClosed(kOrigin1, kDB3);

          // Delete a database and make sure the space used by that origin is
          // updated
          EXPECT_TRUE(tracker->DeleteClosedDatabase(kOrigin1, kDB3));
          origin1_info = tracker->GetCachedOriginInfo(kOrigin1);
          EXPECT_TRUE(origin1_info);
          EXPECT_EQ(1, origin1_info->GetDatabaseSize(kDB1));
          EXPECT_EQ(0, origin1_info->GetDatabaseSize(kDB3));

          // Get all data for all origins
          std::vector<OriginInfo> origins_info;
          EXPECT_TRUE(tracker->GetAllOriginsInfo(&origins_info));
          EXPECT_EQ(size_t(2), origins_info.size());
          EXPECT_EQ(kOrigin1, origins_info[0].GetOriginIdentifier());
          EXPECT_EQ(1, origins_info[0].TotalSize());
          EXPECT_EQ(1, origins_info[0].GetDatabaseSize(kDB1));
          EXPECT_EQ(0, origins_info[0].GetDatabaseSize(kDB3));

          EXPECT_EQ(kOrigin2, origins_info[1].GetOriginIdentifier());
          EXPECT_EQ(2, origins_info[1].TotalSize());

          // Trying to delete an origin with databases in use should fail
          tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, &database_size);
          EXPECT_FALSE(tracker->DeleteOrigin(kOrigin1, false));
          origin1_info = tracker->GetCachedOriginInfo(kOrigin1);
          EXPECT_TRUE(origin1_info);
          EXPECT_EQ(1, origin1_info->GetDatabaseSize(kDB1));
          tracker->DatabaseClosed(kOrigin1, kDB1);

          // Delete an origin that doesn't have any database in use
          EXPECT_TRUE(tracker->DeleteOrigin(kOrigin1, false));
          origins_info.clear();
          EXPECT_TRUE(tracker->GetAllOriginsInfo(&origins_info));
          EXPECT_EQ(size_t(1), origins_info.size());
          EXPECT_EQ(kOrigin2, origins_info[0].GetOriginIdentifier());

          origin1_info = tracker->GetCachedOriginInfo(kOrigin1);
          EXPECT_TRUE(origin1_info);
          EXPECT_EQ(0, origin1_info->TotalSize());

          tracker->Shutdown();
        }));
    run_loop.Run();
  }

  static void DatabaseTrackerQuotaIntegration(bool incognito_mode) {
    const blink::StorageKey kStorageKey =
        blink::StorageKey::CreateFromStringForTesting(kOrigin1Url);
    const std::string kOriginId = GetIdentifierFromOrigin(kStorageKey.origin());
    const std::u16string kName = u"name";
    const std::u16string kDescription = u"description";

    base::test::TaskEnvironment task_environment;
    base::ScopedTempDir temp_dir;
    ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

    // Initialize the tracker with a QuotaManagerProxy
    auto test_quota_proxy = base::MakeRefCounted<TestQuotaManagerProxy>();
    scoped_refptr<DatabaseTracker> tracker = DatabaseTracker::Create(
        temp_dir.GetPath(), incognito_mode,
        /*special_storage_policy=*/nullptr, test_quota_proxy);
    base::RunLoop run_loop;
    tracker->task_runner()->PostTask(
        FROM_HERE, base::BindLambdaForTesting([&]() {
          base::ScopedClosureRunner quit_runner(
              base::BindLambdaForTesting([&]() { run_loop.Quit(); }));

          EXPECT_TRUE(test_quota_proxy->registered_client_);

          // Create a database and modify it a couple of times, close it,
          // then delete it. Observe the tracker notifies accordingly.

          int64_t database_size = 0;
          tracker->DatabaseOpened(kOriginId, kName, kDescription,
                                  &database_size);
          EXPECT_TRUE(test_quota_proxy->WasAccessNotified(kStorageKey));
          test_quota_proxy->ResetRecordedTestState();

          base::FilePath db_file(tracker->GetFullDBFilePath(kOriginId, kName));
          EXPECT_FALSE(
              base::PathExists(tracker->GetOriginDirectory(kOriginId)));
          EXPECT_TRUE(base::CreateDirectory(db_file.DirName()));
          EXPECT_TRUE(EnsureFileOfSize(db_file, 10));
          EXPECT_TRUE(base::PathExists(tracker->GetOriginDirectory(kOriginId)));
          tracker->DatabaseModified(kOriginId, kName);
          EXPECT_TRUE(
              test_quota_proxy->WasModificationNotified(kStorageKey, 10));
          test_quota_proxy->ResetRecordedTestState();

          EXPECT_TRUE(EnsureFileOfSize(db_file, 100));
          tracker->DatabaseModified(kOriginId, kName);
          EXPECT_TRUE(
              test_quota_proxy->WasModificationNotified(kStorageKey, 90));
          test_quota_proxy->ResetRecordedTestState();

          tracker->DatabaseClosed(kOriginId, kName);
          EXPECT_TRUE(test_quota_proxy->WasAccessNotified(kStorageKey));
          net::TestCompletionCallback delete_database_callback;
          tracker->DeleteDatabase(kOriginId, kName,
                                  delete_database_callback.callback());
          EXPECT_TRUE(delete_database_callback.have_result());
          EXPECT_EQ(net::OK, delete_database_callback.WaitForResult());
          EXPECT_TRUE(
              test_quota_proxy->WasModificationNotified(kStorageKey, -100));
          test_quota_proxy->ResetRecordedTestState();

          EXPECT_FALSE(
              base::PathExists(tracker->GetOriginDirectory(kOriginId)));

          // Create a database and modify it, try to delete it while open,
          // then close it (at which time deletion will actually occur).
          // Observe the tracker notifies accordingly.

          tracker->DatabaseOpened(kOriginId, kName, kDescription,
                                  &database_size);
          EXPECT_TRUE(test_quota_proxy->WasAccessNotified(kStorageKey));
          test_quota_proxy->ResetRecordedTestState();

          db_file = tracker->GetFullDBFilePath(kOriginId, kName);
          EXPECT_FALSE(
              base::PathExists(tracker->GetOriginDirectory(kOriginId)));
          EXPECT_TRUE(base::CreateDirectory(db_file.DirName()));
          EXPECT_TRUE(EnsureFileOfSize(db_file, 100));
          EXPECT_TRUE(base::PathExists(tracker->GetOriginDirectory(kOriginId)));
          tracker->DatabaseModified(kOriginId, kName);
          EXPECT_TRUE(
              test_quota_proxy->WasModificationNotified(kStorageKey, 100));
          test_quota_proxy->ResetRecordedTestState();

          net::TestCompletionCallback delete_database_callback2;
          tracker->DeleteDatabase(kOriginId, kName,
                                  delete_database_callback2.callback());
          EXPECT_FALSE(delete_database_callback2.have_result());
          EXPECT_FALSE(
              test_quota_proxy->WasModificationNotified(kStorageKey, -100));
          EXPECT_TRUE(base::PathExists(tracker->GetOriginDirectory(kOriginId)));

          tracker->DatabaseClosed(kOriginId, kName);
          EXPECT_TRUE(test_quota_proxy->WasAccessNotified(kStorageKey));
          EXPECT_TRUE(
              test_quota_proxy->WasModificationNotified(kStorageKey, -100));
          EXPECT_FALSE(
              base::PathExists(tracker->GetOriginDirectory(kOriginId)));
          EXPECT_TRUE(delete_database_callback2.have_result());
          EXPECT_EQ(net::OK, delete_database_callback2.WaitForResult());
          test_quota_proxy->ResetRecordedTestState();

          // Create a database and up the file size without telling
          // the tracker about the modification, than simulate a
          // a renderer crash.
          // Observe the tracker notifies accordingly.

          tracker->DatabaseOpened(kOriginId, kName, kDescription,
                                  &database_size);
          EXPECT_TRUE(test_quota_proxy->WasAccessNotified(kStorageKey));
          test_quota_proxy->ResetRecordedTestState();
          db_file = tracker->GetFullDBFilePath(kOriginId, kName);
          EXPECT_FALSE(
              base::PathExists(tracker->GetOriginDirectory(kOriginId)));
          EXPECT_TRUE(base::CreateDirectory(db_file.DirName()));
          EXPECT_TRUE(base::PathExists(tracker->GetOriginDirectory(kOriginId)));
          EXPECT_TRUE(EnsureFileOfSize(db_file, 100));
          DatabaseConnections crashed_renderer_connections;
          crashed_renderer_connections.AddConnection(kOriginId, kName);
          EXPECT_FALSE(
              test_quota_proxy->WasModificationNotified(kStorageKey, 100));
          tracker->CloseDatabases(crashed_renderer_connections);
          EXPECT_TRUE(
              test_quota_proxy->WasModificationNotified(kStorageKey, 100));

          // Cleanup.
          crashed_renderer_connections.RemoveAllConnections();
          tracker->Shutdown();
        }));
    run_loop.Run();
  }

  static void DatabaseTrackerClearSessionOnlyDatabasesOnExit() {
    int64_t database_size = 0;
    const std::string kOrigin1 = GetIdentifierFromOrigin(GURL(kOrigin1Url));
    const std::string kOrigin2 = GetIdentifierFromOrigin(GURL(kOrigin2Url));
    const std::u16string kDB1 = u"db1";
    const std::u16string kDB2 = u"db2";
    const std::u16string kDescription = u"database_description";

    // Initialize the tracker database.
    base::test::TaskEnvironment task_environment;
    base::ScopedTempDir temp_dir;
    ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
    base::FilePath origin1_db_dir;
    base::FilePath origin2_db_dir;
    {
      auto special_storage_policy =
          base::MakeRefCounted<MockSpecialStoragePolicy>();
      special_storage_policy->AddSessionOnly(GURL(kOrigin2Url));
      scoped_refptr<DatabaseTracker> tracker = DatabaseTracker::Create(
          temp_dir.GetPath(), false, std::move(special_storage_policy),
          /*quota_manager_proxy=*/nullptr);
      base::RunLoop run_loop;
      tracker->task_runner()->PostTask(
          FROM_HERE, base::BindLambdaForTesting([&]() {
            base::ScopedClosureRunner quit_runner(
                base::BindLambdaForTesting([&]() { run_loop.Quit(); }));

            // Open two new databases.
            tracker->DatabaseOpened(kOrigin1, kDB1, kDescription,
                                    &database_size);
            EXPECT_EQ(0, database_size);
            tracker->DatabaseOpened(kOrigin2, kDB2, kDescription,
                                    &database_size);
            EXPECT_EQ(0, database_size);

            // Write some data to each file.
            base::FilePath db_file;
            db_file = tracker->GetFullDBFilePath(kOrigin1, kDB1);
            EXPECT_TRUE(base::CreateDirectory(db_file.DirName()));
            EXPECT_TRUE(EnsureFileOfSize(db_file, 1));

            db_file = tracker->GetFullDBFilePath(kOrigin2, kDB2);
            EXPECT_TRUE(base::CreateDirectory(db_file.DirName()));
            EXPECT_TRUE(EnsureFileOfSize(db_file, 2));

            // Store the origin database directories as long as they still
            // exist.
            origin1_db_dir =
                tracker->GetFullDBFilePath(kOrigin1, kDB1).DirName();
            origin2_db_dir =
                tracker->GetFullDBFilePath(kOrigin2, kDB2).DirName();

            tracker->DatabaseModified(kOrigin1, kDB1);
            tracker->DatabaseModified(kOrigin2, kDB2);

            // Close all databases.
            tracker->DatabaseClosed(kOrigin1, kDB1);
            tracker->DatabaseClosed(kOrigin2, kDB2);

            tracker->Shutdown();
          }));
      run_loop.Run();
    }

    // At this point, the database tracker should be gone. Create a new one.
    scoped_refptr<DatabaseTracker> tracker = DatabaseTracker::Create(
        temp_dir.GetPath(), /*is_incognito=*/false,
        /*special_storage_policy=*/nullptr, /*quota_manager_proxy=*/nullptr);
    base::RunLoop run_loop;
    tracker->task_runner()->PostTask(
        FROM_HERE, base::BindLambdaForTesting([&]() {
          base::ScopedClosureRunner quit_runner(
              base::BindLambdaForTesting([&]() { run_loop.Quit(); }));

          // Get all data for all origins.
          std::vector<OriginInfo> origins_info;
          EXPECT_TRUE(tracker->GetAllOriginsInfo(&origins_info));
          // kOrigin1 was not session-only, so it survived. kOrigin2 was
          // session-only and it got deleted.
          EXPECT_EQ(size_t(1), origins_info.size());
          EXPECT_EQ(kOrigin1, origins_info[0].GetOriginIdentifier());
          EXPECT_TRUE(
              base::PathExists(tracker->GetFullDBFilePath(kOrigin1, kDB1)));
          EXPECT_EQ(base::FilePath(),
                    tracker->GetFullDBFilePath(kOrigin2, kDB2));

          // The origin directory of kOrigin1 remains, but the origin directory
          // of kOrigin2 is deleted.
          EXPECT_TRUE(base::PathExists(origin1_db_dir));
          EXPECT_FALSE(base::PathExists(origin2_db_dir));

          tracker->Shutdown();
        }));
    run_loop.Run();
  }

  static void DatabaseTrackerSetForceKeepSessionState() {
    int64_t database_size = 0;
    const std::string kOrigin1 = GetIdentifierFromOrigin(GURL(kOrigin1Url));
    const std::string kOrigin2 = GetIdentifierFromOrigin(GURL(kOrigin2Url));
    const std::u16string kDB1 = u"db1";
    const std::u16string kDB2 = u"db2";
    const std::u16string kDescription = u"database_description";

    // Initialize the tracker database.
    base::test::TaskEnvironment task_environment;
    base::ScopedTempDir temp_dir;
    ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
    base::FilePath origin1_db_dir;
    base::FilePath origin2_db_dir;
    {
      auto special_storage_policy =
          base::MakeRefCounted<MockSpecialStoragePolicy>();
      special_storage_policy->AddSessionOnly(GURL(kOrigin2Url));
      scoped_refptr<DatabaseTracker> tracker = DatabaseTracker::Create(
          temp_dir.GetPath(), false, std::move(special_storage_policy),
          /*quota_manager_proxy=*/nullptr);
      base::RunLoop run_loop;
      tracker->task_runner()->PostTask(
          FROM_HERE, base::BindLambdaForTesting([&]() {
            base::ScopedClosureRunner quit_runner(
                base::BindLambdaForTesting([&]() { run_loop.Quit(); }));

            tracker->SetForceKeepSessionState();

            // Open two new databases.
            tracker->DatabaseOpened(kOrigin1, kDB1, kDescription,
                                    &database_size);
            EXPECT_EQ(0, database_size);
            tracker->DatabaseOpened(kOrigin2, kDB2, kDescription,
                                    &database_size);
            EXPECT_EQ(0, database_size);

            // Write some data to each file.
            base::FilePath db_file;
            db_file = tracker->GetFullDBFilePath(kOrigin1, kDB1);
            EXPECT_TRUE(base::CreateDirectory(db_file.DirName()));
            EXPECT_TRUE(EnsureFileOfSize(db_file, 1));

            db_file = tracker->GetFullDBFilePath(kOrigin2, kDB2);
            EXPECT_TRUE(base::CreateDirectory(db_file.DirName()));
            EXPECT_TRUE(EnsureFileOfSize(db_file, 2));

            // Store the origin database directories as long as they still
            // exist.
            origin1_db_dir =
                tracker->GetFullDBFilePath(kOrigin1, kDB1).DirName();
            origin2_db_dir =
                tracker->GetFullDBFilePath(kOrigin2, kDB2).DirName();

            tracker->DatabaseModified(kOrigin1, kDB1);
            tracker->DatabaseModified(kOrigin2, kDB2);

            // Close all databases.
            tracker->DatabaseClosed(kOrigin1, kDB1);
            tracker->DatabaseClosed(kOrigin2, kDB2);

            tracker->Shutdown();
          }));
      run_loop.Run();
    }

    // At this point, the database tracker should be gone. Create a new one.
    scoped_refptr<DatabaseTracker> tracker = DatabaseTracker::Create(
        temp_dir.GetPath(), false, /*special_storage_policy=*/nullptr,
        /*quota_manager_proxy=*/nullptr);
    base::RunLoop run_loop;
    tracker->task_runner()->PostTask(
        FROM_HERE, base::BindLambdaForTesting([&]() {
          base::ScopedClosureRunner quit_runner(
              base::BindLambdaForTesting([&]() { run_loop.Quit(); }));

          // Get all data for all origins.
          std::vector<OriginInfo> origins_info;
          EXPECT_TRUE(tracker->GetAllOriginsInfo(&origins_info));
          // No origins were deleted.
          EXPECT_EQ(size_t(2), origins_info.size());
          EXPECT_TRUE(
              base::PathExists(tracker->GetFullDBFilePath(kOrigin1, kDB1)));
          EXPECT_TRUE(
              base::PathExists(tracker->GetFullDBFilePath(kOrigin2, kDB2)));

          EXPECT_TRUE(base::PathExists(origin1_db_dir));
          EXPECT_TRUE(base::PathExists(origin2_db_dir));

          tracker->Shutdown();
        }));
    run_loop.Run();
  }

  static void EmptyDatabaseNameIsValid() {
    const GURL kOrigin(kOrigin1Url);
    const std::string kOriginId = GetIdentifierFromOrigin(kOrigin);
    const std::u16string kEmptyName;
    const std::u16string kDescription(u"description");
    const std::u16string kChangedDescription(u"changed_description");

    // Initialize a tracker database, no need to put it on disk.
    const bool kUseInMemoryTrackerDatabase = true;
    base::test::TaskEnvironment task_environment;
    base::ScopedTempDir temp_dir;
    ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
    scoped_refptr<DatabaseTracker> tracker = DatabaseTracker::Create(
        temp_dir.GetPath(), kUseInMemoryTrackerDatabase,
        /*special_storage_policy=*/nullptr, /*quota_manager_proxy=*/nullptr);
    base::RunLoop run_loop;
    tracker->task_runner()->PostTask(
        FROM_HERE, base::BindLambdaForTesting([&]() {
          base::ScopedClosureRunner quit_runner(
              base::BindLambdaForTesting([&]() { run_loop.Quit(); }));

          // Starts off with no databases.
          std::vector<OriginInfo> infos;
          EXPECT_TRUE(tracker->GetAllOriginsInfo(&infos));
          EXPECT_TRUE(infos.empty());

          // Create a db with an empty name.
          int64_t database_size = -1;
          tracker->DatabaseOpened(kOriginId, kEmptyName, kDescription,
                                  &database_size);
          EXPECT_EQ(0, database_size);
          tracker->DatabaseModified(kOriginId, kEmptyName);
          EXPECT_TRUE(tracker->GetAllOriginsInfo(&infos));
          EXPECT_EQ(1u, infos.size());
          EXPECT_FALSE(
              tracker->GetFullDBFilePath(kOriginId, kEmptyName).empty());
          tracker->DatabaseOpened(kOriginId, kEmptyName, kChangedDescription,
                                  &database_size);
          infos.clear();
          EXPECT_TRUE(tracker->GetAllOriginsInfo(&infos));
          EXPECT_EQ(1u, infos.size());
          tracker->DatabaseClosed(kOriginId, kEmptyName);
          tracker->DatabaseClosed(kOriginId, kEmptyName);

          // Deleting it should return to the initial state.
          net::TestCompletionCallback delete_database_callback;
          tracker->DeleteDatabase(kOriginId, kEmptyName,
                                  delete_database_callback.callback());
          EXPECT_TRUE(delete_database_callback.have_result());
          EXPECT_EQ(net::OK, delete_database_callback.WaitForResult());
          infos.clear();
          EXPECT_TRUE(tracker->GetAllOriginsInfo(&infos));
          EXPECT_TRUE(infos.empty());

          tracker->Shutdown();
        }));
    run_loop.Run();
  }

  static void HandleSqliteError() {
    const GURL kOrigin(kOrigin1Url);
    const std::string kOriginId = GetIdentifierFromOrigin(kOrigin);
    const std::u16string kName(u"name");
    const std::u16string kDescription(u"description");

    // Initialize a tracker database, no need to put it on disk.
    const bool kUseInMemoryTrackerDatabase = true;
    base::test::TaskEnvironment task_environment;
    base::ScopedTempDir temp_dir;
    ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
    scoped_refptr<DatabaseTracker> tracker = DatabaseTracker::Create(
        temp_dir.GetPath(), kUseInMemoryTrackerDatabase,
        /*special_storage_policy=*/nullptr, /*quota_manager_proxy=*/nullptr);
    base::RunLoop run_loop;
    tracker->task_runner()->PostTask(
        FROM_HERE, base::BindLambdaForTesting([&]() {
          base::ScopedClosureRunner quit_runner(
              base::BindLambdaForTesting([&]() { run_loop.Quit(); }));

          // Setup to observe OnScheduledForDelete notifications.
          TestObserver observer(false, true);
          tracker->AddObserver(&observer);

          // Verify does no harm when there is no such database.
          tracker->HandleSqliteError(kOriginId, kName, SQLITE_CORRUPT);
          EXPECT_FALSE(
              tracker->IsDatabaseScheduledForDeletion(kOriginId, kName));
          EXPECT_FALSE(observer.DidReceiveNewNotification());

          // --------------------------------------------------------
          // Create a record of a database in the tracker db and create
          // a spoof_db_file on disk in the expected location.
          int64_t database_size = 0;
          tracker->DatabaseOpened(kOriginId, kName, kDescription,
                                  &database_size);
          base::FilePath spoof_db_file =
              tracker->GetFullDBFilePath(kOriginId, kName);
          EXPECT_FALSE(tracker->GetFullDBFilePath(kOriginId, kName).empty());
          EXPECT_TRUE(base::CreateDirectory(spoof_db_file.DirName()));
          EXPECT_TRUE(EnsureFileOfSize(spoof_db_file, 1));

          // Verify does no harm with a non-error is reported.
          tracker->HandleSqliteError(kOriginId, kName, SQLITE_OK);
          EXPECT_FALSE(
              tracker->IsDatabaseScheduledForDeletion(kOriginId, kName));
          EXPECT_FALSE(observer.DidReceiveNewNotification());

          // Verify that with a connection open, the db is scheduled for
          // deletion, but that the file still exists.
          tracker->HandleSqliteError(kOriginId, kName, SQLITE_CORRUPT);
          EXPECT_TRUE(
              tracker->IsDatabaseScheduledForDeletion(kOriginId, kName));
          EXPECT_TRUE(observer.DidReceiveNewNotification());
          EXPECT_TRUE(base::PathExists(spoof_db_file));

          // Verify that once closed, the file is deleted and the record in the
          // tracker db is removed.
          tracker->DatabaseClosed(kOriginId, kName);
          EXPECT_FALSE(base::PathExists(spoof_db_file));
          EXPECT_TRUE(tracker->GetFullDBFilePath(kOriginId, kName).empty());

          // --------------------------------------------------------
          // Create another record of a database in the tracker db and create
          // a spoof_db_file on disk in the expected location.
          tracker->DatabaseOpened(kOriginId, kName, kDescription,
                                  &database_size);
          base::FilePath spoof_db_file2 =
              tracker->GetFullDBFilePath(kOriginId, kName);
          EXPECT_FALSE(tracker->GetFullDBFilePath(kOriginId, kName).empty());
          EXPECT_NE(spoof_db_file, spoof_db_file2);
          EXPECT_TRUE(base::CreateDirectory(spoof_db_file2.DirName()));
          EXPECT_TRUE(EnsureFileOfSize(spoof_db_file2, 1));

          // Verify that with no connection open, the db is deleted immediately.
          tracker->DatabaseClosed(kOriginId, kName);
          tracker->HandleSqliteError(kOriginId, kName, SQLITE_CORRUPT);
          EXPECT_FALSE(
              tracker->IsDatabaseScheduledForDeletion(kOriginId, kName));
          EXPECT_FALSE(observer.DidReceiveNewNotification());
          EXPECT_TRUE(tracker->GetFullDBFilePath(kOriginId, kName).empty());
          EXPECT_FALSE(base::PathExists(spoof_db_file2));

          tracker->RemoveObserver(&observer);

          tracker->Shutdown();
        }));
    run_loop.Run();
  }
};

TEST(DatabaseTrackerTest, DeleteOpenDatabase) {
  DatabaseTracker_TestHelper_Test::TestDeleteOpenDatabase(false);
}

TEST(DatabaseTrackerTest, DeleteOpenDatabaseIncognitoMode) {
  DatabaseTracker_TestHelper_Test::TestDeleteOpenDatabase(true);
}

TEST(DatabaseTrackerTest, DatabaseTracker) {
  DatabaseTracker_TestHelper_Test::TestDatabaseTracker(false);
}

TEST(DatabaseTrackerTest, DatabaseTrackerIncognitoMode) {
  DatabaseTracker_TestHelper_Test::TestDatabaseTracker(true);
}

TEST(DatabaseTrackerTest, DatabaseTrackerQuotaIntegration) {
  DatabaseTracker_TestHelper_Test::DatabaseTrackerQuotaIntegration(false);
}

TEST(DatabaseTrackerTest, DatabaseTrackerQuotaIntegrationIncognitoMode) {
  DatabaseTracker_TestHelper_Test::DatabaseTrackerQuotaIntegration(true);
}

TEST(DatabaseTrackerTest, DatabaseTrackerClearSessionOnlyDatabasesOnExit) {
  // Only works for regular mode.
  DatabaseTracker_TestHelper_Test::
      DatabaseTrackerClearSessionOnlyDatabasesOnExit();
}

TEST(DatabaseTrackerTest, DatabaseTrackerSetForceKeepSessionState) {
  // Only works for regular mode.
  DatabaseTracker_TestHelper_Test::DatabaseTrackerSetForceKeepSessionState();
}

TEST(DatabaseTrackerTest, EmptyDatabaseNameIsValid) {
  DatabaseTracker_TestHelper_Test::EmptyDatabaseNameIsValid();
}

TEST(DatabaseTrackerTest, HandleSqliteError) {
  DatabaseTracker_TestHelper_Test::HandleSqliteError();
}

}  // namespace storage
