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
20using namespace testing::ext;
21using ::testing::_;
22using ::testing::AnyNumber;
23using ::testing::Return;
24using namespace testing;
25
26namespace Hdc {
27class HdcUARTBaseTest : public testing::Test {
28public:
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 SERVER_ID = 1235;
40    static constexpr uint32_t DAEMON_SESSION_ID = 1236;
41    static constexpr uint32_t PACKAGE_INDEX = 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 {
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
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
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
103void 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
112void HdcUARTBaseTest::TearDownTestCase() {}
113
114void HdcUARTBaseTest::SetUp()
115{
116    serverHdcUart = std::make_unique<HdcUART>();
117    server = std::make_unique<HdcSession>();
118    server->serverOrDaemon = true;
119    server->sessionId = SERVER_ID;
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 = DAEMON_SESSION_ID;
126    daemon->hUART = daemonHdcUart.get();
127
128    mockInterface.expectUserData.clear();
129}
130
131void HdcUARTBaseTest::TearDown() {}
132
133bool 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 = PACKAGE_INDEX;
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
149bool 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
162bool 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 */
184HWTEST_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 */
199HWTEST_F(HdcUARTBaseTest, ResetOldSession, TestSize.Level1)
200{
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 */
214HWTEST_F(HdcUARTBaseTest, SendUartSoftReset, TestSize.Level1)
215{
216    EXPECT_CALL(mockUARTBase, SendUartSoftReset)
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 */
231HWTEST_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)
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 */
291HWTEST_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 */
312HWTEST_F(HdcUARTBaseTest, UartSendToHdcStreamBadMagic, TestSize.Level1)
313{
314    std::vector<uint8_t> sourceData(testPackageSize.back());
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 */
338HWTEST_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 */
371HWTEST_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 */
414HWTEST_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 */
444HWTEST_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));
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 */
483HWTEST_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);
489    std::generate(data.begin(), data.end(), [&]() { return rnd() % 100; });
490    EXPECT_CALL(mockUARTBase, UartToHdcProtocol)
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 */
520HWTEST_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 */
617HWTEST_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 */
643HWTEST_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 */
659HWTEST_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 */
672HWTEST_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 */
690HWTEST_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 */
722HWTEST_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 */
753HWTEST_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 */
771HWTEST_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 */
793HWTEST_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 */
813HWTEST_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 */
829HWTEST_F(HdcUARTBaseTest, ResponseUartTrans, TestSize.Level1)
830{
831    EXPECT_CALL(mockUARTBase, ResponseUartTrans)
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