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 }