diff options
Diffstat (limited to 'test/transport.zig')
| -rw-r--r-- | test/transport.zig | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/test/transport.zig b/test/transport.zig new file mode 100644 index 0000000..3d43ddb --- /dev/null +++ b/test/transport.zig @@ -0,0 +1,82 @@ +const std = @import("std"); +const c9 = @import("cloud9"); +const t = c9.transport; +const testing = std.testing; + +test "standard readers and writers preserve frame boundaries" { + var bytes: [128]u8 = undefined; + const frame = try c9.encode(.{ .tversion = .{ .msize = 4096, .version = "9P2000" } }, c9.notag, &bytes); + var source: testing.Reader = .init(&.{}, &.{.{ .buffer = frame }}); + source.artificial_limit = .limited(1); + var target: [128]u8 = undefined; + const got = try t.readFrame(&source.interface, &target, 4096); + try testing.expectEqualSlices(u8, frame, got); + var output: [128]u8 = undefined; + var writer: std.Io.Writer = .fixed(&output); + try t.writeFrame(&writer, got, 4096); + try testing.expectEqualSlices(u8, frame, writer.buffered()); +} + +test "POSIX TCP and Unix streams handle retry and EOF" { + var dir = testing.tmpDir(.{}); + defer dir.cleanup(); + const io = testing.io; + var path_buffer: [std.fs.max_path_bytes]u8 = undefined; + const parent_len = try dir.dir.realPath(io, &path_buffer); + const parent = path_buffer[0..parent_len]; + var unix_buffer: [t.sun_path_len]u8 = undefined; + const unix = try std.fmt.bufPrintSentinel(&unix_buffer, "{s}/9p", .{parent}, 0); + for ([_]t.Address{ .{ .tcp = .{ .ip4 = .loopback(0) } }, .{ .unix = unix } }) |address| { + const listener = try t.listenFd(address, 4); + defer t.close(listener); + var destination = address; + if (address == .tcp) { + var actual: std.c.sockaddr.in = undefined; + var len: std.c.socklen_t = @sizeOf(@TypeOf(actual)); + try testing.expectEqual(@as(c_int, 0), std.c.getsockname(listener, @ptrCast(&actual), &len)); + destination.tcp.setPort(std.mem.bigToNative(u16, actual.port)); + } + const client = try t.connectFd(destination, t.nowMs() + 1000); + defer t.close(client); + const server = (try t.acceptFd(listener, address == .tcp)) orelse return error.NoConnection; + var buffer: [32]u8 = undefined; + try testing.expectEqual(@as(?usize, null), try t.read(server, &buffer)); + try testing.expectEqual(@as(?usize, 3), try t.write(client, "abc")); + try t.wait(server, @intCast(std.c.POLL.IN), t.nowMs() + 1000); + try testing.expectEqual(@as(?usize, 3), try t.read(server, &buffer)); + try testing.expectEqualStrings("abc", buffer[0..3]); + t.close(server); + try t.wait(client, @intCast(std.c.POLL.IN), t.nowMs() + 1000); + try testing.expectEqual(@as(?usize, 0), try t.read(client, &buffer)); + } +} + +test "std.Io TCP and Unix listener and client adapters" { + var dir = testing.tmpDir(.{}); + defer dir.cleanup(); + const io = testing.io; + var path_buffer: [std.fs.max_path_bytes]u8 = undefined; + const parent_len = try dir.dir.realPath(io, &path_buffer); + const parent = path_buffer[0..parent_len]; + var unix_buffer: [t.sun_path_len]u8 = undefined; + const unix = try std.fmt.bufPrintSentinel(&unix_buffer, "{s}/9p", .{parent}, 0); + for ([_]t.Address{ .{ .tcp = .{ .ip4 = .loopback(0) } }, .{ .unix = unix } }) |address| { + var listener = try t.listen(io, address, 4); + defer listener.deinit(io); + const destination: t.Address = if (address == .tcp) .{ .tcp = listener.socket.address } else address; + const client = try t.connect(io, destination); + defer client.close(io); + const server = try listener.accept(io); + defer server.close(io); + var output: [128]u8 = undefined; + var writer = client.writer(io, &output); + var bytes: [128]u8 = undefined; + const frame = try c9.encode(.rflush, 1, &bytes); + try t.writeFrame(&writer.interface, frame, 4096); + try writer.interface.flush(); + var input: [128]u8 = undefined; + var reader = server.reader(io, &input); + var target: [128]u8 = undefined; + try testing.expectEqualSlices(u8, frame, try t.readFrame(&reader.interface, &target, 4096)); + } +} |
