diff --git a/test/utils/LinuxApiMock/CMakeLists.txt b/test/utils/LinuxApiMock/CMakeLists.txt index 224f22be..85ae0aae 100644 --- a/test/utils/LinuxApiMock/CMakeLists.txt +++ b/test/utils/LinuxApiMock/CMakeLists.txt @@ -6,6 +6,8 @@ include_directories( ./src ./include ${UTILS_SOURCE_PATH}/Log/include + ${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googletest/include + ${EXTERNAL_SOURCE_PATH}/gtest/googletest-release-1.11.0/googlemock/include ) # link_directories( # ${EXTERNAL_SOURCE_PATH}/libconfig/libconfig-1.7.3/lib/.libs @@ -18,7 +20,7 @@ aux_source_directory(./src SRC_FILES) set(TARGET_NAME LinuxApiMock) add_library(${TARGET_NAME} STATIC ${SRC_FILES}) -target_link_libraries(${TARGET_NAME} Log) +target_link_libraries(${TARGET_NAME} gtest gmock Log) if ("${CLANG_TIDY_SUPPORT}" MATCHES "true") add_custom_target( diff --git a/test/utils/LinuxApiMock/include/LinuxApiMock.h b/test/utils/LinuxApiMock/include/LinuxApiMock.h index 6329ca3c..b06c5f26 100644 --- a/test/utils/LinuxApiMock/include/LinuxApiMock.h +++ b/test/utils/LinuxApiMock/include/LinuxApiMock.h @@ -1,5 +1,7 @@ #ifndef LINUX_API_MOCK_H #define LINUX_API_MOCK_H +#include +#include #include #ifdef __cplusplus extern "C" { @@ -9,6 +11,7 @@ int __real_fx_open(const char *pathname, int flags); #ifdef __cplusplus } #endif +constexpr int INVALID_HANDLE = -1; class LinuxApiMock { public: @@ -27,4 +30,26 @@ public: virtual void UnInit() {} virtual int fx_open(const char *pathname, int flags); }; +/** + * A simulation interface class used for automated testing in Ubuntu systems, implementing the function of piling on + * some Linux standard interfaces. + */ +class LinuxTest : public LinuxApiMock +{ +public: + LinuxTest() = default; + virtual ~LinuxTest() = default; + MOCK_METHOD2(fx_open, int(const char *, int)); + +public: + /** + * @brief Get the Handle For Mock object + * + * @return int + */ + virtual int GetHandleForMock(void) { return INVALID_HANDLE; } + +public: + static std::shared_ptr CreateLinuxTest(void); +}; #endif \ No newline at end of file diff --git a/test/utils/LinuxApiMock/src/HandleManager.cpp b/test/utils/LinuxApiMock/src/HandleManager.cpp new file mode 100644 index 00000000..af11571f --- /dev/null +++ b/test/utils/LinuxApiMock/src/HandleManager.cpp @@ -0,0 +1,22 @@ +/* + * 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 "HandleManager.h" +HandleManager::HandleManager() { mFdMax = 1000; } +int HandleManager::GetHandleForMock(void) +{ + int value = mFdMax; + mFdMax++; + return value; +} \ No newline at end of file diff --git a/test/utils/LinuxApiMock/src/HandleManager.h b/test/utils/LinuxApiMock/src/HandleManager.h new file mode 100644 index 00000000..914953c0 --- /dev/null +++ b/test/utils/LinuxApiMock/src/HandleManager.h @@ -0,0 +1,37 @@ +/* + * 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 HANDLE_MANAGER_H +#define HANDLE_MANAGER_H +#include "LinuxApiMock.h" +/** + * @brief Handle management class, which manages all handles in the test program to prevent unclear objects pointed to + * by handles during simulation. + * + */ +class HandleManager : virtual public LinuxTest +{ +public: + HandleManager(); + virtual ~HandleManager() = default; + int GetHandleForMock(void) override; + +private: + /** + * @brief + * + */ + int mFdMax; +}; +#endif \ No newline at end of file diff --git a/test/utils/LinuxApiMock/src/LinuxApiMock.cpp b/test/utils/LinuxApiMock/src/LinuxApiMock.cpp index 9b91dfbd..14c08b12 100644 --- a/test/utils/LinuxApiMock/src/LinuxApiMock.cpp +++ b/test/utils/LinuxApiMock/src/LinuxApiMock.cpp @@ -1,4 +1,6 @@ #include "LinuxApiMock.h" +#include "ILog.h" +#include "LinuxTestImpl.h" #ifdef __cplusplus extern "C" { #endif @@ -7,4 +9,11 @@ int __wrap_fx_open(const char *pathname, int flags) { return LinuxApiMock::GetIn #ifdef __cplusplus } #endif -int LinuxApiMock::fx_open(const char *pathname, int flags) { return __real_fx_open(pathname, flags); } \ No newline at end of file +int LinuxApiMock::fx_open(const char *pathname, int flags) { return __real_fx_open(pathname, flags); } + +std::shared_ptr LinuxTest::CreateLinuxTest(void) +{ + std::shared_ptr test = std::make_shared(); + LinuxTestImpl::ApiInit(test); + return test; +} \ No newline at end of file diff --git a/test/utils/LinuxApiMock/src/LinuxTestImpl.cpp b/test/utils/LinuxApiMock/src/LinuxTestImpl.cpp new file mode 100644 index 00000000..568ed9d2 --- /dev/null +++ b/test/utils/LinuxApiMock/src/LinuxTestImpl.cpp @@ -0,0 +1,27 @@ +/* + * 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 "LinuxTestImpl.h" +#include "ILog.h" +void LinuxTestImpl::ApiInit(std::shared_ptr &mock) +{ + static int openFd = -1; + auto api_open = [](const char *pathname, int flags) { + LogInfo("Call __real_fx_open, pathname = %s.\n", pathname); + openFd = __real_fx_open(pathname, flags); + }; + EXPECT_CALL(*mock.get(), fx_open(::testing::_, ::testing::_)) + .WillRepeatedly(::testing::DoAll(::testing::WithArgs<0, 1>(::testing::Invoke(api_open)), + ::testing::ReturnPointee(&openFd))); +} \ No newline at end of file diff --git a/test/utils/LinuxApiMock/src/LinuxTestImpl.h b/test/utils/LinuxApiMock/src/LinuxTestImpl.h new file mode 100644 index 00000000..39a1d1b6 --- /dev/null +++ b/test/utils/LinuxApiMock/src/LinuxTestImpl.h @@ -0,0 +1,28 @@ +/* + * 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 LINUX_TEST_IMPL_H +#define LINUX_TEST_IMPL_H +#include "HandleManager.h" +#include "LinuxApiMock.h" +class LinuxTestImpl : public HandleManager +{ +public: + LinuxTestImpl() = default; + virtual ~LinuxTestImpl() = default; + +public: + static void ApiInit(std::shared_ptr &mock); +}; +#endif \ No newline at end of file diff --git a/test/utils/UartDevice/CMakeLists.txt b/test/utils/UartDevice/CMakeLists.txt index cb485d84..865a7450 100644 --- a/test/utils/UartDevice/CMakeLists.txt +++ b/test/utils/UartDevice/CMakeLists.txt @@ -3,6 +3,7 @@ include(${CMAKE_SOURCE_DIR_IPCSDK}/build/global_config.cmake) set(EXECUTABLE_OUTPUT_PATH ${TEST_OUTPUT_PATH}/bin) include_directories( + ./tool/include ${UTILS_SOURCE_PATH}/StatusCode/include ${UTILS_SOURCE_PATH}/Log/include ${UTILS_SOURCE_PATH}/UartDevice/include @@ -30,7 +31,7 @@ endif() set(TARGET_NAME UartDeviceTest) add_executable(${TARGET_NAME} ${SRC_FILES}) -target_link_libraries(${TARGET_NAME} UartDevice gtest gmock pthread Log) +target_link_libraries(${TARGET_NAME} UartDevice UartDeviceTestTool gtest gmock pthread Log) if(${TEST_COVERAGE} MATCHES "true") target_link_libraries(${TARGET_NAME} gcov) endif() @@ -68,4 +69,6 @@ add_custom_command( ) endif() -define_file_name(${TARGET_NAME}) \ No newline at end of file +define_file_name(${TARGET_NAME}) + +add_subdirectory(tool) \ No newline at end of file diff --git a/test/utils/UartDevice/src_mock/UartDevice_Mock_Test.cpp b/test/utils/UartDevice/src_mock/UartDevice_Mock_Test.cpp index 3142843a..d4f5b881 100644 --- a/test/utils/UartDevice/src_mock/UartDevice_Mock_Test.cpp +++ b/test/utils/UartDevice/src_mock/UartDevice_Mock_Test.cpp @@ -15,18 +15,21 @@ #include "ILog.h" #include "LinuxApiMock.h" #include "UartDevice.h" +#include "UartDeviceTestTool.h" #include #include namespace UartDeviceMockTest { -class LinuxApiMockTest : public LinuxApiMock -{ -public: - LinuxApiMockTest() = default; - virtual ~LinuxApiMockTest() = default; - MOCK_METHOD2(fx_open, int(const char *, int)); +const char *gDeviceName = "dev/s1"; +static uart_info gUartDevice = { + gDeviceName, + 1152000, + 'N', + 8, + 1, + 'N', }; -class UartDeviceMockTest : public testing::Test +class UartDeviceMockTest : public testing::Test, public UartDeviceTestTool { public: UartDeviceMockTest() {} @@ -37,27 +40,25 @@ public: ILogInit(LOG_INSTANCE_TYPE_END); } static void TearDownTestCase() { ILogUnInit(); } - virtual void SetUp() {} + virtual void SetUp() + { + mLinuxTest = LinuxTest::CreateLinuxTest(); + std::shared_ptr test = mLinuxTest; + LinuxApiMock::GetInstance(&test); + UartDeviceDefaultInit(mLinuxTest, gUartDevice); + } virtual void TearDown() {} + +public: + std::shared_ptr mLinuxTest; + // std::shared_ptr mLinuxApiMock; }; // ../output_files/test/bin/UartDeviceTest --gtest_filter=UartDeviceMockTest.Demo TEST_F(UartDeviceMockTest, Demo) { - const char *deviceName = "dev/s1"; - uart_info device = { - deviceName, - 1152000, - 'N', - 8, - 1, - 'N', - }; - std::shared_ptr tmp = std::make_shared(); - std::shared_ptr test = tmp; - LinuxApiMock::GetInstance(&test); - EXPECT_CALL(*tmp.get(), fx_open(deviceName, ::testing::_)) - .WillRepeatedly(::testing::DoAll((::testing::Return(1000000000)))); - void *object = CreateUartDevice(device); + // EXPECT_CALL(*mLinuxTest.get(), fx_open(deviceName, ::testing::_)) + // .WillRepeatedly(::testing::DoAll((::testing::Return(1000000000)))); + void *object = CreateUartDevice(gUartDevice); IUartOpen(object); // IUartSend(object, nullptr, 0); // IUartRecv(object, nullptr, 0, 0); diff --git a/test/utils/UartDevice/tool/CMakeLists.txt b/test/utils/UartDevice/tool/CMakeLists.txt new file mode 100644 index 00000000..cf971e80 --- /dev/null +++ b/test/utils/UartDevice/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 + ${TEST_SOURCE_PATH}/utils/LinuxApiMock/include +) +# link_directories( +# ${EXTERNAL_SOURCE_PATH}/libconfig/libconfig-1.7.3/lib/.libs +# ) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +aux_source_directory(./src TEST_TOOL_SRC_FILES) +set(TEST_TOOL_TARGET UartDeviceTestTool) +add_library(${TEST_TOOL_TARGET} STATIC ${TEST_TOOL_SRC_FILES}) +target_link_libraries(${TEST_TOOL_TARGET} Log) + +if ("${CLANG_TIDY_SUPPORT}" MATCHES "true") +add_custom_target( + UartDeviceTestTool_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}/utils/UartDevice/tool +) +file(GLOB_RECURSE HEADER_FILES *.h) +add_custom_target( + UartDeviceTestTool_code_format + COMMAND ${CLANG_FORMAT_EXE} + -style=file + -i ${TEST_TOOL_SRC_FILES} ${HEADER_FILES} + WORKING_DIRECTORY ${TEST_SOURCE_PATH}/utils/UartDevice/tool +) +add_custom_command( + TARGET ${TEST_TOOL_TARGET} + PRE_BUILD + COMMAND make UartDeviceTestTool_code_check + COMMAND make UartDeviceTestTool_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/utils/UartDevice/tool/README.md b/test/utils/UartDevice/tool/README.md new file mode 100644 index 00000000..d55e6cc6 --- /dev/null +++ b/test/utils/UartDevice/tool/README.md @@ -0,0 +1,3 @@ +# Tool目录 + +  基于模块独立的测试辅助工具,可被外界模块复用。 \ No newline at end of file diff --git a/test/utils/UartDevice/tool/include/UartDeviceTestTool.h b/test/utils/UartDevice/tool/include/UartDeviceTestTool.h new file mode 100644 index 00000000..2659f53e --- /dev/null +++ b/test/utils/UartDevice/tool/include/UartDeviceTestTool.h @@ -0,0 +1,31 @@ +/* + * 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 UART_DEVICE_TEST_TOOL_H +#define UART_DEVICE_TEST_TOOL_H +#include "LinuxApiMock.h" +#include "UartDevice.h" +class UartDeviceTestTool +{ +public: + UartDeviceTestTool() = default; + virtual ~UartDeviceTestTool() = default; + /** + * @brief Enable the UartDevice module to run and debug on Ubuntu + * + * @param mock + */ + void UartDeviceDefaultInit(std::shared_ptr &mock, const uart_info &uart); +}; +#endif \ No newline at end of file diff --git a/test/utils/UartDevice/tool/src/UartDeviceTestTool.cpp b/test/utils/UartDevice/tool/src/UartDeviceTestTool.cpp new file mode 100644 index 00000000..4a733d81 --- /dev/null +++ b/test/utils/UartDevice/tool/src/UartDeviceTestTool.cpp @@ -0,0 +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 "UartDeviceTestTool.h" +#include "ILog.h" +void UartDeviceTestTool::UartDeviceDefaultInit(std::shared_ptr &mock, const uart_info &uart) +{ + int uartFd = mock->GetHandleForMock(); + LogInfo("uartFd = %d\n", uartFd); + EXPECT_CALL(*mock.get(), fx_open(uart.mDevice, ::testing::_)) + .WillRepeatedly(::testing::DoAll((::testing::Return(uartFd)))); +} \ No newline at end of file