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