authorgravatar for bblack@wikimedia.orgBrandon Black <bblack@wikimedia.org> 2026-05-08 09:57:21-05:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-08-10 20:33:08+02:00
logb9adc659b367bef744b79f9e966c0300f863407f
tree40eb1f5ea97970f74852902dd9f7f5b9a9a78d64
parent5ceec001b5d0feb09f6f7c581b1bdc5d2436bfbe

Io.net: add basic UDP tests


1 files changed, 85 insertions(+), 0 deletions(-)

lib/std/Io/net/test.zig+85
......@@ -372,3 +372,88 @@ test "cancel accept" {
372372
373373 try io.sleep(.fromNanoseconds(1), .awake);
374374}
375
376test "UDP send and receive" {
377 const io = testing.io;
378 const localhost: net.IpAddress = .{ .ip4 = .loopback(0) };
379
380 const recv_sock = localhost.bind(io, .{ .mode = .dgram }) catch |err| switch (err) {
381 error.NetworkDown => return error.SkipZigTest,
382 else => |e| return e,
383 };
384 defer recv_sock.close(io);
385 const send_sock = try localhost.bind(io, .{ .mode = .dgram });
386 defer send_sock.close(io);
387
388 const send_data: [3]u8 = .{ '1', '2', '3' };
389 try send_sock.send(io, &recv_sock.address, &send_data);
390
391 var recv_buf: [4]u8 = undefined;
392 const received = try recv_sock.receive(io, &recv_buf);
393 try testing.expect(received.from.eql(&send_sock.address));
394 try testing.expectEqualStrings(&send_data, received.data);
395}
396
397test "UDP send and receiveTimeout" {
398 const io = testing.io;
399 const localhost: net.IpAddress = .{ .ip4 = .loopback(0) };
400
401 const recv_sock = localhost.bind(io, .{ .mode = .dgram }) catch |err| switch (err) {
402 error.NetworkDown => return error.SkipZigTest,
403 else => |e| return e,
404 };
405 defer recv_sock.close(io);
406 const send_sock = try localhost.bind(io, .{ .mode = .dgram });
407 defer send_sock.close(io);
408
409 const send_data: [3]u8 = .{ '1', '2', '3' };
410 try send_sock.send(io, &recv_sock.address, &send_data);
411
412 const timeo: Io.Timeout = .{ .duration = .{ .clock = .awake, .raw = .fromSeconds(10) } };
413 var recv_buf: [4]u8 = undefined;
414 const received = recv_sock.receiveTimeout(io, &recv_buf, timeo) catch |err| switch (err) {
415 error.ConcurrencyUnavailable => return error.SkipZigTest,
416 else => |e| return e,
417 };
418 try testing.expect(received.from.eql(&send_sock.address));
419 try testing.expectEqualStrings(&send_data, received.data);
420
421 const short: Io.Timeout = .{ .duration = .{ .clock = .awake, .raw = .fromMicroseconds(123) } };
422 try testing.expectError(error.Timeout, recv_sock.receiveTimeout(io, &recv_buf, short));
423}
424
425test "UDP sendMany 1 recvManyTimeout 2" {
426 const io = testing.io;
427 const localhost: net.IpAddress = .{ .ip4 = .loopback(0) };
428
429 const recv_sock = localhost.bind(io, .{ .mode = .dgram }) catch |err| switch (err) {
430 error.NetworkDown => return error.SkipZigTest,
431 else => |e| return e,
432 };
433 defer recv_sock.close(io);
434 const send_sock = try localhost.bind(io, .{ .mode = .dgram });
435 defer send_sock.close(io);
436
437 const send_data: [3]u8 = .{ '1', '2', '3' };
438 var send_msg: Io.net.OutgoingMessage = .{
439 .address = &recv_sock.address,
440 .data_ptr = &send_data,
441 .data_len = 3,
442 };
443 try send_sock.sendMany(io, (&send_msg)[0..1], .{});
444 try testing.expectEqual(3, send_msg.data_len);
445
446 // This should not wait 10 seconds for the absent second message, it should
447 // complete as soon as the first one arrives
448 var recv_msgs: [2]net.IncomingMessage = @splat(.init);
449 var recv_buf: [10]u8 = undefined;
450 const timeo: Io.Timeout = .{ .duration = .{ .clock = .awake, .raw = .fromSeconds(10) } };
451 const maybe_recv_err, const recv_count = recv_sock.receiveManyTimeout(io, &recv_msgs, &recv_buf, .{}, timeo);
452 if (maybe_recv_err) |err| switch (err) {
453 error.ConcurrencyUnavailable => return error.SkipZigTest,
454 else => |e| return e,
455 };
456 try testing.expectEqual(1, recv_count);
457 try testing.expect(recv_msgs[0].from.eql(&send_sock.address));
458 try testing.expectEqualStrings(&send_data, recv_msgs[0].data);
459}