1 /* 2 * Copyright (c) 2021 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<cstring> 17 #include<string> 18 19 #include "gtest/gtest.h" 20 21 #include "platform/threadpool/include/thread.h" 22 #include "platform/threadpool/include/thread_pool.h" 23 #include "platform/time/include/time.h" 24 #include "utils/log/aie_log.h" 25 26 using namespace OHOS::AI; 27 using namespace std; 28 using namespace testing::ext; 29 30 namespace { 31 const int STOP_TIME = 100; 32 const time_t HUNG_TIME = 15; 33 const int SIZE = 70000; 34 const int SIZE_MIN = 0; 35 const int INVALID_THREAD_ID = -1; 36 const string WORKER_DEFAULT_NAME("WorkerDefaultName"); 37 } 38 39 class ThreadPoolTest : public testing::Test { 40 public: 41 // SetUpTestCase:The preset action of the test suite is executed before the first TestCase SetUpTestCase()42 static void SetUpTestCase() {}; 43 44 // TearDownTestCase:The test suite cleanup action is executed after the last TestCase TearDownTestCase()45 static void TearDownTestCase() {}; 46 47 // SetUp:Execute before each test case SetUp()48 void SetUp() {}; 49 50 // TearDown:Execute after each test case TearDown()51 void TearDown() {}; 52 }; 53 54 class CWorker : public IWorker { 55 public: GetName() const56 const char *GetName() const override 57 { 58 return "CWorker"; 59 } 60 OneAction()61 bool OneAction() override 62 { 63 StepSleepMs(THREAD_SLEEP_MS); 64 HILOGD("[Test]Worker OneAction after sleep"); 65 return true; 66 } 67 Initialize()68 bool Initialize() override 69 { 70 HILOGD("[Test]Worker Initialize success"); 71 return true; 72 } 73 }; 74 75 class MultiWorker : public IWorker { 76 public: MultiWorker(const string & workerName)77 explicit MultiWorker(const string &workerName) : workerName_(workerName) 78 { 79 } 80 81 ~MultiWorker() override = default; 82 GetName() const83 const char *GetName() const override 84 { 85 return workerName_.c_str(); 86 } 87 OneAction()88 bool OneAction() override 89 { 90 StepSleepMs(THREAD_SLEEP_MS); 91 HILOGD("[Test]Worker(%s) OneAction success.", GetName()); 92 return true; 93 } 94 Initialize()95 bool Initialize() override 96 { 97 HILOGD("[Test]Worker(%s) Initialize success.", GetName()); 98 return true; 99 } 100 Uninitialize()101 void Uninitialize() override 102 { 103 HILOGD("[Test]Worker(%s) Uninitialize success.", GetName()); 104 } 105 106 private: 107 string workerName_ = WORKER_DEFAULT_NAME; 108 }; 109 110 /** 111 * @tc.name: TestWorker001 112 * @tc.desc: Test worker Initialize/GetStackSize/Status/GetThreadId functions. 113 * @tc.type: FUNC 114 * @tc.require: AR000F77TL 115 */ 116 HWTEST_F(ThreadPoolTest, TestWorker001, TestSize.Level1) 117 { 118 HILOGD("[Test]Test worker begin"); 119 CWorker worker; 120 worker.Initialize(); 121 ASSERT_FALSE(worker.isHung(HUNG_TIME)); 122 ASSERT_EQ(worker.GetStackSize(), THREAD_DEFAULT_STACK_SIZE); 123 ASSERT_EQ(worker.Status(), 0); 124 ASSERT_EQ(static_cast<int>(worker.GetThreadId()), INVALID_THREAD_ID); 125 Thread thread; 126 worker.SetThread(&thread); 127 HILOGD("[Test]Test worker end, GetThreadId is %lu.", worker.GetThreadId()); 128 } 129 130 /** 131 * @tc.name: TestThread001 132 * @tc.desc: Test thread StartThread/IsRunning/IsActive/StopThread functions. 133 * @tc.type: FUNC 134 * @tc.require: AR000F77TL 135 */ 136 HWTEST_F(ThreadPoolTest, TestThread001, TestSize.Level1) 137 { 138 HILOGD("[Test]Test thread1 begin"); 139 Thread testThread; 140 unsigned long id = testThread.GetThreadId(); 141 HILOGD("[Test]Thread id %lu.", id); 142 testThread.SetStackSize(SIZE); 143 CWorker worker; 144 ASSERT_TRUE(testThread.StartThread(&worker)); 145 id = testThread.GetThreadId(); 146 HILOGD("[Test]Thread id %lu.", id); 147 ASSERT_TRUE(testThread.IsRunning()); 148 ASSERT_TRUE(testThread.IsActive()); 149 ASSERT_TRUE(testThread.StopThread(STOP_TIME)); 150 ASSERT_FALSE(testThread.IsRunning()); 151 ASSERT_FALSE(testThread.IsActive()); 152 HILOGD("[Test]Test thread1 end."); 153 } 154 155 /** 156 * @tc.name: ThreadPoolTest001 157 * @tc.desc: Test ThreadPool SetStackSize/getStackSize functions. 158 * @tc.type: FUNC 159 * @tc.require: AR000F77TL 160 */ 161 HWTEST_F(ThreadPoolTest, ThreadPoolTest001, TestSize.Level1) 162 { 163 HILOGD("[Test]ThreadPoolTest001 begin"); 164 ThreadPool *threadPool = ThreadPool::GetInstance(); 165 ASSERT_EQ(threadPool->getStackSize(), 0); 166 threadPool->SetStackSize(SIZE); 167 ASSERT_EQ(threadPool->getStackSize(), SIZE); 168 threadPool->SetStackSize(SIZE_MIN); 169 HILOGD("[Test]ThreadPoolTest001 end"); 170 } 171 172 /** 173 * @tc.name: ThreadPoolTest002 174 * @tc.desc: Test ThreadPool Pop method. 175 * @tc.type: FUNC 176 * @tc.require: AR000F77TL 177 */ 178 HWTEST_F(ThreadPoolTest, ThreadPoolTest002, TestSize.Level1) 179 { 180 HILOGD("[Test]ThreadPoolTest002 begin"); 181 ThreadPool *threadPool = ThreadPool::GetInstance(); 182 ASSERT_NE(threadPool, nullptr); 183 std::shared_ptr<Thread> oneThread = threadPool->Pop(); 184 ASSERT_NE(oneThread, nullptr); 185 HILOGD("[Test]ThreadPoolTest002 end"); 186 } 187 188 /** 189 * @tc.name: ThreadPoolTest003 190 * @tc.desc: Test ThreadPool Push method. 191 * @tc.type: FUNC 192 * @tc.require: AR000F77TL 193 */ 194 HWTEST_F(ThreadPoolTest, ThreadPoolTest003, TestSize.Level1) 195 { 196 HILOGD("[Test]ThreadPoolTest003 begin"); 197 ThreadPool *threadPool = ThreadPool::GetInstance(); 198 ASSERT_NE(threadPool, nullptr); 199 std::shared_ptr<Thread> oneThread = threadPool->Pop(); 200 threadPool->Push(oneThread); 201 HILOGD("[Test]ThreadPoolTest003 end"); 202 } 203 204 /** 205 * @tc.name: TestThreadWithManyWorker001 206 * @tc.desc: Test pop/push thread, and start/stop thread 207 * @tc.type: FUNC 208 * @tc.require: AR000F77TL 209 */ 210 HWTEST_F(ThreadPoolTest, TestThreadWithManyWorker001, TestSize.Level1) 211 { 212 HILOGD("[Test]Test worker begin"); 213 string workerName("MultiWorker"); 214 int maxThreadNum = 10; 215 MultiWorker *workerList[maxThreadNum]; 216 std::shared_ptr<Thread> threadList[maxThreadNum]; 217 ThreadPool *threadPool = ThreadPool::GetInstance(); 218 ASSERT_NE(threadPool, nullptr); 219 for (int i = 0; i < maxThreadNum; i++) { 220 string tempWorkerName = workerName + to_string(i); 221 AIE_NEW(workerList[i], MultiWorker(tempWorkerName)); 222 threadList[i] = threadPool->Pop(); 223 ASSERT_TRUE(threadList[i]->StartThread(workerList[i])); 224 } 225 for (int i = 0; i < maxThreadNum; i++) { 226 threadList[i]->StopThread(); 227 threadPool->Push(threadList[i]); 228 AIE_DELETE(workerList[i]); 229 } 230 threadPool->ReleaseInstance(); 231 } 232