chromium/content/browser/indexed_db/indexed_db_browsertest.cc

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

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

#include <functional>
#include <utility>

#include "base/command_line.h"
#include "base/files/file.h"
#include "base/files/file_enumerator.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/lazy_instance.h"
#include "base/location.h"
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "base/strings/escape.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/bind.h"
#include "base/test/gmock_expected_support.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/test_future.h"
#include "base/test/thread_test_helper.h"
#include "base/threading/thread_restrictions.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "components/services/storage/indexed_db/transactional_leveldb/transactional_leveldb_database.h"
#include "components/services/storage/privileged/mojom/indexed_db_control.mojom-test-utils.h"
#include "components/services/storage/privileged/mojom/indexed_db_control_test.mojom.h"
#include "components/services/storage/public/cpp/buckets/bucket_locator.h"
#include "components/services/storage/public/mojom/storage_usage_info.mojom.h"
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
#include "content/browser/browser_main_loop.h"
#include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/url_constants.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/no_renderer_crashes_assertion.h"
#include "content/shell/browser/shell.h"
#include "net/base/net_errors.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
#include "storage/browser/blob/blob_storage_context.h"
#include "storage/browser/database/database_util.h"
#include "storage/browser/quota/quota_manager.h"
#include "storage/browser/quota/quota_manager_proxy.h"
#include "storage/browser/quota/quota_settings.h"
#include "third_party/blink/public/common/storage_key/storage_key.h"
#include "third_party/blink/public/common/switches.h"
#include "third_party/leveldatabase/src/include/leveldb/status.h"
#include "url/gurl.h"
#include "url/origin.h"

DatabaseUtil;
QuotaManager;
FailClass;
FailMethod;

namespace content {

// This browser test is aimed towards exercising the IndexedDB bindings and
// the actual implementation that lives in the browser side.
class IndexedDBBrowserTest : public ContentBrowserTest {};

class IndexedDBIncognitoTest : public IndexedDBBrowserTest,
                               public ::testing::WithParamInterface<bool> {};

IN_PROC_BROWSER_TEST_P(IndexedDBIncognitoTest, CursorTest) {}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CursorPrefetch) {}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, IndexTest) {}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, KeyPathTest) {}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, TransactionGetTest) {}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, KeyTypesTest) {}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, ObjectStoreTest) {}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DatabaseTest) {}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, TransactionTest) {}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CallbackAccounting) {}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DoesntHangTest) {}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, Bug84933Test) {}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, Bug106883Test) {}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, Bug109187Test) {}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, Bug941965Test) {}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, NegativeDBSchemaVersion) {}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, NegativeDBDataVersion) {}

class IndexedDBBrowserTestWithLowQuota : public IndexedDBBrowserTest {};

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithLowQuota, QuotaTest) {}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithLowQuota, QuotaTestWithCommit) {}

class IndexedDBBrowserTestWithGCExposed : public IndexedDBBrowserTest {};

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithGCExposed,
                       DatabaseCallbacksTest) {}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithGCExposed, Bug346955148Test) {}

struct BlobModificationTime {};

static void CopyLevelDBToProfile(
    Shell* shell,
    const base::FilePath& data_path,
    const std::string& test_directory,
    std::vector<BlobModificationTime> modification_times) {}

class IndexedDBBrowserTestWithPreexistingLevelDB : public IndexedDBBrowserTest {};

class IndexedDBBrowserTestWithVersion3Schema
    : public IndexedDBBrowserTestWithPreexistingLevelDB {};

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithVersion3Schema, MigrationTest) {}

class IndexedDBBrowserTestWithVersion123456Schema : public
    IndexedDBBrowserTestWithPreexistingLevelDB {};

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithVersion123456Schema,
                       DestroyTest) {}

class IndexedDBBrowserTestWithVersion987654SSVData : public
    IndexedDBBrowserTestWithPreexistingLevelDB {};

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithVersion987654SSVData,
                       DestroyTest) {}

class IndexedDBBrowserTestWithCorruptLevelDB : public
    IndexedDBBrowserTestWithPreexistingLevelDB {};

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithCorruptLevelDB,
                       DestroyTest) {}

class IndexedDBBrowserTestWithMissingSSTFile : public
    IndexedDBBrowserTestWithPreexistingLevelDB {};

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithMissingSSTFile,
                       DestroyTest) {}

// IndexedDBBrowserTestWithCrbug899446* capture IDB instances from Chrome stable
// to verify that the current code can read those instances.  For more info on
// a case when Chrome canary couldn't read stable's IDB instances, see
// https://crbug.com/899446.

class IndexedDBBrowserTestWithCrbug899446
    : public IndexedDBBrowserTestWithPreexistingLevelDB {};

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithCrbug899446, StableTest) {}

class IndexedDBBrowserTestWithCrbug899446Noai
    : public IndexedDBBrowserTestWithPreexistingLevelDB {};

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithCrbug899446Noai, StableTest) {}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, LevelDBLogFileTest) {}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CanDeleteWhenOverQuotaTest) {}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, EmptyBlob) {}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, BlobsCountAgainstQuota) {}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DeleteBucketDataDeletesBlobs) {}

// Regression test for crbug.com/330868483
// In this test,
//   1. the page reads a blob
//   2. the backing store is force-closed
//   3. the reference to the blob is GC'd
//      . this disconnects the IndexedDBDataItemReader *after* the backing store
//        is already reset
//   4. the page reads the same blob, reusing the IndexedDBDataItemReader
//   5. the blob reference is dropped and GC'd again
//   6. don't crash
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithGCExposed, ForceCloseWithBlob) {}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DeleteBucketDataIncognito) {}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DiskFullOnCommit) {}

namespace {

std::unique_ptr<net::test_server::HttpResponse> ServePath(
    std::string request_path) {}

#if !BUILDFLAG(IS_WIN)
void CorruptIndexedDBDatabase(const base::FilePath& idb_data_path) {}

const char s_corrupt_db_test_prefix[] =;

std::unique_ptr<net::test_server::HttpResponse> CorruptDBRequestHandler(
    scoped_refptr<base::SequencedTaskRunner> task_runner,
    const storage::BucketLocator& bucket_locator,
    const std::string& path,
    IndexedDBBrowserTest* test,
    const net::test_server::HttpRequest& request) {}
#endif

const char s_indexeddb_test_prefix[] =;

std::unique_ptr<net::test_server::HttpResponse> StaticFileRequestHandler(
    const std::string& path,
    IndexedDBBrowserTest* test,
    const net::test_server::HttpRequest& request) {}

}  // namespace

// See TODO in CorruptDBRequestHandler.  Windows does not support nested
// message loops on the IO thread, so run this test on other platforms.
#if !BUILDFLAG(IS_WIN)
class IndexedDBBrowserTestWithCorruption
    : public IndexedDBBrowserTest,
      public ::testing::WithParamInterface<const char*> {};

INSTANTIATE_TEST_SUITE_P();

IN_PROC_BROWSER_TEST_P(IndexedDBBrowserTestWithCorruption,
                       OperationOnCorruptedOpenDatabase) {}
#endif  // !BUILDFLAG(IS_WIN)

// TODO: http://crbug.com/510520, flaky on all platforms
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest,
                       DISABLED_DeleteCompactsBackingStore) {}

// Complex multi-step (converted from pyauto) tests begin here.

// Verify null key path persists after restarting browser.
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, PRE_NullKeyPathPersistence) {}

// Verify null key path persists after restarting browser.
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, NullKeyPathPersistence) {}

// Disable this test on Android due to failures. See crbug.com/427529 and
// crbug.com/1116464 for details.
#if defined(ANDROID)
#define MAYBE_ConnectionsClosedOnTabClose
#else
#define MAYBE_ConnectionsClosedOnTabClose
#endif
// Verify that open DB connections are closed when a tab is destroyed.
IN_PROC_BROWSER_TEST_F(
    IndexedDBBrowserTest, MAYBE_ConnectionsClosedOnTabClose) {}

// Verify that a "close" event is fired at database connections when
// the backing store is deleted.
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, ForceCloseEventTest) {}

IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, ShutdownWithRequests) {}

// The blob key corruption test runs in a separate class to avoid corrupting
// an IDB store that other tests use.
// This test is for https://crbug.com/1039446.
IndexedDBBrowserTestBlobKeyCorruption;

// Verify the blob key corruption state recovery:
// - Create a file that should be the 'first' blob file.
// - open a database that tries to write a blob.
// - verify the new blob key is correct.
// Regression test for crbug.com/40666839
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestBlobKeyCorruption, LifecycleTest) {}

IN_PROC_BROWSER_TEST_P(IndexedDBIncognitoTest, BucketDurabilityStrict) {}

IN_PROC_BROWSER_TEST_P(IndexedDBIncognitoTest, BucketDurabilityRelaxed) {}

IN_PROC_BROWSER_TEST_P(IndexedDBIncognitoTest, BucketDurabilityOverride) {}

INSTANTIATE_TEST_SUITE_P();

}  // namespace content