1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
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));
}
}
|