• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "uart_test.h"
17 
18 #include <random>
19 
20 using namespace testing::ext;
21 using ::testing::_;
22 using ::testing::AnyNumber;
23 using ::testing::Return;
24 using namespace testing;
25 
26 namespace Hdc {
27 class HdcUARTBaseTest : public testing::Test {
28 public:
29     static void SetUpTestCase(void);
30     static void TearDownTestCase(void);
31     void SetUp();
32     void TearDown();
33     std::default_random_engine rnd;
34 
35     bool MakeData(std::vector<uint8_t> &data, UartHead &head);
36     bool MakeRndData(std::vector<uint8_t> &data, uint32_t sessionId);
37     bool MakeDemoData(std::vector<uint8_t> &data, uint32_t sessionId);
38 
39     static constexpr uint32_t serverId = 1235;
40     static constexpr uint32_t daemonSessionId = 1236;
41     static constexpr uint32_t packageIndex = 1237;
42     std::unique_ptr<HdcUART> serverHdcUart;
43     std::unique_ptr<HdcSession> server;
44     std::unique_ptr<HdcUART> daemonHdcUart;
45     std::unique_ptr<HdcSession> daemon;
46     const std::string testString = "HDC_UART_TEST";
47 
48     class MockHdcSessionBase : public HdcSessionBase {
MockHdcSessionBase(bool serverOrDaemon)49         explicit MockHdcSessionBase(bool serverOrDaemon) : HdcSessionBase(serverOrDaemon) {};
50         MOCK_METHOD1(FreeSession, void(const uint32_t));
51     } mockSessionBase;
52 
53     class MockBaseInterface : public ExternInterface {
54     public:
55         std::vector<uint8_t> expectUserData;
56 
57         MOCK_METHOD3(UvTcpInit, int(uv_loop_t *, uv_tcp_t *, int));
58         MOCK_METHOD3(UvRead, int(uv_stream_t *, uv_alloc_cb, uv_read_cb));
59         MOCK_METHOD3(SendToStream, int(uv_stream_t *, const uint8_t *, const int));
60     } mockInterface;
61 
62     // this mock use to test SendUARTBlock
63     // it will check from SendUARTRaw for data format and content
64     class MockHdcUARTBase : public HdcUARTBase {
65     public:
66         std::vector<uint8_t> expectRawData;
67         MOCK_METHOD2(SendUartSoftReset, void(HSession, uint32_t));
68         MOCK_METHOD1(ResetOldSession, void(uint32_t));
69         MOCK_METHOD3(RequestSendPackage, void(uint8_t *, const size_t, bool));
70         MOCK_METHOD1(ProcessResponsePackage, void(const UartHead &));
71         MOCK_METHOD3(ResponseUartTrans, void(uint32_t, uint32_t, UartProtocolOption));
72         MOCK_METHOD3(UartToHdcProtocol, int(uv_stream_t *, uint8_t *, int));
73         MOCK_METHOD1(OnTransferError, void(const HSession));
74         MOCK_METHOD2(GetSession, HSession(uint32_t, bool));
75         MOCK_METHOD1(ClearUARTOutMap, void(uint32_t));
76 
MockHdcUARTBase(HdcSessionBase & mockSessionBaseIn,MockBaseInterface & interfaceIn)77         MockHdcUARTBase(HdcSessionBase &mockSessionBaseIn, MockBaseInterface &interfaceIn)
78             : HdcUARTBase(mockSessionBaseIn, interfaceIn) {};
79     } mockUARTBase;
80 #if HDC_HOST
81     static constexpr bool serverOrDaemon = true;
82 #else
83     static constexpr bool serverOrDaemon = false;
84 #endif
HdcUARTBaseTest()85     HdcUARTBaseTest()
86         : mockSessionBase(serverOrDaemon), mockUARTBase(mockSessionBase, mockInterface)
87     {
88     }
89     const std::vector<size_t> testPackageSize = {
90         0u,
91         1u,
92         MAX_UART_SIZE_IOBUF - 1u,
93         MAX_UART_SIZE_IOBUF,
94         MAX_UART_SIZE_IOBUF + 1u,
95         MAX_UART_SIZE_IOBUF * 2u - 1u,
96         MAX_UART_SIZE_IOBUF * 2u,
97         MAX_UART_SIZE_IOBUF * 2u + 1u,
98         MAX_UART_SIZE_IOBUF * 3u + 1u,
99         MAX_UART_SIZE_IOBUF * 4u + 1u,
100     };
101 };
102 
SetUpTestCase()103 void HdcUARTBaseTest::SetUpTestCase()
104 {
105 #ifdef UT_DEBUG
106     Hdc::Base::SetLogLevel(LOG_ALL);
107 #else
108     Hdc::Base::SetLogLevel(LOG_OFF);
109 #endif
110 }
111 
TearDownTestCase()112 void HdcUARTBaseTest::TearDownTestCase() {}
113 
SetUp()114 void HdcUARTBaseTest::SetUp()
115 {
116     serverHdcUart = std::make_unique<HdcUART>();
117     server = std::make_unique<HdcSession>();
118     server->serverOrDaemon = true;
119     server->sessionId = serverId;
120     server->hUART = serverHdcUart.get();
121 
122     daemonHdcUart = std::make_unique<HdcUART>();
123     daemon = std::make_unique<HdcSession>();
124     daemon->serverOrDaemon = false;
125     daemon->sessionId = daemonSessionId;
126     daemon->hUART = daemonHdcUart.get();
127 
128     mockInterface.expectUserData.clear();
129 }
130 
TearDown()131 void HdcUARTBaseTest::TearDown() {}
132 
MakeRndData(std::vector<uint8_t> & data,uint32_t sessionId)133 bool HdcUARTBaseTest::MakeRndData(std::vector<uint8_t> &data, uint32_t sessionId)
134 {
135     UartHead head;
136     head.option = PKG_OPTION_TAIL;
137     head.sessionId = sessionId;
138     head.packageIndex = packageIndex;
139 
140     if (data.empty()) {
141         const int MaxTestBufSize = MAX_UART_SIZE_IOBUF * 2 + 2;
142         data.resize(MaxTestBufSize);
143     }
144     const constexpr int mod = 100;
145     std::generate(data.begin(), data.end(), [&]() { return rnd() % mod; });
146     return MakeData(data, head);
147 }
148 
MakeDemoData(std::vector<uint8_t> & data,uint32_t sessionId)149 bool HdcUARTBaseTest::MakeDemoData(std::vector<uint8_t> &data, uint32_t sessionId)
150 {
151     UartHead head;
152     head.option = PKG_OPTION_TAIL;
153     head.sessionId = sessionId;
154     head.packageIndex = packageIndex;
155 
156     data.resize(sizeof(UartHead) + testString.size());
157     head.dataSize = testString.size();
158 
159     return MakeData(data, head);
160 }
161 
MakeData(std::vector<uint8_t> & data,UartHead & head)162 bool HdcUARTBaseTest::MakeData(std::vector<uint8_t> &data, UartHead &head)
163 {
164     // head
165     if (memcpy_s(data.data(), data.size(), &head, sizeof(UartHead)) != EOK) {
166         return false;
167     }
168 
169     // data
170     unsigned char *dataPtr = data.data() + sizeof(UartHead);
171     size_t dataSize = data.size() - sizeof(UartHead);
172     if (memcpy_s(dataPtr, dataSize, testString.data(), testString.size()) != EOK) {
173         return false;
174     }
175 
176     return true;
177 }
178 
179 /*
180  * @tc.name: SendUARTRaw
181  * @tc.desc: Virtual function verification
182  * @tc.type: FUNC
183  */
184 HWTEST_F(HdcUARTBaseTest, SendUARTRaw, TestSize.Level1)
185 {
186     HSession hSession = nullptr;
187     unsigned char dummyData[] = "1234567980";
188     uint8_t *dummyPtr = static_cast<unsigned char *>(&dummyData[0]);
189     int dummySize = sizeof(dummyData);
190     EXPECT_CALL(mockUARTBase, GetSession).Times(1);
191     EXPECT_EQ(mockUARTBase.SendUARTRaw(hSession, dummyPtr, dummySize), 0);
192 }
193 
194 /*
195  * @tc.name: ResetOldSession
196  * @tc.desc: Virtual function verification
197  * @tc.type: FUNC
198  */
199 HWTEST_F(HdcUARTBaseTest, ResetOldSession, TestSize.Level1)
200 {
__anon6048c1370202(uint32_t sessionId) 201     EXPECT_CALL(mockUARTBase, ResetOldSession).WillRepeatedly([&](uint32_t sessionId) {
202         mockUARTBase.HdcUARTBase::ResetOldSession(sessionId);
203     });
204     const uint32_t sessionId = 12345;
205     EXPECT_CALL(mockUARTBase, ResetOldSession(sessionId)).Times(1);
206     mockUARTBase.ResetOldSession(sessionId);
207 }
208 
209 /*
210  * @tc.name: SendUartSoftReset
211  * @tc.desc: Virtual function verification
212  * @tc.type: FUNC
213  */
214 HWTEST_F(HdcUARTBaseTest, SendUartSoftReset, TestSize.Level1)
215 {
216     EXPECT_CALL(mockUARTBase, SendUartSoftReset)
__anon6048c1370302(HSession hUART, uint32_t sessionId) 217         .WillRepeatedly([&](HSession hUART, uint32_t sessionId) {
218             mockUARTBase.HdcUARTBase::SendUartSoftReset(hUART, sessionId);
219         });
220     HSession hSession = nullptr;
221     uint32_t sessionId = 1234567980;
222     EXPECT_CALL(mockUARTBase, SendUartSoftReset(hSession, sessionId)).Times(1);
223     mockUARTBase.SendUartSoftReset(hSession, sessionId);
224 }
225 
226 /*
227  * @tc.name: SendUARTBlock
228  * @tc.desc: Check the data sub-package function, package content, header content.
229  * @tc.type: FUNC
230  */
231 HWTEST_F(HdcUARTBaseTest, SendUARTBlock, TestSize.Level1)
232 {
233     std::vector<uint8_t> sourceData(testPackageSize.back());
234     MakeRndData(sourceData, server->sessionId);
235     ASSERT_GE(sourceData.size(), testPackageSize.back());
236     for (size_t i = 0; i < testPackageSize.size(); i++) {
237         size_t maxSendSize = MAX_UART_SIZE_IOBUF - sizeof(UartHead);
238         int sendTimes =
239             (testPackageSize[i] / maxSendSize) + (testPackageSize[i] % maxSendSize > 0 ? 1 : 0);
240         if (testPackageSize[i] == 0) {
241             sendTimes = 1; // we allow send empty package
242         }
243         const uint8_t *sourceDataPoint = sourceData.data();
244         size_t sendOffset = 0;
245         EXPECT_CALL(mockUARTBase, RequestSendPackage(_, Le(MAX_UART_SIZE_IOBUF), true))
246             .Times(sendTimes)
__anon6048c1370402(uint8_t *data, const size_t length, bool queue) 247             .WillRepeatedly(Invoke([&](uint8_t *data, const size_t length, bool queue) {
248                 // must big thean head
249                 ASSERT_GE(length, sizeof(UartHead));
250 
251                 // check head
252                 const void *pHead = static_cast<const void *>(data);
253                 const UartHead *pUARTHead = static_cast<const UartHead *>(pHead);
254 
255                 // magic check
256                 ASSERT_EQ(pUARTHead->flag[0], 'H');
257                 ASSERT_EQ(pUARTHead->flag[1], 'W');
258 
259                 // sessionId always should this one
260                 ASSERT_EQ(pUARTHead->sessionId, server->sessionId);
261 
262                 // check data size in head
263                 ASSERT_EQ(pUARTHead->dataSize, length - sizeof(UartHead));
264                 sendOffset += pUARTHead->dataSize;
265                 ASSERT_LE(sendOffset, testPackageSize[i]);
266 
267                 // check data
268                 const uint8_t *pData = (data + sizeof(UartHead));
269 
270                 // expectData_ only have data info . not include head
271                 for (uint32_t i = 0; i < pUARTHead->dataSize; i++) {
272                     ASSERT_EQ(sourceDataPoint[i], pData[i]);
273                 }
274                 // after check ,move the pointer for next
275                 sourceDataPoint += pUARTHead->dataSize;
276 
277                 printf("check %zu bytes\n", length);
278             }));
279         ASSERT_EQ(mockUARTBase.SendUARTData(server.get(), sourceData.data(), testPackageSize[i]),
280                   static_cast<int>(testPackageSize[i]));
281         ASSERT_EQ(sendOffset, testPackageSize[i]);
282     }
283 }
284 
285 /*
286  * @tc.name: UartSendToHdcStream
287  * @tc.desc: Check the behavior of the UartSendToHdcStream function
288  *           buf does not reach the head length
289  * @tc.type: FUNC
290  */
291 HWTEST_F(HdcUARTBaseTest, UartSendToHdcStreamLessBuff, TestSize.Level1)
292 {
293     std::vector<uint8_t> data;
294     MakeRndData(data, server->sessionId);
295 
296     for (unsigned int i = 0; i < sizeof(UartHead); i++) {
297         EXPECT_CALL(mockUARTBase, ResponseUartTrans).Times(0);
298         ASSERT_EQ(mockUARTBase.UartSendToHdcStream(server.get(), data.data(), i), true);
299     }
300     for (unsigned int i = 0; i < sizeof(UartHead); i++) {
301         EXPECT_CALL(mockUARTBase, ResponseUartTrans).Times(0);
302         ASSERT_EQ(mockUARTBase.UartSendToHdcStream(daemon.get(), data.data(), i), true);
303     }
304 }
305 
306 /*
307  * @tc.name: UartSendToHdcStream
308  * @tc.desc: Check the behavior of the UartSendToHdcStream function
309  *           magic head is not correct
310  * @tc.type: FUNC
311  */
312 HWTEST_F(HdcUARTBaseTest, UartSendToHdcStreamBadMagic, TestSize.Level1)
313 {
314     std::vector<uint8_t> sourceData(testPackageSize.back());
__anon6048c1370502() 315     std::generate(sourceData.begin(), sourceData.end(), [&]() { return rnd() % 100; });
316     for (size_t i = 0; i < testPackageSize.size() and testPackageSize[i] >= sizeof(UartHead); i++) {
317         EXPECT_CALL(mockUARTBase, ResponseUartTrans(_, _, PKG_OPTION_NAK)).Times(1);
318         ASSERT_EQ(
319             mockUARTBase.UartSendToHdcStream(server.get(), sourceData.data(), testPackageSize[i]),
320             false);
321     }
322 
323     for (size_t i = 0; i < testPackageSize.size() and testPackageSize[i] >= sizeof(UartHead); i++) {
324         EXPECT_CALL(mockUARTBase, ResponseUartTrans(_, _, PKG_OPTION_NAK))
325             .Times(testPackageSize[i] > sizeof(UartHead) ? 1 : 0);
326         ASSERT_EQ(
327             mockUARTBase.UartSendToHdcStream(daemon.get(), sourceData.data(), testPackageSize[i]),
328             false);
329     }
330 }
331 
332 /*
333  * @tc.name: UartSendToHdcStream
334  * @tc.desc: Check the behavior of the UartSendToHdcStream function
335  *           head buffer merge multiple times
336  * @tc.type: FUNC
337  */
338 HWTEST_F(HdcUARTBaseTest, UartSendToHdcStreamAppend, TestSize.Level1)
339 {
340     std::vector<uint8_t> data;
341     ASSERT_TRUE(MakeDemoData(data, server->sessionId));
342 
343     // send head one by one
344     for (unsigned int i = 0; i < sizeof(UartHead); i++) {
345         ASSERT_TRUE(mockUARTBase.UartSendToHdcStream(server.get(), &data.data()[i],
346                                                      sizeof(data.data()[i])));
347     }
348 
349     // send content data  one by one
350 #if HDC_HOST
351     EXPECT_CALL(mockUARTBase, UartToHdcProtocol).Times(0);
352 #else
353     EXPECT_CALL(mockInterface, SendToStream).Times(0);
354 #endif
355     for (unsigned int i = sizeof(UartHead); i < data.size(); i++) {
356         ASSERT_TRUE(mockUARTBase.UartSendToHdcStream(server.get(), &data.data()[i],
357                                                      sizeof(data.data()[i])));
358         if (i + 1 == data.size()) {
359             // if this is the last one , buf will clear after send
360         } else {
361         }
362     }
363 }
364 
365 /*
366  * @tc.name: UartSendToHdcStream
367  * @tc.desc: Check the behavior of the UartSendToHdcStream function
368  *           soft reset when session id is not correct
369  * @tc.type: FUNC
370  */
371 HWTEST_F(HdcUARTBaseTest, UartSendToHdcStreamDiffSession, TestSize.Level1)
372 {
373     bool sendResult = false;
374 
375     std::vector<uint8_t> data;
376     ASSERT_TRUE(MakeDemoData(data, server->sessionId));
377 
378     std::vector<uint8_t> dataDiffSession;
379     // here we make a server session
380     uint32_t diffSessionId = server->sessionId + 1;
381     ASSERT_TRUE(MakeDemoData(dataDiffSession, diffSessionId));
382 
383     // same session
384     EXPECT_CALL(mockUARTBase, SendUartSoftReset(server.get(), server->sessionId)).Times(0);
385     EXPECT_CALL(mockUARTBase, UartToHdcProtocol).Times(1);
386 
387     sendResult = mockUARTBase.UartSendToHdcStream(server.get(), data.data(), data.size());
388     ASSERT_TRUE(sendResult);
389     ASSERT_FALSE(server->hUART->resetIO);
390 
391     // diff session but not server serversession
392     // SendUartSoftReset should only happend from server to daemon
393     EXPECT_CALL(mockUARTBase, SendUartSoftReset(daemon.get(), server->sessionId)).Times(0);
394     EXPECT_CALL(mockInterface, SendToStream).Times(0);
395     sendResult = mockUARTBase.UartSendToHdcStream(daemon.get(), data.data(), data.size());
396     ASSERT_TRUE(sendResult);
397     ASSERT_FALSE(server->hUART->resetIO);
398 
399     // diff session should set reset resetIO to true
400     // and also call SendUartSoftReset
401     // here we use daemonSession_ with server_->sessionId (it's different)
402     EXPECT_CALL(mockUARTBase, SendUartSoftReset(server.get(), diffSessionId)).Times(1);
403 
404     sendResult = mockUARTBase.UartSendToHdcStream(server.get(), dataDiffSession.data(),
405                                                   dataDiffSession.size());
406     ASSERT_FALSE(sendResult);
407     ASSERT_TRUE(server->hUART->resetIO);
408 }
409 /*
410  * @tc.name: ReadyForWorkThread
411  * @tc.desc: Check the behavior of the ReadyForWorkThread function
412  * @tc.type: FUNC
413  */
414 HWTEST_F(HdcUARTBaseTest, ReadyForWorkThread, TestSize.Level1)
415 {
416     HdcSession session;
417     HdcSessionBase sessionBase(true);
418     session.classInstance = &sessionBase;
419     auto loop = &session.childLoop;
420     auto tcp = &session.dataPipe[STREAM_WORK];
421     session.dataFd[STREAM_WORK] = rnd();
422     auto socket = session.dataFd[STREAM_WORK];
423     auto alloc = sessionBase.AllocCallback;
424     auto cb = HdcUARTBase::ReadDataFromUARTStream;
425 
426     EXPECT_CALL(mockInterface, UvTcpInit(loop, tcp, socket)).Times(1);
427     EXPECT_CALL(mockInterface, UvRead((uv_stream_t *)tcp, alloc, cb)).Times(1);
428     EXPECT_EQ(mockUARTBase.ReadyForWorkThread(&session), true);
429 
430     EXPECT_CALL(mockInterface, UvTcpInit(loop, tcp, socket)).Times(1).WillOnce(Return(-1));
431     EXPECT_CALL(mockInterface, UvRead).Times(0);
432     EXPECT_EQ(mockUARTBase.ReadyForWorkThread(&session), false);
433 
434     EXPECT_CALL(mockInterface, UvTcpInit(loop, tcp, socket)).Times(1);
435     EXPECT_CALL(mockInterface, UvRead).Times(1).WillOnce(Return(-1));
436     EXPECT_EQ(mockUARTBase.ReadyForWorkThread(&session), false);
437 }
438 
439 /*
440  * @tc.name: ReadDataFromUARTStream
441  * @tc.desc: Check the behavior of the ReadDataFromUARTStream function
442  * @tc.type: FUNC
443  */
444 HWTEST_F(HdcUARTBaseTest, ReadDataFromUARTStream, TestSize.Level1)
445 {
446     uv_stream_t uvStream;
447     HdcSession hdcSession;
448     HdcUART uart;
449     constexpr uint32_t testSessionId = 0x1234;
450     hdcSession.sessionId = testSessionId;
451     uint8_t dummyArray[] = {1, 2, 3, 4};
452     uart.streamSize = sizeof(dummyArray);
453     uint8_t *dummPtr = dummyArray;
454     ssize_t dummySize = sizeof(dummyArray);
455     class MockHdcSessionBase : public HdcSessionBase {
456     public:
457         MOCK_METHOD3(FetchIOBuf, int(HSession, uint8_t *, int));
MockHdcSessionBase(bool server)458         explicit MockHdcSessionBase(bool server) : HdcSessionBase(server) {}
459     } mockSession(true);
460     hdcSession.classInstance = static_cast<void *>(&mockSession);
461     hdcSession.classModule = &mockUARTBase;
462     hdcSession.ioBuf = dummPtr;
463     hdcSession.hUART = &uart;
464 
465     uvStream.data = static_cast<void *>(&hdcSession);
466 
467     EXPECT_CALL(mockSession, FetchIOBuf(&hdcSession, dummPtr, dummySize)).Times(1);
468     HdcUARTBase::ReadDataFromUARTStream(&uvStream, dummySize, nullptr);
469 
470     uart.streamSize = sizeof(dummyArray);
471     EXPECT_CALL(mockSession, FetchIOBuf(&hdcSession, dummPtr, dummySize))
472         .Times(1)
473         .WillOnce(Return(-1));
474     EXPECT_CALL(mockUARTBase, ResponseUartTrans(_, _, PKG_OPTION_FREE)).Times(1);
475     HdcUARTBase::ReadDataFromUARTStream(&uvStream, dummySize, nullptr);
476 }
477 
478 /*
479  * @tc.name: UartToHdcProtocol
480  * @tc.desc: Check the behavior of the UartToHdcProtocol function
481  * @tc.type: FUNC
482  */
483 HWTEST_F(HdcUARTBaseTest, UartToHdcProtocol, TestSize.Level1)
484 {
485     uv_stream_t stream;
486     HdcSession session;
487     const int MaxTestBufSize = MAX_UART_SIZE_IOBUF * 2 + 2;
488     std::vector<uint8_t> data(MaxTestBufSize);
__anon6048c1370602() 489     std::generate(data.begin(), data.end(), [&]() { return rnd() % 100; });
490     EXPECT_CALL(mockUARTBase, UartToHdcProtocol)
__anon6048c1370702(uv_stream_t *stream, uint8_t *data, int dataSize) 491         .WillRepeatedly([&](uv_stream_t *stream, uint8_t *data, int dataSize) {
492             return mockUARTBase.HdcUARTBase::UartToHdcProtocol(stream, data, dataSize);
493         });
494 
495     stream.data = &session;
496 
497     // have socket
498     ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, session.dataFd), 0);
499     EXPECT_EQ(mockUARTBase.UartToHdcProtocol(&stream, data.data(), data.size()),
500               signed(data.size()));
501     std::string recvBuf;
502     recvBuf.resize(data.size());
503     read(session.dataFd[STREAM_WORK], recvBuf.data(), recvBuf.size());
504     EXPECT_EQ(memcpy_s(recvBuf.data(), recvBuf.size(), data.data(), data.size()), 0);
505 
506     // close one of pair
507     EXPECT_EQ(close(session.dataFd[STREAM_MAIN]), 0);
508     EXPECT_EQ(mockUARTBase.UartToHdcProtocol(&stream, data.data(), data.size()), ERR_IO_FAIL);
509 
510     // close two of pair
511     EXPECT_EQ(close(session.dataFd[STREAM_WORK]), 0);
512     EXPECT_EQ(mockUARTBase.UartToHdcProtocol(&stream, data.data(), data.size()), ERR_IO_FAIL);
513 }
514 
515 /*
516  * @tc.name: ValidateUartPacket
517  * @tc.desc: Check the behavior of the ValidateUartPacket function
518  * @tc.type: FUNC
519  */
520 HWTEST_F(HdcUARTBaseTest, ValidateUartPacket, TestSize.Level1)
521 {
522     uint32_t sessionId = 0;
523     uint32_t packageIndex = 0;
524     constexpr uint32_t sessionIdTest = 1234;
525     constexpr uint32_t dataSizeTest = MAX_UART_SIZE_IOBUF / 2;
526     constexpr uint32_t packageIndexTest = 123;
527     size_t pkgLenth = 0;
528     UartHead testHead;
529     testHead.flag[0] = PACKET_FLAG.at(0);
530     testHead.flag[1] = PACKET_FLAG.at(1);
531     uint8_t *bufPtr = reinterpret_cast<uint8_t *>(&testHead);
532     testHead.sessionId = sessionIdTest;
533     testHead.dataSize = dataSizeTest;
534     testHead.packageIndex = packageIndexTest;
535     UartHead *headPointer = nullptr;
536 
537     std::vector<uint8_t> buffer(MAX_UART_SIZE_IOBUF * 3);
538 
539     buffer.assign(bufPtr, bufPtr + sizeof(UartHead));
540     headPointer = (UartHead *)buffer.data();
541     headPointer->UpdateCheckSum();
542     EXPECT_CALL(mockUARTBase, ProcessResponsePackage).Times(AnyNumber());
543     EXPECT_CALL(mockUARTBase, ResponseUartTrans).Times(AnyNumber());
544     EXPECT_EQ(mockUARTBase.ValidateUartPacket(buffer, sessionId, packageIndex, pkgLenth),
545               RET_SUCCESS);
546 
547     testHead.flag[0] = PACKET_FLAG.at(0);
548     buffer.assign(bufPtr, bufPtr + sizeof(UartHead));
549     headPointer = (UartHead *)buffer.data();
550     headPointer->UpdateCheckSum();
551     EXPECT_EQ(mockUARTBase.ValidateUartPacket(buffer, sessionId, packageIndex, pkgLenth),
552               RET_SUCCESS);
553 
554     testHead.flag[1] = PACKET_FLAG.at(1);
555     buffer.assign(bufPtr, bufPtr + sizeof(UartHead));
556     headPointer = (UartHead *)buffer.data();
557     headPointer->UpdateCheckSum();
558     EXPECT_EQ(mockUARTBase.ValidateUartPacket(buffer, sessionId, packageIndex, pkgLenth),
559               RET_SUCCESS);
560     EXPECT_EQ(sessionId, testHead.sessionId);
561     EXPECT_EQ(pkgLenth, testHead.dataSize + sizeof(UartHead));
562 
563     testHead.dataSize = MAX_UART_SIZE_IOBUF * 2;
564     buffer.assign(bufPtr, bufPtr + sizeof(UartHead));
565     buffer.resize(testHead.dataSize + sizeof(UartHead));
566     headPointer = (UartHead *)buffer.data();
567     headPointer->UpdateCheckSum();
568     EXPECT_EQ(mockUARTBase.ValidateUartPacket(buffer, sessionId, packageIndex, pkgLenth),
569               ERR_BUF_OVERFLOW);
570 
571     testHead.dataSize = MAX_UART_SIZE_IOBUF * 1;
572     buffer.assign(bufPtr, bufPtr + sizeof(UartHead));
573     buffer.resize(testHead.dataSize + sizeof(UartHead));
574     headPointer = (UartHead *)buffer.data();
575     headPointer->UpdateCheckSum();
576     EXPECT_EQ(mockUARTBase.ValidateUartPacket(buffer, sessionId, packageIndex, pkgLenth),
577               ERR_BUF_OVERFLOW);
578 
579     testHead.dataSize = MAX_UART_SIZE_IOBUF / 2;
580     buffer.assign(bufPtr, bufPtr + sizeof(UartHead));
581     buffer.resize(testHead.dataSize + sizeof(UartHead));
582     headPointer = (UartHead *)buffer.data();
583     headPointer->UpdateCheckSum();
584     EXPECT_EQ(mockUARTBase.ValidateUartPacket(buffer, sessionId, packageIndex, pkgLenth),
585               RET_SUCCESS);
586     EXPECT_EQ(sessionId, testHead.sessionId);
587     EXPECT_EQ(pkgLenth, testHead.dataSize + sizeof(UartHead));
588 
589     testHead.option = PKG_OPTION_RESET;
590     testHead.dataSize = MAX_UART_SIZE_IOBUF - sizeof(UartHead);
591     buffer.assign(bufPtr, bufPtr + sizeof(UartHead));
592     buffer.resize(testHead.dataSize + sizeof(UartHead));
593     headPointer = (UartHead *)buffer.data();
594     headPointer->UpdateCheckSum();
595 
596     EXPECT_CALL(mockUARTBase, ResetOldSession(sessionIdTest)).Times(1);
597     EXPECT_EQ(mockUARTBase.ValidateUartPacket(buffer, sessionId, packageIndex, pkgLenth),
598               ERR_IO_SOFT_RESET);
599 
600     testHead.option = PKG_OPTION_ACK;
601     testHead.dataSize = MAX_UART_SIZE_IOBUF - sizeof(UartHead);
602     buffer.assign(bufPtr, bufPtr + sizeof(UartHead));
603     buffer.resize(testHead.dataSize + sizeof(UartHead));
604     headPointer = (UartHead *)buffer.data();
605     headPointer->UpdateCheckSum();
606     EXPECT_CALL(mockUARTBase, ProcessResponsePackage).Times(1);
607     EXPECT_EQ(mockUARTBase.ValidateUartPacket(buffer, sessionId, packageIndex, pkgLenth),
608               RET_SUCCESS);
609 }
610 
611 /*
612  * @tc.name: ExternInterface
613  * @tc.desc: Too many free functions, forcing increased coverage , just check not crash or not
614  * successed
615  * @tc.type: FUNC
616  */
617 HWTEST_F(HdcUARTBaseTest, ExternInterface, TestSize.Level1)
618 {
619     ExternInterface defaultInterface;
620     uv_loop_t dummyLoop;
621     uv_tcp_t server;
622     uv_pipe_t dummyPip;
623     uv_loop_init(&dummyLoop);
624     uv_pipe_init(uv_default_loop(), &dummyPip, 0);
625 
626     defaultInterface.SetTcpOptions(nullptr);
627     EXPECT_NE(defaultInterface.SendToStream(nullptr, nullptr, 0), 0);
628     EXPECT_NE(defaultInterface.UvTcpInit(uv_default_loop(), &server, -1), 0);
629     EXPECT_NE(defaultInterface.UvRead((uv_stream_t *)&dummyPip, nullptr, nullptr), 0);
630     EXPECT_EQ(defaultInterface.StartWorkThread(nullptr, nullptr, nullptr, nullptr), 0);
631     EXPECT_NE(defaultInterface.TimerUvTask(uv_default_loop(), nullptr, nullptr), 0);
632     EXPECT_NE(defaultInterface.UvTimerStart(nullptr, nullptr, 0, 0), 0);
633     EXPECT_NE(defaultInterface.DelayDo(uv_default_loop(), 0, 0, "", nullptr, nullptr), 0);
634     defaultInterface.TryCloseHandle((uv_handle_t *)&dummyPip, nullptr);
635 }
636 
637 /*
638  * @tc.name: GetUartSpeed
639  * @tc.desc: Check the behavior of the GetUartSpeed function
640  * successed
641  * @tc.type: FUNC
642  */
643 HWTEST_F(HdcUARTBaseTest, GetUartSpeed, TestSize.Level1)
644 {
645     EXPECT_EQ(mockUARTBase.GetUartSpeed(UART_SPEED2400), B2400);
646     EXPECT_EQ(mockUARTBase.GetUartSpeed(UART_SPEED4800), B4800);
647     EXPECT_EQ(mockUARTBase.GetUartSpeed(UART_SPEED9600), B9600);
648     EXPECT_EQ(mockUARTBase.GetUartSpeed(UART_SPEED115200), B115200);
649     EXPECT_EQ(mockUARTBase.GetUartSpeed(UART_SPEED921600), B921600);
650     EXPECT_EQ(mockUARTBase.GetUartSpeed(-1), B921600);
651 }
652 
653 /*
654  * @tc.name: GetUartBits
655  * @tc.desc: Check the behavior of the GetUartSpeed function
656  * successed
657  * @tc.type: FUNC
658  */
659 HWTEST_F(HdcUARTBaseTest, GetUartBits, TestSize.Level1)
660 {
661     EXPECT_EQ(mockUARTBase.GetUartBits(UART_BIT1), CS7);
662     EXPECT_EQ(mockUARTBase.GetUartBits(UART_BIT2), CS8);
663     EXPECT_EQ(mockUARTBase.GetUartBits(-1), CS8);
664 }
665 
666 /*
667  * @tc.name: ToPkgIdentityString
668  * @tc.desc: Check the behavior of the ToPkgIdentityString function
669  * successed
670  * @tc.type: FUNC
671  */
672 HWTEST_F(HdcUARTBaseTest, ToPkgIdentityString, TestSize.Level1)
673 {
674     const uint32_t sessionId = 12345;
675     const uint32_t packageIndex = 54321;
676 
677     UartHead head;
678     head.sessionId = sessionId;
679     head.packageIndex = packageIndex;
680     EXPECT_STREQ(head.ToPkgIdentityString().c_str(), "Id:12345pkgIdx:54321");
681     EXPECT_STREQ(head.ToPkgIdentityString(true).c_str(), "R-Id:12345pkgIdx:54321");
682 }
683 
684 /*
685  * @tc.name: HandleOutputPkg
686  * @tc.desc: Check the behavior of the HandleOutputPkg  function
687  * successed
688  * @tc.type: FUNC
689  */
690 HWTEST_F(HdcUARTBaseTest, HandleOutputPkg, TestSize.Level1)
691 {
692     const uint32_t sessionId = 12345;
693     HdcUARTBase::HandleOutputPkg testPackage("key", sessionId, nullptr, 0);
694     testPackage.sendTimePoint = std::chrono::steady_clock::now();
695     std::string debugString = testPackage.ToDebugString();
696     EXPECT_THAT(debugString, HasSubstr("pkgStatus"));
697     EXPECT_THAT(debugString, Not(HasSubstr("sent")));
698 
699     testPackage.pkgStatus = HdcUARTBase::PKG_WAIT_RESPONSE;
700     debugString = testPackage.ToDebugString();
701     EXPECT_THAT(debugString, HasSubstr("pkgStatus"));
702     EXPECT_THAT(debugString, HasSubstr("sent"));
703 
704     testPackage.response = true;
705     debugString = testPackage.ToDebugString();
706     EXPECT_THAT(debugString, HasSubstr("pkgStatus"));
707     EXPECT_THAT(debugString, HasSubstr("NAK"));
708 
709     testPackage.response = true;
710     testPackage.ack = true;
711     debugString = testPackage.ToDebugString();
712     EXPECT_THAT(debugString, HasSubstr("pkgStatus"));
713     EXPECT_THAT(debugString, HasSubstr("ACK"));
714 }
715 
716 /*
717  * @tc.name: TransferStateMachine
718  * @tc.desc: Check the behavior of the TransferStateMachine function
719  * successed
720  * @tc.type: FUNC
721  */
722 HWTEST_F(HdcUARTBaseTest, TransferStateMachine, TestSize.Level1)
723 {
724     HdcUARTBase::TransferStateMachine tsm;
725     // case 1 timeout
726     tsm.Request();
727     EXPECT_EQ(tsm.requested, true);
728     EXPECT_EQ(tsm.timeout, false);
729     tsm.Sent();
730     EXPECT_EQ(tsm.requested, true);
731     EXPECT_EQ(tsm.timeout, true);
732     tsm.Wait(); // not timeout
733     EXPECT_EQ(tsm.requested, false);
734     EXPECT_EQ(tsm.timeout, true);
735     tsm.Wait(); // wait again until timeout
736     EXPECT_EQ(tsm.timeout, false);
737 
738     // case 2 not timeout
739     tsm.Request();
740     EXPECT_EQ(tsm.requested, true);
741     EXPECT_EQ(tsm.timeout, false);
742     tsm.Wait();
743     EXPECT_EQ(tsm.requested, false);
744     EXPECT_EQ(tsm.timeout, false);
745 }
746 
747 /*
748  * @tc.name: TransferSlot
749  * @tc.desc: Check the behavior of the TransferSlot   function
750  * successed
751  * @tc.type: FUNC
752  */
753 HWTEST_F(HdcUARTBaseTest, TransferSlot, TestSize.Level1)
754 {
755     const uint32_t sessionId = 12345;
756     HdcUARTBase::TransferSlot slot;
757     slot.Free(sessionId);
758     EXPECT_THAT(slot.hasWaitPkg, Not(Contains(sessionId)));
759     slot.Wait(sessionId);
760     EXPECT_THAT(slot.hasWaitPkg, Contains(sessionId));
761     slot.WaitFree();
762     EXPECT_THAT(slot.hasWaitPkg, Contains(sessionId));
763 }
764 
765 /*
766  * @tc.name: HandleOutputPkgKeyFinder
767  * @tc.desc: Check the behavior of the HandleOutputPkgKeyFinder function
768  * successed
769  * @tc.type: FUNC
770  */
771 HWTEST_F(HdcUARTBaseTest, HandleOutputPkgKeyFinder, TestSize.Level1)
772 {
773     vector<HdcUARTBase::HandleOutputPkg> outPkgs; // Pkg label, HOutPkg
774     outPkgs.emplace_back("A", 0, nullptr, 0);
775     outPkgs.emplace_back("B", 0, nullptr, 0);
776     EXPECT_NE(
777         std::find_if(outPkgs.begin(), outPkgs.end(), HdcUARTBase::HandleOutputPkgKeyFinder("A")),
778         outPkgs.end());
779     EXPECT_NE(
780         std::find_if(outPkgs.begin(), outPkgs.end(), HdcUARTBase::HandleOutputPkgKeyFinder("B")),
781         outPkgs.end());
782     EXPECT_EQ(
783         std::find_if(outPkgs.begin(), outPkgs.end(), HdcUARTBase::HandleOutputPkgKeyFinder("C")),
784         outPkgs.end());
785 }
786 
787 /*
788  * @tc.name: Restartession
789  * @tc.desc: Check the behavior of the Restartession function
790  * successed
791  * @tc.type: FUNC
792  */
793 HWTEST_F(HdcUARTBaseTest, StopSession, TestSize.Level1)
794 {
795     const uint32_t sessionId = 12345;
796     HdcSession session;
797     session.sessionId = sessionId;
798     EXPECT_CALL(mockUARTBase, ClearUARTOutMap(sessionId)).WillOnce(Return());
799     EXPECT_CALL(mockSessionBase, FreeSession(sessionId)).WillOnce(Return());
800     mockUARTBase.Restartession(&session);
801 
802     EXPECT_CALL(mockUARTBase, ClearUARTOutMap).Times(0);
803     EXPECT_CALL(mockSessionBase, FreeSession).Times(0);
804     mockUARTBase.Restartession(nullptr);
805 }
806 
807 /*
808  * @tc.name: StopSession
809  * @tc.desc: Check the behavior of the Restartession function
810  * successed
811  * @tc.type: FUNC
812  */
813 HWTEST_F(HdcUARTBaseTest, Restartession, TestSize.Level1)
814 {
815     const uint32_t sessionId = 12345;
816     HdcSession session;
817     session.sessionId = sessionId;
818     EXPECT_CALL(mockUARTBase, ClearUARTOutMap(sessionId)).WillOnce(Return());
819     EXPECT_CALL(mockSessionBase, FreeSession).Times(0);
820     mockUARTBase.StopSession(&session);
821 }
822 
823 /*
824  * @tc.name: ResponseUartTrans
825  * @tc.desc: Check the behavior of the ResponseUartTrans function
826  * successed
827  * @tc.type: FUNC
828  */
829 HWTEST_F(HdcUARTBaseTest, ResponseUartTrans, TestSize.Level1)
830 {
831     EXPECT_CALL(mockUARTBase, ResponseUartTrans)
__anon6048c1370802(uint32_t sessionId, uint32_t packageIndex, UartProtocolOption option) 832         .WillRepeatedly([&](uint32_t sessionId, uint32_t packageIndex, UartProtocolOption option) {
833             return mockUARTBase.HdcUARTBase::ResponseUartTrans(sessionId, packageIndex, option);
834         });
835     const uint32_t sessionId = 12345;
836     const uint32_t packageIndex = 54321;
837     EXPECT_CALL(mockUARTBase, RequestSendPackage(_, sizeof(UartHead), false));
838     mockUARTBase.ResponseUartTrans(sessionId, packageIndex, PKG_OPTION_FREE);
839 }
840 } // namespace Hdc
841