1 #include <gtest/gtest.h>
2 #include <pthread.h>
3 #include <signal.h>
4 #include <stdlib.h>
5 #include <sys/mman.h>
6 #include <sys/prctl.h>
7 #include <unistd.h>
8
9 using namespace testing::ext;
10
11 class ThreadPthrdTest : public testing::Test {
SetUp()12 void SetUp() override {}
TearDown()13 void TearDown() override {}
14 };
15
16 class ThreadPthrdDeathTest : public testing::Test {
SetUp()17 void SetUp() override {}
TearDown()18 void TearDown() override {}
19 };
20
21 constexpr size_t BUF_LEN = 16;
22 constexpr size_t NAME_SIZE = 32;
23 constexpr size_t NAME_LONG_SIZE = 64;
24
25 static std::string g_dtorOutput;
26
27 static bool g_controlFlag = true;
28
CancelLoop()29 static void CancelLoop()
30 {
31 g_controlFlag = false;
32 }
33
BeginLoop(void *)34 static void* BeginLoop(void*)
35 {
36 while (g_controlFlag) {
37 }
38 return nullptr;
39 }
40
PthreadNameNp(void * arg)41 static void* PthreadNameNp(void* arg)
42 {
43 EXPECT_EQ(0, pthread_setname_np(pthread_self(), "shortname"));
44 char name[NAME_SIZE];
45 EXPECT_EQ(0, pthread_getname_np(pthread_self(), name, sizeof(name)));
46 EXPECT_STREQ("shortname", name);
47
48 EXPECT_EQ(0, pthread_setname_np(pthread_self(), "uselongnametest"));
49 EXPECT_EQ(0, pthread_getname_np(pthread_self(), name, sizeof(name)));
50 EXPECT_STREQ("uselongnametest", name);
51
52 EXPECT_EQ(ERANGE, pthread_setname_np(pthread_self(), "namecannotoversixth"));
53
54 EXPECT_EQ(0, pthread_getname_np(pthread_self(), name, BUF_LEN));
55 EXPECT_EQ(ERANGE, pthread_getname_np(pthread_self(), name, BUF_LEN - 1));
56 return nullptr;
57 }
58
ReturnFunc(void * arg)59 static void* ReturnFunc(void* arg)
60 {
61 return arg;
62 }
63
64 /**
65 * @tc.name: pthread_setname_np_001
66 * @tc.desc: 1. Set a unique name with a char type size of 32, and determine if it is the same after obtaining it.
67 * 2. Failed to set a name smaller than 16 bytes for the thread, with a minimum of 16 bytes
68 * @tc.type: FUNC
69 * */
70 HWTEST_F(ThreadPthrdTest, pthread_setname_np_001, TestSize.Level1)
71 {
72 void* arg = nullptr;
73 PthreadNameNp(arg);
74 }
75
76 /**
77 * @tc.name: pthread_setname_np_002
78 * @tc.desc: In a multithreaded environment, setting flags to control the operation of a thread ensures that the logic
79 * of setting a name for the thread can be used normally during multithreaded operation.
80 * @tc.type: FUNC
81 * */
82 HWTEST_F(ThreadPthrdTest, pthread_setname_np_002, TestSize.Level1)
83 {
84 pthread_t thread;
85 EXPECT_EQ(0, pthread_create(&thread, nullptr, PthreadNameNp, nullptr));
86 EXPECT_EQ(0, pthread_join(thread, nullptr));
87 }
88
89 /**
90 * @tc.name: pthread_setname_np_003
91 * @tc.desc: Set a dead process and set a unique name for the dead process for death testing, returning 'Death'
92 * @tc.type: FUNC
93 * */
94 HWTEST_F(ThreadPthrdDeathTest, pthread_setname_np_003, TestSize.Level1)
95 {
96 pthread_t deadThread;
97 pthread_create(&deadThread, nullptr, ReturnFunc, nullptr);
98 pthread_join(deadThread, nullptr);
99
100 EXPECT_DEATH(pthread_setname_np(deadThread, "short name"), ".*");
101 }
102
103 /**
104 * @tc.name: pthread_setname_np_004
105 * @tc.desc: Set a null process and set a unique name for the dead process for death testing, returning 'Death'
106 * @tc.type: FUNC
107 * */
108 HWTEST_F(ThreadPthrdDeathTest, pthread_setname_np_004, TestSize.Level1)
109 {
110 pthread_t nullThread = 0;
111 EXPECT_DEATH(pthread_setname_np(nullThread, "short name"), ".*");
112 }
113
114 /**
115 * @tc.name: pthread_getname_np_001
116 * @tc.desc: Set a dead process and set a unique name for the dead process for death testing, returning 'Death'
117 * @tc.type: FUNC
118 * */
119 HWTEST_F(ThreadPthrdDeathTest, pthread_getname_np_001, TestSize.Level1)
120 {
121 pthread_t deadThread;
122 pthread_create(&deadThread, nullptr, ReturnFunc, nullptr);
123 pthread_join(deadThread, nullptr);
124 char name[NAME_LONG_SIZE];
125 EXPECT_DEATH(pthread_getname_np(deadThread, name, sizeof(name)), ".*");
126 }
127
128 /**
129 * @tc.name: pthread_getname_np_002
130 * @tc.desc: Set a null process and set a unique name for the dead process for death testing, returning 'Death'
131 * @tc.type: FUNC
132 * */
133 HWTEST_F(ThreadPthrdDeathTest, pthread_getname_np_002, TestSize.Level1)
134 {
135 pthread_t nullThread = 0;
136 char name[NAME_LONG_SIZE];
137 EXPECT_DEATH(pthread_getname_np(nullThread, name, sizeof(name)), ".*");
138 }
139
140 /**
141 * @tc.name: pthread_sigmask_001
142 * @tc.desc: Modify the status of the SIGUSR1 signal and verify that the results are correct.
143 * @tc.type: FUNC
144 * */
145 HWTEST_F(ThreadPthrdTest, pthread_sigmask_001, TestSize.Level1)
146 {
147 sigset_t originalPthreadSignal;
148 sigset_t loadPthreadSignal;
149 sigset_t finalPthreadSignal;
150
151 sigemptyset(&originalPthreadSignal);
152 EXPECT_EQ(0, pthread_sigmask(SIG_BLOCK, nullptr, &originalPthreadSignal));
153 EXPECT_FALSE(sigismember(&originalPthreadSignal, SIGUSR1));
154 sigemptyset(&loadPthreadSignal);
155 sigaddset(&loadPthreadSignal, SIGUSR1);
156 EXPECT_EQ(0, pthread_sigmask(SIG_BLOCK, &loadPthreadSignal, nullptr));
157 sigemptyset(&finalPthreadSignal);
158 EXPECT_EQ(0, pthread_sigmask(SIG_BLOCK, nullptr, &finalPthreadSignal));
159 EXPECT_TRUE(sigismember(&finalPthreadSignal, SIGUSR1));
160 }
161
WaitSignalHandler(void * arg)162 static void* WaitSignalHandler(void* arg)
163 {
164 sigset_t waitSetBegin;
165 sigfillset(&waitSetBegin);
166 return reinterpret_cast<void*>(sigwait(&waitSetBegin, reinterpret_cast<int*>(arg)));
167 }
168
169 /**
170 * @tc.name: pthread_sigmask_002
171 * @tc.desc: Create a new thread, wait for the SIGUSR1 signal to be received, and verify that the received signal
172 * is correct
173 * @tc.type: FUNC
174 * */
175 HWTEST_F(ThreadPthrdTest, pthread_sigmask_002, TestSize.Level1)
176 {
177 sigset_t originalPthreadSignal;
178 pthread_t signalThread;
179 int receivedPthreadSignal;
180
181 sigemptyset(&originalPthreadSignal);
182 EXPECT_EQ(0, pthread_sigmask(SIG_BLOCK, &originalPthreadSignal, nullptr));
183 EXPECT_FALSE(sigismember(&originalPthreadSignal, SIGUSR1));
184 EXPECT_EQ(0, pthread_create(&signalThread, nullptr, WaitSignalHandler, &receivedPthreadSignal));
185 pthread_kill(signalThread, SIGUSR1);
186 pthread_join(signalThread, nullptr);
187 EXPECT_EQ(SIGUSR1, receivedPthreadSignal);
188 }
189
190 /**
191 * @tc.name: pthread_create_001
192 * @tc.desc: The normal function creation was successfully set, and the thread returned the same result as the initial
193 * creation
194 * @tc.type: FUNC
195 * */
196 HWTEST_F(ThreadPthrdTest, pthread_create_001, TestSize.Level1)
197 {
198 void* getRes = reinterpret_cast<void*>(666);
199
200 pthread_t thread;
201 EXPECT_EQ(0, pthread_create(&thread, nullptr, ReturnFunc, getRes));
202
203 void* realRes;
204 EXPECT_EQ(0, pthread_join(thread, &realRes));
205 EXPECT_EQ(getRes, realRes);
206 }
207
ThreadStr(void * arg)208 static void* ThreadStr(void* arg)
209 {
210 g_dtorOutput += *reinterpret_cast<std::string*>(arg);
211 return nullptr;
212 }
213
214 /**
215 * @tc.name: pthread_create_002
216 * @tc.desc: When creating and waiting for a thread, the specified function of the object in the thread's
217 * local storage can be correctly triggered, and the expected output result of the specified
218 * function can be obtained in the main thread
219 * @tc.type: FUNC
220 * */
221 HWTEST_F(ThreadPthrdTest, pthread_create_002, TestSize.Level1)
222 {
223 std::string msg("dtor");
224 pthread_t thread;
225 EXPECT_EQ(0, pthread_create(&thread, nullptr, ThreadStr, &msg));
226 EXPECT_EQ(0, pthread_join(thread, nullptr));
227 EXPECT_EQ("dtor", g_dtorOutput);
228 }
229
230 /**
231 * @tc.name: pthread_setcancelstate_001
232 * @tc.desc: Verify that the thread cancellation state was successfully set and verify the old state
233 * @tc.type: FUNC
234 * */
235 HWTEST_F(ThreadPthrdTest, pthread_setcancelstate_001, TestSize.Level1)
236 {
237 #ifdef FEATURE_PTHREAD_CANCEL
238 int oldstate;
239 EXPECT_EQ(0, pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate));
240 EXPECT_EQ(oldstate, PTHREAD_CANCEL_ENABLE);
241
242 EXPECT_EQ(0, pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate));
243 EXPECT_EQ(oldstate, PTHREAD_CANCEL_DISABLE);
244
245 EXPECT_EQ(0, pthread_setcancelstate(PTHREAD_CANCEL_MASKED, &oldstate));
246 EXPECT_EQ(oldstate, PTHREAD_CANCEL_ENABLE);
247
248 EXPECT_EQ(0, pthread_setcancelstate(PTHREAD_CANCEL_DEFERRED, &oldstate));
249 EXPECT_EQ(oldstate, PTHREAD_CANCEL_MASKED);
250
251 EXPECT_EQ(0, pthread_setcancelstate(PTHREAD_CANCEL_ASYNCHRONOUS, &oldstate));
252 EXPECT_EQ(oldstate, PTHREAD_CANCEL_DEFERRED);
253 #endif
254 }
255
256 /**
257 * @tc.name: pthread_kill_001
258 * @tc.desc: When creating and waiting for a thread, the specified function of the object in the thread's
259 * local storage can be correctly triggered, and the expected output result of the specified
260 * function can be obtained in the main thread.
261 * @tc.type: FUNC
262 * */
263 HWTEST_F(ThreadPthrdTest, pthread_kill_001, TestSize.Level1)
264 {
265 EXPECT_EQ(0, pthread_kill(pthread_self(), 0));
266 }
267
268 /**
269 * @tc.name: pthread_kill_002
270 * @tc.desc: Sending invalid signal to current thread, returning error.
271 * @tc.type: FUNC
272 * */
273 HWTEST_F(ThreadPthrdTest, pthread_kill_002, TestSize.Level1)
274 {
275 EXPECT_EQ(EINVAL, pthread_kill(pthread_self(), -6));
276 }
277
278 /**
279 * @tc.name: pthread_kill_003
280 * @tc.desc: sending a signal to an empty thread returned an error
281 * @tc.type: FUNC
282 * */
283 HWTEST_F(ThreadPthrdDeathTest, pthread_kill_003, TestSize.Level1)
284 {
285 pthread_t nullThread = 0;
286 EXPECT_DEATH(pthread_kill(nullThread, 0), ".*");
287 }
288
289 /**
290 * @tc.name: pthread_setschedparam_001
291 * @tc.desc: Testing the interface using dead threads
292 * @tc.type: FUNC
293 * */
294 HWTEST_F(ThreadPthrdDeathTest, pthread_setschedparam_001, TestSize.Level1)
295 {
296 pthread_t deadThread;
297 pthread_create(&deadThread, nullptr, ReturnFunc, nullptr);
298 pthread_join(deadThread, nullptr);
299
300 int loadPolicy = 0;
301 sched_param pthreadSchedParam;
302 EXPECT_DEATH(pthread_setschedparam(deadThread, loadPolicy, &pthreadSchedParam), ".*");
303 }
304
305 /**
306 * @tc.name: pthread_setschedparam_002
307 * @tc.desc: Testing the interface using null threads
308 * @tc.type: FUNC
309 * */
310 HWTEST_F(ThreadPthrdDeathTest, pthread_setschedparam_002, TestSize.Level1)
311 {
312 pthread_t nullThread = 0;
313 int loadPolicy = 0;
314 sched_param pthreadSchedParam;
315 EXPECT_DEATH(pthread_setschedparam(nullThread, loadPolicy, &pthreadSchedParam), ".*");
316 }
317
318 /**
319 * @tc.name: pthread_setschedparam_003
320 * @tc.desc: Correct handling of invalid scheduling loadPolicy values
321 * @tc.type: FUNC
322 * */
323 HWTEST_F(ThreadPthrdTest, pthread_setschedparam_003, TestSize.Level1)
324 {
325 sched_param pthreadSchedParam = { .sched_priority = -6 };
326 EXPECT_EQ(EINVAL, pthread_setschedparam(pthread_self(), -6, &pthreadSchedParam));
327 }
328
329 /**
330 * @tc.name: pthread_getschedparam_001
331 * @tc.desc: Testing the interface using dead threads
332 * @tc.type: FUNC
333 * */
334 HWTEST_F(ThreadPthrdDeathTest, pthread_getschedparam_001, TestSize.Level1)
335 {
336 pthread_t deadThread;
337 pthread_create(&deadThread, nullptr, ReturnFunc, nullptr);
338 pthread_join(deadThread, nullptr);
339
340 int loadPolicy;
341 sched_param pthreadSchedParam;
342 EXPECT_DEATH(pthread_getschedparam(deadThread, &loadPolicy, &pthreadSchedParam), ".*");
343 }
344
345 /**
346 * @tc.name: pthread_setschedprio_001
347 * @tc.desc: Testing the interface using dead threads
348 * @tc.type: FUNC
349 * */
350 HWTEST_F(ThreadPthrdDeathTest, pthread_setschedprio_001, TestSize.Level1)
351 {
352 pthread_t deadThread;
353 pthread_create(&deadThread, nullptr, ReturnFunc, nullptr);
354 pthread_join(deadThread, nullptr);
355
356 EXPECT_DEATH(pthread_setschedprio(deadThread, 10), ".*");
357 }
358
359 /**
360 * @tc.name: pthread_setschedprio_002
361 * @tc.desc: Testing the interface using null threads
362 * @tc.type: FUNC
363 * */
364 HWTEST_F(ThreadPthrdDeathTest, pthread_setschedprio_002, TestSize.Level1)
365 {
366 pthread_t nullThread = 0;
367 EXPECT_DEATH(pthread_setschedprio(nullThread, 10), ".*");
368 }
369
370 /**
371 * @tc.name: pthread_setschedprio_003
372 * @tc.desc: Correct handling of invalid scheduling loadPolicy values
373 * @tc.type: FUNC
374 * */
375 HWTEST_F(ThreadPthrdTest, pthread_setschedprio_003, TestSize.Level1)
376 {
377 EXPECT_EQ(EINVAL, pthread_setschedprio(pthread_self(), 1000));
378 }
379
380 /**
381 * @tc.name: pthread_getcpuclockid_001
382 * @tc.desc: Successfully called the function on the thread
383 * @tc.type: FUNC
384 * */
385 HWTEST_F(ThreadPthrdTest, pthread_getcpuclockid_001, TestSize.Level1)
386 {
387 g_controlFlag = true;
388 pthread_t thread;
389 clockid_t realClock;
390 timespec times;
391 EXPECT_EQ(0, pthread_create(&thread, nullptr, BeginLoop, nullptr));
392 EXPECT_EQ(0, pthread_getcpuclockid(thread, &realClock));
393 EXPECT_EQ(0, clock_gettime(realClock, ×));
394 CancelLoop();
395 EXPECT_EQ(0, pthread_join(thread, nullptr));
396 }
397
398 /**
399 * @tc.name: pthread_getcpuclockid_002
400 * @tc.desc: Using dead threads for death testing This interface returns invalid threads
401 * @tc.type: FUNC
402 * */
403 HWTEST_F(ThreadPthrdDeathTest, pthread_getcpuclockid_002, TestSize.Level1)
404 {
405 pthread_t deadThread;
406 clockid_t realClock;
407 pthread_create(&deadThread, nullptr, ReturnFunc, nullptr);
408 pthread_join(deadThread, nullptr);
409 EXPECT_DEATH(pthread_getcpuclockid(deadThread, &realClock), ".*");
410 }
411
412 /**
413 * @tc.name: pthread_getcpuclockid_003
414 * @tc.desc: Using null threads for death testing This interface returns invalid threads
415 * @tc.type: FUNC
416 * */
417 HWTEST_F(ThreadPthrdDeathTest, pthread_getcpuclockid_003, TestSize.Level1)
418 {
419 pthread_t nullThread = 0;
420 clockid_t c;
421 EXPECT_DEATH(pthread_getcpuclockid(nullThread, &c), ".*");
422 }
423
JoinThrd(void * arg)424 static void* JoinThrd(void* arg)
425 {
426 return reinterpret_cast<void*>(pthread_join(reinterpret_cast<pthread_t>(arg), nullptr));
427 }
428
429 /**
430 * @tc.name: pthread_join_002
431 * @tc.desc: Create thread thread1, strongly convert thread1 into a parameter of thread thread2, and set the destructor
432 * of thread2 to add thread1 to pthread_join, call pthread again_ Invalid return for detach (thread1), determine if
433 * thread1 does not end with a detached attribute
434 * @tc.type: FUNC
435 * */
436 HWTEST_F(ThreadPthrdDeathTest, pthread_join_002, TestSize.Level1)
437 {
438 g_controlFlag = true;
439 pthread_t thread1;
440 pthread_create(&thread1, nullptr, BeginLoop, nullptr);
441 pthread_t thread2;
442 pthread_create(&thread2, nullptr, JoinThrd, reinterpret_cast<void*>(thread1));
443
444 sleep(1);
445 EXPECT_DEATH(pthread_detach(thread1), ".*");
446 pthread_attr_t detachAttr;
447 EXPECT_DEATH(pthread_getattr_np(thread1, &detachAttr), ".*");
448 int detachState;
449 pthread_attr_getdetachstate(&detachAttr, &detachState);
450 pthread_attr_destroy(&detachAttr);
451 EXPECT_EQ(PTHREAD_CREATE_JOINABLE, detachState);
452
453 CancelLoop();
454
455 void* joinResult;
456 EXPECT_EQ(0, pthread_join(thread2, &joinResult));
457 EXPECT_EQ(0U, reinterpret_cast<uintptr_t>(joinResult));
458 }
459
460 /**
461 * @tc.name: pthread_join_003
462 * @tc.desc: Test that two identical threads call the function successively. The first time it succeeds, the second time
463 * it fails, and finally verify the results of the first call
464 * @tc.type: FUNC
465 * */
466 HWTEST_F(ThreadPthrdDeathTest, pthread_join_003, TestSize.Level1)
467 {
468 g_controlFlag = true;
469 pthread_t thread1;
470 pthread_create(&thread1, nullptr, BeginLoop, nullptr);
471
472 pthread_t thread2;
473 pthread_create(&thread2, nullptr, JoinThrd, reinterpret_cast<void*>(thread1));
474
475 sleep(1);
476
477 EXPECT_DEATH(pthread_join(thread1, nullptr), ".*");
478
479 CancelLoop();
480
481 void* joinResult;
482 EXPECT_EQ(0, pthread_join(thread2, &joinResult));
483 EXPECT_EQ(0U, reinterpret_cast<uintptr_t>(joinResult));
484 }
485
486 /**
487 * @tc.name: pthread_join_004
488 * @tc.desc: Testing the interface using dead threads returns invalid threads
489 * @tc.type: FUNC
490 * */
491 HWTEST_F(ThreadPthrdDeathTest, pthread_join_004, TestSize.Level1)
492 {
493 pthread_t deadThread;
494 pthread_create(&deadThread, nullptr, ReturnFunc, nullptr);
495 pthread_join(deadThread, nullptr);
496
497 EXPECT_DEATH(pthread_join(deadThread, nullptr), ".*");
498 }
499
500 /**
501 * @tc.name: pthread_join_005
502 * @tc.desc: Testing the interface using null threads returns invalid threads
503 * @tc.type: FUNC
504 * */
505 HWTEST_F(ThreadPthrdDeathTest, pthread_join_005, TestSize.Level1)
506 {
507 pthread_t nullThread = 0;
508 EXPECT_DEATH(pthread_join(nullThread, nullptr), ".*");
509 }
510
511 struct PthreadGettidArg {
512 pid_t tid = 0;
513 pthread_mutex_t mutex;
514 };
515
ThreadGettidNpFn(PthreadGettidArg * arg)516 static void* ThreadGettidNpFn(PthreadGettidArg* arg)
517 {
518 if (arg == nullptr) {
519 return nullptr;
520 }
521 arg->tid = gettid();
522 pthread_mutex_lock(&arg->mutex);
523 pthread_mutex_unlock(&arg->mutex);
524 return nullptr;
525 }
526
527 /**
528 * @tc.name: pthread_gettid_np_001
529 * @tc.desc: Get the ID of the current thread for comparison and equality.
530 * @tc.type: FUNC
531 * */
532 HWTEST_F(ThreadPthrdTest, pthread_gettid_np_001, TestSize.Level1)
533 {
534 EXPECT_EQ(gettid(), pthread_gettid_np(pthread_self()));
535 }
536
537 /**
538 * @tc.name: pthread_gettid_np_002
539 * @tc.desc: 1. Get the ID of the current thread for comparison and equality.
540 * 2. Call the getid function in the new thread to get the ID equal to the main function ID
541
542 * @tc.type: FUNC
543 * */
544 HWTEST_F(ThreadPthrdTest, pthread_gettid_np_002, TestSize.Level1)
545 {
546 pthread_t thread;
547 pthread_mutex_t pMutex = PTHREAD_MUTEX_INITIALIZER;
548 PthreadGettidArg arg;
549 arg.mutex = pMutex;
550 pthread_mutex_lock(&arg.mutex);
551 pthread_create(&thread, nullptr, reinterpret_cast<void* (*)(void*)>(ThreadGettidNpFn), &arg);
552 pid_t resultTid = pthread_gettid_np(thread);
553 pthread_mutex_unlock(&arg.mutex);
554 EXPECT_EQ(0, pthread_join(thread, nullptr));
555 EXPECT_EQ(arg.tid, resultTid);
556 }
557
ThreadExitFunc(void * arg)558 void* ThreadExitFunc(void* arg)
559 {
560 const char* message = "pthread_exit";
561 pthread_exit(const_cast<void*>(static_cast<const void*>(message)));
562 }
563
564 /**
565 * @tc.name: pthread_exit_001
566 * @tc.desc: Verify pthread_exit process success
567 * @tc.type: FUNC
568 */
569 HWTEST_F(ThreadPthrdTest, pthread_exit_001, TestSize.Level1)
570 {
571 pthread_t ph;
572 EXPECT_EQ(0, pthread_create(&ph, nullptr, ThreadExitFunc, nullptr));
573 void* resultFn = nullptr;
574 EXPECT_EQ(0, pthread_join(ph, &resultFn));
575 EXPECT_STREQ("pthread_exit", (char*)resultFn);
576 }