• 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 
21 using namespace testing::ext;
22 using namespace OHOS;
23 using namespace std;
24 
25 static int times = 0;
26 using ThreadRunFunc = bool (*)(int& data);
27 
28 class UtilsThreadTest : public testing::Test
29 {
30 public :
31     static void SetUpTestCase(void);
32     static void TearDownTestCase(void);
33     void SetUp();
34     void TearDown();
35 };
36 
SetUpTestCase(void)37 void UtilsThreadTest::SetUpTestCase(void)
38 {
39     // input testsuit setup step
40 }
41 
TearDownTestCase(void)42 void UtilsThreadTest::TearDownTestCase(void)
43 {
44     // input testsuit teardown step
45 }
46 
SetUp(void)47 void UtilsThreadTest::SetUp(void)
48 {
49     // recover times
50     times = 0;
51 }
52 
TearDown(void)53 void UtilsThreadTest::TearDown(void)
54 {
55     // recover times
56     times = 0;
57 }
58 
59 // get priority of thread
GetThreadPriority(const pthread_t & thread)60 int GetThreadPriority(const pthread_t& thread)
61 {
62     sched_param param;
63     int priority;
64     int policy;
65     int ret;
66 
67     // scheduling parameters of target thread
68     ret = pthread_getschedparam (thread, &policy, &param);
69     if (ret != 0){
70         printf("pthread_getschedparam failed! thread:%lu, ret:%d\n", thread, ret);
71         return -1;
72     }
73 
74     // sched_priority contains the priority of the thread
75     priority = param.sched_priority;
76     return priority;
77 }
78 
79 
TestRun01(int & data)80 bool TestRun01(int& data)
81 {
82     ++data;
83     return false;
84 }
85 
TestRun02(int & data)86 bool TestRun02(int& data)
87 {
88     ++data;
89     return true;
90 }
91 
TestRun03(int & data)92 bool TestRun03(int& data)
93 {
94     static const int TRY_TIMES = 10;
95     if (times <= TRY_TIMES) {
96         ++data;
97         return true;
98     }
99 
100     return false;
101 }
102 
103 constexpr int DEFAULT_PRIO = 0;
104 const std::string& DEFAULT_THREAD_NAME = "default";
105 
106 class TestThread : public OHOS::Thread{
107 public:
TestThread(const int data,const bool readyToWork,ThreadRunFunc runFunc)108     TestThread(const int data, const bool readyToWork, ThreadRunFunc runFunc)
109         : data_(data), priority_(DEFAULT_PRIO), name_(DEFAULT_THREAD_NAME), readyToWork_(readyToWork), runFunc_(runFunc)
110         {};
111 
112     TestThread() = delete;
~TestThread()113     ~TestThread(){};
114 
115     bool ReadyToWork() override;
116 
117     int data_;
118     int priority_;
119     std::string name_;
120 protected:
121     bool Run() override;
122 
123 private:
124     bool readyToWork_;
125     ThreadRunFunc runFunc_;
126 };
127 
ReadyToWork()128 bool TestThread::ReadyToWork()
129 {
130     return readyToWork_;
131 }
132 
Run()133 bool TestThread::Run()
134 {
135     priority_ = getpriority(PRIO_PROCESS, 0);
136     char threadName[MAX_THREAD_NAME_LEN] = {0};
137     prctl(PR_GET_NAME, threadName, 0, 0);
138     name_ = threadName;
139 
140     if (runFunc_ != nullptr) {
141         return (*runFunc_)(data_);
142     }
143 
144     return false;
145 }
146 
147 /*
148  * @tc.name: testThread001
149  * @tc.desc: ThreadTest
150  */
151 HWTEST_F(UtilsThreadTest, testThread001, TestSize.Level1)
152 {
153     times = 0;
154     std::unique_ptr<TestThread> test = std::make_unique<TestThread>(0, false, TestRun01);
155     ThreadStatus status = test->Start("test_thread_01", THREAD_PROI_LOW, 1024);
156     EXPECT_EQ(status == ThreadStatus::OK, true);
157 
158     pthread_t thread = test->GetThread();
159 
160     // pthread_equal return non-zero if equal
161     EXPECT_EQ(pthread_equal(thread ,-1) != 0, (test->IsRunning() ? false : true));
162 
163     // ReadyToWork return false, RUN will not be called!
164     EXPECT_EQ(test->priority_, DEFAULT_PRIO);
165     EXPECT_EQ(test->name_, DEFAULT_THREAD_NAME);
166 
167     // get stacksize of threa, may be different because of system memory align
168 
169     EXPECT_EQ(test->data_, 0);
170     EXPECT_EQ(times, 0);
171     test->NotifyExitSync();
172     sleep(1);
173     EXPECT_EQ(pthread_equal(test->GetThread() ,-1) != 0, (test->IsRunning() ? false : true));
174 }
175 
176 /*
177  * @tc.name: testThread002
178  * @tc.desc: ThreadTest
179  */
180 HWTEST_F(UtilsThreadTest, testThread002, TestSize.Level1)
181 {
182     times = 0;
183     std::unique_ptr<TestThread> test = std::make_unique<TestThread>(0, true, TestRun01);
184     ThreadStatus status = test->Start("test_thread_02", THREAD_PROI_LOW, 1024);
185 
186     EXPECT_EQ(status == ThreadStatus::OK, true);
187 
188     sleep(1); // let the new thread has chance to run
189 
190     // pthread_equal return non-zero if equal, RUN return false,may exit already
191     EXPECT_EQ(pthread_equal(test->GetThread() ,-1) != 0, (test->IsRunning() ? false : true));
192 
193     // ReadyToWork return true, RUN will be called!
194     EXPECT_EQ(test->priority_, THREAD_PROI_LOW);
195     EXPECT_EQ(test->name_, "test_thread_02");
196 
197     EXPECT_EQ(test->data_, 1);
198     EXPECT_EQ(times, 0);
199     test->NotifyExitSync();
200     sleep(1);
201     EXPECT_EQ(pthread_equal(test->GetThread() ,-1) != 0, (test->IsRunning() ? false : true));
202 }
203 
204 /*
205  * @tc.name: testThread003
206  * @tc.desc: ThreadTest
207  */
208 HWTEST_F(UtilsThreadTest, testThread003, TestSize.Level1)
209 {
210     times = 0;
211     std::unique_ptr<TestThread> test = std::make_unique<TestThread>(0, false, TestRun02);
212     ThreadStatus status = test->Start("test_thread_03", THREAD_PROI_LOW, 1024);
213     EXPECT_EQ(status == ThreadStatus::OK, true);
214 
215     pthread_t thread = test->GetThread();
216 
217     // pthread_equal return non-zero if equal
218     EXPECT_EQ(pthread_equal(thread ,-1) != 0, (test->IsRunning() ? false : true));
219 
220     // ReadyToWork return false, RUN will not be called!
221     EXPECT_EQ(test->priority_, DEFAULT_PRIO);
222     EXPECT_EQ(test->name_, DEFAULT_THREAD_NAME);
223 
224     EXPECT_EQ(test->data_, 0);
225     EXPECT_EQ(times, 0);
226     test->NotifyExitSync();
227     sleep(1);
228     EXPECT_EQ(pthread_equal(test->GetThread() ,-1) != 0, (test->IsRunning() ? false : true));
229 }
230 
231 /*
232  * @tc.name: testThread004
233  * @tc.desc: ThreadTest
234  */
235 HWTEST_F(UtilsThreadTest, testThread004, TestSize.Level1)
236 {
237     times = 0;
238     std::unique_ptr<TestThread> test = std::make_unique<TestThread>(0, true, TestRun02);
239     ThreadStatus status = test->Start("test_thread_04", THREAD_PROI_LOW, 1024);
240 
241     EXPECT_EQ(status == ThreadStatus::OK, true);
242 
243     sleep(1); // let the new thread has chance to run
244 
245     // pthread_equal return non-zero if equal, RUN return false,may exit already
246     EXPECT_EQ(pthread_equal(test->GetThread() ,-1) != 0, (test->IsRunning() ? false : true));
247 
248     // ReadyToWork return true, RUN will be called!
249     EXPECT_EQ(test->priority_, THREAD_PROI_LOW);
250     EXPECT_EQ(test->name_, "test_thread_04");
251 
252     EXPECT_GT(test->data_, 1);
253     EXPECT_EQ(times, 0);
254     test->NotifyExitSync();
255     sleep(1);
256     EXPECT_EQ(pthread_equal(test->GetThread() ,-1) != 0, (test->IsRunning() ? false : true));
257 }
258 
259 /*
260  * @tc.name: testThread005
261  * @tc.desc: ThreadTest
262  */
263 HWTEST_F(UtilsThreadTest, testThread005, TestSize.Level1)
264 {
265     times = 0;
266     std::unique_ptr<TestThread> test = std::make_unique<TestThread>(0, false, TestRun03);
267     ThreadStatus status = test->Start("test_thread_05", THREAD_PROI_LOW, 1024);
268     EXPECT_EQ(status == ThreadStatus::OK, true);
269 
270     pthread_t thread = test->GetThread();
271 
272     // pthread_equal return non-zero if equal
273     EXPECT_EQ(pthread_equal(thread ,-1) != 0, (test->IsRunning() ? false : true));
274 
275     // ReadyToWork return false, RUN will not be called!
276     EXPECT_EQ(test->priority_, DEFAULT_PRIO);
277     EXPECT_EQ(test->name_, DEFAULT_THREAD_NAME);
278 
279     EXPECT_EQ(test->data_, 0);
280     EXPECT_EQ(times, 0);
281     test->NotifyExitSync();
282     sleep(1);
283     EXPECT_EQ(pthread_equal(test->GetThread() ,-1) != 0, (test->IsRunning() ? false : true));
284 }
285 
286 /*
287  * @tc.name: testThread006
288  * @tc.desc: ThreadTest
289  */
290 HWTEST_F(UtilsThreadTest, testThread006, TestSize.Level1)
291 {
292     times = 0;
293     std::unique_ptr<TestThread> test = std::make_unique<TestThread>(0, true, TestRun03);
294     ThreadStatus status = test->Start("test_thread_06", THREAD_PROI_LOW, 1024);
295 
296     EXPECT_EQ(status == ThreadStatus::OK, true);
297 
298     sleep(1); // let the new thread has chance to run
299 
300     // pthread_equal return non-zero if equal, RUN return false,may exit already
301     EXPECT_EQ(pthread_equal(test->GetThread() ,-1) != 0, (test->IsRunning() ? false : true));
302 
303     // ReadyToWork return true, RUN will be called!
304     EXPECT_EQ(test->priority_, THREAD_PROI_LOW);
305     EXPECT_EQ(test->name_, "test_thread_06");
306 
307     EXPECT_GT(test->data_, 10);
308     EXPECT_EQ(times, 0);
309 
310     times = 100;
311     EXPECT_GT(test->data_, 10);
312 
313     sleep(1); // let the new thread has chance to run
314 
315     // times > 10, TestRun03 return false, thread exit
316     EXPECT_EQ(pthread_equal(test->GetThread() ,-1) != 0, (test->IsRunning() ? false : true));
317 }
318 
319