ruby/test/fiber/test_io_buffer.rb

200 строки
4.1 KiB
Ruby

# frozen_string_literal: true
require 'test/unit'
require_relative 'scheduler'
require 'timeout'
class TestFiberIOBuffer < Test::Unit::TestCase
MESSAGE = "Hello World"
def test_read_write_blocking
omit "UNIXSocket is not defined!" unless defined?(UNIXSocket)
i, o = UNIXSocket.pair
i.nonblock = false
o.nonblock = false
message = nil
thread = Thread.new do
scheduler = IOBufferScheduler.new
Fiber.set_scheduler scheduler
Fiber.schedule do
message = i.read(20)
i.close
end
Fiber.schedule do
o.write(MESSAGE)
o.close
end
end
thread.join
assert_equal MESSAGE, message
assert_predicate(i, :closed?)
assert_predicate(o, :closed?)
ensure
i&.close
o&.close
end
def test_timeout_after
omit "UNIXSocket is not defined!" unless defined?(UNIXSocket)
i, o = UNIXSocket.pair
i.nonblock = false
o.nonblock = false
message = nil
error = nil
thread = Thread.new do
scheduler = IOBufferScheduler.new
Fiber.set_scheduler scheduler
Fiber.schedule do
Timeout.timeout(0.1) do
message = i.read(20)
end
rescue Timeout::Error => error
# Assertions below.
ensure
i.close
end
end
thread.join
assert_nil message
assert_kind_of Timeout::Error, error
ensure
i&.close
o&.close
end
def test_read_nonblock
omit "UNIXSocket is not defined!" unless defined?(UNIXSocket)
i, o = UNIXSocket.pair
message = nil
thread = Thread.new do
scheduler = IOBufferScheduler.new
Fiber.set_scheduler scheduler
Fiber.schedule do
message = i.read_nonblock(20, exception: false)
i.close
end
end
thread.join
assert_equal :wait_readable, message
ensure
i&.close
o&.close
end
def test_write_nonblock
omit "UNIXSocket is not defined!" unless defined?(UNIXSocket)
i, o = UNIXSocket.pair
thread = Thread.new do
scheduler = IOBufferScheduler.new
Fiber.set_scheduler scheduler
Fiber.schedule do
o.write_nonblock(MESSAGE, exception: false)
o.close
end
end
thread.join
assert_equal MESSAGE, i.read
ensure
i&.close
o&.close
end
def test_io_buffer_read_write
omit "UNIXSocket is not defined!" unless defined?(UNIXSocket)
i, o = UNIXSocket.pair
source_buffer = IO::Buffer.for("Hello World!")
destination_buffer = IO::Buffer.new(source_buffer.size)
# Test non-scheduler code path:
source_buffer.write(o, source_buffer.size)
destination_buffer.read(i, source_buffer.size)
assert_equal source_buffer, destination_buffer
# Test scheduler code path:
destination_buffer.clear
thread = Thread.new do
scheduler = IOBufferScheduler.new
Fiber.set_scheduler scheduler
Fiber.schedule do
source_buffer.write(o, source_buffer.size)
destination_buffer.read(i, source_buffer.size)
end
end
thread.join
assert_equal source_buffer, destination_buffer
ensure
i&.close
o&.close
end
def nonblockable?(io)
io.nonblock{}
true
rescue
false
end
def test_io_buffer_pread_pwrite
file = Tempfile.new("test_io_buffer_pread_pwrite")
omit "Non-blocking file IO is not supported" unless nonblockable?(file)
source_buffer = IO::Buffer.for("Hello World!")
destination_buffer = IO::Buffer.new(source_buffer.size)
# Test non-scheduler code path:
source_buffer.pwrite(file, 1, source_buffer.size)
destination_buffer.pread(file, 1, source_buffer.size)
assert_equal source_buffer, destination_buffer
# Test scheduler code path:
destination_buffer.clear
file.truncate(0)
thread = Thread.new do
scheduler = IOBufferScheduler.new
Fiber.set_scheduler scheduler
Fiber.schedule do
source_buffer.pwrite(file, 1, source_buffer.size)
destination_buffer.pread(file, 1, source_buffer.size)
end
end
thread.join
assert_equal source_buffer, destination_buffer
ensure
file&.close!
end
end