2016-03-08 00:52:19 +00:00
|
|
|
# frozen_string_literal: true
|
2018-03-01 00:11:41 +00:00
|
|
|
|
2010-09-17 23:56:32 +00:00
|
|
|
require 'spec_helper'
|
2009-12-13 13:33:14 +00:00
|
|
|
|
2014-04-03 17:25:03 +00:00
|
|
|
RSpec.describe Capybara::Server do
|
2018-07-10 21:18:39 +00:00
|
|
|
it 'should spool up a rack server' do
|
2019-02-25 23:50:24 +00:00
|
|
|
app = proc { |_env| [200, {}, ['Hello Server!']] }
|
|
|
|
server = Capybara::Server.new(app).boot
|
2010-09-15 16:19:50 +00:00
|
|
|
|
2019-02-25 23:50:24 +00:00
|
|
|
res = Net::HTTP.start(server.host, server.port) { |http| http.get('/') }
|
2010-09-15 16:19:50 +00:00
|
|
|
|
2019-02-25 23:50:24 +00:00
|
|
|
expect(res.body).to include('Hello Server')
|
2009-12-13 13:33:14 +00:00
|
|
|
end
|
2010-03-12 18:14:10 +00:00
|
|
|
|
2018-07-10 21:18:39 +00:00
|
|
|
it 'should do nothing when no server given' do
|
2012-10-30 13:26:19 +00:00
|
|
|
expect do
|
2019-02-25 23:50:24 +00:00
|
|
|
Capybara::Server.new(nil).boot
|
2012-10-30 13:26:19 +00:00
|
|
|
end.not_to raise_error
|
2010-03-12 18:14:10 +00:00
|
|
|
end
|
2010-09-15 16:19:50 +00:00
|
|
|
|
2018-07-10 21:18:39 +00:00
|
|
|
it 'should bind to the specified host' do
|
2018-03-01 00:11:41 +00:00
|
|
|
# TODO: travis with jruby in container mode has an issue with this test
|
2018-07-10 21:18:39 +00:00
|
|
|
skip 'This platform has an issue with this test' if (ENV['TRAVIS'] && (RUBY_ENGINE == 'jruby')) || Gem.win_platform?
|
|
|
|
|
2013-09-11 21:26:37 +00:00
|
|
|
begin
|
2018-03-01 00:11:41 +00:00
|
|
|
app = proc { |_env| [200, {}, ['Hello Server!']] }
|
2013-09-11 21:26:37 +00:00
|
|
|
|
|
|
|
Capybara.server_host = '127.0.0.1'
|
|
|
|
server = Capybara::Server.new(app).boot
|
|
|
|
res = Net::HTTP.get(URI("http://127.0.0.1:#{server.port}"))
|
|
|
|
expect(res).to eq('Hello Server!')
|
|
|
|
|
|
|
|
Capybara.server_host = '0.0.0.0'
|
|
|
|
server = Capybara::Server.new(app).boot
|
|
|
|
res = Net::HTTP.get(URI("http://127.0.0.1:#{server.port}"))
|
|
|
|
expect(res).to eq('Hello Server!')
|
|
|
|
ensure
|
|
|
|
Capybara.server_host = nil
|
|
|
|
end
|
2018-07-10 21:18:39 +00:00
|
|
|
end
|
2011-10-05 19:09:37 +00:00
|
|
|
|
2018-07-10 21:18:39 +00:00
|
|
|
it 'should use specified port' do
|
2010-09-02 13:03:49 +00:00
|
|
|
Capybara.server_port = 22789
|
|
|
|
|
2019-02-25 23:50:24 +00:00
|
|
|
app = proc { |_env| [200, {}, ['Hello Server!']] }
|
|
|
|
server = Capybara::Server.new(app).boot
|
2010-09-28 20:37:43 +00:00
|
|
|
|
2019-02-25 23:50:24 +00:00
|
|
|
res = Net::HTTP.start(server.host, 22789) { |http| http.get('/') }
|
|
|
|
expect(res.body).to include('Hello Server')
|
2010-09-02 13:03:49 +00:00
|
|
|
|
|
|
|
Capybara.server_port = nil
|
|
|
|
end
|
2010-09-28 20:37:43 +00:00
|
|
|
|
2018-07-10 21:18:39 +00:00
|
|
|
it 'should use given port' do
|
2019-02-25 23:50:24 +00:00
|
|
|
app = proc { |_env| [200, {}, ['Hello Server!']] }
|
|
|
|
server = Capybara::Server.new(app, port: 22790).boot
|
2012-07-13 13:19:20 +00:00
|
|
|
|
2019-02-25 23:50:24 +00:00
|
|
|
res = Net::HTTP.start(server.host, 22790) { |http| http.get('/') }
|
|
|
|
expect(res.body).to include('Hello Server')
|
2012-07-13 13:19:20 +00:00
|
|
|
|
|
|
|
Capybara.server_port = nil
|
|
|
|
end
|
|
|
|
|
2018-07-10 21:18:39 +00:00
|
|
|
it 'should find an available port' do
|
2019-02-25 23:50:24 +00:00
|
|
|
responses = ['Hello Server!', 'Hello Second Server!']
|
|
|
|
apps = responses.map do |response|
|
|
|
|
proc { |_env| [200, {}, [response]] }
|
|
|
|
end
|
|
|
|
servers = apps.map { |app| Capybara::Server.new(app).boot }
|
2010-09-15 16:19:50 +00:00
|
|
|
|
2019-02-25 23:50:24 +00:00
|
|
|
servers.each_with_index do |server, idx|
|
|
|
|
result = Net::HTTP.start(server.host, server.port) { |http| http.get('/') }
|
|
|
|
expect(result.body).to include(responses[idx])
|
|
|
|
end
|
2009-12-13 13:33:14 +00:00
|
|
|
end
|
2010-09-15 16:19:50 +00:00
|
|
|
|
2018-07-10 21:18:39 +00:00
|
|
|
it 'should support SSL' do
|
2018-05-01 20:36:42 +00:00
|
|
|
begin
|
2018-07-10 21:18:39 +00:00
|
|
|
key = File.join(Dir.pwd, 'spec', 'fixtures', 'key.pem')
|
|
|
|
cert = File.join(Dir.pwd, 'spec', 'fixtures', 'certificate.pem')
|
2018-05-01 20:36:42 +00:00
|
|
|
Capybara.server = :puma, { Host: "ssl://#{Capybara.server_host}?key=#{key}&cert=#{cert}" }
|
|
|
|
app = proc { |_env| [200, {}, ['Hello SSL Server!']] }
|
|
|
|
server = Capybara::Server.new(app).boot
|
|
|
|
|
|
|
|
expect do
|
2019-05-13 23:49:22 +00:00
|
|
|
Net::HTTP.start(server.host, server.port, max_retries: 0) { |http| http.get('/__identify__') }
|
|
|
|
end.to(raise_error do |e|
|
|
|
|
expect(e.is_a?(EOFError) || e.is_a?(Net::ReadTimeout)).to be true
|
|
|
|
end)
|
2018-05-01 20:36:42 +00:00
|
|
|
|
|
|
|
res = Net::HTTP.start(server.host, server.port, use_ssl: true, verify_mode: OpenSSL::SSL::VERIFY_NONE) do |https|
|
|
|
|
https.get('/')
|
|
|
|
end
|
|
|
|
|
|
|
|
expect(res.body).to include('Hello SSL Server!')
|
|
|
|
ensure
|
|
|
|
Capybara.server = :default
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-07-10 21:18:39 +00:00
|
|
|
context 'When Capybara.reuse_server is true' do
|
2019-02-25 23:50:24 +00:00
|
|
|
let!(:old_reuse_server) { Capybara.reuse_server }
|
|
|
|
|
2016-01-18 22:01:12 +00:00
|
|
|
before do
|
|
|
|
Capybara.reuse_server = true
|
|
|
|
end
|
2009-12-13 13:33:14 +00:00
|
|
|
|
2016-01-18 22:01:12 +00:00
|
|
|
after do
|
2019-02-25 23:50:24 +00:00
|
|
|
Capybara.reuse_server = old_reuse_server
|
2016-01-18 22:01:12 +00:00
|
|
|
end
|
2010-09-15 16:19:50 +00:00
|
|
|
|
2018-07-10 21:18:39 +00:00
|
|
|
it 'should use the existing server if it already running' do
|
2019-02-25 23:50:24 +00:00
|
|
|
app = proc { |_env| [200, {}, ['Hello Server!']] }
|
2016-01-18 22:01:12 +00:00
|
|
|
|
2019-02-25 23:50:24 +00:00
|
|
|
servers = Array.new(2) { Capybara::Server.new(app).boot }
|
2016-01-18 22:01:12 +00:00
|
|
|
|
2019-02-25 23:50:24 +00:00
|
|
|
servers.each do |server|
|
|
|
|
res = Net::HTTP.start(server.host, server.port) { |http| http.get('/') }
|
|
|
|
expect(res.body).to include('Hello Server')
|
|
|
|
end
|
2016-01-18 22:01:12 +00:00
|
|
|
|
2019-02-25 23:50:24 +00:00
|
|
|
expect(servers[0].port).to eq(servers[1].port)
|
2016-01-18 22:01:12 +00:00
|
|
|
end
|
|
|
|
|
2018-07-10 21:18:39 +00:00
|
|
|
it 'detects and waits for all reused server sessions pending requests' do
|
2017-05-26 02:18:38 +00:00
|
|
|
done = 0
|
2016-01-18 22:01:12 +00:00
|
|
|
|
|
|
|
app = proc do |env|
|
|
|
|
request = Rack::Request.new(env)
|
|
|
|
sleep request.params['wait_time'].to_f
|
2017-05-26 02:18:38 +00:00
|
|
|
done += 1
|
2018-07-10 21:18:39 +00:00
|
|
|
[200, {}, ['Hello Server!']]
|
2016-01-18 22:01:12 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
server1 = Capybara::Server.new(app).boot
|
|
|
|
server2 = Capybara::Server.new(app).boot
|
|
|
|
|
2018-03-01 00:11:41 +00:00
|
|
|
expect do
|
2017-05-26 02:18:38 +00:00
|
|
|
start_request(server1, 1.0)
|
|
|
|
start_request(server2, 3.0)
|
2016-01-18 22:01:12 +00:00
|
|
|
server1.wait_for_pending_requests
|
2018-03-01 00:11:41 +00:00
|
|
|
end.to change { done }.from(0).to(2)
|
2016-07-25 18:34:15 +00:00
|
|
|
expect(server2.send(:pending_requests?)).to eq(false)
|
2016-01-18 22:01:12 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-07-10 21:18:39 +00:00
|
|
|
context 'When Capybara.reuse_server is false' do
|
2016-01-18 22:01:12 +00:00
|
|
|
before do
|
|
|
|
@old_reuse_server = Capybara.reuse_server
|
|
|
|
Capybara.reuse_server = false
|
|
|
|
end
|
|
|
|
|
|
|
|
after do
|
2019-02-25 23:50:24 +00:00
|
|
|
Capybara.reuse_server = @old_reuse_server # rubocop:disable RSpec/InstanceVariable
|
2016-01-18 22:01:12 +00:00
|
|
|
end
|
|
|
|
|
2018-07-10 21:18:39 +00:00
|
|
|
it 'should not reuse an already running server' do
|
2019-02-25 23:50:24 +00:00
|
|
|
app = proc { |_env| [200, {}, ['Hello Server!']] }
|
2016-01-18 22:01:12 +00:00
|
|
|
|
2019-02-25 23:50:24 +00:00
|
|
|
servers = Array.new(2) { Capybara::Server.new(app).boot }
|
2016-01-18 22:01:12 +00:00
|
|
|
|
2019-02-25 23:50:24 +00:00
|
|
|
servers.each do |server|
|
|
|
|
res = Net::HTTP.start(server.host, server.port) { |http| http.get('/') }
|
|
|
|
expect(res.body).to include('Hello Server')
|
|
|
|
end
|
2016-01-18 22:01:12 +00:00
|
|
|
|
2019-02-25 23:50:24 +00:00
|
|
|
expect(servers[0].port).not_to eq(servers[1].port)
|
2016-01-18 22:01:12 +00:00
|
|
|
end
|
|
|
|
|
2018-07-10 21:18:39 +00:00
|
|
|
it 'detects and waits for only one sessions pending requests' do
|
2017-05-26 02:18:38 +00:00
|
|
|
done = 0
|
2016-01-18 22:01:12 +00:00
|
|
|
|
|
|
|
app = proc do |env|
|
|
|
|
request = Rack::Request.new(env)
|
|
|
|
sleep request.params['wait_time'].to_f
|
2017-05-26 02:18:38 +00:00
|
|
|
done += 1
|
2018-07-10 21:18:39 +00:00
|
|
|
[200, {}, ['Hello Server!']]
|
2016-01-18 22:01:12 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
server1 = Capybara::Server.new(app).boot
|
|
|
|
server2 = Capybara::Server.new(app).boot
|
|
|
|
|
2018-03-01 00:11:41 +00:00
|
|
|
expect do
|
2017-05-26 02:18:38 +00:00
|
|
|
start_request(server1, 1.0)
|
|
|
|
start_request(server2, 3.0)
|
2016-01-18 22:01:12 +00:00
|
|
|
server1.wait_for_pending_requests
|
2018-03-01 00:11:41 +00:00
|
|
|
end.to change { done }.from(0).to(1)
|
2016-07-25 18:34:15 +00:00
|
|
|
expect(server2.send(:pending_requests?)).to eq(true)
|
2018-03-01 00:11:41 +00:00
|
|
|
expect do
|
2017-05-26 02:18:38 +00:00
|
|
|
server2.wait_for_pending_requests
|
2018-03-01 00:11:41 +00:00
|
|
|
end.to change { done }.from(1).to(2)
|
2016-01-18 22:01:12 +00:00
|
|
|
end
|
2009-12-13 13:33:14 +00:00
|
|
|
end
|
2012-03-06 22:42:47 +00:00
|
|
|
|
2018-07-10 21:18:39 +00:00
|
|
|
it 'should raise server errors when the server errors before the timeout' do
|
2012-03-06 22:42:47 +00:00
|
|
|
begin
|
2016-08-17 20:51:32 +00:00
|
|
|
Capybara.register_server :kaboom do
|
2012-03-06 22:42:47 +00:00
|
|
|
sleep 0.1
|
|
|
|
raise 'kaboom'
|
|
|
|
end
|
2016-08-17 20:51:32 +00:00
|
|
|
Capybara.server = :kaboom
|
2012-03-06 22:42:47 +00:00
|
|
|
|
2013-11-14 17:43:36 +00:00
|
|
|
expect do
|
2018-03-01 00:11:41 +00:00
|
|
|
Capybara::Server.new(proc { |e| }).boot
|
2013-11-14 17:43:36 +00:00
|
|
|
end.to raise_error(RuntimeError, 'kaboom')
|
2012-03-06 22:42:47 +00:00
|
|
|
ensure
|
2016-08-17 20:51:32 +00:00
|
|
|
Capybara.server = :default
|
2012-03-06 22:42:47 +00:00
|
|
|
end
|
|
|
|
end
|
2013-03-16 18:59:02 +00:00
|
|
|
|
2018-07-10 21:18:39 +00:00
|
|
|
it 'is not #responsive? when Net::HTTP raises a SystemCallError' do
|
2018-03-01 00:11:41 +00:00
|
|
|
app = -> { [200, {}, ['Hello, world']] }
|
2013-03-17 23:35:48 +00:00
|
|
|
server = Capybara::Server.new(app)
|
2018-04-27 18:01:47 +00:00
|
|
|
allow(Net::HTTP).to receive(:start).and_raise(SystemCallError.allocate)
|
2013-03-17 23:35:48 +00:00
|
|
|
expect(server.responsive?).to eq false
|
2013-03-16 18:59:02 +00:00
|
|
|
end
|
2015-07-06 23:19:47 +00:00
|
|
|
|
2018-05-01 20:36:42 +00:00
|
|
|
[EOFError, Net::ReadTimeout].each do |err|
|
|
|
|
it "should attempt an HTTPS connection if HTTP connection returns #{err}" do
|
|
|
|
app = -> { [200, {}, ['Hello, world']] }
|
|
|
|
ordered_errors = [Errno::ECONNREFUSED, err]
|
|
|
|
allow(Net::HTTP).to receive(:start).with(anything, anything, hash_excluding(:use_ssl)) do
|
|
|
|
raise ordered_errors.shift
|
|
|
|
end
|
|
|
|
response = Net::HTTPSuccess.allocate
|
|
|
|
allow(response).to receive(:body).and_return app.object_id.to_s
|
|
|
|
allow(Net::HTTP).to receive(:start).with(anything, anything, hash_including(use_ssl: true)).and_return(response).once
|
|
|
|
Capybara::Server.new(app).boot
|
|
|
|
expect(Net::HTTP).to have_received(:start).exactly(3).times
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-01-18 22:01:12 +00:00
|
|
|
def start_request(server, wait_time)
|
2015-07-06 23:19:47 +00:00
|
|
|
# Start request, but don't wait for it to finish
|
|
|
|
socket = TCPSocket.new(server.host, server.port)
|
2018-03-01 00:11:41 +00:00
|
|
|
socket.write "GET /?wait_time=#{wait_time} HTTP/1.0\r\n\r\n"
|
2017-05-26 02:18:38 +00:00
|
|
|
sleep 0.1
|
2015-07-06 23:19:47 +00:00
|
|
|
socket.close
|
|
|
|
sleep 0.1
|
|
|
|
end
|
2009-12-13 13:33:14 +00:00
|
|
|
end
|