blob: 4daff6641b264970d84a9fed1b328bdbfdd7b470 [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 "rmad/state_handler/base_state_handler.h"
#include <set>
#include <string>
#include <vector>
#include <base/files/file_util.h>
#include <base/test/task_environment.h>
#include <gtest/gtest.h>
#include "rmad/constants.h"
#include "rmad/metrics/metrics_constants.h"
#include "rmad/state_handler/state_handler_test_common.h"
namespace {
constexpr int kDelayTimeInSec = 1;
} // namespace
namespace rmad {
class TestBaseStateHandler : public BaseStateHandler {
public:
explicit TestBaseStateHandler(scoped_refptr<JsonStore> json_store)
: BaseStateHandler(json_store) {}
RmadState::StateCase GetStateCase() const override {
return RmadState::STATE_NOT_SET;
}
SET_REPEATABLE
RmadErrorCode InitializeState() override { return RMAD_ERROR_OK; }
GetNextStateCaseReply GetNextStateCase(const RmadState& state) override {
return {.error = RMAD_ERROR_OK, .state_case = RmadState::STATE_NOT_SET};
}
RmadState& GetStateInternalForTest() { return state_; }
protected:
~TestBaseStateHandler() override = default;
};
class TestUnrepeatableBaseStateHandler : public BaseStateHandler {
public:
explicit TestUnrepeatableBaseStateHandler(scoped_refptr<JsonStore> json_store)
: BaseStateHandler(json_store) {}
RmadState::StateCase GetStateCase() const override {
return RmadState::STATE_NOT_SET;
}
SET_UNREPEATABLE
RmadErrorCode InitializeState() override { return RMAD_ERROR_OK; }
GetNextStateCaseReply GetNextStateCase(const RmadState& state) override {
return {.error = RMAD_ERROR_OK, .state_case = RmadState::STATE_NOT_SET};
}
protected:
~TestUnrepeatableBaseStateHandler() override = default;
};
class BaseStateHandlerTest : public StateHandlerTest {
public:
scoped_refptr<TestBaseStateHandler> CreateStateHandler() {
return base::MakeRefCounted<TestBaseStateHandler>(json_store_);
}
scoped_refptr<TestUnrepeatableBaseStateHandler>
CreateUnrepeatableStateHandler() {
return base::MakeRefCounted<TestUnrepeatableBaseStateHandler>(json_store_);
}
protected:
// Variables for TaskRunner.
base::test::TaskEnvironment task_environment_{
base::test::TaskEnvironment::ThreadPoolExecutionMode::ASYNC,
base::test::TaskEnvironment::TimeSource::MOCK_TIME};
void SetUp() override { StateHandlerTest::SetUp(); }
};
TEST_F(BaseStateHandlerTest, CleanUpState_Success) {
auto handler = CreateStateHandler();
handler->CleanUpState();
}
TEST_F(BaseStateHandlerTest, RegisterSignalSender_Success) {
auto handler = CreateStateHandler();
handler->RegisterSignalSender(base::RepeatingCallback<void(bool)>());
handler->RegisterSignalSender(
rmad::BaseStateHandler::HardwareVerificationResultSignalCallback());
handler->RegisterSignalSender(
rmad::BaseStateHandler::CalibrationOverallSignalCallback());
handler->RegisterSignalSender(
rmad::BaseStateHandler::CalibrationComponentSignalCallback());
handler->RegisterSignalSender(
rmad::BaseStateHandler::ProvisionSignalCallback());
handler->RegisterSignalSender(
rmad::BaseStateHandler::FinalizeSignalCallback());
}
TEST_F(BaseStateHandlerTest, IsRepeatable_RepeatableSuccess) {
auto handler = CreateStateHandler();
EXPECT_TRUE(handler->IsRepeatable());
}
TEST_F(BaseStateHandlerTest, IsRepeatable_UnrepeatableSuccess) {
auto handler = CreateUnrepeatableStateHandler();
EXPECT_FALSE(handler->IsRepeatable());
}
TEST_F(BaseStateHandlerTest, StoreState_EmptySuccess) {
auto handler = CreateStateHandler();
EXPECT_TRUE(handler->StoreState());
}
TEST_F(BaseStateHandlerTest, StoreState_WelcomeSuccess) {
auto handler = CreateStateHandler();
EXPECT_FALSE(handler->GetStateInternalForTest().has_welcome());
handler->GetStateInternalForTest().set_allocated_welcome(new WelcomeState);
EXPECT_TRUE(handler->GetStateInternalForTest().has_welcome());
EXPECT_TRUE(handler->StoreState());
}
TEST_F(BaseStateHandlerTest, RetrieveState_EmptyFailed) {
auto handler = CreateStateHandler();
EXPECT_FALSE(handler->RetrieveState());
}
TEST_F(BaseStateHandlerTest, RetrieveState_EmptyStateSuccess) {
auto handler = CreateStateHandler();
EXPECT_TRUE(handler->StoreState());
auto handler2 = CreateStateHandler();
EXPECT_TRUE(handler2->RetrieveState());
}
TEST_F(BaseStateHandlerTest, RetrieveState_WelcomeStateSuccess) {
auto handler = CreateStateHandler();
EXPECT_FALSE(handler->GetStateInternalForTest().has_welcome());
handler->GetStateInternalForTest().set_allocated_welcome(new WelcomeState);
EXPECT_TRUE(handler->GetStateInternalForTest().has_welcome());
EXPECT_TRUE(handler->StoreState());
auto handler2 = CreateStateHandler();
EXPECT_TRUE(handler2->RetrieveState());
EXPECT_TRUE(handler2->GetStateInternalForTest().has_welcome());
}
TEST_F(BaseStateHandlerTest, StoreErrorCode_Success) {
std::vector<std::string> target_occurred_errors;
for (int i = RmadErrorCode_MIN; i <= RmadErrorCode_MAX; i++) {
auto handler = CreateStateHandler();
RmadErrorCode error_code = static_cast<RmadErrorCode>(i);
EXPECT_TRUE(handler->StoreErrorCode(error_code));
if (std::find(kExpectedErrorCodes.begin(), kExpectedErrorCodes.end(),
error_code) == kExpectedErrorCodes.end()) {
target_occurred_errors.push_back(RmadErrorCode_Name(error_code));
}
}
std::vector<std::string> occurred_errors;
json_store_->GetValue(kOccurredErrors, &occurred_errors);
EXPECT_EQ(occurred_errors, target_occurred_errors);
}
TEST_F(BaseStateHandlerTest, StoreErrorCode_Failed) {
base::SetPosixFilePermissions(GetStateFilePath(), 0444);
for (int i = RmadErrorCode_MIN; i <= RmadErrorCode_MAX; i++) {
auto handler = CreateStateHandler();
RmadErrorCode error_code = static_cast<RmadErrorCode>(i);
if (std::find(kExpectedErrorCodes.begin(), kExpectedErrorCodes.end(),
error_code) == kExpectedErrorCodes.end()) {
EXPECT_FALSE(handler->StoreErrorCode(error_code));
} else {
EXPECT_TRUE(handler->StoreErrorCode(error_code));
}
}
}
TEST_F(BaseStateHandlerTest, StoreAdditionalActivity_NothingSuccess) {
auto handler = CreateStateHandler();
EXPECT_TRUE(handler->StoreAdditionalActivity(AdditionalActivity::NOTHING));
}
TEST_F(BaseStateHandlerTest, StoreAdditionalActivity_Success) {
std::vector<int> target_additional_activities;
for (AdditionalActivity activity : kValidAdditionalActivities) {
auto handler = CreateStateHandler();
if (std::find(kExpectedPowerCycleActivities.begin(),
kExpectedPowerCycleActivities.end(),
activity) != kExpectedPowerCycleActivities.end()) {
EXPECT_TRUE(json_store_->SetValue(kSetupTimestamp,
base::Time::Now().ToDoubleT()));
task_environment_.FastForwardBy(base::Seconds(kDelayTimeInSec));
double pre_running_time = 0.0;
json_store_->GetValue(kRunningTime, &pre_running_time);
EXPECT_TRUE(handler->StoreAdditionalActivity(activity));
double running_time;
EXPECT_TRUE(json_store_->GetValue(kRunningTime, &running_time));
EXPECT_EQ(running_time - pre_running_time, kDelayTimeInSec);
} else {
EXPECT_TRUE(handler->StoreAdditionalActivity(activity));
}
if (activity != AdditionalActivity::NOTHING) {
target_additional_activities.push_back(static_cast<int>(activity));
}
}
std::vector<int> additional_activities;
json_store_->GetValue(kAdditionalActivities, &additional_activities);
EXPECT_EQ(additional_activities, target_additional_activities);
}
TEST_F(BaseStateHandlerTest, StoreAdditionalActivity_JsonFailed) {
EXPECT_TRUE(
json_store_->SetValue(kSetupTimestamp, base::Time::Now().ToDoubleT()));
base::SetPosixFilePermissions(GetStateFilePath(), 0444);
for (AdditionalActivity activity : kValidAdditionalActivities) {
auto handler = CreateStateHandler();
EXPECT_FALSE(handler->StoreAdditionalActivity(activity));
}
}
TEST_F(BaseStateHandlerTest, StoreAdditionalActivity_RunningTimeFailed) {
for (AdditionalActivity activity : kValidAdditionalActivities) {
auto handler = CreateStateHandler();
// If it does power cycle, it needs to calculate the running time.
if (std::find(kExpectedPowerCycleActivities.begin(),
kExpectedPowerCycleActivities.end(),
activity) != kExpectedPowerCycleActivities.end()) {
EXPECT_FALSE(handler->StoreAdditionalActivity(activity));
} else {
EXPECT_TRUE(handler->StoreAdditionalActivity(activity));
}
}
}
TEST_F(BaseStateHandlerTest, NextStateCaseWrapper_Sucesss) {
std::vector<std::string> target_occurred_errors;
std::vector<int> target_additional_activities;
RmadState::StateCase state_case = RmadState::kWelcome;
for (int i = RmadErrorCode_MIN; i <= RmadErrorCode_MAX; i++) {
RmadErrorCode error_code = static_cast<RmadErrorCode>(i);
auto handler = CreateStateHandler();
BaseStateHandler::GetNextStateCaseReply reply =
handler->NextStateCaseWrapper(state_case, error_code,
AdditionalActivity::NOTHING);
EXPECT_EQ(reply.state_case, state_case);
EXPECT_EQ(reply.error, error_code);
if (std::find(kExpectedErrorCodes.begin(), kExpectedErrorCodes.end(),
error_code) == kExpectedErrorCodes.end()) {
target_occurred_errors.push_back(RmadErrorCode_Name(error_code));
}
}
for (AdditionalActivity activity : kValidAdditionalActivities) {
auto handler = CreateStateHandler();
if (std::find(kExpectedPowerCycleActivities.begin(),
kExpectedPowerCycleActivities.end(),
activity) != kExpectedPowerCycleActivities.end()) {
EXPECT_TRUE(json_store_->SetValue(kSetupTimestamp,
base::Time::Now().ToDoubleT()));
task_environment_.FastForwardBy(base::Seconds(kDelayTimeInSec));
double pre_running_time = 0.0;
json_store_->GetValue(kRunningTime, &pre_running_time);
BaseStateHandler::GetNextStateCaseReply reply =
handler->NextStateCaseWrapper(state_case, RMAD_ERROR_OK, activity);
EXPECT_EQ(reply.state_case, state_case);
EXPECT_EQ(reply.error, RMAD_ERROR_OK);
double running_time;
EXPECT_TRUE(json_store_->GetValue(kRunningTime, &running_time));
EXPECT_EQ(running_time - pre_running_time, kDelayTimeInSec);
} else {
BaseStateHandler::GetNextStateCaseReply reply =
handler->NextStateCaseWrapper(state_case, RMAD_ERROR_OK, activity);
EXPECT_EQ(reply.state_case, state_case);
EXPECT_EQ(reply.error, RMAD_ERROR_OK);
}
if (activity != AdditionalActivity::NOTHING) {
target_additional_activities.push_back(static_cast<int>(activity));
}
}
std::vector<int> additional_activities;
EXPECT_TRUE(
json_store_->GetValue(kAdditionalActivities, &additional_activities));
EXPECT_EQ(additional_activities, target_additional_activities);
std::vector<std::string> occurred_errors;
EXPECT_TRUE(json_store_->GetValue(kOccurredErrors, &occurred_errors));
EXPECT_EQ(occurred_errors, target_occurred_errors);
}
TEST_F(BaseStateHandlerTest, NextStateCaseWrapper_JsonFailed) {
base::SetPosixFilePermissions(GetStateFilePath(), 0444);
std::vector<std::string> target_occurred_errors;
RmadState::StateCase state_case = RmadState::kWelcome;
for (int i = RmadErrorCode_MIN; i <= RmadErrorCode_MAX; i++) {
RmadErrorCode error_code = static_cast<RmadErrorCode>(i);
auto handler = CreateStateHandler();
BaseStateHandler::GetNextStateCaseReply reply =
handler->NextStateCaseWrapper(state_case, error_code,
AdditionalActivity::NOTHING);
EXPECT_EQ(reply.state_case, state_case);
EXPECT_EQ(reply.error, error_code);
}
for (AdditionalActivity activity : kValidAdditionalActivities) {
auto handler = CreateStateHandler();
BaseStateHandler::GetNextStateCaseReply reply =
handler->NextStateCaseWrapper(state_case, RMAD_ERROR_OK, activity);
EXPECT_EQ(reply.state_case, state_case);
EXPECT_EQ(reply.error, RMAD_ERROR_OK);
}
std::vector<int> additional_activities;
json_store_->GetValue(kAdditionalActivities, &additional_activities);
EXPECT_EQ(additional_activities, std::vector<int>());
std::vector<std::string> occurred_errors;
json_store_->GetValue(kOccurredErrors, &occurred_errors);
EXPECT_EQ(occurred_errors, std::vector<std::string>());
}
TEST_F(BaseStateHandlerTest, NextStateCaseWrapper_RunningTimeFailed) {
std::vector<std::string> target_occurred_errors;
std::vector<int> target_additional_activities;
RmadState::StateCase state_case = RmadState::kWelcome;
for (int i = RmadErrorCode_MIN; i <= RmadErrorCode_MAX; i++) {
RmadErrorCode error_code = static_cast<RmadErrorCode>(i);
auto handler = CreateStateHandler();
BaseStateHandler::GetNextStateCaseReply reply =
handler->NextStateCaseWrapper(state_case, error_code,
AdditionalActivity::NOTHING);
EXPECT_EQ(reply.state_case, state_case);
EXPECT_EQ(reply.error, error_code);
if (std::find(kExpectedErrorCodes.begin(), kExpectedErrorCodes.end(),
error_code) == kExpectedErrorCodes.end()) {
target_occurred_errors.push_back(RmadErrorCode_Name(error_code));
}
}
for (AdditionalActivity activity : kValidAdditionalActivities) {
auto handler = CreateStateHandler();
BaseStateHandler::GetNextStateCaseReply reply =
handler->NextStateCaseWrapper(state_case, RMAD_ERROR_OK, activity);
EXPECT_EQ(reply.state_case, state_case);
EXPECT_EQ(reply.error, RMAD_ERROR_OK);
if (activity != AdditionalActivity::NOTHING &&
std::find(kExpectedPowerCycleActivities.begin(),
kExpectedPowerCycleActivities.end(),
activity) == kExpectedPowerCycleActivities.end()) {
target_additional_activities.push_back(static_cast<int>(activity));
}
}
std::vector<int> additional_activities;
EXPECT_TRUE(
json_store_->GetValue(kAdditionalActivities, &additional_activities));
EXPECT_EQ(additional_activities, target_additional_activities);
std::vector<std::string> occurred_errors;
EXPECT_TRUE(json_store_->GetValue(kOccurredErrors, &occurred_errors));
EXPECT_EQ(occurred_errors, target_occurred_errors);
}
} // namespace rmad