From f0d9daaaac162bc0c87d25be9613e6383a0c8359 Mon Sep 17 00:00:00 2001 From: Samuel Williams Date: Thu, 24 Sep 2026 12:44:42 +1200 Subject: [PATCH 1/2] Cover partial and zero-progress writes in the legacy Select backend --- test/io/event/selector/select.rb | 51 ++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/test/io/event/selector/select.rb b/test/io/event/selector/select.rb index b1a2d58d..6639658b 100644 --- a/test/io/event/selector/select.rb +++ b/test/io/event/selector/select.rb @@ -88,6 +88,57 @@ end end + with "#io_write (legacy IO::Buffer)" do + before do + if defined?(IO::Buffer::VERSION) && IO::Buffer::VERSION >= 3 + skip "Requires the legacy minimum-length write loop" + end + end + + it "advances the offset after a partial write until the minimum is reached" do + input, output = IO.pipe + buffer = IO::Buffer.new(8) + writes = [] + results = [2, 2] + + # Force short writes without depending on the pipe's capacity: + mock(buffer) do |mock| + mock.replace(:write) do |io, length, offset| + writes << [io, length, offset] + results.shift or raise "Unexpected write!" + end + end + + expect(selector.io_write(Fiber.current, output, buffer, 4, 1)).to be == 4 + expect(writes).to be == [[output, 0, 1], [output, 0, 3]] + ensure + input&.close + output&.close + buffer&.free + end + + it "stops on a zero-byte write and returns the bytes already written" do + input, output = IO.pipe + buffer = IO::Buffer.new(8) + writes = [] + results = [2, 0] + + mock(buffer) do |mock| + mock.replace(:write) do |io, length, offset| + writes << [io, length, offset] + results.shift or raise "Unexpected write!" + end + end + + expect(selector.io_write(Fiber.current, output, buffer, 4, 1)).to be == 2 + expect(writes).to be == [[output, 0, 1], [output, 0, 3]] + ensure + input&.close + output&.close + buffer&.free + end + end + with "#select" do it "dispatches priority events" do server = TCPServer.new("127.0.0.1", 0) From 63fbea56344340e056d53c4203dc86ce2dcb5aac Mon Sep 17 00:00:00 2001 From: Samuel Williams Date: Thu, 24 Sep 2026 12:47:31 +1200 Subject: [PATCH 2/2] Skip legacy write tests from their test bodies on Ruby head --- test/io/event/selector/select.rb | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/test/io/event/selector/select.rb b/test/io/event/selector/select.rb index 6639658b..a35ef92b 100644 --- a/test/io/event/selector/select.rb +++ b/test/io/event/selector/select.rb @@ -89,13 +89,9 @@ end with "#io_write (legacy IO::Buffer)" do - before do - if defined?(IO::Buffer::VERSION) && IO::Buffer::VERSION >= 3 - skip "Requires the legacy minimum-length write loop" - end - end - it "advances the offset after a partial write until the minimum is reached" do + skip "Requires the legacy minimum-length write loop" if defined?(IO::Buffer::VERSION) && IO::Buffer::VERSION >= 3 + input, output = IO.pipe buffer = IO::Buffer.new(8) writes = [] @@ -118,6 +114,8 @@ end it "stops on a zero-byte write and returns the bytes already written" do + skip "Requires the legacy minimum-length write loop" if defined?(IO::Buffer::VERSION) && IO::Buffer::VERSION >= 3 + input, output = IO.pipe buffer = IO::Buffer.new(8) writes = []