| // Copyright 2023 The ChromiumOS Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "printscanmgr/daemon/printscan_tool.h" | |
| #include <memory> | |
| #include <string> | |
| #include <utility> | |
| #include <base/files/file_path.h> | |
| #include <base/files/file_util.h> | |
| #include <base/files/scoped_temp_dir.h> | |
| #include <base/task/single_thread_task_runner.h> | |
| #include <base/test/task_environment.h> | |
| #include <gmock/gmock.h> | |
| #include <gtest/gtest.h> | |
| #include <mojo/core/embedder/scoped_ipc_support.h> | |
| #include <mojo/public/cpp/bindings/remote.h> | |
| #include <lorgnette/proto_bindings/lorgnette_service.pb.h> | |
| #include <lorgnette-client-test/lorgnette/dbus-proxy-mocks.h> | |
| #include <printscanmgr/proto_bindings/printscanmgr_service.pb.h> | |
| #include "printscanmgr/executor/mock_executor.h" | |
| #include "printscanmgr/mojom/executor.mojom.h" | |
| using ::testing::_; | |
| using ::testing::DoAll; | |
| using ::testing::Invoke; | |
| using ::testing::Return; | |
| using ::testing::StrictMock; | |
| using ::testing::WithArg; | |
| namespace printscanmgr { | |
| namespace { | |
| const char kCupsDebugPath[] = "run/cups/debug/debug-flag"; | |
| const char kIppusbDebugPath[] = "run/ippusb/debug/debug-flag"; | |
| MATCHER_P(EqualsProto, | |
| message, | |
| "Match a proto Message equal to the matcher's argument.") { | |
| std::string expected_serialized, actual_serialized; | |
| message.SerializeToString(&expected_serialized); | |
| arg.SerializeToString(&actual_serialized); | |
| return expected_serialized == actual_serialized; | |
| } | |
| lorgnette::SetDebugConfigRequest ConstructSetDebugConfigRequest(bool enabled) { | |
| lorgnette::SetDebugConfigRequest request; | |
| request.set_enabled(enabled); | |
| return request; | |
| } | |
| } // namespace | |
| class PrintscanToolTest : public testing::Test { | |
| protected: | |
| base::ScopedTempDir temp_dir_; | |
| StrictMock<MockExecutor> mock_executor_; | |
| std::unique_ptr<PrintscanTool> printscan_tool_; | |
| // Owned by `printscan_tool_`. | |
| StrictMock<org::chromium::lorgnette::ManagerProxyMock>* lorgnette_proxy_mock_; | |
| void SetUp() override { | |
| // Initialize IPC support for Mojo. | |
| ipc_support_ = std::make_unique<::mojo::core::ScopedIPCSupport>( | |
| base::SingleThreadTaskRunner:: | |
| GetCurrentDefault() /* io_thread_task_runner */, | |
| ::mojo::core::ScopedIPCSupport::ShutdownPolicy:: | |
| CLEAN /* blocking shutdown */); | |
| // Create directories we expect PrintscanTool to interact with. | |
| ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | |
| ASSERT_TRUE(base::SetPosixFilePermissions(temp_dir_.GetPath(), 0755)); | |
| ASSERT_TRUE( | |
| base::CreateDirectory(temp_dir_.GetPath().Append("run/cups/debug/"))); | |
| ASSERT_TRUE( | |
| base::CreateDirectory(temp_dir_.GetPath().Append("run/ippusb/debug/"))); | |
| // Prepare default responses for the mock Mojo method. | |
| ON_CALL(mock_executor_, RestartUpstartJob(_, _)) | |
| .WillByDefault(WithArg<1>( | |
| Invoke([](mojom::Executor::RestartUpstartJobCallback callback) { | |
| std::move(callback).Run(/*success=*/true, /*errorMsg=*/""); | |
| }))); | |
| auto lorgnette_proxy_mock = std::make_unique< | |
| StrictMock<org::chromium::lorgnette::ManagerProxyMock>>(); | |
| lorgnette_proxy_mock_ = lorgnette_proxy_mock.get(); | |
| // Prepare default responses for the mock D-Bus methods. | |
| ON_CALL(*lorgnette_proxy_mock_, SetDebugConfig(_, _, _, _)) | |
| .WillByDefault(DoAll( | |
| WithArg<1>(Invoke([](lorgnette::SetDebugConfigResponse* response) { | |
| ASSERT_NE(response, nullptr); | |
| response->set_success(true); | |
| })), | |
| Return(true))); | |
| // Initialize PrintscanTool with a fake root for testing. | |
| remote_.Bind(mock_executor_.pending_remote()); | |
| printscan_tool_ = PrintscanTool::CreateAndInitForTesting( | |
| remote_.get(), temp_dir_.GetPath(), std::move(lorgnette_proxy_mock)); | |
| } | |
| private: | |
| base::test::SingleThreadTaskEnvironment task_environment_; | |
| std::unique_ptr<mojo::core::ScopedIPCSupport> ipc_support_; | |
| mojo::Remote<mojom::Executor> remote_; | |
| }; | |
| TEST_F(PrintscanToolTest, SetNoCategories) { | |
| // Test disabling debugging when it is already off. | |
| EXPECT_CALL(mock_executor_, RestartUpstartJob(mojom::UpstartJob::kCupsd, _)); | |
| EXPECT_CALL(*lorgnette_proxy_mock_, | |
| SetDebugConfig(EqualsProto(ConstructSetDebugConfigRequest(false)), | |
| _, _, _)); | |
| PrintscanDebugSetCategoriesRequest request; | |
| auto response = printscan_tool_->DebugSetCategories(request); | |
| EXPECT_TRUE(response.result()); | |
| EXPECT_FALSE(base::PathExists(temp_dir_.GetPath().Append(kCupsDebugPath))); | |
| EXPECT_FALSE(base::PathExists(temp_dir_.GetPath().Append(kIppusbDebugPath))); | |
| } | |
| TEST_F(PrintscanToolTest, SetPrintingCategory) { | |
| // Test starting printing debugging only. | |
| EXPECT_CALL(mock_executor_, RestartUpstartJob(mojom::UpstartJob::kCupsd, _)); | |
| EXPECT_CALL(*lorgnette_proxy_mock_, | |
| SetDebugConfig(EqualsProto(ConstructSetDebugConfigRequest(false)), | |
| _, _, _)); | |
| PrintscanDebugSetCategoriesRequest request; | |
| request.add_categories( | |
| PrintscanDebugSetCategoriesRequest::DEBUG_LOG_CATEGORY_PRINTING); | |
| auto response = printscan_tool_->DebugSetCategories(request); | |
| EXPECT_TRUE(response.result()); | |
| EXPECT_TRUE(base::PathExists(temp_dir_.GetPath().Append(kCupsDebugPath))); | |
| EXPECT_TRUE(base::PathExists(temp_dir_.GetPath().Append(kIppusbDebugPath))); | |
| } | |
| TEST_F(PrintscanToolTest, SetScanningCategory) { | |
| // Test starting scanning debugging only. | |
| EXPECT_CALL(mock_executor_, RestartUpstartJob(mojom::UpstartJob::kCupsd, _)); | |
| EXPECT_CALL(*lorgnette_proxy_mock_, | |
| SetDebugConfig(EqualsProto(ConstructSetDebugConfigRequest(true)), | |
| _, _, _)); | |
| PrintscanDebugSetCategoriesRequest request; | |
| request.add_categories( | |
| PrintscanDebugSetCategoriesRequest::DEBUG_LOG_CATEGORY_SCANNING); | |
| auto response = printscan_tool_->DebugSetCategories(request); | |
| EXPECT_TRUE(response.result()); | |
| EXPECT_FALSE(base::PathExists(temp_dir_.GetPath().Append(kCupsDebugPath))); | |
| EXPECT_TRUE(base::PathExists(temp_dir_.GetPath().Append(kIppusbDebugPath))); | |
| } | |
| TEST_F(PrintscanToolTest, SetAllCategories) { | |
| // Test starting all debugging. | |
| EXPECT_CALL(mock_executor_, RestartUpstartJob(mojom::UpstartJob::kCupsd, _)); | |
| EXPECT_CALL(*lorgnette_proxy_mock_, | |
| SetDebugConfig(EqualsProto(ConstructSetDebugConfigRequest(true)), | |
| _, _, _)); | |
| PrintscanDebugSetCategoriesRequest request; | |
| request.add_categories( | |
| PrintscanDebugSetCategoriesRequest::DEBUG_LOG_CATEGORY_PRINTING); | |
| request.add_categories( | |
| PrintscanDebugSetCategoriesRequest::DEBUG_LOG_CATEGORY_SCANNING); | |
| auto response = printscan_tool_->DebugSetCategories(request); | |
| EXPECT_TRUE(response.result()); | |
| EXPECT_TRUE(base::PathExists(temp_dir_.GetPath().Append(kCupsDebugPath))); | |
| EXPECT_TRUE(base::PathExists(temp_dir_.GetPath().Append(kIppusbDebugPath))); | |
| } | |
| TEST_F(PrintscanToolTest, ResetCategories) { | |
| // Test starting all debugging. | |
| EXPECT_CALL(mock_executor_, RestartUpstartJob(mojom::UpstartJob::kCupsd, _)) | |
| .Times(2); | |
| EXPECT_CALL(*lorgnette_proxy_mock_, | |
| SetDebugConfig(EqualsProto(ConstructSetDebugConfigRequest(true)), | |
| _, _, _)); | |
| EXPECT_CALL(*lorgnette_proxy_mock_, | |
| SetDebugConfig(EqualsProto(ConstructSetDebugConfigRequest(false)), | |
| _, _, _)); | |
| PrintscanDebugSetCategoriesRequest request; | |
| request.add_categories( | |
| PrintscanDebugSetCategoriesRequest::DEBUG_LOG_CATEGORY_PRINTING); | |
| request.add_categories( | |
| PrintscanDebugSetCategoriesRequest::DEBUG_LOG_CATEGORY_SCANNING); | |
| auto response = printscan_tool_->DebugSetCategories(request); | |
| EXPECT_TRUE(response.result()); | |
| EXPECT_TRUE(base::PathExists(temp_dir_.GetPath().Append(kCupsDebugPath))); | |
| EXPECT_TRUE(base::PathExists(temp_dir_.GetPath().Append(kIppusbDebugPath))); | |
| // Test stopping all debugging. | |
| PrintscanDebugSetCategoriesRequest empty_request; | |
| response = printscan_tool_->DebugSetCategories(empty_request); | |
| EXPECT_TRUE(response.result()); | |
| EXPECT_FALSE(base::PathExists(temp_dir_.GetPath().Append(kCupsDebugPath))); | |
| EXPECT_FALSE(base::PathExists(temp_dir_.GetPath().Append(kIppusbDebugPath))); | |
| } | |
| } // namespace printscanmgr |