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
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 
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 
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 
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 
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 
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 
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 
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 
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 
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