Skip to content

Commit c47f7e2

Browse files
ko1claude
authored andcommitted
Fix flaky TCPSocket#local_address implicit-hostname spec
The "using an implicit hostname" example connects with TCPSocket.new(nil, port) to a server bound to the IPv4 loopback, then asserts that local_address.ip_address equals @host ("127.0.0.1"). This is flaky. A nil hostname resolves to the loopback of both families, and Happy Eyeballs prefers IPv6, so the connection is not guaranteed to reach the IPv4 test server. IPv4 and IPv6 can share the same ephemeral port number (v6only), so under parallel runs (-j20) an unrelated listener on ::1:<same port> can be reached instead. local_address then comes back as "::1" and the spec fails. The invariant the example actually wants to check is that local_address reflects the connection's family, which always matches the peer. Compare against remote_address.ip_address instead of @host: deterministic in a clean environment and robust to the cross-family ephemeral-port collision. Verified: the spec passes normally, and with a forced ::1 listener on the same port the old `== @host` assertion fails while `== remote` holds. (Imported from ruby/spec; should be upstreamed there.) Error: TCPSocket#local_address using IPv4 using an implicit hostname the returned Addrinfo uses the correct IP address FAILED Expected "::1" == "127.0.0.1" to be truthy but was false spec/ruby/library/socket/tcpsocket/local_address_spec.rb:68 CI: https://ci.rvm.jp/results/trunk@ruby-sp3/6380323 Log: https://ci.rvm.jp/logfiles/brlog.trunk.20260616-071309 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent bf5378a commit c47f7e2

1 file changed

Lines changed: 7 additions & 1 deletion

File tree

‎library/socket/tcpsocket/local_address_spec.rb‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,13 @@
6565

6666
describe 'the returned Addrinfo' do
6767
it 'uses the correct IP address' do
68-
@sock.local_address.ip_address.should == @host
68+
# An implicit (nil) hostname resolves to the loopback of either family
69+
# and Happy Eyeballs prefers IPv6, so the connection is not guaranteed
70+
# to land on @host: under parallel runs an unrelated listener on
71+
# ::1:<same ephemeral port> can be reached instead, making @host a
72+
# flaky expectation (local_address would be ::1). The local end always
73+
# matches the family actually connected, so compare against the peer.
74+
@sock.local_address.ip_address.should == @sock.remote_address.ip_address
6975
end
7076
end
7177
end

0 commit comments

Comments
 (0)