Fix tests for fast_fallback (#12406)
* TCPSocket.new: Close resources in ensure * TCPSocket.new: Remove unnecessary comments * Socket.tcp: Make assert_separately in TestSocket more readable * Socket.tcp: Returning instead of exiting * Socket.tcp: Close resources in ensure * Socket.tcp: Avoid test failures on hosts that only support IPv4
This commit is contained in:
parent
2f6c694977
commit
b53a75230f
Notes:
git
2025-05-14 12:41:59 +00:00
Merged-By: shioimm <shioi.mm@gmail.com>
@ -780,17 +780,18 @@ class TestSocket < Test::Unit::TestCase
|
||||
|
||||
def test_tcp_socket_v6_hostname_resolved_earlier
|
||||
opts = %w[-rsocket -W1]
|
||||
assert_separately opts, "#{<<-"begin;"}\n#{<<-'end;'}"
|
||||
|
||||
begin;
|
||||
assert_separately opts, <<~RUBY
|
||||
begin
|
||||
begin
|
||||
# Verify that "localhost" can be resolved to an IPv6 address
|
||||
Socket.getaddrinfo("localhost", 0, Socket::AF_INET6)
|
||||
server = TCPServer.new("::1", 0)
|
||||
rescue Errno::EADDRNOTAVAIL # IPv6 is not supported
|
||||
exit
|
||||
rescue Socket::ResolutionError, Errno::EADDRNOTAVAIL # IPv6 is not supported
|
||||
return
|
||||
end
|
||||
|
||||
_, port, = server.addr
|
||||
server_thread = Thread.new { server.accept }
|
||||
port = server.addr[1]
|
||||
|
||||
Addrinfo.define_singleton_method(:getaddrinfo) do |_, _, family, *_|
|
||||
case family
|
||||
@ -801,19 +802,21 @@ class TestSocket < Test::Unit::TestCase
|
||||
|
||||
socket = Socket.tcp("localhost", port)
|
||||
assert_true(socket.remote_address.ipv6?)
|
||||
server_thread.value.close
|
||||
server.close
|
||||
socket.close if socket && !socket.closed?
|
||||
end;
|
||||
ensure
|
||||
server_thread&.value&.close
|
||||
server&.close
|
||||
socket&.close
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
def test_tcp_socket_v4_hostname_resolved_earlier
|
||||
opts = %w[-rsocket -W1]
|
||||
assert_separately opts, "#{<<-"begin;"}\n#{<<-'end;'}"
|
||||
|
||||
begin;
|
||||
assert_separately opts, <<~RUBY
|
||||
begin
|
||||
server = TCPServer.new("127.0.0.1", 0)
|
||||
port = server.addr[1]
|
||||
_, port, = server.addr
|
||||
server_thread = Thread.new { server.accept }
|
||||
|
||||
Addrinfo.define_singleton_method(:getaddrinfo) do |_, _, family, *_|
|
||||
case family
|
||||
@ -822,27 +825,31 @@ class TestSocket < Test::Unit::TestCase
|
||||
end
|
||||
end
|
||||
|
||||
server_thread = Thread.new { server.accept }
|
||||
socket = Socket.tcp("localhost", port)
|
||||
assert_true(socket.remote_address.ipv4?)
|
||||
server_thread.value.close
|
||||
server.close
|
||||
socket.close if socket && !socket.closed?
|
||||
end;
|
||||
ensure
|
||||
server_thread&.value&.close
|
||||
server&.close
|
||||
socket&.close
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
def test_tcp_socket_v6_hostname_resolved_in_resolution_delay
|
||||
opts = %w[-rsocket -W1]
|
||||
assert_separately opts, "#{<<-"begin;"}\n#{<<-'end;'}"
|
||||
|
||||
begin;
|
||||
assert_separately opts, <<~RUBY
|
||||
begin
|
||||
begin
|
||||
# Verify that "localhost" can be resolved to an IPv6 address
|
||||
Socket.getaddrinfo("localhost", 0, Socket::AF_INET6)
|
||||
server = TCPServer.new("::1", 0)
|
||||
rescue Errno::EADDRNOTAVAIL # IPv6 is not supported
|
||||
exit
|
||||
rescue Socket::ResolutionError, Errno::EADDRNOTAVAIL # IPv6 is not supported
|
||||
return
|
||||
end
|
||||
|
||||
port = server.addr[1]
|
||||
_, port, = server.addr
|
||||
server_thread = Thread.new { server.accept }
|
||||
|
||||
delay_time = 0.025 # Socket::RESOLUTION_DELAY (private) is 0.05
|
||||
|
||||
Addrinfo.define_singleton_method(:getaddrinfo) do |_, _, family, *_|
|
||||
@ -852,24 +859,25 @@ class TestSocket < Test::Unit::TestCase
|
||||
end
|
||||
end
|
||||
|
||||
server_thread = Thread.new { server.accept }
|
||||
socket = Socket.tcp("localhost", port)
|
||||
assert_true(socket.remote_address.ipv6?)
|
||||
server_thread.value.close
|
||||
server.close
|
||||
socket.close if socket && !socket.closed?
|
||||
end;
|
||||
ensure
|
||||
server_thread&.value&.close
|
||||
server&.close
|
||||
socket&.close
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
def test_tcp_socket_v6_hostname_resolved_earlier_and_v6_server_is_not_listening
|
||||
opts = %w[-rsocket -W1]
|
||||
assert_separately opts, "#{<<-"begin;"}\n#{<<-'end;'}"
|
||||
|
||||
begin;
|
||||
assert_separately opts, <<~RUBY
|
||||
begin
|
||||
ipv4_address = "127.0.0.1"
|
||||
ipv4_server = Socket.new(Socket::AF_INET, :STREAM)
|
||||
ipv4_server.bind(Socket.pack_sockaddr_in(0, ipv4_address))
|
||||
port = ipv4_server.connect_address.ip_port
|
||||
server = Socket.new(Socket::AF_INET, :STREAM)
|
||||
server.bind(Socket.pack_sockaddr_in(0, ipv4_address))
|
||||
port = server.connect_address.ip_port
|
||||
server_thread = Thread.new { server.listen(1); server.accept }
|
||||
|
||||
Addrinfo.define_singleton_method(:getaddrinfo) do |_, _, family, *_|
|
||||
case family
|
||||
@ -878,67 +886,71 @@ class TestSocket < Test::Unit::TestCase
|
||||
end
|
||||
end
|
||||
|
||||
ipv4_server_thread = Thread.new { ipv4_server.listen(1); ipv4_server.accept }
|
||||
socket = Socket.tcp("localhost", port)
|
||||
assert_equal(ipv4_address, socket.remote_address.ip_address)
|
||||
|
||||
accepted, _ = ipv4_server_thread.value
|
||||
accepted.close
|
||||
ipv4_server.close
|
||||
socket.close if socket && !socket.closed?
|
||||
end;
|
||||
ensure
|
||||
accepted, _ = server_thread&.value
|
||||
accepted&.close
|
||||
server&.close
|
||||
socket&.close
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
def test_tcp_socket_resolv_timeout
|
||||
opts = %w[-rsocket -W1]
|
||||
assert_separately opts, "#{<<-"begin;"}\n#{<<-'end;'}"
|
||||
assert_separately opts, <<~RUBY
|
||||
begin
|
||||
server = TCPServer.new("localhost", 0)
|
||||
_, port, = server.addr
|
||||
|
||||
begin;
|
||||
Addrinfo.define_singleton_method(:getaddrinfo) { |*_| sleep }
|
||||
port = TCPServer.new("localhost", 0).addr[1]
|
||||
|
||||
assert_raise(Errno::ETIMEDOUT) do
|
||||
Socket.tcp("localhost", port, resolv_timeout: 0.01)
|
||||
end
|
||||
end;
|
||||
ensure
|
||||
server&.close
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
def test_tcp_socket_resolv_timeout_with_connection_failure
|
||||
opts = %w[-rsocket -W1]
|
||||
assert_separately opts, "#{<<-"begin;"}\n#{<<-'end;'}"
|
||||
assert_separately opts, <<~RUBY
|
||||
server = TCPServer.new("127.0.0.1", 12345)
|
||||
_, port, = server.addr
|
||||
|
||||
begin;
|
||||
server = TCPServer.new("127.0.0.1", 12345)
|
||||
_, port, = server.addr
|
||||
|
||||
Addrinfo.define_singleton_method(:getaddrinfo) do |_, _, family, *_|
|
||||
if family == Socket::AF_INET6
|
||||
sleep
|
||||
else
|
||||
[Addrinfo.tcp("127.0.0.1", port)]
|
||||
end
|
||||
Addrinfo.define_singleton_method(:getaddrinfo) do |_, _, family, *_|
|
||||
if family == Socket::AF_INET6
|
||||
sleep
|
||||
else
|
||||
[Addrinfo.tcp("127.0.0.1", port)]
|
||||
end
|
||||
end
|
||||
|
||||
server.close
|
||||
server.close
|
||||
|
||||
assert_raise(Errno::ETIMEDOUT) do
|
||||
Socket.tcp("localhost", port, resolv_timeout: 0.01)
|
||||
end
|
||||
end;
|
||||
assert_raise(Errno::ETIMEDOUT) do
|
||||
Socket.tcp("localhost", port, resolv_timeout: 0.01)
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
def test_tcp_socket_one_hostname_resolution_succeeded_at_least
|
||||
opts = %w[-rsocket -W1]
|
||||
assert_separately opts, "#{<<-"begin;"}\n#{<<-'end;'}"
|
||||
|
||||
begin;
|
||||
assert_separately opts, <<~RUBY
|
||||
begin
|
||||
begin
|
||||
# Verify that "localhost" can be resolved to an IPv6 address
|
||||
Socket.getaddrinfo("localhost", 0, Socket::AF_INET6)
|
||||
server = TCPServer.new("::1", 0)
|
||||
rescue Errno::EADDRNOTAVAIL # IPv6 is not supported
|
||||
exit
|
||||
rescue Socket::ResolutionError, Errno::EADDRNOTAVAIL # IPv6 is not supported
|
||||
return
|
||||
end
|
||||
|
||||
port = server.addr[1]
|
||||
_, port, = server.addr
|
||||
server_thread = Thread.new { server.accept }
|
||||
|
||||
Addrinfo.define_singleton_method(:getaddrinfo) do |_, _, family, *_|
|
||||
case family
|
||||
@ -947,63 +959,69 @@ class TestSocket < Test::Unit::TestCase
|
||||
end
|
||||
end
|
||||
|
||||
server_thread = Thread.new { server.accept }
|
||||
socket = nil
|
||||
|
||||
assert_nothing_raised do
|
||||
socket = Socket.tcp("localhost", port)
|
||||
end
|
||||
|
||||
server_thread.value.close
|
||||
server.close
|
||||
socket.close if socket && !socket.closed?
|
||||
end;
|
||||
ensure
|
||||
server_thread&.value&.close
|
||||
server&.close
|
||||
socket&.close
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
def test_tcp_socket_all_hostname_resolution_failed
|
||||
opts = %w[-rsocket -W1]
|
||||
assert_separately opts, "#{<<-"begin;"}\n#{<<-'end;'}"
|
||||
assert_separately opts, <<~RUBY
|
||||
begin
|
||||
server = TCPServer.new("localhost", 0)
|
||||
_, port, = server.addr
|
||||
|
||||
begin;
|
||||
Addrinfo.define_singleton_method(:getaddrinfo) do |_, _, family, *_|
|
||||
case family
|
||||
when Socket::AF_INET6 then raise SocketError
|
||||
when Socket::AF_INET then sleep(0.001); raise SocketError, "Last hostname resolution error"
|
||||
end
|
||||
end
|
||||
port = TCPServer.new("localhost", 0).addr[1]
|
||||
|
||||
assert_raise_with_message(SocketError, "Last hostname resolution error") do
|
||||
Socket.tcp("localhost", port)
|
||||
end
|
||||
end;
|
||||
ensure
|
||||
server&.close
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
def test_tcp_socket_v6_address_passed
|
||||
opts = %w[-rsocket -W1]
|
||||
assert_separately opts, "#{<<-"begin;"}\n#{<<-'end;'}"
|
||||
|
||||
begin;
|
||||
assert_separately opts, <<~RUBY
|
||||
begin
|
||||
begin
|
||||
# Verify that "localhost" can be resolved to an IPv6 address
|
||||
Socket.getaddrinfo("localhost", 0, Socket::AF_INET6)
|
||||
server = TCPServer.new("::1", 0)
|
||||
rescue Errno::EADDRNOTAVAIL # IPv6 is not supported
|
||||
exit
|
||||
rescue Socket::ResolutionError, Errno::EADDRNOTAVAIL # IPv6 is not supported
|
||||
return
|
||||
end
|
||||
|
||||
_, port, = server.addr
|
||||
server_thread = Thread.new { server.accept }
|
||||
|
||||
Addrinfo.define_singleton_method(:getaddrinfo) do |*_|
|
||||
[Addrinfo.tcp("::1", port)]
|
||||
end
|
||||
|
||||
server_thread = Thread.new { server.accept }
|
||||
socket = Socket.tcp("::1", port)
|
||||
|
||||
assert_true(socket.remote_address.ipv6?)
|
||||
server_thread.value.close
|
||||
server.close
|
||||
socket.close if socket && !socket.closed?
|
||||
end;
|
||||
ensure
|
||||
server_thread&.value&.close
|
||||
server&.close
|
||||
socket&.close
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
def test_tcp_socket_fast_fallback_is_false
|
||||
@ -1011,11 +1029,11 @@ class TestSocket < Test::Unit::TestCase
|
||||
_, port, = server.addr
|
||||
server_thread = Thread.new { server.accept }
|
||||
socket = Socket.tcp("127.0.0.1", port, fast_fallback: false)
|
||||
|
||||
assert_true(socket.remote_address.ipv4?)
|
||||
server_thread.value.close
|
||||
server.close
|
||||
socket.close if socket && !socket.closed?
|
||||
ensure
|
||||
server_thread&.value&.close
|
||||
server&.close
|
||||
socket&.close
|
||||
end
|
||||
|
||||
def test_tcp_fast_fallback
|
||||
|
@ -142,7 +142,6 @@ class TestSocket_TCPSocket < Test::Unit::TestCase
|
||||
end
|
||||
|
||||
def test_initialize_v6_hostname_resolved_earlier
|
||||
# pend "to suppress the output of test failure logs in CI temporarily"
|
||||
return if RUBY_PLATFORM =~ /mswin|mingw|cygwin/
|
||||
|
||||
begin
|
||||
@ -163,13 +162,13 @@ class TestSocket_TCPSocket < Test::Unit::TestCase
|
||||
test_mode_settings: { delay: { ipv4: 1000 } }
|
||||
)
|
||||
assert_true(socket.remote_address.ipv6?)
|
||||
server_thread.value.close
|
||||
server.close
|
||||
socket.close if socket && !socket.closed?
|
||||
ensure
|
||||
server_thread&.value&.close
|
||||
server&.close
|
||||
socket&.close
|
||||
end
|
||||
|
||||
def test_initialize_v4_hostname_resolved_earlier
|
||||
# pend "to suppress the output of test failure logs in CI temporarily"
|
||||
return if RUBY_PLATFORM =~ /mswin|mingw|cygwin/
|
||||
|
||||
server = TCPServer.new("127.0.0.1", 0)
|
||||
@ -182,15 +181,14 @@ class TestSocket_TCPSocket < Test::Unit::TestCase
|
||||
fast_fallback: true,
|
||||
test_mode_settings: { delay: { ipv6: 1000 } }
|
||||
)
|
||||
|
||||
assert_true(socket.remote_address.ipv4?)
|
||||
server_thread.value.close
|
||||
server.close
|
||||
socket.close if socket && !socket.closed?
|
||||
ensure
|
||||
server_thread&.value&.close
|
||||
server&.close
|
||||
socket&.close
|
||||
end
|
||||
|
||||
def test_initialize_v6_hostname_resolved_in_resolution_delay
|
||||
# pend "to suppress the output of test failure logs in CI temporarily"
|
||||
return if RUBY_PLATFORM =~ /mswin|mingw|cygwin/
|
||||
|
||||
begin
|
||||
@ -212,21 +210,21 @@ class TestSocket_TCPSocket < Test::Unit::TestCase
|
||||
test_mode_settings: { delay: { ipv6: delay_time } }
|
||||
)
|
||||
assert_true(socket.remote_address.ipv6?)
|
||||
server_thread.value.close
|
||||
server.close
|
||||
socket.close if socket && !socket.closed?
|
||||
ensure
|
||||
server_thread&.value&.close
|
||||
server&.close
|
||||
socket&.close
|
||||
end
|
||||
|
||||
def test_initialize_v6_hostname_resolved_earlier_and_v6_server_is_not_listening
|
||||
# pend "to suppress the output of test failure logs in CI temporarily"
|
||||
return if RUBY_PLATFORM =~ /mswin|mingw|cygwin/
|
||||
|
||||
ipv4_address = "127.0.0.1"
|
||||
ipv4_server = Socket.new(Socket::AF_INET, :STREAM)
|
||||
ipv4_server.bind(Socket.pack_sockaddr_in(0, ipv4_address))
|
||||
port = ipv4_server.connect_address.ip_port
|
||||
server = Socket.new(Socket::AF_INET, :STREAM)
|
||||
server.bind(Socket.pack_sockaddr_in(0, ipv4_address))
|
||||
port = server.connect_address.ip_port
|
||||
|
||||
ipv4_server_thread = Thread.new { ipv4_server.listen(1); ipv4_server.accept }
|
||||
server_thread = Thread.new { server.listen(1); server.accept }
|
||||
socket = TCPSocket.new(
|
||||
"localhost",
|
||||
port,
|
||||
@ -234,40 +232,36 @@ class TestSocket_TCPSocket < Test::Unit::TestCase
|
||||
test_mode_settings: { delay: { ipv4: 10 } }
|
||||
)
|
||||
assert_equal(ipv4_address, socket.remote_address.ip_address)
|
||||
accepted, _ = ipv4_server_thread.value
|
||||
accepted.close
|
||||
ipv4_server.close
|
||||
socket.close if socket && !socket.closed?
|
||||
ensure
|
||||
accepted, _ = server_thread&.value
|
||||
accepted&.close
|
||||
server&.close
|
||||
socket&.close
|
||||
end
|
||||
|
||||
def test_initialize_v6_hostname_resolved_later_and_v6_server_is_not_listening
|
||||
# pend "to suppress the output of test failure logs in CI temporarily"
|
||||
return if RUBY_PLATFORM =~ /mswin|mingw|cygwin/
|
||||
|
||||
ipv4_server = Socket.new(Socket::AF_INET, :STREAM)
|
||||
ipv4_server.bind(Socket.pack_sockaddr_in(0, "127.0.0.1"))
|
||||
port = ipv4_server.connect_address.ip_port
|
||||
server = Socket.new(Socket::AF_INET, :STREAM)
|
||||
server.bind(Socket.pack_sockaddr_in(0, "127.0.0.1"))
|
||||
port = server.connect_address.ip_port
|
||||
|
||||
ipv4_server_thread = Thread.new { ipv4_server.listen(1); ipv4_server.accept }
|
||||
server_thread = Thread.new { server.listen(1); server.accept }
|
||||
socket = TCPSocket.new(
|
||||
"localhost",
|
||||
port,
|
||||
fast_fallback: true,
|
||||
test_mode_settings: { delay: { ipv6: 25 } }
|
||||
)
|
||||
|
||||
assert_equal(
|
||||
socket.remote_address.ipv4?,
|
||||
true
|
||||
)
|
||||
accepted, _ = ipv4_server_thread.value
|
||||
accepted.close
|
||||
ipv4_server.close
|
||||
socket.close if socket && !socket.closed?
|
||||
assert_true(socket.remote_address.ipv4?)
|
||||
ensure
|
||||
accepted, _ = server_thread&.value
|
||||
accepted&.close
|
||||
server&.close
|
||||
socket&.close
|
||||
end
|
||||
|
||||
def test_initialize_v6_hostname_resolution_failed_and_v4_hostname_resolution_is_success
|
||||
# pend "to suppress the output of test failure logs in CI temporarily"
|
||||
return if RUBY_PLATFORM =~ /mswin|mingw|cygwin/
|
||||
|
||||
server = TCPServer.new("127.0.0.1", 0)
|
||||
@ -280,15 +274,14 @@ class TestSocket_TCPSocket < Test::Unit::TestCase
|
||||
fast_fallback: true,
|
||||
test_mode_settings: { delay: { ipv4: 10 }, error: { ipv6: Socket::EAI_FAIL } }
|
||||
)
|
||||
|
||||
assert_true(socket.remote_address.ipv4?)
|
||||
server_thread.value.close
|
||||
server.close
|
||||
socket.close if socket && !socket.closed?
|
||||
ensure
|
||||
server_thread&.value&.close
|
||||
server&.close
|
||||
socket&.close
|
||||
end
|
||||
|
||||
def test_initialize_resolv_timeout_with_connection_failure
|
||||
# pend "to suppress the output of test failure logs in CI temporarily"
|
||||
return if RUBY_PLATFORM =~ /mswin|mingw|cygwin/
|
||||
|
||||
begin
|
||||
@ -312,7 +305,6 @@ class TestSocket_TCPSocket < Test::Unit::TestCase
|
||||
end
|
||||
|
||||
def test_initialize_with_hostname_resolution_failure_after_connection_failure
|
||||
# pend "to suppress the output of test failure logs in CI temporarily"
|
||||
return if RUBY_PLATFORM =~ /mswin|mingw|cygwin/
|
||||
|
||||
begin
|
||||
@ -335,7 +327,6 @@ class TestSocket_TCPSocket < Test::Unit::TestCase
|
||||
end
|
||||
|
||||
def test_initialize_with_connection_failure_after_hostname_resolution_failure
|
||||
# pend "to suppress the output of test failure logs in CI temporarily"
|
||||
return if RUBY_PLATFORM =~ /mswin|mingw|cygwin/
|
||||
|
||||
server = TCPServer.new("127.0.0.1", 0)
|
||||
@ -367,11 +358,9 @@ class TestSocket_TCPSocket < Test::Unit::TestCase
|
||||
socket = TCPSocket.new("::1", port)
|
||||
assert_true(socket.remote_address.ipv6?)
|
||||
ensure
|
||||
return if RUBY_PLATFORM =~ /mswin|mingw|cygwin/
|
||||
|
||||
server_thread.value.close
|
||||
server.close
|
||||
socket.close if socket && !socket.closed?
|
||||
server_thread&.value&.close
|
||||
server&.close
|
||||
socket&.close
|
||||
end
|
||||
|
||||
def test_initialize_v4_connected_socket_with_v4_address
|
||||
@ -384,11 +373,9 @@ class TestSocket_TCPSocket < Test::Unit::TestCase
|
||||
socket = TCPSocket.new("127.0.0.1", port)
|
||||
assert_true(socket.remote_address.ipv4?)
|
||||
ensure
|
||||
return if RUBY_PLATFORM =~ /mswin|mingw|cygwin/
|
||||
|
||||
server_thread.value.close
|
||||
server.close
|
||||
socket.close if socket && !socket.closed?
|
||||
server_thread&.value&.close
|
||||
server&.close
|
||||
socket&.close
|
||||
end
|
||||
|
||||
def test_initialize_fast_fallback_is_false
|
||||
@ -401,10 +388,8 @@ class TestSocket_TCPSocket < Test::Unit::TestCase
|
||||
socket = TCPSocket.new("127.0.0.1", port, fast_fallback: false)
|
||||
assert_true(socket.remote_address.ipv4?)
|
||||
ensure
|
||||
return if RUBY_PLATFORM =~ /mswin|mingw|cygwin/
|
||||
|
||||
server_thread.value.close
|
||||
server.close
|
||||
socket.close if socket && !socket.closed?
|
||||
server_thread&.value&.close
|
||||
server&.close
|
||||
socket&.close
|
||||
end
|
||||
end if defined?(TCPSocket)
|
||||
|
Loading…
x
Reference in New Issue
Block a user