Skip to content

Commit 72e7deb

Browse files
cfriedtcarlescufi
authored andcommitted
tests: posix: tests for nanosleep(2)
This commit provides test-cases for nanosleep(2) Signed-off-by: Christopher Friedt <[email protected]>
1 parent 8bcf005 commit 72e7deb

File tree

2 files changed

+250
-1
lines changed

2 files changed

+250
-1
lines changed

tests/posix/common/src/main.c

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,18 @@ extern void test_posix_pthread_execution(void);
1919
extern void test_posix_pthread_termination(void);
2020
extern void test_posix_multiple_threads_single_key(void);
2121
extern void test_posix_single_thread_multiple_keys(void);
22+
extern void test_nanosleep_NULL_NULL(void);
23+
extern void test_nanosleep_NULL_notNULL(void);
24+
extern void test_nanosleep_notNULL_NULL(void);
25+
extern void test_nanosleep_notNULL_notNULL(void);
26+
extern void test_nanosleep_req_is_rem(void);
27+
extern void test_nanosleep_n1_0(void);
28+
extern void test_nanosleep_0_n1(void);
29+
extern void test_nanosleep_n1_n1(void);
30+
extern void test_nanosleep_0_1000000000(void);
31+
extern void test_nanosleep_0_1(void);
32+
extern void test_nanosleep_0_500000000(void);
33+
extern void test_nanosleep_1_0(void);
2234

2335
void test_main(void)
2436
{
@@ -34,7 +46,19 @@ void test_main(void)
3446
ztest_unit_test(test_posix_mqueue),
3547
ztest_unit_test(test_posix_realtime),
3648
ztest_unit_test(test_posix_timer),
37-
ztest_unit_test(test_posix_rw_lock)
49+
ztest_unit_test(test_posix_rw_lock),
50+
ztest_unit_test(test_nanosleep_NULL_NULL),
51+
ztest_unit_test(test_nanosleep_NULL_notNULL),
52+
ztest_unit_test(test_nanosleep_notNULL_NULL),
53+
ztest_unit_test(test_nanosleep_notNULL_notNULL),
54+
ztest_unit_test(test_nanosleep_req_is_rem),
55+
ztest_unit_test(test_nanosleep_n1_0),
56+
ztest_unit_test(test_nanosleep_0_n1),
57+
ztest_unit_test(test_nanosleep_n1_n1),
58+
ztest_unit_test(test_nanosleep_0_1000000000),
59+
ztest_unit_test(test_nanosleep_0_1),
60+
ztest_unit_test(test_nanosleep_0_500000000),
61+
ztest_unit_test(test_nanosleep_1_0)
3862
);
3963
ztest_run_test_suite(posix_apis);
4064
}

tests/posix/common/src/nanosleep.c

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
/*
2+
* Copyright (c) 2018 Friedt Professional Engineering Services, Inc
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <ztest.h>
8+
#include <errno.h>
9+
#include <posix/time.h>
10+
#include <stdint.h>
11+
#include <sys_clock.h>
12+
13+
/* TODO: Upper bounds check when hr timers are available */
14+
#define NSEC_PER_TICK \
15+
(NSEC_PER_SEC / CONFIG_SYS_CLOCK_TICKS_PER_SEC)
16+
#define NSEC_PER_CYCLE \
17+
(NSEC_PER_SEC / CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC)
18+
19+
/** req and rem are both NULL */
20+
void test_nanosleep_NULL_NULL(void)
21+
{
22+
int r = nanosleep(NULL, NULL);
23+
24+
zassert_equal(r, -1, "actual: %d expected: %d", r, -1);
25+
zassert_equal(errno, EFAULT, "actual: %d expected: %d", errno, EFAULT);
26+
}
27+
28+
/**
29+
* req is NULL, rem is non-NULL (all-zero)
30+
*
31+
* Expect rem to be the same when function returns
32+
*/
33+
void test_nanosleep_NULL_notNULL(void)
34+
{
35+
struct timespec rem = {};
36+
37+
errno = 0;
38+
int r = nanosleep(NULL, &rem);
39+
40+
zassert_equal(r, -1, "actual: %d expected: %d", r, -1);
41+
zassert_equal(errno, EFAULT, "actual: %d expected: %d",
42+
errno, EFAULT);
43+
zassert_equal(rem.tv_sec, 0, "actual: %d expected: %d",
44+
rem.tv_sec, 0);
45+
zassert_equal(rem.tv_nsec, 0, "actual: %d expected: %d",
46+
rem.tv_nsec, 0);
47+
}
48+
49+
/**
50+
* req is non-NULL (all-zero), rem is NULL
51+
*
52+
* Expect req to be the same when function returns
53+
*/
54+
void test_nanosleep_notNULL_NULL(void)
55+
{
56+
struct timespec req = {};
57+
58+
errno = 0;
59+
int r = nanosleep(&req, NULL);
60+
61+
zassert_equal(req.tv_sec, 0, "actual: %d expected: %d",
62+
req.tv_sec, 0);
63+
zassert_equal(req.tv_nsec, 0, "actual: %d expected: %d",
64+
req.tv_nsec, 0);
65+
zassert_equal(r, 0, "actual: %d expected: %d", r, -1);
66+
zassert_equal(errno, 0, "actual: %d expected: %d", errno, 0);
67+
}
68+
69+
/**
70+
* req is non-NULL (all-zero), rem is non-NULL (all-zero)
71+
*
72+
* Expect req & rem to be the same when function returns
73+
*/
74+
void test_nanosleep_notNULL_notNULL(void)
75+
{
76+
struct timespec req = {};
77+
struct timespec rem = {};
78+
79+
errno = 0;
80+
int r = nanosleep(&req, &rem);
81+
82+
zassert_equal(r, 0, "actual: %d expected: %d", r, -1);
83+
zassert_equal(errno, 0, "actual: %d expected: %d", errno, 0);
84+
zassert_equal(req.tv_sec, 0, "actual: %d expected: %d",
85+
req.tv_sec, 0);
86+
zassert_equal(req.tv_nsec, 0, "actual: %d expected: %d",
87+
req.tv_nsec, 0);
88+
zassert_equal(rem.tv_sec, 0, "actual: %d expected: %d",
89+
rem.tv_sec, 0);
90+
zassert_equal(rem.tv_nsec, 0, "actual: %d expected: %d",
91+
rem.tv_nsec, 0);
92+
}
93+
94+
/**
95+
* req and rem point to the same timespec
96+
*
97+
* Normative spec says they may be the same.
98+
* Expect rem to be zero after returning.
99+
*/
100+
void test_nanosleep_req_is_rem(void)
101+
{
102+
struct timespec ts = {0, 1};
103+
104+
errno = 0;
105+
int r = nanosleep(&ts, &ts);
106+
107+
zassert_equal(r, 0, "actual: %d expected: %d", r, -1);
108+
zassert_equal(errno, 0, "actual: %d expected: %d", errno, 0);
109+
zassert_equal(ts.tv_sec, 0, "actual: %d expected: %d",
110+
ts.tv_sec, 0);
111+
zassert_equal(ts.tv_nsec, 0, "actual: %d expected: %d",
112+
ts.tv_nsec, 0);
113+
}
114+
115+
/** req tv_sec is -1 */
116+
void test_nanosleep_n1_0(void)
117+
{
118+
struct timespec req = {-1, 0};
119+
120+
errno = 0;
121+
int r = nanosleep(&req, NULL);
122+
123+
zassert_equal(r, -1, "actual: %d expected: %d", r, -1);
124+
zassert_equal(errno, EINVAL, "actual: %d expected: %d", errno, EFAULT);
125+
}
126+
127+
/** req tv_nsec is -1 */
128+
void test_nanosleep_0_n1(void)
129+
{
130+
struct timespec req = {0, -1};
131+
132+
errno = 0;
133+
int r = nanosleep(&req, NULL);
134+
135+
zassert_equal(r, -1, "actual: %d expected: %d", r, -1);
136+
zassert_equal(errno, EINVAL, "actual: %d expected: %d", errno, EFAULT);
137+
}
138+
139+
/** req tv_sec and tv_nsec are both -1 */
140+
void test_nanosleep_n1_n1(void)
141+
{
142+
struct timespec req = {-1, -1};
143+
144+
errno = 0;
145+
int r = nanosleep(&req, NULL);
146+
147+
zassert_equal(r, -1, "actual: %d expected: %d", r, -1);
148+
zassert_equal(errno, EINVAL, "actual: %d expected: %d", errno, EFAULT);
149+
}
150+
151+
/** req tv_sec is 0 tv_nsec is 10^9 */
152+
void test_nanosleep_0_1000000000(void)
153+
{
154+
struct timespec req = {0, 1000000000};
155+
156+
errno = 0;
157+
int r = nanosleep(&req, NULL);
158+
159+
zassert_equal(r, -1, "actual: %d expected: %d", r, -1);
160+
zassert_equal(errno, EINVAL, "actual: %d expected: %d", errno, EFAULT);
161+
}
162+
163+
static void common(const uint32_t s, uint32_t ns)
164+
{
165+
uint32_t then;
166+
uint32_t now;
167+
uint32_t dt;
168+
uint64_t dt_ns;
169+
int r;
170+
struct timespec req = {s, ns};
171+
struct timespec rem = {0, 0};
172+
173+
errno = 0;
174+
then = k_cycle_get_32();
175+
r = nanosleep(&req, &rem);
176+
now = k_cycle_get_32();
177+
178+
zassert_equal(r, 0, "actual: %d expected: %d", r, -1);
179+
zassert_equal(errno, 0, "actual: %d expected: %d", errno, 0);
180+
zassert_equal(req.tv_sec, s, "actual: %d expected: %d",
181+
req.tv_sec, s);
182+
zassert_equal(req.tv_nsec, ns, "actual: %d expected: %d",
183+
req.tv_nsec, ns);
184+
zassert_equal(rem.tv_sec, 0, "actual: %d expected: %d",
185+
rem.tv_sec, 0);
186+
zassert_equal(rem.tv_nsec, 0, "actual: %d expected: %d",
187+
rem.tv_nsec, 0);
188+
189+
ns += s * NSEC_PER_SEC;
190+
191+
dt = now - then;
192+
dt_ns = k_cyc_to_ns_ceil64(dt);
193+
if (dt_ns == 0) {
194+
/* k_cycle_get_32() does not seem to be completely accurate on
195+
* some virtual platforms in CI (some function calls to
196+
* nanosleep reportedly take 0ns).
197+
*/
198+
dt_ns = 1;
199+
}
200+
201+
printk("dt_ns: %llu\n", dt_ns);
202+
203+
zassert_true(dt_ns >= ns, "expected dt_ns >= %d: actual: %d", (int)ns,
204+
(int)dt_ns);
205+
206+
/* TODO: Upper bounds check when hr timers are available */
207+
}
208+
209+
/** sleep for 1ns */
210+
void test_nanosleep_0_1(void)
211+
{
212+
common(0, 1);
213+
}
214+
215+
/** sleep for 500000000ns */
216+
void test_nanosleep_0_500000000(void)
217+
{
218+
common(0, 500000000);
219+
}
220+
221+
/** sleep for 1s */
222+
void test_nanosleep_1_0(void)
223+
{
224+
common(1, 0);
225+
}

0 commit comments

Comments
 (0)