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