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(); IFilesManager::GetInstance()->UnInit();
IStorageManager::GetInstance()->FormatSDCardNow(); IStorageManager::GetInstance()->FormatSDCardNow();
// IFilesManager::GetInstance()->Init(); // IFilesManager::GetInstance()->Init();
MissionStateMachine::GetInstance()->SwitchState(SystemState::IDLE_STATE); // MissionStateMachine::GetInstance()->SwitchState(SystemState::IDLE_STATE);
LogInfo("Formatting SD card done.\n"); 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_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_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_fopen" CACHE STRING INTERNAL FORCE)
set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=fx_system" CACHE STRING INTERNAL FORCE)
endif() endif()
# Mock Linux api. # Mock Linux api.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${TEST_LINUX_MOCK}") 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); SetAllCamerasResult(mAllCamerasMock);
MockOtherSideIpcMissionReply(IpcMission::TEST); MockOtherSideIpcMissionReply(IpcMission::TEST);
MockSdCardFormatReturn(mLinuxTest, FORMAT_SD_CARD_SUCESS);
MainThread::GetInstance()->Init(); MainThread::GetInstance()->Init();
TestManager::ResetTimeOut(1000 * 17); TestManager::ResetTimeOut(1000 * 25);
HalTestTool::MockKeyClick("format", 1000 * 18); // Simulate pressing a button. HalTestTool::MockKeyClick("format", 1000 * 18); // Simulate pressing a button.
std::this_thread::sleep_for(std::chrono::milliseconds(100)); std::this_thread::sleep_for(std::chrono::milliseconds(100));
MainThread::GetInstance()->Runing(); MainThread::GetInstance()->Runing();

View File

@ -18,6 +18,8 @@
#include "IHalCpp.h" #include "IHalCpp.h"
#include "LedControl.h" #include "LedControl.h"
#include "LinuxApiMock.h" #include "LinuxApiMock.h"
constexpr int FORMAT_SD_CARD_SUCESS = 0;
constexpr int FORMAT_SD_CARD_FAIL = -1;
class HalTestTool class HalTestTool
{ {
public: public:
@ -71,6 +73,7 @@ private: // About camera hal
protected: // About sd card hal protected: // About sd card hal
void MockSdCardRemove(std::shared_ptr<LinuxTest> &mock); void MockSdCardRemove(std::shared_ptr<LinuxTest> &mock);
void MockSdCardInsert(std::shared_ptr<LinuxTest> &mock); void MockSdCardInsert(std::shared_ptr<LinuxTest> &mock);
void MockSdCardFormatReturn(std::shared_ptr<LinuxTest> &mock, const int &systemResult);
public: public:
static std::shared_ptr<VKeyHal> MakeKeyHalTest(const std::string &keyName); 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); 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> HalTestTool::MakeKeyHalTest(const std::string &keyName)
{ {
std::shared_ptr<VKeyHal> key = std::make_shared<KeyControlMock>(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) void SdCardHalMock::MockSdCardInsert(std::shared_ptr<LinuxTest> &mock)
{ {
EXPECT_CALL(*mock.get(), fx_access(SD_CARD_DEVICE, F_OK)).WillRepeatedly(DoAll(Return(FILE_EXIST))); 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 SetLinuxTest(std::shared_ptr<LinuxTest> &mock);
void MockSdCardRemove(std::shared_ptr<LinuxTest> &mock); void MockSdCardRemove(std::shared_ptr<LinuxTest> &mock);
void MockSdCardInsert(std::shared_ptr<LinuxTest> &mock); void MockSdCardInsert(std::shared_ptr<LinuxTest> &mock);
void MockSdCardFormatResult(std::shared_ptr<LinuxTest> &mock, const int &result);
private: private:
std::shared_ptr<LinuxTest> mLinuxTest; std::shared_ptr<LinuxTest> mLinuxTest;

View File

@ -32,7 +32,7 @@ endif()
set(TARGET_NAME HuntingUpgradeTest) set(TARGET_NAME HuntingUpgradeTest)
add_executable(${TARGET_NAME} ${SRC_FILES_MAIN} ${SRC_FILES}) 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") if(${TEST_COVERAGE} MATCHES "true")
target_link_libraries(${TARGET_NAME} gcov) target_link_libraries(${TARGET_NAME} gcov)
endif() endif()

View File

@ -35,6 +35,7 @@ public:
virtual int fx_fstat(int fd, struct stat *statbuf); virtual int fx_fstat(int fd, struct stat *statbuf);
virtual int fx_access(const char *pathname, int mode); virtual int fx_access(const char *pathname, int mode);
virtual FILE *fx_fopen(const char *pathname, const char *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 * 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_fstat, int(int, struct stat *));
MOCK_METHOD2(fx_access, int(const char *, int)); MOCK_METHOD2(fx_access, int(const char *, int));
MOCK_METHOD2(fx_fopen, FILE *(const char *, const char *)); MOCK_METHOD2(fx_fopen, FILE *(const char *, const char *));
MOCK_METHOD1(fx_system, int(const char *));
public: public:
/** /**
@ -67,5 +69,6 @@ public:
public: public:
static std::shared_ptr<LinuxTest> CreateLinuxTest(void); static std::shared_ptr<LinuxTest> CreateLinuxTest(void);
static void SetSystemCommandResult(std::shared_ptr<LinuxTest> &mock, const std::string &command, const int &result);
}; };
#endif #endif

View File

@ -13,6 +13,7 @@
* limitations under the License. * limitations under the License.
*/ */
#include "LinuxApiMock.h" #include "LinuxApiMock.h"
#include "ILog.h"
#include "LinuxTestImpl.h" #include "LinuxTestImpl.h"
#include "WrapApi.h" #include "WrapApi.h"
#if defined(__x86_64__) #if defined(__x86_64__)
@ -81,12 +82,25 @@ FILE *LinuxApiMock::fx_fopen(const char *pathname, const char *mode)
{ {
return __real_fx_fopen(pathname, 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> LinuxTest::CreateLinuxTest(void)
{ {
std::shared_ptr<LinuxTest> test = std::make_shared<LinuxTestImpl>(); std::shared_ptr<LinuxTest> test = std::make_shared<LinuxTestImpl>();
LinuxTestImpl::ApiInit(test); LinuxTestImpl::ApiInit(test);
return 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) int LinuxTest::GetHandleForMock(void)
{ {
return INVALID_HANDLE; return INVALID_HANDLE;

View File

@ -21,6 +21,7 @@
#include <bits/types/struct_timeval.h> #include <bits/types/struct_timeval.h>
#endif #endif
#include <gmock/gmock-spec-builders.h> #include <gmock/gmock-spec-builders.h>
#include <map>
#include <memory> #include <memory>
#include <stdio.h> #include <stdio.h>
#include <sys/select.h> #include <sys/select.h>
@ -136,6 +137,26 @@ void LinuxTestImpl::ApiInit(std::shared_ptr<LinuxTest> &mock)
WithArgs<0, 1>(Invoke(api_fopen)), WithArgs<0, 1>(Invoke(api_fopen)),
Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiUnlockThread), Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiUnlockThread),
ReturnPointee(&fopenResult))); 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() void LinuxTestImpl::Init()
{ {
@ -161,6 +182,42 @@ void LinuxTestImpl::ApiUnlock(void)
// mApiMutex.unlock(); // mApiMutex.unlock();
// LogInfo("unlock api.\n"); // 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) void LinuxTestImpl::ApiUnlockThread(void)
{ {
// LogInfo("ApiUnlockThread\n"); // 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()); // std::shared_ptr<LinuxTestImpl> test = std::dynamic_pointer_cast<LinuxTestImpl>(LinuxTest::shared_from_this());
// mApiThread = std::thread(api_unlock, test); // 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 "HandleManager.h"
#include "LinuxApiMock.h" #include "LinuxApiMock.h"
#include "WrapApi.h" #include "WrapApi.h"
#include <map>
#include <mutex> #include <mutex>
#include <thread> #include <thread>
/** /**
@ -35,9 +36,12 @@ public:
void UnInit() override; void UnInit() override;
void ApiLock(void); void ApiLock(void);
void ApiUnlock(void); void ApiUnlock(void);
void SetSystemReturn(const std::string &command, const int &returnValue);
private: private:
void ApiUnlockThread(void); void ApiUnlockThread(void);
int ReturnMockSystem(const std::string &command);
bool CheckIfNeedToMockSystem(const std::string &command);
public: public:
static void ApiInit(std::shared_ptr<LinuxTest> &mock); static void ApiInit(std::shared_ptr<LinuxTest> &mock);
@ -45,5 +49,6 @@ public:
private: private:
std::mutex mApiMutex; std::mutex mApiMutex;
std::thread mApiThread; std::thread mApiThread;
std::map<std::string, int> mSystemReturn;
}; };
#endif #endif

View File

@ -77,6 +77,12 @@ FILE *__wrap_fx_fopen(const char *pathname, const char *mode)
std::lock_guard<std::mutex> locker(gMutex); std::lock_guard<std::mutex> locker(gMutex);
return LinuxApiMock::GetInstance()->fx_fopen(pathname, mode); 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 #ifdef __cplusplus
} }
#endif #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_fstat(int fd, struct stat *statbuf);
int __real_fx_access(const char *pathname, int mode); int __real_fx_access(const char *pathname, int mode);
FILE *__real_fx_fopen(const char *pathname, const char *mode); FILE *__real_fx_fopen(const char *pathname, const char *mode);
int __real_fx_system(const char *command);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -15,16 +15,12 @@ link_directories(
${EXTERNAL_LIBS_OUTPUT_PATH} ${EXTERNAL_LIBS_OUTPUT_PATH}
) )
aux_source_directory(. SRC_FILES) aux_source_directory(. SRC_FILES)
aux_source_directory(./src SRC_FILES) aux_source_directory(./src SRC_FILES)
set(TARGET_NAME SharedDataTest) set(TARGET_NAME SharedDataTest)
add_executable(${TARGET_NAME} ${SRC_FILES}) 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") if(${TEST_COVERAGE} MATCHES "true")
target_link_libraries(${TARGET_NAME} gcov) target_link_libraries(${TARGET_NAME} gcov)
endif() endif()