Commit 3d8d900e authored by Adrienne Walker's avatar Adrienne Walker Committed by Commit Bot

indexeddb: convert mock idb class factory to IndexedDBControl

Bug: 1015214
Change-Id: I8836e79a52f35e166c5d5ec310ccc82dc52689a5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2090878
Commit-Queue: enne <enne@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Reviewed-by: default avatarDaniel Murphy <dmurph@chromium.org>
Auto-Submit: enne <enne@chromium.org>
Cr-Commit-Position: refs/heads/master@{#748824}
parent 3174752f
...@@ -15,9 +15,32 @@ enum V2SchemaCorruptionStatus { ...@@ -15,9 +15,32 @@ enum V2SchemaCorruptionStatus {
CORRUPTION_YES, CORRUPTION_YES,
}; };
enum FailClass {
NOTHING,
LEVELDB_ITERATOR,
LEVELDB_DIRECT_TRANSACTION,
LEVELDB_TRANSACTION,
LEVELDB_DATABASE,
};
enum FailMethod {
NOTHING,
COMMIT,
COMMIT_DISK_FULL,
GET,
SEEK,
WRITE,
};
// A test-only interface for creating fake failures in IndexedDB methods.
interface MockFailureInjector {
// Causes indexeddb to fail in a given way on a given call.
FailOperation(FailClass failure_class, FailMethod failure_method,
int32 instance_num, int32 call_num) => ();
};
// A test-only interface extending storage.mojom.IndexedDBControl. // A test-only interface extending storage.mojom.IndexedDBControl.
interface IndexedDBControlTest { interface IndexedDBControlTest {
// Gets the root data path for storage. // Gets the root data path for storage.
GetBaseDataPathForTesting() => (mojo_base.mojom.FilePath path); GetBaseDataPathForTesting() => (mojo_base.mojom.FilePath path);
...@@ -53,4 +76,18 @@ interface IndexedDBControlTest { ...@@ -53,4 +76,18 @@ interface IndexedDBControlTest {
// Compacts the backing store for a given origin. // Compacts the backing store for a given origin.
CompactBackingStoreForTesting(url.mojom.Origin origin) => (); CompactBackingStoreForTesting(url.mojom.Origin origin) => ();
// Overrides IndexedDB with a mock class factory that can inject failures
// at specific points. For now, because this is static, there can only
// be one of these bound at a single time.
//
// Note: in order for this not to be flaky, this should be called before
// using the IndexedDB system in any way to ensure that that the default
// class factory isn't used before the testing one is set.
BindMockFailureSingletonForTesting(
pending_receiver<MockFailureInjector> receiver);
// Return keys used in WriteToIndexedDBForTesting.
GetDatabaseKeysForTesting() =>
(string schema_version_key, string data_version_key);
}; };
...@@ -1059,6 +1059,8 @@ jumbo_source_set("browser") { ...@@ -1059,6 +1059,8 @@ jumbo_source_set("browser") {
"indexed_db/indexed_db_value.cc", "indexed_db/indexed_db_value.cc",
"indexed_db/indexed_db_value.h", "indexed_db/indexed_db_value.h",
"indexed_db/list_set.h", "indexed_db/list_set.h",
"indexed_db/mock_browsertest_indexed_db_class_factory.cc",
"indexed_db/mock_browsertest_indexed_db_class_factory.h",
"indexed_db/transaction_impl.cc", "indexed_db/transaction_impl.cc",
"indexed_db/transaction_impl.h", "indexed_db/transaction_impl.h",
"initiator_csp_context.cc", "initiator_csp_context.cc",
......
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
#include "components/services/storage/public/mojom/indexed_db_control.mojom-test-utils.h" #include "components/services/storage/public/mojom/indexed_db_control.mojom-test-utils.h"
#include "content/browser/blob_storage/chrome_blob_storage_context.h" #include "content/browser/blob_storage/chrome_blob_storage_context.h"
#include "content/browser/browser_main_loop.h" #include "content/browser/browser_main_loop.h"
#include "content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.h"
#include "content/browser/web_contents/web_contents_impl.h" #include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_task_traits.h"
...@@ -60,8 +59,10 @@ ...@@ -60,8 +59,10 @@
#include "url/origin.h" #include "url/origin.h"
using base::ASCIIToUTF16; using base::ASCIIToUTF16;
using storage::QuotaManager;
using storage::DatabaseUtil; using storage::DatabaseUtil;
using storage::QuotaManager;
using storage::mojom::FailClass;
using storage::mojom::FailMethod;
namespace content { namespace content {
...@@ -72,22 +73,17 @@ class IndexedDBBrowserTest : public ContentBrowserTest, ...@@ -72,22 +73,17 @@ class IndexedDBBrowserTest : public ContentBrowserTest,
public: public:
IndexedDBBrowserTest() = default; IndexedDBBrowserTest() = default;
void SetUp() override { void SetUpOnMainThread() override {
GetTestClassFactory()->Reset();
IndexedDBClassFactory::SetIndexedDBClassFactoryGetter(GetIDBClassFactory);
// Some tests need more space than the default used for browser tests. // Some tests need more space than the default used for browser tests.
static storage::QuotaSettings quota_settings = static storage::QuotaSettings quota_settings =
storage::GetHardCodedSettings(100 * 1024 * 1024); storage::GetHardCodedSettings(100 * 1024 * 1024);
StoragePartition::SetDefaultQuotaSettingsForTesting(&quota_settings); StoragePartition::SetDefaultQuotaSettingsForTesting(&quota_settings);
ContentBrowserTest::SetUp(); GetControlTest()->BindMockFailureSingletonForTesting(
failure_injector_.BindNewPipeAndPassReceiver());
} }
void TearDown() override { void TearDownOnMainThread() override { failure_injector_.reset(); }
IndexedDBClassFactory::SetIndexedDBClassFactoryGetter(nullptr);
ContentBrowserTest::TearDown();
}
bool UseProductionQuotaSettings() override { bool UseProductionQuotaSettings() override {
// So that the browser test harness doesn't call // So that the browser test harness doesn't call
...@@ -99,8 +95,21 @@ class IndexedDBBrowserTest : public ContentBrowserTest, ...@@ -99,8 +95,21 @@ class IndexedDBBrowserTest : public ContentBrowserTest,
FailMethod failure_method, FailMethod failure_method,
int fail_on_instance_num, int fail_on_instance_num,
int fail_on_call_num) { int fail_on_call_num) {
GetTestClassFactory()->FailOperation( base::RunLoop loop;
failure_class, failure_method, fail_on_instance_num, fail_on_call_num); FailOperationWithCallback(failure_class, failure_method,
fail_on_instance_num, fail_on_call_num,
loop.QuitClosure());
loop.Run();
}
void FailOperationWithCallback(FailClass failure_class,
FailMethod failure_method,
int fail_on_instance_num,
int fail_on_call_num,
base::OnceClosure callback) {
failure_injector_->FailOperation(failure_class, failure_method,
fail_on_instance_num, fail_on_call_num,
std::move(callback));
} }
void SimpleTest(const GURL& test_url, void SimpleTest(const GURL& test_url,
...@@ -274,18 +283,9 @@ class IndexedDBBrowserTest : public ContentBrowserTest, ...@@ -274,18 +283,9 @@ class IndexedDBBrowserTest : public ContentBrowserTest,
loop.Run(); loop.Run();
} }
protected:
static MockBrowserTestIndexedDBClassFactory* GetTestClassFactory() {
static ::base::LazyInstance<MockBrowserTestIndexedDBClassFactory>::Leaky
s_factory = LAZY_INSTANCE_INITIALIZER;
return s_factory.Pointer();
}
static IndexedDBClassFactory* GetIDBClassFactory() {
return GetTestClassFactory();
}
private: private:
mojo::Remote<storage::mojom::MockFailureInjector> failure_injector_;
DISALLOW_COPY_AND_ASSIGN(IndexedDBBrowserTest); DISALLOW_COPY_AND_ASSIGN(IndexedDBBrowserTest);
}; };
...@@ -381,13 +381,26 @@ IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, Bug941965Test) { ...@@ -381,13 +381,26 @@ IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, Bug941965Test) {
} }
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, NegativeDBSchemaVersion) { IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, NegativeDBSchemaVersion) {
return;
const GURL database_open_url = GetTestUrl("indexeddb", "database_test.html"); const GURL database_open_url = GetTestUrl("indexeddb", "database_test.html");
const url::Origin origin = url::Origin::Create(database_open_url); const url::Origin origin = url::Origin::Create(database_open_url);
// Create the database. // Create the database.
SimpleTest(database_open_url); SimpleTest(database_open_url);
// -10, little endian. // -10, little endian.
std::string value = "\xF6\xFF\xFF\xFF\xFF\xFF\xFF\xFF"; std::string value = "\xF6\xFF\xFF\xFF\xFF\xFF\xFF\xFF";
WriteToIndexedDB(origin, SchemaVersionKey::Encode(), value);
auto control_test = GetControlTest();
base::RunLoop loop;
std::string key;
control_test->GetDatabaseKeysForTesting(
base::BindLambdaForTesting([&](const std::string& schema_version_key,
const std::string& data_version_key) {
key = schema_version_key;
loop.Quit();
}));
loop.Run();
WriteToIndexedDB(origin, key, value);
// Crash the tab to ensure no old navigations are picked up. // Crash the tab to ensure no old navigations are picked up.
CrashTab(shell()->web_contents()); CrashTab(shell()->web_contents());
SimpleTest(GetTestUrl("indexeddb", "open_bad_db.html")); SimpleTest(GetTestUrl("indexeddb", "open_bad_db.html"));
...@@ -400,7 +413,19 @@ IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, NegativeDBDataVersion) { ...@@ -400,7 +413,19 @@ IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, NegativeDBDataVersion) {
SimpleTest(database_open_url); SimpleTest(database_open_url);
// -10, little endian. // -10, little endian.
std::string value = "\xF6\xFF\xFF\xFF\xFF\xFF\xFF\xFF"; std::string value = "\xF6\xFF\xFF\xFF\xFF\xFF\xFF\xFF";
WriteToIndexedDB(origin, DataVersionKey::Encode(), value);
auto control_test = GetControlTest();
base::RunLoop loop;
std::string key;
control_test->GetDatabaseKeysForTesting(
base::BindLambdaForTesting([&](const std::string& schema_version_key,
const std::string& data_version_key) {
key = data_version_key;
loop.Quit();
}));
loop.Run();
WriteToIndexedDB(origin, key, value);
// Crash the tab to ensure no old navigations are picked up. // Crash the tab to ensure no old navigations are picked up.
CrashTab(shell()->web_contents()); CrashTab(shell()->web_contents());
SimpleTest(GetTestUrl("indexeddb", "open_bad_db.html")); SimpleTest(GetTestUrl("indexeddb", "open_bad_db.html"));
...@@ -758,7 +783,7 @@ IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DiskFullOnCommit) { ...@@ -758,7 +783,7 @@ IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, DiskFullOnCommit) {
// #2: IndexedDBTransaction::Commit - the test's "readwrite" transaction) // #2: IndexedDBTransaction::Commit - the test's "readwrite" transaction)
const int instance_num = 2; const int instance_num = 2;
const int call_num = 1; const int call_num = 1;
FailOperation(FAIL_CLASS_LEVELDB_TRANSACTION, FAIL_METHOD_COMMIT_DISK_FULL, FailOperation(FailClass::LEVELDB_TRANSACTION, FailMethod::COMMIT_DISK_FULL,
instance_num, call_num); instance_num, call_num);
SimpleTest(GetTestUrl("indexeddb", "disk_full_on_commit.html")); SimpleTest(GetTestUrl("indexeddb", "disk_full_on_commit.html"));
} }
...@@ -870,8 +895,8 @@ std::unique_ptr<net::test_server::HttpResponse> CorruptDBRequestHandler( ...@@ -870,8 +895,8 @@ std::unique_ptr<net::test_server::HttpResponse> CorruptDBRequestHandler(
http_response->set_code(net::HTTP_OK); http_response->set_code(net::HTTP_OK);
return std::move(http_response); return std::move(http_response);
} else if (request_path == "fail" && !request_query.empty()) { } else if (request_path == "fail" && !request_query.empty()) {
FailClass failure_class = FAIL_CLASS_NOTHING; FailClass failure_class = FailClass::NOTHING;
FailMethod failure_method = FAIL_METHOD_NOTHING; FailMethod failure_method = FailMethod::NOTHING;
int instance_num = 1; int instance_num = 1;
int call_num = 1; int call_num = 1;
std::string fail_class; std::string fail_class;
...@@ -901,29 +926,29 @@ std::unique_ptr<net::test_server::HttpResponse> CorruptDBRequestHandler( ...@@ -901,29 +926,29 @@ std::unique_ptr<net::test_server::HttpResponse> CorruptDBRequestHandler(
} }
if (fail_class == "LevelDBTransaction") { if (fail_class == "LevelDBTransaction") {
failure_class = FAIL_CLASS_LEVELDB_TRANSACTION; failure_class = FailClass::LEVELDB_TRANSACTION;
if (fail_method == "Get") if (fail_method == "Get")
failure_method = FAIL_METHOD_GET; failure_method = FailMethod::GET;
else if (fail_method == "Commit") else if (fail_method == "Commit")
failure_method = FAIL_METHOD_COMMIT; failure_method = FailMethod::COMMIT;
else else
NOTREACHED() << "Unknown method: \"" << fail_method << "\""; NOTREACHED() << "Unknown method: \"" << fail_method << "\"";
} else if (fail_class == "LevelDBIterator") { } else if (fail_class == "LevelDBIterator") {
failure_class = FAIL_CLASS_LEVELDB_ITERATOR; failure_class = FailClass::LEVELDB_ITERATOR;
if (fail_method == "Seek") if (fail_method == "Seek")
failure_method = FAIL_METHOD_SEEK; failure_method = FailMethod::SEEK;
else else
NOTREACHED() << "Unknown method: \"" << fail_method << "\""; NOTREACHED() << "Unknown method: \"" << fail_method << "\"";
} else if (fail_class == "LevelDBDatabase") { } else if (fail_class == "LevelDBDatabase") {
failure_class = FAIL_CLASS_LEVELDB_DATABASE; failure_class = FailClass::LEVELDB_DATABASE;
if (fail_method == "Write") if (fail_method == "Write")
failure_method = FAIL_METHOD_WRITE; failure_method = FailMethod::WRITE;
else else
NOTREACHED() << "Unknown method: \"" << fail_method << "\""; NOTREACHED() << "Unknown method: \"" << fail_method << "\"";
} else if (fail_class == "LevelDBDirectTransaction") { } else if (fail_class == "LevelDBDirectTransaction") {
failure_class = FAIL_CLASS_LEVELDB_DIRECT_TRANSACTION; failure_class = FailClass::LEVELDB_DIRECT_TRANSACTION;
if (fail_method == "Get") if (fail_method == "Get")
failure_method = FAIL_METHOD_GET; failure_method = FailMethod::GET;
else else
NOTREACHED() << "Unknown method: \"" << fail_method << "\""; NOTREACHED() << "Unknown method: \"" << fail_method << "\"";
} else { } else {
...@@ -933,7 +958,13 @@ std::unique_ptr<net::test_server::HttpResponse> CorruptDBRequestHandler( ...@@ -933,7 +958,13 @@ std::unique_ptr<net::test_server::HttpResponse> CorruptDBRequestHandler(
DCHECK_GE(instance_num, 1); DCHECK_GE(instance_num, 1);
DCHECK_GE(call_num, 1); DCHECK_GE(call_num, 1);
test->FailOperation(failure_class, failure_method, instance_num, call_num); base::RunLoop loop;
task_runner->PostTask(
FROM_HERE,
base::BindOnce(&IndexedDBBrowserTest::FailOperationWithCallback,
base::Unretained(test), failure_class, failure_method,
instance_num, call_num, loop.QuitClosure()));
loop.Run();
std::unique_ptr<net::test_server::BasicHttpResponse> http_response( std::unique_ptr<net::test_server::BasicHttpResponse> http_response(
new net::test_server::BasicHttpResponse); new net::test_server::BasicHttpResponse);
...@@ -1109,14 +1140,7 @@ IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, ForceCloseEventTest) { ...@@ -1109,14 +1140,7 @@ IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, ForceCloseEventTest) {
// The V2 schema corruption test runs in a separate class to avoid corrupting // The V2 schema corruption test runs in a separate class to avoid corrupting
// an IDB store that other tests use. // an IDB store that other tests use.
class IndexedDBBrowserTestV2SchemaCorruption : public IndexedDBBrowserTest { class IndexedDBBrowserTestV2SchemaCorruption : public IndexedDBBrowserTest {};
public:
void SetUp() override {
GetTestClassFactory()->Reset();
IndexedDBClassFactory::SetIndexedDBClassFactoryGetter(GetIDBClassFactory);
ContentBrowserTest::SetUp();
}
};
// Verify the V2 schema corruption lifecycle: // Verify the V2 schema corruption lifecycle:
// - create a current version backing store (v3 or later) // - create a current version backing store (v3 or later)
...@@ -1187,12 +1211,6 @@ IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestSingleProcess, ...@@ -1187,12 +1211,6 @@ IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestSingleProcess,
// This test is for https://crbug.com/1039446. // This test is for https://crbug.com/1039446.
class IndexedDBBrowserTestBlobKeyCorruption : public IndexedDBBrowserTest { class IndexedDBBrowserTestBlobKeyCorruption : public IndexedDBBrowserTest {
public: public:
void SetUp() override {
GetTestClassFactory()->Reset();
IndexedDBClassFactory::SetIndexedDBClassFactoryGetter(GetIDBClassFactory);
ContentBrowserTest::SetUp();
}
int64_t GetNextBlobNumber(const url::Origin& origin, int64_t database_id) { int64_t GetNextBlobNumber(const url::Origin& origin, int64_t database_id) {
int64_t number; int64_t number;
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include "content/browser/indexed_db/indexed_db_quota_client.h" #include "content/browser/indexed_db/indexed_db_quota_client.h"
#include "content/browser/indexed_db/indexed_db_tracing.h" #include "content/browser/indexed_db/indexed_db_tracing.h"
#include "content/browser/indexed_db/indexed_db_transaction.h" #include "content/browser/indexed_db/indexed_db_transaction.h"
#include "content/browser/indexed_db/mock_browsertest_indexed_db_class_factory.h"
#include "storage/browser/database/database_util.h" #include "storage/browser/database/database_util.h"
#include "storage/common/database/database_identifier.h" #include "storage/common/database/database_identifier.h"
#include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h" #include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h"
...@@ -57,6 +58,16 @@ const base::FilePath::CharType IndexedDBContextImpl::kIndexedDBDirectory[] = ...@@ -57,6 +58,16 @@ const base::FilePath::CharType IndexedDBContextImpl::kIndexedDBDirectory[] =
namespace { namespace {
static MockBrowserTestIndexedDBClassFactory* GetTestClassFactory() {
static ::base::LazyInstance<MockBrowserTestIndexedDBClassFactory>::Leaky
s_factory = LAZY_INSTANCE_INITIALIZER;
return s_factory.Pointer();
}
static IndexedDBClassFactory* GetTestIDBClassFactory() {
return GetTestClassFactory();
}
bool IsAllowedPath(const std::vector<base::FilePath>& allowed_paths, bool IsAllowedPath(const std::vector<base::FilePath>& allowed_paths,
const base::FilePath& candidate_path) { const base::FilePath& candidate_path) {
for (const base::FilePath& allowed_path : allowed_paths) { for (const base::FilePath& allowed_path : allowed_paths) {
...@@ -579,6 +590,28 @@ void IndexedDBContextImpl::CompactBackingStoreForTesting( ...@@ -579,6 +590,28 @@ void IndexedDBContextImpl::CompactBackingStoreForTesting(
std::move(callback).Run(); std::move(callback).Run();
} }
void IndexedDBContextImpl::BindMockFailureSingletonForTesting(
mojo::PendingReceiver<storage::mojom::MockFailureInjector> receiver) {
// Lazily instantiate the GetTestClassFactory.
if (!mock_failure_injector_.has_value())
mock_failure_injector_.emplace(GetTestClassFactory());
// TODO(enne): this should really not be a static setter.
CHECK(!mock_failure_injector_->is_bound());
GetTestClassFactory()->Reset();
IndexedDBClassFactory::SetIndexedDBClassFactoryGetter(GetTestIDBClassFactory);
mock_failure_injector_->Bind(std::move(receiver));
mock_failure_injector_->set_disconnect_handler(base::BindOnce([]() {
IndexedDBClassFactory::SetIndexedDBClassFactoryGetter(nullptr);
}));
}
void IndexedDBContextImpl::GetDatabaseKeysForTesting(
GetDatabaseKeysForTestingCallback callback) {
std::move(callback).Run(SchemaVersionKey::Encode(), DataVersionKey::Encode());
}
void IndexedDBContextImpl::ForceCloseSync( void IndexedDBContextImpl::ForceCloseSync(
const Origin& origin, const Origin& origin,
storage::mojom::ForceCloseReason reason) { storage::mojom::ForceCloseReason reason) {
......
...@@ -120,6 +120,11 @@ class CONTENT_EXPORT IndexedDBContextImpl ...@@ -120,6 +120,11 @@ class CONTENT_EXPORT IndexedDBContextImpl
GetPathForBlobForTestingCallback callback) override; GetPathForBlobForTestingCallback callback) override;
void CompactBackingStoreForTesting(const url::Origin& origin, void CompactBackingStoreForTesting(const url::Origin& origin,
base::OnceClosure callback) override; base::OnceClosure callback) override;
void BindMockFailureSingletonForTesting(
mojo::PendingReceiver<storage::mojom::MockFailureInjector> receiver)
override;
void GetDatabaseKeysForTesting(
GetDatabaseKeysForTestingCallback callback) override;
// TODO(enne): fix internal indexeddb callers to use ForceClose async instead. // TODO(enne): fix internal indexeddb callers to use ForceClose async instead.
void ForceCloseSync(const url::Origin& origin, void ForceCloseSync(const url::Origin& origin,
...@@ -241,6 +246,8 @@ class CONTENT_EXPORT IndexedDBContextImpl ...@@ -241,6 +246,8 @@ class CONTENT_EXPORT IndexedDBContextImpl
mojo::ReceiverSet<storage::mojom::IndexedDBControl> receivers_; mojo::ReceiverSet<storage::mojom::IndexedDBControl> receivers_;
mojo::ReceiverSet<storage::mojom::IndexedDBControlTest> test_receivers_; mojo::ReceiverSet<storage::mojom::IndexedDBControlTest> test_receivers_;
base::Optional<mojo::Receiver<storage::mojom::MockFailureInjector>>
mock_failure_injector_;
mojo::RemoteSet<storage::mojom::IndexedDBObserver> observers_; mojo::RemoteSet<storage::mojom::IndexedDBObserver> observers_;
DISALLOW_COPY_AND_ASSIGN(IndexedDBContextImpl); DISALLOW_COPY_AND_ASSIGN(IndexedDBContextImpl);
......
...@@ -21,6 +21,9 @@ ...@@ -21,6 +21,9 @@
#include "third_party/leveldatabase/env_chromium.h" #include "third_party/leveldatabase/env_chromium.h"
#include "third_party/leveldatabase/src/include/leveldb/status.h" #include "third_party/leveldatabase/src/include/leveldb/status.h"
using storage::mojom::FailClass;
using storage::mojom::FailMethod;
namespace { namespace {
class FunctionTracer { class FunctionTracer {
...@@ -121,15 +124,15 @@ class LevelDBTestDatabase : public TransactionalLevelDBDatabase { ...@@ -121,15 +124,15 @@ class LevelDBTestDatabase : public TransactionalLevelDBDatabase {
fail_method_(fail_method), fail_method_(fail_method),
fail_on_call_num_(fail_on_call_num), fail_on_call_num_(fail_on_call_num),
current_call_num_(0) { current_call_num_(0) {
DCHECK(fail_method != FAIL_METHOD_NOTHING); DCHECK(fail_method != FailMethod::NOTHING);
DCHECK_GT(fail_on_call_num, 0); DCHECK_GT(fail_on_call_num, 0);
} }
~LevelDBTestDatabase() override {} ~LevelDBTestDatabase() override = default;
leveldb::Status Get(const base::StringPiece& key, leveldb::Status Get(const base::StringPiece& key,
std::string* value, std::string* value,
bool* found) override { bool* found) override {
if (fail_method_ != FAIL_METHOD_GET || if (fail_method_ != FailMethod::GET ||
++current_call_num_ != fail_on_call_num_) ++current_call_num_ != fail_on_call_num_)
return TransactionalLevelDBDatabase::Get(key, value, found); return TransactionalLevelDBDatabase::Get(key, value, found);
*found = false; *found = false;
...@@ -137,7 +140,7 @@ class LevelDBTestDatabase : public TransactionalLevelDBDatabase { ...@@ -137,7 +140,7 @@ class LevelDBTestDatabase : public TransactionalLevelDBDatabase {
} }
leveldb::Status Write(LevelDBWriteBatch* write_batch) override { leveldb::Status Write(LevelDBWriteBatch* write_batch) override {
if ((fail_method_ != FAIL_METHOD_WRITE) || if ((fail_method_ != FailMethod::WRITE) ||
++current_call_num_ != fail_on_call_num_) ++current_call_num_ != fail_on_call_num_)
return TransactionalLevelDBDatabase::Write(write_batch); return TransactionalLevelDBDatabase::Write(write_batch);
return leveldb::Status::Corruption("Corrupted for the test"); return leveldb::Status::Corruption("Corrupted for the test");
...@@ -158,15 +161,15 @@ class LevelDBTestDirectTransaction : public LevelDBDirectTransaction { ...@@ -158,15 +161,15 @@ class LevelDBTestDirectTransaction : public LevelDBDirectTransaction {
fail_method_(fail_method), fail_method_(fail_method),
fail_on_call_num_(fail_on_call_num), fail_on_call_num_(fail_on_call_num),
current_call_num_(0) { current_call_num_(0) {
DCHECK(fail_method != FAIL_METHOD_NOTHING); DCHECK(fail_method != FailMethod::NOTHING);
DCHECK_GT(fail_on_call_num, 0); DCHECK_GT(fail_on_call_num, 0);
} }
~LevelDBTestDirectTransaction() override {} ~LevelDBTestDirectTransaction() override = default;
leveldb::Status Get(const base::StringPiece& key, leveldb::Status Get(const base::StringPiece& key,
std::string* value, std::string* value,
bool* found) override { bool* found) override {
if (fail_method_ != FAIL_METHOD_GET || if (fail_method_ != FailMethod::GET ||
++current_call_num_ != fail_on_call_num_) ++current_call_num_ != fail_on_call_num_)
return LevelDBTestDirectTransaction::Get(key, value, found); return LevelDBTestDirectTransaction::Get(key, value, found);
...@@ -190,14 +193,14 @@ class LevelDBTestTransaction : public TransactionalLevelDBTransaction { ...@@ -190,14 +193,14 @@ class LevelDBTestTransaction : public TransactionalLevelDBTransaction {
fail_method_(fail_method), fail_method_(fail_method),
fail_on_call_num_(fail_on_call_num), fail_on_call_num_(fail_on_call_num),
current_call_num_(0) { current_call_num_(0) {
DCHECK(fail_method != FAIL_METHOD_NOTHING); DCHECK(fail_method != FailMethod::NOTHING);
DCHECK_GT(fail_on_call_num, 0); DCHECK_GT(fail_on_call_num, 0);
} }
leveldb::Status Get(const base::StringPiece& key, leveldb::Status Get(const base::StringPiece& key,
std::string* value, std::string* value,
bool* found) override { bool* found) override {
if (fail_method_ != FAIL_METHOD_GET || if (fail_method_ != FailMethod::GET ||
++current_call_num_ != fail_on_call_num_) ++current_call_num_ != fail_on_call_num_)
return TransactionalLevelDBTransaction::Get(key, value, found); return TransactionalLevelDBTransaction::Get(key, value, found);
...@@ -206,13 +209,13 @@ class LevelDBTestTransaction : public TransactionalLevelDBTransaction { ...@@ -206,13 +209,13 @@ class LevelDBTestTransaction : public TransactionalLevelDBTransaction {
} }
leveldb::Status Commit(bool sync_on_commit) override { leveldb::Status Commit(bool sync_on_commit) override {
if ((fail_method_ != FAIL_METHOD_COMMIT && if ((fail_method_ != FailMethod::COMMIT &&
fail_method_ != FAIL_METHOD_COMMIT_DISK_FULL) || fail_method_ != FailMethod::COMMIT_DISK_FULL) ||
++current_call_num_ != fail_on_call_num_) ++current_call_num_ != fail_on_call_num_)
return TransactionalLevelDBTransaction::Commit(sync_on_commit); return TransactionalLevelDBTransaction::Commit(sync_on_commit);
// TODO(jsbell): Consider parameterizing the failure mode. // TODO(jsbell): Consider parameterizing the failure mode.
if (fail_method_ == FAIL_METHOD_COMMIT_DISK_FULL) { if (fail_method_ == FailMethod::COMMIT_DISK_FULL) {
return leveldb_env::MakeIOError("dummy filename", "Disk Full", return leveldb_env::MakeIOError("dummy filename", "Disk Full",
leveldb_env::kWritableFileAppend, leveldb_env::kWritableFileAppend,
base::File::FILE_ERROR_NO_SPACE); base::File::FILE_ERROR_NO_SPACE);
...@@ -235,8 +238,9 @@ class LevelDBTraceTransaction : public TransactionalLevelDBTransaction { ...@@ -235,8 +238,9 @@ class LevelDBTraceTransaction : public TransactionalLevelDBTransaction {
std::unique_ptr<LevelDBScope> scope, std::unique_ptr<LevelDBScope> scope,
int tx_num) int tx_num)
: TransactionalLevelDBTransaction(db, std::move(scope)), : TransactionalLevelDBTransaction(db, std::move(scope)),
commit_tracer_(s_class_name, "Commit", tx_num), class_name_("LevelDBTransaction"),
get_tracer_(s_class_name, "Get", tx_num) {} commit_tracer_(class_name_, "Commit", tx_num),
get_tracer_(class_name_, "Get", tx_num) {}
leveldb::Status Get(const base::StringPiece& key, leveldb::Status Get(const base::StringPiece& key,
std::string* value, std::string* value,
...@@ -251,16 +255,14 @@ class LevelDBTraceTransaction : public TransactionalLevelDBTransaction { ...@@ -251,16 +255,14 @@ class LevelDBTraceTransaction : public TransactionalLevelDBTransaction {
} }
private: private:
static const std::string s_class_name; const std::string class_name_;
~LevelDBTraceTransaction() override {} ~LevelDBTraceTransaction() override = default;
FunctionTracer commit_tracer_; FunctionTracer commit_tracer_;
FunctionTracer get_tracer_; FunctionTracer get_tracer_;
}; };
const std::string LevelDBTraceTransaction::s_class_name = "LevelDBTransaction";
class LevelDBTraceIterator : public TransactionalLevelDBIterator { class LevelDBTraceIterator : public TransactionalLevelDBIterator {
public: public:
LevelDBTraceIterator(std::unique_ptr<leveldb::Iterator> iterator, LevelDBTraceIterator(std::unique_ptr<leveldb::Iterator> iterator,
...@@ -272,17 +274,18 @@ class LevelDBTraceIterator : public TransactionalLevelDBIterator { ...@@ -272,17 +274,18 @@ class LevelDBTraceIterator : public TransactionalLevelDBIterator {
std::move(db), std::move(db),
std::move(txn), std::move(txn),
std::move(snapshot)), std::move(snapshot)),
is_valid_tracer_(s_class_name, "IsValid", inst_num), class_name_("LevelDBIterator"),
seek_to_last_tracer_(s_class_name, "SeekToLast", inst_num), is_valid_tracer_(class_name_, "IsValid", inst_num),
seek_tracer_(s_class_name, "Seek", inst_num), seek_to_last_tracer_(class_name_, "SeekToLast", inst_num),
next_tracer_(s_class_name, "Next", inst_num), seek_tracer_(class_name_, "Seek", inst_num),
prev_tracer_(s_class_name, "Prev", inst_num), next_tracer_(class_name_, "Next", inst_num),
key_tracer_(s_class_name, "Key", inst_num), prev_tracer_(class_name_, "Prev", inst_num),
value_tracer_(s_class_name, "Value", inst_num) {} key_tracer_(class_name_, "Key", inst_num),
~LevelDBTraceIterator() override {} value_tracer_(class_name_, "Value", inst_num) {}
~LevelDBTraceIterator() override = default;
private: private:
static const std::string s_class_name; const std::string class_name_;
bool IsValid() const override { bool IsValid() const override {
is_valid_tracer_.log_call(); is_valid_tracer_.log_call();
...@@ -322,8 +325,6 @@ class LevelDBTraceIterator : public TransactionalLevelDBIterator { ...@@ -322,8 +325,6 @@ class LevelDBTraceIterator : public TransactionalLevelDBIterator {
mutable FunctionTracer value_tracer_; mutable FunctionTracer value_tracer_;
}; };
const std::string LevelDBTraceIterator::s_class_name = "LevelDBIterator";
class LevelDBTestIterator : public content::TransactionalLevelDBIterator { class LevelDBTestIterator : public content::TransactionalLevelDBIterator {
public: public:
LevelDBTestIterator(std::unique_ptr<leveldb::Iterator> iterator, LevelDBTestIterator(std::unique_ptr<leveldb::Iterator> iterator,
...@@ -343,7 +344,7 @@ class LevelDBTestIterator : public content::TransactionalLevelDBIterator { ...@@ -343,7 +344,7 @@ class LevelDBTestIterator : public content::TransactionalLevelDBIterator {
private: private:
leveldb::Status Seek(const base::StringPiece& target) override { leveldb::Status Seek(const base::StringPiece& target) override {
if (fail_method_ != FAIL_METHOD_SEEK || if (fail_method_ != FailMethod::SEEK ||
++current_call_num_ != fail_on_call_num_) ++current_call_num_ != fail_on_call_num_)
return TransactionalLevelDBIterator::Seek(target); return TransactionalLevelDBIterator::Seek(target);
return leveldb::Status::Corruption("Corrupted for test"); return leveldb::Status::Corruption("Corrupted for test");
...@@ -355,11 +356,12 @@ class LevelDBTestIterator : public content::TransactionalLevelDBIterator { ...@@ -355,11 +356,12 @@ class LevelDBTestIterator : public content::TransactionalLevelDBIterator {
}; };
MockBrowserTestIndexedDBClassFactory::MockBrowserTestIndexedDBClassFactory() MockBrowserTestIndexedDBClassFactory::MockBrowserTestIndexedDBClassFactory()
: failure_class_(FAIL_CLASS_NOTHING), : failure_class_(FailClass::NOTHING),
failure_method_(FAIL_METHOD_NOTHING), failure_method_(FailMethod::NOTHING),
only_trace_calls_(false) {} only_trace_calls_(false) {}
MockBrowserTestIndexedDBClassFactory::~MockBrowserTestIndexedDBClassFactory() {} MockBrowserTestIndexedDBClassFactory::~MockBrowserTestIndexedDBClassFactory() =
default;
TransactionalLevelDBFactory& TransactionalLevelDBFactory&
MockBrowserTestIndexedDBClassFactory::transactional_leveldb_factory() { MockBrowserTestIndexedDBClassFactory::transactional_leveldb_factory() {
...@@ -406,15 +408,15 @@ MockBrowserTestIndexedDBClassFactory::CreateLevelDBDatabase( ...@@ -406,15 +408,15 @@ MockBrowserTestIndexedDBClassFactory::CreateLevelDBDatabase(
std::unique_ptr<LevelDBScopes> scopes, std::unique_ptr<LevelDBScopes> scopes,
scoped_refptr<base::SequencedTaskRunner> task_runner, scoped_refptr<base::SequencedTaskRunner> task_runner,
size_t max_open_iterators) { size_t max_open_iterators) {
instance_count_[FAIL_CLASS_LEVELDB_DATABASE] = instance_count_[FailClass::LEVELDB_DATABASE] =
instance_count_[FAIL_CLASS_LEVELDB_DATABASE] + 1; instance_count_[FailClass::LEVELDB_DATABASE] + 1;
if (failure_class_ == FAIL_CLASS_LEVELDB_DATABASE && if (failure_class_ == FailClass::LEVELDB_DATABASE &&
instance_count_[FAIL_CLASS_LEVELDB_DATABASE] == instance_count_[FailClass::LEVELDB_DATABASE] ==
fail_on_instance_num_[FAIL_CLASS_LEVELDB_DATABASE]) { fail_on_instance_num_[FailClass::LEVELDB_DATABASE]) {
return std::make_unique<LevelDBTestDatabase>( return std::make_unique<LevelDBTestDatabase>(
std::move(state), std::move(scopes), this, std::move(task_runner), std::move(state), std::move(scopes), this, std::move(task_runner),
max_open_iterators, failure_method_, max_open_iterators, failure_method_,
fail_on_call_num_[FAIL_CLASS_LEVELDB_DATABASE]); fail_on_call_num_[FailClass::LEVELDB_DATABASE]);
} else { } else {
return DefaultTransactionalLevelDBFactory::CreateLevelDBDatabase( return DefaultTransactionalLevelDBFactory::CreateLevelDBDatabase(
std::move(state), std::move(scopes), std::move(task_runner), std::move(state), std::move(scopes), std::move(task_runner),
...@@ -425,14 +427,14 @@ MockBrowserTestIndexedDBClassFactory::CreateLevelDBDatabase( ...@@ -425,14 +427,14 @@ MockBrowserTestIndexedDBClassFactory::CreateLevelDBDatabase(
std::unique_ptr<LevelDBDirectTransaction> std::unique_ptr<LevelDBDirectTransaction>
MockBrowserTestIndexedDBClassFactory::CreateLevelDBDirectTransaction( MockBrowserTestIndexedDBClassFactory::CreateLevelDBDirectTransaction(
TransactionalLevelDBDatabase* db) { TransactionalLevelDBDatabase* db) {
instance_count_[FAIL_CLASS_LEVELDB_DIRECT_TRANSACTION] = instance_count_[FailClass::LEVELDB_DIRECT_TRANSACTION] =
instance_count_[FAIL_CLASS_LEVELDB_DIRECT_TRANSACTION] + 1; instance_count_[FailClass::LEVELDB_DIRECT_TRANSACTION] + 1;
if (failure_class_ == FAIL_CLASS_LEVELDB_DIRECT_TRANSACTION && if (failure_class_ == FailClass::LEVELDB_DIRECT_TRANSACTION &&
instance_count_[FAIL_CLASS_LEVELDB_DIRECT_TRANSACTION] == instance_count_[FailClass::LEVELDB_DIRECT_TRANSACTION] ==
fail_on_instance_num_[FAIL_CLASS_LEVELDB_DIRECT_TRANSACTION]) { fail_on_instance_num_[FailClass::LEVELDB_DIRECT_TRANSACTION]) {
return std::make_unique<LevelDBTestDirectTransaction>( return std::make_unique<LevelDBTestDirectTransaction>(
db, failure_method_, db, failure_method_,
fail_on_call_num_[FAIL_CLASS_LEVELDB_DIRECT_TRANSACTION]); fail_on_call_num_[FailClass::LEVELDB_DIRECT_TRANSACTION]);
} else { } else {
return DefaultTransactionalLevelDBFactory::CreateLevelDBDirectTransaction( return DefaultTransactionalLevelDBFactory::CreateLevelDBDirectTransaction(
db); db);
...@@ -443,18 +445,18 @@ scoped_refptr<TransactionalLevelDBTransaction> ...@@ -443,18 +445,18 @@ scoped_refptr<TransactionalLevelDBTransaction>
MockBrowserTestIndexedDBClassFactory::CreateLevelDBTransaction( MockBrowserTestIndexedDBClassFactory::CreateLevelDBTransaction(
TransactionalLevelDBDatabase* db, TransactionalLevelDBDatabase* db,
std::unique_ptr<LevelDBScope> scope) { std::unique_ptr<LevelDBScope> scope) {
instance_count_[FAIL_CLASS_LEVELDB_TRANSACTION] = instance_count_[FailClass::LEVELDB_TRANSACTION] =
instance_count_[FAIL_CLASS_LEVELDB_TRANSACTION] + 1; instance_count_[FailClass::LEVELDB_TRANSACTION] + 1;
if (only_trace_calls_) { if (only_trace_calls_) {
return base::MakeRefCounted<LevelDBTraceTransaction>( return base::MakeRefCounted<LevelDBTraceTransaction>(
db, std::move(scope), instance_count_[FAIL_CLASS_LEVELDB_TRANSACTION]); db, std::move(scope), instance_count_[FailClass::LEVELDB_TRANSACTION]);
} else { } else {
if (failure_class_ == FAIL_CLASS_LEVELDB_TRANSACTION && if (failure_class_ == FailClass::LEVELDB_TRANSACTION &&
instance_count_[FAIL_CLASS_LEVELDB_TRANSACTION] == instance_count_[FailClass::LEVELDB_TRANSACTION] ==
fail_on_instance_num_[FAIL_CLASS_LEVELDB_TRANSACTION]) { fail_on_instance_num_[FailClass::LEVELDB_TRANSACTION]) {
return base::MakeRefCounted<LevelDBTestTransaction>( return base::MakeRefCounted<LevelDBTestTransaction>(
db, std::move(scope), failure_method_, db, std::move(scope), failure_method_,
fail_on_call_num_[FAIL_CLASS_LEVELDB_TRANSACTION]); fail_on_call_num_[FailClass::LEVELDB_TRANSACTION]);
} else { } else {
return DefaultTransactionalLevelDBFactory::CreateLevelDBTransaction( return DefaultTransactionalLevelDBFactory::CreateLevelDBTransaction(
db, std::move(scope)); db, std::move(scope));
...@@ -468,19 +470,19 @@ MockBrowserTestIndexedDBClassFactory::CreateIterator( ...@@ -468,19 +470,19 @@ MockBrowserTestIndexedDBClassFactory::CreateIterator(
base::WeakPtr<TransactionalLevelDBDatabase> db, base::WeakPtr<TransactionalLevelDBDatabase> db,
base::WeakPtr<TransactionalLevelDBTransaction> txn, base::WeakPtr<TransactionalLevelDBTransaction> txn,
std::unique_ptr<LevelDBSnapshot> snapshot) { std::unique_ptr<LevelDBSnapshot> snapshot) {
instance_count_[FAIL_CLASS_LEVELDB_ITERATOR] = instance_count_[FailClass::LEVELDB_ITERATOR] =
instance_count_[FAIL_CLASS_LEVELDB_ITERATOR] + 1; instance_count_[FailClass::LEVELDB_ITERATOR] + 1;
if (only_trace_calls_) { if (only_trace_calls_) {
return std::make_unique<LevelDBTraceIterator>( return std::make_unique<LevelDBTraceIterator>(
std::move(iterator), db, std::move(txn), std::move(snapshot), std::move(iterator), db, std::move(txn), std::move(snapshot),
instance_count_[FAIL_CLASS_LEVELDB_ITERATOR]); instance_count_[FailClass::LEVELDB_ITERATOR]);
} else { } else {
if (failure_class_ == FAIL_CLASS_LEVELDB_ITERATOR && if (failure_class_ == FailClass::LEVELDB_ITERATOR &&
instance_count_[FAIL_CLASS_LEVELDB_ITERATOR] == instance_count_[FailClass::LEVELDB_ITERATOR] ==
fail_on_instance_num_[FAIL_CLASS_LEVELDB_ITERATOR]) { fail_on_instance_num_[FailClass::LEVELDB_ITERATOR]) {
return std::make_unique<LevelDBTestIterator>( return std::make_unique<LevelDBTestIterator>(
std::move(iterator), db, std::move(txn), std::move(snapshot), std::move(iterator), db, std::move(txn), std::move(snapshot),
failure_method_, fail_on_call_num_[FAIL_CLASS_LEVELDB_ITERATOR]); failure_method_, fail_on_call_num_[FailClass::LEVELDB_ITERATOR]);
} else { } else {
return DefaultTransactionalLevelDBFactory::CreateIterator( return DefaultTransactionalLevelDBFactory::CreateIterator(
std::move(iterator), db, std::move(txn), std::move(snapshot)); std::move(iterator), db, std::move(txn), std::move(snapshot));
...@@ -489,26 +491,29 @@ MockBrowserTestIndexedDBClassFactory::CreateIterator( ...@@ -489,26 +491,29 @@ MockBrowserTestIndexedDBClassFactory::CreateIterator(
} }
void MockBrowserTestIndexedDBClassFactory::FailOperation( void MockBrowserTestIndexedDBClassFactory::FailOperation(
FailClass failure_class, storage::mojom::FailClass failure_class,
FailMethod failure_method, storage::mojom::FailMethod failure_method,
int fail_on_instance_num, int fail_on_instance_num,
int fail_on_call_num) { int fail_on_call_num,
base::OnceClosure callback) {
VLOG(0) << "FailOperation: class=" << failure_class VLOG(0) << "FailOperation: class=" << failure_class
<< ", method=" << failure_method << ", method=" << failure_method
<< ", instanceNum=" << fail_on_instance_num << ", instanceNum=" << fail_on_instance_num
<< ", callNum=" << fail_on_call_num; << ", callNum=" << fail_on_call_num;
DCHECK(failure_class != FAIL_CLASS_NOTHING); DCHECK(failure_class != FailClass::NOTHING);
DCHECK(failure_method != FAIL_METHOD_NOTHING); DCHECK(failure_method != FailMethod::NOTHING);
failure_class_ = failure_class; failure_class_ = failure_class;
failure_method_ = failure_method; failure_method_ = failure_method;
fail_on_instance_num_[failure_class_] = fail_on_instance_num; fail_on_instance_num_[failure_class_] = fail_on_instance_num;
fail_on_call_num_[failure_class_] = fail_on_call_num; fail_on_call_num_[failure_class_] = fail_on_call_num;
instance_count_.clear(); instance_count_.clear();
std::move(callback).Run();
} }
void MockBrowserTestIndexedDBClassFactory::Reset() { void MockBrowserTestIndexedDBClassFactory::Reset() {
failure_class_ = FAIL_CLASS_NOTHING; failure_class_ = FailClass::NOTHING;
failure_method_ = FAIL_METHOD_NOTHING; failure_method_ = FailMethod::NOTHING;
instance_count_.clear(); instance_count_.clear();
fail_on_instance_num_.clear(); fail_on_instance_num_.clear();
fail_on_call_num_.clear(); fail_on_call_num_.clear();
......
...@@ -13,10 +13,12 @@ ...@@ -13,10 +13,12 @@
#include "components/services/storage/indexed_db/scopes/scopes_lock_manager.h" #include "components/services/storage/indexed_db/scopes/scopes_lock_manager.h"
#include "components/services/storage/indexed_db/transactional_leveldb/transactional_leveldb_factory.h" #include "components/services/storage/indexed_db/transactional_leveldb/transactional_leveldb_factory.h"
#include "components/services/storage/public/mojom/indexed_db_control_test.mojom.h"
#include "content/browser/indexed_db/indexed_db_backing_store.h" #include "content/browser/indexed_db/indexed_db_backing_store.h"
#include "content/browser/indexed_db/indexed_db_class_factory.h" #include "content/browser/indexed_db/indexed_db_class_factory.h"
#include "content/browser/indexed_db/indexed_db_database.h" #include "content/browser/indexed_db/indexed_db_database.h"
#include "content/browser/indexed_db/indexed_db_task_helper.h" #include "content/browser/indexed_db/indexed_db_task_helper.h"
#include "content/common/content_export.h"
#include "third_party/blink/public/common/indexeddb/web_idb_types.h" #include "third_party/blink/public/common/indexeddb/web_idb_types.h"
namespace content { namespace content {
...@@ -30,26 +32,10 @@ class LevelDBSnapshot; ...@@ -30,26 +32,10 @@ class LevelDBSnapshot;
class TransactionalLevelDBTransaction; class TransactionalLevelDBTransaction;
class TransactionalLevelDBDatabase; class TransactionalLevelDBDatabase;
enum FailClass { class CONTENT_EXPORT MockBrowserTestIndexedDBClassFactory
FAIL_CLASS_NOTHING,
FAIL_CLASS_LEVELDB_ITERATOR,
FAIL_CLASS_LEVELDB_DIRECT_TRANSACTION,
FAIL_CLASS_LEVELDB_TRANSACTION,
FAIL_CLASS_LEVELDB_DATABASE,
};
enum FailMethod {
FAIL_METHOD_NOTHING,
FAIL_METHOD_COMMIT,
FAIL_METHOD_COMMIT_DISK_FULL,
FAIL_METHOD_GET,
FAIL_METHOD_SEEK,
FAIL_METHOD_WRITE,
};
class MockBrowserTestIndexedDBClassFactory
: public IndexedDBClassFactory, : public IndexedDBClassFactory,
public DefaultTransactionalLevelDBFactory { public DefaultTransactionalLevelDBFactory,
public storage::mojom::MockFailureInjector {
public: public:
MockBrowserTestIndexedDBClassFactory(); MockBrowserTestIndexedDBClassFactory();
~MockBrowserTestIndexedDBClassFactory() override; ~MockBrowserTestIndexedDBClassFactory() override;
...@@ -90,18 +76,19 @@ class MockBrowserTestIndexedDBClassFactory ...@@ -90,18 +76,19 @@ class MockBrowserTestIndexedDBClassFactory
base::WeakPtr<TransactionalLevelDBTransaction> txn, base::WeakPtr<TransactionalLevelDBTransaction> txn,
std::unique_ptr<LevelDBSnapshot> snapshot) override; std::unique_ptr<LevelDBSnapshot> snapshot) override;
void FailOperation(FailClass failure_class, void FailOperation(storage::mojom::FailClass failure_class,
FailMethod failure_method, storage::mojom::FailMethod failure_method,
int fail_on_instance_num, int fail_on_instance_num,
int fail_on_call_num); int fail_on_call_num,
base::OnceClosure callback) override;
void Reset(); void Reset();
private: private:
FailClass failure_class_; storage::mojom::FailClass failure_class_;
FailMethod failure_method_; storage::mojom::FailMethod failure_method_;
std::map<FailClass, int> instance_count_; std::map<storage::mojom::FailClass, int> instance_count_;
std::map<FailClass, int> fail_on_instance_num_; std::map<storage::mojom::FailClass, int> fail_on_instance_num_;
std::map<FailClass, int> fail_on_call_num_; std::map<storage::mojom::FailClass, int> fail_on_call_num_;
bool only_trace_calls_; bool only_trace_calls_;
}; };
......
...@@ -915,8 +915,6 @@ test("content_browsertests") { ...@@ -915,8 +915,6 @@ test("content_browsertests") {
"../browser/idle/idle_browsertest.cc", "../browser/idle/idle_browsertest.cc",
"../browser/indexed_db/indexed_db_browsertest.cc", "../browser/indexed_db/indexed_db_browsertest.cc",
"../browser/indexed_db/indexed_db_feature_observer_browsertest.cc", "../browser/indexed_db/indexed_db_feature_observer_browsertest.cc",
"../browser/indexed_db/mock_browsertest_indexed_db_class_factory.cc",
"../browser/indexed_db/mock_browsertest_indexed_db_class_factory.h",
"../browser/isolated_origin_browsertest.cc", "../browser/isolated_origin_browsertest.cc",
"../browser/keyboard_lock_browsertest.cc", "../browser/keyboard_lock_browsertest.cc",
"../browser/keyboard_lock_browsertest.h", "../browser/keyboard_lock_browsertest.h",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment