test(coverage): cover os_aio backends + os_method via a direct C driver - #78
Merged
Conversation
The async-I/O abstraction (src/os/os_aio.c) and its backends (os_aio_pool.c, os_aio_posix.c, os_aio_uring.c) plus the DB_ENV os-method setters (src/common/os_method.c) were all at 0%. The buffer pool reaches os_aio ONLY via DB_ENV->set_flags(DB_MPOOL_AIO) (off by default) and then probes a SINGLE backend at runtime in preference order (io_uring > IOCP > kqueue+aio > POSIX aio > thread-pool). On a Linux box with liburing a normal Tcl workload can therefore only ever exercise io_uring -- the pool + posix backends stay dark, and os_aio is unreachable at all without the flag. test/os/os_aio_direct.c links the internal libdb symbols and drives each configured backend directly (submit N writes, reap, read back, verify the round-trip), then exercises __os_aio_create's automatic selection and the synchronous fallback, and finally runs a real DB_MPOOL_AIO checkpoint workload so the production mp_sync -> __memp_bhwrite_async -> backend -> __memp_aio_drain path runs too. It also sets/clears every DB_ENV os-method function. Runs single-process under a SIGALRM guard so the blocking reap loop can never hang the coverage run. test/os/run_os_aio.sh compiles it against the just-built .so and runs it under a timeout, mirroring test/xa/run_xa_direct.sh; it is wired into the COV_XA_UPG driver block of run_coverage.sh. Coverage lift (measured, gcov): os_aio.c 0% -> ~84% os_aio_pool.c 0% -> ~73% os_aio_posix.c 0% -> ~84% os_aio_uring.c 0% -> ~81% common/os_method.c 0% -> 100% (mp_bh.c / mp_sync.c async writeback path also newly exercised.) os_aio_iocp.c (Windows) and os_aio_kqueue.c (BSD) stay 0%: on Linux they compile only their #else init stub and need their target OS to be reachable. No engine code changed; async writeback + reap ordering round-trips correctly across all backends (no bug surfaced).
Coccinelle convention checksNo new violations. ✅ Resolved since baseline (2) -- update dist/cocci/baseline.txt to lock these in. |
ABI diff vs
|
This was referenced Jul 29, 2026
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Raises coverage of libdb's async-I/O backends (all at 0%) and the DB_ENV
os-method setters via one bounded, single-process C driver.
New files:
test/os/os_aio_direct.c-- links internal libdb symbols and drives theos_aio abstraction and each backend directly.
test/os/run_os_aio.sh-- compiles + runs it under a timeout (mirrorstest/xa/run_xa_direct.sh); wired into theCOV_XA_UPGblock oftest/coverage/run_coverage.sh.How AIO is enabled / selected (findings)
DB_ENV->set_flags(DB_MPOOL_AIO)is set (mp_region.c); otherwise writebackis synchronous. The flag is public (
DB_MPOOL_AIO, api_flags) and alsosettable from a
DB_CONFIGset_flags db_mpool_aioline.__os_aio_create(os_aio.c) probes backends inpreference order and installs the first that initializes: io_uring >
IOCP > kqueue+aio > POSIX aio > thread-pool. On this nix Linux env
configureenablesHAVE_IO_URING(flake liburing),HAVE_AIO_POSIX(librt), and
HAVE_AIO_THREADPOOL(pthread) -- so io_uring always winsand no Tcl workload can ever reach the pool or posix backends.
mp_syncwriteback (checkpoint / cache flush/ trickle):
__memp_bhwrite_async->__os_aio_submit->__memp_aio_drain->
__os_aio_reap.DB_MPOOL_AIOis not wired into the Tclset_flagsbinding, confirming the DST/Tcl suite does not exercise os_aio (matches
DESIGN.md's "os_aio* hooks remain follow-ups").
The driver therefore forces each backend's
__os_aio_*_initin turn to coverall of them in one run, then also runs a genuine
DB_MPOOL_AIOcheckpointworkload so the production integration path (io_uring) runs too.
Which backend actually executed
threadpool,posixaio,io_uring,auto (io_uring), andsync-fallbackall ran and round-tripped 40 pages each (write -> reap -> read -> verify). The
real
DB_MPOOL_AIOworkload ran through io_uring (the auto-selectedbackend on Linux).
Coverage: before -> after (measured, gcov)
os_aio_iocp.c(Windows) andos_aio_kqueue.c(BSD) stay 0%: on Linux theycompile only their
#elseinit stub -- unreachable without their target OS.Bugs
None. Async writeback + reap ordering round-trips correctly across every
backend; no engine code was touched.
Validation
nix dev shell,
--enable-debug --enable-test, run twice: all backends PASS,deterministic, no hang (SIGALRM guard), no cores/orphans, clean home.