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
./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(

View File

@ -1,5 +1,7 @@
#ifndef LINUX_API_MOCK_H
#define LINUX_API_MOCK_H
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <memory>
#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<LinuxTest> CreateLinuxTest(void);
};
#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 "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); }
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)
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})
define_file_name(${TARGET_NAME})
add_subdirectory(tool)

View File

@ -15,18 +15,21 @@
#include "ILog.h"
#include "LinuxApiMock.h"
#include "UartDevice.h"
#include "UartDeviceTestTool.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
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<LinuxApiMock> test = mLinuxTest;
LinuxApiMock::GetInstance(&test);
UartDeviceDefaultInit(mLinuxTest, gUartDevice);
}
virtual void TearDown() {}
public:
std::shared_ptr<LinuxTest> mLinuxTest;
// std::shared_ptr<LinuxApiMock> 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<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);
// 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);

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