Simplify fix and test

This commit is contained in:
Thomas Walpole 2019-09-08 09:09:06 -07:00
parent bb75591306
commit 4cd9d8790b
2 changed files with 31 additions and 27 deletions

View File

@ -105,23 +105,20 @@ module Capybara
end
def find_available_port(host)
port = 0
while port.zero?
begin
server = TCPServer.new(host, port)
port = server.addr[1]
ensure
server&.close
end
begin
server = TCPServer.new(host, port)
rescue Errno::EADDRINUSE
port = 0
ensure
server&.close
end
end
server = TCPServer.new(host, 0)
port = server.addr[1]
server.close
# Workaround issue where some platforms (mac, ???) when passed a host
# of '0.0.0.0' will return a port that is only available on one of the
# ip addresses that resolves to, but the next binding to that port requires
# that port to be available on all ips
server = TCPServer.new(host, port)
port
rescue Errno::EADDRINUSE
retry
ensure
server&.close
end
end
end

View File

@ -74,19 +74,26 @@ RSpec.describe Capybara::Server do
end
end
def use_port(host, port)
server = TCPServer.new(host, port)
ensure
server&.close
end
it 'should handle that getting available ports fails randomly' do
expect do
100000.times do
port = described_class.new(Object.new).send(:find_available_port, '0.0.0.0')
use_port('0.0.0.0', port)
begin
# Use a port to force a EADDRINUSE error to be generated
server = TCPServer.new('0.0.0.0', 0)
server_port = server.addr[1]
d_server = instance_double('TCPServer', addr: [nil, server_port, nil, nil], close: nil)
call_count = 0
allow(TCPServer).to receive(:new).and_wrap_original do |m, *args|
begin
call_count.zero? ? d_server : m.call(*args)
ensure
call_count += 1
end
end
end.not_to raise_error
port = described_class.new(Object.new, host: '0.0.0.0').port
expect(port).not_to eq(server_port)
ensure
server&.close
end
end
it 'should return its #base_url' do