1 /*
2 * Copyright (c) 2006-2021, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2021-08-12 flybreak the first version
9 *
10 * case 1:rt_signal_install, install all available signal
11 * case 2:rt_signal_install, install illegal signal
12 * case 3:rt_signal_mask/unmask, one thread self, install and unmask, then kill, should received.
13 * case 4:rt_signal_mask/unmask, one thread self, install and unmask and mask, then kill, should can't received.
14 * case 5:rt_signal_wait, two thread, thread1: install and unmask, then wait 1s; thread2: kill, should received.
15 * case 6:rt_signal_wait, two thread, thread1: install and unmask, then wait 1s; thread2: sleep 2s then kill, should can't received.
16 * case 7:rt_signal_kill, kill legal thread, return 0;
17 * case 8:rt_signal_kill, kill illegal thread, return failed (unused);
18 * case 9:rt_signal_kill, kill illegal signo, return -RT_EINVAL;
19 *
20 */
21
22 #include <rtthread.h>
23 #include "utest.h"
24
25 static volatile int recive_sig = 0;
26 static struct rt_semaphore _received_signal;
27
sig_handle_default(int signo)28 void sig_handle_default(int signo)
29 {
30 recive_sig = signo;
31 }
32
rt_signal_install_test(void)33 static void rt_signal_install_test(void)
34 {
35 int signo;
36 rt_sighandler_t result;
37
38 /* case 1:rt_signal_install, install all available signal. */
39 for (signo = 0; signo < RT_SIG_MAX; signo++)
40 {
41 result = rt_signal_install(signo, sig_handle_default);
42 uassert_true(result != SIG_ERR);
43 }
44 /* case 2:rt_signal_install, install illegal signal. */
45 result = rt_signal_install(signo, sig_handle_default);
46 uassert_true(result == SIG_ERR);
47
48 return;
49 }
50
rt_signal_mask_test(void)51 static void rt_signal_mask_test(void)
52 {
53 int signo;
54 rt_sighandler_t result;
55
56 /* case 3:rt_signal_mask/unmask, one thread self, install and unmask, then kill, should received. */
57 for (signo = 0; signo < RT_SIG_MAX; signo++)
58 {
59 recive_sig = -1;
60 result = rt_signal_install(signo, sig_handle_default);
61 uassert_true(result != SIG_ERR);
62 rt_signal_unmask(signo);
63 uassert_int_equal(rt_thread_kill(rt_thread_self(), signo), RT_EOK);
64 rt_thread_mdelay(1);
65 uassert_int_equal(recive_sig, signo);
66 }
67
68 return;
69 }
70
rt_signal_unmask_test(void)71 static void rt_signal_unmask_test(void)
72 {
73 int signo;
74 rt_sighandler_t result;
75
76 /* case 4:rt_signal_mask/unmask, one thread self, install and unmask and mask, then kill, should can't received. */
77 for (signo = 0; signo < RT_SIG_MAX; signo++)
78 {
79 recive_sig = -1;
80 result = rt_signal_install(signo, sig_handle_default);
81 uassert_true(result != SIG_ERR);
82 rt_signal_unmask(signo);
83 rt_signal_mask(signo);
84 uassert_int_equal(rt_thread_kill(rt_thread_self(), signo), RT_EOK);
85 rt_thread_mdelay(1);
86 uassert_int_not_equal(recive_sig, signo);
87 }
88
89 return;
90 }
91
rt_signal_kill_test(void)92 static void rt_signal_kill_test(void)
93 {
94 int signo;
95 rt_sighandler_t result;
96
97 /* case 7:rt_signal_kill, kill legal thread, return 0; */
98 for (signo = 0; signo < RT_SIG_MAX; signo++)
99 {
100 recive_sig = -1;
101 result = rt_signal_install(signo, sig_handle_default);
102 uassert_true(result != SIG_ERR);
103 rt_signal_unmask(signo);
104 uassert_int_equal(rt_thread_kill(rt_thread_self(), signo), RT_EOK);
105 rt_thread_mdelay(1);
106 uassert_int_equal(recive_sig, signo);
107 }
108 /* case 8:rt_signal_kill, kill illegal thread, return failed; */
109 // uassert_true(rt_thread_kill((rt_thread_t)-1, signo) == -RT_ERROR);
110
111 /* case 9:rt_signal_kill, kill illegal signo, return -RT_EINVAL; */
112 uassert_true(rt_thread_kill(rt_thread_self(), -1) == -RT_EINVAL);
113
114 return;
115 }
116
rt_signal_wait_thread(void * parm)117 void rt_signal_wait_thread(void *parm)
118 {
119 sigset_t selectset;
120 siginfo_t recive_si;
121
122 rt_signal_install(SIGUSR1, sig_handle_default);
123 rt_signal_unmask(SIGUSR1);
124
125 (void)sigemptyset(&selectset);
126 (void)sigaddset(&selectset, SIGUSR1);
127
128 /* case 5:rt_signal_wait, two thread, thread1: install and unmask, then wait 1s; thread2: kill, should received. */
129 if (rt_signal_wait((void *)&selectset, &recive_si, RT_TICK_PER_SECOND) != RT_EOK)
130 {
131 return;
132 }
133
134 recive_sig = recive_si.si_signo;
135
136 LOG_I("received signal %d", recive_sig);
137 rt_sem_release(&_received_signal);
138 }
139
rt_signal_wait_test(void)140 static void rt_signal_wait_test(void)
141 {
142 rt_thread_t t1;
143
144 recive_sig = -1;
145 t1 = rt_thread_create("sig_t1", rt_signal_wait_thread, 0, 4096, 14, 10);
146 if (t1)
147 {
148 rt_thread_startup(t1);
149 }
150
151 rt_thread_mdelay(1);
152 /* case 5:rt_signal_wait, two thread, thread1: install and unmask, then wait 1s; thread2: kill, should received. */
153 uassert_int_equal(rt_thread_kill(t1, SIGUSR1), RT_EOK);
154 rt_sem_take(&_received_signal, RT_WAITING_FOREVER);
155 uassert_int_equal(recive_sig, SIGUSR1);
156
157 return;
158 }
159
rt_signal_wait_test2(void)160 static void rt_signal_wait_test2(void)
161 {
162 rt_thread_t t1;
163
164 recive_sig = -1;
165 t1 = rt_thread_create("sig_t1", rt_signal_wait_thread, 0, 4096, 14, 10);
166 if (t1)
167 {
168 rt_thread_startup(t1);
169 }
170
171 /* case 6:rt_signal_wait, two thread, thread1: install and unmask, then wait 1s; thread2: sleep 2s then kill, should can't received. */
172 rt_thread_mdelay(2000);
173 uassert_int_equal(rt_thread_kill(t1, SIGUSR1), RT_EOK);
174 uassert_int_not_equal(
175 rt_sem_take(&_received_signal, 1),
176 RT_EOK);
177 uassert_int_not_equal(recive_sig, SIGUSR1);
178
179 return;
180 }
181
utest_tc_init(void)182 static rt_err_t utest_tc_init(void)
183 {
184 rt_sem_init(&_received_signal, "utest", 0, RT_IPC_FLAG_PRIO);
185 return RT_EOK;
186 }
187
utest_tc_cleanup(void)188 static rt_err_t utest_tc_cleanup(void)
189 {
190 rt_sem_detach(&_received_signal);
191 return RT_EOK;
192 }
193
testcase(void)194 static void testcase(void)
195 {
196 #ifdef RT_USING_HEAP
197 UTEST_UNIT_RUN(rt_signal_install_test);
198 UTEST_UNIT_RUN(rt_signal_mask_test);
199 UTEST_UNIT_RUN(rt_signal_unmask_test);
200 UTEST_UNIT_RUN(rt_signal_kill_test);
201 UTEST_UNIT_RUN(rt_signal_wait_test);
202 UTEST_UNIT_RUN(rt_signal_wait_test2);
203 #endif /* RT_USING_HEAP */
204 }
205 UTEST_TC_EXPORT(testcase, "testcases.kernel.signal_tc", utest_tc_init, utest_tc_cleanup, 1000);
206
207 /*********************** end of file ****************************/
208