lib/wayland/src/test.zig
daab053ee43316e1809a84551d573ddd1e5bf3d2
1 const std = @import("std");
2 const wayland = @import("root.zig");
3
4 const Transport = wayland.Transport;
5 const TransportCapacity = wayland.TransportCapacity;
6 const stream = wayland.stream;
7 const transport = wayland.transport;
8 const wire = wayland.wire;
9
10 test "Wayland transport package namespace is complete" {
11 std.testing.refAllDecls(wayland);
12 _ = @import("protocol/test.zig");
13 _ = @import("runtime/test.zig");
14 _ = @import("stream/test.zig");
15 }
16
17 test "interleaved requests preserve descriptor order across ancillary batches" {
18 const sys = @import("sys");
19 const capacity = try TransportCapacity.derive(.{
20 .inbound_descriptor_count = sys.ancillary.maximum_descriptors + 1,
21 .outbound_descriptor_count = sys.ancillary.maximum_descriptors + 1,
22 });
23
24 const sockets = sys.fd.socketPairUnixStream(.{ .close_on_exec = true }) catch |err| switch (err) {
25 error.UnsupportedPlatform => return error.SkipZigTest,
26 else => return err,
27 };
28 var sender = Transport.initOwned(std.testing.allocator, sockets[0], capacity) catch |err| {
29 sys.fd.close(sockets[1]);
30 return err;
31 };
32 defer sender.deinit();
33 var receiver = try Transport.initOwned(std.testing.allocator, sockets[1], capacity);
34 defer receiver.deinit();
35
36 const first_pipe = try sys.fd.pipeWithOptions(.{ .close_on_exec = true });
37 defer sys.fd.close(first_pipe[0]);
38 defer sys.fd.close(first_pipe[1]);
39 const last_pipe = try sys.fd.pipeWithOptions(.{ .close_on_exec = true });
40 defer sys.fd.close(last_pipe[0]);
41 defer sys.fd.close(last_pipe[1]);
42
43 var first_descriptors: [sys.ancillary.maximum_descriptors]sys.fd.Descriptor = undefined;
44 var first_descriptor_count: usize = 0;
45 var first_queued = false;
46 defer if (!first_queued) {
47 for (first_descriptors[0..first_descriptor_count]) |descriptor| sys.fd.close(descriptor);
48 };
49 while (first_descriptor_count < first_descriptors.len) : (first_descriptor_count += 1) {
50 first_descriptors[first_descriptor_count] = try sys.fd.duplicate(first_pipe[1]);
51 }
52 const last_descriptor = try sys.fd.duplicate(last_pipe[1]);
53 var last_queued = false;
54 defer if (!last_queued) sys.fd.close(last_descriptor);
55
56 try sender.queueOwned(2, 10, &.{}, &first_descriptors);
57 first_queued = true;
58 try sender.queueOwned(3, 11, &.{}, &.{});
59 try sender.queueOwned(4, 12, &.{}, &.{last_descriptor});
60 last_queued = true;
61 try std.testing.expectEqual(stream.FlushStatus.drained, try sender.flush());
62
63 try std.testing.expectEqual(transport.ReceiveStatus.data, try receiver.receive());
64 try std.testing.expectEqual(@as(usize, 1), receiver.inbox.queuedByteCount());
65 try std.testing.expectEqual(first_descriptors.len, receiver.inbox.queuedDescriptorCount());
66 try std.testing.expect((try receiver.inbox.peek()) == null);
67 try std.testing.expectEqual(transport.ReceiveStatus.data, try receiver.receive());
68 try std.testing.expectEqual(@as(usize, 3 * wire.header_size), receiver.inbox.queuedByteCount());
69 try std.testing.expectEqual(first_descriptors.len + 1, receiver.inbox.queuedDescriptorCount());
70
71 var received_descriptors: [first_descriptors.len + 1]sys.fd.Descriptor = undefined;
72 var received_descriptor_count: usize = 0;
73 defer {
74 for (received_descriptors[0..received_descriptor_count]) |descriptor| sys.fd.close(descriptor);
75 }
76
77 try std.testing.expectEqual(@as(u32, 2), (try receiver.inbox.peek()).?.header.object_id);
78 for (received_descriptors[0..first_descriptors.len]) |*descriptor| {
79 descriptor.* = receiver.inbox.takeDescriptor().?;
80 received_descriptor_count += 1;
81 }
82 try receiver.inbox.consume();
83 try std.testing.expectEqual(@as(u32, 3), (try receiver.inbox.peek()).?.header.object_id);
84 try receiver.inbox.consume();
85 try std.testing.expectEqual(@as(u32, 4), (try receiver.inbox.peek()).?.header.object_id);
86 received_descriptors[first_descriptors.len] = receiver.inbox.takeDescriptor().?;
87 received_descriptor_count += 1;
88 try receiver.inbox.consume();
89 try std.testing.expect(receiver.inbox.takeDescriptor() == null);
90
91 for (received_descriptors[0..first_descriptors.len]) |descriptor| {
92 try std.testing.expectEqual(@as(usize, 1), try sys.fd.write(descriptor, "a"));
93 }
94 try std.testing.expectEqual(
95 @as(usize, 1),
96 try sys.fd.write(received_descriptors[first_descriptors.len], "b"),
97 );
98
99 var first_bytes: [first_descriptors.len]u8 = undefined;
100 var first_byte_count: usize = 0;
101 while (first_byte_count < first_bytes.len) {
102 first_byte_count += try sys.fd.read(first_pipe[0], first_bytes[first_byte_count..]);
103 }
104 for (first_bytes) |byte| try std.testing.expectEqual(@as(u8, 'a'), byte);
105 var last_byte: [1]u8 = undefined;
106 try std.testing.expectEqual(@as(usize, 1), try sys.fd.read(last_pipe[0], &last_byte));
107 try std.testing.expectEqual(@as(u8, 'b'), last_byte[0]);
108 }