• 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 "host_uart_test.h"
17 
18 #include <chrono>
19 #include <random>
20 #include <thread>
21 
22 #include "server.h"
23 
24 using namespace std::chrono;
25 using namespace std::chrono_literals;
26 using namespace testing::ext;
27 using namespace testing;
28 
29 namespace Hdc {
30 class HdcHostUARTTest : public testing::Test {
31 public:
32     static void SetUpTestCase(void);
33     static void TearDownTestCase(void);
34     void SetUp();
35     void TearDown();
36 
37     constexpr static int PAIR = 2;
38     constexpr static int SENDER = 0;
39     constexpr static int RECEIVER = 1;
40 
41     std::default_random_engine rnd;
42     const std::string nullDevPath = "/dev/null";
43     class MockHdcServer : public HdcServer {
MockHdcServer()44         MockHdcServer() : HdcServer(true) {};
45         MOCK_METHOD3(AdminDaemonMap, string(uint8_t, const string &, HDaemonInfo &));
46         MOCK_METHOD1(EnumUARTDeviceRegister, void(UartKickoutZombie));
47         MOCK_METHOD4(MallocSession, HSession(bool, const ConnType, void *, uint32_t));
48         MOCK_METHOD1(FreeSession, void(const uint32_t));
49         MOCK_METHOD3(AdminSession, HSession(const uint8_t, const uint32_t, HSession));
50         MOCK_METHOD2(EchoToClientsForSession, void(uint32_t, const string &));
51     } mockServer;
52 
53     class MockBaseInterface : public ExternInterface {
54     public:
55         MOCK_METHOD4(StartWorkThread, int(uv_loop_t *, uv_work_cb, uv_after_work_cb, void *));
56         MOCK_METHOD2(TryCloseHandle, void(const uv_handle_t *, uv_close_cb));
57         MOCK_METHOD3(TimerUvTask, bool(uv_loop_t *, void *, uv_timer_cb));
58         MOCK_METHOD3(SendToStream, int(uv_stream_t *, const uint8_t *, const int));
59         MOCK_METHOD6(DelayDo, bool(uv_loop_t *, const int, const uint8_t, string, void *, DelayCB));
60         MOCK_METHOD4(UvTimerStart, bool(uv_timer_t *, uv_timer_cb, uint64_t, uint64_t));
61     } mockInterface;
62 
63     class MockHdcHostUART : public HdcHostUART {
64     public:
MockHdcHostUART(HdcServer & daemonIn,ExternInterface & externInterface=HdcUARTBase::defaultInterface)65         explicit MockHdcHostUART(HdcServer &daemonIn,
66                         ExternInterface &externInterface = HdcUARTBase::defaultInterface)
67             : HdcHostUART(daemonIn, externInterface)
68         {
69         }
70         MOCK_METHOD0(StartupUARTWork, RetErrCode());
71         MOCK_METHOD0(UartWriteThread, void());
72         MOCK_METHOD1(CloseSerialPort, void(const HUART));
73         MOCK_METHOD1(EnumSerialPort, bool(bool &));
74         MOCK_METHOD0(Stop, void());
75         MOCK_METHOD3(UpdateUARTDaemonInfo, void(const std::string &, HSession, ConnStatus));
76         MOCK_METHOD1(StartUartReadThread, bool(HSession));
77         MOCK_METHOD0(StartUartSendThread, bool());
78         MOCK_METHOD0(WatchUartDevPlugin, void());
79         MOCK_METHOD1(OpenSerialPort, int(const std::string &));
80         MOCK_METHOD1(UartReadThread, void(HSession));
81         MOCK_METHOD3(SendUARTRaw, bool(HSession, uint8_t *, const size_t));
82         MOCK_METHOD3(RequestSendPackage, void(uint8_t *, const size_t, bool));
83         MOCK_METHOD1(UartSendThread, void(HSession));
84         MOCK_METHOD0(SendPkgInUARTOutMap, void());
85         MOCK_METHOD1(IsDeviceOpened, bool(const HdcUART &));
86         MOCK_METHOD3(ReadUartDev, ssize_t(std::vector<uint8_t> &, size_t, HdcUART &));
87         MOCK_METHOD1(NeedStop, bool(const HSession));
88         MOCK_METHOD2(PackageProcess, size_t(vector<uint8_t> &, HSession hSession));
89         MOCK_METHOD1(OnTransferError, void(const HSession));
90         MOCK_METHOD1(ClearUARTOutMap, void(uint32_t));
91     } mockHostUART;
92 
93     HdcSession mySession;
94     HdcUART myUART;
95     const int testSerialHandle = 0x1234;
96     const std::string testSerialPortName = "COMX";
97 
HdcHostUARTTest()98     HdcHostUARTTest() : mockHostUART(mockServer, mockInterface)
99     {
100         myUART.serialPort = testSerialPortName;
101         myUART.devUartHandle = testSerialHandle;
102         mySession.hUART = &myUART;
103         mySession.classModule = &mockHostUART;
104         mySession.classInstance = &mockServer;
105     };
106 };
107 
SetUpTestCase()108 void HdcHostUARTTest::SetUpTestCase()
109 {
110 #ifdef UT_DEBUG
111     Hdc::Base::SetLogLevel(LOG_ALL);
112 #else
113     Hdc::Base::SetLogLevel(LOG_OFF);
114 #endif
115 }
116 
TearDownTestCase()117 void HdcHostUARTTest::TearDownTestCase() {}
118 
SetUp()119 void HdcHostUARTTest::SetUp()
120 {
121     // The destructor will call these
122     EXPECT_CALL(mockHostUART, Stop).Times(AnyNumber());
123     EXPECT_CALL(mockInterface, TryCloseHandle).Times(AnyNumber());
124 }
125 
TearDown()126 void HdcHostUARTTest::TearDown()
127 {
128     // session will close mockDaemon.loopMain ,so we dont need close it in UT
129 
130     // ~HdcHostUART will call close
131 }
132 
133 /*
134  * @tc.name: HdcHostUART
135  * @tc.desc: Check the behavior of the HdcHostUART function
136  * @tc.type: FUNC
137  */
138 HWTEST_F(HdcHostUARTTest, HdcHostUART, TestSize.Level1)
139 {
140     HdcHostUART hostUart(mockServer);
141     EXPECT_EQ(hostUart.uartOpened, false);
142     EXPECT_EQ(hostUart.baudRate, 0u);
143     EXPECT_EQ(hostUart.mapIgnoreDevice.empty(), true);
144     EXPECT_EQ(hostUart.serialPortInfo.empty(), true);
145 
146     hostUart.devUartWatcher.data = this;
147     uv_timer_start(
148         &hostUart.devUartWatcher,
__anon5322a9160102(uv_timer_s *timer) 149         [](uv_timer_s *timer) {
150             EXPECT_NE(timer->data, nullptr);
151             timer->data = nullptr;
152         },
153         100, 0);
154 
155     std::this_thread::sleep_for(200ms);
156     uv_run(&mockServer.loopMain, UV_RUN_NOWAIT);
157 
158     EXPECT_EQ(hostUart.devUartWatcher.data, nullptr);
159     EXPECT_EQ(hostUart.semUartDevCheck.try_lock(), true);
160 
161     EXPECT_NE(uv_has_ref(reinterpret_cast<uv_handle_t *>(&hostUart.devUartWatcher)), 0);
162 }
163 
164 /*
165  * @tc.name: Initial
166  * @tc.desc: Check the behavior of the Initial function
167  * @tc.type: FUNC
168  */
169 HWTEST_F(HdcHostUARTTest, Initial, TestSize.Level1)
170 {
171     EXPECT_CALL(mockHostUART, StartupUARTWork).Times(1);
172     EXPECT_EQ(mockHostUART.Initial(), 0);
173     EXPECT_EQ(mockHostUART.uartOpened, false);
174     EXPECT_EQ(mockHostUART.stopped, false);
175 }
176 
177 /*
178  * @tc.name: Stop
179  * @tc.desc: Check the behavior of the Stop function
180  * @tc.type: FUNC
181  */
182 HWTEST_F(HdcHostUARTTest, Stop, TestSize.Level1)
183 {
__anon5322a9160202() 184     ON_CALL(mockHostUART, Stop).WillByDefault(Invoke([&]() {
185         return mockHostUART.HdcHostUART::Stop();
186     }));
187     EXPECT_CALL(mockHostUART, Stop).Times(1);
188     EXPECT_CALL(
189         mockInterface,
190         TryCloseHandle(reinterpret_cast<uv_handle_t *>(&mockHostUART.devUartWatcher), nullptr))
191         .Times(1);
192     mockHostUART.Stop();
193 
194     // unable stop twice
195     EXPECT_CALL(mockHostUART, Stop).Times(1);
196     EXPECT_CALL(mockInterface, TryCloseHandle).Times(0);
197     mockHostUART.Stop();
198 }
199 
200 /*
201  * @tc.name: ConnectDaemonByUart
202  * @tc.desc: Check the behavior of the ConnectDaemonByUart function
203  * @tc.type: FUNC
204  */
205 HWTEST_F(HdcHostUARTTest, ConnectDaemonByUart, TestSize.Level1)
206 {
207     mockHostUART.uartOpened = true;
208 
209     EXPECT_CALL(mockHostUART, UpdateUARTDaemonInfo(mySession.connectKey, &mySession, STATUS_READY))
210         .Times(1);
211     EXPECT_CALL(mockHostUART, StartUartReadThread(&mySession)).Times(1).WillOnce(Return(true));
212     EXPECT_CALL(mockInterface, StartWorkThread(&mockServer.loopMain, mockServer.SessionWorkThread,
213                                                Base::FinishWorkThread, &mySession))
214         .Times(1);
215     EXPECT_CALL(
216         mockInterface,
217         SendToStream(reinterpret_cast<uv_stream_t *>(&mySession.ctrlPipe[STREAM_MAIN]), _, _))
218         .Times(1);
219     mySession.childLoop.active_handles = 1;
220     EXPECT_EQ(mockHostUART.ConnectDaemonByUart(&mySession), &mySession);
221 
222     // delay case
223     EXPECT_CALL(mockHostUART, UpdateUARTDaemonInfo(mySession.connectKey, &mySession, STATUS_READY))
224         .Times(1);
225     EXPECT_CALL(mockHostUART, StartUartReadThread(&mySession)).Times(1).WillOnce(Return(true));
226     EXPECT_CALL(mockInterface, StartWorkThread(&mockServer.loopMain, mockServer.SessionWorkThread,
227                                                Base::FinishWorkThread, &mySession))
228         .Times(1);
229     EXPECT_CALL(
230         mockInterface,
231         SendToStream(reinterpret_cast<uv_stream_t *>(&mySession.ctrlPipe[STREAM_MAIN]), _, _))
232         .Times(1);
233 
234     mySession.childLoop.active_handles = 0;
__anon5322a9160302() 235     std::thread mockActiveHandles([&]() {
236         std::this_thread::sleep_for(1000ms);
237         mySession.childLoop.active_handles = 1;
238     });
239     EXPECT_EQ(mockHostUART.ConnectDaemonByUart(&mySession), &mySession);
240     mockActiveHandles.join();
241 }
242 
243 /*
244  * @tc.name: ConnectDaemonByUart
245  * @tc.desc: Check the behavior of the ConnectDaemonByUart function
246  * @tc.type: FUNC
247  */
248 HWTEST_F(HdcHostUARTTest, ConnectDaemonByUartFail, TestSize.Level1)
249 {
250     mockHostUART.uartOpened = false;
251     EXPECT_EQ(mockHostUART.ConnectDaemonByUart(&mySession), nullptr);
252 
253     mockHostUART.uartOpened = true;
254     EXPECT_CALL(mockHostUART, UpdateUARTDaemonInfo(mySession.connectKey, &mySession, STATUS_READY))
255         .Times(1);
256     EXPECT_CALL(mockHostUART, StartUartReadThread).Times(1).WillOnce(Return(false));
257     EXPECT_EQ(mockHostUART.ConnectDaemonByUart(&mySession), nullptr);
258 }
259 
260 /*
261  * @tc.name: UvWatchUartDevPlugin
262  * @tc.desc: Check the behavior of the UvWatchUartDevPlugin function
263  * @tc.type: FUNC
264  */
265 HWTEST_F(HdcHostUARTTest, UvWatchUartDevPlugin, TestSize.Level1)
266 {
267     EXPECT_CALL(mockHostUART, WatchUartDevPlugin).Times(0);
268     HdcHostUART::UvWatchUartDevPlugin(nullptr);
269 
270     EXPECT_CALL(mockHostUART, WatchUartDevPlugin()).Times(1);
271     uv_timer_t handle;
272     handle.data = &mockHostUART;
273     HdcHostUART::UvWatchUartDevPlugin(&handle);
274 
275     handle.data = nullptr;
276     HdcHostUART::UvWatchUartDevPlugin(&handle);
277 }
278 
279 /*
280  * @tc.name: WatchUartDevPlugin
281  * @tc.desc: Check the behavior of the WatchUartDevPlugin function
282  * @tc.type: FUNC
283  */
284 HWTEST_F(HdcHostUARTTest, WatchUartDevPluginHaveSerialDaemon, TestSize.Level1)
285 {
__anon5322a9160402() 286     EXPECT_CALL(mockHostUART, WatchUartDevPlugin).WillRepeatedly([&]() {
287         mockHostUART.HdcHostUART::WatchUartDevPlugin();
288     });
289     // case 1 EnumSerialPort failed
290     EXPECT_CALL(mockHostUART, EnumSerialPort).WillOnce(Return(false));
291     EXPECT_CALL(mockServer, AdminDaemonMap).Times(0);
292     EXPECT_CALL(mockHostUART, UpdateUARTDaemonInfo).Times(0);
293     mockHostUART.WatchUartDevPlugin();
294 
295     // case 2 EnumSerialPort not fail but no port change
296     EXPECT_CALL(mockHostUART, EnumSerialPort)
297         .WillOnce(DoAll(SetArgReferee<0>(false), Return(true)));
298     EXPECT_CALL(mockServer, AdminDaemonMap).Times(0);
299     EXPECT_CALL(mockHostUART, UpdateUARTDaemonInfo).Times(0);
300     mockHostUART.WatchUartDevPlugin();
301 }
302 
303 /*
304  * @tc.name: WatchUartDevPlugin
305  * @tc.desc: Check the behavior of the WatchUartDevPlugin function
306  * @tc.type: FUNC
307  */
308 HWTEST_F(HdcHostUARTTest, WatchUartDevPluginHaveSomePort, TestSize.Level1)
309 {
__anon5322a9160502() 310     EXPECT_CALL(mockHostUART, WatchUartDevPlugin).WillRepeatedly([&]() {
311         mockHostUART.HdcHostUART::WatchUartDevPlugin();
312     });
313 
314     // case 3 EnumSerialPort return two port, not port removed
315     // one port is not connected , the other is connected
316     EXPECT_CALL(mockHostUART, EnumSerialPort).WillOnce(DoAll(SetArgReferee<0>(true), Return(true)));
317     mockHostUART.serialPortInfo.clear();
318     mockHostUART.serialPortInfo.emplace_back("COMX");
319     mockHostUART.serialPortInfo.emplace_back("COMY");
320     mockHostUART.connectedPorts.clear();
321     mockHostUART.connectedPorts.emplace("COMY");
322     EXPECT_CALL(mockServer, AdminDaemonMap(OP_QUERY, "COMX", _))
323         .WillOnce(DoAll(SetArgReferee<2>(nullptr), Return("")));
324     EXPECT_CALL(mockHostUART, UpdateUARTDaemonInfo("COMX", nullptr, STATUS_READY)).Times(1);
325     EXPECT_CALL(mockServer, AdminDaemonMap(OP_QUERY, "COMY", _))
326         .WillOnce(DoAll(SetArgReferee<2>(nullptr), Return("")));
327     EXPECT_CALL(mockHostUART, UpdateUARTDaemonInfo("COMY", nullptr, STATUS_READY)).Times(0);
328     mockHostUART.WatchUartDevPlugin();
329 }
330 
331 /*
332  * @tc.name: WatchUartDevPlugin
333  * @tc.desc: Check the behavior of the WatchUartDevPlugin function
334  * @tc.type: FUNC
335  */
336 HWTEST_F(HdcHostUARTTest, WatchUartDevPluginHaveRemovedPort, TestSize.Level1)
337 {
__anon5322a9160602() 338     EXPECT_CALL(mockHostUART, WatchUartDevPlugin).WillRepeatedly([&]() {
339         mockHostUART.HdcHostUART::WatchUartDevPlugin();
340     });
341 
342     // case 4 EnumSerialPort return two port, and one port removed
343     // one port is not connected , the other is connected
344     EXPECT_CALL(mockHostUART, EnumSerialPort).WillOnce(DoAll(SetArgReferee<0>(true), Return(true)));
345     mockHostUART.serialPortInfo.clear();
346     mockHostUART.serialPortInfo.emplace_back("COMX");
347     mockHostUART.serialPortInfo.emplace_back("COMY");
348     mockHostUART.connectedPorts.clear();
349     mockHostUART.connectedPorts.emplace("COMY");
350     mockHostUART.serialPortRemoved.clear();
351     mockHostUART.serialPortRemoved.emplace_back("COMZ");
352 
353     HdcDaemonInformation di;
354     EXPECT_CALL(mockServer, AdminDaemonMap(OP_QUERY, "COMX", _))
355         .WillOnce(DoAll(SetArgReferee<2>(nullptr), Return("")));
356     EXPECT_CALL(mockHostUART, UpdateUARTDaemonInfo("COMX", nullptr, STATUS_READY)).Times(1);
357     EXPECT_CALL(mockServer, AdminDaemonMap(OP_QUERY, "COMY", _))
358         .WillOnce(DoAll(SetArgReferee<2>(nullptr), Return("")));
359     EXPECT_CALL(mockHostUART, UpdateUARTDaemonInfo("COMY", nullptr, STATUS_READY)).Times(0);
360     EXPECT_CALL(mockServer, AdminDaemonMap(OP_QUERY, "COMZ", _))
361         .WillOnce(DoAll(SetArgReferee<2>(&di), Return("")));
362     EXPECT_CALL(mockHostUART, UpdateUARTDaemonInfo("COMZ", nullptr, STATUS_READY)).Times(0);
363     mockHostUART.WatchUartDevPlugin();
364 }
365 
366 /*
367  * @tc.name: UpdateUARTDaemonInfo
368  * @tc.desc: Check the behavior of the UpdateUARTDaemonInfo function
369  * @tc.type: FUNC
370  */
371 HWTEST_F(HdcHostUARTTest, UpdateUARTDaemonInfo, TestSize.Level1)
372 {
373     EXPECT_CALL(mockHostUART, UpdateUARTDaemonInfo)
374         .WillRepeatedly(
__anon5322a9160702(const std::string &connectKey, HSession hSession, ConnStatus connStatus) 375             [&](const std::string &connectKey, HSession hSession, ConnStatus connStatus) {
376                 mockHostUART.HdcHostUART::UpdateUARTDaemonInfo(connectKey, hSession, connStatus);
377             });
378 
379     // case 1 STATUS_UNKNOW
380     HdcDaemonInformation diNew;
381     EXPECT_CALL(mockServer,
382                 AdminDaemonMap(OP_REMOVE, testSerialPortName,
383                                Field(&HdcDaemonInformation::connectKey, testSerialPortName)))
384         .Times(1)
385         .WillOnce(DoAll(SetArgReferee<2>(nullptr), Return("")));
386 
387     mockHostUART.UpdateUARTDaemonInfo(myUART.serialPort, &mySession, STATUS_UNKNOW);
388 
389     // case 2 STATUS_CONNECTED
390     HdcDaemonInformation diDummy;
391     EXPECT_CALL(mockServer, AdminDaemonMap(OP_QUERY, testSerialPortName, _))
392         .Times(1)
393         .WillOnce(DoAll(SetArgReferee<2>(&diDummy), Return("")));
394 
395     EXPECT_CALL(mockServer,
396                 AdminDaemonMap(OP_UPDATE, testSerialPortName,
397                                Field(&HdcDaemonInformation::connectKey, testSerialPortName)))
398         .Times(1)
399         .WillOnce(DoAll(SetArgReferee<2>(nullptr), Return("")));
400 
401     mockHostUART.UpdateUARTDaemonInfo(myUART.serialPort, &mySession, STATUS_CONNECTED);
402 }
403 
404 /*
405  * @tc.name: StartUartReadThread
406  * @tc.desc: Check the behavior of the StartUartReadThread function
407  * @tc.type: FUNC
408  */
409 HWTEST_F(HdcHostUARTTest, StartUartReadThread, TestSize.Level1)
410 {
__anon5322a9160802(HSession hSession) 411     EXPECT_CALL(mockHostUART, StartUartReadThread).WillOnce(Invoke([&](HSession hSession) {
412         return mockHostUART.HdcHostUART::StartUartReadThread(hSession);
413     }));
414 
415     EXPECT_CALL(mockHostUART, UartReadThread(&mySession)).Times(1);
416     mockHostUART.StartUartReadThread(&mySession);
417     if (mySession.hUART->readThread.joinable()) {
418         mySession.hUART->readThread.join();
419     }
420 }
421 
422 /*
423  * @tc.name: ConnectMyNeed
424  * @tc.desc: Check the behavior of the ConnectMyNeed function
425  * @tc.type: FUNC
426  */
427 HWTEST_F(HdcHostUARTTest, ConnectMyNeed, TestSize.Level1)
428 {
429     HdcUART newUART;
430     mySession.hUART = &newUART;
431     EXPECT_CALL(mockHostUART, UpdateUARTDaemonInfo(myUART.serialPort, nullptr, STATUS_READY))
432         .Times(1);
433     EXPECT_CALL(mockServer, MallocSession(true, CONN_SERIAL, &mockHostUART, 0))
434         .Times(1)
435         .WillOnce(Return(&mySession));
436     EXPECT_CALL(mockInterface, UvTimerStart(Field(&uv_timer_t::data, &mySession),
437                                             &mockServer.UartPreConnect, UV_TIMEOUT, UV_REPEAT))
438         .Times(1)
439         .WillOnce(Return(RET_SUCCESS));
440 
441     EXPECT_EQ(mockHostUART.ConnectMyNeed(&myUART, myUART.serialPort), true);
442 
443     EXPECT_EQ(newUART.devUartHandle, testSerialHandle);
444     EXPECT_EQ(newUART.serialPort, testSerialPortName);
445 }
446 
447 /*
448  * @tc.name: ConnectMyNeed
449  * @tc.desc: Check the behavior of the ConnectMyNeed function
450  * @tc.type: FUNC
451  */
452 HWTEST_F(HdcHostUARTTest, ConnectMyNeedFail, TestSize.Level1)
453 {
454     HdcUART newUART;
455     mySession.hUART = &newUART;
456     EXPECT_CALL(mockHostUART, UpdateUARTDaemonInfo(myUART.serialPort, nullptr, STATUS_READY))
457         .Times(1);
458     EXPECT_CALL(mockServer, MallocSession(true, CONN_SERIAL, &mockHostUART, 0))
459         .Times(1)
460         .WillOnce(Return(&mySession));
461     EXPECT_CALL(mockInterface, UvTimerStart(Field(&uv_timer_t::data, &mySession),
462                                             &mockServer.UartPreConnect, UV_TIMEOUT, UV_REPEAT))
463         .Times(1)
464         .WillOnce(Return(-1));
465 
466     EXPECT_EQ(mockHostUART.ConnectMyNeed(&myUART), false);
467 
468     EXPECT_EQ(newUART.devUartHandle, testSerialHandle);
469     EXPECT_EQ(newUART.serialPort, testSerialPortName);
470 }
471 
472 /*
473  * @tc.name: StartupUARTWork
474  * @tc.desc: Check the behavior of the StartupUARTWork function
475  * @tc.type: FUNC
476  */
477 HWTEST_F(HdcHostUARTTest, StartupUARTWork, TestSize.Level1)
478 {
__anon5322a9160902() 479     EXPECT_CALL(mockHostUART, StartupUARTWork).WillRepeatedly([&]() {
480         return mockHostUART.HdcHostUART::StartupUARTWork();
481     });
482     EXPECT_CALL(mockInterface, UvTimerStart(Field(&uv_timer_t::data, &mockHostUART),
483                                             mockHostUART.UvWatchUartDevPlugin, _, _))
484         .Times(1)
485         .WillOnce(Return(0));
486 
487     EXPECT_CALL(mockHostUART, StartUartSendThread()).Times(1).WillOnce(Return(false));
488 
489     EXPECT_EQ(mockHostUART.StartupUARTWork(), ERR_GENERIC);
490 
491     EXPECT_CALL(mockInterface, UvTimerStart(Field(&uv_timer_t::data, &mockHostUART),
492                                             mockHostUART.UvWatchUartDevPlugin, _, _))
493         .Times(1)
494         .WillOnce(Return(-1));
495     EXPECT_EQ(mockHostUART.StartupUARTWork(), ERR_GENERIC);
496 }
497 
498 MATCHER_P(EqUartHead, otherUartHead, "Equality matcher for type UartHead")
499 {
500     UartHead *argUartHead = reinterpret_cast<UartHead *>(arg);
501     return *argUartHead == *otherUartHead;
502 }
503 
504 /*
505  * @tc.name: SendUartSoftReset
506  * @tc.desc: Check the behavior of the SendUartSoftReset function
507  * @tc.type: FUNC
508  */
509 HWTEST_F(HdcHostUARTTest, SendUartSoftReset, TestSize.Level1)
510 {
511     UartHead resetPackage;
512     constexpr uint32_t sessionId = 1234;
513     resetPackage.option = PKG_OPTION_RESET;
514     resetPackage.dataSize = sizeof(UartHead);
515     resetPackage.sessionId = sessionId;
516 
517     EXPECT_CALL(mockHostUART,
518                 RequestSendPackage(EqUartHead(&resetPackage), sizeof(UartHead), false))
519         .Times(1);
520     mockHostUART.SendUartSoftReset(&mySession, sessionId);
521 }
522 
523 /*
524  * @tc.name: KickoutZombie
525  * @tc.desc: Check the behavior of the KickoutZombie function
526  * @tc.type: FUNC
527  */
528 HWTEST_F(HdcHostUARTTest, KickoutZombie, TestSize.Level1)
529 {
530     mockHostUART.KickoutZombie(nullptr);
531 
532     mySession.isDead = true;
533     mockHostUART.KickoutZombie(&mySession);
534     mySession.isDead = false;
535 
536     myUART.devUartHandle = -1;
537     mockHostUART.KickoutZombie(&mySession);
538     myUART.devUartHandle = 0;
539 
540     EXPECT_CALL(mockServer, FreeSession(mySession.sessionId)).Times(1);
541     mockHostUART.KickoutZombie(&mySession);
542 }
543 
544 /*
545  * @tc.name: StartUartSendThread
546  * @tc.desc: Check the behavior of the StartUartSendThread function
547  * @tc.type: FUNC
548  */
549 HWTEST_F(HdcHostUARTTest, StartUartSendThread, TestSize.Level1)
550 {
__anon5322a9160a02() 551     EXPECT_CALL(mockHostUART, StartUartSendThread).WillRepeatedly([&]() {
552         return mockHostUART.HdcHostUART::StartUartSendThread();
553     });
554     EXPECT_CALL(mockHostUART, UartWriteThread).Times(1);
555     EXPECT_TRUE(mockHostUART.StartUartSendThread());
556     std::this_thread::sleep_for(500ms);
557 }
558 
559 /*
560  * @tc.name: NeedStop
561  * @tc.desc: Check the behavior of the NeedStop function
562  * @tc.type: FUNC
563  */
564 HWTEST_F(HdcHostUARTTest, NeedStop, TestSize.Level1)
565 {
__anon5322a9160b02(const HSession hSession) 566     EXPECT_CALL(mockHostUART, NeedStop).WillRepeatedly([&](const HSession hSession) {
567         return mockHostUART.HdcHostUART::NeedStop(hSession);
568     });
569     mockHostUART.uartOpened = true;
570     mySession.isDead = false;
571     mySession.ref = 1;
572     EXPECT_EQ(mockHostUART.NeedStop(&mySession), false);
573 
574     mockHostUART.uartOpened = true;
575     mySession.isDead = false;
576     mySession.ref = 0;
577     EXPECT_EQ(mockHostUART.NeedStop(&mySession), false);
578 
579     mockHostUART.uartOpened = true;
580     mySession.isDead = true;
581     mySession.ref = 1;
582     EXPECT_EQ(mockHostUART.NeedStop(&mySession), false);
583 
584     mockHostUART.uartOpened = true;
585     mySession.isDead = true;
586     mySession.ref = 0;
587     EXPECT_EQ(mockHostUART.NeedStop(&mySession), true);
588 
589     mockHostUART.uartOpened = false;
590     mySession.isDead = false;
591     mySession.ref = 1;
592     EXPECT_EQ(mockHostUART.NeedStop(&mySession), true);
593 }
594 
595 /*
596  * @tc.name: IsDeviceOpened
597  * @tc.desc: Check the behavior of the IsDeviceOpened function
598  * @tc.type: FUNC
599  */
600 HWTEST_F(HdcHostUARTTest, IsDeviceOpened, TestSize.Level1)
601 {
__anon5322a9160c02(const HdcUART &uart) 602     EXPECT_CALL(mockHostUART, IsDeviceOpened).WillRepeatedly([&](const HdcUART &uart) {
603         return mockHostUART.HdcHostUART::IsDeviceOpened(uart);
604     });
605     myUART.devUartHandle = -1;
606     EXPECT_EQ(mockHostUART.IsDeviceOpened(myUART), false);
607 
608     myUART.devUartHandle = -2;
609     EXPECT_EQ(mockHostUART.IsDeviceOpened(myUART), false);
610 
611     myUART.devUartHandle = 0;
612     EXPECT_EQ(mockHostUART.IsDeviceOpened(myUART), true);
613 
614     myUART.devUartHandle = 1;
615     EXPECT_EQ(mockHostUART.IsDeviceOpened(myUART), true);
616 }
617 
618 /*
619  * @tc.name: UartWriteThread
620  * @tc.desc: Check the behavior of the UartWriteThread function
621  * @tc.type: FUNC
622  */
623 HWTEST_F(HdcHostUARTTest, UartWriteThread, TestSize.Level1)
624 {
__anon5322a9160d02() 625     EXPECT_CALL(mockHostUART, UartWriteThread).WillOnce(Invoke([&]() {
626         return mockHostUART.HdcHostUART::UartWriteThread();
627     }));
628 
629     EXPECT_CALL(mockHostUART, SendPkgInUARTOutMap).Times(0);
630     auto sendThread = std::thread(&HdcHostUART::UartWriteThread, &mockHostUART);
631     std::this_thread::sleep_for(1000ms);
632     EXPECT_CALL(mockHostUART, SendPkgInUARTOutMap).Times(1);
633     mockHostUART.transfer.Request();
634     std::this_thread::sleep_for(200ms);
635     mockHostUART.stopped = true;
636     mockHostUART.transfer.Request();
637     sendThread.join();
638 }
639 
640 /*
641  * @tc.name: UartReadThread
642  * @tc.desc: Check the behavior of the UartReadThread function
643  * @tc.type: FUNC
644  */
645 HWTEST_F(HdcHostUARTTest, UartReadThread, TestSize.Level1)
646 {
__anon5322a9160e02(HSession hSession) 647     EXPECT_CALL(mockHostUART, UartReadThread).WillRepeatedly(Invoke([&](HSession hSession) {
648         return mockHostUART.HdcHostUART::UartReadThread(hSession);
649     }));
650 
651     // case 1 need stop
652     EXPECT_CALL(mockHostUART, NeedStop).WillOnce(Return(true));
653     auto readThread = std::thread(&HdcHostUART::UartReadThread, &mockHostUART, &mySession);
654     readThread.join();
655 
656     // case 2 ReadUartDev return -1 will cause OnTransferError
657     EXPECT_CALL(mockHostUART, NeedStop).WillOnce(Return(false)).WillOnce(Return(true));
658     EXPECT_CALL(mockHostUART, ReadUartDev).WillOnce(Return(-1));
659     EXPECT_CALL(mockHostUART, OnTransferError).Times(1);
660     EXPECT_CALL(mockHostUART, PackageProcess).Times(0);
661     auto readThread2 = std::thread(&HdcHostUART::UartReadThread, &mockHostUART, &mySession);
662     readThread2.join();
663 
664     // case 3 ReadUartDev retturn 0 will timeout, try again
665     EXPECT_CALL(mockHostUART, NeedStop).WillOnce(Return(false)).WillOnce(Return(true));
666     EXPECT_CALL(mockHostUART, ReadUartDev).WillOnce(Return(0));
667     EXPECT_CALL(mockHostUART, OnTransferError).Times(0);
668     EXPECT_CALL(mockHostUART, PackageProcess).Times(0);
669     auto readThread3 = std::thread(&HdcHostUART::UartReadThread, &mockHostUART, &mySession);
670     readThread3.join();
671 
672     // case 4 ReadUartDev return sizeof(UartHead)
673     EXPECT_CALL(mockHostUART, NeedStop).WillOnce(Return(false)).WillOnce(Return(true));
674     EXPECT_CALL(mockHostUART, ReadUartDev)
__anon5322a9160f02(std::vector<uint8_t> &readBuf, size_t expectedSize, HdcUART &uart) 675         .WillOnce(Invoke([&](std::vector<uint8_t> &readBuf, size_t expectedSize, HdcUART &uart) {
676             readBuf.resize(sizeof(UartHead));
677             return readBuf.size();
678         }));
679     EXPECT_CALL(mockHostUART, OnTransferError).Times(0);
680     EXPECT_CALL(mockHostUART, PackageProcess).WillOnce(Return(0));
681     auto readThread4 = std::thread(&HdcHostUART::UartReadThread, &mockHostUART, &mySession);
682     readThread4.join();
683 
684     // case 5 ReadUartDev return more than sizeof(UartHead)
685     EXPECT_CALL(mockHostUART, NeedStop).WillOnce(Return(false)).WillOnce(Return(true));
686     const size_t testDataSize = sizeof(UartHead) * 2;
687 
688     EXPECT_CALL(mockHostUART, ReadUartDev)
__anon5322a9161002(std::vector<uint8_t> &readBuf, size_t expectedSize, HdcUART &uart) 689         .WillOnce(Invoke([&](std::vector<uint8_t> &readBuf, size_t expectedSize, HdcUART &uart) {
690             readBuf.resize(testDataSize);
691             return readBuf.size();
692         }));
693     EXPECT_CALL(mockHostUART, OnTransferError).Times(0);
694     EXPECT_CALL(mockHostUART, PackageProcess).WillOnce(Return(0));
695     auto readThread5 = std::thread(&HdcHostUART::UartReadThread, &mockHostUART, &mySession);
696     readThread5.join();
697 }
698 
699 /*
700  * @tc.name: WaitUartIdle
701  * @tc.desc: Check the behavior of the WaitUartIdle function
702  * @tc.type: FUNC
703  */
704 HWTEST_F(HdcHostUARTTest, WaitUartIdle, TestSize.Level1)
705 {
706     EXPECT_CALL(mockHostUART, ReadUartDev(_, 1, Ref(myUART))).WillOnce(Return(0));
707     EXPECT_EQ(mockHostUART.WaitUartIdle(myUART), true);
708 
709     EXPECT_CALL(mockHostUART, ReadUartDev(_, 1, Ref(myUART)))
710         .WillOnce(Return(1))
711         .WillOnce(Return(0));
712     EXPECT_EQ(mockHostUART.WaitUartIdle(myUART), true);
713 
714     EXPECT_CALL(mockHostUART, ReadUartDev(_, 1, Ref(myUART)))
715         .WillOnce(Return(1))
716         .WillOnce(Return(1));
717     EXPECT_EQ(mockHostUART.WaitUartIdle(myUART), false);
718 }
719 
720 /*
721  * @tc.name: ConnectDaemon
722  * @tc.desc: Check the behavior of the ConnectDaemon function
723  * @tc.type: FUNC
724  */
725 HWTEST_F(HdcHostUARTTest, ConnectDaemon, TestSize.Level1)
726 {
727     std::string connectKey = "dummykey";
728     EXPECT_CALL(mockHostUART, OpenSerialPort(connectKey)).WillOnce(Return(0));
729     EXPECT_EQ(mockHostUART.ConnectDaemon(connectKey), nullptr);
730 }
731 
732 /*
733  * @tc.name: GetSession
734  * @tc.desc: Check the behavior of the GetSession function
735  * @tc.type: FUNC
736  */
737 HWTEST_F(HdcHostUARTTest, GetSession, TestSize.Level1)
738 {
739     constexpr uint32_t sessionId = 1234;
740     HdcSession mySession;
741     HdcUART myUART;
742     mySession.hUART = &myUART;
743     EXPECT_CALL(mockServer, AdminSession(OP_QUERY, sessionId, nullptr))
744         .Times(1)
745         .WillOnce(Return(&mySession));
746     mockHostUART.GetSession(sessionId, false);
747 }
748 
749 /*
750  * @tc.name: CloseSerialPort
751  * @tc.desc: Check the behavior of the CloseSerialPort function
752  * @tc.type: FUNC
753  */
754 HWTEST_F(HdcHostUARTTest, CloseSerialPort, TestSize.Level1)
755 {
756     myUART.devUartHandle = -1;
757     mockHostUART.CloseSerialPort(&myUART);
758 }
759 
760 /*
761  * @tc.name: GetPortFromKey
762  * @tc.desc: Check the behavior of the GetPortFromKey function
763  * @tc.type: FUNC
764  */
765 HWTEST_F(HdcHostUARTTest, GetPortFromKey, TestSize.Level1)
766 {
767     std::string portName;
768     uint32_t baudRate;
769     const uint32_t baudRateTest = 111u;
770     EXPECT_EQ(mockHostUART.GetPortFromKey("COM1", portName, baudRate), true);
771     EXPECT_STREQ(portName.c_str(), "COM1");
772     EXPECT_EQ(baudRate, mockHostUART.DEFAULT_BAUD_RATE_VALUE);
773 
774     EXPECT_EQ(mockHostUART.GetPortFromKey("COM1,aaa", portName, baudRate), false);
775 
776     EXPECT_EQ(mockHostUART.GetPortFromKey("COM1,111", portName, baudRate), true);
777     EXPECT_STREQ(portName.c_str(), "COM1");
778     EXPECT_EQ(baudRate, baudRateTest);
779 }
780 
781 /*
782  * @tc.name: Restartession
783  * @tc.desc: Check the behavior of the Restartession function
784  * successed
785  * @tc.type: FUNC
786  */
787 HWTEST_F(HdcHostUARTTest, Restartession, TestSize.Level1)
788 {
789     const uint32_t sessionId = 12345;
790     mySession.sessionId = sessionId;
791     EXPECT_CALL(mockHostUART, CloseSerialPort(mySession.hUART)).WillOnce(Return());
792     EXPECT_CALL(mockServer, EchoToClientsForSession(sessionId, _)).WillOnce(Return());
793     mockHostUART.Restartession(&mySession);
794 }
795 
796 /*
797  * @tc.name: StopSession
798  * @tc.desc: Check the behavior of the StopSession function
799  * successed
800  * @tc.type: FUNC
801  */
802 HWTEST_F(HdcHostUARTTest, StopSession, TestSize.Level1)
803 {
804     EXPECT_EQ(mySession.hUART->ioCancel, false);
805     mockHostUART.StopSession(nullptr);
806     EXPECT_EQ(mySession.hUART->ioCancel, false);
807     mockHostUART.StopSession(&mySession);
808     EXPECT_EQ(mySession.hUART->ioCancel, true);
809 }
810 
811 /*
812  * @tc.name: OnTransferError
813  * @tc.desc: Check the behavior of the OnTransferError function
814  * @tc.type: FUNC
815  */
816 HWTEST_F(HdcHostUARTTest, OnTransferError, TestSize.Level1)
817 {
__anon5322a9161102(const HSession session) 818     EXPECT_CALL(mockHostUART, OnTransferError).WillRepeatedly(Invoke([&](const HSession session) {
819         return mockHostUART.HdcHostUART::OnTransferError(session);
820     }));
821     mockHostUART.OnTransferError(nullptr);
822     const uint32_t sessionId = mySession.sessionId;
823 
824     EXPECT_CALL(mockHostUART, IsDeviceOpened(Ref(*mySession.hUART))).WillOnce(Return(true));
825     EXPECT_CALL(mockServer, EchoToClientsForSession(sessionId, _)).WillOnce(Return());
826     EXPECT_CALL(mockHostUART, CloseSerialPort(mySession.hUART)).WillOnce(Return());
827     EXPECT_CALL(mockHostUART,
828                 UpdateUARTDaemonInfo(mySession.connectKey, &mySession, STATUS_OFFLINE))
829         .WillOnce(Return());
830     EXPECT_CALL(mockServer, FreeSession(sessionId)).WillOnce(Return());
831     EXPECT_CALL(mockHostUART, ClearUARTOutMap(sessionId)).WillOnce(Return());
832     mockHostUART.OnTransferError(&mySession);
833 }
834 } // namespace Hdc