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