Improve:system mock code.

This commit is contained in:
Fancy code 2024-07-16 21:52:03 +08:00
parent 93cb0f8573
commit 3a4538a82c
15 changed files with 128 additions and 8 deletions

View File

@ -65,6 +65,6 @@ void FormattingState::FormattingThread(void)
IFilesManager::GetInstance()->UnInit();
IStorageManager::GetInstance()->FormatSDCardNow();
// IFilesManager::GetInstance()->Init();
MissionStateMachine::GetInstance()->SwitchState(SystemState::IDLE_STATE);
// MissionStateMachine::GetInstance()->SwitchState(SystemState::IDLE_STATE);
LogInfo("Formatting SD card done.\n");
}

View File

@ -28,6 +28,7 @@ if(${TARGET_PLATFORM} MATCHES ${DEFINE_LINUX})
set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=fx_read" CACHE STRING INTERNAL FORCE)
set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=fx_access" CACHE STRING INTERNAL FORCE)
set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=fx_fopen" CACHE STRING INTERNAL FORCE)
set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=fx_system" CACHE STRING INTERNAL FORCE)
endif()
# Mock Linux api.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${TEST_LINUX_MOCK}")

View File

@ -74,8 +74,9 @@ TEST_F(HuntingCameraTest, HS_INTEGRATION_HunttingCamera_EXAMPLE_FormatSDCard)
{
SetAllCamerasResult(mAllCamerasMock);
MockOtherSideIpcMissionReply(IpcMission::TEST);
MockSdCardFormatReturn(mLinuxTest, FORMAT_SD_CARD_SUCESS);
MainThread::GetInstance()->Init();
TestManager::ResetTimeOut(1000 * 17);
TestManager::ResetTimeOut(1000 * 25);
HalTestTool::MockKeyClick("format", 1000 * 18); // Simulate pressing a button.
std::this_thread::sleep_for(std::chrono::milliseconds(100));
MainThread::GetInstance()->Runing();

View File

@ -18,6 +18,8 @@
#include "IHalCpp.h"
#include "LedControl.h"
#include "LinuxApiMock.h"
constexpr int FORMAT_SD_CARD_SUCESS = 0;
constexpr int FORMAT_SD_CARD_FAIL = -1;
class HalTestTool
{
public:
@ -71,6 +73,7 @@ private: // About camera hal
protected: // About sd card hal
void MockSdCardRemove(std::shared_ptr<LinuxTest> &mock);
void MockSdCardInsert(std::shared_ptr<LinuxTest> &mock);
void MockSdCardFormatReturn(std::shared_ptr<LinuxTest> &mock, const int &systemResult);
public:
static std::shared_ptr<VKeyHal> MakeKeyHalTest(const std::string &keyName);

View File

@ -365,6 +365,15 @@ void HalTestTool::MockSdCardInsert(std::shared_ptr<LinuxTest> &mock)
}
sdCardHal->MockSdCardInsert(mock);
}
void HalTestTool::MockSdCardFormatReturn(std::shared_ptr<LinuxTest> &mock, const int &systemResult)
{
std::shared_ptr<SdCardHalMock> sdCardHal = std::dynamic_pointer_cast<SdCardHalMock>(mSdCardHal);
if (nullptr == sdCardHal) {
LogError("SdCardHalMock is null.\n");
return;
}
sdCardHal->MockSdCardFormatResult(mock, systemResult);
}
std::shared_ptr<VKeyHal> HalTestTool::MakeKeyHalTest(const std::string &keyName)
{
std::shared_ptr<VKeyHal> key = std::make_shared<KeyControlMock>(keyName);

View File

@ -47,4 +47,9 @@ void SdCardHalMock::MockSdCardRemove(std::shared_ptr<LinuxTest> &mock)
void SdCardHalMock::MockSdCardInsert(std::shared_ptr<LinuxTest> &mock)
{
EXPECT_CALL(*mock.get(), fx_access(SD_CARD_DEVICE, F_OK)).WillRepeatedly(DoAll(Return(FILE_EXIST)));
}
void SdCardHalMock::MockSdCardFormatResult(std::shared_ptr<LinuxTest> &mock, const int &result)
{
LinuxTest::SetSystemCommandResult(mock, "mkfs.vfat", result);
LinuxTest::SetSystemCommandResult(mock, "umount", result);
}

View File

@ -25,6 +25,7 @@ public:
void SetLinuxTest(std::shared_ptr<LinuxTest> &mock);
void MockSdCardRemove(std::shared_ptr<LinuxTest> &mock);
void MockSdCardInsert(std::shared_ptr<LinuxTest> &mock);
void MockSdCardFormatResult(std::shared_ptr<LinuxTest> &mock, const int &result);
private:
std::shared_ptr<LinuxTest> mLinuxTest;

View File

@ -32,7 +32,7 @@ endif()
set(TARGET_NAME HuntingUpgradeTest)
add_executable(${TARGET_NAME} ${SRC_FILES_MAIN} ${SRC_FILES})
target_link_libraries(${TARGET_NAME} HuntingUpgradeTestTool gtest gmock pthread)
target_link_libraries(${TARGET_NAME} HuntingUpgradeTestTool LinuxApiMock gtest gmock pthread)
if(${TEST_COVERAGE} MATCHES "true")
target_link_libraries(${TARGET_NAME} gcov)
endif()

View File

@ -35,6 +35,7 @@ public:
virtual int fx_fstat(int fd, struct stat *statbuf);
virtual int fx_access(const char *pathname, int mode);
virtual FILE *fx_fopen(const char *pathname, const char *mode);
virtual int fx_system(const char *command);
};
/**
* A simulation interface class used for automated testing in Ubuntu systems, implementing the function of piling on
@ -54,6 +55,7 @@ public:
MOCK_METHOD2(fx_fstat, int(int, struct stat *));
MOCK_METHOD2(fx_access, int(const char *, int));
MOCK_METHOD2(fx_fopen, FILE *(const char *, const char *));
MOCK_METHOD1(fx_system, int(const char *));
public:
/**
@ -67,5 +69,6 @@ public:
public:
static std::shared_ptr<LinuxTest> CreateLinuxTest(void);
static void SetSystemCommandResult(std::shared_ptr<LinuxTest> &mock, const std::string &command, const int &result);
};
#endif

View File

@ -13,6 +13,7 @@
* limitations under the License.
*/
#include "LinuxApiMock.h"
#include "ILog.h"
#include "LinuxTestImpl.h"
#include "WrapApi.h"
#if defined(__x86_64__)
@ -81,12 +82,25 @@ FILE *LinuxApiMock::fx_fopen(const char *pathname, const char *mode)
{
return __real_fx_fopen(pathname, mode);
}
int LinuxApiMock::fx_system(const char *command)
{
return __real_fx_system(command);
}
std::shared_ptr<LinuxTest> LinuxTest::CreateLinuxTest(void)
{
std::shared_ptr<LinuxTest> test = std::make_shared<LinuxTestImpl>();
LinuxTestImpl::ApiInit(test);
return test;
}
void LinuxTest::SetSystemCommandResult(std::shared_ptr<LinuxTest> &mock, const std::string &command, const int &result)
{
std::shared_ptr<LinuxTestImpl> test = std::dynamic_pointer_cast<LinuxTestImpl>(mock);
if (test) {
test->SetSystemReturn(command, result);
return;
}
LogWarning("The mock is null.\n");
}
int LinuxTest::GetHandleForMock(void)
{
return INVALID_HANDLE;

View File

@ -21,6 +21,7 @@
#include <bits/types/struct_timeval.h>
#endif
#include <gmock/gmock-spec-builders.h>
#include <map>
#include <memory>
#include <stdio.h>
#include <sys/select.h>
@ -136,6 +137,26 @@ void LinuxTestImpl::ApiInit(std::shared_ptr<LinuxTest> &mock)
WithArgs<0, 1>(Invoke(api_fopen)),
Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiUnlockThread),
ReturnPointee(&fopenResult)));
static int systemResult = -1;
auto api_system = [=](const char *command) {
// char command_buf[1024] = {0};
// size_t length = strcspn(command, " ");
// strncpy(command_buf, command, length);
// command_buf[length] = '\0';
// std::shared_ptr<LinuxTestImpl> testLinuxApi = std::dynamic_pointer_cast<LinuxTestImpl>(mock);
// if (testLinuxApi && testLinuxApi->CheckIfNeedToMockSystem(command)) {
// systemResult = testLinuxApi->ReturnMockSystem(command);
// }
// else {
systemResult = __real_fx_system(command);
// }
};
EXPECT_CALL(*mock.get(), fx_system(_))
.WillRepeatedly(
DoAll(Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiLock),
WithArgs<0>(Invoke(api_system)),
Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiUnlockThread),
ReturnPointee(&systemResult)));
}
void LinuxTestImpl::Init()
{
@ -161,6 +182,42 @@ void LinuxTestImpl::ApiUnlock(void)
// mApiMutex.unlock();
// LogInfo("unlock api.\n");
}
void LinuxTestImpl::SetSystemReturn(const std::string &command, const int &returnValue)
{
LogInfo(" command = %s, return value = %d\n", command.c_str(), returnValue);
mSystemReturn[command] = returnValue;
if (mSystemReturn.size() > 1) {
return;
}
static int systemResult = -1;
std::shared_ptr<LinuxTest> mock = LinuxTest::shared_from_this();
std::weak_ptr<LinuxTest> weakMock = mock;
auto api_system = [=](const char *command) {
char command_buf[1024] = {0};
size_t length = strcspn(command, " ");
strncpy(command_buf, command, length);
command_buf[length] = '\0';
auto mock = weakMock.lock();
if (weakMock.expired()) {
LogWarning("weakMock is expired.\n");
systemResult = __real_fx_system(command);
return;
}
std::shared_ptr<LinuxTestImpl> testLinuxApi = std::dynamic_pointer_cast<LinuxTestImpl>(mock);
if (testLinuxApi && testLinuxApi->CheckIfNeedToMockSystem(command_buf)) {
systemResult = testLinuxApi->ReturnMockSystem(command_buf);
}
else {
systemResult = __real_fx_system(command);
}
};
EXPECT_CALL(*mock.get(), fx_system(_))
.WillRepeatedly(
DoAll(Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiLock),
WithArgs<0>(Invoke(api_system)),
Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiUnlockThread),
ReturnPointee(&systemResult)));
}
void LinuxTestImpl::ApiUnlockThread(void)
{
// LogInfo("ApiUnlockThread\n");
@ -173,4 +230,22 @@ void LinuxTestImpl::ApiUnlockThread(void)
// };
// std::shared_ptr<LinuxTestImpl> test = std::dynamic_pointer_cast<LinuxTestImpl>(LinuxTest::shared_from_this());
// mApiThread = std::thread(api_unlock, test);
}
int LinuxTestImpl::ReturnMockSystem(const std::string &command)
{
auto returnInt = mSystemReturn.find(command);
if (returnInt != mSystemReturn.end()) {
LogInfo("command = %s, return value = %d\n", command.c_str(), returnInt->second);
return returnInt->second;
}
LogWarning("command = %s, return value not found.\n", command.c_str());
return -1;
}
bool LinuxTestImpl::CheckIfNeedToMockSystem(const std::string &command)
{
auto returnInt = mSystemReturn.find(command);
if (returnInt != mSystemReturn.end()) {
return true;
}
return false;
}

View File

@ -17,6 +17,7 @@
#include "HandleManager.h"
#include "LinuxApiMock.h"
#include "WrapApi.h"
#include <map>
#include <mutex>
#include <thread>
/**
@ -35,9 +36,12 @@ public:
void UnInit() override;
void ApiLock(void);
void ApiUnlock(void);
void SetSystemReturn(const std::string &command, const int &returnValue);
private:
void ApiUnlockThread(void);
int ReturnMockSystem(const std::string &command);
bool CheckIfNeedToMockSystem(const std::string &command);
public:
static void ApiInit(std::shared_ptr<LinuxTest> &mock);
@ -45,5 +49,6 @@ public:
private:
std::mutex mApiMutex;
std::thread mApiThread;
std::map<std::string, int> mSystemReturn;
};
#endif

View File

@ -77,6 +77,12 @@ FILE *__wrap_fx_fopen(const char *pathname, const char *mode)
std::lock_guard<std::mutex> locker(gMutex);
return LinuxApiMock::GetInstance()->fx_fopen(pathname, mode);
}
int __wrap_fx_system(const char *command)
{
static std::mutex gMutex;
std::lock_guard<std::mutex> locker(gMutex);
return LinuxApiMock::GetInstance()->fx_system(command);
}
#ifdef __cplusplus
}
#endif

View File

@ -32,6 +32,7 @@ int __real_fx_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *except
int __real_fx_fstat(int fd, struct stat *statbuf);
int __real_fx_access(const char *pathname, int mode);
FILE *__real_fx_fopen(const char *pathname, const char *mode);
int __real_fx_system(const char *command);
#ifdef __cplusplus
}
#endif

View File

@ -15,16 +15,12 @@ link_directories(
${EXTERNAL_LIBS_OUTPUT_PATH}
)
aux_source_directory(. SRC_FILES)
aux_source_directory(./src SRC_FILES)
set(TARGET_NAME SharedDataTest)
add_executable(${TARGET_NAME} ${SRC_FILES})
target_link_libraries(${TARGET_NAME} SharedData gtest gmock pthread Log)
target_link_libraries(${TARGET_NAME} SharedData LinuxApiMock gtest gmock pthread Log)
if(${TEST_COVERAGE} MATCHES "true")
target_link_libraries(${TARGET_NAME} gcov)
endif()