* Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
*/
#include <gtest/gtest.h>
#include <mockcpp/mokc.h>
#include <mockcpp/mockcpp.hpp>
#include <gmock/gmock.h>
#include "acc_tcp_ssl_helper.h"
#include "common.h"
#include "controller_state_machine.h"
using namespace ock::ttp;
#define MOCKER_CPP(api, TT) MOCKCPP_NS::mockAPI(#api, reinterpret_cast<TT>(api))
#ifndef MOCKCPP_RESET
#define MOCKCPP_RESET GlobalMockObject::reset()
#endif
namespace {
using controllerStateMachinePtr = Ref<controllerStateMachine>;
controllerStateMachinePtr stateMachinePtr_ = nullptr;
std::atomic<uint32_t> g_callCount;
int32_t g_initSn = 0;
int32_t g_normalSn = 0;
int32_t g_pauseSn = 0;
int32_t g_abnormalSn = 0;
int32_t g_dumpSn = 0;
int32_t g_exitSn = 0;
int32_t g_envclearSn = 0;
int32_t g_repairSn = 0;
int32_t g_downgradeSn = 0;
int32_t g_upgradeSn = 0;
int32_t g_dgRepairSn = 0;
constexpr uint32_t CHECK_COUNT_ONE = 1;
constexpr uint32_t CHECK_COUNT_TWO = 2;
constexpr uint32_t CHECK_COUNT_THREE = 3;
constexpr uint32_t CHECK_COUNT_FOUR = 4;
constexpr uint32_t CHECK_COUNT_FIVE = 5;
constexpr uint32_t CHECK_COUNT_SIX = 6;
constexpr uint32_t CHECK_COUNT_SEVEN = 7;
constexpr uint32_t CHECK_COUNT_EIGHT = 8;
constexpr uint32_t CHECK_COUNT_NINE = 9;
bool g_dump = false;
bool g_pause = false;
bool g_continue = false;
bool g_downgrade = false;
class TestControllerStateMachine : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
void SetUp() override;
void TearDown() override;
void InitSource();
private:
int32_t InitCallback();
int32_t NormalCallback();
int32_t PauseCallback();
int32_t AbnormalCallback();
int32_t DumpCallback();
int32_t ExitCallback();
int32_t EnvclearCallback();
int32_t RepairCallback();
int32_t DowngradeCallback();
int32_t UpgradeCallback();
int32_t DgRepairCallback();
};
void TestControllerStateMachine::SetUpTestCase() {}
void TestControllerStateMachine::TearDownTestCase() {}
void TestControllerStateMachine::SetUp() {}
void TestControllerStateMachine::TearDown()
{
if (stateMachinePtr_ != nullptr) {
stateMachinePtr_->Stop();
stateMachinePtr_ = nullptr;
}
}
void TestControllerStateMachine::InitSource()
{
g_callCount.store(0);
stateMachinePtr_ = MakeRef<controllerStateMachine>();
int32_t ret = stateMachinePtr_->Initialize(0);
ASSERT_EQ(ret, TTP_OK);
g_initSn = 0;
g_normalSn = 0;
g_pauseSn = 0;
g_abnormalSn = 0;
g_dumpSn = 0;
g_exitSn = 0;
g_envclearSn = 0;
g_repairSn = 0;
g_downgradeSn = 0;
g_upgradeSn = 0;
g_dgRepairSn = 0;
auto initMethod = [this]() { return InitCallback(); };
stateMachinePtr_->ControllerActionRegister(STATE_OP_INIT, initMethod);
auto normalMethod = [this]() { return NormalCallback(); };
stateMachinePtr_->ControllerActionRegister(STATE_OP_NORMAL, normalMethod);
auto abnormalMethod = [this]() { return AbnormalCallback(); };
stateMachinePtr_->ControllerActionRegister(STATE_OP_ABNORMAL, abnormalMethod);
auto dumpMethod = [this]() { return DumpCallback(); };
stateMachinePtr_->ControllerActionRegister(STATE_OP_DUMP, dumpMethod);
auto exitMethod = [this]() { return ExitCallback(); };
stateMachinePtr_->ControllerActionRegister(STATE_OP_EXIT, exitMethod);
auto envclearMethod = [this]() { return EnvclearCallback(); };
stateMachinePtr_->ControllerActionRegister(STATE_OP_ENV_CLEAR, envclearMethod);
auto repairMethod = [this]() { return RepairCallback(); };
stateMachinePtr_->ControllerActionRegister(STATE_OP_REPAIR, repairMethod);
auto downgradeMethod = [this]() { return DowngradeCallback(); };
stateMachinePtr_->ControllerActionRegister(STATE_OP_DOWNGRADE, downgradeMethod);
auto upgradeMethod = [this]() { return UpgradeCallback(); };
stateMachinePtr_->ControllerActionRegister(STATE_OP_UPGRADE, upgradeMethod);
auto dpRepairMethod = [this]() { return DgRepairCallback(); };
stateMachinePtr_->ControllerActionRegister(STATE_OP_DG_REPAIR, dpRepairMethod);
auto pauseMethod = [this]() { return PauseCallback(); };
stateMachinePtr_->ControllerActionRegister(STATE_OP_PAUSE, pauseMethod);
}
int32_t TestControllerStateMachine::InitCallback()
{
g_callCount.fetch_add(1);
g_initSn = g_callCount.load();
TTP_LOG_INFO("STATE_OP_INIT --> STATE_OP_NORMAL");
return TTP_OK;
}
int32_t TestControllerStateMachine::NormalCallback()
{
g_callCount.fetch_add(1);
g_normalSn = g_callCount.load();
TTP_LOG_INFO("STATE_OP_NORMAL --> STATE_OP_ABNORMAL");
if (g_pause) {
TTP_LOG_INFO("STATE_OP_ABNORMAL --> STATE_OP_PAUSE");
return TTP_PAUSE;
}
return TTP_ERROR;
}
int32_t TestControllerStateMachine::AbnormalCallback()
{
g_callCount.fetch_add(1);
g_abnormalSn = g_callCount.load();
if (g_dump) {
TTP_LOG_INFO("STATE_OP_ABNORMAL --> STATE_OP_DUMP");
return TTP_ERROR;
} else {
TTP_LOG_INFO("STATE_OP_ABNORMAL --> STATE_OP_ENV_CLEAR");
return TTP_OK;
}
}
int32_t TestControllerStateMachine::PauseCallback()
{
g_callCount.fetch_add(1);
g_pauseSn = g_callCount.load();
if (g_continue) {
TTP_LOG_INFO("STATE_OP_PAUSE --> STATE_OP_NORMAL");
return TTP_OK;
} else {
TTP_LOG_INFO("STATE_OP_PAUSE --> STATE_OP_ABNORMAL");
return TTP_ERROR;
}
}
int32_t TestControllerStateMachine::DumpCallback()
{
g_callCount.fetch_add(1);
g_dumpSn = g_callCount.load();
TTP_LOG_INFO("STATE_OP_DUMP --> STATE_OP_EXIT");
return TTP_OK;
}
int32_t TestControllerStateMachine::ExitCallback()
{
g_callCount.fetch_add(1);
g_exitSn = g_callCount.load();
TTP_LOG_INFO("STATE_OP_EXIT --> STATE_OP_FINAL");
return TTP_STOP_SERVICE;
}
int32_t TestControllerStateMachine::EnvclearCallback()
{
g_callCount.fetch_add(1);
g_envclearSn = g_callCount.load();
if (g_downgrade) {
TTP_LOG_INFO("STATE_OP_ENV_CLEAR --> STATE_OP_DG_REPAIR");
return TTP_DOWNGRADE;
} else {
TTP_LOG_INFO("STATE_OP_ENV_CLEAR --> STATE_OP_REPAIR");
return TTP_OK;
}
}
int32_t TestControllerStateMachine::RepairCallback()
{
g_callCount.fetch_add(1);
g_repairSn = g_callCount.load();
TTP_LOG_INFO("STATE_OP_REPAIR --> STATE_OP_DUMP");
return TTP_ERROR;
}
int32_t TestControllerStateMachine::DowngradeCallback()
{
g_callCount.fetch_add(1);
g_downgradeSn = g_callCount.load();
TTP_LOG_INFO("STATE_OP_DOWNGRADE --> STATE_OP_UPGRADE");
return TTP_NEED_RETRY;
}
int32_t TestControllerStateMachine::UpgradeCallback()
{
g_callCount.fetch_add(1);
g_upgradeSn = g_callCount.load();
TTP_LOG_INFO("STATE_OP_UPGRADE --> STATE_OP_DUMP");
return TTP_ERROR;
}
int32_t TestControllerStateMachine::DgRepairCallback()
{
g_callCount.fetch_add(1);
g_dgRepairSn = g_callCount.load();
TTP_LOG_INFO("STATE_OP_DG_REPAIR --> STATE_OP_DOWNGRADE");
return TTP_OK;
}
TEST_F(TestControllerStateMachine, dump_state)
{
g_dump = true;
InitSource();
stateMachinePtr_->StartStateMachine();
sleep(1);
ASSERT_EQ(g_initSn, 1);
ASSERT_EQ(g_normalSn, 2);
ASSERT_EQ(g_abnormalSn, 3);
ASSERT_EQ(g_dumpSn, 4);
ASSERT_EQ(g_exitSn, 5);
g_dump = false;
}
TEST_F(TestControllerStateMachine, read_tls_option)
{
AccTlsOption tlsOpts;
std::string tlsInfo = R"(
tlsCert: test/llt/openssl_cert/certs/cert.pem;
tlsCrlPath: test/llt/openssl_cert/crl/;
tlsCaPath: test/llt/openssl_cert/ca/;
tlsCaFile: ca_cert_1.pem, ca_cert_2.pem;
tlsCrlFile: crl.pem;
tlsPk: test private key;
tlsPkPwd: test private key pwd;
packagePath: /etc/lib/
)";
bool ret = FileUtils::ParseTlsInfo(tlsInfo, tlsOpts);
tlsOpts.enableTls = true;
ASSERT_EQ(ret, true);
ASSERT_EQ(tlsOpts.enableTls, true);
ASSERT_EQ(tlsOpts.tlsPkPwd, "test private key pwd");
ASSERT_EQ(tlsOpts.tlsPk, "test private key");
ASSERT_EQ(tlsOpts.tlsCrlPath, "test/llt/openssl_cert/crl/");
ASSERT_EQ(tlsOpts.tlsCrlFile.size(), 1);
ASSERT_EQ(tlsOpts.tlsCaPath, "test/llt/openssl_cert/ca/");
ASSERT_EQ(tlsOpts.tlsCaFile.size(), 2);
ASSERT_EQ(tlsOpts.tlsCert, "test/llt/openssl_cert/certs/cert.pem");
for (auto file : tlsOpts.tlsCaFile) {
std::cout << file << std::endl;
}
ASSERT_EQ(tlsOpts.packagePath, "/etc/lib/");
}
TEST_F(TestControllerStateMachine, uce_state)
{
InitSource();
stateMachinePtr_->StartStateMachine();
sleep(1);
ASSERT_EQ(g_initSn, 1);
ASSERT_EQ(g_normalSn, 2);
ASSERT_EQ(g_abnormalSn, 3);
ASSERT_EQ(g_envclearSn, 4);
ASSERT_EQ(g_repairSn, 5);
ASSERT_EQ(g_dumpSn, 6);
ASSERT_EQ(g_exitSn, 7);
}
TEST_F(TestControllerStateMachine, zit_state)
{
g_downgrade = true;
InitSource();
stateMachinePtr_->StartStateMachine();
sleep(1);
ASSERT_EQ(g_initSn, 1);
ASSERT_EQ(g_normalSn, 2);
ASSERT_EQ(g_abnormalSn, 3);
ASSERT_EQ(g_envclearSn, 4);
ASSERT_EQ(g_dgRepairSn, 5);
ASSERT_EQ(g_downgradeSn, 6);
ASSERT_EQ(g_upgradeSn, 7);
ASSERT_EQ(g_dumpSn, 8);
ASSERT_EQ(g_exitSn, 9);
g_downgrade = false;
}
TEST_F(TestControllerStateMachine, pause_state)
{
g_pause = true;
InitSource();
stateMachinePtr_->StartStateMachine();
sleep(1);
ASSERT_EQ(g_initSn, CHECK_COUNT_ONE);
ASSERT_EQ(g_normalSn, CHECK_COUNT_TWO);
ASSERT_EQ(g_pauseSn, CHECK_COUNT_THREE);
ASSERT_EQ(g_abnormalSn, CHECK_COUNT_FOUR);
ASSERT_EQ(g_envclearSn, CHECK_COUNT_FIVE);
ASSERT_EQ(g_repairSn, CHECK_COUNT_SIX);
ASSERT_EQ(g_dumpSn, CHECK_COUNT_SEVEN);
ASSERT_EQ(g_exitSn, CHECK_COUNT_EIGHT);
g_pause = false;
}
}