This commit is contained in:
Benoit Daloze 2019-05-30 22:11:24 +02:00
Родитель e935a3227d
Коммит a4161b7649
3 изменённых файлов: 61 добавлений и 32 удалений

Просмотреть файл

@ -132,4 +132,33 @@ module SocketSpecs
@logger.puts message if @logger
end
end
# We need to find a free port for Socket.tcp_server_loop and Socket.udp_server_loop,
# and the only reliable way to do that is to pass 0 as the port, but then we need to
# find out which one was chosen and the API doesn't let us find what it is. So we
# intercept one of the public API methods called by these methods.
class ServerLoopPortFinder < Socket
def self.tcp_server_sockets(*args)
super(*args) { |sockets|
@port = sockets.first.local_address.ip_port
yield(sockets)
}
end
def self.udp_server_sockets(*args, &block)
super(*args) { |sockets|
@port = sockets.first.local_address.ip_port
yield(sockets)
}
end
def self.cleanup
@port = nil
end
def self.port
sleep 0.001 until @port
@port
end
end
end

Просмотреть файл

@ -11,7 +11,7 @@ describe 'Socket.tcp_server_loop' do
describe 'when a connection is available' do
before do
@client = Socket.new(:INET, :STREAM)
@port = 9998
SocketSpecs::ServerLoopPortFinder.cleanup
end
after do
@ -19,38 +19,36 @@ describe 'Socket.tcp_server_loop' do
@client.close
end
# Not working since ruby/ruby a66bc2c01194a9c017c874a30db5b3b6bd95e966
# https://travis-ci.org/ruby/ruby/jobs/538438184
platform_is_not :darwin do
it 'yields a Socket and an Addrinfo' do
@sock, addr = nil
it 'yields a Socket and an Addrinfo' do
@sock, addr = nil
thread = Thread.new do
Socket.tcp_server_loop('127.0.0.1', @port) do |socket, addrinfo|
@sock = socket
addr = addrinfo
thread = Thread.new do
SocketSpecs::ServerLoopPortFinder.tcp_server_loop('127.0.0.1', 0) do |socket, addrinfo|
@sock = socket
addr = addrinfo
break
end
break
end
SocketSpecs.loop_with_timeout do
begin
@client.connect(Socket.sockaddr_in(@port, '127.0.0.1'))
rescue SystemCallError
sleep 0.01
:retry
end
end
# At this point the connection has been set up but the thread may not yet
# have returned, thus we'll need to wait a little longer for it to
# complete.
thread.join(2)
@sock.should be_an_instance_of(Socket)
addr.should be_an_instance_of(Addrinfo)
end
port = SocketSpecs::ServerLoopPortFinder.port
SocketSpecs.loop_with_timeout do
begin
@client.connect(Socket.sockaddr_in(port, '127.0.0.1'))
rescue SystemCallError
sleep 0.01
:retry
end
end
# At this point the connection has been set up but the thread may not yet
# have returned, thus we'll need to wait a little longer for it to
# complete.
thread.join(2)
@sock.should be_an_instance_of(Socket)
addr.should be_an_instance_of(Addrinfo)
end
end
end

Просмотреть файл

@ -11,7 +11,7 @@ describe 'Socket.udp_server_loop' do
describe 'when a connection is available' do
before do
@client = Socket.new(:INET, :DGRAM)
@port = 9997
SocketSpecs::ServerLoopPortFinder.cleanup
end
after do
@ -22,7 +22,7 @@ describe 'Socket.udp_server_loop' do
msg, src = nil
Thread.new do
Socket.udp_server_loop('127.0.0.1', @port) do |message, source|
SocketSpecs::ServerLoopPortFinder.udp_server_loop('127.0.0.1', 0) do |message, source|
msg = message
src = source
@ -30,9 +30,11 @@ describe 'Socket.udp_server_loop' do
end
end
port = SocketSpecs::ServerLoopPortFinder.port
# Because this will return even if the server is up and running (it's UDP
# after all) we'll have to write and wait until "msg" is set.
@client.connect(Socket.sockaddr_in(@port, '127.0.0.1'))
@client.connect(Socket.sockaddr_in(port, '127.0.0.1'))
SocketSpecs.loop_with_timeout do
begin