| // Copyright 2020 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 "components/services/storage/test_api/test_api.h" |
| |
| #include "base/bind.h" |
| #include "base/check.h" |
| #include "base/immediate_crash.h" |
| #include "base/no_destructor.h" |
| #include "base/task/task_traits.h" |
| #include "base/task/thread_pool.h" |
| #include "base/threading/sequenced_task_runner_handle.h" |
| #include "components/services/storage/filesystem_proxy_factory.h" |
| #include "components/services/storage/public/mojom/test_api.test-mojom.h" |
| #include "components/services/storage/test_api_stubs.h" |
| #include "mojo/public/cpp/bindings/receiver_set.h" |
| #include "third_party/leveldatabase/env_chromium.h" |
| #include "third_party/leveldatabase/src/include/leveldb/db.h" |
| |
| namespace storage { |
| |
| namespace { |
| |
| class TestApiDatabaseEnv : public leveldb_env::ChromiumEnv { |
| public: |
| TestApiDatabaseEnv() |
| : ChromiumEnv("ChromiumEnv.TestApi", CreateFilesystemProxy()) {} |
| TestApiDatabaseEnv(const TestApiDatabaseEnv&) = delete; |
| TestApiDatabaseEnv& operator=(const TestApiDatabaseEnv&) = delete; |
| }; |
| |
| TestApiDatabaseEnv* GetTestApiDatabaseEnv() { |
| static base::NoDestructor<TestApiDatabaseEnv> env; |
| return env.get(); |
| } |
| |
| void CreateAndCompactDatabase( |
| const std::string& name, |
| scoped_refptr<base::SequencedTaskRunner> callback_task_runner, |
| mojom::TestApi::ForceLeveldbDatabaseCompactionCallback callback) { |
| leveldb_env::Options options; |
| options.create_if_missing = true; |
| options.env = GetTestApiDatabaseEnv(); |
| std::unique_ptr<leveldb::DB> db; |
| leveldb::Status status = leveldb_env::OpenDB(options, name, &db); |
| CHECK(status.ok()) << status.ToString(); |
| db->CompactRange(nullptr, nullptr); |
| db.reset(); |
| callback_task_runner->PostTask(FROM_HERE, std::move(callback)); |
| } |
| |
| class TestApiImpl : public mojom::TestApi { |
| public: |
| TestApiImpl() = default; |
| ~TestApiImpl() override = default; |
| |
| void AddReceiver(mojo::PendingReceiver<mojom::TestApi> receiver) { |
| receivers_.Add(this, std::move(receiver)); |
| } |
| |
| // mojom::TestApi implementation: |
| void CrashNow() override { IMMEDIATE_CRASH(); } |
| |
| void ForceLeveldbDatabaseCompaction( |
| const std::string& name, |
| ForceLeveldbDatabaseCompactionCallback callback) override { |
| // Note that we post to a SequencedTaskRunner because the task will use Mojo |
| // bindings, and by default Mojo bindings assume there is a current |
| // SequencedTaskRunnerHandle they can use for scheduling. |
| base::ThreadPool::CreateSequencedTaskRunner( |
| {base::MayBlock(), base::WithBaseSyncPrimitives()}) |
| ->PostTask(FROM_HERE, |
| base::BindOnce(&CreateAndCompactDatabase, name, |
| base::SequencedTaskRunnerHandle::Get(), |
| std::move(callback))); |
| } |
| |
| private: |
| mojo::ReceiverSet<mojom::TestApi> receivers_; |
| }; |
| |
| void BindTestApi(mojo::ScopedMessagePipeHandle test_api_receiver) { |
| static base::NoDestructor<TestApiImpl> impl; |
| impl->AddReceiver( |
| mojo::PendingReceiver<mojom::TestApi>(std::move(test_api_receiver))); |
| } |
| |
| } // namespace |
| |
| void InjectTestApiImplementation() { |
| SetTestApiBinderForTesting(base::BindRepeating(&BindTestApi)); |
| } |
| |
| } // namespace storage |