xref: /aosp_15_r20/external/ot-br-posix/tests/gtest/test_async_task.cpp (revision 4a64e381480ef79f0532b2421e44e6ee336b8e0d)
1*4a64e381SAndroid Build Coastguard Worker /*
2*4a64e381SAndroid Build Coastguard Worker  *    Copyright (c) 2024, The OpenThread Authors.
3*4a64e381SAndroid Build Coastguard Worker  *    All rights reserved.
4*4a64e381SAndroid Build Coastguard Worker  *
5*4a64e381SAndroid Build Coastguard Worker  *    Redistribution and use in source and binary forms, with or without
6*4a64e381SAndroid Build Coastguard Worker  *    modification, are permitted provided that the following conditions are met:
7*4a64e381SAndroid Build Coastguard Worker  *    1. Redistributions of source code must retain the above copyright
8*4a64e381SAndroid Build Coastguard Worker  *       notice, this list of conditions and the following disclaimer.
9*4a64e381SAndroid Build Coastguard Worker  *    2. Redistributions in binary form must reproduce the above copyright
10*4a64e381SAndroid Build Coastguard Worker  *       notice, this list of conditions and the following disclaimer in the
11*4a64e381SAndroid Build Coastguard Worker  *       documentation and/or other materials provided with the distribution.
12*4a64e381SAndroid Build Coastguard Worker  *    3. Neither the name of the copyright holder nor the
13*4a64e381SAndroid Build Coastguard Worker  *       names of its contributors may be used to endorse or promote products
14*4a64e381SAndroid Build Coastguard Worker  *       derived from this software without specific prior written permission.
15*4a64e381SAndroid Build Coastguard Worker  *
16*4a64e381SAndroid Build Coastguard Worker  *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17*4a64e381SAndroid Build Coastguard Worker  *    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*4a64e381SAndroid Build Coastguard Worker  *    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*4a64e381SAndroid Build Coastguard Worker  *    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20*4a64e381SAndroid Build Coastguard Worker  *    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*4a64e381SAndroid Build Coastguard Worker  *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*4a64e381SAndroid Build Coastguard Worker  *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*4a64e381SAndroid Build Coastguard Worker  *    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*4a64e381SAndroid Build Coastguard Worker  *    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*4a64e381SAndroid Build Coastguard Worker  *    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*4a64e381SAndroid Build Coastguard Worker  *    POSSIBILITY OF SUCH DAMAGE.
27*4a64e381SAndroid Build Coastguard Worker  */
28*4a64e381SAndroid Build Coastguard Worker 
29*4a64e381SAndroid Build Coastguard Worker #include <gtest/gtest.h>
30*4a64e381SAndroid Build Coastguard Worker 
31*4a64e381SAndroid Build Coastguard Worker #include <memory>
32*4a64e381SAndroid Build Coastguard Worker #include <string>
33*4a64e381SAndroid Build Coastguard Worker 
34*4a64e381SAndroid Build Coastguard Worker #include <openthread/error.h>
35*4a64e381SAndroid Build Coastguard Worker 
36*4a64e381SAndroid Build Coastguard Worker #include "common/code_utils.hpp"
37*4a64e381SAndroid Build Coastguard Worker #include "ncp/async_task.hpp"
38*4a64e381SAndroid Build Coastguard Worker 
39*4a64e381SAndroid Build Coastguard Worker using otbr::Ncp::AsyncTask;
40*4a64e381SAndroid Build Coastguard Worker using otbr::Ncp::AsyncTaskPtr;
41*4a64e381SAndroid Build Coastguard Worker 
TEST(AsyncTask,TestOneStep)42*4a64e381SAndroid Build Coastguard Worker TEST(AsyncTask, TestOneStep)
43*4a64e381SAndroid Build Coastguard Worker {
44*4a64e381SAndroid Build Coastguard Worker     AsyncTaskPtr task;
45*4a64e381SAndroid Build Coastguard Worker     AsyncTaskPtr step1;
46*4a64e381SAndroid Build Coastguard Worker     int          resultHandlerCalledTimes = 0;
47*4a64e381SAndroid Build Coastguard Worker     int          stepCount                = 0;
48*4a64e381SAndroid Build Coastguard Worker 
49*4a64e381SAndroid Build Coastguard Worker     auto errorHandler = [&resultHandlerCalledTimes](otError aError, const std::string &aErrorInfo) {
50*4a64e381SAndroid Build Coastguard Worker         OTBR_UNUSED_VARIABLE(aError);
51*4a64e381SAndroid Build Coastguard Worker         OTBR_UNUSED_VARIABLE(aErrorInfo);
52*4a64e381SAndroid Build Coastguard Worker 
53*4a64e381SAndroid Build Coastguard Worker         resultHandlerCalledTimes++;
54*4a64e381SAndroid Build Coastguard Worker     };
55*4a64e381SAndroid Build Coastguard Worker 
56*4a64e381SAndroid Build Coastguard Worker     task = std::make_shared<AsyncTask>(errorHandler);
57*4a64e381SAndroid Build Coastguard Worker     task->First([&stepCount, &step1](AsyncTaskPtr aNext) {
58*4a64e381SAndroid Build Coastguard Worker         step1 = std::move(aNext);
59*4a64e381SAndroid Build Coastguard Worker         stepCount++;
60*4a64e381SAndroid Build Coastguard Worker     });
61*4a64e381SAndroid Build Coastguard Worker     task->Run();
62*4a64e381SAndroid Build Coastguard Worker 
63*4a64e381SAndroid Build Coastguard Worker     step1->SetResult(OT_ERROR_NONE, "Success");
64*4a64e381SAndroid Build Coastguard Worker 
65*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(resultHandlerCalledTimes, 1);
66*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(stepCount, 1);
67*4a64e381SAndroid Build Coastguard Worker }
68*4a64e381SAndroid Build Coastguard Worker 
TEST(AsyncTask,TestNoResultReturned)69*4a64e381SAndroid Build Coastguard Worker TEST(AsyncTask, TestNoResultReturned)
70*4a64e381SAndroid Build Coastguard Worker {
71*4a64e381SAndroid Build Coastguard Worker     AsyncTaskPtr task;
72*4a64e381SAndroid Build Coastguard Worker     AsyncTaskPtr step1;
73*4a64e381SAndroid Build Coastguard Worker     AsyncTaskPtr step2;
74*4a64e381SAndroid Build Coastguard Worker     AsyncTaskPtr step3;
75*4a64e381SAndroid Build Coastguard Worker 
76*4a64e381SAndroid Build Coastguard Worker     int     resultHandlerCalledTimes = 0;
77*4a64e381SAndroid Build Coastguard Worker     int     stepCount                = 0;
78*4a64e381SAndroid Build Coastguard Worker     otError error                    = OT_ERROR_NONE;
79*4a64e381SAndroid Build Coastguard Worker 
80*4a64e381SAndroid Build Coastguard Worker     auto errorHandler = [&resultHandlerCalledTimes, &error](otError aError, const std::string &aErrorInfo) {
81*4a64e381SAndroid Build Coastguard Worker         OTBR_UNUSED_VARIABLE(aErrorInfo);
82*4a64e381SAndroid Build Coastguard Worker 
83*4a64e381SAndroid Build Coastguard Worker         resultHandlerCalledTimes++;
84*4a64e381SAndroid Build Coastguard Worker         error = aError;
85*4a64e381SAndroid Build Coastguard Worker     };
86*4a64e381SAndroid Build Coastguard Worker 
87*4a64e381SAndroid Build Coastguard Worker     task = std::make_shared<AsyncTask>(errorHandler);
88*4a64e381SAndroid Build Coastguard Worker     task->First([&stepCount, &step1](AsyncTaskPtr aNext) {
89*4a64e381SAndroid Build Coastguard Worker             step1 = std::move(aNext);
90*4a64e381SAndroid Build Coastguard Worker             stepCount++;
91*4a64e381SAndroid Build Coastguard Worker         })
92*4a64e381SAndroid Build Coastguard Worker         ->Then([&stepCount, &step2](AsyncTaskPtr aNext) {
93*4a64e381SAndroid Build Coastguard Worker             step2 = std::move(aNext);
94*4a64e381SAndroid Build Coastguard Worker             stepCount++;
95*4a64e381SAndroid Build Coastguard Worker         })
96*4a64e381SAndroid Build Coastguard Worker         ->Then([&stepCount, &step3](AsyncTaskPtr aNext) {
97*4a64e381SAndroid Build Coastguard Worker             step3 = std::move(aNext);
98*4a64e381SAndroid Build Coastguard Worker             stepCount++;
99*4a64e381SAndroid Build Coastguard Worker         });
100*4a64e381SAndroid Build Coastguard Worker     task->Run();
101*4a64e381SAndroid Build Coastguard Worker 
102*4a64e381SAndroid Build Coastguard Worker     // Asyn task ends without calling 'SetResult'.
103*4a64e381SAndroid Build Coastguard Worker     step1 = nullptr;
104*4a64e381SAndroid Build Coastguard Worker     task  = nullptr;
105*4a64e381SAndroid Build Coastguard Worker 
106*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(resultHandlerCalledTimes, 1);
107*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(stepCount, 1);
108*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(error, OT_ERROR_FAILED);
109*4a64e381SAndroid Build Coastguard Worker }
110*4a64e381SAndroid Build Coastguard Worker 
TEST(AsyncTask,TestMultipleStepsSuccess)111*4a64e381SAndroid Build Coastguard Worker TEST(AsyncTask, TestMultipleStepsSuccess)
112*4a64e381SAndroid Build Coastguard Worker {
113*4a64e381SAndroid Build Coastguard Worker     AsyncTaskPtr task;
114*4a64e381SAndroid Build Coastguard Worker     AsyncTaskPtr step1;
115*4a64e381SAndroid Build Coastguard Worker     AsyncTaskPtr step2;
116*4a64e381SAndroid Build Coastguard Worker     AsyncTaskPtr step3;
117*4a64e381SAndroid Build Coastguard Worker 
118*4a64e381SAndroid Build Coastguard Worker     int     resultHandlerCalledTimes = 0;
119*4a64e381SAndroid Build Coastguard Worker     int     stepCount                = 0;
120*4a64e381SAndroid Build Coastguard Worker     otError error                    = OT_ERROR_NONE;
121*4a64e381SAndroid Build Coastguard Worker 
122*4a64e381SAndroid Build Coastguard Worker     auto errorHandler = [&resultHandlerCalledTimes, &error](otError aError, const std::string &aErrorInfo) {
123*4a64e381SAndroid Build Coastguard Worker         OTBR_UNUSED_VARIABLE(aErrorInfo);
124*4a64e381SAndroid Build Coastguard Worker 
125*4a64e381SAndroid Build Coastguard Worker         resultHandlerCalledTimes++;
126*4a64e381SAndroid Build Coastguard Worker         error = aError;
127*4a64e381SAndroid Build Coastguard Worker     };
128*4a64e381SAndroid Build Coastguard Worker 
129*4a64e381SAndroid Build Coastguard Worker     task = std::make_shared<AsyncTask>(errorHandler);
130*4a64e381SAndroid Build Coastguard Worker     task->First([&stepCount, &step1](AsyncTaskPtr aNext) {
131*4a64e381SAndroid Build Coastguard Worker             step1 = std::move(aNext);
132*4a64e381SAndroid Build Coastguard Worker             stepCount++;
133*4a64e381SAndroid Build Coastguard Worker         })
134*4a64e381SAndroid Build Coastguard Worker         ->Then([&stepCount, &step2](AsyncTaskPtr aNext) {
135*4a64e381SAndroid Build Coastguard Worker             step2 = std::move(aNext);
136*4a64e381SAndroid Build Coastguard Worker             stepCount++;
137*4a64e381SAndroid Build Coastguard Worker         })
138*4a64e381SAndroid Build Coastguard Worker         ->Then([&stepCount, &step3](AsyncTaskPtr aNext) {
139*4a64e381SAndroid Build Coastguard Worker             step3 = std::move(aNext);
140*4a64e381SAndroid Build Coastguard Worker             stepCount++;
141*4a64e381SAndroid Build Coastguard Worker         });
142*4a64e381SAndroid Build Coastguard Worker     task->Run();
143*4a64e381SAndroid Build Coastguard Worker 
144*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(stepCount, 1);
145*4a64e381SAndroid Build Coastguard Worker     step1->SetResult(OT_ERROR_NONE, "");
146*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(resultHandlerCalledTimes, 0);
147*4a64e381SAndroid Build Coastguard Worker 
148*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(stepCount, 2);
149*4a64e381SAndroid Build Coastguard Worker     step2->SetResult(OT_ERROR_NONE, "");
150*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(resultHandlerCalledTimes, 0);
151*4a64e381SAndroid Build Coastguard Worker 
152*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(stepCount, 3);
153*4a64e381SAndroid Build Coastguard Worker     error = OT_ERROR_GENERIC;
154*4a64e381SAndroid Build Coastguard Worker     step3->SetResult(OT_ERROR_NONE, "");
155*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(resultHandlerCalledTimes, 1);
156*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(error, OT_ERROR_NONE);
157*4a64e381SAndroid Build Coastguard Worker }
158*4a64e381SAndroid Build Coastguard Worker 
TEST(AsyncTask,TestMultipleStepsFailedHalfWay)159*4a64e381SAndroid Build Coastguard Worker TEST(AsyncTask, TestMultipleStepsFailedHalfWay)
160*4a64e381SAndroid Build Coastguard Worker {
161*4a64e381SAndroid Build Coastguard Worker     AsyncTaskPtr task;
162*4a64e381SAndroid Build Coastguard Worker     AsyncTaskPtr step1;
163*4a64e381SAndroid Build Coastguard Worker     AsyncTaskPtr step2;
164*4a64e381SAndroid Build Coastguard Worker     AsyncTaskPtr step3;
165*4a64e381SAndroid Build Coastguard Worker 
166*4a64e381SAndroid Build Coastguard Worker     int     resultHandlerCalledTimes = 0;
167*4a64e381SAndroid Build Coastguard Worker     int     stepCount                = 0;
168*4a64e381SAndroid Build Coastguard Worker     otError error                    = OT_ERROR_NONE;
169*4a64e381SAndroid Build Coastguard Worker 
170*4a64e381SAndroid Build Coastguard Worker     auto errorHandler = [&resultHandlerCalledTimes, &error](otError aError, const std::string &aErrorInfo) {
171*4a64e381SAndroid Build Coastguard Worker         OTBR_UNUSED_VARIABLE(aErrorInfo);
172*4a64e381SAndroid Build Coastguard Worker 
173*4a64e381SAndroid Build Coastguard Worker         resultHandlerCalledTimes++;
174*4a64e381SAndroid Build Coastguard Worker         error = aError;
175*4a64e381SAndroid Build Coastguard Worker     };
176*4a64e381SAndroid Build Coastguard Worker 
177*4a64e381SAndroid Build Coastguard Worker     task = std::make_shared<AsyncTask>(errorHandler);
178*4a64e381SAndroid Build Coastguard Worker     task->First([&stepCount, &step1](AsyncTaskPtr aNext) {
179*4a64e381SAndroid Build Coastguard Worker             step1 = std::move(aNext);
180*4a64e381SAndroid Build Coastguard Worker             stepCount++;
181*4a64e381SAndroid Build Coastguard Worker         })
182*4a64e381SAndroid Build Coastguard Worker         ->Then([&stepCount, &step2](AsyncTaskPtr aNext) {
183*4a64e381SAndroid Build Coastguard Worker             step2 = std::move(aNext);
184*4a64e381SAndroid Build Coastguard Worker             stepCount++;
185*4a64e381SAndroid Build Coastguard Worker         })
186*4a64e381SAndroid Build Coastguard Worker         ->Then([&stepCount, &step3](AsyncTaskPtr aNext) {
187*4a64e381SAndroid Build Coastguard Worker             step3 = std::move(aNext);
188*4a64e381SAndroid Build Coastguard Worker             stepCount++;
189*4a64e381SAndroid Build Coastguard Worker         });
190*4a64e381SAndroid Build Coastguard Worker     task->Run();
191*4a64e381SAndroid Build Coastguard Worker 
192*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(stepCount, 1);
193*4a64e381SAndroid Build Coastguard Worker     step1->SetResult(OT_ERROR_NONE, "");
194*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(resultHandlerCalledTimes, 0);
195*4a64e381SAndroid Build Coastguard Worker 
196*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(stepCount, 2);
197*4a64e381SAndroid Build Coastguard Worker     step2->SetResult(OT_ERROR_BUSY, "");
198*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(resultHandlerCalledTimes, 1);
199*4a64e381SAndroid Build Coastguard Worker     EXPECT_EQ(error, OT_ERROR_BUSY);
200*4a64e381SAndroid Build Coastguard Worker }
201