blob: da93a74e2390956a8aa185bd7d6b3fc11e64ed96 [file] [log] [blame] [edit]
// 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