authorgravatar for mega.alpha100@gmail.comBernard Assan <mega.alpha100@gmail.com> 2026-04-16 11:54:46+00:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-08-08 20:33:19+02:00
log6fd38ce13f4cff552272fcc33c8a23d735ac0a49
tree80252825b789f991fd226440ad5cba45d541d298
parent8dfddf95fee5982d22512c0ac15278eabac5bcbb

Use iouring probing over kernel version checks

this will enable test passing on all linux kernels (particularly WSL) without version checks and making `skipKernelLessThan` redundant closes https://github.com/ziglang/zig/pull/24042 Signed-off-by: Bernard Assan <mega.alpha100@gmail.com>

1 files changed, 26 insertions(+), 57 deletions(-)

lib/std/os/linux/IoUring/test.zig+26-57
......@@ -475,9 +475,6 @@ test "close" {
475475}
476476
477477test "accept/connect/send/recv" {
478 const io = testing.io;
479 _ = io;
480
481478 var ring = IoUring.init(16, 0) catch |err| switch (err) {
482479 error.SystemOutdated => return error.SkipZigTest,
483480 error.PermissionDenied => return error.SkipZigTest,
......@@ -620,7 +617,7 @@ test "timeout (after a relative time)" {
620617
621618 const ms = 10;
622619 const margin = 5;
623 const ts: linux.kernel_timespec = .{ .sec = 0, .nsec = ms * 1000000 };
620 const ts: linux.kernel_timespec = .{ .sec = 0, .nsec = ms * std.time.ns_per_ms };
624621
625622 const started = std.Io.Clock.awake.now(io);
626623 const sqe = try ring.timeout(0x55555555, &ts, 0, 0);
......@@ -730,9 +727,6 @@ test "timeout_remove" {
730727}
731728
732729test "accept/connect/recv/link_timeout" {
733 const io = testing.io;
734 _ = io;
735
736730 var ring = IoUring.init(16, 0) catch |err| switch (err) {
737731 error.SystemOutdated => return error.SkipZigTest,
738732 error.PermissionDenied => return error.SkipZigTest,
......@@ -748,7 +742,7 @@ test "accept/connect/recv/link_timeout" {
748742 const sqe_recv = try ring.recv(0xffffffff, socket_test_harness.server, .{ .buffer = buffer_recv[0..] }, 0);
749743 sqe_recv.flags |= linux.IOSQE_IO_LINK;
750744
751 const ts = linux.kernel_timespec{ .sec = 0, .nsec = 1000000 };
745 const ts: linux.kernel_timespec = .{ .sec = 0, .nsec = std.time.ns_per_ms };
752746 _ = try ring.link_timeout(0x22222222, &ts, 0);
753747
754748 const nr_wait = try ring.submit();
......@@ -883,9 +877,6 @@ test "statx" {
883877}
884878
885879test "accept/connect/recv/cancel" {
886 const io = testing.io;
887 _ = io;
888
889880 var ring = IoUring.init(16, 0) catch |err| switch (err) {
890881 error.SystemOutdated => return error.SkipZigTest,
891882 error.PermissionDenied => return error.SkipZigTest,
......@@ -1568,9 +1559,6 @@ test "remove_buffers" {
15681559}
15691560
15701561test "provide_buffers: accept/connect/send/recv" {
1571 const io = testing.io;
1572 _ = io;
1573
15741562 var ring = IoUring.init(16, 0) catch |err| switch (err) {
15751563 error.SystemOutdated => return error.SkipZigTest,
15761564 error.PermissionDenied => return error.SkipZigTest,
......@@ -1777,11 +1765,6 @@ test "accept multishot" {
17771765}
17781766
17791767test "accept/connect/send_zc/recv" {
1780 try skipKernelLessThan(.{ .major = 6, .minor = 0, .patch = 0 });
1781
1782 const io = testing.io;
1783 _ = io;
1784
17851768 var ring = IoUring.init(16, 0) catch |err| switch (err) {
17861769 error.SystemOutdated => return error.SkipZigTest,
17871770 error.PermissionDenied => return error.SkipZigTest,
......@@ -1789,6 +1772,13 @@ test "accept/connect/send_zc/recv" {
17891772 };
17901773 defer ring.deinit();
17911774
1775 const probe = ring.get_probe() catch return error.SkipZigTest;
1776 const ops_not_supported = !probe.is_supported(.ACCEPT) or
1777 !probe.is_supported(.CONNECT) or
1778 !probe.is_supported(.SEND_ZC) or
1779 !probe.is_supported(.RECV);
1780 if (ops_not_supported) return error.SkipZigTest;
1781
17921782 const socket_test_harness = try createSocketTestHarness(&ring);
17931783 defer socket_test_harness.close();
17941784
......@@ -1836,14 +1826,16 @@ test "accept/connect/send_zc/recv" {
18361826}
18371827
18381828test "accept_direct" {
1839 try skipKernelLessThan(.{ .major = 5, .minor = 19, .patch = 0 });
1840
18411829 var ring = IoUring.init(1, 0) catch |err| switch (err) {
18421830 error.SystemOutdated => return error.SkipZigTest,
18431831 error.PermissionDenied => return error.SkipZigTest,
18441832 else => return err,
18451833 };
18461834 defer ring.deinit();
1835
1836 const probe = ring.get_probe() catch return error.SkipZigTest;
1837 if (!probe.is_supported(.ACCEPT)) return error.SkipZigTest;
1838
18471839 var address: linux.sockaddr.in = .{
18481840 .port = 0,
18491841 .addr = @as(*align(1) const u32, @ptrCast(
......@@ -1921,8 +1913,6 @@ test "accept_direct" {
19211913}
19221914
19231915test "accept_multishot_direct" {
1924 try skipKernelLessThan(.{ .major = 5, .minor = 19, .patch = 0 });
1925
19261916 var ring = IoUring.init(1, 0) catch |err| switch (err) {
19271917 error.SystemOutdated => return error.SkipZigTest,
19281918 error.PermissionDenied => return error.SkipZigTest,
......@@ -1930,6 +1920,9 @@ test "accept_multishot_direct" {
19301920 };
19311921 defer ring.deinit();
19321922
1923 const probe = ring.get_probe() catch return error.SkipZigTest;
1924 if (!probe.is_supported(.ACCEPT)) return error.SkipZigTest;
1925
19331926 var address: linux.sockaddr.in = .{
19341927 .port = 0,
19351928 .addr = @as(*align(1) const u32, @ptrCast(
......@@ -1984,8 +1977,6 @@ test "accept_multishot_direct" {
19841977}
19851978
19861979test "socket" {
1987 try skipKernelLessThan(.{ .major = 5, .minor = 19, .patch = 0 });
1988
19891980 var ring = IoUring.init(1, 0) catch |err| switch (err) {
19901981 error.SystemOutdated => return error.SkipZigTest,
19911982 error.PermissionDenied => return error.SkipZigTest,
......@@ -1993,6 +1984,9 @@ test "socket" {
19931984 };
19941985 defer ring.deinit();
19951986
1987 const probe = ring.get_probe() catch return error.SkipZigTest;
1988 if (!probe.is_supported(.SOCKET)) return error.SkipZigTest;
1989
19961990 // prepare, submit socket operation
19971991 _ = try ring.socket(0, linux.AF.INET, posix.SOCK.STREAM, 0, 0);
19981992 try testing.expectEqual(@as(u32, 1), try ring.submit());
......@@ -2007,8 +2001,6 @@ test "socket" {
20072001}
20082002
20092003test "socket_direct/socket_direct_alloc/close_direct" {
2010 try skipKernelLessThan(.{ .major = 5, .minor = 19, .patch = 0 });
2011
20122004 var ring = IoUring.init(2, 0) catch |err| switch (err) {
20132005 error.SystemOutdated => return error.SkipZigTest,
20142006 error.PermissionDenied => return error.SkipZigTest,
......@@ -2016,6 +2008,9 @@ test "socket_direct/socket_direct_alloc/close_direct" {
20162008 };
20172009 defer ring.deinit();
20182010
2011 const probe = ring.get_probe() catch return error.SkipZigTest;
2012 if (!probe.is_supported(.SOCKET) or !probe.is_supported(.CLOSE)) return error.SkipZigTest;
2013
20192014 var registered_fds: [3]linux.fd_t = @splat(-1);
20202015 try ring.register_files(registered_fds[0..]);
20212016
......@@ -2090,8 +2085,6 @@ test "socket_direct/socket_direct_alloc/close_direct" {
20902085}
20912086
20922087test "openat_direct/close_direct" {
2093 try skipKernelLessThan(.{ .major = 5, .minor = 19, .patch = 0 });
2094
20952088 var ring = IoUring.init(2, 0) catch |err| switch (err) {
20962089 error.SystemOutdated => return error.SkipZigTest,
20972090 error.PermissionDenied => return error.SkipZigTest,
......@@ -2099,6 +2092,9 @@ test "openat_direct/close_direct" {
20992092 };
21002093 defer ring.deinit();
21012094
2095 const probe = ring.get_probe() catch return error.SkipZigTest;
2096 if (!probe.is_supported(.OPENAT) or !probe.is_supported(.CLOSE)) return error.SkipZigTest;
2097
21022098 var registered_fds: [3]linux.fd_t = @splat(-1);
21032099 try ring.register_files(registered_fds[0..]);
21042100
......@@ -2141,9 +2137,6 @@ test "openat_direct/close_direct" {
21412137}
21422138
21432139test "ring mapped buffers recv" {
2144 const io = testing.io;
2145 _ = io;
2146
21472140 var ring = IoUring.init(16, 0) catch |err| switch (err) {
21482141 error.SystemOutdated => return error.SkipZigTest,
21492142 error.PermissionDenied => return error.SkipZigTest,
......@@ -2231,9 +2224,6 @@ test "ring mapped buffers recv" {
22312224}
22322225
22332226test "ring mapped buffers multishot recv" {
2234 const io = testing.io;
2235 _ = io;
2236
22372227 var ring = IoUring.init(16, 0) catch |err| switch (err) {
22382228 error.SystemOutdated => return error.SkipZigTest,
22392229 error.PermissionDenied => return error.SkipZigTest,
......@@ -2665,7 +2655,7 @@ pub fn createSocketTestHarness(ring: *IoUring) !SocketTestHarness {
26652655
26662656 // All good
26672657
2668 return SocketTestHarness{
2658 return .{
26692659 .listener = listener_socket,
26702660 .server = cqe_accept.res,
26712661 .client = client,
......@@ -2688,27 +2678,6 @@ fn createListenerSocket(address: *linux.sockaddr.in) !posix.socket_t {
26882678 return listener_socket;
26892679}
26902680
2691/// For use in tests. Returns SkipZigTest if kernel version is less than required.
2692inline fn skipKernelLessThan(required: std.SemanticVersion) !void {
2693 var uts: linux.utsname = undefined;
2694 const res = linux.uname(&uts);
2695 switch (linux.errno(res)) {
2696 .SUCCESS => {},
2697 else => |errno| return posix.unexpectedErrno(errno),
2698 }
2699
2700 const release = mem.sliceTo(&uts.release, 0);
2701 // Strips potential extra, as kernel version might not be semver compliant, example "6.8.9-300.fc40.x86_64"
2702 const extra_index = std.mem.findAny(u8, release, "-+");
2703 const stripped = release[0..(extra_index orelse release.len)];
2704 // Make sure the input don't rely on the extra we just stripped
2705 try testing.expect(required.pre == null and required.build == null);
2706
2707 var current = try std.SemanticVersion.parse(stripped);
2708 current.pre = null; // don't check pre field
2709 if (required.order(current) == .gt) return error.SkipZigTest;
2710}
2711
27122681fn addrAny(addr: *linux.sockaddr.in) *linux.sockaddr {
27132682 return @ptrCast(addr);
27142683}