blob: 9cb1aa885453068c2ccde8c7e258f13beb8808e3 [file] [log] [blame]
// Copyright 2021 The Chromium OS 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 <memory>
#include <string>
#include <utility>
#include <vector>
#include <base/bind.h>
#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <base/memory/scoped_refptr.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "rmad/metrics/mock_metrics_utils.h"
#include "rmad/rmad_interface_impl.h"
#include "rmad/state_handler/mock_state_handler.h"
#include "rmad/state_handler/state_handler_manager.h"
#include "rmad/system/mock_power_manager_client.h"
#include "rmad/system/mock_runtime_probe_client.h"
#include "rmad/system/mock_shill_client.h"
#include "rmad/system/mock_tpm_manager_client.h"
#include "rmad/utils/json_store.h"
#include "rmad/utils/mock_cmd_utils.h"
using testing::_;
using testing::Assign;
using testing::DoAll;
using testing::NiceMock;
using testing::Return;
using testing::ReturnRef;
using testing::SetArgPointee;
namespace rmad {
constexpr char kJsonStoreFileName[] = "json_store_file";
constexpr char kCurrentStateSetJson[] = R"({"state_history": [ 1 ]})";
constexpr char kCurrentStateNotSetJson[] = "{}";
constexpr char kCurrentStateInvalidStateJson[] = R"("state_history": [0])";
constexpr char kCurrentStateWithRepeatableHistoryJson[] =
R"({"state_history": [ 1, 2 ]})";
constexpr char kCurrentStateWithUnrepeatableHistoryJson[] =
R"({"state_history": [ 1, 2, 3 ]})";
constexpr char kCurrentStateWithUnsupportedStateJson[] =
R"({"state_history": [ 1, 2, 4 ]})";
constexpr char kInitializeCurrentStateFailJson[] =
R"({"state_history": [ 1 ]})";
constexpr char kInitializeNextStateFailJson[] =
R"({"state_history": [ 1, 2 ]})";
constexpr char kInitializePreviousStateFailJson[] =
R"({"state_history": [ 1, 2 ]})";
constexpr char kInvalidJson[] = R"(alfkjklsfsgdkjnbknd^^)";
class RmadInterfaceImplTest : public testing::Test {
public:
RmadInterfaceImplTest() {
welcome_proto_.set_allocated_welcome(new WelcomeState());
components_repair_proto_.set_allocated_components_repair(
new ComponentsRepairState());
device_destination_proto_.set_allocated_device_destination(
new DeviceDestinationState());
}
base::FilePath CreateInputFile(std::string filename,
const char* str,
int size) {
base::FilePath file_path = temp_dir_.GetPath().AppendASCII(filename);
base::WriteFile(file_path, str, size);
return file_path;
}
scoped_refptr<BaseStateHandler> CreateMockHandler(
scoped_refptr<JsonStore> json_store,
const RmadState& state,
bool is_repeatable,
RmadErrorCode initialize_error,
RmadState::StateCase next_state) {
auto mock_handler =
base::MakeRefCounted<NiceMock<MockStateHandler>>(json_store);
RmadState::StateCase state_case = state.state_case();
ON_CALL(*mock_handler, GetStateCase()).WillByDefault(Return(state_case));
ON_CALL(*mock_handler, GetState(_)).WillByDefault(ReturnRef(state));
ON_CALL(*mock_handler, IsRepeatable()).WillByDefault(Return(is_repeatable));
ON_CALL(*mock_handler, InitializeState())
.WillByDefault(Return(initialize_error));
ON_CALL(*mock_handler, GetNextStateCase(_))
.WillByDefault(Return(BaseStateHandler::GetNextStateCaseReply{
.error = RMAD_ERROR_OK, .state_case = next_state}));
return mock_handler;
}
std::unique_ptr<StateHandlerManager> CreateStateHandlerManagerWithHandlers(
scoped_refptr<JsonStore> json_store,
std::vector<scoped_refptr<BaseStateHandler>> mock_handlers) {
auto state_handler_manager =
std::make_unique<StateHandlerManager>(json_store);
// TODO(gavindodd): Work out how to create RmadState objects and have them
// scoped to the test.
for (auto mock_handler : mock_handlers) {
state_handler_manager->RegisterStateHandler(mock_handler);
}
return state_handler_manager;
}
std::unique_ptr<StateHandlerManager> CreateStateHandlerManager(
scoped_refptr<JsonStore> json_store) {
// TODO(gavindodd): Work out how to create RmadState objects and have them
// scoped to the test.
std::vector<scoped_refptr<BaseStateHandler>> mock_handlers;
mock_handlers.push_back(CreateMockHandler(json_store, welcome_proto_, true,
RMAD_ERROR_OK,
RmadState::kComponentsRepair));
mock_handlers.push_back(
CreateMockHandler(json_store, components_repair_proto_, true,
RMAD_ERROR_OK, RmadState::kDeviceDestination));
mock_handlers.push_back(
CreateMockHandler(json_store, device_destination_proto_, false,
RMAD_ERROR_OK, RmadState::kWpDisableMethod));
return CreateStateHandlerManagerWithHandlers(json_store, mock_handlers);
}
std::unique_ptr<StateHandlerManager> CreateStateHandlerManagerMissingHandler(
scoped_refptr<JsonStore> json_store) {
// TODO(gavindodd): Work out how to create RmadState objects and have them
// scoped to the test.
std::vector<scoped_refptr<BaseStateHandler>> mock_handlers;
mock_handlers.push_back(CreateMockHandler(json_store, welcome_proto_, true,
RMAD_ERROR_OK,
RmadState::kComponentsRepair));
return CreateStateHandlerManagerWithHandlers(json_store, mock_handlers);
}
std::unique_ptr<StateHandlerManager>
CreateStateHandlerManagerInitializeStateFail(
scoped_refptr<JsonStore> json_store) {
std::vector<scoped_refptr<BaseStateHandler>> mock_handlers;
mock_handlers.push_back(CreateMockHandler(json_store, welcome_proto_, true,
RMAD_ERROR_MISSING_COMPONENT,
RmadState::kComponentsRepair));
mock_handlers.push_back(
CreateMockHandler(json_store, components_repair_proto_, true,
RMAD_ERROR_OK, RmadState::kDeviceDestination));
mock_handlers.push_back(CreateMockHandler(
json_store, device_destination_proto_, false,
RMAD_ERROR_DEVICE_INFO_INVALID, RmadState::kWpDisableMethod));
return CreateStateHandlerManagerWithHandlers(json_store, mock_handlers);
}
std::unique_ptr<RuntimeProbeClient> CreateRuntimeProbeClient(
bool has_cellular) {
auto mock_runtime_probe_client =
std::make_unique<NiceMock<MockRuntimeProbeClient>>();
ComponentsWithIdentifier components;
if (has_cellular) {
components.push_back(std::make_pair(RMAD_COMPONENT_CELLULAR, ""));
}
ON_CALL(*mock_runtime_probe_client, ProbeCategories(_, _))
.WillByDefault(DoAll(SetArgPointee<1>(components), Return(true)));
return mock_runtime_probe_client;
}
std::unique_ptr<ShillClient> CreateShillClient(bool* cellular_disabled) {
auto mock_shill_client = std::make_unique<NiceMock<MockShillClient>>();
if (cellular_disabled) {
ON_CALL(*mock_shill_client, DisableCellular())
.WillByDefault(DoAll(Assign(cellular_disabled, true), Return(true)));
} else {
ON_CALL(*mock_shill_client, DisableCellular())
.WillByDefault(Return(true));
}
return mock_shill_client;
}
std::unique_ptr<TpmManagerClient> CreateTpmManagerClient(
RoVerificationStatus ro_verification_status) {
auto mock_tpm_manager_client =
std::make_unique<NiceMock<MockTpmManagerClient>>();
ON_CALL(*mock_tpm_manager_client, GetRoVerificationStatus(_))
.WillByDefault(
DoAll(SetArgPointee<0>(ro_verification_status), Return(true)));
return mock_tpm_manager_client;
}
std::unique_ptr<PowerManagerClient> CreatePowerManagerClient() {
return std::make_unique<NiceMock<MockPowerManagerClient>>();
}
std::unique_ptr<CmdUtils> CreateCmdUtils() {
auto mock_cmd_utils = std::make_unique<NiceMock<MockCmdUtils>>();
ON_CALL(*mock_cmd_utils,
GetOutput(std::vector<std::string>(
{"/usr/sbin/croslog", "--identifier=rmad"}),
_))
.WillByDefault(DoAll(SetArgPointee<1>("fake_log"), Return(true)));
ON_CALL(*mock_cmd_utils,
GetOutput(std::vector<std::string>(
{"/sbin/initctl", "status", "system-services"}),
_))
.WillByDefault(DoAll(SetArgPointee<1>("running"), Return(true)));
return mock_cmd_utils;
}
std::unique_ptr<MetricsUtils> CreateMetricsUtils(bool success) {
auto mock_metrics_utils = std::make_unique<NiceMock<MockMetricsUtils>>();
ON_CALL(*mock_metrics_utils, Record(_, _)).WillByDefault(Return(success));
return mock_metrics_utils;
}
protected:
void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); }
RmadState welcome_proto_;
RmadState components_repair_proto_;
RmadState device_destination_proto_;
base::ScopedTempDir temp_dir_;
};
TEST_F(RmadInterfaceImplTest, GetCurrentState_Set_HasCellular) {
base::FilePath json_store_file_path =
CreateInputFile(kJsonStoreFileName, kCurrentStateSetJson,
std::size(kCurrentStateSetJson) - 1);
auto json_store = base::MakeRefCounted<JsonStore>(json_store_file_path);
bool cellular_disabled = false;
RmadInterfaceImpl rmad_interface(
json_store, CreateStateHandlerManager(json_store),
CreateRuntimeProbeClient(true), CreateShillClient(&cellular_disabled),
CreateTpmManagerClient(RoVerificationStatus::NOT_TRIGGERED),
CreatePowerManagerClient(), CreateCmdUtils(), CreateMetricsUtils(true));
EXPECT_TRUE(rmad_interface.SetUp());
EXPECT_TRUE(cellular_disabled);
auto callback = [](const GetStateReply& reply) {
EXPECT_EQ(RMAD_ERROR_OK, reply.error());
EXPECT_EQ(RmadState::kWelcome, reply.state().state_case());
EXPECT_EQ(false, reply.can_go_back());
EXPECT_EQ(true, reply.can_abort());
};
rmad_interface.GetCurrentState(base::BindOnce(callback));
}
TEST_F(RmadInterfaceImplTest, GetCurrentState_Set_NoCellular) {
base::FilePath json_store_file_path =
CreateInputFile(kJsonStoreFileName, kCurrentStateSetJson,
std::size(kCurrentStateSetJson) - 1);
auto json_store = base::MakeRefCounted<JsonStore>(json_store_file_path);
bool cellular_disabled = false;
RmadInterfaceImpl rmad_interface(
json_store, CreateStateHandlerManager(json_store),
CreateRuntimeProbeClient(false), CreateShillClient(&cellular_disabled),
CreateTpmManagerClient(RoVerificationStatus::NOT_TRIGGERED),
CreatePowerManagerClient(), CreateCmdUtils(), CreateMetricsUtils(true));
EXPECT_TRUE(rmad_interface.SetUp());
EXPECT_FALSE(cellular_disabled);
auto callback = [](const GetStateReply& reply) {
EXPECT_EQ(RMAD_ERROR_OK, reply.error());
EXPECT_EQ(RmadState::kWelcome, reply.state().state_case());
EXPECT_EQ(false, reply.can_go_back());
EXPECT_EQ(true, reply.can_abort());
};
rmad_interface.GetCurrentState(base::BindOnce(callback));
}
TEST_F(RmadInterfaceImplTest,
GetCurrentState_NotInRma_RoVerificationNotTriggered) {
base::FilePath json_store_file_path =
temp_dir_.GetPath().AppendASCII("missing.json");
auto json_store = base::MakeRefCounted<JsonStore>(json_store_file_path);
bool cellular_disabled = false;
RmadInterfaceImpl rmad_interface(
json_store, CreateStateHandlerManager(json_store),
CreateRuntimeProbeClient(false), CreateShillClient(&cellular_disabled),
CreateTpmManagerClient(RoVerificationStatus::NOT_TRIGGERED),
CreatePowerManagerClient(), CreateCmdUtils(), CreateMetricsUtils(true));
EXPECT_TRUE(rmad_interface.SetUp());
EXPECT_FALSE(cellular_disabled);
auto callback = [](const GetStateReply& reply) {
EXPECT_EQ(RMAD_ERROR_RMA_NOT_REQUIRED, reply.error());
EXPECT_EQ(RmadState::STATE_NOT_SET, reply.state().state_case());
};
rmad_interface.GetCurrentState(base::BindOnce(callback));
}
TEST_F(RmadInterfaceImplTest, GetCurrentState_NotInRma_RoVerificationPass) {
base::FilePath json_store_file_path =
temp_dir_.GetPath().AppendASCII("missing.json");
auto json_store = base::MakeRefCounted<JsonStore>(json_store_file_path);
RmadInterfaceImpl rmad_interface(
json_store, CreateStateHandlerManager(json_store),
CreateRuntimeProbeClient(false), CreateShillClient(nullptr),
CreateTpmManagerClient(RoVerificationStatus::PASS),
CreatePowerManagerClient(), CreateCmdUtils(), CreateMetricsUtils(true));
EXPECT_TRUE(rmad_interface.SetUp());
auto callback = [](const GetStateReply& reply) {
EXPECT_EQ(RMAD_ERROR_OK, reply.error());
EXPECT_EQ(RmadState::kWelcome, reply.state().state_case());
EXPECT_EQ(false, reply.can_go_back());
EXPECT_EQ(true, reply.can_abort());
};
rmad_interface.GetCurrentState(base::BindOnce(callback));
}
TEST_F(RmadInterfaceImplTest,
GetCurrentState_NotInRma_RoVerificationUnsupportedTriggered) {
base::FilePath json_store_file_path =
temp_dir_.GetPath().AppendASCII("missing.json");
auto json_store = base::MakeRefCounted<JsonStore>(json_store_file_path);
RmadInterfaceImpl rmad_interface(
json_store, CreateStateHandlerManager(json_store),
CreateRuntimeProbeClient(false), CreateShillClient(nullptr),
CreateTpmManagerClient(RoVerificationStatus::UNSUPPORTED_TRIGGERED),
CreatePowerManagerClient(), CreateCmdUtils(), CreateMetricsUtils(true));
EXPECT_TRUE(rmad_interface.SetUp());
auto callback = [](const GetStateReply& reply) {
EXPECT_EQ(RMAD_ERROR_OK, reply.error());
EXPECT_EQ(RmadState::kWelcome, reply.state().state_case());
EXPECT_EQ(false, reply.can_go_back());
EXPECT_EQ(true, reply.can_abort());
};
rmad_interface.GetCurrentState(base::BindOnce(callback));
}
TEST_F(RmadInterfaceImplTest, GetCurrentState_CorruptedFile) {
base::FilePath json_store_file_path =
CreateInputFile(kJsonStoreFileName, "", 0);
// Make the file read-only.
base::SetPosixFilePermissions(json_store_file_path, 0444);
auto json_store = base::MakeRefCounted<JsonStore>(json_store_file_path);
RmadInterfaceImpl rmad_interface(
json_store, CreateStateHandlerManager(json_store),
CreateRuntimeProbeClient(false), CreateShillClient(nullptr),
CreateTpmManagerClient(RoVerificationStatus::NOT_TRIGGERED),
CreatePowerManagerClient(), CreateCmdUtils(), CreateMetricsUtils(true));
EXPECT_FALSE(rmad_interface.SetUp());
}
TEST_F(RmadInterfaceImplTest, GetCurrentState_EmptyFile) {
base::FilePath json_store_file_path =
CreateInputFile(kJsonStoreFileName, "", 0);
auto json_store = base::MakeRefCounted<JsonStore>(json_store_file_path);
RmadInterfaceImpl rmad_interface(
json_store, CreateStateHandlerManager(json_store),
CreateRuntimeProbeClient(false), CreateShillClient(nullptr),
CreateTpmManagerClient(RoVerificationStatus::NOT_TRIGGERED),
CreatePowerManagerClient(), CreateCmdUtils(), CreateMetricsUtils(true));
EXPECT_TRUE(rmad_interface.SetUp());
auto callback = [](const GetStateReply& reply) {
EXPECT_EQ(RMAD_ERROR_OK, reply.error());
EXPECT_EQ(RmadState::kWelcome, reply.state().state_case());
EXPECT_EQ(false, reply.can_go_back());
EXPECT_EQ(true, reply.can_abort());
};
rmad_interface.GetCurrentState(base::BindOnce(callback));
}
TEST_F(RmadInterfaceImplTest, GetCurrentState_NotSet) {
base::FilePath json_store_file_path =
CreateInputFile(kJsonStoreFileName, kCurrentStateNotSetJson,
std::size(kCurrentStateNotSetJson) - 1);
auto json_store = base::MakeRefCounted<JsonStore>(json_store_file_path);
RmadInterfaceImpl rmad_interface(
json_store, CreateStateHandlerManager(json_store),
CreateRuntimeProbeClient(false), CreateShillClient(nullptr),
CreateTpmManagerClient(RoVerificationStatus::NOT_TRIGGERED),
CreatePowerManagerClient(), CreateCmdUtils(), CreateMetricsUtils(true));
EXPECT_TRUE(rmad_interface.SetUp());
auto callback = [](const GetStateReply& reply) {
EXPECT_EQ(RMAD_ERROR_OK, reply.error());
EXPECT_EQ(RmadState::kWelcome, reply.state().state_case());
EXPECT_EQ(false, reply.can_go_back());
EXPECT_EQ(true, reply.can_abort());
};
rmad_interface.GetCurrentState(base::BindOnce(callback));
}
TEST_F(RmadInterfaceImplTest, GetCurrentState_WithHistory) {
base::FilePath json_store_file_path = CreateInputFile(
kJsonStoreFileName, kCurrentStateWithRepeatableHistoryJson,
std::size(kCurrentStateWithRepeatableHistoryJson) - 1);
auto json_store = base::MakeRefCounted<JsonStore>(json_store_file_path);
RmadInterfaceImpl rmad_interface(
json_store, CreateStateHandlerManager(json_store),
CreateRuntimeProbeClient(false), CreateShillClient(nullptr),
CreateTpmManagerClient(RoVerificationStatus::NOT_TRIGGERED),
CreatePowerManagerClient(), CreateCmdUtils(), CreateMetricsUtils(true));
EXPECT_TRUE(rmad_interface.SetUp());
auto callback = [](const GetStateReply& reply) {
EXPECT_EQ(RMAD_ERROR_OK, reply.error());
EXPECT_EQ(RmadState::kComponentsRepair, reply.state().state_case());
EXPECT_EQ(true, reply.can_go_back());
EXPECT_EQ(true, reply.can_abort());
};
rmad_interface.GetCurrentState(base::BindOnce(callback));
}
TEST_F(RmadInterfaceImplTest, GetCurrentState_WithUnsupportedState) {
base::FilePath json_store_file_path =
CreateInputFile(kJsonStoreFileName, kCurrentStateWithUnsupportedStateJson,
std::size(kCurrentStateWithUnsupportedStateJson) - 1);
auto json_store = base::MakeRefCounted<JsonStore>(json_store_file_path);
RmadInterfaceImpl rmad_interface(
json_store, CreateStateHandlerManager(json_store),
CreateRuntimeProbeClient(false), CreateShillClient(nullptr),
CreateTpmManagerClient(RoVerificationStatus::NOT_TRIGGERED),
CreatePowerManagerClient(), CreateCmdUtils(), CreateMetricsUtils(true));
EXPECT_TRUE(rmad_interface.SetUp());
auto callback = [](const GetStateReply& reply) {
EXPECT_EQ(RMAD_ERROR_OK, reply.error());
EXPECT_EQ(RmadState::kComponentsRepair, reply.state().state_case());
EXPECT_EQ(true, reply.can_go_back());
EXPECT_EQ(true, reply.can_abort());
};
// TODO(gavindodd): Use mock log to check for expected error.
rmad_interface.GetCurrentState(base::BindOnce(callback));
}
TEST_F(RmadInterfaceImplTest, GetCurrentState_InvalidState) {
base::FilePath json_store_file_path =
CreateInputFile(kJsonStoreFileName, kCurrentStateInvalidStateJson,
std::size(kCurrentStateInvalidStateJson) - 1);
auto json_store = base::MakeRefCounted<JsonStore>(json_store_file_path);
RmadInterfaceImpl rmad_interface(
json_store, CreateStateHandlerManager(json_store),
CreateRuntimeProbeClient(false), CreateShillClient(nullptr),
CreateTpmManagerClient(RoVerificationStatus::NOT_TRIGGERED),
CreatePowerManagerClient(), CreateCmdUtils(), CreateMetricsUtils(true));
EXPECT_TRUE(rmad_interface.SetUp());
auto callback = [](const GetStateReply& reply) {
EXPECT_EQ(RMAD_ERROR_OK, reply.error());
EXPECT_EQ(RmadState::kWelcome, reply.state().state_case());
EXPECT_EQ(false, reply.can_go_back());
EXPECT_EQ(true, reply.can_abort());
};
rmad_interface.GetCurrentState(base::BindOnce(callback));
}
TEST_F(RmadInterfaceImplTest, GetCurrentState_InvalidJson) {
base::FilePath json_store_file_path = CreateInputFile(
kJsonStoreFileName, kInvalidJson, std::size(kInvalidJson) - 1);
auto json_store = base::MakeRefCounted<JsonStore>(json_store_file_path);
RmadInterfaceImpl rmad_interface(
json_store, CreateStateHandlerManager(json_store),
CreateRuntimeProbeClient(false), CreateShillClient(nullptr),
CreateTpmManagerClient(RoVerificationStatus::NOT_TRIGGERED),
CreatePowerManagerClient(), CreateCmdUtils(), CreateMetricsUtils(true));
EXPECT_TRUE(rmad_interface.SetUp());
auto callback = [](const GetStateReply& reply) {
EXPECT_EQ(RMAD_ERROR_OK, reply.error());
EXPECT_EQ(RmadState::kWelcome, reply.state().state_case());
EXPECT_EQ(false, reply.can_go_back());
EXPECT_EQ(true, reply.can_abort());
};
rmad_interface.GetCurrentState(base::BindOnce(callback));
}
TEST_F(RmadInterfaceImplTest, GetCurrentState_InitializeStateFail) {
base::FilePath json_store_file_path =
CreateInputFile(kJsonStoreFileName, kInitializeCurrentStateFailJson,
std::size(kInitializeCurrentStateFailJson) - 1);
auto json_store = base::MakeRefCounted<JsonStore>(json_store_file_path);
RmadInterfaceImpl rmad_interface(
json_store, CreateStateHandlerManagerInitializeStateFail(json_store),
CreateRuntimeProbeClient(false), CreateShillClient(nullptr),
CreateTpmManagerClient(RoVerificationStatus::NOT_TRIGGERED),
CreatePowerManagerClient(), CreateCmdUtils(), CreateMetricsUtils(true));
EXPECT_TRUE(rmad_interface.SetUp());
auto callback = [](const GetStateReply& reply) {
EXPECT_EQ(RMAD_ERROR_MISSING_COMPONENT, reply.error());
EXPECT_EQ(RmadState::STATE_NOT_SET, reply.state().state_case());
};
rmad_interface.GetCurrentState(base::BindOnce(callback));
}
TEST_F(RmadInterfaceImplTest, TransitionNextState) {
base::FilePath json_store_file_path =
CreateInputFile(kJsonStoreFileName, kCurrentStateSetJson,
std::size(kCurrentStateSetJson) - 1);
auto json_store = base::MakeRefCounted<JsonStore>(json_store_file_path);
RmadInterfaceImpl rmad_interface(
json_store, CreateStateHandlerManager(json_store),
CreateRuntimeProbeClient(false), CreateShillClient(nullptr),
CreateTpmManagerClient(RoVerificationStatus::NOT_TRIGGERED),
CreatePowerManagerClient(), CreateCmdUtils(), CreateMetricsUtils(true));
EXPECT_TRUE(rmad_interface.SetUp());
EXPECT_EQ(true, rmad_interface.CanAbort());
TransitionNextStateRequest request;
auto callback1 = [](const GetStateReply& reply) {
EXPECT_EQ(RMAD_ERROR_OK, reply.error());
EXPECT_EQ(RmadState::kComponentsRepair, reply.state().state_case());
EXPECT_EQ(true, reply.can_go_back());
EXPECT_EQ(true, reply.can_abort());
};
rmad_interface.TransitionNextState(request, base::BindOnce(callback1));
EXPECT_EQ(true, rmad_interface.CanAbort());
auto callback2 = [](const GetStateReply& reply) {
EXPECT_EQ(RMAD_ERROR_OK, reply.error());
EXPECT_EQ(RmadState::kDeviceDestination, reply.state().state_case());
EXPECT_EQ(false, reply.can_go_back());
EXPECT_EQ(false, reply.can_abort());
};
rmad_interface.TransitionNextState(request, base::BindOnce(callback2));
EXPECT_EQ(false, rmad_interface.CanAbort());
}
TEST_F(RmadInterfaceImplTest, TransitionNextState_MissingHandler) {
base::FilePath json_store_file_path =
CreateInputFile(kJsonStoreFileName, kCurrentStateSetJson,
std::size(kCurrentStateSetJson) - 1);
auto json_store = base::MakeRefCounted<JsonStore>(json_store_file_path);
RmadInterfaceImpl rmad_interface(
json_store, CreateStateHandlerManagerMissingHandler(json_store),
CreateRuntimeProbeClient(false), CreateShillClient(nullptr),
CreateTpmManagerClient(RoVerificationStatus::NOT_TRIGGERED),
CreatePowerManagerClient(), CreateCmdUtils(), CreateMetricsUtils(true));
EXPECT_TRUE(rmad_interface.SetUp());
TransitionNextStateRequest request;
auto callback = [](const GetStateReply& reply) {
FAIL() << "Unexpected call to callback";
};
EXPECT_DEATH(
rmad_interface.TransitionNextState(request, base::BindOnce(callback)),
"No registered state handler");
}
TEST_F(RmadInterfaceImplTest, TransitionNextState_InitializeNextStateFail) {
base::FilePath json_store_file_path =
CreateInputFile(kJsonStoreFileName, kInitializeNextStateFailJson,
std::size(kInitializeNextStateFailJson) - 1);
auto json_store = base::MakeRefCounted<JsonStore>(json_store_file_path);
RmadInterfaceImpl rmad_interface(
json_store, CreateStateHandlerManagerInitializeStateFail(json_store),
CreateRuntimeProbeClient(false), CreateShillClient(nullptr),
CreateTpmManagerClient(RoVerificationStatus::NOT_TRIGGERED),
CreatePowerManagerClient(), CreateCmdUtils(), CreateMetricsUtils(true));
EXPECT_TRUE(rmad_interface.SetUp());
TransitionNextStateRequest request;
auto callback = [](const GetStateReply& reply) {
EXPECT_EQ(RMAD_ERROR_DEVICE_INFO_INVALID, reply.error());
EXPECT_EQ(RmadState::kComponentsRepair, reply.state().state_case());
EXPECT_EQ(true, reply.can_go_back());
EXPECT_EQ(true, reply.can_abort());
};
rmad_interface.TransitionNextState(request, base::BindOnce(callback));
}
TEST_F(RmadInterfaceImplTest, TransitionPreviousState) {
base::FilePath json_store_file_path = CreateInputFile(
kJsonStoreFileName, kCurrentStateWithRepeatableHistoryJson,
std::size(kCurrentStateWithRepeatableHistoryJson) - 1);
auto json_store = base::MakeRefCounted<JsonStore>(json_store_file_path);
RmadInterfaceImpl rmad_interface(
json_store, CreateStateHandlerManager(json_store),
CreateRuntimeProbeClient(false), CreateShillClient(nullptr),
CreateTpmManagerClient(RoVerificationStatus::NOT_TRIGGERED),
CreatePowerManagerClient(), CreateCmdUtils(), CreateMetricsUtils(true));
EXPECT_TRUE(rmad_interface.SetUp());
auto callback = [](const GetStateReply& reply) {
EXPECT_EQ(RMAD_ERROR_OK, reply.error());
EXPECT_EQ(RmadState::kWelcome, reply.state().state_case());
EXPECT_EQ(false, reply.can_go_back());
EXPECT_EQ(true, reply.can_abort());
};
rmad_interface.TransitionPreviousState(base::BindOnce(callback));
}
TEST_F(RmadInterfaceImplTest, TransitionPreviousState_NoHistory) {
base::FilePath json_store_file_path =
CreateInputFile(kJsonStoreFileName, kCurrentStateSetJson,
std::size(kCurrentStateSetJson) - 1);
auto json_store = base::MakeRefCounted<JsonStore>(json_store_file_path);
RmadInterfaceImpl rmad_interface(
json_store, CreateStateHandlerManager(json_store),
CreateRuntimeProbeClient(false), CreateShillClient(nullptr),
CreateTpmManagerClient(RoVerificationStatus::NOT_TRIGGERED),
CreatePowerManagerClient(), CreateCmdUtils(), CreateMetricsUtils(true));
EXPECT_TRUE(rmad_interface.SetUp());
auto callback = [](const GetStateReply& reply) {
EXPECT_EQ(RMAD_ERROR_TRANSITION_FAILED, reply.error());
EXPECT_EQ(RmadState::kWelcome, reply.state().state_case());
EXPECT_EQ(false, reply.can_go_back());
EXPECT_EQ(true, reply.can_abort());
};
rmad_interface.TransitionPreviousState(base::BindOnce(callback));
}
TEST_F(RmadInterfaceImplTest, TransitionPreviousState_MissingHandler) {
base::FilePath json_store_file_path = CreateInputFile(
kJsonStoreFileName, kCurrentStateWithRepeatableHistoryJson,
std::size(kCurrentStateWithRepeatableHistoryJson) - 1);
auto json_store = base::MakeRefCounted<JsonStore>(json_store_file_path);
RmadInterfaceImpl rmad_interface(
json_store, CreateStateHandlerManagerMissingHandler(json_store),
CreateRuntimeProbeClient(false), CreateShillClient(nullptr),
CreateTpmManagerClient(RoVerificationStatus::NOT_TRIGGERED),
CreatePowerManagerClient(), CreateCmdUtils(), CreateMetricsUtils(true));
EXPECT_TRUE(rmad_interface.SetUp());
auto callback = [](const GetStateReply& reply) {
EXPECT_EQ(RMAD_ERROR_TRANSITION_FAILED, reply.error());
EXPECT_EQ(RmadState::kWelcome, reply.state().state_case());
EXPECT_EQ(false, reply.can_go_back());
EXPECT_EQ(true, reply.can_abort());
};
rmad_interface.TransitionPreviousState(base::BindOnce(callback));
}
TEST_F(RmadInterfaceImplTest,
TransitionPreviousState_InitializePreviousStateFail) {
base::FilePath json_store_file_path =
CreateInputFile(kJsonStoreFileName, kInitializePreviousStateFailJson,
std::size(kInitializePreviousStateFailJson) - 1);
auto json_store = base::MakeRefCounted<JsonStore>(json_store_file_path);
RmadInterfaceImpl rmad_interface(
json_store, CreateStateHandlerManagerInitializeStateFail(json_store),
CreateRuntimeProbeClient(false), CreateShillClient(nullptr),
CreateTpmManagerClient(RoVerificationStatus::NOT_TRIGGERED),
CreatePowerManagerClient(), CreateCmdUtils(), CreateMetricsUtils(true));
EXPECT_TRUE(rmad_interface.SetUp());
auto callback = [](const GetStateReply& reply) {
EXPECT_EQ(RMAD_ERROR_MISSING_COMPONENT, reply.error());
EXPECT_EQ(RmadState::kComponentsRepair, reply.state().state_case());
EXPECT_EQ(true, reply.can_go_back());
EXPECT_EQ(true, reply.can_abort());
};
rmad_interface.TransitionPreviousState(base::BindOnce(callback));
}
TEST_F(RmadInterfaceImplTest, AbortRma) {
base::FilePath json_store_file_path = CreateInputFile(
kJsonStoreFileName, kCurrentStateWithRepeatableHistoryJson,
std::size(kCurrentStateWithRepeatableHistoryJson) - 1);
auto json_store = base::MakeRefCounted<JsonStore>(json_store_file_path);
RmadInterfaceImpl rmad_interface(
json_store, CreateStateHandlerManager(json_store),
CreateRuntimeProbeClient(false), CreateShillClient(nullptr),
CreateTpmManagerClient(RoVerificationStatus::NOT_TRIGGERED),
CreatePowerManagerClient(), CreateCmdUtils(), CreateMetricsUtils(true));
EXPECT_TRUE(rmad_interface.SetUp());
// Check that the state file exists now.
EXPECT_TRUE(base::PathExists(json_store_file_path));
auto callback = [](const AbortRmaReply& reply) {
EXPECT_EQ(RMAD_ERROR_RMA_NOT_REQUIRED, reply.error());
};
rmad_interface.AbortRma(base::BindOnce(callback));
// Check the the state file is cleared.
EXPECT_FALSE(base::PathExists(json_store_file_path));
}
TEST_F(RmadInterfaceImplTest, AbortRma_NoHistory) {
base::FilePath json_store_file_path =
CreateInputFile(kJsonStoreFileName, kCurrentStateSetJson,
std::size(kCurrentStateSetJson) - 1);
auto json_store = base::MakeRefCounted<JsonStore>(json_store_file_path);
RmadInterfaceImpl rmad_interface(
json_store, CreateStateHandlerManager(json_store),
CreateRuntimeProbeClient(false), CreateShillClient(nullptr),
CreateTpmManagerClient(RoVerificationStatus::NOT_TRIGGERED),
CreatePowerManagerClient(), CreateCmdUtils(), CreateMetricsUtils(true));
EXPECT_TRUE(rmad_interface.SetUp());
// Check that the state file exists now.
EXPECT_TRUE(base::PathExists(json_store_file_path));
auto callback = [](const AbortRmaReply& reply) {
EXPECT_EQ(RMAD_ERROR_RMA_NOT_REQUIRED, reply.error());
};
rmad_interface.AbortRma(base::BindOnce(callback));
// Check the the state file is cleared.
EXPECT_FALSE(base::PathExists(json_store_file_path));
}
TEST_F(RmadInterfaceImplTest, AbortRma_Failed) {
base::FilePath json_store_file_path = CreateInputFile(
kJsonStoreFileName, kCurrentStateWithUnrepeatableHistoryJson,
std::size(kCurrentStateWithUnrepeatableHistoryJson) - 1);
auto json_store = base::MakeRefCounted<JsonStore>(json_store_file_path);
RmadInterfaceImpl rmad_interface(
json_store, CreateStateHandlerManager(json_store),
CreateRuntimeProbeClient(false), CreateShillClient(nullptr),
CreateTpmManagerClient(RoVerificationStatus::NOT_TRIGGERED),
CreatePowerManagerClient(), CreateCmdUtils(), CreateMetricsUtils(true));
EXPECT_TRUE(rmad_interface.SetUp());
// Check that the state file exists now.
EXPECT_TRUE(base::PathExists(json_store_file_path));
auto callback = [](const AbortRmaReply& reply) {
EXPECT_EQ(RMAD_ERROR_ABORT_FAILED, reply.error());
};
rmad_interface.AbortRma(base::BindOnce(callback));
// Check the the state file still exists.
EXPECT_TRUE(base::PathExists(json_store_file_path));
}
TEST_F(RmadInterfaceImplTest, GetLog) {
base::FilePath json_store_file_path =
CreateInputFile(kJsonStoreFileName, "", 0);
auto json_store = base::MakeRefCounted<JsonStore>(json_store_file_path);
RmadInterfaceImpl rmad_interface(
json_store, CreateStateHandlerManager(json_store),
CreateRuntimeProbeClient(false), CreateShillClient(nullptr),
CreateTpmManagerClient(RoVerificationStatus::NOT_TRIGGERED),
CreatePowerManagerClient(), CreateCmdUtils(), CreateMetricsUtils(true));
EXPECT_TRUE(rmad_interface.SetUp());
auto callback = [](const GetLogReply& reply) {
EXPECT_EQ("fake_log", reply.log());
};
rmad_interface.GetLog(base::BindOnce(callback));
}
TEST_F(RmadInterfaceImplTest, SaveLog) {
base::FilePath json_store_file_path =
CreateInputFile(kJsonStoreFileName, "", 0);
auto json_store = base::MakeRefCounted<JsonStore>(json_store_file_path);
RmadInterfaceImpl rmad_interface(
json_store, CreateStateHandlerManager(json_store),
CreateRuntimeProbeClient(false), CreateShillClient(nullptr),
CreateTpmManagerClient(RoVerificationStatus::NOT_TRIGGERED),
CreatePowerManagerClient(), CreateCmdUtils(), CreateMetricsUtils(true));
EXPECT_TRUE(rmad_interface.SetUp());
auto callback = [](const SaveLogReply& reply) {
EXPECT_EQ(RMAD_ERROR_OK, reply.error());
EXPECT_EQ("fake_path", reply.save_path());
};
rmad_interface.SaveLog("", base::BindOnce(callback));
}
} // namespace rmad