Skip to content

Commit 2e21442

Browse files
committed
aio: add socket tests
1 parent 2362349 commit 2e21442

File tree

1 file changed

+189
-4
lines changed

1 file changed

+189
-4
lines changed

src/aio.zig

Lines changed: 189 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -593,19 +593,204 @@ test "ChildExit" {
593593
}
594594
}
595595

596-
test "Socket" {
596+
test "Socket/TCP" {
597597
if (builtin.target.os.tag == .wasi) {
598598
return error.SkipZigTest;
599599
}
600600

601-
var sock: std.posix.socket_t = undefined;
601+
var server: std.posix.socket_t = undefined;
602602
try single(.socket, .{
603603
.domain = std.posix.AF.INET,
604604
.flags = std.posix.SOCK.STREAM | std.posix.SOCK.CLOEXEC,
605605
.protocol = std.posix.IPPROTO.TCP,
606-
.out_socket = &sock,
606+
.out_socket = &server,
607607
});
608-
try single(.close_socket, .{ .socket = sock });
608+
609+
try std.posix.setsockopt(server, std.posix.SOL.SOCKET, std.posix.SO.REUSEADDR, &std.mem.toBytes(@as(c_int, 1)));
610+
if (@hasDecl(std.posix.SO, "REUSEPORT")) {
611+
try std.posix.setsockopt(server, std.posix.SOL.SOCKET, std.posix.SO.REUSEPORT, &std.mem.toBytes(@as(c_int, 1)));
612+
}
613+
614+
var client: std.posix.socket_t = undefined;
615+
try single(.socket, .{
616+
.domain = std.posix.AF.INET,
617+
.flags = std.posix.SOCK.STREAM | std.posix.SOCK.CLOEXEC,
618+
.protocol = std.posix.IPPROTO.TCP,
619+
.out_socket = &client,
620+
});
621+
622+
const address = std.net.Address.initIp4(.{ 127, 0, 0, 1 }, 3131);
623+
try std.posix.bind(server, &address.any, address.getOsSockLen());
624+
try std.posix.listen(server, 1);
625+
626+
var client_comm: std.posix.socket_t = undefined;
627+
var client_addr_posix: std.posix.sockaddr align(4) = undefined;
628+
var client_addr_len: posix.socklen_t = @sizeOf(std.posix.sockaddr);
629+
try multi(.{
630+
op(.accept, .{
631+
.socket = server,
632+
.out_socket = &client_comm,
633+
.out_addr = &client_addr_posix,
634+
.inout_addrlen = &client_addr_len,
635+
}, .unlinked),
636+
op(.connect, .{
637+
.socket = client,
638+
.addr = &address.any,
639+
.addrlen = address.getOsSockLen(),
640+
}, .unlinked),
641+
});
642+
643+
const client_addr = std.net.Address.initPosix(&client_addr_posix);
644+
try std.testing.expectEqual(address.in.sa.addr, client_addr.in.sa.addr);
645+
646+
var buf1: [32]u8 = undefined;
647+
var wlen1: usize = 0;
648+
var rlen1: usize = 0;
649+
var buf2: [32]u8 = undefined;
650+
var wlen2: usize = 0;
651+
var rlen2: usize = 0;
652+
try multi(.{
653+
op(.send, .{ .socket = client_comm, .buffer = "PING", .out_written = &wlen1 }, .soft),
654+
op(.recv, .{ .socket = client, .buffer = &buf1, .out_read = &rlen1 }, .soft),
655+
op(.send, .{ .socket = client, .buffer = "PONG", .out_written = &wlen2 }, .soft),
656+
op(.recv, .{ .socket = client_comm, .buffer = &buf2, .out_read = &rlen2 }, .unlinked),
657+
});
658+
659+
try std.testing.expectEqual(wlen1, 4);
660+
try std.testing.expectEqual(rlen1, 4);
661+
try std.testing.expectEqual(wlen1, wlen2);
662+
try std.testing.expectEqual(rlen1, rlen2);
663+
try std.testing.expectEqualSlices(u8, buf1[0..rlen1], "PING");
664+
try std.testing.expectEqualSlices(u8, buf2[0..rlen2], "PONG");
665+
666+
try single(.shutdown, .{ .socket = client, .how = .both });
667+
try single(.close_socket, .{ .socket = client });
668+
try single(.close_socket, .{ .socket = server });
669+
}
670+
671+
test "Socket/UDP" {
672+
if (builtin.target.os.tag == .wasi) {
673+
return error.SkipZigTest;
674+
}
675+
676+
var server: std.posix.socket_t = undefined;
677+
try single(.socket, .{
678+
.domain = std.posix.AF.INET,
679+
.flags = std.posix.SOCK.DGRAM | std.posix.SOCK.CLOEXEC,
680+
.protocol = std.posix.IPPROTO.UDP,
681+
.out_socket = &server,
682+
});
683+
684+
try std.posix.setsockopt(server, std.posix.SOL.SOCKET, std.posix.SO.REUSEADDR, &std.mem.toBytes(@as(c_int, 1)));
685+
if (@hasDecl(std.posix.SO, "REUSEPORT")) {
686+
try std.posix.setsockopt(server, std.posix.SOL.SOCKET, std.posix.SO.REUSEPORT, &std.mem.toBytes(@as(c_int, 1)));
687+
}
688+
689+
var client: std.posix.socket_t = undefined;
690+
try single(.socket, .{
691+
.domain = std.posix.AF.INET,
692+
.flags = std.posix.SOCK.DGRAM | std.posix.SOCK.CLOEXEC,
693+
.protocol = std.posix.IPPROTO.UDP,
694+
.out_socket = &client,
695+
});
696+
697+
try std.posix.setsockopt(client, std.posix.SOL.SOCKET, std.posix.SO.REUSEADDR, &std.mem.toBytes(@as(c_int, 1)));
698+
if (@hasDecl(std.posix.SO, "REUSEPORT")) {
699+
try std.posix.setsockopt(client, std.posix.SOL.SOCKET, std.posix.SO.REUSEPORT, &std.mem.toBytes(@as(c_int, 1)));
700+
}
701+
702+
const saddress = std.net.Address.initIp4(.{ 127, 0, 0, 1 }, 3131);
703+
const caddress = std.net.Address.initIp4(.{ 127, 0, 0, 1 }, 3232);
704+
try std.posix.bind(server, &saddress.any, saddress.getOsSockLen());
705+
try std.posix.bind(client, &caddress.any, caddress.getOsSockLen());
706+
707+
var ping_msg: posix.msghdr_const = .{
708+
.name = @ptrCast(&caddress.any),
709+
.namelen = caddress.getOsSockLen(),
710+
.iov = &.{
711+
.{
712+
.base = "PING",
713+
.len = "PING".len,
714+
},
715+
},
716+
.iovlen = 1,
717+
.control = null,
718+
.controllen = 0,
719+
.flags = 0,
720+
};
721+
722+
var pong_msg: posix.msghdr_const = .{
723+
.name = @ptrCast(&saddress.any),
724+
.namelen = saddress.getOsSockLen(),
725+
.iov = &.{
726+
.{
727+
.base = "PONG",
728+
.len = "PONG".len,
729+
},
730+
},
731+
.iovlen = 1,
732+
.control = null,
733+
.controllen = 0,
734+
.flags = 0,
735+
};
736+
737+
var buf1: [32]u8 = undefined;
738+
var recv_addr1: std.posix.sockaddr align(4) = undefined;
739+
var recv_iovec1: [1]posix.iovec = .{.{
740+
.base = &buf1,
741+
.len = buf1.len,
742+
}};
743+
var recv_msg1: posix.msghdr = .{
744+
.name = @ptrCast(&recv_addr1),
745+
.namelen = @sizeOf(@TypeOf(recv_addr1)),
746+
.iov = &recv_iovec1,
747+
.iovlen = 1,
748+
.control = null,
749+
.controllen = 0,
750+
.flags = 0,
751+
};
752+
753+
var buf2: [32]u8 = undefined;
754+
var recv_addr2: std.posix.sockaddr align(4) = undefined;
755+
var recv_iovec2: [1]posix.iovec = .{.{
756+
.base = &buf2,
757+
.len = buf2.len,
758+
}};
759+
var recv_msg2: posix.msghdr = .{
760+
.name = @ptrCast(&recv_addr2),
761+
.namelen = @sizeOf(@TypeOf(recv_addr2)),
762+
.iov = &recv_iovec2,
763+
.iovlen = 1,
764+
.control = null,
765+
.controllen = 0,
766+
.flags = 0,
767+
};
768+
769+
var wlen1: usize = 0;
770+
var rlen1: usize = 0;
771+
var wlen2: usize = 0;
772+
var rlen2: usize = 0;
773+
try multi(.{
774+
op(.send_msg, .{ .socket = server, .msg = &ping_msg, .out_written = &wlen1 }, .soft),
775+
op(.recv_msg, .{ .socket = client, .out_msg = &recv_msg1, .out_read = &rlen1 }, .soft),
776+
op(.send_msg, .{ .socket = client, .msg = &pong_msg, .out_written = &wlen2 }, .soft),
777+
op(.recv_msg, .{ .socket = server, .out_msg = &recv_msg2, .out_read = &rlen2 }, .unlinked),
778+
});
779+
780+
const addr1 = std.net.Address.initPosix(&recv_addr1);
781+
std.debug.assert(addr1.eql(saddress));
782+
const addr2 = std.net.Address.initPosix(&recv_addr2);
783+
std.debug.assert(addr2.eql(caddress));
784+
785+
try std.testing.expectEqual(wlen1, 4);
786+
try std.testing.expectEqual(rlen1, 4);
787+
try std.testing.expectEqual(wlen1, wlen2);
788+
try std.testing.expectEqual(rlen1, rlen2);
789+
try std.testing.expectEqualSlices(u8, buf1[0..rlen1], "PING");
790+
try std.testing.expectEqualSlices(u8, buf2[0..rlen2], "PONG");
791+
792+
try single(.close_socket, .{ .socket = client });
793+
try single(.close_socket, .{ .socket = server });
609794
}
610795

611796
test "EventSource" {

0 commit comments

Comments
 (0)