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