| // 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 "chromeos/components/cdm_factory_daemon/cdm_storage_adapter.h" |
| |
| #include <utility> |
| |
| #include "base/logging.h" |
| #include "base/test/mock_callback.h" |
| #include "base/test/task_environment.h" |
| #include "chromeos/components/cdm_factory_daemon/mojom/cdm_storage.mojom.h" |
| #include "media/mojo/mojom/cdm_storage.mojom.h" |
| #include "media/mojo/mojom/frame_interface_factory.mojom.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| using DaemonStorage = chromeos::cdm::mojom::CdmStorage; |
| using BrowserStorage = media::mojom::CdmStorage; |
| using media::mojom::CdmFile; |
| using testing::_; |
| |
| namespace chromeos { |
| |
| namespace { |
| |
| constexpr char kFakeFilename[] = "filename"; |
| |
| class MockBrowserStorage : public BrowserStorage { |
| public: |
| MockBrowserStorage(mojo::PendingReceiver<BrowserStorage> receiver) { |
| receiver_.Bind(std::move(receiver)); |
| } |
| ~MockBrowserStorage() override = default; |
| |
| MOCK_METHOD(void, Open, (const std::string&, OpenCallback)); |
| |
| mojo::Receiver<BrowserStorage> receiver_{this}; |
| }; |
| |
| class MockCdmFile : public media::mojom::CdmFile { |
| public: |
| MockCdmFile() = default; |
| ~MockCdmFile() override = default; |
| |
| mojo::PendingAssociatedRemote<CdmFile> CreateRemote() { |
| mojo::PendingAssociatedRemote<CdmFile> remote; |
| receiver_.Bind(remote.InitWithNewEndpointAndPassReceiver()); |
| return remote; |
| } |
| |
| MOCK_METHOD(void, Read, (ReadCallback)); |
| MOCK_METHOD(void, Write, (const std::vector<uint8_t>&, WriteCallback)); |
| |
| private: |
| mojo::AssociatedReceiver<CdmFile> receiver_{this}; |
| }; |
| |
| class MockFrameInterfaceFactory : public media::mojom::FrameInterfaceFactory { |
| public: |
| MockFrameInterfaceFactory() = default; |
| ~MockFrameInterfaceFactory() override = default; |
| |
| MOCK_METHOD(void, |
| CreateProvisionFetcher, |
| (mojo::PendingReceiver<media::mojom::ProvisionFetcher>)); |
| MOCK_METHOD(void, CreateCdmStorage, (mojo::PendingReceiver<BrowserStorage>)); |
| MOCK_METHOD(bool, GetCdmOrigin, (url::Origin*)); |
| MOCK_METHOD(void, GetCdmOrigin, (GetCdmOriginCallback)); |
| MOCK_METHOD(void, BindEmbedderReceiver, (mojo::GenericPendingReceiver)); |
| }; |
| |
| } // namespace |
| |
| class CdmStorageAdapterTest : public testing::Test { |
| protected: |
| CdmStorageAdapterTest() { |
| mock_frame_interface_factory_ = |
| std::make_unique<MockFrameInterfaceFactory>(); |
| EXPECT_CALL(*mock_frame_interface_factory_, CreateCdmStorage(_)) |
| .WillOnce([this](mojo::PendingReceiver<BrowserStorage> receiver) { |
| mock_browser_storage_ = |
| std::make_unique<MockBrowserStorage>(std::move(receiver)); |
| }); |
| cdm_storage_adapter_ = std::make_unique<CdmStorageAdapter>( |
| mock_frame_interface_factory_.get(), |
| daemon_storage_mojo_ |
| .BindNewEndpointAndPassDedicatedReceiverForTesting()); |
| task_environment_.RunUntilIdle(); |
| } |
| |
| ~CdmStorageAdapterTest() override = default; |
| |
| std::unique_ptr<MockBrowserStorage> mock_browser_storage_; |
| std::unique_ptr<CdmStorageAdapter> cdm_storage_adapter_; |
| std::unique_ptr<MockFrameInterfaceFactory> mock_frame_interface_factory_; |
| mojo::AssociatedRemote<DaemonStorage> daemon_storage_mojo_; |
| |
| private: |
| base::test::TaskEnvironment task_environment_; |
| }; |
| |
| TEST_F(CdmStorageAdapterTest, Read_Success) { |
| std::vector<uint8_t> expected_data({1, 2, 3}); |
| MockCdmFile mock_file; |
| EXPECT_CALL(*mock_browser_storage_, Open(kFakeFilename, _)) |
| .WillOnce([&mock_file](const std::string& filename, |
| BrowserStorage::OpenCallback callback) { |
| std::move(callback).Run(BrowserStorage::Status::kSuccess, |
| mock_file.CreateRemote()); |
| }); |
| EXPECT_CALL(mock_file, Read(_)) |
| .WillOnce([expected_data](CdmFile::ReadCallback callback) { |
| std::move(callback).Run(CdmFile::Status::kSuccess, expected_data); |
| }); |
| base::MockCallback<DaemonStorage::ReadCallback> callback_mock; |
| EXPECT_CALL(callback_mock, Run(true, expected_data)); |
| daemon_storage_mojo_->Read(kFakeFilename, callback_mock.Get()); |
| base::RunLoop().RunUntilIdle(); |
| } |
| |
| TEST_F(CdmStorageAdapterTest, Read_OpenFailure) { |
| EXPECT_CALL(*mock_browser_storage_, Open(kFakeFilename, _)) |
| .WillOnce([](const std::string& filename, |
| BrowserStorage::OpenCallback callback) { |
| std::move(callback).Run(BrowserStorage::Status::kFailure, |
| mojo::NullAssociatedRemote()); |
| }); |
| base::MockCallback<DaemonStorage::ReadCallback> callback_mock; |
| EXPECT_CALL(callback_mock, Run(false, _)); |
| daemon_storage_mojo_->Read(kFakeFilename, callback_mock.Get()); |
| base::RunLoop().RunUntilIdle(); |
| } |
| |
| TEST_F(CdmStorageAdapterTest, Read_ReadFailure) { |
| MockCdmFile mock_file; |
| EXPECT_CALL(*mock_browser_storage_, Open(kFakeFilename, _)) |
| .WillOnce([&mock_file](const std::string& filename, |
| BrowserStorage::OpenCallback callback) { |
| std::move(callback).Run(BrowserStorage::Status::kSuccess, |
| mock_file.CreateRemote()); |
| }); |
| EXPECT_CALL(mock_file, Read(_)).WillOnce([](CdmFile::ReadCallback callback) { |
| std::move(callback).Run(CdmFile::Status::kFailure, {}); |
| }); |
| base::MockCallback<DaemonStorage::ReadCallback> callback_mock; |
| EXPECT_CALL(callback_mock, Run(false, _)); |
| daemon_storage_mojo_->Read(kFakeFilename, callback_mock.Get()); |
| base::RunLoop().RunUntilIdle(); |
| } |
| |
| TEST_F(CdmStorageAdapterTest, Write_Success) { |
| std::vector<uint8_t> expected_data({1, 2, 3}); |
| MockCdmFile mock_file; |
| EXPECT_CALL(*mock_browser_storage_, Open(kFakeFilename, _)) |
| .WillOnce([&mock_file](const std::string& filename, |
| BrowserStorage::OpenCallback callback) { |
| std::move(callback).Run(BrowserStorage::Status::kSuccess, |
| mock_file.CreateRemote()); |
| }); |
| EXPECT_CALL(mock_file, Write(expected_data, _)) |
| .WillOnce([expected_data](const std::vector<uint8_t>& data, |
| CdmFile::WriteCallback callback) { |
| std::move(callback).Run(CdmFile::Status::kSuccess); |
| }); |
| base::MockCallback<DaemonStorage::WriteCallback> callback_mock; |
| EXPECT_CALL(callback_mock, Run(true)); |
| daemon_storage_mojo_->Write(kFakeFilename, expected_data, |
| callback_mock.Get()); |
| base::RunLoop().RunUntilIdle(); |
| } |
| |
| TEST_F(CdmStorageAdapterTest, Write_OpenFailure) { |
| EXPECT_CALL(*mock_browser_storage_, Open(kFakeFilename, _)) |
| .WillOnce([](const std::string& filename, |
| BrowserStorage::OpenCallback callback) { |
| std::move(callback).Run(BrowserStorage::Status::kFailure, |
| mojo::NullAssociatedRemote()); |
| }); |
| base::MockCallback<DaemonStorage::WriteCallback> callback_mock; |
| EXPECT_CALL(callback_mock, Run(false)); |
| daemon_storage_mojo_->Write(kFakeFilename, std::vector<uint8_t>({1}), |
| callback_mock.Get()); |
| base::RunLoop().RunUntilIdle(); |
| } |
| |
| TEST_F(CdmStorageAdapterTest, Write_WriteFailure) { |
| std::vector<uint8_t> expected_data({1, 2, 3}); |
| MockCdmFile mock_file; |
| EXPECT_CALL(*mock_browser_storage_, Open(kFakeFilename, _)) |
| .WillOnce([&mock_file](const std::string& filename, |
| BrowserStorage::OpenCallback callback) { |
| std::move(callback).Run(BrowserStorage::Status::kSuccess, |
| mock_file.CreateRemote()); |
| }); |
| EXPECT_CALL(mock_file, Write(expected_data, _)) |
| .WillOnce([expected_data](const std::vector<uint8_t>& data, |
| CdmFile::WriteCallback callback) { |
| std::move(callback).Run(CdmFile::Status::kFailure); |
| }); |
| base::MockCallback<DaemonStorage::WriteCallback> callback_mock; |
| EXPECT_CALL(callback_mock, Run(false)); |
| daemon_storage_mojo_->Write(kFakeFilename, expected_data, |
| callback_mock.Get()); |
| base::RunLoop().RunUntilIdle(); |
| } |
| |
| TEST_F(CdmStorageAdapterTest, Exists_Success) { |
| MockCdmFile mock_file; |
| EXPECT_CALL(*mock_browser_storage_, Open(kFakeFilename, _)) |
| .WillOnce([&mock_file](const std::string& filename, |
| BrowserStorage::OpenCallback callback) { |
| std::move(callback).Run(BrowserStorage::Status::kSuccess, |
| mock_file.CreateRemote()); |
| }); |
| EXPECT_CALL(mock_file, Read(_)).WillOnce([](CdmFile::ReadCallback callback) { |
| std::move(callback).Run(CdmFile::Status::kSuccess, |
| std::vector<uint8_t>({1})); |
| }); |
| base::MockCallback<DaemonStorage::ExistsCallback> callback_mock; |
| EXPECT_CALL(callback_mock, Run(true)); |
| daemon_storage_mojo_->Exists(kFakeFilename, callback_mock.Get()); |
| base::RunLoop().RunUntilIdle(); |
| } |
| |
| TEST_F(CdmStorageAdapterTest, Exists_OpenFailure) { |
| EXPECT_CALL(*mock_browser_storage_, Open(kFakeFilename, _)) |
| .WillOnce([](const std::string& filename, |
| BrowserStorage::OpenCallback callback) { |
| std::move(callback).Run(BrowserStorage::Status::kFailure, |
| mojo::NullAssociatedRemote()); |
| }); |
| base::MockCallback<DaemonStorage::ExistsCallback> callback_mock; |
| EXPECT_CALL(callback_mock, Run(false)); |
| daemon_storage_mojo_->Exists(kFakeFilename, callback_mock.Get()); |
| base::RunLoop().RunUntilIdle(); |
| } |
| |
| TEST_F(CdmStorageAdapterTest, Exists_ReadFailure) { |
| MockCdmFile mock_file; |
| EXPECT_CALL(*mock_browser_storage_, Open(kFakeFilename, _)) |
| .WillOnce([&mock_file](const std::string& filename, |
| BrowserStorage::OpenCallback callback) { |
| std::move(callback).Run(BrowserStorage::Status::kSuccess, |
| mock_file.CreateRemote()); |
| }); |
| EXPECT_CALL(mock_file, Read(_)).WillOnce([](CdmFile::ReadCallback callback) { |
| std::move(callback).Run(CdmFile::Status::kFailure, {}); |
| }); |
| base::MockCallback<DaemonStorage::ExistsCallback> callback_mock; |
| EXPECT_CALL(callback_mock, Run(false)); |
| daemon_storage_mojo_->Exists(kFakeFilename, callback_mock.Get()); |
| base::RunLoop().RunUntilIdle(); |
| } |
| |
| TEST_F(CdmStorageAdapterTest, Exists_EmptyFile) { |
| MockCdmFile mock_file; |
| EXPECT_CALL(*mock_browser_storage_, Open(kFakeFilename, _)) |
| .WillOnce([&mock_file](const std::string& filename, |
| BrowserStorage::OpenCallback callback) { |
| std::move(callback).Run(BrowserStorage::Status::kSuccess, |
| mock_file.CreateRemote()); |
| }); |
| EXPECT_CALL(mock_file, Read(_)).WillOnce([](CdmFile::ReadCallback callback) { |
| std::move(callback).Run(CdmFile::Status::kSuccess, {}); |
| }); |
| base::MockCallback<DaemonStorage::ExistsCallback> callback_mock; |
| EXPECT_CALL(callback_mock, Run(false)); |
| daemon_storage_mojo_->Exists(kFakeFilename, callback_mock.Get()); |
| base::RunLoop().RunUntilIdle(); |
| } |
| |
| TEST_F(CdmStorageAdapterTest, GetSize_Success) { |
| constexpr size_t kFakeSize = 42; |
| MockCdmFile mock_file; |
| EXPECT_CALL(*mock_browser_storage_, Open(kFakeFilename, _)) |
| .WillOnce([&mock_file](const std::string& filename, |
| BrowserStorage::OpenCallback callback) { |
| std::move(callback).Run(BrowserStorage::Status::kSuccess, |
| mock_file.CreateRemote()); |
| }); |
| EXPECT_CALL(mock_file, Read(_)).WillOnce([](CdmFile::ReadCallback callback) { |
| std::move(callback).Run(CdmFile::Status::kSuccess, |
| std::vector<uint8_t>(kFakeSize)); |
| }); |
| base::MockCallback<DaemonStorage::GetSizeCallback> callback_mock; |
| EXPECT_CALL(callback_mock, Run(true, kFakeSize)); |
| daemon_storage_mojo_->GetSize(kFakeFilename, callback_mock.Get()); |
| base::RunLoop().RunUntilIdle(); |
| } |
| |
| TEST_F(CdmStorageAdapterTest, GetSize_OpenFailure) { |
| EXPECT_CALL(*mock_browser_storage_, Open(kFakeFilename, _)) |
| .WillOnce([](const std::string& filename, |
| BrowserStorage::OpenCallback callback) { |
| std::move(callback).Run(BrowserStorage::Status::kFailure, |
| mojo::NullAssociatedRemote()); |
| }); |
| base::MockCallback<DaemonStorage::GetSizeCallback> callback_mock; |
| EXPECT_CALL(callback_mock, Run(false, _)); |
| daemon_storage_mojo_->GetSize(kFakeFilename, callback_mock.Get()); |
| base::RunLoop().RunUntilIdle(); |
| } |
| |
| TEST_F(CdmStorageAdapterTest, GetSize_ReadFailure) { |
| MockCdmFile mock_file; |
| EXPECT_CALL(*mock_browser_storage_, Open(kFakeFilename, _)) |
| .WillOnce([&mock_file](const std::string& filename, |
| BrowserStorage::OpenCallback callback) { |
| std::move(callback).Run(BrowserStorage::Status::kSuccess, |
| mock_file.CreateRemote()); |
| }); |
| EXPECT_CALL(mock_file, Read(_)).WillOnce([](CdmFile::ReadCallback callback) { |
| std::move(callback).Run(CdmFile::Status::kFailure, {}); |
| }); |
| base::MockCallback<DaemonStorage::GetSizeCallback> callback_mock; |
| EXPECT_CALL(callback_mock, Run(false, _)); |
| daemon_storage_mojo_->GetSize(kFakeFilename, callback_mock.Get()); |
| base::RunLoop().RunUntilIdle(); |
| } |
| |
| TEST_F(CdmStorageAdapterTest, Remove_Success) { |
| MockCdmFile mock_file; |
| EXPECT_CALL(*mock_browser_storage_, Open(kFakeFilename, _)) |
| .WillOnce([&mock_file](const std::string& filename, |
| BrowserStorage::OpenCallback callback) { |
| std::move(callback).Run(BrowserStorage::Status::kSuccess, |
| mock_file.CreateRemote()); |
| }); |
| EXPECT_CALL(mock_file, Write(std::vector<uint8_t>(), _)) |
| .WillOnce([](const std::vector<uint8_t>& data, |
| CdmFile::WriteCallback callback) { |
| std::move(callback).Run(CdmFile::Status::kSuccess); |
| }); |
| base::MockCallback<DaemonStorage::RemoveCallback> callback_mock; |
| EXPECT_CALL(callback_mock, Run(true)); |
| daemon_storage_mojo_->Remove(kFakeFilename, callback_mock.Get()); |
| base::RunLoop().RunUntilIdle(); |
| } |
| |
| TEST_F(CdmStorageAdapterTest, Remove_OpenFailure) { |
| EXPECT_CALL(*mock_browser_storage_, Open(kFakeFilename, _)) |
| .WillOnce([](const std::string& filename, |
| BrowserStorage::OpenCallback callback) { |
| std::move(callback).Run(BrowserStorage::Status::kFailure, |
| mojo::NullAssociatedRemote()); |
| }); |
| base::MockCallback<DaemonStorage::RemoveCallback> callback_mock; |
| EXPECT_CALL(callback_mock, Run(false)); |
| daemon_storage_mojo_->Remove(kFakeFilename, callback_mock.Get()); |
| base::RunLoop().RunUntilIdle(); |
| } |
| |
| TEST_F(CdmStorageAdapterTest, Remove_WriteFailure) { |
| MockCdmFile mock_file; |
| EXPECT_CALL(*mock_browser_storage_, Open(kFakeFilename, _)) |
| .WillOnce([&mock_file](const std::string& filename, |
| BrowserStorage::OpenCallback callback) { |
| std::move(callback).Run(BrowserStorage::Status::kSuccess, |
| mock_file.CreateRemote()); |
| }); |
| EXPECT_CALL(mock_file, Write(std::vector<uint8_t>(), _)) |
| .WillOnce([](const std::vector<uint8_t>& data, |
| CdmFile::WriteCallback callback) { |
| std::move(callback).Run(CdmFile::Status::kFailure); |
| }); |
| base::MockCallback<DaemonStorage::RemoveCallback> callback_mock; |
| EXPECT_CALL(callback_mock, Run(false)); |
| daemon_storage_mojo_->Remove(kFakeFilename, callback_mock.Get()); |
| base::RunLoop().RunUntilIdle(); |
| } |
| |
| } // namespace chromeos |