Skip to content

Commit e64a808

Browse files
committed
[rb] make flaky unit tests hermetic
1 parent 702c97b commit e64a808

3 files changed

Lines changed: 25 additions & 15 deletions

File tree

rb/spec/unit/selenium/server_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ module Selenium
108108
'bar')
109109
.and_return(mock_process)
110110

111-
server = described_class.new('selenium_server_deploy.jar', background: true)
111+
server = described_class.new('selenium_server_deploy.jar', port: port, background: true)
112112
allow(server).to receive_messages(socket: mock_poller, status_ok?: true)
113113

114114
server << %w[foo bar]
@@ -200,7 +200,7 @@ module Selenium
200200
poller = instance_double(WebDriver::SocketPoller)
201201
allow(poller).to receive(:connected?).and_return(false)
202202

203-
server = described_class.new('selenium_server_deploy.jar', background: true)
203+
server = described_class.new('selenium_server_deploy.jar', port: port, background: true)
204204
allow(server).to receive(:socket).and_return(poller)
205205

206206
expect { server.start }.to raise_error(Selenium::Server::Error)

rb/spec/unit/selenium/webdriver/socket_poller_spec.rb

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,26 @@ module Selenium
2323
module WebDriver
2424
describe SocketPoller do
2525
before(:context) do
26-
@server_thread = Thread.new do
27-
server = TCPServer.open(Platform.localhost, 9250)
28-
Thread.current.thread_variable_set(:server, server)
29-
loop { server.accept.close }
26+
# Open the listening socket synchronously so the server object is captured
27+
# deterministically (no race with the accept thread) and bind errors surface here.
28+
@listening_server = TCPServer.new(Platform.localhost, 0)
29+
@listening_port = @listening_server.addr[1]
30+
@accept_thread = Thread.new do
31+
loop { @listening_server.accept.close }
32+
rescue IOError, Errno::EBADF, Errno::ECONNABORTED
33+
# listening socket closed during teardown
3034
end
31-
@server_thread.report_on_exception = false
35+
@accept_thread.report_on_exception = false
36+
37+
# Reserve an ephemeral port, then release it so nothing is listening on it.
38+
closed_server = TCPServer.new(Platform.localhost, 0)
39+
@closed_port = closed_server.addr[1]
40+
closed_server.close
3241
end
3342

3443
after(:context) do
35-
@server_thread.thread_variable_get(:server).close
44+
@listening_server&.close
45+
@accept_thread&.kill
3646
end
3747

3848
def poller(port)
@@ -41,7 +51,7 @@ def poller(port)
4151

4252
describe '#connected?' do
4353
it 'returns true when the socket is listening' do
44-
expect(poller(9250)).to be_connected
54+
expect(poller(@listening_port)).to be_connected
4555
end
4656

4757
it 'returns false if the socket is not listening after the given timeout' do
@@ -50,13 +60,13 @@ def poller(port)
5060
stop = Time.parse('2010-01-01 00:00:06')
5161

5262
allow(Process).to receive(:clock_gettime).and_return(start, wait, stop)
53-
expect(poller(9251)).not_to be_connected
63+
expect(poller(@closed_port)).not_to be_connected
5464
end
5565
end
5666

5767
describe '#closed?' do
5868
it 'returns true when the socket is closed' do
59-
expect(poller(9251)).to be_closed
69+
expect(poller(@closed_port)).to be_closed
6070
end
6171

6272
it 'returns false if the socket is still listening after the given timeout' do
@@ -65,7 +75,7 @@ def poller(port)
6575
stop = Time.parse('2010-01-01 00:00:06').to_f
6676

6777
allow(Process).to receive(:clock_gettime).and_return(start, wait, stop)
68-
expect(poller(9250)).not_to be_closed
78+
expect(poller(@listening_port)).not_to be_closed
6979
end
7080
end
7181
end

rb/spec/unit/selenium/webdriver/zipper_spec.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ module WebDriver
2424
describe Zipper do
2525
let(:base_file_name) { 'file.txt' }
2626
let(:file_content) { 'content' }
27-
let(:zip_file) { File.join(Dir.tmpdir, 'test.zip') }
27+
let(:tmp_dir) { Dir.mktmpdir('webdriver-spec-zip') }
28+
let(:zip_file) { File.join(tmp_dir, 'test.zip') }
2829
let(:dir_to_zip) { Dir.mktmpdir('webdriver-spec-zipper') }
2930

3031
def create_file
@@ -34,7 +35,7 @@ def create_file
3435
filename
3536
end
3637

37-
after { FileUtils.rm_rf zip_file }
38+
after { FileUtils.rm_rf tmp_dir }
3839

3940
describe '#zip' do
4041
it 'a file' do
@@ -59,7 +60,6 @@ def create_file
5960
filename = create_file
6061
File.symlink(filename, File.join(dir_to_zip, 'link'))
6162

62-
zip_file = File.join(Dir.tmpdir, 'test.zip')
6363
File.open(zip_file, 'wb') do |io|
6464
io << Base64.decode64(described_class.zip(dir_to_zip))
6565
end

0 commit comments

Comments
 (0)