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 
16 #include "task_scheduler.h"
17 
18 #include <gtest/gtest.h>
19 
20 #include "block_data.h"
21 namespace OHOS::Test {
22 using namespace testing::ext;
23 using namespace OHOS;
24 using duration = std::chrono::steady_clock::duration;
25 class TaskSchedulerTest : public testing::Test {
26 public:
27     static constexpr uint32_t SHORT_INTERVAL = 100; // ms
28     static constexpr uint32_t LONG_INTERVAL = 1;    // s
SetUpTestCase(void)29     static void SetUpTestCase(void){};
TearDownTestCase(void)30     static void TearDownTestCase(void){};
SetUp()31     void SetUp(){};
TearDown()32     void TearDown() {}
33 };
34 
35 /**
36 * @tc.name: At
37 * @tc.desc:
38 * @tc.type: FUNC
39 * @tc.require:
40 * @tc.author: ht
41 */
42 HWTEST_F(TaskSchedulerTest, At, TestSize.Level0)
43 {
44     TaskScheduler taskScheduler("atTest");
45     auto expiredTime = std::chrono::steady_clock::now() + std::chrono::milliseconds(SHORT_INTERVAL);
46     int testData = 10;
47     auto blockData = std::make_shared<BlockData<int>>(LONG_INTERVAL, testData);
__anon38b05aad0102() 48     auto atTaskId1 = taskScheduler.At(expiredTime, [blockData]() {
49         int testData = 11;
50         blockData->SetValue(testData);
51     });
52     ASSERT_EQ(blockData->GetValue(), 11);
53     blockData->Clear();
54     expiredTime = std::chrono::steady_clock::now() + std::chrono::milliseconds(SHORT_INTERVAL);
__anon38b05aad0202() 55     auto atTaskId2 = taskScheduler.At(expiredTime, [blockData]() {
56         int testData = 12;
57         blockData->SetValue(testData);
58     });
59     ASSERT_EQ(blockData->GetValue(), 12);
60     ASSERT_NE(atTaskId1, atTaskId2);
61 }
62 
63 /**
64 * @tc.name: Every
65 * @tc.desc:execute task periodically with duration
66 * @tc.type: FUNC
67 * @tc.require:
68 * @tc.author: ht
69 */
70 HWTEST_F(TaskSchedulerTest, ExecuteDuration, TestSize.Level0)
71 {
72     TaskScheduler taskScheduler("everyTest");
73     auto blockData = std::make_shared<BlockData<int>>(LONG_INTERVAL, 0);
74     int testData = 0;
__anon38b05aad0302() 75     taskScheduler.Every(std::chrono::milliseconds(SHORT_INTERVAL), [blockData, &testData]() {
76         testData++;
77         blockData->SetValue(testData);
78     });
79     for (int i = 1; i < 10; ++i) {
80         ASSERT_EQ(blockData->GetValue(), i);
81         blockData->Clear(0);
82     }
83 }
84 
85 /**
86 * @tc.name: Reset
87 * @tc.desc: Reset before task execution and the task is tasks_.begin() or not
88 * @tc.type: FUNC
89 * @tc.require:
90 * @tc.author: ht
91 */
92 HWTEST_F(TaskSchedulerTest, Reset1, TestSize.Level0)
93 {
94     TaskScheduler taskScheduler("reset1Test");
95     auto expiredTime = std::chrono::steady_clock::now() + std::chrono::milliseconds(SHORT_INTERVAL);
__anon38b05aad0402() 96     auto atTaskId1 = taskScheduler.At(expiredTime, []() {});
97     ASSERT_EQ(atTaskId1, 1);
98     expiredTime += std::chrono::milliseconds(LONG_INTERVAL);
__anon38b05aad0502() 99     auto atTaskId2 = taskScheduler.At(expiredTime, []() {});
100     ASSERT_EQ(atTaskId2, 2);
101 
102     auto resetTaskId1 = taskScheduler.Reset(atTaskId1, std::chrono::milliseconds(SHORT_INTERVAL));
103     ASSERT_EQ(resetTaskId1, atTaskId1);
104 
105     auto resetTaskId2 = taskScheduler.Reset(atTaskId2, std::chrono::milliseconds(SHORT_INTERVAL));
106     ASSERT_EQ(resetTaskId2, atTaskId2);
107 }
108 
109 /**
110 * @tc.name: Reset
111 * @tc.desc: Reset during task execution
112 * @tc.type: FUNC
113 * @tc.require:
114 * @tc.author: ht
115 */
116 HWTEST_F(TaskSchedulerTest, Reset2, TestSize.Level0)
117 {
118     TaskScheduler taskScheduler("reset2Test");
119     int testData = 10;
120     auto blockData = std::make_shared<BlockData<int>>(LONG_INTERVAL, testData);
121     auto expiredTime = std::chrono::steady_clock::now();
__anon38b05aad0602() 122     auto atTaskId = taskScheduler.At(expiredTime, [blockData]() {
123         blockData->GetValue();
124     });
125     ASSERT_EQ(atTaskId, 1);
126     std::this_thread::sleep_for(std::chrono::milliseconds(SHORT_INTERVAL));
127     auto resetTaskId = taskScheduler.Reset(atTaskId, std::chrono::milliseconds(0));
128     ASSERT_EQ(resetTaskId, TaskScheduler::INVALID_TASK_ID);
129     blockData->SetValue(testData);
130 }
131 
132 /**
133 * @tc.name: Reset
134 * @tc.desc: Reset after task execution
135 * @tc.type: FUNC
136 * @tc.require:
137 * @tc.author: ht
138 */
139 HWTEST_F(TaskSchedulerTest, Reset3, TestSize.Level0)
140 {
141     TaskScheduler taskScheduler("reset3Test");
142     auto expiredTime = std::chrono::steady_clock::now();
143     int testData = 10;
144     auto blockData = std::make_shared<BlockData<int>>(LONG_INTERVAL, testData);
__anon38b05aad0702() 145     auto atTaskId = taskScheduler.At(expiredTime, [blockData]() {
146         blockData->GetValue();
147     });
148     ASSERT_EQ(atTaskId, 1);
149     blockData->SetValue(testData);
150     blockData->SetValue(testData);
151     ASSERT_EQ(blockData->GetValue(), testData);
152     std::this_thread::sleep_for(std::chrono::milliseconds(SHORT_INTERVAL));
153     auto resetTaskId = taskScheduler.Reset(atTaskId, std::chrono::milliseconds(0));
154     ASSERT_EQ(resetTaskId, TaskScheduler::INVALID_TASK_ID);
155 }
156 
157 /**
158 * @tc.name: Every
159 * @tc.desc: execute task for some times periodically with duration.
160 * @tc.type: FUNC
161 * @tc.require:
162 * @tc.author: zuojiangjiang
163 */
164 HWTEST_F(TaskSchedulerTest, EveryExecuteTimes, TestSize.Level0)
165 {
166     TaskScheduler taskScheduler("everyTimes");
167     auto blockData = std::make_shared<BlockData<int>>(LONG_INTERVAL, 0);
168     int testData = 0;
169     int times = 5;
170     auto taskId = taskScheduler.Every(times, std::chrono::milliseconds(0),
__anon38b05aad0802() 171         std::chrono::milliseconds(SHORT_INTERVAL), [blockData, times, &testData]() {
172         testData++;
173         if (testData < times) {
174             blockData->Clear(testData);
175             return;
176         }
177         blockData->SetValue(testData);
178     });
179     ASSERT_EQ(blockData->GetValue(), times);
180     auto resetId = taskScheduler.Reset(taskId, std::chrono::milliseconds(SHORT_INTERVAL));
181     ASSERT_EQ(resetId, TaskScheduler::INVALID_TASK_ID);
182     ASSERT_EQ(blockData->GetValue(), times);
183 }
184 
185 /**
186 * @tc.name: Remove
187 * @tc.desc: remove task before execute.
188 * @tc.type: FUNC
189 * @tc.require:
190 * @tc.author: zuojiangjiang
191 */
192 HWTEST_F(TaskSchedulerTest, RemoveBeforeExecute, TestSize.Level0)
193 {
194     TaskScheduler taskScheduler("RemoveBeforeExecute");
195     auto expiredTime = std::chrono::steady_clock::now() + std::chrono::milliseconds(SHORT_INTERVAL);
196     auto blockData = std::make_shared<BlockData<int>>(LONG_INTERVAL, 0);
197     int testData = 0;
__anon38b05aad0902() 198     auto taskId = taskScheduler.At(expiredTime, [blockData, testData]() {
199         int tmpData = testData + 1;
200         blockData->SetValue(tmpData);
201     }, std::chrono::milliseconds(SHORT_INTERVAL));
202     taskScheduler.Remove(taskId);
203     auto resetId = taskScheduler.Reset(taskId, std::chrono::milliseconds(SHORT_INTERVAL));
204     ASSERT_EQ(resetId, TaskScheduler::INVALID_TASK_ID);
205     ASSERT_EQ(blockData->GetValue(), testData);
206 }
207 
208 /**
209 * @tc.name: Remove
210 * @tc.desc: remove task during execute, and waiting.
211 * @tc.type: FUNC
212 * @tc.require:
213 * @tc.author: zuojiangjiang
214 */
215 HWTEST_F(TaskSchedulerTest, RemoveWaitExecute, TestSize.Level0)
216 {
217     TaskScheduler taskScheduler("RemoveWaitExecute");
218     auto expiredTime = std::chrono::steady_clock::now() + std::chrono::milliseconds(0);
219     auto blockDataTest = std::make_shared<BlockData<int>>(LONG_INTERVAL, 0);
220     auto blockDataWait = std::make_shared<BlockData<int>>(LONG_INTERVAL, 0);
221     int testData = 1;
__anon38b05aad0a02() 222     auto taskId = taskScheduler.At(expiredTime, [blockDataTest, blockDataWait, &testData]() {
223         blockDataTest->SetValue(testData);
224         blockDataWait->GetValue();
225         int tmpData = testData + 1;
226         blockDataTest->SetValue(tmpData);
227     }, std::chrono::milliseconds(SHORT_INTERVAL));
228     ASSERT_EQ(blockDataTest->GetValue(), testData);
229     auto resetId = taskScheduler.Reset(taskId, std::chrono::milliseconds(SHORT_INTERVAL));
230     ASSERT_EQ(taskId, resetId);
231     taskScheduler.Remove(taskId, true);
232     ASSERT_EQ(blockDataTest->GetValue(), testData + 1);
233 }
234 
235 /**
236 * @tc.name: Remove
237 * @tc.desc: remove task during execute, but no wait.
238 * @tc.type: FUNC
239 * @tc.require:
240 * @tc.author: zuojiangjiang
241 */
242 HWTEST_F(TaskSchedulerTest, RemoveNoWaitExecute, TestSize.Level0)
243 {
244     TaskScheduler taskScheduler("RemoveNoWaitExecute");
245     auto expiredTime = std::chrono::steady_clock::now() + std::chrono::milliseconds(0);
246     auto blockDataTest = std::make_shared<BlockData<int>>(LONG_INTERVAL, 0);
247     auto blockDataWait = std::make_shared<BlockData<int>>(LONG_INTERVAL, 0);
248     int testData = 1;
__anon38b05aad0b02() 249     auto taskId = taskScheduler.At(expiredTime, [blockDataTest, blockDataWait, &testData]() {
250         blockDataTest->SetValue(testData);
251         blockDataWait->GetValue();
252         int tmpData = testData + 1;
253         blockDataTest->SetValue(tmpData);
254     });
255     ASSERT_EQ(blockDataTest->GetValue(), testData);
256     blockDataTest->Clear(0);
257     taskScheduler.Remove(taskId);
258     blockDataWait->SetValue(testData);
259     ASSERT_EQ(blockDataTest->GetValue(), testData + 1);
260 }
261 } // namespace OHOS::Test