1 /* 2 * Copyright (c) 2023 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 <gtest/gtest.h> 16 17 #include "block_data.h" 18 #include "executor_pool.h" 19 20 namespace OHOS::Test { 21 using namespace testing::ext; 22 using namespace OHOS; 23 using duration = std::chrono::steady_clock::duration; 24 class ExecutorPoolTest : public testing::Test { 25 public: 26 struct Data { 27 std::mutex mutex_; 28 int data = 0; AddOHOS::Test::ExecutorPoolTest::Data29 void Add() 30 { 31 std::lock_guard<std::mutex> lockGuard(mutex_); 32 data++; 33 } 34 }; 35 static constexpr uint32_t SHORT_INTERVAL = 100; // ms 36 static constexpr uint32_t LONG_INTERVAL = 1; // s 37 static std::shared_ptr<ExecutorPool> executorPool_; SetUpTestCase(void)38 static void SetUpTestCase(void){}; TearDownTestCase(void)39 static void TearDownTestCase(void) 40 { 41 executorPool_ = nullptr; 42 }; SetUp()43 void SetUp(){}; TearDown()44 void TearDown() {} 45 }; 46 std::shared_ptr<ExecutorPool> ExecutorPoolTest::executorPool_ = std::make_shared<ExecutorPool>(12, 5); 47 48 /** 49 * @tc.name: Execute 50 * @tc.desc: 51 * @tc.type: FUNC 52 * @tc.require: 53 * @tc.author: CRJ 54 */ 55 HWTEST_F(ExecutorPoolTest, Execute, TestSize.Level0) 56 { 57 auto expiredTime = std::chrono::milliseconds(SHORT_INTERVAL); 58 int testData = 10; 59 auto blockData = std::make_shared<BlockData<int>>(LONG_INTERVAL, testData); __anon319724040102() 60 auto atTaskId1 = executorPool_->Schedule(expiredTime, [blockData]() { 61 int testData = 11; 62 blockData->SetValue(testData); 63 }); 64 ASSERT_EQ(blockData->GetValue(), 11); 65 blockData->Clear(); __anon319724040202() 66 auto atTaskId2 = executorPool_->Schedule(expiredTime, [blockData]() { 67 int testData = 12; 68 blockData->SetValue(testData); 69 }); 70 ASSERT_EQ(blockData->GetValue(), 12); 71 ASSERT_NE(atTaskId1, atTaskId2); 72 } 73 74 /** 75 * @tc.name: Schedule 76 * @tc.desc: 77 * @tc.type: FUNC 78 * @tc.require: 79 * @tc.author: CRJ 80 */ 81 HWTEST_F(ExecutorPoolTest, Schedule, TestSize.Level0) 82 { 83 auto expiredTime = std::chrono::milliseconds(SHORT_INTERVAL); 84 auto testData = std::make_shared<Data>(); 85 auto taskId = executorPool_->Schedule( __anon319724040302null86 [testData] { 87 testData->Add(); 88 }, 89 expiredTime); 90 ASSERT_NE(taskId, ExecutorPool::INVALID_TASK_ID); 91 std::this_thread::sleep_for(std::chrono::milliseconds(SHORT_INTERVAL * 10)); 92 ASSERT_EQ(testData->data, 10); 93 executorPool_->Remove(taskId); 94 } 95 96 /** 97 * @tc.name: MultiSchedule 98 * @tc.desc: 99 * @tc.type: FUNC 100 * @tc.require: 101 * @tc.author: CRJ 102 */ 103 HWTEST_F(ExecutorPoolTest, MultiSchedule, TestSize.Level0) 104 { 105 auto data = std::make_shared<Data>(); __anon319724040402null106 auto task = [data] { 107 data->Add(); 108 }; 109 std::set<ExecutorPool::TaskId> ids; 110 for (int i = 0; i < 10; ++i) { 111 auto id = executorPool_->Schedule(task, std::chrono::seconds(0), std::chrono::seconds(LONG_INTERVAL), 10); 112 ASSERT_EQ(ids.count(id), 0); 113 ids.insert(id); 114 } 115 std::this_thread::sleep_for(std::chrono::seconds(LONG_INTERVAL * 10)); 116 ASSERT_EQ(data->data, 100); 117 for (auto id : ids) { 118 executorPool_->Remove(id); 119 } 120 } 121 /** 122 * @tc.name: Remove 123 * @tc.desc: 124 * @tc.type: FUNC 125 * @tc.require: 126 * @tc.author: CRJ 127 */ 128 HWTEST_F(ExecutorPoolTest, Remove, TestSize.Level0) 129 { 130 auto expiredTime = std::chrono::milliseconds(SHORT_INTERVAL); 131 auto data = std::make_shared<Data>(); __anon319724040502null132 auto task = [data] { 133 data->Add(); 134 }; 135 auto temp = executorPool_->Schedule(task, expiredTime * 2); 136 std::this_thread::sleep_for(std::chrono::milliseconds(SHORT_INTERVAL)); 137 ASSERT_EQ(data->data, 1); 138 ASSERT_TRUE(executorPool_->Remove(temp)); 139 std::this_thread::sleep_for(expiredTime * 4); 140 ASSERT_EQ(data->data, 1); 141 } 142 /** 143 * @tc.name: Reset 144 * @tc.desc: 145 * @tc.type: FUNC 146 * @tc.require: 147 * @tc.author: CRJ 148 */ 149 HWTEST_F(ExecutorPoolTest, Reset, TestSize.Level0) 150 { 151 auto expiredTime = std::chrono::milliseconds(SHORT_INTERVAL); 152 auto data = std::make_shared<Data>(); __anon319724040602null153 auto task = [data] { 154 data->Add(); 155 }; 156 auto temp = executorPool_->Schedule(task, expiredTime * 2); 157 std::this_thread::sleep_for(std::chrono::milliseconds(SHORT_INTERVAL)); 158 ASSERT_EQ(data->data, 1); 159 ASSERT_EQ(executorPool_->Reset(temp, std::chrono::milliseconds(expiredTime * 2)), temp); 160 std::this_thread::sleep_for(std::chrono::milliseconds(expiredTime * 5)); 161 ASSERT_EQ(data->data, 3); 162 executorPool_->Remove(temp); 163 } 164 165 /** 166 * @tc.name: MaxEqualsOne 167 * @tc.desc: 168 * @tc.type: FUNC 169 * @tc.require: 170 * @tc.author: CRJ 171 */ 172 HWTEST_F(ExecutorPoolTest, MaxEqualsOne, TestSize.Level0) 173 { 174 auto executors = std::make_shared<ExecutorPool>(1, 0); 175 std::atomic<int> testNum = 1; __anon319724040702null176 auto delayTask = [&testNum] { 177 testNum++; 178 }; __anon319724040802null179 auto task = [&testNum] { 180 testNum += 2; 181 }; 182 executors->Schedule(std::chrono::milliseconds(SHORT_INTERVAL * 2), delayTask); 183 ASSERT_EQ(testNum, 1); 184 executors->Execute(task); 185 std::this_thread::sleep_for(std::chrono::milliseconds(SHORT_INTERVAL)); 186 ASSERT_EQ(testNum, 3); 187 std::this_thread::sleep_for(std::chrono::milliseconds(SHORT_INTERVAL * 2)); 188 ASSERT_EQ(testNum, 4); 189 } 190 191 /** 192 * @tc.name: RemoveInExcuteTask 193 * @tc.desc: test remove task when the task is running. 194 * @tc.type: FUNC 195 * @tc.require: 196 * @tc.author: ht 197 */ 198 HWTEST_F(ExecutorPoolTest, RemoveWhenExcute, TestSize.Level0) 199 { 200 auto executors = std::make_shared<ExecutorPool>(1, 1); 201 auto taskId = ExecutorPool::INVALID_TASK_ID; 202 std::atomic<int> flag = 0; 203 taskId = executors->Schedule( __anon319724040902() 204 [executors, &taskId, &flag]() { 205 flag++; 206 executors->Remove(taskId, false); 207 taskId = ExecutorPool::INVALID_TASK_ID; 208 }, 209 std::chrono::seconds(0), std::chrono::milliseconds(SHORT_INTERVAL), 10); 210 std::this_thread::sleep_for(std::chrono::seconds(LONG_INTERVAL)); 211 ASSERT_EQ(taskId, ExecutorPool::INVALID_TASK_ID); 212 ASSERT_EQ(flag, 1); 213 } 214 } // namespace OHOS::Test 215