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