mirror of
https://gitee.com/jiuyilian/embedded-framework.git
synced 2025-01-06 10:16:51 -05:00
Improve:Optimize the write resend logic when sending.
This commit is contained in:
parent
328b12abc9
commit
06a0edbfd0
|
@ -12,7 +12,7 @@
|
|||
示例:
|
||||
|
||||
```
|
||||
TEST(SharedDataTest, UNIT_SharedData_DEME_Demo7)
|
||||
TEST(SharedDataTest, UNIT_SharedData_EXAMPLE_Demo7)
|
||||
{
|
||||
// TODO:
|
||||
}
|
||||
|
@ -47,13 +47,14 @@ int main(int argc, char *argv[])
|
|||
|
||||
## 1.2. 目录结构
|
||||
|
||||
  所有测试代码位于<test>目录下,<test>下的目录结构保持和<SDK>一致,表示对应sdk代码模块的测试代码;
|
||||
  所有测试代码位于< test >目录下,< test >下的目录结构保持和< SDK >一致,表示对应sdk代码模块的测试代码;
|
||||
|
||||
如果是芯片平台的test目录,需要区分板载测试代码和x86 Linux系统的测试代码;如下:
|
||||
```
|
||||
└── hal
|
||||
├── CMakeLists.txt
|
||||
├── mainTest.cpp
|
||||
├── src // 芯片平台的测试代码
|
||||
└── src_mock // Linux x86测试代码 需要对板载接口打桩进行测试;
|
||||
├── src // 芯片平台的测试代码;
|
||||
├── src_mock // Linux x86测试代码 需要对板载接口打桩进行测试;
|
||||
└── tool // 该模块需要对外复用的测试代码;
|
||||
```
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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_API_MOCK_H
|
||||
#define LINUX_API_MOCK_H
|
||||
#include <gmock/gmock.h>
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 "LinuxApiMock.h"
|
||||
#include "ILog.h"
|
||||
#include "LinuxTestImpl.h"
|
||||
|
|
|
@ -52,20 +52,23 @@ void LinuxTestImpl::ApiInit(std::shared_ptr<LinuxTest> &mock)
|
|||
Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiUnlockThread),
|
||||
ReturnPointee(&openFd)));
|
||||
EXPECT_CALL(*mock.get(), fx_tcgetattr(_, _))
|
||||
.WillRepeatedly(DoAll(Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiLock),
|
||||
WithArgs<0, 1>(Invoke(api_tcgetattr)),
|
||||
Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiLock),
|
||||
ReturnPointee(&resultTcgetattr)));
|
||||
.WillRepeatedly(
|
||||
DoAll(Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiLock),
|
||||
WithArgs<0, 1>(Invoke(api_tcgetattr)),
|
||||
Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiUnlockThread),
|
||||
ReturnPointee(&resultTcgetattr)));
|
||||
EXPECT_CALL(*mock.get(), fx_tcsetattr(_, _, _))
|
||||
.WillRepeatedly(DoAll(Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiLock),
|
||||
WithArgs<0, 1, 2>(Invoke(api_tcsetattr)),
|
||||
Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiLock),
|
||||
ReturnPointee(&resultTcsetattr)));
|
||||
.WillRepeatedly(
|
||||
DoAll(Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiLock),
|
||||
WithArgs<0, 1, 2>(Invoke(api_tcsetattr)),
|
||||
Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiUnlockThread),
|
||||
ReturnPointee(&resultTcsetattr)));
|
||||
EXPECT_CALL(*mock.get(), fx_write(_, _, _))
|
||||
.WillRepeatedly(DoAll(Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiLock),
|
||||
WithArgs<0, 1, 2>(Invoke(api_write)),
|
||||
Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiLock),
|
||||
ReturnPointee(&writeLength)));
|
||||
.WillRepeatedly(
|
||||
DoAll(Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiLock),
|
||||
WithArgs<0, 1, 2>(Invoke(api_write)),
|
||||
Invoke((std::dynamic_pointer_cast<LinuxTestImpl>(mock)).get(), &LinuxTestImpl::ApiUnlockThread),
|
||||
ReturnPointee(&writeLength)));
|
||||
}
|
||||
void LinuxTestImpl::Init() {}
|
||||
void LinuxTestImpl::UnInit()
|
||||
|
|
|
@ -47,7 +47,7 @@ public:
|
|||
std::shared_ptr<LinuxApiMock> test = mLinuxTest;
|
||||
LinuxApiMock::GetInstance(&test);
|
||||
LinuxApiMock::GetInstance()->Init();
|
||||
// UartDeviceDefaultInit(mLinuxTest, gUartDevice);
|
||||
RegisterUartDevice(mLinuxTest, gUartDevice);
|
||||
}
|
||||
virtual void TearDown()
|
||||
{
|
||||
|
@ -60,18 +60,90 @@ public:
|
|||
public:
|
||||
std::shared_ptr<LinuxTest> mLinuxTest;
|
||||
};
|
||||
// ../output_files/test/bin/UartDeviceTest --gtest_filter=UartDeviceMockTest.Demo
|
||||
TEST_F(UartDeviceMockTest, Demo)
|
||||
// ../output_files/test/bin/UartDeviceTest --gtest_filter=UartDeviceMockTest.UNIT_UartDevice_EXAMPLE_Demo
|
||||
TEST_F(UartDeviceMockTest, UNIT_UartDevice_EXAMPLE_Demo)
|
||||
{
|
||||
void *object = CreateUartDevice(gUartDevice);
|
||||
IUartOpen(object);
|
||||
// IUartSend(object, nullptr, 0);
|
||||
const char *SEND_BUF = "TEST";
|
||||
ssize_t sendResult = IUartSend(object, SEND_BUF, strlen(SEND_BUF));
|
||||
EXPECT_EQ(sendResult, static_cast<ssize_t>(strlen(SEND_BUF)));
|
||||
// IUartRecv(object, nullptr, 0, 0);
|
||||
// IUartTcflush(object);
|
||||
IUartDeviceFree(object);
|
||||
}
|
||||
// ../output_files/test/bin/UartDeviceTest --gtest_filter=UartDeviceMockTest.Test
|
||||
TEST_F(UartDeviceMockTest, Test)
|
||||
// ../output_files/test/bin/UartDeviceTest --gtest_filter=UartDeviceMockTest.UNIT_UartDevice_AUTO_ParameterEarror
|
||||
/**
|
||||
* @brief Construct a new test f object
|
||||
* Is the interface accurate when testing parameter errors in this test case.
|
||||
*/
|
||||
TEST_F(UartDeviceMockTest, UNIT_UartDevice_AUTO_ParameterEarror)
|
||||
{
|
||||
char *deviceName = nullptr;
|
||||
static uart_info uartDevice = {
|
||||
deviceName,
|
||||
1152000,
|
||||
'N',
|
||||
8,
|
||||
1,
|
||||
'N',
|
||||
};
|
||||
RegisterUartDevice(mLinuxTest, uartDevice);
|
||||
void *object = CreateUartDevice(uartDevice);
|
||||
IUartOpen(object);
|
||||
IUartDeviceFree(object);
|
||||
EXPECT_EQ(object, nullptr);
|
||||
}
|
||||
// ../output_files/test/bin/UartDeviceTest --gtest_filter=UartDeviceMockTest.UNIT_UartDevice_AUTO_ParameterEarror2
|
||||
/**
|
||||
* @brief Construct a new test f object
|
||||
* Is the interface accurate when testing parameter errors in this test case.
|
||||
*/
|
||||
TEST_F(UartDeviceMockTest, UNIT_UartDevice_AUTO_ParameterEarror2)
|
||||
{
|
||||
// TODO:
|
||||
// const char *SEND_BUF = "TEST";
|
||||
// char *deviceName = (char *)malloc(strlen(SEND_BUF) + 1);
|
||||
// memset(deviceName, 0, strlen(SEND_BUF) + 1);
|
||||
// static uart_info uartDevice = {
|
||||
// "deviceName",
|
||||
// 1152000,
|
||||
// 'N',
|
||||
// 8,
|
||||
// 1,
|
||||
// 'N',
|
||||
// };
|
||||
// RegisterUartDevice(mLinuxTest, uartDevice);
|
||||
// void *object = CreateUartDevice(uartDevice);
|
||||
// IUartOpen(object);
|
||||
// IUartDeviceFree(object);
|
||||
// free(deviceName);
|
||||
// deviceName = nullptr;
|
||||
}
|
||||
// ../output_files/test/bin/UartDeviceTest --gtest_filter=UartDeviceMockTest.UNIT_UartDevice_AUTO_WriteAllData
|
||||
/**
|
||||
* @brief Construct a new test f object
|
||||
* This test case verifies whether the application will call the write function twice until all data is written when the
|
||||
* write function does not write the length of the data.
|
||||
*/
|
||||
TEST_F(UartDeviceMockTest, UNIT_UartDevice_AUTO_WriteAllData)
|
||||
{
|
||||
const char *SEND_BUF = "TEST";
|
||||
constexpr ssize_t SEND_LENGTH = 1; // less than static_cast<ssize_t>(strlen(SEND_BUF))
|
||||
SetSendApiOnce(mLinuxTest, gUartDevice, SEND_LENGTH);
|
||||
void *object = CreateUartDevice(gUartDevice);
|
||||
IUartOpen(object);
|
||||
ssize_t sendResult = IUartSend(object, SEND_BUF, strlen(SEND_BUF));
|
||||
EXPECT_EQ(sendResult, static_cast<ssize_t>(strlen(SEND_BUF)));
|
||||
IUartDeviceFree(object);
|
||||
}
|
||||
// ../output_files/test/bin/UartDeviceTest --gtest_filter=UartDeviceMockTest.UNIT_UartDevice_EXAMPLE_MultiThreadTest
|
||||
/**
|
||||
* @brief Construct a new test f object
|
||||
* This test case tests whether the correct return value can be obtained when simulating multi-threaded operations on
|
||||
* the interface.
|
||||
*/
|
||||
TEST_F(UartDeviceMockTest, UNIT_UartDevice_AUTO_MultiThreadTest)
|
||||
{
|
||||
auto openThread = [](void) {
|
||||
LogInfo("===========openThread \n");
|
||||
|
@ -84,9 +156,5 @@ TEST_F(UartDeviceMockTest, Test)
|
|||
std::thread test2 = std::thread(openThread);
|
||||
test2.detach();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
// std::thread(openThread2);
|
||||
// IUartSend(object, nullptr, 0);
|
||||
// IUartRecv(object, nullptr, 0, 0);
|
||||
// IUartTcflush(object);
|
||||
}
|
||||
} // namespace UartDeviceMockTest
|
|
@ -16,6 +16,7 @@
|
|||
#define UART_DEVICE_TEST_TOOL_H
|
||||
#include "LinuxApiMock.h"
|
||||
#include "UartDevice.h"
|
||||
#include <map>
|
||||
class UartDeviceTestTool
|
||||
{
|
||||
public:
|
||||
|
@ -25,7 +26,19 @@ public:
|
|||
* @brief Enable the UartDevice module to run and debug on Ubuntu
|
||||
*
|
||||
* @param mock
|
||||
* @param uart
|
||||
*/
|
||||
void UartDeviceDefaultInit(std::shared_ptr<LinuxTest> &mock, const uart_info &uart);
|
||||
void RegisterUartDevice(std::shared_ptr<LinuxTest> &mock, const uart_info &uart);
|
||||
/**
|
||||
* @brief Set the Send Api object
|
||||
*
|
||||
* @param mock
|
||||
* @param uart
|
||||
* @param length
|
||||
*/
|
||||
void SetSendApiOnce(std::shared_ptr<LinuxTest> &mock, const uart_info &uart, const ssize_t &length);
|
||||
|
||||
private:
|
||||
std::map<const char *, int> mDeviceMap;
|
||||
};
|
||||
#endif
|
|
@ -14,16 +14,33 @@
|
|||
*/
|
||||
#include "UartDeviceTestTool.h"
|
||||
#include "ILog.h"
|
||||
void UartDeviceTestTool::UartDeviceDefaultInit(std::shared_ptr<LinuxTest> &mock, const uart_info &uart)
|
||||
static size_t WRITE_COUNT = -1;
|
||||
void UartDeviceTestTool::RegisterUartDevice(std::shared_ptr<LinuxTest> &mock, const uart_info &uart)
|
||||
{
|
||||
if (nullptr == uart.mDevice) {
|
||||
LogError("Parament error, nullptr == uartInfo.mDevice\n");
|
||||
return;
|
||||
}
|
||||
constexpr int TCGETATTR_SUCCEED = 0;
|
||||
constexpr int TCSETATTR_SUCCEED = 0;
|
||||
int uartFd = mock->GetHandleForMock();
|
||||
LogInfo("uartFd = %d\n", uartFd);
|
||||
EXPECT_CALL(*mock.get(), fx_open(uart.mDevice, ::testing::_))
|
||||
.WillRepeatedly(::testing::DoAll((::testing::Return(uartFd))));
|
||||
EXPECT_CALL(*mock.get(), fx_tcgetattr(uartFd, ::testing::_))
|
||||
.WillRepeatedly(::testing::DoAll(::testing::Return(TCGETATTR_SUCCEED)));
|
||||
EXPECT_CALL(*mock.get(), fx_tcsetattr(uartFd, ::testing::_, ::testing::_))
|
||||
.WillRepeatedly(::testing::DoAll(::testing::Return(TCSETATTR_SUCCEED)));
|
||||
EXPECT_CALL(*mock.get(), fx_open(uart.mDevice, _)).WillRepeatedly(DoAll((Return(uartFd))));
|
||||
EXPECT_CALL(*mock.get(), fx_tcgetattr(uartFd, _)).WillRepeatedly(DoAll(Return(TCGETATTR_SUCCEED)));
|
||||
EXPECT_CALL(*mock.get(), fx_tcsetattr(uartFd, _, _)).WillRepeatedly(DoAll(Return(TCSETATTR_SUCCEED)));
|
||||
EXPECT_CALL(*mock.get(), fx_write(uartFd, _, _))
|
||||
.WillRepeatedly(DoAll(SaveArg<2>(&WRITE_COUNT), ReturnPointee(&WRITE_COUNT)));
|
||||
mDeviceMap[uart.mDevice] = uartFd;
|
||||
}
|
||||
void UartDeviceTestTool::SetSendApiOnce(std::shared_ptr<LinuxTest> &mock, const uart_info &uart, 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;
|
||||
}
|
||||
EXPECT_CALL(*mock.get(), fx_write(mDeviceMap[uart.mDevice], _, _))
|
||||
.WillOnce(DoAll(Return(length)))
|
||||
.WillRepeatedly(DoAll(SaveArg<2>(&WRITE_COUNT), ReturnPointee(&WRITE_COUNT)));
|
||||
}
|
|
@ -23,11 +23,7 @@
|
|||
#include <unistd.h>
|
||||
|
||||
int fx_system(const char *command) { return system(command); }
|
||||
int fx_open(const char *pathname, int flags)
|
||||
{
|
||||
// printf("ssssssssssssssssssssssssssssssss\n");
|
||||
return open(pathname, flags);
|
||||
}
|
||||
int fx_open(const char *pathname, int flags) { return open(pathname, flags); }
|
||||
int fx_tcgetattr(int fd, struct termios *termios_p) { return tcgetattr(fd, termios_p); }
|
||||
int fx_tcsetattr(int fd, int optional_actions, const struct termios *termios_p)
|
||||
{
|
||||
|
|
|
@ -40,19 +40,25 @@ const StatusCode UartDeviceImpl::UartOpen(void)
|
|||
const size_t UartDeviceImpl::UartSend(const char *buff, const size_t &buffLength)
|
||||
{
|
||||
constexpr int SEND_FAILED = -1;
|
||||
size_t len = 0;
|
||||
size_t writeLength = 0;
|
||||
if (nullptr == buff) {
|
||||
LogError("data buff is nullptr.\n");
|
||||
return SEND_FAILED;
|
||||
}
|
||||
if (mFd <= 0) {
|
||||
LogError("open uart failed.\n");
|
||||
return SEND_FAILED;
|
||||
}
|
||||
// TODO: what if write return less then buffLength?
|
||||
len = write(mFd, buff, buffLength);
|
||||
LogInfo("len = %d\n", len);
|
||||
if (len == buffLength) {
|
||||
return len;
|
||||
size_t writeTotal = 0;
|
||||
while (writeTotal < buffLength) {
|
||||
writeLength = fx_write(mFd, buff, buffLength - writeTotal);
|
||||
writeTotal += writeLength;
|
||||
}
|
||||
if (writeTotal == buffLength) {
|
||||
return writeTotal;
|
||||
}
|
||||
tcflush(mFd, TCOFLUSH);
|
||||
return len;
|
||||
return writeTotal;
|
||||
}
|
||||
const size_t UartDeviceImpl::UartRecv(char *buff, const size_t &buffLength, const unsigned int &timeOutMs,
|
||||
const unsigned int delayRead)
|
||||
|
@ -243,8 +249,13 @@ static void UartImpllFree(void *ptr)
|
|||
LogError("Unknow ptr.\n");
|
||||
}
|
||||
}
|
||||
// static const char *test = "zhanqu";
|
||||
UartDevice *NewUartDeviceImpl(const UartInfo &uartInfo)
|
||||
{
|
||||
if (nullptr == uartInfo.mDevice) {
|
||||
LogError("Parament error, nullptr == uartInfo.mDevice\n");
|
||||
return nullptr;
|
||||
}
|
||||
LogInfo("Create the uart device object.\n");
|
||||
UartDeviceImpl_S *impl = (UartDeviceImpl_S *)malloc(sizeof(UartDeviceImpl_S));
|
||||
UartDeviceImpl_S tmp;
|
||||
|
|
Loading…
Reference in New Issue
Block a user