zig/lib/std/net/test.zig
Andrew Kelley c3d816a98e
std lib networking improvements, especially non-blocking I/O
* 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.
2019-10-29 22:59:30 -04:00

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");
}