1 /*
2 * Copyright (c) 2022 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 #include <chrono>
16 #include <thread>
17 #include <gtest/gtest.h>
18
19 #include "service_control.h"
20 #include "beget_ext.h"
21 #include "test_utils.h"
22
23 using namespace testing::ext;
24 namespace initModuleTest {
25 namespace {
26 // Default wait for service status change time is 10 seconds
27 constexpr int WAIT_SERVICE_STATUS_TIMEOUT = 10;
28 }
29
30 class ServiceControlTest : public testing::Test {
31 public:
SetUpTestCase()32 static void SetUpTestCase() {};
TearDownTestCase()33 static void TearDownTestCase() {};
SetUp()34 void SetUp() {};
TearDown()35 void TearDown() {};
36 };
37
38 // Test service start
HWTEST_F(ServiceControlTest, ServiceStartTest, TestSize.Level1)39 HWTEST_F(ServiceControlTest, ServiceStartTest, TestSize.Level1)
40 {
41 // Pick an unusual service for testing
42 // Try to start media_service.
43
44 // 1) Check if media_service exist
45 std::string serviceName = "media_service";
46 auto status = GetServiceStatus(serviceName);
47 if (status == "running") {
48 int ret = ServiceControl(serviceName.c_str(), STOP);
49 ASSERT_EQ(ret, 0);
50 ret = ServiceWaitForStatus(serviceName.c_str(), SERVICE_STOPPED, WAIT_SERVICE_STATUS_TIMEOUT);
51 ASSERT_EQ(ret, 0);
52 } else if (status != "created" && status != "stopped") {
53 std::cout << serviceName << " in invalid status " << status << std::endl;
54 std::cout << "Debug " << serviceName << " in unexpected status " << status << std::endl;
55 ASSERT_TRUE(0);
56 }
57
58 // 2) Now try to start service
59 int ret = ServiceControl(serviceName.c_str(), START);
60 EXPECT_EQ(ret, 0);
61 ret = ServiceWaitForStatus(serviceName.c_str(), SERVICE_STARTED, WAIT_SERVICE_STATUS_TIMEOUT);
62 EXPECT_EQ(ret, 0);
63 status = GetServiceStatus(serviceName);
64 std::cout << "Debug " << serviceName << " in status " << status << std::endl;
65 EXPECT_TRUE(status == "running");
66 }
67
HWTEST_F(ServiceControlTest, NonExistServiceStartTest, TestSize.Level1)68 HWTEST_F(ServiceControlTest, NonExistServiceStartTest, TestSize.Level1)
69 {
70 std::string serviceName = "non_exist_service";
71 int ret = ServiceControl(serviceName.c_str(), START);
72 EXPECT_EQ(ret, 0); // No matter if service exist or not, ServiceControl always success.
73
74 auto status = GetServiceStatus(serviceName);
75 EXPECT_TRUE(status == "idle");
76 }
77
HWTEST_F(ServiceControlTest, ServiceStopTest, TestSize.Level1)78 HWTEST_F(ServiceControlTest, ServiceStopTest, TestSize.Level1)
79 {
80 std::string serviceName = "media_service";
81 auto status = GetServiceStatus(serviceName);
82 if (status == "stopped" || status == "created") {
83 int ret = ServiceControl(serviceName.c_str(), START);
84 ASSERT_EQ(ret, 0); // start must be success
85
86 } else if (status != "running") {
87 std::cout << serviceName << " in invalid status " << status << std::endl;
88 ASSERT_TRUE(0);
89 }
90
91 int ret = ServiceControl(serviceName.c_str(), STOP);
92 EXPECT_EQ(ret, 0);
93 // Sleep for a while, let init handle service starting.
94 const int64_t ms = 500;
95 std::this_thread::sleep_for(std::chrono::milliseconds(ms));
96 status = GetServiceStatus(serviceName);
97 bool isStopped = status == "stopped";
98 EXPECT_TRUE(isStopped);
99 }
100
HWTEST_F(ServiceControlTest, NonExistServiceStopTest, TestSize.Level1)101 HWTEST_F(ServiceControlTest, NonExistServiceStopTest, TestSize.Level1)
102 {
103 std::string serviceName = "non_exist_service";
104 int ret = ServiceControl(serviceName.c_str(), STOP);
105 EXPECT_EQ(ret, 0); // No matter if service exist or not, ServiceControl always success.
106
107 auto status = GetServiceStatus(serviceName);
108 EXPECT_TRUE(status == "idle");
109 }
110
HWTEST_F(ServiceControlTest, ServiceTimerStartTest, TestSize.Level1)111 HWTEST_F(ServiceControlTest, ServiceTimerStartTest, TestSize.Level1)
112 {
113 uint64_t timeout = 1000; // Start service in 1 second
114 std::string serviceName = "media_service";
115 // stop this service first
116 int ret = ServiceControl(serviceName.c_str(), STOP);
117 auto oldStatus = GetServiceStatus(serviceName);
118 bool isRunning = oldStatus == "running";
119 EXPECT_FALSE(isRunning);
120
121 ret = StartServiceByTimer(serviceName.c_str(), timeout);
122 EXPECT_EQ(ret, 0);
123
124 // Service will be started in @timeout seconds
125 // Now we try to sleep about @timeout / 2 seconds, then check service status.
126 int64_t ms = 600;
127 std::this_thread::sleep_for(std::chrono::milliseconds(ms));
128 // Get service status.
129 auto newStatus = GetServiceStatus(serviceName);
130 bool notChange = oldStatus == newStatus;
131 EXPECT_TRUE(notChange);
132
133 std::this_thread::sleep_for(std::chrono::milliseconds(ms));
134 newStatus = GetServiceStatus(serviceName);
135
136 isRunning = newStatus == "running";
137 EXPECT_TRUE(isRunning);
138 }
139
HWTEST_F(ServiceControlTest, ServiceTimerStartContinuouslyTest, TestSize.Level1)140 HWTEST_F(ServiceControlTest, ServiceTimerStartContinuouslyTest, TestSize.Level1)
141 {
142 uint64_t oldTimeout = 500;
143 uint64_t newTimeout = 1000;
144 std::string serviceName = "media_service";
145 int ret = ServiceControl(serviceName.c_str(), STOP);
146 EXPECT_EQ(ret, 0);
147 ret = ServiceWaitForStatus(serviceName.c_str(), SERVICE_STOPPED, WAIT_SERVICE_STATUS_TIMEOUT);
148 EXPECT_EQ(ret, 0);
149 auto oldStatus = GetServiceStatus(serviceName);
150 bool isRunning = oldStatus == "running";
151 EXPECT_FALSE(isRunning);
152
153 ret = StartServiceByTimer(serviceName.c_str(), oldTimeout); // Set timer as 500 ms
154 EXPECT_EQ(ret, 0);
155 ret = StartServiceByTimer(serviceName.c_str(), newTimeout); // Set timer as 1 second
156 EXPECT_EQ(ret, 0);
157
158 std::this_thread::sleep_for(std::chrono::milliseconds(static_cast<int64_t>(oldTimeout)));
159 auto newStatus = GetServiceStatus(serviceName);
160 bool notChange = oldStatus == newStatus;
161 EXPECT_TRUE(notChange);
162 uint64_t margin = 20; // 20 ms margin in case of timer not that precisely
163 std::this_thread::sleep_for(std::chrono::milliseconds(static_cast<int64_t>(oldTimeout + margin)));
164 newStatus = GetServiceStatus(serviceName);
165 isRunning = newStatus == "running";
166 EXPECT_TRUE(isRunning);
167 }
168
HWTEST_F(ServiceControlTest, ServiceTimerStopTest, TestSize.Level1)169 HWTEST_F(ServiceControlTest, ServiceTimerStopTest, TestSize.Level1)
170 {
171 uint64_t timeout = 1000; // set timer as 1 second
172 std::string serviceName = "media_service";
173 int ret = ServiceControl(serviceName.c_str(), STOP);
174 EXPECT_EQ(ret, 0);
175 ret = ServiceWaitForStatus(serviceName.c_str(), SERVICE_STOPPED, WAIT_SERVICE_STATUS_TIMEOUT);
176 EXPECT_EQ(ret, 0);
177 auto oldStatus = GetServiceStatus(serviceName);
178 bool isRunning = oldStatus == "running";
179 EXPECT_FALSE(isRunning);
180
181 ret = StartServiceByTimer(serviceName.c_str(), timeout);
182 EXPECT_EQ(ret, 0);
183
184 // Now sleep for a while
185 int64_t ms = 300;
186 std::this_thread::sleep_for(std::chrono::milliseconds(ms));
187 auto newStatus = GetServiceStatus(serviceName);
188
189 bool notChange = oldStatus == newStatus;
190 EXPECT_TRUE(notChange);
191
192 ret = StopServiceTimer(serviceName.c_str());
193 EXPECT_EQ(ret, 0);
194 std::this_thread::sleep_for(std::chrono::milliseconds(ms));
195
196 newStatus = GetServiceStatus(serviceName);
197 notChange = oldStatus == newStatus;
198 EXPECT_TRUE(notChange);
199 }
200
HWTEST_F(ServiceControlTest, ServiceTimerStopLateTest, TestSize.Level1)201 HWTEST_F(ServiceControlTest, ServiceTimerStopLateTest, TestSize.Level1)
202 {
203 uint64_t timeout = 500; // set timer as 5 micro seconds
204 std::string serviceName = "media_service";
205 int ret = ServiceControl(serviceName.c_str(), STOP);
206 auto oldStatus = GetServiceStatus(serviceName);
207 bool isRunning = oldStatus == "running";
208 EXPECT_FALSE(isRunning);
209
210 ret = StartServiceByTimer(serviceName.c_str(), timeout);
211 EXPECT_EQ(ret, 0);
212
213 int64_t ms = 550;
214 std::this_thread::sleep_for(std::chrono::milliseconds(ms));
215 ret = StopServiceTimer(serviceName.c_str());
216 EXPECT_EQ(ret, 0);
217
218 auto newStatus = GetServiceStatus(serviceName);
219 isRunning = newStatus == "running";
220 EXPECT_TRUE(isRunning);
221 }
222
HWTEST_F(ServiceControlTest, RestartServiceTest, TestSize.Level1)223 HWTEST_F(ServiceControlTest, RestartServiceTest, TestSize.Level1)
224 {
225 std::string serviceName = "media_service";
226 auto status = GetServiceStatus(serviceName);
227 EXPECT_FALSE(status.empty());
228
229 int ret = ServiceControl(serviceName.c_str(), RESTART);
230 EXPECT_EQ(ret, 0);
231
232 ret = ServiceControl(serviceName.c_str(), STOP);
233 EXPECT_EQ(ret, 0);
234
235 ret = ServiceWaitForStatus(serviceName.c_str(), SERVICE_STOPPED, WAIT_SERVICE_STATUS_TIMEOUT);
236 EXPECT_EQ(ret, 0);
237
238 ret = ServiceControl(serviceName.c_str(), RESTART);
239 EXPECT_EQ(ret, 0);
240
241 status = GetServiceStatus(serviceName);
242
243 bool isRunning = status == "running";
244 EXPECT_TRUE(isRunning);
245 }
246
HWTEST_F(ServiceControlTest, WaitForServiceStatusTest, TestSize.Level1)247 HWTEST_F(ServiceControlTest, WaitForServiceStatusTest, TestSize.Level1)
248 {
249 std::string serviceName = "media_service";
250 int ret = ServiceControl(serviceName.c_str(), STOP);
251 EXPECT_EQ(ret, 0);
252
253 ret = ServiceWaitForStatus(serviceName.c_str(), SERVICE_STOPPED, WAIT_SERVICE_STATUS_TIMEOUT);
254 EXPECT_EQ(ret, 0);
255
256 auto status = GetServiceStatus(serviceName);
257 bool isStopped = status == "stopped";
258 EXPECT_TRUE(isStopped);
259
260 // service is stopped now. try to wait a status which will not be set
261 std::cout << "Wait for service " << serviceName << " status change to start\n";
262 ret = ServiceWaitForStatus(serviceName.c_str(), SERVICE_STARTED, WAIT_SERVICE_STATUS_TIMEOUT);
263 BEGET_ERROR_CHECK(ret == -1, return, "Get media_service status failed.");
264
265 serviceName = "non-exist-service";
266 std::cout << "Wait for service " << serviceName << " status change to stop\n";
267 ret = ServiceWaitForStatus(serviceName.c_str(), SERVICE_STOPPED, WAIT_SERVICE_STATUS_TIMEOUT);
268 EXPECT_EQ(ret, -1);
269 }
270 } // initModuleTest
271