Improve:UartDevice test code.

This commit is contained in:
fancy 2024-01-25 12:01:03 -08:00
parent 9b12014f76
commit b99d2c9461
13 changed files with 291 additions and 27 deletions

View File

@ -6,6 +6,8 @@ include_directories(
./src ./src
./include ./include
${UTILS_SOURCE_PATH}/Log/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( # link_directories(
# ${EXTERNAL_SOURCE_PATH}/libconfig/libconfig-1.7.3/lib/.libs # ${EXTERNAL_SOURCE_PATH}/libconfig/libconfig-1.7.3/lib/.libs
@ -18,7 +20,7 @@ aux_source_directory(./src SRC_FILES)
set(TARGET_NAME LinuxApiMock) set(TARGET_NAME LinuxApiMock)
add_library(${TARGET_NAME} STATIC ${SRC_FILES}) 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") if ("${CLANG_TIDY_SUPPORT}" MATCHES "true")
add_custom_target( add_custom_target(

View File

@ -1,5 +1,7 @@
#ifndef LINUX_API_MOCK_H #ifndef LINUX_API_MOCK_H
#define LINUX_API_MOCK_H #define LINUX_API_MOCK_H
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <memory> #include <memory>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -9,6 +11,7 @@ int __real_fx_open(const char *pathname, int flags);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
constexpr int INVALID_HANDLE = -1;
class LinuxApiMock class LinuxApiMock
{ {
public: public:
@ -27,4 +30,26 @@ public:
virtual void UnInit() {} virtual void UnInit() {}
virtual int fx_open(const char *pathname, int flags); 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<LinuxTest> CreateLinuxTest(void);
};
#endif #endif

View File

@ -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;
}

View File

@ -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

View File

@ -1,4 +1,6 @@
#include "LinuxApiMock.h" #include "LinuxApiMock.h"
#include "ILog.h"
#include "LinuxTestImpl.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -8,3 +10,10 @@ int __wrap_fx_open(const char *pathname, int flags) { return LinuxApiMock::GetIn
} }
#endif #endif
int LinuxApiMock::fx_open(const char *pathname, int flags) { return __real_fx_open(pathname, flags); } int LinuxApiMock::fx_open(const char *pathname, int flags) { return __real_fx_open(pathname, flags); }
std::shared_ptr<LinuxTest> LinuxTest::CreateLinuxTest(void)
{
std::shared_ptr<LinuxTest> test = std::make_shared<LinuxTestImpl>();
LinuxTestImpl::ApiInit(test);
return test;
}

View File

@ -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<LinuxTest> &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)));
}

View File

@ -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<LinuxTest> &mock);
};
#endif

View File

@ -3,6 +3,7 @@ include(${CMAKE_SOURCE_DIR_IPCSDK}/build/global_config.cmake)
set(EXECUTABLE_OUTPUT_PATH ${TEST_OUTPUT_PATH}/bin) set(EXECUTABLE_OUTPUT_PATH ${TEST_OUTPUT_PATH}/bin)
include_directories( include_directories(
./tool/include
${UTILS_SOURCE_PATH}/StatusCode/include ${UTILS_SOURCE_PATH}/StatusCode/include
${UTILS_SOURCE_PATH}/Log/include ${UTILS_SOURCE_PATH}/Log/include
${UTILS_SOURCE_PATH}/UartDevice/include ${UTILS_SOURCE_PATH}/UartDevice/include
@ -30,7 +31,7 @@ endif()
set(TARGET_NAME UartDeviceTest) set(TARGET_NAME UartDeviceTest)
add_executable(${TARGET_NAME} ${SRC_FILES}) 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") if(${TEST_COVERAGE} MATCHES "true")
target_link_libraries(${TARGET_NAME} gcov) target_link_libraries(${TARGET_NAME} gcov)
endif() endif()
@ -69,3 +70,5 @@ add_custom_command(
endif() endif()
define_file_name(${TARGET_NAME}) define_file_name(${TARGET_NAME})
add_subdirectory(tool)

View File

@ -15,18 +15,21 @@
#include "ILog.h" #include "ILog.h"
#include "LinuxApiMock.h" #include "LinuxApiMock.h"
#include "UartDevice.h" #include "UartDevice.h"
#include "UartDeviceTestTool.h"
#include <gmock/gmock.h> #include <gmock/gmock.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
namespace UartDeviceMockTest namespace UartDeviceMockTest
{ {
class LinuxApiMockTest : public LinuxApiMock const char *gDeviceName = "dev/s1";
{ static uart_info gUartDevice = {
public: gDeviceName,
LinuxApiMockTest() = default; 1152000,
virtual ~LinuxApiMockTest() = default; 'N',
MOCK_METHOD2(fx_open, int(const char *, int)); 8,
1,
'N',
}; };
class UartDeviceMockTest : public testing::Test class UartDeviceMockTest : public testing::Test, public UartDeviceTestTool
{ {
public: public:
UartDeviceMockTest() {} UartDeviceMockTest() {}
@ -37,27 +40,25 @@ public:
ILogInit(LOG_INSTANCE_TYPE_END); ILogInit(LOG_INSTANCE_TYPE_END);
} }
static void TearDownTestCase() { ILogUnInit(); } static void TearDownTestCase() { ILogUnInit(); }
virtual void SetUp() {} virtual void SetUp()
{
mLinuxTest = LinuxTest::CreateLinuxTest();
std::shared_ptr<LinuxApiMock> test = mLinuxTest;
LinuxApiMock::GetInstance(&test);
UartDeviceDefaultInit(mLinuxTest, gUartDevice);
}
virtual void TearDown() {} virtual void TearDown() {}
public:
std::shared_ptr<LinuxTest> mLinuxTest;
// std::shared_ptr<LinuxApiMock> mLinuxApiMock;
}; };
// ../output_files/test/bin/UartDeviceTest --gtest_filter=UartDeviceMockTest.Demo // ../output_files/test/bin/UartDeviceTest --gtest_filter=UartDeviceMockTest.Demo
TEST_F(UartDeviceMockTest, Demo) TEST_F(UartDeviceMockTest, Demo)
{ {
const char *deviceName = "dev/s1"; // EXPECT_CALL(*mLinuxTest.get(), fx_open(deviceName, ::testing::_))
uart_info device = { // .WillRepeatedly(::testing::DoAll((::testing::Return(1000000000))));
deviceName, void *object = CreateUartDevice(gUartDevice);
1152000,
'N',
8,
1,
'N',
};
std::shared_ptr<LinuxApiMockTest> tmp = std::make_shared<LinuxApiMockTest>();
std::shared_ptr<LinuxApiMock> test = tmp;
LinuxApiMock::GetInstance(&test);
EXPECT_CALL(*tmp.get(), fx_open(deviceName, ::testing::_))
.WillRepeatedly(::testing::DoAll((::testing::Return(1000000000))));
void *object = CreateUartDevice(device);
IUartOpen(object); IUartOpen(object);
// IUartSend(object, nullptr, 0); // IUartSend(object, nullptr, 0);
// IUartRecv(object, nullptr, 0, 0); // IUartRecv(object, nullptr, 0, 0);

View File

@ -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})

View File

@ -0,0 +1,3 @@
# Tool目录
&emsp;&emsp;基于模块独立的测试辅助工具,可被外界模块复用。

View File

@ -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<LinuxTest> &mock, const uart_info &uart);
};
#endif

View File

@ -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<LinuxTest> &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))));
}