Skip to content

Commit a1652da

Browse files
riptlripatel-fd
authored andcommitted
vinyl: add test_vinyl_io_ur
Adds test for io_uring backend
1 parent 211fd61 commit a1652da

File tree

2 files changed

+186
-1
lines changed

2 files changed

+186
-1
lines changed

src/vinyl/io/Local.mk

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,6 @@ endif
99

1010
$(call add-hdrs,fd_vinyl_io_ur.h)
1111
$(call add-objs,fd_vinyl_io_ur,fd_vinyl)
12-
12+
ifdef FD_HAS_LIBURING
13+
$(call make-unit-test,test_vinyl_io_ur,test_vinyl_io_ur,fd_vinyl fd_tango fd_util)
14+
endif

src/vinyl/io/test_vinyl_io_ur.c

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
#include "fd_vinyl_io_ur.h"
2+
#include <liburing/io_uring.h>
3+
4+
#if !FD_HAS_LIBURING
5+
#error "This test requires liburing"
6+
#endif
7+
8+
#include <stdlib.h> /* mkstemp */
9+
#include <errno.h>
10+
#include <unistd.h> /* ftruncate */
11+
#include <fcntl.h> /* open */
12+
#include <liburing.h>
13+
14+
#include "test_vinyl_io_common.c"
15+
16+
int
17+
main( int argc,
18+
char ** argv ) {
19+
fd_boot( &argc, &argv );
20+
21+
ulong spad_max = fd_env_strip_cmdline_ulong( &argc, &argv, "--spad-max", NULL, 131072UL );
22+
char const * path = fd_env_strip_cmdline_cstr ( &argc, &argv, "--path", NULL, NULL );
23+
ulong seed = fd_env_strip_cmdline_ulong( &argc, &argv, "--seed", NULL, 1234UL );
24+
uint depth = fd_env_strip_cmdline_uint ( &argc, &argv, "--depth", NULL, 256U );
25+
26+
FD_LOG_NOTICE(( "Testing with --spad-max %lu --seed %lu", spad_max, seed ));
27+
28+
fd_rng_t rng[1]; fd_rng_join( fd_rng_new( rng, 0U, 0UL ) );
29+
30+
ulong store_sz = (off_t)(FD_VINYL_BSTREAM_BLOCK_SZ + BCACHE_SZ);
31+
32+
char _path[] = "/tmp/test_vinyl_io_ur.XXXXXX";
33+
34+
int fd;
35+
if( FD_UNLIKELY( path ) ) {
36+
FD_LOG_NOTICE(( "Using --path %s for the test storage", path ));
37+
fd = open( path, O_RDWR | O_CREAT | O_EXCL, (mode_t)0644 );
38+
if( FD_UNLIKELY( fd==-1 ) ) FD_LOG_ERR(( "open failed (%i-%s)", errno, fd_io_strerror( errno ) ));
39+
} else {
40+
FD_LOG_NOTICE(( "--path not specified, using a temp file for test storage" ));
41+
fd = mkstemp( _path );
42+
if( FD_UNLIKELY( fd==-1 ) ) FD_LOG_ERR(( "mkstemp failed (%i-%s)", errno, fd_io_strerror( errno ) ));
43+
path = _path;
44+
FD_LOG_NOTICE(( "temp file at %s", path ));
45+
}
46+
47+
if( FD_UNLIKELY( ftruncate( fd, (off_t)store_sz ) ) )
48+
FD_LOG_ERR(( "ftruncate failed (%i-%s)", errno, fd_io_strerror( errno ) ));
49+
50+
# define MEM_MAX (1048576UL)
51+
static uchar mem[ MEM_MAX ] __attribute__((aligned(512)));
52+
53+
FD_LOG_NOTICE(( "Testing construction" ));
54+
55+
/* Create a bstream using io_bd */
56+
{
57+
char const * info = "info";
58+
ulong info_sz = strlen( info ) + 1UL;
59+
60+
ulong align = fd_vinyl_io_bd_align();
61+
ulong footprint = fd_vinyl_io_bd_footprint( spad_max );
62+
if( FD_UNLIKELY( (footprint>MEM_MAX) | (align>512UL) ) ) FD_LOG_ERR(( "update mem for this test" ));
63+
fd_vinyl_io_t * io_bd = fd_vinyl_io_bd_init( mem, spad_max, fd, 1, info, info_sz, seed );
64+
FD_TEST( io_bd );
65+
FD_TEST( fd_vinyl_io_fini( io_bd )==mem );
66+
}
67+
68+
/* Join the bstream using io_ur */
69+
struct io_uring ring[1];
70+
fd_vinyl_io_t * io = NULL;
71+
{
72+
struct io_uring_params params = {
73+
.flags = IORING_SETUP_CQSIZE |
74+
IORING_SETUP_COOP_TASKRUN |
75+
IORING_SETUP_SINGLE_ISSUER,
76+
.features = IORING_SETUP_DEFER_TASKRUN,
77+
.cq_entries = depth
78+
};
79+
80+
int init_err = io_uring_queue_init_params( depth, ring, &params );
81+
if( FD_UNLIKELY( init_err==-EPERM ) ) {
82+
FD_LOG_WARNING(( "skip: unit test is missing privileges to setup io_uring" ));
83+
if( FD_UNLIKELY( unlink( path ) ) ) FD_LOG_WARNING(( "unlink failed (%i-%s)", errno, fd_io_strerror( errno ) ));
84+
fd_rng_delete( fd_rng_leave( rng ) );
85+
return 0;
86+
} else if( init_err<0 ) {
87+
FD_LOG_ERR(( "io_uring_queue_init_params failed (%i-%s)", init_err, fd_io_strerror( -init_err ) ));
88+
}
89+
90+
ulong align = fd_vinyl_io_ur_align();
91+
FD_TEST( fd_ulong_is_pow2( align ) );
92+
ulong footprint = fd_vinyl_io_ur_footprint( spad_max );
93+
FD_TEST( fd_ulong_is_aligned( footprint, align ) );
94+
if( FD_UNLIKELY( (footprint>MEM_MAX) | (align>512UL) ) ) FD_LOG_ERR(( "update mem for this test" ));
95+
io = fd_vinyl_io_ur_init( mem, spad_max, fd, ring );
96+
FD_TEST( io );
97+
}
98+
99+
FD_LOG_NOTICE(( "Testing accessors" ));
100+
101+
FD_TEST( fd_vinyl_io_type ( io )==FD_VINYL_IO_TYPE_UR );
102+
FD_TEST( fd_vinyl_io_seed ( io )==seed );
103+
FD_TEST( fd_vinyl_io_seq_ancient ( io )==seq_ancient );
104+
FD_TEST( fd_vinyl_io_seq_past ( io )==seq_past );
105+
FD_TEST( fd_vinyl_io_seq_present ( io )==seq_present );
106+
FD_TEST( fd_vinyl_io_seq_future ( io )==seq_future );
107+
108+
FD_LOG_NOTICE(( "Testing operations" ));
109+
110+
test( io, rng );
111+
112+
FD_LOG_NOTICE(( "Aborting and resuming" ));
113+
114+
FD_TEST( fd_vinyl_io_fini( io )==mem );
115+
116+
io = fd_vinyl_io_ur_init( mem, spad_max, fd, ring );
117+
FD_TEST( io );
118+
119+
FD_LOG_NOTICE(( "Testing operations (after resume)" ));
120+
121+
test( io, rng );
122+
123+
FD_TEST( fd_vinyl_io_type ( io )==FD_VINYL_IO_TYPE_UR );
124+
FD_TEST( fd_vinyl_io_seed ( io )==seed );
125+
FD_TEST( fd_vinyl_io_seq_ancient ( io )==seq_ancient );
126+
FD_TEST( fd_vinyl_io_seq_past ( io )==seq_past );
127+
FD_TEST( fd_vinyl_io_seq_present ( io )==seq_present );
128+
FD_TEST( fd_vinyl_io_seq_future ( io )==seq_future );
129+
130+
/* FIXME: TEST BSTREAM WRITE HELPERS */
131+
132+
FD_LOG_NOTICE(( "Testing scratch pad" ));
133+
134+
FD_TEST( !fd_vinyl_io_commit( io, FD_VINYL_IO_FLAG_BLOCKING ) ); /* empty the spad */
135+
136+
void * smem = NULL;
137+
ulong smem_sz = 0UL;
138+
ulong spad_used = 0UL;
139+
140+
while( spad_used<spad_max ) {
141+
142+
FD_TEST( fd_vinyl_io_spad_max ( io )==spad_max );
143+
FD_TEST( fd_vinyl_io_spad_used( io )==spad_used );
144+
FD_TEST( fd_vinyl_io_spad_free( io )==spad_max-spad_used );
145+
146+
void * last = smem;
147+
ulong last_sz = smem_sz;
148+
149+
smem_sz = fd_ulong_min( FD_VINYL_BSTREAM_BLOCK_SZ*fd_rng_coin_tosses( rng ), spad_max - spad_used );
150+
151+
smem = fd_vinyl_io_alloc( io, smem_sz, 0 );
152+
153+
FD_TEST( smem );
154+
FD_TEST( fd_ulong_is_aligned( (ulong)smem, FD_VINYL_BSTREAM_BLOCK_SZ ) );
155+
if( last ) FD_TEST( ((ulong)smem - (ulong)last)==last_sz );
156+
spad_used += smem_sz;
157+
}
158+
159+
FD_TEST( fd_vinyl_io_spad_max ( io )==spad_max );
160+
FD_TEST( fd_vinyl_io_spad_used( io )==spad_used );
161+
FD_TEST( fd_vinyl_io_spad_free( io )==spad_max-spad_used );
162+
163+
FD_LOG_NOTICE(( "Testing destruction" ));
164+
165+
fd_vinyl_bstream_block_t block[1];
166+
memset( block, 0, FD_VINYL_BSTREAM_BLOCK_SZ );
167+
fd_vinyl_io_append( io, block, FD_VINYL_BSTREAM_BLOCK_SZ );
168+
169+
FD_TEST( !fd_vinyl_io_fini( NULL ) );
170+
FD_TEST( fd_vinyl_io_fini( io )==mem ); /* fini with uncommitted bytes */
171+
172+
FD_LOG_NOTICE(( "Cleaning up" ));
173+
174+
io_uring_queue_exit( ring );
175+
176+
if( FD_UNLIKELY( unlink( path ) ) ) FD_LOG_WARNING(( "unlink failed (%i-%s)", errno, fd_io_strerror( errno ) ));
177+
178+
fd_rng_delete( fd_rng_leave( rng ) );
179+
180+
FD_LOG_NOTICE(( "pass" ));
181+
fd_halt();
182+
return 0;
183+
}

0 commit comments

Comments
 (0)