Skip to content

Commit f156e34

Browse files
cfriedtJakub Klimczak
andcommitted
tests: posix: add POSIX_DEVICE_IO testsuite
Add a testsuite for the POSIX_DEVICE_IO Option Group. Signed-off-by: Chris Friedt <[email protected]> Co-authored-by: Jakub Klimczak <[email protected]> Signed-off-by: Jakub Klimczak <[email protected]>
1 parent e606b23 commit f156e34

File tree

4 files changed

+240
-0
lines changed

4 files changed

+240
-0
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
cmake_minimum_required(VERSION 3.20.0)
4+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
5+
project(posix_c_lib_ext)
6+
7+
FILE(GLOB app_sources src/*.c)
8+
9+
target_sources(app PRIVATE ${app_sources})
10+
11+
target_include_directories(app PRIVATE ${ZEPHYR_BASE}/lib/posix/options/getopt)
12+
target_compile_options(app PRIVATE -U_POSIX_C_SOURCE -D_POSIX_C_SOURCE=200809L)

tests/posix/device_io/prj.conf

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CONFIG_POSIX_API=y
2+
CONFIG_ZTEST=y
3+
4+
CONFIG_POSIX_AEP_CHOICE_BASE=y
5+
CONFIG_POSIX_DEVICE_IO=y
6+
7+
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048
8+
CONFIG_ZTEST_STACK_SIZE=2048

tests/posix/device_io/src/main.c

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
/*
2+
* Copyright (c) 2025 Tenstorrent AI ULC
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <stdio.h>
8+
9+
#include <zephyr/ztest.h>
10+
11+
#include <zephyr/posix/fcntl.h>
12+
#include <zephyr/posix/poll.h>
13+
#include <zephyr/posix/sys/select.h>
14+
#include <zephyr/posix/unistd.h>
15+
16+
#ifndef STDIN_FILENO
17+
#define STDIN_FILENO 0
18+
#endif
19+
20+
#ifndef STDOUT_FILENO
21+
#define STDOUT_FILENO 1
22+
#endif
23+
24+
#ifndef STDERR_FILENO
25+
#define STDERR_FILENO 2
26+
#endif
27+
28+
ZTEST(posix_device_io, test_FD_CLR)
29+
{
30+
fd_set fds;
31+
32+
FD_CLR(0, &fds);
33+
}
34+
35+
ZTEST(posix_device_io, test_FD_ISSET)
36+
{
37+
fd_set fds;
38+
39+
zassert_false(FD_ISSET(0, &fds));
40+
}
41+
42+
ZTEST(posix_device_io, test_FD_SET)
43+
{
44+
fd_set fds;
45+
46+
FD_SET(0, &fds);
47+
zassert_true(FD_ISSET(0, &fds));
48+
}
49+
50+
ZTEST(posix_device_io, test_FD_ZERO)
51+
{
52+
fd_set fds;
53+
54+
FD_ZERO(&fds);
55+
zassert_false(FD_ISSET(0, &fds));
56+
}
57+
58+
ZTEST(posix_device_io, test_close)
59+
{
60+
zassert_not_ok(close(-1));
61+
}
62+
63+
ZTEST(posix_device_io, test_fdopen)
64+
{
65+
zassert_not_null(fdopen(1, "r"));
66+
}
67+
68+
ZTEST(posix_device_io, test_fileno)
69+
{
70+
#define DECL_TDATA(_stream, _fd) \
71+
{ \
72+
.stream_name = #_stream, \
73+
.stream = _stream, \
74+
.fd_name = #_fd, \
75+
.fd = _fd, \
76+
}
77+
78+
const struct fileno_test_data {
79+
const char *stream_name;
80+
FILE *stream;
81+
const char *fd_name;
82+
int fd;
83+
} test_data[] = {
84+
DECL_TDATA(stdin, STDIN_FILENO),
85+
DECL_TDATA(stdout, STDOUT_FILENO),
86+
DECL_TDATA(stderr, STDERR_FILENO),
87+
};
88+
89+
ARRAY_FOR_EACH(test_data, i) {
90+
FILE *stream = test_data[i].stream;
91+
int expect_fd = test_data[i].fd;
92+
int actual_fd = fileno(stream);
93+
94+
if ((i == STDERR_FILENO) &&
95+
(IS_ENABLED(CONFIG_PICOLIBC) || IS_ENABLED(CONFIG_NEWLIB_LIBC))) {
96+
TC_PRINT("Note: stderr not enabled\n");
97+
continue;
98+
}
99+
100+
zexpect_equal(actual_fd, expect_fd, "fileno(%s) (%d) != %s (%d)",
101+
test_data[i].stream_name, actual_fd, test_data[i].fd_name, expect_fd);
102+
}
103+
}
104+
105+
ZTEST(posix_device_io, test_open)
106+
{
107+
/*
108+
* Note: open() is already exercised extensively in tests/posix/fs, but we should test it
109+
* here on device nodes as well.
110+
*/
111+
zexpect_equal(open("/dev/null", O_RDONLY), -1);
112+
zexpect_equal(errno, ENOENT);
113+
}
114+
115+
ZTEST(posix_device_io, test_poll)
116+
{
117+
struct pollfd fds[1] = {{.fd = STDIN_FILENO, .events = POLLIN}};
118+
119+
/*
120+
* Note: poll() is already exercised extensively in tests/posix/eventfd, but we should test
121+
* it here on device nodes as well.
122+
*/
123+
zexpect_equal(poll(fds, ARRAY_SIZE(fds), 0), 1);
124+
}
125+
126+
ZTEST(posix_device_io, test_pread)
127+
{
128+
uint8_t buf[8];
129+
130+
zexpect_equal(pread(STDIN_FILENO, buf, sizeof(buf), 0), -1);
131+
zexpect_equal(errno, ENOTSUP);
132+
}
133+
134+
ZTEST(posix_device_io, test_pselect)
135+
{
136+
fd_set fds;
137+
struct timespec timeout = {.tv_sec = 0, .tv_nsec = 0};
138+
139+
FD_ZERO(&fds);
140+
FD_SET(STDIN_FILENO, &fds);
141+
142+
/* Zephyr does not yet support select or poll on stdin */
143+
zexpect_equal(pselect(STDIN_FILENO + 1, &fds, NULL, NULL, &timeout, NULL), -1);
144+
zexpect_equal(errno, EBADF);
145+
}
146+
147+
ZTEST(posix_device_io, test_pwrite)
148+
{
149+
/* Zephyr does not yet support writing through a file descriptor */
150+
zexpect_equal(pwrite(STDOUT_FILENO, "x", 1, 0), -1);
151+
zexpect_equal(errno, ENOTSUP, "%d", errno);
152+
}
153+
154+
ZTEST(posix_device_io, test_read)
155+
{
156+
uint8_t buf[8];
157+
158+
/* reading from stdin does not work in Zephyr */
159+
zassert_equal(read(STDIN_FILENO, buf, sizeof(buf)), 0);
160+
}
161+
162+
ZTEST(posix_device_io, test_select)
163+
{
164+
fd_set fds;
165+
struct timeval timeout = {.tv_sec = 0, .tv_usec = 0};
166+
167+
FD_ZERO(&fds);
168+
FD_SET(STDIN_FILENO, &fds);
169+
170+
/* Zephyr does not yet support select or poll on stdin */
171+
zassert_equal(select(STDIN_FILENO + 1, &fds, NULL, NULL, &timeout), -1);
172+
zexpect_equal(errno, EBADF, "%d", errno);
173+
}
174+
175+
ZTEST(posix_device_io, test_write)
176+
{
177+
/* write is only implemented in newlib and arcmwdt */
178+
#if defined(CONFIG_NEWLIB_LIBC) || defined(CONFIG_ARCMWDT_LIBC)
179+
zexpect_equal(write(STDOUT_FILENO, "x", 1), 1);
180+
#else
181+
zexpect_equal(write(STDOUT_FILENO, "x", 1), 0);
182+
#endif
183+
}
184+
185+
ZTEST_SUITE(posix_device_io, NULL, NULL, NULL, NULL, NULL);
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
common:
2+
filter: not CONFIG_NATIVE_LIBC
3+
tags:
4+
- posix
5+
- device_io
6+
# 1 tier0 platform per supported architecture
7+
platform_key:
8+
- arch
9+
- simulation
10+
min_ram: 32
11+
tests:
12+
portability.posix.device_io:
13+
extra_configs:
14+
- CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=256
15+
portability.posix.device_io.armclang_std_libc:
16+
toolchain_allow: armclang
17+
extra_configs:
18+
- CONFIG_ARMCLANG_STD_LIBC=y
19+
portability.posix.device_io.arcmwdtlib:
20+
toolchain_allow: arcmwdt
21+
extra_configs:
22+
- CONFIG_ARCMWDT_LIBC=y
23+
portability.posix.device_io.minimal:
24+
extra_configs:
25+
- CONFIG_MINIMAL_LIBC=y
26+
- CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=256
27+
portability.posix.device_io.newlib:
28+
filter: TOOLCHAIN_HAS_NEWLIB == 1
29+
extra_configs:
30+
- CONFIG_NEWLIB_LIBC=y
31+
portability.posix.device_io.picolibc:
32+
tags: picolibc
33+
filter: CONFIG_PICOLIBC_SUPPORTED
34+
extra_configs:
35+
- CONFIG_PICOLIBC=y

0 commit comments

Comments
 (0)