• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <gtest/gtest.h>
16 #include "thread_ex.h"
17 #include <iostream>
18 #include <cstdio>
19 #include <sys/prctl.h>
20 using namespace testing::ext;
21 using namespace std;
22 
23 namespace OHOS {
24 namespace {
25 static int times = 0;
26 using ThreadRunFunc = bool (*)(int& data);
27 
28 class UtilsThreadTest : public testing::Test {
29 public:
30     static void SetUpTestCase(void);
31     static void TearDownTestCase(void);
32     void SetUp();
33     void TearDown();
34 };
35 
SetUpTestCase(void)36 void UtilsThreadTest::SetUpTestCase(void)
37 {
38     // input testsuit setup step
39 }
40 
TearDownTestCase(void)41 void UtilsThreadTest::TearDownTestCase(void)
42 {
43     // input testsuit teardown step
44 }
45 
SetUp(void)46 void UtilsThreadTest::SetUp(void)
47 {
48     // recover times
49     times = 0;
50 }
51 
TearDown(void)52 void UtilsThreadTest::TearDown(void)
53 {
54     // recover times
55     times = 0;
56 }
57 
TestRun01(int & data)58 bool TestRun01(int& data)
59 {
60     ++data;
61     return false;
62 }
63 
TestRun02(int & data)64 bool TestRun02(int& data)
65 {
66     ++data;
67     return true;
68 }
69 
TestRun03(int & data)70 bool TestRun03(int& data)
71 {
72     static const int TRY_TIMES = 10;
73     if (times <= TRY_TIMES) {
74         ++data;
75         return true;
76     }
77 
78     return false;
79 }
80 
81 constexpr int DEFAULT_PRIO = 0;
82 const std::string& DEFAULT_THREAD_NAME = "default";
83 
84 class TestThread : public OHOS::Thread {
85 public:
TestThread(const int data,const bool readyToWork,ThreadRunFunc runFunc)86     TestThread(const int data, const bool readyToWork, ThreadRunFunc runFunc)
87         : data_(data), priority_(DEFAULT_PRIO), name_(DEFAULT_THREAD_NAME), readyToWork_(readyToWork), runFunc_(runFunc)
88         {};
89 
90     TestThread() = delete;
~TestThread()91     ~TestThread() {}
92 
93     bool ReadyToWork() override;
94 
95     int data_;
96     int priority_;
97     std::string name_;
98 protected:
99     bool Run() override;
100 
101 private:
102     bool readyToWork_;
103     ThreadRunFunc runFunc_;
104 };
105 
ReadyToWork()106 bool TestThread::ReadyToWork()
107 {
108     return readyToWork_;
109 }
110 
Run()111 bool TestThread::Run()
112 {
113     priority_ = getpriority(PRIO_PROCESS, 0);
114     char threadName[MAX_THREAD_NAME_LEN + 1] = {0};
115     prctl(PR_GET_NAME, threadName, 0, 0);
116     name_ = threadName;
117 
118     if (runFunc_ != nullptr) {
119         return (*runFunc_)(data_);
120     }
121 
122     return false;
123 }
124 
125 /*
126  * @tc.name: testThread001
127  * @tc.desc: ThreadTest
128  */
129 HWTEST_F(UtilsThreadTest, testThread001, TestSize.Level0)
130 {
131     times = 0;
132     std::unique_ptr<TestThread> test = std::make_unique<TestThread>(0, false, TestRun01);
133     ThreadStatus status = test->Start("test_thread_01", THREAD_PROI_LOW, 1024);
134     EXPECT_EQ(status == ThreadStatus::OK, true);
135 
136     pthread_t thread = test->GetThread();
137 
138     // pthread_equal return non-zero if equal
139     EXPECT_EQ(pthread_equal(thread, -1) != 0, (test->IsRunning() ? false : true));
140 
141     // ReadyToWork return false, RUN will not be called!
142     EXPECT_EQ(test->priority_, DEFAULT_PRIO);
143     EXPECT_EQ(test->name_, DEFAULT_THREAD_NAME);
144 
145     // get stacksize of thread, may be different because of system memory align
146     EXPECT_EQ(test->data_, 0);
147     test->NotifyExitSync();
148     sleep(1);
149     EXPECT_EQ(pthread_equal(test->GetThread(), -1) != 0, (test->IsRunning() ? false : true));
150 }
151 
152 /*
153  * @tc.name: testThread002
154  * @tc.desc: ThreadTest
155  */
156 HWTEST_F(UtilsThreadTest, testThread002, TestSize.Level0)
157 {
158     times = 0;
159     std::unique_ptr<TestThread> test = std::make_unique<TestThread>(0, true, TestRun01);
160     ThreadStatus status = test->Start("test_thread_02", THREAD_PROI_LOW, 1024);
161 
162     EXPECT_EQ(status == ThreadStatus::OK, true);
163 
164     sleep(1); // let the new thread has chance to run
165 
166     // pthread_equal return non-zero if equal, RUN return false,may exit already
167     EXPECT_EQ(pthread_equal(test->GetThread(), -1) != 0, (test->IsRunning() ? false : true));
168 
169     // ReadyToWork return true, RUN will be called!
170     EXPECT_EQ(test->priority_, THREAD_PROI_LOW);
171     EXPECT_EQ(test->name_, "test_thread_02");
172 
173     EXPECT_EQ(test->data_, 1);
174     test->NotifyExitSync();
175     sleep(1);
176     EXPECT_EQ(pthread_equal(test->GetThread(), -1) != 0, (test->IsRunning() ? false : true));
177 }
178 
179 /*
180  * @tc.name: testThread003
181  * @tc.desc: ThreadTest
182  */
183 HWTEST_F(UtilsThreadTest, testThread003, TestSize.Level0)
184 {
185     times = 0;
186     std::unique_ptr<TestThread> test = std::make_unique<TestThread>(0, false, TestRun02);
187     ThreadStatus status = test->Start("test_thread_03", THREAD_PROI_LOW, 1024);
188     EXPECT_EQ(status == ThreadStatus::OK, true);
189 
190     pthread_t thread = test->GetThread();
191 
192     // pthread_equal return non-zero if equal
193     EXPECT_EQ(pthread_equal(thread , -1) != 0, (test->IsRunning() ? false : true));
194 
195     // ReadyToWork return false, RUN will not be called!
196     EXPECT_EQ(test->priority_, DEFAULT_PRIO);
197     EXPECT_EQ(test->name_, DEFAULT_THREAD_NAME);
198 
199     EXPECT_EQ(test->data_, 0);
200     test->NotifyExitSync();
201     sleep(1);
202     EXPECT_EQ(pthread_equal(test->GetThread(), -1) != 0, (test->IsRunning() ? false : true));
203 }
204 
205 /*
206  * @tc.name: testThread004
207  * @tc.desc: ThreadTest
208  */
209 HWTEST_F(UtilsThreadTest, testThread004, TestSize.Level0)
210 {
211     times = 0;
212     std::unique_ptr<TestThread> test = std::make_unique<TestThread>(0, true, TestRun02);
213     ThreadStatus status = test->Start("test_thread_04", THREAD_PROI_LOW, 1024);
214 
215     EXPECT_EQ(status == ThreadStatus::OK, true);
216 
217     sleep(1); // let the new thread has chance to run
218 
219     // pthread_equal return non-zero if equal, RUN return false,may exit already
220     EXPECT_EQ(pthread_equal(test->GetThread(), -1) != 0, (test->IsRunning() ? false : true));
221 
222     // ReadyToWork return true, RUN will be called!
223     EXPECT_EQ(test->priority_, THREAD_PROI_LOW);
224     EXPECT_EQ(test->name_, "test_thread_04");
225 
226     EXPECT_GT(test->data_, 1);
227     test->NotifyExitSync();
228     sleep(1);
229     EXPECT_EQ(pthread_equal(test->GetThread(), -1) != 0, (test->IsRunning() ? false : true));
230 }
231 
232 /*
233  * @tc.name: testThread005
234  * @tc.desc: ThreadTest
235  */
236 HWTEST_F(UtilsThreadTest, testThread005, TestSize.Level0)
237 {
238     times = 0;
239     std::unique_ptr<TestThread> test = std::make_unique<TestThread>(0, false, TestRun03);
240     ThreadStatus status = test->Start("test_thread_05", THREAD_PROI_LOW, 1024);
241     EXPECT_EQ(status == ThreadStatus::OK, true);
242 
243     pthread_t thread = test->GetThread();
244 
245     // pthread_equal return non-zero if equal
246     EXPECT_EQ(pthread_equal(thread , -1) != 0, (test->IsRunning() ? false : true));
247 
248     // ReadyToWork return false, RUN will not be called!
249     EXPECT_EQ(test->priority_, DEFAULT_PRIO);
250     EXPECT_EQ(test->name_, DEFAULT_THREAD_NAME);
251 
252     EXPECT_EQ(test->data_, 0);
253     test->NotifyExitSync();
254     sleep(1);
255     EXPECT_EQ(pthread_equal(test->GetThread(), -1) != 0, (test->IsRunning() ? false : true));
256 }
257 
258 /*
259  * @tc.name: testThread006
260  * @tc.desc: ThreadTest
261  */
262 HWTEST_F(UtilsThreadTest, testThread006, TestSize.Level0)
263 {
264     times = 0;
265     std::unique_ptr<TestThread> test = std::make_unique<TestThread>(0, true, TestRun03);
266     ThreadStatus status = test->Start("test_thread_06", THREAD_PROI_LOW, 1024);
267 
268     EXPECT_EQ(status == ThreadStatus::OK, true);
269 
270     sleep(1); // let the new thread has chance to run
271 
272     // pthread_equal return non-zero if equal, RUN return false,may exit already
273     EXPECT_EQ(pthread_equal(test->GetThread(), -1) != 0, (test->IsRunning() ? false : true));
274 
275     // ReadyToWork return true, RUN will be called!
276     EXPECT_EQ(test->priority_, THREAD_PROI_LOW);
277     EXPECT_EQ(test->name_, "test_thread_06");
278 
279     EXPECT_GT(test->data_, 10);
280 
281     times = 100;
282     EXPECT_GT(test->data_, 10);
283 
284     sleep(1); // let the new thread has chance to run
285 
286     // times > 10, TestRun03 return false, thread exit
287     EXPECT_EQ(pthread_equal(test->GetThread(), -1) != 0, (test->IsRunning() ? false : true));
288 }
289 
290 /*
291  * @tc.name: testThread007
292  * @tc.desc: ThreadTest
293  */
294 HWTEST_F(UtilsThreadTest, testThread007, TestSize.Level0)
295 {
296     times = 0;
297     std::unique_ptr<TestThread> test = std::make_unique<TestThread>(0, true, TestRun03);
298     ThreadStatus status = test->Start("", THREAD_PROI_LOW, 0);
299 
300     EXPECT_EQ(status == ThreadStatus::OK, true);
301     if (test->IsRunning()) {
302         status = test->Start("", THREAD_PROI_NORMAL, 1024);
303         EXPECT_EQ(status == ThreadStatus::INVALID_OPERATION, true);
304 
305         test->NotifyExitSync();
306         EXPECT_EQ(pthread_equal(test->GetThread(), -1) != 0, (test->IsRunning() ? false : true));
307     }
308 
309     sleep(1); // let the new thread has chance to run
310 
311     EXPECT_EQ(pthread_equal(test->GetThread(), -1) != 0, (test->IsRunning() ? false : true));
312 }
313 
314 /*
315  * @tc.name: testThread008
316  * @tc.desc: ThreadTest
317  */
318 HWTEST_F(UtilsThreadTest, testThread008, TestSize.Level0)
319 {
320     times = 0;
321     std::unique_ptr<TestThread> test = std::make_unique<TestThread>(0, true, TestRun03);
322 
323     bool res = test->Thread::ReadyToWork();
324     EXPECT_EQ(res, true);
325 
326     ThreadStatus status = test->Start("", THREAD_PROI_NORMAL, 1024);
327     EXPECT_EQ(status == ThreadStatus::OK, true);
328 
329     sleep(1);
330     test->NotifyExitAsync();
331 
332     sleep(1); // let the new thread has chance to run
333     EXPECT_EQ(pthread_equal(test->GetThread(), -1) != 0, (test->IsRunning() ? false : true));
334 }
335 
336 class TestThread2 : public OHOS::Thread {
337 public:
TestThread2(const int data,ThreadRunFunc runFunc)338     TestThread2(const int data, ThreadRunFunc runFunc)
339         : data_(data), priority_(DEFAULT_PRIO), name_(DEFAULT_THREAD_NAME), runFunc_(runFunc)
340         {};
341 
342     TestThread2() = delete;
~TestThread2()343     ~TestThread2() {}
344 
345     int data_;
346     int priority_;
347     std::string name_;
348 protected:
349     bool Run() override;
350 
351 private:
352     ThreadRunFunc runFunc_;
353 };
354 
Run()355 bool TestThread2::Run()
356 {
357     priority_ = getpriority(PRIO_PROCESS, 0);
358     char threadName[MAX_THREAD_NAME_LEN + 1] = {0};
359     prctl(PR_GET_NAME, threadName, 0, 0);
360     name_ = threadName;
361 
362     if (runFunc_ != nullptr) {
363         return (*runFunc_)(data_);
364     }
365 
366     return false;
367 }
368 
369 /*
370  * @tc.name: testThread009
371  * @tc.desc: ThreadTest
372  */
373 HWTEST_F(UtilsThreadTest, testThread009, TestSize.Level0)
374 {
375     times = 0;
376     std::unique_ptr<TestThread2> test = std::make_unique<TestThread2>(0, TestRun03);
377 
378     bool res = test->ReadyToWork();
379     EXPECT_EQ(res, true);
380 
381     ThreadStatus status = test->Start("", THREAD_PROI_NORMAL, 1024);
382     EXPECT_EQ(status == ThreadStatus::OK, true);
383 
384     sleep(1);
385     test->NotifyExitAsync();
386 
387     sleep(1); // let the new thread has chance to run
388     EXPECT_EQ(pthread_equal(test->GetThread(), -1) != 0, (test->IsRunning() ? false : true));
389 }
390 
391 }  // namespace
392 }  // namespace OHOS