* delete the std/event/net directory * `std.event.Loop.waitUntilFdReadable` and related functions no longer have possibility of failure. On Linux, they fall back to poll() and then fall back to sleep(). * add some missing `noasync` decorations in `std.event.Loop` * redo the `std.net.Server` API. it's quite nice now, but shutdown does not work cleanly. There is a race condition with close() that I am actively working on. * move `std.io.OutStream` to its own file to match `std.io.InStream`. I started working on making `write` integrated with evented I/O, but it got tricky so I backed off and filed #3557. However I did integrate `std.os.writev` and `std.os.pwritev` with evented I/O. * add `std.Target.stack_align` * move networking tests to `lib/std/net/test.zig` * add `std.net.tcpConnectToHost` and `std.net.tcpConnectToAddress`. * rename `error.UnknownName` to `error.UnknownHostName` within the context of DNS resolution. * add `std.os.readv`, which is integrated with evented I/O. * `std.os.preadv`, is now integrated with evented I/O. * `std.os.accept4` now asserts that ENOTSOCK and EOPNOTSUPP never occur (misuse of API), instead of returning errors. * `std.os.connect` is now integrated with evented I/O. `std.os.connect_async` is gone. Just use `std.os.connect`. * fix false positive dependency loop regarding async function frames * add more compile notes to help when dependency loops occur in determining whether a function is async. * ir: change an assert to ir_assert to make it easier to find workarounds for when such an assert is triggered. In this case it was trying to parse an IPv4 address at comptime.
72 lines
2.2 KiB
Zig
72 lines
2.2 KiB
Zig
const std = @import("../std.zig");
|
|
const net = std.net;
|
|
const mem = std.mem;
|
|
const testing = std.testing;
|
|
|
|
test "std.net.parseIp4" {
|
|
assert((try parseIp4("127.0.0.1")) == mem.bigToNative(u32, 0x7f000001));
|
|
|
|
testParseIp4Fail("256.0.0.1", error.Overflow);
|
|
testParseIp4Fail("x.0.0.1", error.InvalidCharacter);
|
|
testParseIp4Fail("127.0.0.1.1", error.InvalidEnd);
|
|
testParseIp4Fail("127.0.0.", error.Incomplete);
|
|
testParseIp4Fail("100..0.1", error.InvalidCharacter);
|
|
}
|
|
|
|
fn testParseIp4Fail(buf: []const u8, expected_err: anyerror) void {
|
|
if (parseIp4(buf)) |_| {
|
|
@panic("expected error");
|
|
} else |e| {
|
|
assert(e == expected_err);
|
|
}
|
|
}
|
|
|
|
test "std.net.parseIp6" {
|
|
const ip6 = try parseIp6("FF01:0:0:0:0:0:0:FB");
|
|
const addr = Address.initIp6(ip6, 80);
|
|
var buf: [100]u8 = undefined;
|
|
const printed = try std.fmt.bufPrint(&buf, "{}", addr);
|
|
std.testing.expect(mem.eql(u8, "[ff01::fb]:80", printed));
|
|
}
|
|
|
|
test "listen on a port, send bytes, receive bytes" {
|
|
if (std.builtin.os != .linux) {
|
|
// TODO build abstractions for other operating systems
|
|
return error.SkipZigTest;
|
|
}
|
|
if (std.io.mode != .evented) {
|
|
// TODO add ability to run tests in non-blocking I/O mode
|
|
return error.SkipZigTest;
|
|
}
|
|
|
|
// TODO doing this at comptime crashed the compiler
|
|
const localhost = net.Address.initIp4(net.parseIp4("127.0.0.1") catch unreachable, 0);
|
|
|
|
var server = try net.Server.init(net.Server.Options{});
|
|
defer server.deinit();
|
|
try server.listen(localhost);
|
|
|
|
var server_frame = async testServer(&server);
|
|
var client_frame = async testClient(server.listen_address);
|
|
|
|
try await server_frame;
|
|
try await client_frame;
|
|
}
|
|
|
|
fn testClient(addr: net.Address) anyerror!void {
|
|
const socket_file = try net.tcpConnectToAddress(addr);
|
|
defer socket_file.close();
|
|
|
|
var buf: [100]u8 = undefined;
|
|
const len = try socket_file.read(&buf);
|
|
const msg = buf[0..len];
|
|
testing.expect(mem.eql(u8, msg, "hello from server\n"));
|
|
}
|
|
|
|
fn testServer(server: *net.Server) anyerror!void {
|
|
var client_file = try server.connections.get();
|
|
|
|
const stream = &client_file.outStream().stream;
|
|
try stream.print("hello from server\n");
|
|
}
|