From 3a4538a82cc5801ab4ccac567e633dded17563e4 Mon Sep 17 00:00:00 2001 From: Fancy code <258828110.@qq.com> Date: Tue, 16 Jul 2024 21:52:03 +0800 Subject: [PATCH] Improve:system mock code. --- .../MissionManager/src/FormattingState.cpp | 2 +- test/CMakeLists.txt | 1 + .../src_mock/DeviceManager_Mock_Test.cpp | 3 +- test/hal/tool/include/HalTestTool.h | 3 + test/hal/tool/src/HalTestTool.cpp | 9 +++ test/hal/tool/src/SdCardHalMock.cpp | 5 ++ test/hal/tool/src/SdCardHalMock.h | 1 + test/middleware/HuntingUpgrade/CMakeLists.txt | 2 +- .../utils/LinuxApiMock/include/LinuxApiMock.h | 3 + test/utils/LinuxApiMock/src/LinuxApiMock.cpp | 14 ++++ test/utils/LinuxApiMock/src/LinuxTestImpl.cpp | 75 +++++++++++++++++++ test/utils/LinuxApiMock/src/LinuxTestImpl.h | 5 ++ test/utils/LinuxApiMock/src/WrapApi.cpp | 6 ++ test/utils/LinuxApiMock/src/WrapApi.h | 1 + test/utils/SharedData/CMakeLists.txt | 6 +- 15 files changed, 128 insertions(+), 8 deletions(-) diff --git a/application/MissionManager/src/FormattingState.cpp b/application/MissionManager/src/FormattingState.cpp index ef8eaa5..4f6ad9b 100644 --- a/application/MissionManager/src/FormattingState.cpp +++ b/application/MissionManager/src/FormattingState.cpp @@ -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"); } \ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 921a6cf..095ffbe 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -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}") diff --git a/test/application/HuntingCamera/src_mock/DeviceManager_Mock_Test.cpp b/test/application/HuntingCamera/src_mock/DeviceManager_Mock_Test.cpp index e6f8d1d..c860389 100644 --- a/test/application/HuntingCamera/src_mock/DeviceManager_Mock_Test.cpp +++ b/test/application/HuntingCamera/src_mock/DeviceManager_Mock_Test.cpp @@ -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(); diff --git a/test/hal/tool/include/HalTestTool.h b/test/hal/tool/include/HalTestTool.h index 52d619e..39e8014 100644 --- a/test/hal/tool/include/HalTestTool.h +++ b/test/hal/tool/include/HalTestTool.h @@ -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 &mock); void MockSdCardInsert(std::shared_ptr &mock); + void MockSdCardFormatReturn(std::shared_ptr &mock, const int &systemResult); public: static std::shared_ptr MakeKeyHalTest(const std::string &keyName); diff --git a/test/hal/tool/src/HalTestTool.cpp b/test/hal/tool/src/HalTestTool.cpp index d8db9cd..4f0a45f 100644 --- a/test/hal/tool/src/HalTestTool.cpp +++ b/test/hal/tool/src/HalTestTool.cpp @@ -365,6 +365,15 @@ void HalTestTool::MockSdCardInsert(std::shared_ptr &mock) } sdCardHal->MockSdCardInsert(mock); } +void HalTestTool::MockSdCardFormatReturn(std::shared_ptr &mock, const int &systemResult) +{ + std::shared_ptr sdCardHal = std::dynamic_pointer_cast(mSdCardHal); + if (nullptr == sdCardHal) { + LogError("SdCardHalMock is null.\n"); + return; + } + sdCardHal->MockSdCardFormatResult(mock, systemResult); +} std::shared_ptr HalTestTool::MakeKeyHalTest(const std::string &keyName) { std::shared_ptr key = std::make_shared(keyName); diff --git a/test/hal/tool/src/SdCardHalMock.cpp b/test/hal/tool/src/SdCardHalMock.cpp index 847957d..efff5c5 100644 --- a/test/hal/tool/src/SdCardHalMock.cpp +++ b/test/hal/tool/src/SdCardHalMock.cpp @@ -47,4 +47,9 @@ void SdCardHalMock::MockSdCardRemove(std::shared_ptr &mock) void SdCardHalMock::MockSdCardInsert(std::shared_ptr &mock) { EXPECT_CALL(*mock.get(), fx_access(SD_CARD_DEVICE, F_OK)).WillRepeatedly(DoAll(Return(FILE_EXIST))); +} +void SdCardHalMock::MockSdCardFormatResult(std::shared_ptr &mock, const int &result) +{ + LinuxTest::SetSystemCommandResult(mock, "mkfs.vfat", result); + LinuxTest::SetSystemCommandResult(mock, "umount", result); } \ No newline at end of file diff --git a/test/hal/tool/src/SdCardHalMock.h b/test/hal/tool/src/SdCardHalMock.h index bf7f5e2..94d4169 100644 --- a/test/hal/tool/src/SdCardHalMock.h +++ b/test/hal/tool/src/SdCardHalMock.h @@ -25,6 +25,7 @@ public: void SetLinuxTest(std::shared_ptr &mock); void MockSdCardRemove(std::shared_ptr &mock); void MockSdCardInsert(std::shared_ptr &mock); + void MockSdCardFormatResult(std::shared_ptr &mock, const int &result); private: std::shared_ptr mLinuxTest; diff --git a/test/middleware/HuntingUpgrade/CMakeLists.txt b/test/middleware/HuntingUpgrade/CMakeLists.txt index 77999f0..afbd69c 100644 --- a/test/middleware/HuntingUpgrade/CMakeLists.txt +++ b/test/middleware/HuntingUpgrade/CMakeLists.txt @@ -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() diff --git a/test/utils/LinuxApiMock/include/LinuxApiMock.h b/test/utils/LinuxApiMock/include/LinuxApiMock.h index f1d6eae..93d4bb8 100644 --- a/test/utils/LinuxApiMock/include/LinuxApiMock.h +++ b/test/utils/LinuxApiMock/include/LinuxApiMock.h @@ -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 CreateLinuxTest(void); + static void SetSystemCommandResult(std::shared_ptr &mock, const std::string &command, const int &result); }; #endif \ No newline at end of file diff --git a/test/utils/LinuxApiMock/src/LinuxApiMock.cpp b/test/utils/LinuxApiMock/src/LinuxApiMock.cpp index e719089..52c0f59 100644 --- a/test/utils/LinuxApiMock/src/LinuxApiMock.cpp +++ b/test/utils/LinuxApiMock/src/LinuxApiMock.cpp @@ -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::CreateLinuxTest(void) { std::shared_ptr test = std::make_shared(); LinuxTestImpl::ApiInit(test); return test; } +void LinuxTest::SetSystemCommandResult(std::shared_ptr &mock, const std::string &command, const int &result) +{ + std::shared_ptr test = std::dynamic_pointer_cast(mock); + if (test) { + test->SetSystemReturn(command, result); + return; + } + LogWarning("The mock is null.\n"); +} int LinuxTest::GetHandleForMock(void) { return INVALID_HANDLE; diff --git a/test/utils/LinuxApiMock/src/LinuxTestImpl.cpp b/test/utils/LinuxApiMock/src/LinuxTestImpl.cpp index 4720b57..3a236b3 100644 --- a/test/utils/LinuxApiMock/src/LinuxTestImpl.cpp +++ b/test/utils/LinuxApiMock/src/LinuxTestImpl.cpp @@ -21,6 +21,7 @@ #include #endif #include +#include #include #include #include @@ -136,6 +137,26 @@ void LinuxTestImpl::ApiInit(std::shared_ptr &mock) WithArgs<0, 1>(Invoke(api_fopen)), Invoke((std::dynamic_pointer_cast(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 testLinuxApi = std::dynamic_pointer_cast(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(mock)).get(), &LinuxTestImpl::ApiLock), + WithArgs<0>(Invoke(api_system)), + Invoke((std::dynamic_pointer_cast(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 mock = LinuxTest::shared_from_this(); + std::weak_ptr 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 testLinuxApi = std::dynamic_pointer_cast(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(mock)).get(), &LinuxTestImpl::ApiLock), + WithArgs<0>(Invoke(api_system)), + Invoke((std::dynamic_pointer_cast(mock)).get(), &LinuxTestImpl::ApiUnlockThread), + ReturnPointee(&systemResult))); +} void LinuxTestImpl::ApiUnlockThread(void) { // LogInfo("ApiUnlockThread\n"); @@ -173,4 +230,22 @@ void LinuxTestImpl::ApiUnlockThread(void) // }; // std::shared_ptr test = std::dynamic_pointer_cast(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; } \ No newline at end of file diff --git a/test/utils/LinuxApiMock/src/LinuxTestImpl.h b/test/utils/LinuxApiMock/src/LinuxTestImpl.h index 1a5623c..2d3c20f 100644 --- a/test/utils/LinuxApiMock/src/LinuxTestImpl.h +++ b/test/utils/LinuxApiMock/src/LinuxTestImpl.h @@ -17,6 +17,7 @@ #include "HandleManager.h" #include "LinuxApiMock.h" #include "WrapApi.h" +#include #include #include /** @@ -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 &mock); @@ -45,5 +49,6 @@ public: private: std::mutex mApiMutex; std::thread mApiThread; + std::map mSystemReturn; }; #endif \ No newline at end of file diff --git a/test/utils/LinuxApiMock/src/WrapApi.cpp b/test/utils/LinuxApiMock/src/WrapApi.cpp index b994ee5..19f3d14 100644 --- a/test/utils/LinuxApiMock/src/WrapApi.cpp +++ b/test/utils/LinuxApiMock/src/WrapApi.cpp @@ -77,6 +77,12 @@ FILE *__wrap_fx_fopen(const char *pathname, const char *mode) std::lock_guard locker(gMutex); return LinuxApiMock::GetInstance()->fx_fopen(pathname, mode); } +int __wrap_fx_system(const char *command) +{ + static std::mutex gMutex; + std::lock_guard locker(gMutex); + return LinuxApiMock::GetInstance()->fx_system(command); +} #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/test/utils/LinuxApiMock/src/WrapApi.h b/test/utils/LinuxApiMock/src/WrapApi.h index 734729c..d10b96c 100644 --- a/test/utils/LinuxApiMock/src/WrapApi.h +++ b/test/utils/LinuxApiMock/src/WrapApi.h @@ -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 diff --git a/test/utils/SharedData/CMakeLists.txt b/test/utils/SharedData/CMakeLists.txt index 4f3b70e..89a4764 100644 --- a/test/utils/SharedData/CMakeLists.txt +++ b/test/utils/SharedData/CMakeLists.txt @@ -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()