summaryrefslogtreecommitdiff
path: root/test/transport.zig
diff options
context:
space:
mode:
Diffstat (limited to 'test/transport.zig')
-rw-r--r--test/transport.zig82
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));
+ }
+}