зеркало из https://github.com/github/ruby.git
200 строки
4.1 KiB
Ruby
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
|