1 /*
2 * Copyright (c) 2023 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 "async_shutdown_callback_test.h"
17
18 #include <condition_variable>
19 #include <future>
20 #include <mutex>
21 #include "power_log.h"
22 #include "power_mgr_client.h"
23 #include "power_mgr_service.h"
24 #include "shutdown/shutdown_client.h"
25
26 #include "mock_power_action.h"
27 #include "mock_state_action.h"
28
29 namespace OHOS {
30 namespace PowerMgr {
31 namespace UnitTest {
32 namespace {
33 sptr<PowerMgrService> g_service = nullptr;
34 MockPowerAction* g_mockPowerAction = nullptr;
35 MockStateAction* g_mockStateAction = nullptr;
36 std::condition_variable g_cv;
37 std::mutex g_mtx;
38 bool g_isHighPriority = false;
39 bool g_isDefaultPriority = false;
40 bool g_isLowPriority = false;
41 const int32_t TIMEOUT_SEC = 5;
42 }
43 using namespace testing::ext;
44 using namespace std;
SetUpTestCase()45 void AsyncShutdownCallbackTest::SetUpTestCase()
46 {
47 // create singleton service object at the beginning
48 g_service = DelayedSpSingleton<PowerMgrService>::GetInstance();
49 g_service->OnStart();
50 }
51
TearDownTestCase()52 void AsyncShutdownCallbackTest::TearDownTestCase()
53 {
54 g_service->OnStop();
55 DelayedSpSingleton<PowerMgrService>::DestroyInstance();
56 }
57
SetUp()58 void AsyncShutdownCallbackTest::SetUp()
59 {
60 g_isHighPriority = false;
61 g_isDefaultPriority = false;
62 g_isLowPriority = false;
63 g_mockPowerAction = new MockPowerAction();
64 g_mockStateAction = new MockStateAction();
65 auto shutdownController = g_service->GetShutdownController();
66 if (shutdownController->IsShuttingDown()) {
67 // wait for detached threads to finish before next testcase
68 sleep(1);
69 }
70 shutdownController->EnableMock(g_mockPowerAction, g_mockStateAction);
71 }
72
TearDown()73 void AsyncShutdownCallbackTest::TearDown()
74 {}
75
OnAsyncShutdown()76 void AsyncShutdownCallbackTest::AsyncShutdownCallback::OnAsyncShutdown()
77 {
78 g_isDefaultPriority = true;
79 g_cv.notify_one();
80 }
81
OnAsyncShutdown()82 void AsyncShutdownCallbackTest::HighPriorityAsyncShutdownCallback::OnAsyncShutdown()
83 {
84 g_isHighPriority = true;
85 g_cv.notify_one();
86 }
87
OnAsyncShutdown()88 void AsyncShutdownCallbackTest::LowPriorityAsyncShutdownCallback::OnAsyncShutdown()
89 {
90 g_isLowPriority = true;
91 g_cv.notify_one();
92 }
93
OnAsyncShutdown()94 void AsyncShutdownCallbackTest::NotAsyncShutdownCallback::OnAsyncShutdown()
95 {
96 }
97
OnAsyncShutdownOrReboot(bool isReboot)98 void AsyncShutdownCallbackTest::AsyncShutdownOrRebootCallback::OnAsyncShutdownOrReboot(bool isReboot)
99 {
100 g_isDefaultPriority = true;
101 g_cv.notify_one();
102 }
103
OnAsyncShutdownOrReboot(bool isReboot)104 void AsyncShutdownCallbackTest::HighPriorityAsyncShutdownOrRebootCallback::OnAsyncShutdownOrReboot(bool isReboot)
105 {
106 g_isHighPriority = true;
107 g_cv.notify_one();
108 }
109
OnAsyncShutdownOrReboot(bool isReboot)110 void AsyncShutdownCallbackTest::LowPriorityAsyncShutdownOrRebootCallback::OnAsyncShutdownOrReboot(bool isReboot)
111 {
112 g_isLowPriority = true;
113 g_cv.notify_one();
114 }
115
OnAsyncShutdownOrReboot(bool isReboot)116 void AsyncShutdownCallbackTest::NotAsyncShutdownOrRebootCallback::OnAsyncShutdownOrReboot(bool isReboot)
117 {
118 }
119
WaitingCallback(bool & isPriority)120 static bool WaitingCallback(bool &isPriority)
121 {
122 std::unique_lock<std::mutex> lck(g_mtx);
123 auto callbackStart = [&]() {
124 while (!isPriority) {
125 g_cv.wait(lck);
126 }
127 };
128
129 packaged_task<void()> callbackTask(callbackStart);
130 future<void> fut = callbackTask.get_future();
131 make_unique<thread>(std::move(callbackTask))->detach();
132 future_status status = fut.wait_for(std::chrono::seconds(TIMEOUT_SEC));
133 if (status == future_status::timeout) {
134 return false;
135 }
136 return true;
137 }
138
139 /**
140 * @tc.name: AsyncShutdownCallbackk001
141 * @tc.desc: Test asynchronous shutdown callback for shutdown and reboot
142 * @tc.type: FUNC
143 */
144 HWTEST_F(AsyncShutdownCallbackTest, AsyncShutdownCallbackk001, TestSize.Level0)
145 {
146 POWER_HILOGI(LABEL_TEST, "AsyncShutdownCallbackk001 start");
147 auto callback = new AsyncShutdownCallback();
148 g_service->RegisterShutdownCallback(callback, ShutdownPriority::DEFAULT);
149 auto callback2 = new AsyncShutdownOrRebootCallback();
150 g_service->RegisterShutdownCallback(callback2, ShutdownPriority::DEFAULT);
151
152 g_service->RebootDevice("test_reboot");
153 EXPECT_TRUE(WaitingCallback(g_isDefaultPriority));
154
155 g_service->ShutDownDevice("test_shutdown");
156 EXPECT_TRUE(WaitingCallback(g_isDefaultPriority));
157 POWER_HILOGI(LABEL_TEST, "AsyncShutdownCallback001 end");
158 }
159
160 /**
161 * @tc.name: AsyncShutdownCallbackk002
162 * @tc.desc: Test the low and default priority of asynchronous shutdown callback
163 * @tc.type: FUNC
164 */
165 HWTEST_F(AsyncShutdownCallbackTest, AsyncShutdownCallbackk002, TestSize.Level0)
166 {
167 POWER_HILOGI(LABEL_TEST, "AsyncShutdownCallbackk002 start");
168 auto lowPriorityCallback = new LowPriorityAsyncShutdownCallback();
169 g_service->RegisterShutdownCallback(lowPriorityCallback, ShutdownPriority::LOW);
170 auto defaultPriorityCallback = new AsyncShutdownCallback();
171 g_service->RegisterShutdownCallback(defaultPriorityCallback, ShutdownPriority::DEFAULT);
172
173 g_service->ShutDownDevice("test_shutdown");
174 EXPECT_TRUE(WaitingCallback(g_isDefaultPriority));
175 EXPECT_TRUE(WaitingCallback(g_isLowPriority));
176 POWER_HILOGI(LABEL_TEST, "AsyncShutdownCallbackk002 end");
177 }
178
179 /**
180 * @tc.name: AsyncShutdownCallbackk003
181 * @tc.desc: Test the low and high priority of asynchronous shutdown callback
182 * @tc.type: FUNC
183 */
184 HWTEST_F(AsyncShutdownCallbackTest, AsyncShutdownCallbackk003, TestSize.Level0)
185 {
186 POWER_HILOGI(LABEL_TEST, "AsyncShutdownCallbackk003 start");
187 auto lowPriorityCallback = new LowPriorityAsyncShutdownCallback();
188 g_service->RegisterShutdownCallback(lowPriorityCallback, ShutdownPriority::LOW);
189 auto highPriorityCallback = new HighPriorityAsyncShutdownCallback();
190 g_service->RegisterShutdownCallback(highPriorityCallback, ShutdownPriority::HIGH);
191
192 g_service->ShutDownDevice("test_shutdown");
193 EXPECT_TRUE(WaitingCallback(g_isHighPriority));
194 EXPECT_TRUE(WaitingCallback(g_isLowPriority));
195 POWER_HILOGI(LABEL_TEST, "AsyncShutdownCallbackk003 end");
196 }
197
198 /**
199 * @tc.name: AsyncShutdownCallback004
200 * @tc.desc: Test the default and high priority of asynchronous shutdown callback
201 * @tc.type: FUNC
202 */
203 HWTEST_F(AsyncShutdownCallbackTest, AsyncShutdownCallback004, TestSize.Level0)
204 {
205 POWER_HILOGI(LABEL_TEST, "AsyncShutdownCallback004 start");
206 auto defaultPriorityCallback = new AsyncShutdownCallback();
207 g_service->RegisterShutdownCallback(defaultPriorityCallback, ShutdownPriority::DEFAULT);
208 auto highPriorityCallback = new HighPriorityAsyncShutdownCallback();
209 g_service->RegisterShutdownCallback(highPriorityCallback, ShutdownPriority::HIGH);
210
211 g_service->ShutDownDevice("test_shutdown");
212 EXPECT_TRUE(WaitingCallback(g_isHighPriority));
213 EXPECT_TRUE(WaitingCallback(g_isDefaultPriority));
214 POWER_HILOGI(LABEL_TEST, "AsyncShutdownCallback004 end");
215 }
216
217 /**
218 * @tc.name: AsyncShutdownCallback005
219 * @tc.desc: Test do not asynchronous shutdown
220 * @tc.type: FUNC
221 */
222 HWTEST_F(AsyncShutdownCallbackTest, AsyncShutdownCallback005, TestSize.Level0)
223 {
224 POWER_HILOGI(LABEL_TEST, "AsyncShutdownCallback005 start");
225 auto notAsyncCallback = new NotAsyncShutdownCallback();
226 g_service->RegisterShutdownCallback(notAsyncCallback, ShutdownPriority::DEFAULT);
227
228 EXPECT_CALL(*g_mockPowerAction, Reboot(std::string("test_reboot"))).Times(1);
229 g_service->RebootDevice("test_reboot");
230
231 EXPECT_CALL(*g_mockPowerAction, Shutdown(std::string("test_shutdown"))).Times(1);
232 g_service->ShutDownDevice("test_shutdown");
233
234 // wait for detached threads to finish
235 sleep(1);
236 POWER_HILOGI(LABEL_TEST, "AsyncShutdownCallback005 end");
237 }
238 } // namespace UnitTest
239 } // namespace PowerMgr
240 } // namespace OHOS
241