Skip to content

Commit 8c22bb2

Browse files
Fix-Pointxiaoxiang781216
authored andcommitted
testing/ostest: Add wdog_test to ostest
This patch introduces wdog_test, which is used to ensure the functional correctness of the wdog module. Signed-off-by: ouyangxiangzhen <[email protected]>
1 parent 23bf7fb commit 8c22bb2

File tree

5 files changed

+268
-2
lines changed

5 files changed

+268
-2
lines changed

testing/ostest/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ if(CONFIG_TESTING_OSTEST)
2727
sigprocmask.c
2828
sighand.c
2929
signest.c
30-
sighelper.c)
30+
sighelper.c
31+
wdog.c)
3132

3233
if(CONFIG_DEV_NULL)
3334
list(APPEND SRCS dev_null.c)

testing/ostest/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ MODULE = $(CONFIG_TESTING_OSTEST)
3030
# NuttX OS Test
3131

3232
CSRCS = getopt.c libc_memmem.c restart.c sigprocmask.c sighand.c \
33-
signest.c sighelper.c
33+
signest.c sighelper.c wdog.c
3434

3535
MAINSRC = ostest_main.c
3636

testing/ostest/ostest.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,10 @@ void signest_test(void);
209209

210210
void suspend_test(void);
211211

212+
/* wdog.c *******************************************************************/
213+
214+
void wdog_test(void);
215+
212216
/* posixtimers.c ************************************************************/
213217

214218
void timer_test(void);

testing/ostest/ostest_main.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,12 @@ static int user_main(int argc, char *argv[])
524524
check_test_memory_usage();
525525
#endif
526526

527+
#ifndef CONFIG_BUILD_KERNEL
528+
printf("\nuser_main: wdog test\n");
529+
wdog_test();
530+
check_test_memory_usage();
531+
#endif
532+
527533
#ifndef CONFIG_DISABLE_POSIX_TIMERS
528534
/* Verify posix timers (with SIGEV_SIGNAL) */
529535

testing/ostest/wdog.c

Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
/****************************************************************************
2+
* apps/testing/ostest/wdog.c
3+
*
4+
* Licensed to the Apache Software Foundation (ASF) under one or more
5+
* contributor license agreements. See the NOTICE file distributed with
6+
* this work for additional information regarding copyright ownership. The
7+
* ASF licenses this file to you under the Apache License, Version 2.0 (the
8+
* "License"); you may not use this file except in compliance with the
9+
* License. You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16+
* License for the specific language governing permissions and limitations
17+
* under the License.
18+
*
19+
****************************************************************************/
20+
21+
/****************************************************************************
22+
* Included Files
23+
****************************************************************************/
24+
25+
#include <nuttx/config.h>
26+
#include <nuttx/wdog.h>
27+
28+
#include <pthread.h>
29+
#include <stdio.h>
30+
#include <assert.h>
31+
#include <unistd.h>
32+
33+
/****************************************************************************
34+
* Pre-processor Definitions
35+
****************************************************************************/
36+
37+
#define WDOGTEST_RAND_ITER 1024
38+
#define WDOGTEST_THREAD_NR 8
39+
40+
#define wdtest_assert(x) ASSERT(x)
41+
42+
#define wdtest_printf(...) printf(__VA_ARGS__)
43+
44+
/****************************************************************************
45+
* Private Type
46+
****************************************************************************/
47+
48+
typedef struct wdtest_param_s
49+
{
50+
uint64_t callback_cnt;
51+
clock_t triggerd_tick;
52+
} wdtest_param_t;
53+
54+
/****************************************************************************
55+
* Private Functions
56+
****************************************************************************/
57+
58+
#ifndef CONFIG_BUILD_KERNEL
59+
static void wdtest_callback(wdparm_t param)
60+
{
61+
struct timespec tp;
62+
FAR wdtest_param_t *wdtest_param = (FAR wdtest_param_t *)param;
63+
64+
clock_gettime(CLOCK_MONOTONIC, &tp);
65+
66+
wdtest_param->callback_cnt += 1;
67+
wdtest_param->triggerd_tick = clock_time2ticks(&tp);
68+
}
69+
70+
static void wdtest_once(FAR struct wdog_s *wdog, FAR wdtest_param_t *param,
71+
sclock_t delay_ns)
72+
{
73+
uint64_t cnt;
74+
long diff;
75+
clock_t wdset_tick;
76+
struct timespec tp;
77+
78+
clock_gettime(CLOCK_MONOTONIC, &tp);
79+
80+
wdset_tick = clock_time2ticks(&tp);
81+
cnt = param->callback_cnt;
82+
wdtest_assert(wd_start(wdog, NSEC2TICK(delay_ns), wdtest_callback,
83+
(wdparm_t)param) == OK);
84+
usleep(delay_ns / 1000 + 1);
85+
diff = (long)(param->triggerd_tick - wdset_tick);
86+
wdtest_printf("wd_start with delay %ld ns, latency tick %ld\n",
87+
(long)delay_ns, (long)(diff - NSEC2TICK(delay_ns)));
88+
wdtest_assert(cnt + 1 == param->callback_cnt);
89+
}
90+
91+
static void wdtest_rand(FAR struct wdog_s *wdog, FAR wdtest_param_t *param,
92+
sclock_t rand_ns)
93+
{
94+
int idx;
95+
sclock_t delay_ns;
96+
uint64_t cnt = param->callback_cnt;
97+
98+
for (idx = 0; idx < WDOGTEST_RAND_ITER; idx++)
99+
{
100+
delay_ns = rand() % rand_ns;
101+
wdtest_assert(wd_start(wdog, NSEC2TICK(delay_ns), wdtest_callback,
102+
(wdparm_t)param) == 0);
103+
104+
/* Wait or Cancel 50/50 */
105+
106+
if (delay_ns % 2)
107+
{
108+
usleep((delay_ns / 1000) + 1);
109+
wdtest_assert(cnt + 1 == param->callback_cnt);
110+
}
111+
else
112+
{
113+
wd_cancel(wdog);
114+
}
115+
116+
cnt = param->callback_cnt;
117+
}
118+
}
119+
120+
static void wdog_test_run(FAR wdtest_param_t *param)
121+
{
122+
uint64_t cnt;
123+
sclock_t rest;
124+
sclock_t delay;
125+
struct wdog_s test_wdog =
126+
{
127+
0
128+
};
129+
130+
/* Wrong arguments, all 7 combinations */
131+
132+
wdtest_assert(wd_start(NULL, 0, NULL, (wdparm_t)NULL) != OK);
133+
wdtest_assert(wd_start(NULL, 0, wdtest_callback, (wdparm_t)NULL) != OK);
134+
wdtest_assert(wd_start(NULL, -1, NULL, (wdparm_t)NULL) != OK);
135+
wdtest_assert(wd_start(NULL, -1, wdtest_callback, (wdparm_t)NULL) != OK);
136+
wdtest_assert(wd_start(&test_wdog, 0, NULL, (wdparm_t)NULL) != OK);
137+
wdtest_assert(wd_start(&test_wdog, -1, NULL, (wdparm_t)NULL) != OK);
138+
wdtest_assert(wd_start(&test_wdog, -1, wdtest_callback, (wdparm_t)NULL)
139+
!= OK);
140+
141+
/* Delay = 0 */
142+
143+
wdtest_once(&test_wdog, param, 0);
144+
145+
/* Delay > 0, small */
146+
147+
wdtest_once(&test_wdog, param, 1);
148+
149+
/* Delay > 0, middle 100us */
150+
151+
wdtest_once(&test_wdog, param, 100000);
152+
153+
/* Delay > 0, large ~123456us */
154+
155+
wdtest_once(&test_wdog, param, 123456789);
156+
157+
/* Delay > 0, maximum */
158+
159+
cnt = param->callback_cnt;
160+
161+
/* Maximum */
162+
163+
delay = ((clock_t)1 << (sizeof(sclock_t) * CHAR_BIT - 1)) - 1;
164+
wdtest_assert(wd_start(&test_wdog, delay,
165+
wdtest_callback, (wdparm_t)param) == OK);
166+
167+
/* Sleep for 1s */
168+
169+
usleep(USEC_PER_SEC);
170+
171+
/* Testing wd_gettime */
172+
173+
wdtest_assert(wd_gettime(NULL) == 0);
174+
wdtest_assert(wd_cancel(NULL) != 0);
175+
176+
/* Ensure watchdog not alarmed */
177+
178+
wdtest_assert(cnt == param->callback_cnt);
179+
180+
rest = wd_gettime(&test_wdog);
181+
182+
wdtest_assert(rest < delay && rest > (delay >> 1));
183+
184+
wdtest_printf("wd_start with maximum delay, cancel %ld\n", (long)rest);
185+
186+
wdtest_assert(wd_cancel(&test_wdog) == 0);
187+
188+
/* Delay wraparound (delay < 0) */
189+
190+
wdtest_assert(wd_start(&test_wdog, delay + 1,
191+
wdtest_callback, (wdparm_t)param) != OK);
192+
wdtest_assert(wd_gettime(&test_wdog) == 0);
193+
194+
/* Random delay ~1024us */
195+
196+
wdtest_rand(&test_wdog, param, 1024);
197+
198+
/* Random delay ~12345us */
199+
200+
wdtest_rand(&test_wdog, param, 12345);
201+
}
202+
203+
/* Multi threaded */
204+
205+
static FAR void *wdog_test_thread(FAR void *param)
206+
{
207+
wdog_test_run(param);
208+
return NULL;
209+
}
210+
211+
/****************************************************************************
212+
* Public Functions
213+
****************************************************************************/
214+
215+
void wdog_test(void)
216+
{
217+
int ret;
218+
unsigned int thread_id;
219+
pthread_attr_t attr;
220+
pthread_t pthreads[WDOGTEST_THREAD_NR];
221+
wdtest_param_t params[WDOGTEST_THREAD_NR] =
222+
{
223+
0
224+
};
225+
226+
printf("wdog_test start...\n");
227+
228+
ret = pthread_attr_init(&attr);
229+
if (ret)
230+
{
231+
wdtest_printf("pthread_attr_init failed %d\n", ret);
232+
}
233+
234+
/* Create wdog test thread */
235+
236+
for (thread_id = 0; thread_id < WDOGTEST_THREAD_NR; thread_id++)
237+
{
238+
pthread_create(&pthreads[thread_id], &attr, wdog_test_thread,
239+
&params[thread_id]);
240+
}
241+
242+
for (thread_id = 0; thread_id < WDOGTEST_THREAD_NR; thread_id++)
243+
{
244+
pthread_join(pthreads[thread_id], NULL);
245+
}
246+
247+
ret = pthread_attr_destroy(&attr);
248+
if (ret)
249+
{
250+
wdtest_printf("pthread_attr_destroy failed %d\n", ret);
251+
}
252+
253+
printf("wdog_test end...\n");
254+
}
255+
#endif

0 commit comments

Comments
 (0)