diff --git a/README.md b/README.md index 4f9f28cd..57dbc3d9 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,8 @@ ### 1.2.1. Ubuntu系统 在项目根目录下执行命令: -``` + +```code make clean // 如果之前有跨平台编译过,需要先make clean make cmake // 构建源码,生成Makefile文件 cd cmake-shell/ // 在中间文件目录进行编译,把所有中间文件创建在此目录 @@ -27,11 +28,30 @@ make // 编译全部输出构建文件 参考: -``` +```code //build/cmake/toolchain/linux.toolchain.cmake //Makefile ```   参考上述文件新建一份配置文件,建议不要修改原文档,新建一个交叉编译工程,把IPC SDK工程作为子仓库进行git管理,维护SDK的绝对跨平台属性。 -  交叉编译请参考基于IPC SDK作为子仓库的工程配置,此处忽略。 \ No newline at end of file +  交叉编译请参考基于IPC SDK作为子仓库的工程配置,此处忽略。 + +### 1.2.3. 小技巧 + +#### 1.2.3.1. 代码阅读辅助工具(基于vscode) + +  为了方便代码跳转阅读,除了安装基本的c++插件外,结合cmake构建工具生成的compile_commands.json文件可实现代码之间的精准跳转。 + +**compile_commands.json文件生成路径:** + +```code +//cmake-shell/compile_commands.json +``` + +**compile_commands.json文件配置方法:** + +```code +在//.vscode/settings.json配置文件中添加: +"C_Cpp.default.compileCommands": "/home/xiaojiazhu/project/ipc-sdk/ipc/cmake-shell/compile_commands.json", +``` diff --git a/middleware/IpcConfig/CMakeLists.txt b/middleware/IpcConfig/CMakeLists.txt index b902352f..9bf3c391 100644 --- a/middleware/IpcConfig/CMakeLists.txt +++ b/middleware/IpcConfig/CMakeLists.txt @@ -10,6 +10,7 @@ include_directories( ${UTILS_SOURCE_PATH}/StatusCode/include ${UTILS_SOURCE_PATH}/Log/include ${UTILS_SOURCE_PATH}/ConfigBase/include + ${UTILS_SOURCE_PATH}/LinuxApi/include ) #do not rely on any other library #link_directories( @@ -20,7 +21,7 @@ aux_source_directory(./src SRC_FILES) set(TARGET_NAME IpcConfig) add_library(${TARGET_NAME} STATIC ${SRC_FILES}) -target_link_libraries(${TARGET_NAME} ConfigBase StatusCode Log) +target_link_libraries(${TARGET_NAME} LinuxApi ConfigBase StatusCode Log) if ("${COMPILE_IMPROVE_SUPPORT}" MATCHES "true") add_custom_target( diff --git a/middleware/IpcConfig/src/IpcConfigImpl.cpp b/middleware/IpcConfig/src/IpcConfigImpl.cpp index 417ef367..32f7e73b 100644 --- a/middleware/IpcConfig/src/IpcConfigImpl.cpp +++ b/middleware/IpcConfig/src/IpcConfigImpl.cpp @@ -14,6 +14,7 @@ */ #include "IpcConfigImpl.h" #include "ILog.h" +#include "LinuxApi.h" #include #include #include @@ -459,7 +460,7 @@ void IpcConfigImpl::ReadingConfigThread(void) char dirPath[DIR_PATH_LENGTH] = {0}; strncpy(dirPath, IPC_CONFIG_FILE_PATH, DIR_PATH_LENGTH - 1); char *lastSlash = strrchr(dirPath, '/'); - if (lastSlash == NULL) { + if (lastSlash == nullptr) { strcpy(dirPath, "."); } else { @@ -878,19 +879,20 @@ void IpcConfigImpl::ReadAllConfigParameters(void) ConfigSaveFile(mCfg); } } +const char *SYSTEM_MOUNTED_FILE = "/proc/mounts"; bool IpcConfigImpl::CheckConfigPathMounted(void) { - FILE *fp; + FILE *fp = nullptr; char line[1024]; char mount_point[1024] = {0}; - fp = fopen("/proc/mounts", "r"); - if (fp == NULL) { + fp = fx_fopen(SYSTEM_MOUNTED_FILE, "r"); + if (fp == nullptr) { perror("Error opening /proc/mounts"); return false; } - while (fgets(line, sizeof(line), fp) != NULL) { + while (fgets(line, sizeof(line), fp) != nullptr) { if (sscanf(line, "%*s %1023s %*s %*s %*d %*d\n", mount_point) == 1) { // LogInfo("mount_point: %s\n", mount_point); if (strcmp("/userdata", mount_point) == 0) { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 3967676f..cbd8e4cb 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -27,6 +27,7 @@ if(${TARGET_PLATFORM} MATCHES ${DEFINE_LINUX}) set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=fx_write" 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_fopen" CACHE STRING INTERNAL FORCE) endif() # Mock Linux api. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${TEST_LINUX_MOCK}") diff --git a/test/middleware/IpcConfig/CMakeLists.txt b/test/middleware/IpcConfig/CMakeLists.txt index 36b234ef..95b66409 100644 --- a/test/middleware/IpcConfig/CMakeLists.txt +++ b/test/middleware/IpcConfig/CMakeLists.txt @@ -13,6 +13,9 @@ include_directories( ${UTILS_SOURCE_PATH}/ConfigBase/include ${MIDDLEWARE_SOURCE_PATH}/IpcConfig/include ${MIDDLEWARE_SOURCE_PATH}/IpcConfig/src + ${TEST_SOURCE_PATH} + ${TEST_SOURCE_PATH}/middleware/IpcConfig/tool/include + ${TEST_SOURCE_PATH}/utils/LinuxApiMock/include ${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googletest/include ${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googlemock/include ) @@ -24,10 +27,13 @@ link_directories( aux_source_directory(. SRC_FILES_MAIN) aux_source_directory(./src SRC_FILES) +if(${TARGET_PLATFORM} MATCHES ${DEFINE_LINUX}) + aux_source_directory(./src_mock SRC_FILES) +endif() set(TARGET_NAME IpcConfigTest) add_executable(${TARGET_NAME} ${SRC_FILES_MAIN} ${SRC_FILES}) -target_link_libraries(${TARGET_NAME} IpcConfig LinuxApi gtest gmock pthread) +target_link_libraries(${TARGET_NAME} IpcConfigTestTool LinuxApi gtest gmock pthread) if(${TEST_COVERAGE} MATCHES "true") target_link_libraries(${TARGET_NAME} gcov) endif() @@ -69,4 +75,8 @@ add_custom_command( ) endif() -define_file_name(${TARGET_NAME}) \ No newline at end of file +define_file_name(${TARGET_NAME}) + +if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tool/CMakeLists.txt") + add_subdirectory(tool) +endif() \ No newline at end of file diff --git a/test/middleware/IpcConfig/src/IpcConfig_Test.cpp b/test/middleware/IpcConfig/src/IpcConfig_Test.cpp index 8947b8a2..9831828a 100644 --- a/test/middleware/IpcConfig/src/IpcConfig_Test.cpp +++ b/test/middleware/IpcConfig/src/IpcConfig_Test.cpp @@ -1,11 +1,23 @@ +/* + * Copyright (c) 2023 Fancy Code. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #include "IIpcConfig.h" #include "ILog.h" #include "IpcConfigImpl.h" #include "LinuxApi.h" // #include #include -extern const char *CONFIG_WIFI_SSID_DEFAULT; -extern const char *CONFIG_WIFI_PASSWORD_DEFAULT; namespace IpcConfigTest { // ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigDemo.Demo @@ -113,186 +125,4 @@ TEST(IpcConfigDemo, Demo) DestroyIpcConfigModule(); DestroyLogModule(); } -class IpcConfigTest : public testing::Test -{ -public: - IpcConfigTest() - { - } - virtual ~IpcConfigTest() - { - } - static void SetUpTestCase() - { - CreateLogModule(); - ILogInit(LOG_INSTANCE_TYPE_END); - } - static void TearDownTestCase() - { - ILogUnInit(); - DestroyLogModule(); - } - virtual void SetUp() - { - CreateIpcConfigModule(); - IIpcConfig::GetInstance()->Init(); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } - virtual void TearDown() - { - IIpcConfig::GetInstance()->UnInit(); - DestroyIpcConfigModule(); - RemoveConfigFile(); - } - -private: - void RemoveConfigFile(void) - { - constexpr int FIEL_EXIST = 0; - if (FIEL_EXIST == access(IPC_CONFIG_FILE_PATH, F_OK)) { - constexpr int BUFF_SIZE = 128; - char cmd[BUFF_SIZE] = {0}; - snprintf(cmd, BUFF_SIZE, "rm -f %s", IPC_CONFIG_FILE_PATH); - fx_system(cmd); - } - } -}; -// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_WifiSsid -TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_WifiSsid) -{ - const char *MODIFIED_STRING = "modified_string"; - const char *MODIFIED_STRING_SHORTER = "modified"; - const char *LONG_STRING = - "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL" - "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL"; - std::string config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_SSID); - LogInfo("Get wifi ssid = %s\n", config.c_str()); - EXPECT_STREQ(config.c_str(), CONFIG_WIFI_SSID_DEFAULT); - IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_SSID, MODIFIED_STRING); - config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_SSID); - LogInfo("Get wifiSsid = %s\n", config.c_str()); - EXPECT_STREQ(config.c_str(), MODIFIED_STRING); - IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_SSID, LONG_STRING); - config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_SSID); - EXPECT_STREQ(config.c_str(), MODIFIED_STRING); - IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_SSID, ""); - config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_SSID); - EXPECT_STREQ(config.c_str(), ""); - IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_SSID, MODIFIED_STRING_SHORTER); - config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_SSID); - EXPECT_STREQ(config.c_str(), MODIFIED_STRING_SHORTER); - IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_SSID, MODIFIED_STRING); - config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_SSID); - EXPECT_STREQ(config.c_str(), MODIFIED_STRING); -} -// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_WifiPassword -TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_WifiPassword) -{ - const char *MODIFIED_STRING = "99999999"; - const char *MODIFIED_STRING_SHORTER = "999"; - const char *LONG_STRING = - "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL" - "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL"; - std::string config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_PASSWORD); - LogInfo("Get wifi password = %s\n", config.c_str()); - EXPECT_STREQ(config.c_str(), CONFIG_WIFI_PASSWORD_DEFAULT); - IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_PASSWORD, MODIFIED_STRING); - config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_PASSWORD); - LogInfo("Get wifi password = %s\n", config.c_str()); - EXPECT_STREQ(config.c_str(), MODIFIED_STRING); - IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_PASSWORD, LONG_STRING); - config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_PASSWORD); - EXPECT_STREQ(config.c_str(), MODIFIED_STRING); - IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_PASSWORD, ""); - config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_PASSWORD); - EXPECT_STREQ(config.c_str(), ""); - IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_PASSWORD, MODIFIED_STRING_SHORTER); - config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_PASSWORD); - EXPECT_STREQ(config.c_str(), MODIFIED_STRING_SHORTER); - IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_PASSWORD, MODIFIED_STRING); - config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_PASSWORD); - EXPECT_STREQ(config.c_str(), MODIFIED_STRING); -} -// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_WorkMode -TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_WorkMode) -{ - WorkMode config = IIpcConfig::GetInstance()->GetWorkMode(); - EXPECT_EQ(static_cast(config), static_cast(CONFIG_WORK_MODE_DEFAULT)); - IIpcConfig::GetInstance()->SetWorkMode(WorkMode::MODE_PIC_VIDEO); - config = IIpcConfig::GetInstance()->GetWorkMode(); - EXPECT_EQ(static_cast(config), static_cast(WorkMode::MODE_PIC_VIDEO)); -} -// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_ContinueShot -TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_ContinueShot) -{ - int config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::CONTINUOUS_SHOT); - EXPECT_EQ(config, CONFIG_CONTINUE_SHOT_DEFAULT); - IIpcConfig::GetInstance()->SetInt(IpcConfigKey::CONTINUOUS_SHOT, 2); - config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::CONTINUOUS_SHOT); - EXPECT_EQ(config, 2); -} -// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_BurstPhotoInterval -TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_BurstPhotoInterval) -{ - int config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::BURST_PHOTO_INTERVAL); - EXPECT_EQ(config, CONFIG_BURST_PHOTO_INTERVAL_DEFAULT); - IIpcConfig::GetInstance()->SetInt(IpcConfigKey::BURST_PHOTO_INTERVAL, 10); - config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::BURST_PHOTO_INTERVAL); - EXPECT_EQ(config, 10); -} -// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_ImageSize -TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_ImageSize) -{ - int config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::IMGAE_SIZE); - EXPECT_EQ(config, CONFIG_IMAGE_SIZE_DEFAULT); - IIpcConfig::GetInstance()->SetInt(IpcConfigKey::IMGAE_SIZE, 16); - config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::IMGAE_SIZE); - EXPECT_EQ(config, 16); -} -// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_VideoLength -TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_VideoLength) -{ - int config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::VIDEO_LENGTH); - EXPECT_EQ(config, CONFIG_VIDEO_SIZE_DEFAULT); - IIpcConfig::GetInstance()->SetInt(IpcConfigKey::VIDEO_LENGTH, 15); - config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::VIDEO_LENGTH); - EXPECT_EQ(config, 15); -} -// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_PirDelayed -TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_PirDelayed) -{ - int config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::PIR_DELAYED); - EXPECT_EQ(config, CONFIG_PIR_DELAYED_DEFAULT); - IIpcConfig::GetInstance()->SetInt(IpcConfigKey::PIR_DELAYED, 15); - config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::PIR_DELAYED); - EXPECT_EQ(config, 15); -} -// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_StorageLoop -TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_StorageLoop) -{ - ConfigSwitch config = IIpcConfig::GetInstance()->GetSwitch(IpcConfigKey::STORAGE_LOOP_SWITCH); - EXPECT_EQ(static_cast(config), - static_cast(CONFIG_STORAGE_LOOP_DEFAULT == true ? ConfigSwitch::ON : ConfigSwitch::OFF)); - IIpcConfig::GetInstance()->SetSwitch(IpcConfigKey::STORAGE_LOOP_SWITCH, ConfigSwitch::OFF); - config = IIpcConfig::GetInstance()->GetSwitch(IpcConfigKey::STORAGE_LOOP_SWITCH); - EXPECT_EQ(static_cast(config), static_cast(ConfigSwitch::OFF)); -} -// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_InfraredPower -TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_InfraredPower) -{ - ConfigLevel config = IIpcConfig::GetInstance()->GetLevel(IpcConfigKey::INFRARED_POWER); - EXPECT_EQ(static_cast(config), static_cast(CONFIG_INFRARED_POWER_DEFAULT)); - IIpcConfig::GetInstance()->SetLevel(IpcConfigKey::INFRARED_POWER, ConfigLevel::HIGHT); - config = IIpcConfig::GetInstance()->GetLevel(IpcConfigKey::INFRARED_POWER); - EXPECT_EQ(static_cast(config), static_cast(ConfigSwitch::OFF)); -} -// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_PirSensitivity -TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_PirSensitivity) -{ - int config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::PIR_SENSITIVITY); - EXPECT_EQ(config, CONFIG_PIR_SENSITIVITY_DEFAULT); - IIpcConfig::GetInstance()->SetInt(IpcConfigKey::PIR_SENSITIVITY, 0); - config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::PIR_SENSITIVITY); - EXPECT_EQ(config, 0); -} } // namespace IpcConfigTest \ No newline at end of file diff --git a/test/middleware/IpcConfig/src_mock/IpcConfigTest.cpp b/test/middleware/IpcConfig/src_mock/IpcConfigTest.cpp new file mode 100644 index 00000000..cf4b85e5 --- /dev/null +++ b/test/middleware/IpcConfig/src_mock/IpcConfigTest.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2023 Fancy Code. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "IpcConfigTest.h" +#include "IIpcConfig.h" +#include "ILog.h" +#include "LinuxApi.h" +#include +IpcConfigTest::IpcConfigTest() +{ +} +IpcConfigTest::~IpcConfigTest() +{ +} +void IpcConfigTest::SetUpTestCase() +{ + CreateLogModule(); + ILogInit(LOG_INSTANCE_TYPE_END); +} +void IpcConfigTest::TearDownTestCase() +{ + ILogUnInit(); + DestroyLogModule(); +} +void IpcConfigTest::SetUp() +{ + mLinuxTest = LinuxTest::CreateLinuxTest(); + std::shared_ptr test = mLinuxTest; + LinuxApiMock::GetInstance(&test); + IpcConfigTestTool::Init(mLinuxTest); + CreateIpcConfigModule(); + IIpcConfig::GetInstance()->Init(); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); +} +void IpcConfigTest::TearDown() +{ + IIpcConfig::GetInstance()->UnInit(); + DestroyIpcConfigModule(); + RemoveConfigFile(); + IpcConfigTestTool::UnInit(); + mLinuxTest = std::make_shared(); + std::shared_ptr test = std::make_shared(); + LinuxApiMock::GetInstance(&test); +} +void IpcConfigTest::RemoveConfigFile(void) +{ + constexpr int FIEL_EXIST = 0; + if (FIEL_EXIST == access(IPC_CONFIG_FILE_PATH, F_OK)) { + constexpr int BUFF_SIZE = 128; + char cmd[BUFF_SIZE] = {0}; + snprintf(cmd, BUFF_SIZE, "rm -f %s", IPC_CONFIG_FILE_PATH); + fx_system(cmd); + } +} \ No newline at end of file diff --git a/test/middleware/IpcConfig/src_mock/IpcConfigTest.h b/test/middleware/IpcConfig/src_mock/IpcConfigTest.h new file mode 100644 index 00000000..6a050d89 --- /dev/null +++ b/test/middleware/IpcConfig/src_mock/IpcConfigTest.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023 Fancy Code. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef IPC_CONFIG_TEST_H +#define IPC_CONFIG_TEST_H +#include "GtestUsing.h" +#include "IpcConfigTestTool.h" +class IpcConfigTest : public testing::Test, public IpcConfigTestTool +{ +public: + IpcConfigTest(); + virtual ~IpcConfigTest(); + static void SetUpTestCase(); + static void TearDownTestCase(); + virtual void SetUp(); + virtual void TearDown(); + +private: + void RemoveConfigFile(void); + +public: + std::shared_ptr mLinuxTest; +}; +#endif \ No newline at end of file diff --git a/test/middleware/IpcConfig/src_mock/IpcConfig_Mock_Test.cpp b/test/middleware/IpcConfig/src_mock/IpcConfig_Mock_Test.cpp new file mode 100644 index 00000000..ef0b2ba7 --- /dev/null +++ b/test/middleware/IpcConfig/src_mock/IpcConfig_Mock_Test.cpp @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2023 Fancy Code. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "IpcConfigTest.h" +#include "IIpcConfig.h" +#include "ILog.h" +#include "IpcConfigImpl.h" +extern const char *CONFIG_WIFI_SSID_DEFAULT; +extern const char *CONFIG_WIFI_PASSWORD_DEFAULT; +// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_WifiSsid +TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_WifiSsid) +{ + const char *MODIFIED_STRING = "modified_string"; + const char *MODIFIED_STRING_SHORTER = "modified"; + const char *LONG_STRING = + "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL" + "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL"; + std::string config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_SSID); + LogInfo("Get wifi ssid = %s\n", config.c_str()); + EXPECT_STREQ(config.c_str(), CONFIG_WIFI_SSID_DEFAULT); + IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_SSID, MODIFIED_STRING); + config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_SSID); + LogInfo("Get wifiSsid = %s\n", config.c_str()); + EXPECT_STREQ(config.c_str(), MODIFIED_STRING); + IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_SSID, LONG_STRING); + config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_SSID); + EXPECT_STREQ(config.c_str(), MODIFIED_STRING); + IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_SSID, ""); + config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_SSID); + EXPECT_STREQ(config.c_str(), ""); + IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_SSID, MODIFIED_STRING_SHORTER); + config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_SSID); + EXPECT_STREQ(config.c_str(), MODIFIED_STRING_SHORTER); + IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_SSID, MODIFIED_STRING); + config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_SSID); + EXPECT_STREQ(config.c_str(), MODIFIED_STRING); +} +// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_WifiPassword +TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_WifiPassword) +{ + const char *MODIFIED_STRING = "99999999"; + const char *MODIFIED_STRING_SHORTER = "999"; + const char *LONG_STRING = + "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL" + "LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL"; + std::string config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_PASSWORD); + LogInfo("Get wifi password = %s\n", config.c_str()); + EXPECT_STREQ(config.c_str(), CONFIG_WIFI_PASSWORD_DEFAULT); + IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_PASSWORD, MODIFIED_STRING); + config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_PASSWORD); + LogInfo("Get wifi password = %s\n", config.c_str()); + EXPECT_STREQ(config.c_str(), MODIFIED_STRING); + IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_PASSWORD, LONG_STRING); + config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_PASSWORD); + EXPECT_STREQ(config.c_str(), MODIFIED_STRING); + IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_PASSWORD, ""); + config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_PASSWORD); + EXPECT_STREQ(config.c_str(), ""); + IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_PASSWORD, MODIFIED_STRING_SHORTER); + config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_PASSWORD); + EXPECT_STREQ(config.c_str(), MODIFIED_STRING_SHORTER); + IIpcConfig::GetInstance()->SetString(IpcConfigKey::WIFI_PASSWORD, MODIFIED_STRING); + config = IIpcConfig::GetInstance()->GetString(IpcConfigKey::WIFI_PASSWORD); + EXPECT_STREQ(config.c_str(), MODIFIED_STRING); +} +// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_WorkMode +TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_WorkMode) +{ + WorkMode config = IIpcConfig::GetInstance()->GetWorkMode(); + EXPECT_EQ(static_cast(config), static_cast(CONFIG_WORK_MODE_DEFAULT)); + IIpcConfig::GetInstance()->SetWorkMode(WorkMode::MODE_PIC_VIDEO); + config = IIpcConfig::GetInstance()->GetWorkMode(); + EXPECT_EQ(static_cast(config), static_cast(WorkMode::MODE_PIC_VIDEO)); +} +// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_ContinueShot +TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_ContinueShot) +{ + int config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::CONTINUOUS_SHOT); + EXPECT_EQ(config, CONFIG_CONTINUE_SHOT_DEFAULT); + IIpcConfig::GetInstance()->SetInt(IpcConfigKey::CONTINUOUS_SHOT, 2); + config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::CONTINUOUS_SHOT); + EXPECT_EQ(config, 2); +} +// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_BurstPhotoInterval +TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_BurstPhotoInterval) +{ + int config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::BURST_PHOTO_INTERVAL); + EXPECT_EQ(config, CONFIG_BURST_PHOTO_INTERVAL_DEFAULT); + IIpcConfig::GetInstance()->SetInt(IpcConfigKey::BURST_PHOTO_INTERVAL, 10); + config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::BURST_PHOTO_INTERVAL); + EXPECT_EQ(config, 10); +} +// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_ImageSize +TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_ImageSize) +{ + int config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::IMGAE_SIZE); + EXPECT_EQ(config, CONFIG_IMAGE_SIZE_DEFAULT); + IIpcConfig::GetInstance()->SetInt(IpcConfigKey::IMGAE_SIZE, 16); + config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::IMGAE_SIZE); + EXPECT_EQ(config, 16); +} +// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_VideoLength +TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_VideoLength) +{ + int config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::VIDEO_LENGTH); + EXPECT_EQ(config, CONFIG_VIDEO_SIZE_DEFAULT); + IIpcConfig::GetInstance()->SetInt(IpcConfigKey::VIDEO_LENGTH, 15); + config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::VIDEO_LENGTH); + EXPECT_EQ(config, 15); +} +// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_PirDelayed +TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_PirDelayed) +{ + int config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::PIR_DELAYED); + EXPECT_EQ(config, CONFIG_PIR_DELAYED_DEFAULT); + IIpcConfig::GetInstance()->SetInt(IpcConfigKey::PIR_DELAYED, 15); + config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::PIR_DELAYED); + EXPECT_EQ(config, 15); +} +// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_StorageLoop +TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_StorageLoop) +{ + ConfigSwitch config = IIpcConfig::GetInstance()->GetSwitch(IpcConfigKey::STORAGE_LOOP_SWITCH); + EXPECT_EQ(static_cast(config), + static_cast(CONFIG_STORAGE_LOOP_DEFAULT == true ? ConfigSwitch::ON : ConfigSwitch::OFF)); + IIpcConfig::GetInstance()->SetSwitch(IpcConfigKey::STORAGE_LOOP_SWITCH, ConfigSwitch::OFF); + config = IIpcConfig::GetInstance()->GetSwitch(IpcConfigKey::STORAGE_LOOP_SWITCH); + EXPECT_EQ(static_cast(config), static_cast(ConfigSwitch::OFF)); +} +// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_InfraredPower +TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_InfraredPower) +{ + ConfigLevel config = IIpcConfig::GetInstance()->GetLevel(IpcConfigKey::INFRARED_POWER); + EXPECT_EQ(static_cast(config), static_cast(CONFIG_INFRARED_POWER_DEFAULT)); + IIpcConfig::GetInstance()->SetLevel(IpcConfigKey::INFRARED_POWER, ConfigLevel::HIGHT); + config = IIpcConfig::GetInstance()->GetLevel(IpcConfigKey::INFRARED_POWER); + EXPECT_EQ(static_cast(config), static_cast(ConfigSwitch::OFF)); +} +// ../output_files/test/bin/IpcConfigTest --gtest_filter=IpcConfigTest.HS_RH_UNIT_IpcConfig_AUTO_PirSensitivity +TEST_F(IpcConfigTest, HS_RH_UNIT_IpcConfig_AUTO_PirSensitivity) +{ + int config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::PIR_SENSITIVITY); + EXPECT_EQ(config, CONFIG_PIR_SENSITIVITY_DEFAULT); + IIpcConfig::GetInstance()->SetInt(IpcConfigKey::PIR_SENSITIVITY, 0); + config = IIpcConfig::GetInstance()->GetInt(IpcConfigKey::PIR_SENSITIVITY); + EXPECT_EQ(config, 0); +} \ No newline at end of file diff --git a/test/middleware/IpcConfig/tool/CMakeLists.txt b/test/middleware/IpcConfig/tool/CMakeLists.txt new file mode 100644 index 00000000..c91e235a --- /dev/null +++ b/test/middleware/IpcConfig/tool/CMakeLists.txt @@ -0,0 +1,53 @@ +include(${CMAKE_SOURCE_DIR_IPCSDK}/build/global_config.cmake) +set(EXECUTABLE_OUTPUT_PATH ${EXEC_OUTPUT_PATH}) +set(LIBRARY_OUTPUT_PATH ${LIBS_OUTPUT_PATH}) + +include_directories( + ./src + ./include + ${UTILS_SOURCE_PATH}/StatusCode/include + ${UTILS_SOURCE_PATH}/Log/include + ${MIDDLEWARE_SOURCE_PATH}/IpcConfig/src + ${TEST_SOURCE_PATH} + ${TEST_SOURCE_PATH}/utils/LinuxApiMock/include + ${TEST_SOURCE_PATH}/utils/McuProtocol/tool/include +) +# link_directories( +# ${EXTERNAL_SOURCE_PATH}/libconfig/libconfig-1.7.3/lib/.libs +# ) + +aux_source_directory(./src TEST_TOOL_SRC_FILES) +set(TEST_TOOL_TARGET IpcConfigTestTool) +add_library(${TEST_TOOL_TARGET} STATIC ${TEST_TOOL_SRC_FILES}) +target_link_libraries(${TEST_TOOL_TARGET} IpcConfig LinuxApiMock Log) + +if ("${COMPILE_IMPROVE_SUPPORT}" MATCHES "true") +add_custom_target( + IpcConfigTestTool_code_check + COMMAND ${CLANG_TIDY_EXE} + -checks='${CLANG_TIDY_CHECKS}' + --header-filter=.* + --system-headers=false + ${TEST_TOOL_SRC_FILES} + ${CLANG_TIDY_CONFIG} + -p ${PLATFORM_PATH}/cmake-shell + WORKING_DIRECTORY ${TEST_SOURCE_PATH}/middleware/IpcConfig/tool +) +file(GLOB_RECURSE HEADER_FILES *.h) +add_custom_target( + IpcConfigTestTool_code_format + COMMAND ${CLANG_FORMAT_EXE} + -style=file + -i ${TEST_TOOL_SRC_FILES} ${HEADER_FILES} + WORKING_DIRECTORY ${TEST_SOURCE_PATH}/middleware/IpcConfig/tool +) +add_custom_command( + TARGET ${TEST_TOOL_TARGET} + PRE_BUILD + COMMAND make IpcConfigTestTool_code_check + COMMAND make IpcConfigTestTool_code_format + WORKING_DIRECTORY ${PLATFORM_PATH}/cmake-shell/ +) +endif() + +define_file_name(${TEST_TOOL_TARGET}) \ No newline at end of file diff --git a/test/middleware/IpcConfig/tool/include/IpcConfigTestTool.h b/test/middleware/IpcConfig/tool/include/IpcConfigTestTool.h new file mode 100644 index 00000000..50af0130 --- /dev/null +++ b/test/middleware/IpcConfig/tool/include/IpcConfigTestTool.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023 Fancy Code. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef IPC_CONFIG_TEST_TOOL_H +#define IPC_CONFIG_TEST_TOOL_H +#include "GtestUsing.h" +#include "LinuxApiMock.h" +class IpcConfigTestTool +{ +public: + IpcConfigTestTool() = default; + virtual ~IpcConfigTestTool() = default; + void Init(std::shared_ptr &mock); + void UnInit(void); + +private: + void MockMountedFile(void); + FILE *OpenMockMountedFile(const char *mode); + +private: + std::shared_ptr mLinuxTest; + FILE *mFile = nullptr; +}; +#endif \ No newline at end of file diff --git a/test/middleware/IpcConfig/tool/src/IpcConfigTestTool.cpp b/test/middleware/IpcConfig/tool/src/IpcConfigTestTool.cpp new file mode 100644 index 00000000..2a345c8d --- /dev/null +++ b/test/middleware/IpcConfig/tool/src/IpcConfigTestTool.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2023 Fancy Code. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "IpcConfigTestTool.h" +#include "ILog.h" +#include "LinuxApi.h" +#include +#include +const char *MOUNTED_FILE = "./mount_info.txt"; +extern const char *SYSTEM_MOUNTED_FILE; +void IpcConfigTestTool::Init(std::shared_ptr &mock) +{ + MockMountedFile(); + auto api_fopen = [=](const char *pathname, const char *mode) { + LogInfo("Open mock mounted file.\n"); + mFile = OpenMockMountedFile(mode); + }; + EXPECT_CALL(*mock.get(), fx_fopen(SYSTEM_MOUNTED_FILE, _)) + .WillRepeatedly(DoAll(WithArgs<0, 1>(Invoke(api_fopen)), (ReturnPointee(&mFile)))); +} +void IpcConfigTestTool::UnInit(void) +{ + constexpr int BUF_LENGTH = 256; + char cmd[BUF_LENGTH] = {0}; + sprintf(cmd, "rm -rf %s", MOUNTED_FILE); + fx_system(cmd); +} +void IpcConfigTestTool::MockMountedFile(void) +{ + FILE *file; + file = fopen(MOUNTED_FILE, "w"); + if (file == NULL) { + perror("Error opening file"); + return; + } + + fprintf(file, "devtmpfs /dev devtmpfs rw,relatime,size=10176k,nr_inodes=2544,mode=755 0 0\n"); + fprintf(file, "proc /proc proc rw,relatime 0 0\n"); + fprintf(file, "tmpfs /tmp tmpfs rw,relatime,size=14464k,nr_inodes=3616 0 0\n"); + fprintf(file, "tmpfs /run tmpfs rw,nosuid,nodev,relatime,size=14464k,nr_inodes=3616,mode=755 0 0\n"); + fprintf(file, "sysfs /sys sysfs rw,relatime 0 0\n"); + fprintf(file, "/dev/block/by-name/userdata /userdata jffs2 rw,relatime 0 0\n"); + fprintf( + file, + "/dev/mmcblk1p1 /mnt/sdcard vfat " + "rw,relatime,fmask=0022,dmask=0022,codepage=936,iocharset=cp936,shortname=mixed,utf8,errors=remount-ro 0 0\n"); + + fclose(file); + fx_system("sync"); + LogInfo("File written successfully.\n"); +} +FILE *IpcConfigTestTool::OpenMockMountedFile(const char *mode) +{ + FILE *fp = nullptr; + fp = fopen(MOUNTED_FILE, mode); + return fp; +} \ No newline at end of file diff --git a/test/utils/LinuxApiMock/include/LinuxApiMock.h b/test/utils/LinuxApiMock/include/LinuxApiMock.h index 60ade215..f1d6eae9 100644 --- a/test/utils/LinuxApiMock/include/LinuxApiMock.h +++ b/test/utils/LinuxApiMock/include/LinuxApiMock.h @@ -34,6 +34,7 @@ public: virtual int fx_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); 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); }; /** * A simulation interface class used for automated testing in Ubuntu systems, implementing the function of piling on @@ -52,6 +53,7 @@ public: MOCK_METHOD5(fx_select, int(int, fd_set *, fd_set *, fd_set *, struct timeval *)); 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 *)); public: /** diff --git a/test/utils/LinuxApiMock/src/LinuxApiMock.cpp b/test/utils/LinuxApiMock/src/LinuxApiMock.cpp index 42371d4e..3af63f02 100644 --- a/test/utils/LinuxApiMock/src/LinuxApiMock.cpp +++ b/test/utils/LinuxApiMock/src/LinuxApiMock.cpp @@ -68,6 +68,10 @@ int LinuxApiMock::fx_access(const char *pathname, int mode) { return __real_fx_access(pathname, mode); } +FILE *LinuxApiMock::fx_fopen(const char *pathname, const char *mode) +{ + return __real_fx_fopen(pathname, mode); +} std::shared_ptr LinuxTest::CreateLinuxTest(void) { std::shared_ptr test = std::make_shared(); diff --git a/test/utils/LinuxApiMock/src/LinuxTestImpl.cpp b/test/utils/LinuxApiMock/src/LinuxTestImpl.cpp index d062ba1d..39d1966f 100644 --- a/test/utils/LinuxApiMock/src/LinuxTestImpl.cpp +++ b/test/utils/LinuxApiMock/src/LinuxTestImpl.cpp @@ -114,6 +114,16 @@ void LinuxTestImpl::ApiInit(std::shared_ptr &mock) WithArgs<0, 1>(Invoke(api_access)), Invoke((std::dynamic_pointer_cast(mock)).get(), &LinuxTestImpl::ApiUnlockThread), ReturnPointee(&accessResult))); + static FILE *fopenResult = nullptr; + auto api_fopen = [=](const char *pathname, const char *mode) { + fopenResult = __real_fx_fopen(pathname, mode); + }; + EXPECT_CALL(*mock.get(), fx_fopen(_, _)) + .WillRepeatedly( + DoAll(Invoke((std::dynamic_pointer_cast(mock)).get(), &LinuxTestImpl::ApiLock), + WithArgs<0, 1>(Invoke(api_fopen)), + Invoke((std::dynamic_pointer_cast(mock)).get(), &LinuxTestImpl::ApiUnlockThread), + ReturnPointee(&fopenResult))); } void LinuxTestImpl::Init() { @@ -126,13 +136,18 @@ void LinuxTestImpl::UnInit() } void LinuxTestImpl::ApiLock(void) { - mApiMutex.lock(); - LogInfo("lock api.\n"); + /** + * @brief This has been optimized and does not require locking; Place the lock position in the WrapApi file, and + * lock the Mock function to ensure that it returns the value of the global variable before it can return, to avoid + * the problem of obtaining incorrect return values due to multithreading timing errors. + */ + // mApiMutex.lock(); + // LogInfo("lock api.\n"); } void LinuxTestImpl::ApiUnlock(void) { - mApiMutex.unlock(); - LogInfo("unlock api.\n"); + // mApiMutex.unlock(); + // LogInfo("unlock api.\n"); } void LinuxTestImpl::ApiUnlockThread(void) { diff --git a/test/utils/LinuxApiMock/src/WrapApi.cpp b/test/utils/LinuxApiMock/src/WrapApi.cpp index 0aed79f8..688eaa84 100644 --- a/test/utils/LinuxApiMock/src/WrapApi.cpp +++ b/test/utils/LinuxApiMock/src/WrapApi.cpp @@ -14,42 +14,56 @@ */ #include "WrapApi.h" #include "LinuxApiMock.h" +#include +static std::mutex gMutex; #ifdef __cplusplus extern "C" { #endif int __wrap_fx_open(const char *pathname, int flags) { + std::lock_guard locker(gMutex); return LinuxApiMock::GetInstance()->fx_open(pathname, flags); } int __wrap_fx_tcgetattr(int fd, struct termios *termios_p) { + std::lock_guard locker(gMutex); return LinuxApiMock::GetInstance()->fx_tcgetattr(fd, termios_p); } int __wrap_fx_tcsetattr(int fd, int optional_actions, const struct termios *termios_p) { + std::lock_guard locker(gMutex); return LinuxApiMock::GetInstance()->fx_tcsetattr(fd, optional_actions, termios_p); } ssize_t __wrap_fx_write(int fd, const void *buf, size_t count) { + std::lock_guard locker(gMutex); return LinuxApiMock::GetInstance()->fx_write(fd, buf, count); } ssize_t __wrap_fx_read(int fd, void *buf, size_t count) { + std::lock_guard locker(gMutex); return LinuxApiMock::GetInstance()->fx_read(fd, buf, count); } int __wrap_fx_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) { + std::lock_guard locker(gMutex); return LinuxApiMock::GetInstance()->fx_select(nfds, readfds, writefds, exceptfds, timeout); } int __wrap_fx_fstat(int fd, struct stat *statbuf) { - // TODO: 在此处加锁,优化打桩时,接口需要调用真实接口并返回真实接口的返回值返回全局变量的多线程安全问题。 + std::lock_guard locker(gMutex); return LinuxApiMock::GetInstance()->fx_fstat(fd, statbuf); } int __wrap_fx_access(const char *pathname, int mode) { + std::lock_guard locker(gMutex); return LinuxApiMock::GetInstance()->fx_access(pathname, mode); } +FILE *__wrap_fx_fopen(const char *pathname, const char *mode) +{ + std::lock_guard locker(gMutex); + return LinuxApiMock::GetInstance()->fx_fopen(pathname, mode); +} #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 426ef863..734729cc 100644 --- a/test/utils/LinuxApiMock/src/WrapApi.h +++ b/test/utils/LinuxApiMock/src/WrapApi.h @@ -14,6 +14,7 @@ */ #ifndef WRAP_API_H #define WRAP_API_H +#include #include #include #include @@ -30,6 +31,7 @@ ssize_t __real_fx_read(int fd, void *buf, size_t count); int __real_fx_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); 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); #ifdef __cplusplus } #endif diff --git a/utils/LinuxApi/include/LinuxApi.h b/utils/LinuxApi/include/LinuxApi.h index ce9a5ca0..96f4568b 100644 --- a/utils/LinuxApi/include/LinuxApi.h +++ b/utils/LinuxApi/include/LinuxApi.h @@ -15,6 +15,7 @@ #ifndef LINUX_API_H #define LINUX_API_H #include +#include #include #include #include @@ -33,6 +34,7 @@ ssize_t fx_read(int fd, void *buf, size_t count); int fx_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); int fx_fstat(int fd, struct stat *statbuf); int fx_access(const char *pathname, int mode); +FILE *fx_fopen(const char *pathname, const char *mode); #ifdef __cplusplus } #endif diff --git a/utils/LinuxApi/src/LinuxApi.c b/utils/LinuxApi/src/LinuxApi.c index 42e161ae..754cf9c5 100644 --- a/utils/LinuxApi/src/LinuxApi.c +++ b/utils/LinuxApi/src/LinuxApi.c @@ -57,4 +57,8 @@ int fx_fstat(int fd, struct stat *statbuf) int fx_access(const char *pathname, int mode) { return access(pathname, mode); +} +FILE *fx_fopen(const char *pathname, const char *mode) +{ + return fopen(pathname, mode); } \ No newline at end of file