1ea497e4dSopenharmony_ci/*
2ea497e4dSopenharmony_ci * Copyright (C) 2023 Huawei Device Co., Ltd.
3ea497e4dSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4ea497e4dSopenharmony_ci * you may not use this file except in compliance with the License.
5ea497e4dSopenharmony_ci * You may obtain a copy of the License at
6ea497e4dSopenharmony_ci *
7ea497e4dSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8ea497e4dSopenharmony_ci *
9ea497e4dSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10ea497e4dSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11ea497e4dSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12ea497e4dSopenharmony_ci * See the License for the specific language governing permissions and
13ea497e4dSopenharmony_ci * limitations under the License.
14ea497e4dSopenharmony_ci */
15ea497e4dSopenharmony_ci
16ea497e4dSopenharmony_ci#include <chrono>
17ea497e4dSopenharmony_ci
18ea497e4dSopenharmony_ci#include "finite_state_machine.h"
19ea497e4dSopenharmony_ci
20ea497e4dSopenharmony_ci#include "mock_thread_handler.h"
21ea497e4dSopenharmony_ci
22ea497e4dSopenharmony_cinamespace OHOS {
23ea497e4dSopenharmony_cinamespace UserIam {
24ea497e4dSopenharmony_cinamespace FaceAuth {
25ea497e4dSopenharmony_ciusing namespace testing;
26ea497e4dSopenharmony_ciusing namespace testing::ext;
27ea497e4dSopenharmony_ci
28ea497e4dSopenharmony_cienum State : uint32_t {
29ea497e4dSopenharmony_ci    STATE_INIT,
30ea497e4dSopenharmony_ci    STATE_VERIFY_STARING,
31ea497e4dSopenharmony_ci    STATE_COLLECT_STARING,
32ea497e4dSopenharmony_ci    STATE_AUTH_PROCESSING,
33ea497e4dSopenharmony_ci    STATE_VERIFY_STOPPING,
34ea497e4dSopenharmony_ci    STATE_COLLECT_STOPPING,
35ea497e4dSopenharmony_ci    STATE_END
36ea497e4dSopenharmony_ci};
37ea497e4dSopenharmony_ci
38ea497e4dSopenharmony_cienum Event : uint32_t {
39ea497e4dSopenharmony_ci    EVENT_START_AUTH,
40ea497e4dSopenharmony_ci    EVENT_VERIFY_STARTED,
41ea497e4dSopenharmony_ci    EVENT_COLLECT_STARTED,
42ea497e4dSopenharmony_ci    EVENT_AUTH_RESULT_GET,
43ea497e4dSopenharmony_ci    EVENT_VERIFY_STOPPED,
44ea497e4dSopenharmony_ci    EVENT_COLLECT_STOP,
45ea497e4dSopenharmony_ci    EVENT_USER_CANCEL,
46ea497e4dSopenharmony_ci    EVENT_TIME_OUT,
47ea497e4dSopenharmony_ci};
48ea497e4dSopenharmony_ci
49ea497e4dSopenharmony_ciclass StateMachineTest : public testing::Test {
50ea497e4dSopenharmony_cipublic:
51ea497e4dSopenharmony_ci    static void SetUpTestCase();
52ea497e4dSopenharmony_ci
53ea497e4dSopenharmony_ci    static void TearDownTestCase();
54ea497e4dSopenharmony_ci
55ea497e4dSopenharmony_ci    void SetUp() override;
56ea497e4dSopenharmony_ci
57ea497e4dSopenharmony_ci    void TearDown() override;
58ea497e4dSopenharmony_ci};
59ea497e4dSopenharmony_ci
60ea497e4dSopenharmony_civoid StateMachineTest::SetUpTestCase()
61ea497e4dSopenharmony_ci{
62ea497e4dSopenharmony_ci}
63ea497e4dSopenharmony_ci
64ea497e4dSopenharmony_civoid StateMachineTest::TearDownTestCase()
65ea497e4dSopenharmony_ci{
66ea497e4dSopenharmony_ci}
67ea497e4dSopenharmony_ci
68ea497e4dSopenharmony_civoid StateMachineTest::SetUp()
69ea497e4dSopenharmony_ci{
70ea497e4dSopenharmony_ci    ThreadHandler::GetSingleThreadInstance()->EnsureTask(nullptr);
71ea497e4dSopenharmony_ci}
72ea497e4dSopenharmony_ci
73ea497e4dSopenharmony_civoid StateMachineTest::TearDown()
74ea497e4dSopenharmony_ci{
75ea497e4dSopenharmony_ci    ThreadHandler::GetSingleThreadInstance()->EnsureTask(nullptr);
76ea497e4dSopenharmony_ci}
77ea497e4dSopenharmony_ci
78ea497e4dSopenharmony_ciHWTEST_F(StateMachineTest, MachineCreateSelfReturn, TestSize.Level0)
79ea497e4dSopenharmony_ci{
80ea497e4dSopenharmony_ci    auto handler = ThreadHandler::GetSingleThreadInstance();
81ea497e4dSopenharmony_ci    auto machineBuilder = FiniteStateMachine::Builder::New("testMachine0", STATE_INIT);
82ea497e4dSopenharmony_ci    EXPECT_NE(machineBuilder, nullptr);
83ea497e4dSopenharmony_ci
84ea497e4dSopenharmony_ci    auto ret1 = machineBuilder->MakeTransition(STATE_INIT, EVENT_START_AUTH, STATE_VERIFY_STARING);
85ea497e4dSopenharmony_ci    EXPECT_NE(ret1, nullptr);
86ea497e4dSopenharmony_ci
87ea497e4dSopenharmony_ci    auto ret2 = ret1->MakeTransition(STATE_VERIFY_STARING, EVENT_VERIFY_STARTED, STATE_COLLECT_STARING);
88ea497e4dSopenharmony_ci    EXPECT_EQ(ret2, ret1);
89ea497e4dSopenharmony_ci}
90ea497e4dSopenharmony_ci
91ea497e4dSopenharmony_ciHWTEST_F(StateMachineTest, MachineCreateOnlyBuildOnce, TestSize.Level0)
92ea497e4dSopenharmony_ci{
93ea497e4dSopenharmony_ci    auto handler = ThreadHandler::GetSingleThreadInstance();
94ea497e4dSopenharmony_ci    auto machineBuilder = FiniteStateMachine::Builder::New("testMachine1", STATE_INIT);
95ea497e4dSopenharmony_ci    EXPECT_NE(machineBuilder, nullptr);
96ea497e4dSopenharmony_ci
97ea497e4dSopenharmony_ci    machineBuilder->MakeTransition(STATE_INIT, EVENT_START_AUTH, STATE_VERIFY_STARING)
98ea497e4dSopenharmony_ci        ->MakeTransition(STATE_VERIFY_STARING, EVENT_VERIFY_STARTED, STATE_COLLECT_STARING);
99ea497e4dSopenharmony_ci
100ea497e4dSopenharmony_ci    auto first = machineBuilder->Build();
101ea497e4dSopenharmony_ci    EXPECT_NE(first, nullptr);
102ea497e4dSopenharmony_ci
103ea497e4dSopenharmony_ci    auto second = machineBuilder->Build();
104ea497e4dSopenharmony_ci    EXPECT_EQ(second, nullptr);
105ea497e4dSopenharmony_ci}
106ea497e4dSopenharmony_ci
107ea497e4dSopenharmony_ciHWTEST_F(StateMachineTest, MachineCreateCheckTransition, TestSize.Level0)
108ea497e4dSopenharmony_ci{
109ea497e4dSopenharmony_ci    auto handler = ThreadHandler::GetSingleThreadInstance();
110ea497e4dSopenharmony_ci    auto machineBuilder = FiniteStateMachine::Builder::New("testMachine2", STATE_INIT);
111ea497e4dSopenharmony_ci    EXPECT_NE(machineBuilder, nullptr);
112ea497e4dSopenharmony_ci
113ea497e4dSopenharmony_ci    machineBuilder->MakeTransition(STATE_INIT, EVENT_START_AUTH, STATE_VERIFY_STARING)
114ea497e4dSopenharmony_ci        ->MakeTransition(STATE_INIT, EVENT_START_AUTH, STATE_COLLECT_STARING);
115ea497e4dSopenharmony_ci
116ea497e4dSopenharmony_ci    auto machine = machineBuilder->Build();
117ea497e4dSopenharmony_ci    EXPECT_EQ(machine, nullptr);
118ea497e4dSopenharmony_ci}
119ea497e4dSopenharmony_ci
120ea497e4dSopenharmony_ciHWTEST_F(StateMachineTest, MachineCreateInitialState, TestSize.Level0)
121ea497e4dSopenharmony_ci{
122ea497e4dSopenharmony_ci    auto handler = ThreadHandler::GetSingleThreadInstance();
123ea497e4dSopenharmony_ci    auto machineBuilder = FiniteStateMachine::Builder::New("testMachine3", STATE_COLLECT_STOPPING);
124ea497e4dSopenharmony_ci    ASSERT_NE(machineBuilder, nullptr);
125ea497e4dSopenharmony_ci
126ea497e4dSopenharmony_ci    machineBuilder->MakeTransition(STATE_COLLECT_STOPPING, EVENT_START_AUTH, STATE_VERIFY_STARING);
127ea497e4dSopenharmony_ci    auto machine = machineBuilder->Build();
128ea497e4dSopenharmony_ci    ASSERT_NE(machine, nullptr);
129ea497e4dSopenharmony_ci    EXPECT_EQ(machine->GetCurrentState(), STATE_COLLECT_STOPPING);
130ea497e4dSopenharmony_ci}
131ea497e4dSopenharmony_ci
132ea497e4dSopenharmony_ciHWTEST_F(StateMachineTest, MachineCreateNameCheck, TestSize.Level0)
133ea497e4dSopenharmony_ci{
134ea497e4dSopenharmony_ci    auto handler = ThreadHandler::GetSingleThreadInstance();
135ea497e4dSopenharmony_ci    auto machineBuilder = FiniteStateMachine::Builder::New("testMachine4", STATE_COLLECT_STOPPING);
136ea497e4dSopenharmony_ci    ASSERT_NE(machineBuilder, nullptr);
137ea497e4dSopenharmony_ci
138ea497e4dSopenharmony_ci    machineBuilder->MakeTransition(STATE_COLLECT_STOPPING, EVENT_START_AUTH, STATE_VERIFY_STARING);
139ea497e4dSopenharmony_ci    auto machine = machineBuilder->Build();
140ea497e4dSopenharmony_ci    ASSERT_NE(machine, nullptr);
141ea497e4dSopenharmony_ci    EXPECT_EQ(machine->GetMachineName(), "testMachine4");
142ea497e4dSopenharmony_ci}
143ea497e4dSopenharmony_ci
144ea497e4dSopenharmony_ciHWTEST_F(StateMachineTest, MachineScheduleStepIn, TestSize.Level0)
145ea497e4dSopenharmony_ci{
146ea497e4dSopenharmony_ci    auto handler = ThreadHandler::GetSingleThreadInstance();
147ea497e4dSopenharmony_ci    auto machineBuilder = FiniteStateMachine::Builder::New("testMachine5", STATE_INIT);
148ea497e4dSopenharmony_ci    ASSERT_NE(machineBuilder, nullptr);
149ea497e4dSopenharmony_ci
150ea497e4dSopenharmony_ci    machineBuilder->MakeTransition(STATE_INIT, EVENT_START_AUTH, STATE_VERIFY_STARING)
151ea497e4dSopenharmony_ci        ->MakeTransition(STATE_VERIFY_STARING, EVENT_VERIFY_STARTED, STATE_COLLECT_STARING);
152ea497e4dSopenharmony_ci
153ea497e4dSopenharmony_ci    auto machine = machineBuilder->Build();
154ea497e4dSopenharmony_ci    ASSERT_NE(machine, nullptr);
155ea497e4dSopenharmony_ci    EXPECT_EQ(machine->GetCurrentState(), STATE_INIT);
156ea497e4dSopenharmony_ci
157ea497e4dSopenharmony_ci    machine->Schedule(EVENT_START_AUTH);
158ea497e4dSopenharmony_ci    EXPECT_EQ(machine->EnsureCurrentState(), STATE_VERIFY_STARING);
159ea497e4dSopenharmony_ci    machine->Schedule(EVENT_VERIFY_STARTED);
160ea497e4dSopenharmony_ci    EXPECT_EQ(machine->EnsureCurrentState(), STATE_COLLECT_STARING);
161ea497e4dSopenharmony_ci    machine->Schedule(EVENT_VERIFY_STARTED);
162ea497e4dSopenharmony_ci    EXPECT_EQ(machine->EnsureCurrentState(), STATE_COLLECT_STARING);
163ea497e4dSopenharmony_ci}
164ea497e4dSopenharmony_ci
165ea497e4dSopenharmony_ciHWTEST_F(StateMachineTest, MachineScheduleWithAction, TestSize.Level0)
166ea497e4dSopenharmony_ci{
167ea497e4dSopenharmony_ci    auto handler = ThreadHandler::GetSingleThreadInstance();
168ea497e4dSopenharmony_ci    auto machineBuilder = FiniteStateMachine::Builder::New("testMachine6", STATE_INIT);
169ea497e4dSopenharmony_ci    ASSERT_NE(machineBuilder, nullptr);
170ea497e4dSopenharmony_ci
171ea497e4dSopenharmony_ci    MockFunction<void(FiniteStateMachine & machine, uint32_t event)> action1;
172ea497e4dSopenharmony_ci    MockFunction<void(FiniteStateMachine & machine, uint32_t event)> action2;
173ea497e4dSopenharmony_ci    {
174ea497e4dSopenharmony_ci        auto init = [](FiniteStateMachine &machine) { return machine.GetCurrentState() == STATE_INIT; };
175ea497e4dSopenharmony_ci        auto verify = [](FiniteStateMachine &machine) { return machine.GetCurrentState() == EVENT_VERIFY_STARTED; };
176ea497e4dSopenharmony_ci        InSequence s;
177ea497e4dSopenharmony_ci        EXPECT_CALL(action1, Call(Truly(init), EVENT_START_AUTH)).Times(Exactly(1));
178ea497e4dSopenharmony_ci        EXPECT_CALL(action2, Call(Truly(verify), EVENT_VERIFY_STARTED)).Times(Exactly(1));
179ea497e4dSopenharmony_ci    }
180ea497e4dSopenharmony_ci
181ea497e4dSopenharmony_ci    machineBuilder
182ea497e4dSopenharmony_ci        ->MakeTransition(STATE_INIT, EVENT_START_AUTH, STATE_VERIFY_STARING,
183ea497e4dSopenharmony_ci            [&action1](FiniteStateMachine &machine, uint32_t event) { action1.Call(machine, event); })
184ea497e4dSopenharmony_ci        ->MakeTransition(STATE_VERIFY_STARING, EVENT_VERIFY_STARTED, STATE_COLLECT_STARING,
185ea497e4dSopenharmony_ci            [&action2](FiniteStateMachine &machine, uint32_t event) { action2.Call(machine, event); });
186ea497e4dSopenharmony_ci
187ea497e4dSopenharmony_ci    auto machine = machineBuilder->Build();
188ea497e4dSopenharmony_ci    ASSERT_NE(machine, nullptr);
189ea497e4dSopenharmony_ci    EXPECT_EQ(machine->EnsureCurrentState(), STATE_INIT);
190ea497e4dSopenharmony_ci
191ea497e4dSopenharmony_ci    machine->Schedule(EVENT_START_AUTH);
192ea497e4dSopenharmony_ci    EXPECT_EQ(machine->EnsureCurrentState(), STATE_VERIFY_STARING);
193ea497e4dSopenharmony_ci    machine->Schedule(EVENT_VERIFY_STARTED);
194ea497e4dSopenharmony_ci    EXPECT_EQ(machine->EnsureCurrentState(), STATE_COLLECT_STARING);
195ea497e4dSopenharmony_ci    machine->Schedule(EVENT_VERIFY_STARTED);
196ea497e4dSopenharmony_ci    EXPECT_EQ(machine->EnsureCurrentState(), STATE_COLLECT_STARING);
197ea497e4dSopenharmony_ci}
198ea497e4dSopenharmony_ci
199ea497e4dSopenharmony_ciHWTEST_F(StateMachineTest, MachineScheduleWithComplexActionDirectly, TestSize.Level0)
200ea497e4dSopenharmony_ci{
201ea497e4dSopenharmony_ci    auto handler = MockThreadHandler::InvokeDirectly();
202ea497e4dSopenharmony_ci    auto machineBuilder = FiniteStateMachine::Builder::New("testMachine7", STATE_INIT);
203ea497e4dSopenharmony_ci    ASSERT_NE(machineBuilder, nullptr);
204ea497e4dSopenharmony_ci
205ea497e4dSopenharmony_ci    MockFunction<void(FiniteStateMachine & machine, uint32_t event)> action1;
206ea497e4dSopenharmony_ci    MockFunction<void(FiniteStateMachine & machine, uint32_t event)> action2;
207ea497e4dSopenharmony_ci    {
208ea497e4dSopenharmony_ci        auto init = [](FiniteStateMachine &machine) { return machine.GetCurrentState() == STATE_INIT; };
209ea497e4dSopenharmony_ci        auto verify = [](FiniteStateMachine &machine) { return machine.GetCurrentState() == EVENT_VERIFY_STARTED; };
210ea497e4dSopenharmony_ci
211ea497e4dSopenharmony_ci        InSequence s;
212ea497e4dSopenharmony_ci        EXPECT_CALL(action1, Call(Truly(init), EVENT_START_AUTH)).Times(Exactly(1));
213ea497e4dSopenharmony_ci        EXPECT_CALL(action2, Call(Truly(verify), EVENT_VERIFY_STARTED)).Times(Exactly(1));
214ea497e4dSopenharmony_ci    }
215ea497e4dSopenharmony_ci
216ea497e4dSopenharmony_ci    machineBuilder
217ea497e4dSopenharmony_ci        ->MakeTransition(STATE_INIT, EVENT_START_AUTH, STATE_VERIFY_STARING,
218ea497e4dSopenharmony_ci            [&action1](FiniteStateMachine &machine, uint32_t event) {
219ea497e4dSopenharmony_ci                action1.Call(machine, event);
220ea497e4dSopenharmony_ci                machine.Schedule(EVENT_VERIFY_STARTED);
221ea497e4dSopenharmony_ci            })
222ea497e4dSopenharmony_ci        ->MakeTransition(STATE_VERIFY_STARING, EVENT_VERIFY_STARTED, STATE_COLLECT_STARING,
223ea497e4dSopenharmony_ci            [&action2](FiniteStateMachine &machine, uint32_t event) {
224ea497e4dSopenharmony_ci                action2.Call(machine, event);
225ea497e4dSopenharmony_ci                machine.Schedule(EVENT_COLLECT_STARTED);
226ea497e4dSopenharmony_ci            })
227ea497e4dSopenharmony_ci        ->MakeTransition(STATE_COLLECT_STARING, EVENT_COLLECT_STARTED, STATE_AUTH_PROCESSING, nullptr);
228ea497e4dSopenharmony_ci
229ea497e4dSopenharmony_ci    auto machine = machineBuilder->Build();
230ea497e4dSopenharmony_ci    ASSERT_NE(machine, nullptr);
231ea497e4dSopenharmony_ci    EXPECT_EQ(machine->EnsureCurrentState(), STATE_INIT);
232ea497e4dSopenharmony_ci
233ea497e4dSopenharmony_ci    machine->Schedule(EVENT_START_AUTH);
234ea497e4dSopenharmony_ci    EXPECT_EQ(machine->EnsureCurrentState(), STATE_AUTH_PROCESSING);
235ea497e4dSopenharmony_ci}
236ea497e4dSopenharmony_ci
237ea497e4dSopenharmony_ciHWTEST_F(StateMachineTest, MachineScheduleWithComplexActionBackGround, TestSize.Level0)
238ea497e4dSopenharmony_ci{
239ea497e4dSopenharmony_ci    auto handler = ThreadHandler::GetSingleThreadInstance();
240ea497e4dSopenharmony_ci    auto machineBuilder = FiniteStateMachine::Builder::New("testMachine8", STATE_INIT);
241ea497e4dSopenharmony_ci    ASSERT_NE(machineBuilder, nullptr);
242ea497e4dSopenharmony_ci
243ea497e4dSopenharmony_ci    machineBuilder
244ea497e4dSopenharmony_ci        ->MakeTransition(STATE_INIT, EVENT_START_AUTH, STATE_VERIFY_STARING,
245ea497e4dSopenharmony_ci            [](FiniteStateMachine &machine, [[maybe_unused]] uint32_t event) {
246ea497e4dSopenharmony_ci                machine.Schedule(EVENT_VERIFY_STARTED);
247ea497e4dSopenharmony_ci                machine.Schedule(EVENT_COLLECT_STARTED);
248ea497e4dSopenharmony_ci                machine.Schedule(EVENT_USER_CANCEL);
249ea497e4dSopenharmony_ci            })
250ea497e4dSopenharmony_ci        ->MakeTransition(STATE_VERIFY_STARING, EVENT_VERIFY_STARTED, STATE_COLLECT_STARING, nullptr)
251ea497e4dSopenharmony_ci        ->MakeTransition(STATE_COLLECT_STARING, EVENT_COLLECT_STARTED, STATE_AUTH_PROCESSING, nullptr)
252ea497e4dSopenharmony_ci        ->MakeTransition(STATE_AUTH_PROCESSING, EVENT_USER_CANCEL, STATE_END, nullptr);
253ea497e4dSopenharmony_ci    auto machine = machineBuilder->Build();
254ea497e4dSopenharmony_ci    ASSERT_NE(machine, nullptr);
255ea497e4dSopenharmony_ci    EXPECT_EQ(machine->EnsureCurrentState(), STATE_INIT);
256ea497e4dSopenharmony_ci
257ea497e4dSopenharmony_ci    machine->Schedule(EVENT_START_AUTH);
258ea497e4dSopenharmony_ci    EXPECT_EQ(machine->EnsureCurrentState(), STATE_END);
259ea497e4dSopenharmony_ci}
260ea497e4dSopenharmony_ci
261ea497e4dSopenharmony_ciHWTEST_F(StateMachineTest, MachineScheduleDeadlock, TestSize.Level0)
262ea497e4dSopenharmony_ci{
263ea497e4dSopenharmony_ci    auto handler = ThreadHandler::GetSingleThreadInstance();
264ea497e4dSopenharmony_ci    auto machineBuilder = FiniteStateMachine::Builder::New("testMachine9", STATE_INIT);
265ea497e4dSopenharmony_ci    ASSERT_NE(machineBuilder, nullptr);
266ea497e4dSopenharmony_ci    machineBuilder->MakeTransition(STATE_INIT, STATE_INIT, STATE_INIT, [](FiniteStateMachine &machine, uint32_t event) {
267ea497e4dSopenharmony_ci        machine.Schedule(STATE_INIT);
268ea497e4dSopenharmony_ci        machine.Schedule(STATE_INIT);
269ea497e4dSopenharmony_ci        machine.Schedule(STATE_INIT);
270ea497e4dSopenharmony_ci    });
271ea497e4dSopenharmony_ci    auto machine = machineBuilder->Build();
272ea497e4dSopenharmony_ci    ASSERT_NE(machine, nullptr);
273ea497e4dSopenharmony_ci    EXPECT_EQ(machine->EnsureCurrentState(), STATE_INIT);
274ea497e4dSopenharmony_ci
275ea497e4dSopenharmony_ci    machine->Schedule(EVENT_START_AUTH);
276ea497e4dSopenharmony_ci    EXPECT_EQ(machine->EnsureCurrentState(), STATE_INIT);
277ea497e4dSopenharmony_ci}
278ea497e4dSopenharmony_ci
279ea497e4dSopenharmony_ciHWTEST_F(StateMachineTest, MachineScheduleContinues, TestSize.Level0)
280ea497e4dSopenharmony_ci{
281ea497e4dSopenharmony_ci    MockFunction<void(FiniteStateMachine & machine, uint32_t event)> action;
282ea497e4dSopenharmony_ci    EXPECT_CALL(action, Call(_, STATE_INIT)).Times(Exactly(3));
283ea497e4dSopenharmony_ci    auto handler = ThreadHandler::GetSingleThreadInstance();
284ea497e4dSopenharmony_ci    {
285ea497e4dSopenharmony_ci        auto machineBuilder = FiniteStateMachine::Builder::New("testMachine10", STATE_INIT);
286ea497e4dSopenharmony_ci        ASSERT_NE(machineBuilder, nullptr);
287ea497e4dSopenharmony_ci        machineBuilder->MakeTransition(STATE_INIT, STATE_INIT, STATE_INIT,
288ea497e4dSopenharmony_ci            [&action](FiniteStateMachine &machine, [[maybe_unused]] uint32_t event) {
289ea497e4dSopenharmony_ci                action.Call(machine, STATE_INIT);
290ea497e4dSopenharmony_ci            });
291ea497e4dSopenharmony_ci        auto machine = machineBuilder->Build();
292ea497e4dSopenharmony_ci        ASSERT_NE(machine, nullptr);
293ea497e4dSopenharmony_ci        machine->Schedule(STATE_INIT);
294ea497e4dSopenharmony_ci        machine->Schedule(STATE_INIT);
295ea497e4dSopenharmony_ci        machine->Schedule(STATE_INIT);
296ea497e4dSopenharmony_ci        handler->EnsureTask(nullptr);
297ea497e4dSopenharmony_ci    }
298ea497e4dSopenharmony_ci}
299ea497e4dSopenharmony_ci
300ea497e4dSopenharmony_ciHWTEST_F(StateMachineTest, MachineScheduleExpireNodeTimeout, TestSize.Level0)
301ea497e4dSopenharmony_ci{
302ea497e4dSopenharmony_ci    auto handler = ThreadHandler::GetSingleThreadInstance();
303ea497e4dSopenharmony_ci
304ea497e4dSopenharmony_ci    MockFunction<void(FiniteStateMachine & machine, uint32_t event)> action;
305ea497e4dSopenharmony_ci    EXPECT_CALL(action, Call(_, STATE_INIT)).Times(Exactly(5));
306ea497e4dSopenharmony_ci    {
307ea497e4dSopenharmony_ci        auto machineBuilder = FiniteStateMachine::Builder::New("testMachine11", STATE_INIT);
308ea497e4dSopenharmony_ci        ASSERT_NE(machineBuilder, nullptr);
309ea497e4dSopenharmony_ci        machineBuilder->MakeTransition(STATE_INIT, STATE_INIT, STATE_INIT,
310ea497e4dSopenharmony_ci            [&action](FiniteStateMachine &machine, [[maybe_unused]] uint32_t event) {
311ea497e4dSopenharmony_ci                std::this_thread::sleep_for(std::chrono::milliseconds(200));
312ea497e4dSopenharmony_ci                action.Call(machine, STATE_INIT);
313ea497e4dSopenharmony_ci            });
314ea497e4dSopenharmony_ci        auto machine = machineBuilder->Build();
315ea497e4dSopenharmony_ci        ASSERT_NE(machine, nullptr);
316ea497e4dSopenharmony_ci
317ea497e4dSopenharmony_ci        machine->SetThreadHandler(handler);
318ea497e4dSopenharmony_ci        handler->EnsureTask(nullptr);
319ea497e4dSopenharmony_ci        machine->Schedule(STATE_INIT);
320ea497e4dSopenharmony_ci        machine->Schedule(STATE_INIT);
321ea497e4dSopenharmony_ci        machine->Schedule(STATE_INIT);
322ea497e4dSopenharmony_ci        machine->Schedule(STATE_INIT);
323ea497e4dSopenharmony_ci        machine->Schedule(STATE_INIT);
324ea497e4dSopenharmony_ci        std::this_thread::sleep_for(std::chrono::milliseconds(100));
325ea497e4dSopenharmony_ci        machine = nullptr;
326ea497e4dSopenharmony_ci        handler->EnsureTask(nullptr);
327ea497e4dSopenharmony_ci    }
328ea497e4dSopenharmony_ci}
329ea497e4dSopenharmony_ci
330ea497e4dSopenharmony_ciHWTEST_F(StateMachineTest, MachineScheduleExpireNodeExpire, TestSize.Level0)
331ea497e4dSopenharmony_ci{
332ea497e4dSopenharmony_ci    auto handler = ThreadHandler::GetSingleThreadInstance();
333ea497e4dSopenharmony_ci    MockFunction<void(FiniteStateMachine & machine, uint32_t event)> action;
334ea497e4dSopenharmony_ci    EXPECT_CALL(action, Call(_, STATE_INIT)).Times(Exactly(0));
335ea497e4dSopenharmony_ci    {
336ea497e4dSopenharmony_ci        auto machineBuilder = FiniteStateMachine::Builder::New("testMachine12", STATE_INIT);
337ea497e4dSopenharmony_ci        ASSERT_NE(machineBuilder, nullptr);
338ea497e4dSopenharmony_ci        machineBuilder->MakeTransition(STATE_INIT, STATE_INIT, STATE_INIT,
339ea497e4dSopenharmony_ci            [&action](FiniteStateMachine &machine, [[maybe_unused]] uint32_t event) {
340ea497e4dSopenharmony_ci                action.Call(machine, STATE_INIT);
341ea497e4dSopenharmony_ci            });
342ea497e4dSopenharmony_ci        auto machine = machineBuilder->Build();
343ea497e4dSopenharmony_ci        ASSERT_NE(machine, nullptr);
344ea497e4dSopenharmony_ci        handler->PostTask([]() { std::this_thread::sleep_for(std::chrono::milliseconds(1000)); });
345ea497e4dSopenharmony_ci        machine->Schedule(STATE_INIT);
346ea497e4dSopenharmony_ci        machine->Schedule(STATE_INIT);
347ea497e4dSopenharmony_ci        machine->Schedule(STATE_INIT);
348ea497e4dSopenharmony_ci        machine->Schedule(STATE_INIT);
349ea497e4dSopenharmony_ci        machine->Schedule(STATE_INIT);
350ea497e4dSopenharmony_ci        machine = nullptr;
351ea497e4dSopenharmony_ci    }
352ea497e4dSopenharmony_ci    handler->EnsureTask(nullptr);
353ea497e4dSopenharmony_ci}
354ea497e4dSopenharmony_ci
355ea497e4dSopenharmony_cistatic void GetTestMachine(std::shared_ptr<FiniteStateMachine> &machine,
356ea497e4dSopenharmony_ci    MockFunction<void(FiniteStateMachine &machine, uint32_t event)> &action,
357ea497e4dSopenharmony_ci    MockFunction<void(FiniteStateMachine &machine, uint32_t event)> &enter,
358ea497e4dSopenharmony_ci    MockFunction<void(FiniteStateMachine &machine, uint32_t event)> &leave)
359ea497e4dSopenharmony_ci{
360ea497e4dSopenharmony_ci    auto machineBuilder = FiniteStateMachine::Builder::New("testMachine13", STATE_INIT);
361ea497e4dSopenharmony_ci    ASSERT_NE(machineBuilder, nullptr);
362ea497e4dSopenharmony_ci
363ea497e4dSopenharmony_ci    machineBuilder->MakeTransition(STATE_INIT, EVENT_START_AUTH, STATE_VERIFY_STARING,
364ea497e4dSopenharmony_ci        [&action](FiniteStateMachine &machine, uint32_t event) {
365ea497e4dSopenharmony_ci            action.Call(machine, event);
366ea497e4dSopenharmony_ci            machine.Schedule(EVENT_VERIFY_STARTED);
367ea497e4dSopenharmony_ci            machine.Schedule(EVENT_COLLECT_STARTED);
368ea497e4dSopenharmony_ci        });
369ea497e4dSopenharmony_ci    machineBuilder->MakeTransition(STATE_VERIFY_STARING, EVENT_VERIFY_STARTED, STATE_COLLECT_STARING,
370ea497e4dSopenharmony_ci        [&action](FiniteStateMachine &machine, uint32_t event) { action.Call(machine, event); });
371ea497e4dSopenharmony_ci    machineBuilder->MakeTransition(STATE_COLLECT_STARING, EVENT_COLLECT_STARTED, STATE_AUTH_PROCESSING,
372ea497e4dSopenharmony_ci        [&action](FiniteStateMachine &machine, uint32_t event) { action.Call(machine, event); });
373ea497e4dSopenharmony_ci    machineBuilder->MakeTransition(STATE_AUTH_PROCESSING, EVENT_USER_CANCEL, STATE_END,
374ea497e4dSopenharmony_ci        [&action](FiniteStateMachine &machine, uint32_t event) { action.Call(machine, event); });
375ea497e4dSopenharmony_ci
376ea497e4dSopenharmony_ci    machineBuilder->MakeOnStateEnter(STATE_INIT,
377ea497e4dSopenharmony_ci        [&enter](FiniteStateMachine &machine, uint32_t event) { enter.Call(machine, event); });
378ea497e4dSopenharmony_ci    machineBuilder->MakeOnStateLeave(STATE_INIT,
379ea497e4dSopenharmony_ci        [&leave](FiniteStateMachine &machine, uint32_t event) { leave.Call(machine, event); });
380ea497e4dSopenharmony_ci
381ea497e4dSopenharmony_ci    machineBuilder->MakeOnStateEnter(STATE_VERIFY_STARING,
382ea497e4dSopenharmony_ci        [&enter](FiniteStateMachine &machine, uint32_t event) { enter.Call(machine, event); });
383ea497e4dSopenharmony_ci    machineBuilder->MakeOnStateLeave(STATE_VERIFY_STARING,
384ea497e4dSopenharmony_ci        [&leave](FiniteStateMachine &machine, uint32_t event) { leave.Call(machine, event); });
385ea497e4dSopenharmony_ci
386ea497e4dSopenharmony_ci    machineBuilder->MakeOnStateEnter(STATE_COLLECT_STARING,
387ea497e4dSopenharmony_ci        [&enter](FiniteStateMachine &machine, uint32_t event) { enter.Call(machine, event); });
388ea497e4dSopenharmony_ci    machineBuilder->MakeOnStateLeave(STATE_COLLECT_STARING,
389ea497e4dSopenharmony_ci        [&leave](FiniteStateMachine &machine, uint32_t event) { leave.Call(machine, event); });
390ea497e4dSopenharmony_ci
391ea497e4dSopenharmony_ci    machineBuilder->MakeOnStateEnter(STATE_AUTH_PROCESSING,
392ea497e4dSopenharmony_ci        [&enter](FiniteStateMachine &machine, uint32_t event) { enter.Call(machine, event); });
393ea497e4dSopenharmony_ci    machineBuilder->MakeOnStateLeave(STATE_AUTH_PROCESSING,
394ea497e4dSopenharmony_ci        [&leave](FiniteStateMachine &machine, uint32_t event) { leave.Call(machine, event); });
395ea497e4dSopenharmony_ci
396ea497e4dSopenharmony_ci    machineBuilder->MakeOnStateEnter(STATE_END,
397ea497e4dSopenharmony_ci        [&enter](FiniteStateMachine &machine, uint32_t event) { enter.Call(machine, event); });
398ea497e4dSopenharmony_ci
399ea497e4dSopenharmony_ci    machine = machineBuilder->Build();
400ea497e4dSopenharmony_ci}
401ea497e4dSopenharmony_ci
402ea497e4dSopenharmony_ciHWTEST_F(StateMachineTest, MachineScheduleEnterAndLeave, TestSize.Level0)
403ea497e4dSopenharmony_ci{
404ea497e4dSopenharmony_ci    auto handler = ThreadHandler::GetSingleThreadInstance();
405ea497e4dSopenharmony_ci    MockFunction<void(FiniteStateMachine & machine, uint32_t event)> action;
406ea497e4dSopenharmony_ci    MockFunction<void(FiniteStateMachine & machine, uint32_t event)> enter;
407ea497e4dSopenharmony_ci    MockFunction<void(FiniteStateMachine & machine, uint32_t event)> leave;
408ea497e4dSopenharmony_ci
409ea497e4dSopenharmony_ci    InSequence s;
410ea497e4dSopenharmony_ci    EXPECT_CALL(action, Call(_, EVENT_START_AUTH));
411ea497e4dSopenharmony_ci    EXPECT_CALL(leave, Call(_, STATE_INIT));
412ea497e4dSopenharmony_ci    EXPECT_CALL(enter, Call(_, STATE_VERIFY_STARING));
413ea497e4dSopenharmony_ci
414ea497e4dSopenharmony_ci    EXPECT_CALL(action, Call(_, EVENT_VERIFY_STARTED));
415ea497e4dSopenharmony_ci    EXPECT_CALL(leave, Call(_, STATE_VERIFY_STARING));
416ea497e4dSopenharmony_ci    EXPECT_CALL(enter, Call(_, STATE_COLLECT_STARING));
417ea497e4dSopenharmony_ci
418ea497e4dSopenharmony_ci    EXPECT_CALL(action, Call(_, EVENT_COLLECT_STARTED));
419ea497e4dSopenharmony_ci    EXPECT_CALL(leave, Call(_, STATE_COLLECT_STARING));
420ea497e4dSopenharmony_ci    EXPECT_CALL(enter, Call(_, STATE_AUTH_PROCESSING));
421ea497e4dSopenharmony_ci
422ea497e4dSopenharmony_ci    EXPECT_CALL(action, Call(_, EVENT_USER_CANCEL));
423ea497e4dSopenharmony_ci    EXPECT_CALL(leave, Call(_, STATE_AUTH_PROCESSING));
424ea497e4dSopenharmony_ci    EXPECT_CALL(enter, Call(_, STATE_END));
425ea497e4dSopenharmony_ci
426ea497e4dSopenharmony_ci    std::shared_ptr<FiniteStateMachine> machine;
427ea497e4dSopenharmony_ci    GetTestMachine(machine, action, enter, leave);
428ea497e4dSopenharmony_ci    ASSERT_NE(machine, nullptr);
429ea497e4dSopenharmony_ci
430ea497e4dSopenharmony_ci    machine->SetThreadHandler(handler);
431ea497e4dSopenharmony_ci    handler->EnsureTask(nullptr);
432ea497e4dSopenharmony_ci    machine->Schedule(EVENT_START_AUTH);
433ea497e4dSopenharmony_ci    handler->EnsureTask(nullptr);
434ea497e4dSopenharmony_ci    machine->Schedule(EVENT_USER_CANCEL);
435ea497e4dSopenharmony_ci    EXPECT_EQ(STATE_END, machine->EnsureCurrentState());
436ea497e4dSopenharmony_ci
437ea497e4dSopenharmony_ci    handler->EnsureTask(nullptr);
438ea497e4dSopenharmony_ci}
439ea497e4dSopenharmony_ci} // namespace FaceAuth
440ea497e4dSopenharmony_ci} // namespace UserIam
441ea497e4dSopenharmony_ci} // namespace OHOS