UratDevice mock code done.

This commit is contained in:
fancy 2024-01-29 12:48:41 -08:00
parent 06a0edbfd0
commit 6e11dc58f6
14 changed files with 201 additions and 38 deletions

View File

@ -15,13 +15,13 @@ if(${TARGET_PLATFORM} MATCHES ${DEFINE_LINUX})
# set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=gethostbyname" CACHE STRING INTERNAL FORCE) # set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=gethostbyname" CACHE STRING INTERNAL FORCE)
# set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=connect" CACHE STRING INTERNAL FORCE) # set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=connect" CACHE STRING INTERNAL FORCE)
# set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=socket" CACHE STRING INTERNAL FORCE) # set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=socket" CACHE STRING INTERNAL FORCE)
# set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=select" CACHE STRING INTERNAL FORCE) set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=fx_select" CACHE STRING INTERNAL FORCE)
# set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=linux_open" CACHE STRING INTERNAL FORCE) # set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=linux_open" CACHE STRING INTERNAL FORCE)
# set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=linux_read" CACHE STRING INTERNAL FORCE) # set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=linux_read" CACHE STRING INTERNAL FORCE)
set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=fx_write" CACHE STRING INTERNAL FORCE) set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=fx_write" CACHE STRING INTERNAL FORCE)
# set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=linux_close" CACHE STRING INTERNAL FORCE) # set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=linux_close" CACHE STRING INTERNAL FORCE)
# set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=linux_fclose" CACHE STRING INTERNAL FORCE) # set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=linux_fclose" CACHE STRING INTERNAL FORCE)
# set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=linux_fread" 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=linux_fcntl" CACHE STRING INTERNAL FORCE) # set(TEST_LINUX_MOCK "${TEST_LINUX_MOCK},--wrap=linux_fcntl" CACHE STRING INTERNAL FORCE)
endif() endif()
# Mock Linux api. # Mock Linux api.

View File

@ -45,6 +45,7 @@ using ::testing::Unused;
using ::testing::WithArgs; using ::testing::WithArgs;
using ::testing::internal::BuiltInDefaultValue; using ::testing::internal::BuiltInDefaultValue;
constexpr int INVALID_HANDLE = -1; constexpr int INVALID_HANDLE = -1;
constexpr int MOCK_SELECT_TIME_OUT = 0;
class LinuxApiMock class LinuxApiMock
{ {
public: public:
@ -65,6 +66,8 @@ public:
virtual int fx_tcgetattr(int fd, struct termios *termios_p); virtual int fx_tcgetattr(int fd, struct termios *termios_p);
virtual int fx_tcsetattr(int fd, int optional_actions, const struct termios *termios_p); virtual int fx_tcsetattr(int fd, int optional_actions, const struct termios *termios_p);
virtual ssize_t fx_write(int fd, const void *buf, size_t count); virtual ssize_t fx_write(int fd, const void *buf, size_t count);
virtual ssize_t fx_read(int fd, void *buf, size_t count);
virtual int fx_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
public: public:
/** /**
@ -91,6 +94,8 @@ public:
MOCK_METHOD2(fx_tcgetattr, int(int, struct termios *)); MOCK_METHOD2(fx_tcgetattr, int(int, struct termios *));
MOCK_METHOD3(fx_tcsetattr, int(int, int, const struct termios *)); MOCK_METHOD3(fx_tcsetattr, int(int, int, const struct termios *));
MOCK_METHOD3(fx_write, ssize_t(int, const void *, size_t)); MOCK_METHOD3(fx_write, ssize_t(int, const void *, size_t));
MOCK_METHOD3(fx_read, ssize_t(int, void *, size_t));
MOCK_METHOD5(fx_select, int(int, fd_set *, fd_set *, fd_set *, struct timeval *));
public: public:
/** /**

View File

@ -15,13 +15,36 @@
#include "LinuxApiMock.h" #include "LinuxApiMock.h"
#include "ILog.h" #include "ILog.h"
#include "LinuxTestImpl.h" #include "LinuxTestImpl.h"
int LinuxApiMock::fx_open(const char *pathname, int flags) { return __real_fx_open(pathname, flags); } #include "WrapApi.h"
int LinuxApiMock::fx_tcgetattr(int fd, struct termios *termios_p) { return __real_fx_tcgetattr(fd, termios_p); } int LinuxApiMock::fx_open(const char *pathname, int flags)
{
// LogInfo("Call the real api.\n");
return __real_fx_open(pathname, flags);
}
int LinuxApiMock::fx_tcgetattr(int fd, struct termios *termios_p)
{
// LogInfo("Call the real api.\n");
return __real_fx_tcgetattr(fd, termios_p);
}
int LinuxApiMock::fx_tcsetattr(int fd, int optional_actions, const struct termios *termios_p) int LinuxApiMock::fx_tcsetattr(int fd, int optional_actions, const struct termios *termios_p)
{ {
return __real_fx_tcsetattr(fd, optional_actions, termios_p); return __real_fx_tcsetattr(fd, optional_actions, termios_p);
} }
ssize_t LinuxApiMock::fx_write(int fd, const void *buf, size_t count) { return __real_fx_write(fd, buf, count); } ssize_t LinuxApiMock::fx_write(int fd, const void *buf, size_t count)
{
// LogInfo("Call the real api.\n");
return __real_fx_write(fd, buf, count);
}
ssize_t LinuxApiMock::fx_read(int fd, void *buf, size_t count)
{
// LogInfo("Call the real api.\n");
return __real_fx_read(fd, buf, count);
}
int LinuxApiMock::fx_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
{
// LogInfo("Call the real api.\n");
return __real_fx_select(nfds, readfds, writefds, exceptfds, timeout);
}
std::shared_ptr<LinuxTest> LinuxTest::CreateLinuxTest(void) std::shared_ptr<LinuxTest> LinuxTest::CreateLinuxTest(void)
{ {
std::shared_ptr<LinuxTest> test = std::make_shared<LinuxTestImpl>(); std::shared_ptr<LinuxTest> test = std::make_shared<LinuxTestImpl>();

View File

@ -30,45 +30,67 @@ void LinuxTestImpl::ApiInit(std::shared_ptr<LinuxTest> &mock)
openFd = __real_fx_open(pathname, flags); openFd = __real_fx_open(pathname, flags);
LogInfo("openFd = %d\n", openFd); LogInfo("openFd = %d\n", openFd);
}; };
static int resultTcgetattr = -1;
auto api_tcgetattr = [=](int fd, struct termios *termios_p) {
resultTcgetattr = __real_fx_tcgetattr(fd, termios_p);
LogInfo("resultTcgetattr = %d\n", resultTcgetattr);
};
static int resultTcsetattr = -1;
auto api_tcsetattr = [=](int fd, int optional_actions, const struct termios *termios_p) {
resultTcsetattr = __real_fx_tcsetattr(fd, optional_actions, termios_p);
LogInfo("resultTcsetattr = %d\n", resultTcsetattr);
};
static int writeLength = -1;
auto api_write = [=](int fd, const void *buf, size_t count) {
writeLength = __real_fx_write(fd, buf, count);
LogInfo("writeLength = %d\n", writeLength);
};
EXPECT_CALL(*mock.get(), fx_open(_, _)) EXPECT_CALL(*mock.get(), fx_open(_, _))
.WillRepeatedly( .WillRepeatedly(
DoAll(Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiLock), DoAll(Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiLock),
WithArgs<0, 1>(Invoke(api_open)), WithArgs<0, 1>(Invoke(api_open)),
Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiUnlockThread), Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiUnlockThread),
ReturnPointee(&openFd))); ReturnPointee(&openFd)));
static int resultTcgetattr = -1;
auto api_tcgetattr = [=](int fd, struct termios *termios_p) {
resultTcgetattr = __real_fx_tcgetattr(fd, termios_p);
LogInfo("resultTcgetattr = %d\n", resultTcgetattr);
};
EXPECT_CALL(*mock.get(), fx_tcgetattr(_, _)) EXPECT_CALL(*mock.get(), fx_tcgetattr(_, _))
.WillRepeatedly( .WillRepeatedly(
DoAll(Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiLock), DoAll(Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiLock),
WithArgs<0, 1>(Invoke(api_tcgetattr)), WithArgs<0, 1>(Invoke(api_tcgetattr)),
Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiUnlockThread), Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiUnlockThread),
ReturnPointee(&resultTcgetattr))); ReturnPointee(&resultTcgetattr)));
static int resultTcsetattr = -1;
auto api_tcsetattr = [=](int fd, int optional_actions, const struct termios *termios_p) {
resultTcsetattr = __real_fx_tcsetattr(fd, optional_actions, termios_p);
LogInfo("resultTcsetattr = %d\n", resultTcsetattr);
};
EXPECT_CALL(*mock.get(), fx_tcsetattr(_, _, _)) EXPECT_CALL(*mock.get(), fx_tcsetattr(_, _, _))
.WillRepeatedly( .WillRepeatedly(
DoAll(Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiLock), DoAll(Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiLock),
WithArgs<0, 1, 2>(Invoke(api_tcsetattr)), WithArgs<0, 1, 2>(Invoke(api_tcsetattr)),
Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiUnlockThread), Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiUnlockThread),
ReturnPointee(&resultTcsetattr))); ReturnPointee(&resultTcsetattr)));
static int writeLength = -1;
auto api_write = [=](int fd, const void *buf, size_t count) {
writeLength = __real_fx_write(fd, buf, count);
LogInfo("writeLength = %d\n", writeLength);
};
EXPECT_CALL(*mock.get(), fx_write(_, _, _)) EXPECT_CALL(*mock.get(), fx_write(_, _, _))
.WillRepeatedly( .WillRepeatedly(
DoAll(Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiLock), DoAll(Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiLock),
WithArgs<0, 1, 2>(Invoke(api_write)), WithArgs<0, 1, 2>(Invoke(api_write)),
Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiUnlockThread), Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiUnlockThread),
ReturnPointee(&writeLength))); ReturnPointee(&writeLength)));
static int readLength = -1;
auto api_read = [=](int fd, void *buf, size_t count) {
readLength = __real_fx_read(fd, buf, count);
LogInfo("readLength = %d\n", readLength);
};
EXPECT_CALL(*mock.get(), fx_read(_, _, _))
.WillRepeatedly(
DoAll(Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiLock),
WithArgs<0, 1, 2>(Invoke(api_read)),
Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiUnlockThread),
ReturnPointee(&readLength)));
static int selectResult = -1;
auto api_select = [=](int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) {
selectResult = __real_fx_select(nfds, readfds, writefds, exceptfds, timeout);
LogInfo("selectResult = %d\n", selectResult);
};
EXPECT_CALL(*mock.get(), fx_select(_, _, _, _, _))
.WillRepeatedly(
DoAll(Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiLock),
WithArgs<0, 1, 2, 3, 4>(Invoke(api_select)),
Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiUnlockThread),
ReturnPointee(&selectResult)));
} }
void LinuxTestImpl::Init() {} void LinuxTestImpl::Init() {}
void LinuxTestImpl::UnInit() void LinuxTestImpl::UnInit()

View File

@ -30,6 +30,11 @@ ssize_t __wrap_fx_write(int fd, const void *buf, size_t count)
{ {
return LinuxApiMock::GetInstance()->fx_write(fd, buf, count); return LinuxApiMock::GetInstance()->fx_write(fd, buf, count);
} }
ssize_t __wrap_fx_read(int fd, void *buf, size_t count) { 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)
{
return LinuxApiMock::GetInstance()->fx_select(nfds, readfds, writefds, exceptfds, timeout);
}
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -14,6 +14,9 @@
*/ */
#ifndef WRAP_API_H #ifndef WRAP_API_H
#define WRAP_API_H #define WRAP_API_H
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -23,6 +26,8 @@ int __real_fx_open(const char *pathname, int flags);
int __real_fx_tcgetattr(int fd, struct termios *termios_p); int __real_fx_tcgetattr(int fd, struct termios *termios_p);
int __real_fx_tcsetattr(int fd, int optional_actions, const struct termios *termios_p); int __real_fx_tcsetattr(int fd, int optional_actions, const struct termios *termios_p);
ssize_t __real_fx_write(int fd, const void *buf, size_t count); ssize_t __real_fx_write(int fd, const void *buf, size_t count);
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);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -18,11 +18,11 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
namespace UartDeviceTest namespace UartDeviceTest
{ {
// ../output_files/test/bin/UartDeviceTest --gtest_filter=UartDeviceTest.IllegalObject // ../output_files/test/bin/UartDeviceTest --gtest_filter=UartDeviceTest.UNIT_UartDevice_AUTO_IllegalObject
/** /**
* UartDevice module api will not crash when object is illegal. * UartDevice module api will not crash when object is illegal.
*/ */
TEST(UartDeviceTest, IllegalObject) TEST(UartDeviceTest, UNIT_UartDevice_AUTO_IllegalObject)
{ {
CreateLogModule(); CreateLogModule();
ILogInit(LOG_INSTANCE_TYPE_END); ILogInit(LOG_INSTANCE_TYPE_END);
@ -31,8 +31,8 @@ TEST(UartDeviceTest, IllegalObject)
IUartRecv(nullptr, nullptr, 0, 0); IUartRecv(nullptr, nullptr, 0, 0);
IUartTcflush(nullptr); IUartTcflush(nullptr);
IUartDeviceFree(nullptr); IUartDeviceFree(nullptr);
int illegalObject = 0; char illegalObject[100] = {0};
void *object = &illegalObject; void *object = &illegalObject[10];
IUartOpen(object); IUartOpen(object);
IUartSend(object, nullptr, 0); IUartSend(object, nullptr, 0);
IUartRecv(object, nullptr, 0, 0); IUartRecv(object, nullptr, 0, 0);
@ -40,8 +40,8 @@ TEST(UartDeviceTest, IllegalObject)
IUartDeviceFree(object); IUartDeviceFree(object);
ILogUnInit(); ILogUnInit();
} }
// ../output_files/test/bin/UartDeviceTest --gtest_filter=UartDeviceTest.Demo // ../output_files/test/bin/UartDeviceTest --gtest_filter=UartDeviceTest.UNIT_UartDevice_EXAMPLE_Demo
TEST(UartDeviceTest, Demo) TEST(UartDeviceTest, UNIT_UartDevice_EXAMPLE_Demo)
{ {
CreateLogModule(); CreateLogModule();
ILogInit(LOG_INSTANCE_TYPE_END); ILogInit(LOG_INSTANCE_TYPE_END);

View File

@ -55,21 +55,26 @@ public:
mLinuxTest = std::make_shared<LinuxTest>(); mLinuxTest = std::make_shared<LinuxTest>();
std::shared_ptr<LinuxApiMock> test = std::make_shared<LinuxApiMock>(); std::shared_ptr<LinuxApiMock> test = std::make_shared<LinuxApiMock>();
LinuxApiMock::GetInstance(&test); LinuxApiMock::GetInstance(&test);
UnregisterUartDevice(gUartDevice);
} }
public: public:
std::shared_ptr<LinuxTest> mLinuxTest; std::shared_ptr<LinuxTest> mLinuxTest;
}; };
// ../output_files/test/bin/UartDeviceTest --gtest_filter=UartDeviceMockTest.UNIT_UartDevice_EXAMPLE_Demo // ../output_files/test/bin/UartDeviceTest --gtest_filter=UartDeviceMockTest.UNIT_UartDevice_EXAMPLE_AUTO_Demo
TEST_F(UartDeviceMockTest, UNIT_UartDevice_EXAMPLE_Demo) TEST_F(UartDeviceMockTest, UNIT_UartDevice_EXAMPLE_AUTO_Demo)
{ {
void *object = CreateUartDevice(gUartDevice); void *object = CreateUartDevice(gUartDevice);
IUartOpen(object); IUartOpen(object);
const char *SEND_BUF = "TEST"; const char *SEND_BUF = "TEST";
ssize_t sendResult = IUartSend(object, SEND_BUF, strlen(SEND_BUF)); ssize_t sendResult = IUartSend(object, SEND_BUF, strlen(SEND_BUF));
EXPECT_EQ(sendResult, static_cast<ssize_t>(strlen(SEND_BUF))); EXPECT_EQ(sendResult, static_cast<ssize_t>(strlen(SEND_BUF)));
// IUartRecv(object, nullptr, 0, 0); constexpr int RECV_TIME_OUT_MS = 1000;
// IUartTcflush(object); constexpr int RECV_BUF_LENGTH = 256;
char recvBuf[RECV_BUF_LENGTH] = {0};
ssize_t recvResult = IUartRecv(object, recvBuf, RECV_BUF_LENGTH, RECV_TIME_OUT_MS);
LogInfo("recvResult = %d\n", recvResult);
IUartTcflush(object);
IUartDeviceFree(object); IUartDeviceFree(object);
} }
// ../output_files/test/bin/UartDeviceTest --gtest_filter=UartDeviceMockTest.UNIT_UartDevice_AUTO_ParameterEarror // ../output_files/test/bin/UartDeviceTest --gtest_filter=UartDeviceMockTest.UNIT_UartDevice_AUTO_ParameterEarror
@ -93,6 +98,7 @@ TEST_F(UartDeviceMockTest, UNIT_UartDevice_AUTO_ParameterEarror)
IUartOpen(object); IUartOpen(object);
IUartDeviceFree(object); IUartDeviceFree(object);
EXPECT_EQ(object, nullptr); EXPECT_EQ(object, nullptr);
UnregisterUartDevice(uartDevice);
} }
// ../output_files/test/bin/UartDeviceTest --gtest_filter=UartDeviceMockTest.UNIT_UartDevice_AUTO_ParameterEarror2 // ../output_files/test/bin/UartDeviceTest --gtest_filter=UartDeviceMockTest.UNIT_UartDevice_AUTO_ParameterEarror2
/** /**
@ -137,6 +143,21 @@ TEST_F(UartDeviceMockTest, UNIT_UartDevice_AUTO_WriteAllData)
EXPECT_EQ(sendResult, static_cast<ssize_t>(strlen(SEND_BUF))); EXPECT_EQ(sendResult, static_cast<ssize_t>(strlen(SEND_BUF)));
IUartDeviceFree(object); IUartDeviceFree(object);
} }
// ../output_files/test/bin/UartDeviceTest --gtest_filter=UartDeviceMockTest.UNIT_UartDevice_AUTO_RecvData
TEST_F(UartDeviceMockTest, UNIT_UartDevice_AUTO_RecvData)
{
const char *RECV_BUFF = "TEST";
SetRecvApiOnce(mLinuxTest, gUartDevice, (void *)RECV_BUFF, strlen(RECV_BUFF));
void *object = CreateUartDevice(gUartDevice);
IUartOpen(object);
constexpr int RECV_TIME_OUT_MS = 1000;
constexpr int RECV_BUF_LENGTH = 256;
char recvBuf[RECV_BUF_LENGTH] = {0};
ssize_t recvResult = IUartRecv(object, recvBuf, RECV_BUF_LENGTH, RECV_TIME_OUT_MS);
EXPECT_EQ(recvResult, static_cast<ssize_t>(strlen(RECV_BUFF)));
EXPECT_EQ(0, memcmp(recvBuf, RECV_BUFF, strlen(RECV_BUFF)));
IUartDeviceFree(object);
}
// ../output_files/test/bin/UartDeviceTest --gtest_filter=UartDeviceMockTest.UNIT_UartDevice_EXAMPLE_MultiThreadTest // ../output_files/test/bin/UartDeviceTest --gtest_filter=UartDeviceMockTest.UNIT_UartDevice_EXAMPLE_MultiThreadTest
/** /**
* @brief Construct a new test f object * @brief Construct a new test f object

View File

@ -29,6 +29,12 @@ public:
* @param uart * @param uart
*/ */
void RegisterUartDevice(std::shared_ptr<LinuxTest> &mock, const uart_info &uart); void RegisterUartDevice(std::shared_ptr<LinuxTest> &mock, const uart_info &uart);
/**
* @brief
*
* @param uart
*/
void UnregisterUartDevice(const uart_info &uart);
/** /**
* @brief Set the Send Api object * @brief Set the Send Api object
* *
@ -37,6 +43,15 @@ public:
* @param length * @param length
*/ */
void SetSendApiOnce(std::shared_ptr<LinuxTest> &mock, const uart_info &uart, const ssize_t &length); void SetSendApiOnce(std::shared_ptr<LinuxTest> &mock, const uart_info &uart, const ssize_t &length);
/**
* @brief Set the Recv Api Once object
*
* @param mock
* @param uart
* @param recvBuff
* @param length
*/
void SetRecvApiOnce(std::shared_ptr<LinuxTest> &mock, const uart_info &uart, void *recvBuff, const ssize_t &length);
private: private:
std::map<const char *, int> mDeviceMap; std::map<const char *, int> mDeviceMap;

View File

@ -14,6 +14,7 @@
*/ */
#include "UartDeviceTestTool.h" #include "UartDeviceTestTool.h"
#include "ILog.h" #include "ILog.h"
#include <thread>
static size_t WRITE_COUNT = -1; static size_t WRITE_COUNT = -1;
void UartDeviceTestTool::RegisterUartDevice(std::shared_ptr<LinuxTest> &mock, const uart_info &uart) void UartDeviceTestTool::RegisterUartDevice(std::shared_ptr<LinuxTest> &mock, const uart_info &uart)
{ {
@ -30,8 +31,27 @@ void UartDeviceTestTool::RegisterUartDevice(std::shared_ptr<LinuxTest> &mock, co
EXPECT_CALL(*mock.get(), fx_tcsetattr(uartFd, _, _)).WillRepeatedly(DoAll(Return(TCSETATTR_SUCCEED))); EXPECT_CALL(*mock.get(), fx_tcsetattr(uartFd, _, _)).WillRepeatedly(DoAll(Return(TCSETATTR_SUCCEED)));
EXPECT_CALL(*mock.get(), fx_write(uartFd, _, _)) EXPECT_CALL(*mock.get(), fx_write(uartFd, _, _))
.WillRepeatedly(DoAll(SaveArg<2>(&WRITE_COUNT), ReturnPointee(&WRITE_COUNT))); .WillRepeatedly(DoAll(SaveArg<2>(&WRITE_COUNT), ReturnPointee(&WRITE_COUNT)));
auto selectTimeOut =
[=, &mock](int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) {
long long timeMs = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
std::this_thread::sleep_for(std::chrono::milliseconds(timeMs));
};
EXPECT_CALL(*mock.get(), fx_select(uartFd + 1, _, _, _, _))
.WillRepeatedly(DoAll(WithArgs<0, 1, 2, 3, 4>(Invoke(selectTimeOut)), Return(MOCK_SELECT_TIME_OUT)));
constexpr int READ_NOTHING = 0;
EXPECT_CALL(*mock.get(), fx_read(uartFd, _, _)).WillRepeatedly(DoAll(Return(READ_NOTHING)));
mDeviceMap[uart.mDevice] = uartFd; mDeviceMap[uart.mDevice] = uartFd;
} }
void UartDeviceTestTool::UnregisterUartDevice(const uart_info &uart)
{
std::map<const char *, int>::iterator iter;
iter = mDeviceMap.find(uart.mDevice);
if (iter != mDeviceMap.end()) {
mDeviceMap.erase(iter);
return;
}
LogError("Can't found the uart device[%s].\n", uart.mDevice);
}
void UartDeviceTestTool::SetSendApiOnce(std::shared_ptr<LinuxTest> &mock, const uart_info &uart, const ssize_t &length) void UartDeviceTestTool::SetSendApiOnce(std::shared_ptr<LinuxTest> &mock, const uart_info &uart, const ssize_t &length)
{ {
std::map<const char *, int>::iterator iter; std::map<const char *, int>::iterator iter;
@ -44,3 +64,33 @@ void UartDeviceTestTool::SetSendApiOnce(std::shared_ptr<LinuxTest> &mock, const
.WillOnce(DoAll(Return(length))) .WillOnce(DoAll(Return(length)))
.WillRepeatedly(DoAll(SaveArg<2>(&WRITE_COUNT), ReturnPointee(&WRITE_COUNT))); .WillRepeatedly(DoAll(SaveArg<2>(&WRITE_COUNT), ReturnPointee(&WRITE_COUNT)));
} }
void UartDeviceTestTool::SetRecvApiOnce(std::shared_ptr<LinuxTest> &mock, const uart_info &uart, void *recvBuff,
const ssize_t &length)
{
std::map<const char *, int>::iterator iter;
iter = mDeviceMap.find(uart.mDevice);
if (iter == mDeviceMap.end()) {
LogError("Can't found the uart device[%s].\n", uart.mDevice);
return;
}
int uartFd = mDeviceMap[uart.mDevice];
auto selectSucceed =
[=, &mock](int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) {
FD_ZERO(readfds);
FD_SET(uartFd, readfds);
};
auto selectTimeOut =
[=, &mock](int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) {
long long timeMs = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
std::this_thread::sleep_for(std::chrono::milliseconds(timeMs));
};
constexpr int SELECT_READABLE = 1;
EXPECT_CALL(*mock.get(), fx_select(uartFd + 1, _, _, _, _))
.WillOnce(DoAll(WithArgs<0, 1, 2, 3, 4>(Invoke(selectSucceed)), Return(SELECT_READABLE)))
.WillRepeatedly(DoAll(WithArgs<0, 1, 2, 3, 4>(Invoke(selectTimeOut)), Return(MOCK_SELECT_TIME_OUT)));
auto readBuf = [=, &mock](int fd, void *buf, size_t count) { memcpy(buf, recvBuff, length); };
constexpr int READ_NOTHING = 0;
EXPECT_CALL(*mock.get(), fx_read(uartFd, _, _))
.WillOnce(DoAll(WithArgs<0, 1, 2>(Invoke(readBuf)), Return(length)))
.WillRepeatedly(DoAll(Return(READ_NOTHING)));
}

View File

@ -15,6 +15,9 @@
#ifndef LINUX_API_H #ifndef LINUX_API_H
#define LINUX_API_H #define LINUX_API_H
#include <stddef.h> #include <stddef.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <termios.h> #include <termios.h>
#include <unistd.h> #include <unistd.h>
#ifdef __cplusplus #ifdef __cplusplus
@ -25,6 +28,8 @@ int fx_open(const char *pathname, int flags);
int fx_tcgetattr(int fd, struct termios *termios_p); int fx_tcgetattr(int fd, struct termios *termios_p);
int fx_tcsetattr(int fd, int optional_actions, const struct termios *termios_p); int fx_tcsetattr(int fd, int optional_actions, const struct termios *termios_p);
ssize_t fx_write(int fd, const void *buf, size_t count); ssize_t fx_write(int fd, const void *buf, size_t count);
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);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -30,3 +30,8 @@ int fx_tcsetattr(int fd, int optional_actions, const struct termios *termios_p)
return tcsetattr(fd, optional_actions, termios_p); return tcsetattr(fd, optional_actions, termios_p);
} }
ssize_t fx_write(int fd, const void *buf, size_t count) { return write(fd, buf, count); } ssize_t fx_write(int fd, const void *buf, size_t count) { return write(fd, buf, count); }
ssize_t fx_read(int fd, void *buf, size_t count) { return read(fd, buf, count); }
int fx_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
{
return select(nfds, readfds, writefds, exceptfds, timeout);
}

View File

@ -22,6 +22,7 @@
#include <stdio.h> #include <stdio.h>
#include <sys/types.h> #include <sys/types.h>
#include <termios.h> #include <termios.h>
#include <thread>
#include <unistd.h> #include <unistd.h>
constexpr int INVALID_FD = -1; constexpr int INVALID_FD = -1;
static const char *UART_DEVICE_NAME = "uart_device"; static const char *UART_DEVICE_NAME = "uart_device";
@ -61,14 +62,20 @@ const size_t UartDeviceImpl::UartSend(const char *buff, const size_t &buffLength
return writeTotal; return writeTotal;
} }
const size_t UartDeviceImpl::UartRecv(char *buff, const size_t &buffLength, const unsigned int &timeOutMs, const size_t UartDeviceImpl::UartRecv(char *buff, const size_t &buffLength, const unsigned int &timeOutMs,
const unsigned int delayRead) const unsigned int delayReadMs)
{ {
constexpr int RECV_FAILED = -1; constexpr int RECV_FAILED = -1;
int len, fs_sel; int readLength = 0;
int fs_sel = -1;
fd_set fs_read; fd_set fs_read;
struct timeval time; struct timeval time;
if (nullptr == buff) {
LogError("data buff is nullptr.\n");
return RECV_FAILED;
}
if (mFd <= 0) { if (mFd <= 0) {
LogError("open uart failed.\n");
return RECV_FAILED; return RECV_FAILED;
} }
@ -76,11 +83,11 @@ const size_t UartDeviceImpl::UartRecv(char *buff, const size_t &buffLength, cons
FD_SET(mFd, &fs_read); FD_SET(mFd, &fs_read);
time.tv_sec = timeOutMs / 1000; time.tv_sec = timeOutMs / 1000;
time.tv_usec = (timeOutMs % 1000) * 1000; time.tv_usec = (timeOutMs % 1000) * 1000;
fs_sel = select(mFd + 1, &fs_read, NULL, NULL, &time); fs_sel = fx_select(mFd + 1, &fs_read, NULL, NULL, &time);
if (fs_sel) { if (fs_sel) {
usleep(1000 * delayRead); std::this_thread::sleep_for(std::chrono::milliseconds(delayReadMs));
len = read(mFd, buff, buffLength); readLength = fx_read(mFd, buff, buffLength);
return len; return readLength;
} }
return RECV_FAILED; return RECV_FAILED;
} }

View File

@ -31,7 +31,7 @@ public:
const StatusCode UartOpen(void); const StatusCode UartOpen(void);
const size_t UartSend(const char *buff, const size_t &buffLength); const size_t UartSend(const char *buff, const size_t &buffLength);
const size_t UartRecv(char *buff, const size_t &buffLength, const unsigned int &timeOutMs = 0, const size_t UartRecv(char *buff, const size_t &buffLength, const unsigned int &timeOutMs = 0,
const unsigned int delayRead = 0); const unsigned int delayReadMs = 0);
void UartTcflush(void); void UartTcflush(void);
private: private: