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