Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test cleanup and parallelization #1846

Merged
merged 6 commits into from Jul 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/puma.rb
@@ -1,3 +1,5 @@
# frozen_string_literal: true

# Standard libraries
require 'socket'
require 'tempfile'
Expand Down
2 changes: 2 additions & 0 deletions lib/puma/accept_nonblock.rb
@@ -1,3 +1,5 @@
# frozen_string_literal: true

require 'openssl'

module OpenSSL
Expand Down
2 changes: 2 additions & 0 deletions lib/puma/app/status.rb
@@ -1,3 +1,5 @@
# frozen_string_literal: true

require 'json'

module Puma
Expand Down
2 changes: 2 additions & 0 deletions lib/puma/plugin/tmp_restart.rb
@@ -1,3 +1,5 @@
# frozen_string_literal: true

require 'puma/plugin'

Puma::Plugin.create do
Expand Down
2 changes: 2 additions & 0 deletions lib/puma/rack/builder.rb
@@ -1,3 +1,5 @@
# frozen_string_literal: true

module Puma
end

Expand Down
2 changes: 2 additions & 0 deletions lib/puma/rack/urlmap.rb
@@ -1,3 +1,5 @@
# frozen_string_literal: true

module Puma::Rack
# Rack::URLMap takes a hash mapping urls or paths to apps, and
# dispatches accordingly. Support for HTTP/1.1 host names exists if
Expand Down
2 changes: 2 additions & 0 deletions lib/puma/rack_default.rb
@@ -1,3 +1,5 @@
# frozen_string_literal: true

require 'rack/handler/puma'

module Rack::Handler
Expand Down
2 changes: 2 additions & 0 deletions lib/rack/handler/puma.rb
@@ -1,3 +1,5 @@
# frozen_string_literal: true

require 'rack/handler'

module Rack
Expand Down
2 changes: 2 additions & 0 deletions test/helper.rb
Expand Up @@ -5,6 +5,8 @@
begin
require 'stopgap_13632'
rescue LoadError
puts "For test stability, you must install the stopgap_13632 gem."
exit(1)
end
end

Expand Down
4 changes: 4 additions & 0 deletions test/test_app_status.rb
@@ -1,9 +1,13 @@
# frozen_string_literal: true

require_relative "helper"

require "puma/app/status"
require "rack"

class TestAppStatus < Minitest::Test
parallelize_me!

class FakeServer
def initialize
@status = :running
Expand Down
97 changes: 43 additions & 54 deletions test/test_binder.rb
@@ -1,96 +1,85 @@
# frozen_string_literal: true

require_relative "helper"

require "puma/binder"
require "puma/puma_http11"

class TestBinder < Minitest::Test
class TestBinderBase < Minitest::Test
def setup
@events = Puma::Events.null
@binder = Puma::Binder.new(@events)
@key = File.expand_path "../../examples/puma/puma_keypair.pem", __FILE__
@cert = File.expand_path "../../examples/puma/cert_puma.pem", __FILE__
end

def test_localhost_addresses_dont_alter_listeners_for_tcp_addresses
skip_on :jruby
private

def ssl_context_for_binder(binder)
binder.instance_variable_get(:@ios)[0].instance_variable_get(:@ctx)
end
end

class TestBinder < TestBinderBase
def test_localhost_addresses_dont_alter_listeners_for_tcp_addresses
@binder.parse(["tcp://localhost:10001"], @events)

assert_equal [], @binder.listeners
end
end

def test_localhost_addresses_dont_alter_listeners_for_ssl_addresses
skip_on :jruby
class TestBinderJRuby < TestBinderBase
def setup
super
skip_unless :jruby
end

key = File.expand_path "../../examples/puma/puma_keypair.pem", __FILE__
cert = File.expand_path "../../examples/puma/cert_puma.pem", __FILE__
def test_binder_parses_jruby_ssl_options
keystore = File.expand_path "../../examples/puma/keystore.jks", __FILE__
ssl_cipher_list = "TLS_DHE_RSA_WITH_DES_CBC_SHA,TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA"

@binder.parse(["ssl://localhost:10002?key=#{key}&cert=#{cert}"], @events)
@binder.parse(["ssl://0.0.0.0:8080?keystore=#{keystore}&keystore-pass=&ssl_cipher_list=#{ssl_cipher_list}"], @events)

assert_equal [], @binder.listeners
assert_equal keystore, ssl_context_for_binder(@binder).keystore
assert_equal ssl_cipher_list, ssl_context_for_binder(@binder).ssl_cipher_list
end
end

def test_binder_parses_ssl_cipher_filter
class TestBinderMRI < TestBinderBase
def setup
super
skip_on :jruby
end

key = File.expand_path "../../examples/puma/puma_keypair.pem", __FILE__
cert = File.expand_path "../../examples/puma/cert_puma.pem", __FILE__
ssl_cipher_filter = "AES@STRENGTH"

@binder.parse(["ssl://0.0.0.0?key=#{key}&cert=#{cert}&ssl_cipher_filter=#{ssl_cipher_filter}"], @events)
def test_localhost_addresses_dont_alter_listeners_for_ssl_addresses
@binder.parse(["ssl://localhost:10002?key=#{@key}&cert=#{@cert}"], @events)

ssl = @binder.instance_variable_get(:@ios)[0]
ctx = ssl.instance_variable_get(:@ctx)
assert_equal(ssl_cipher_filter, ctx.ssl_cipher_filter)
assert_equal [], @binder.listeners
end

def test_binder_parses_jruby_ssl_options
skip_unless :jruby
def test_binder_parses_ssl_cipher_filter
ssl_cipher_filter = "AES@STRENGTH"

keystore = File.expand_path "../../examples/puma/keystore.jks", __FILE__
ssl_cipher_list = "TLS_DHE_RSA_WITH_DES_CBC_SHA,TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA"
@binder.parse(["ssl://0.0.0.0:8080?keystore=#{keystore}&keystore-pass=&ssl_cipher_list=#{ssl_cipher_list}"], @events)
@binder.parse(["ssl://0.0.0.0?key=#{@key}&cert=#{@cert}&ssl_cipher_filter=#{ssl_cipher_filter}"], @events)

ssl= @binder.instance_variable_get(:@ios)[0]
ctx = ssl.instance_variable_get(:@ctx)
assert_equal(keystore, ctx.keystore)
assert_equal(ssl_cipher_list, ctx.ssl_cipher_list)
assert_equal ssl_cipher_filter, ssl_context_for_binder(@binder).ssl_cipher_filter
end

def test_binder_parses_tlsv1_disabled
skip_on :jruby

key = File.expand_path "../../examples/puma/puma_keypair.pem", __FILE__
cert = File.expand_path "../../examples/puma/cert_puma.pem", __FILE__
@binder.parse(["ssl://0.0.0.0?key=#{@key}&cert=#{@cert}&no_tlsv1=true"], @events)

@binder.parse(["ssl://0.0.0.0?key=#{key}&cert=#{cert}&no_tlsv1=true"], @events)

ssl = @binder.instance_variable_get(:@ios).first
ctx = ssl.instance_variable_get(:@ctx)
assert_equal(true, ctx.no_tlsv1)
assert ssl_context_for_binder(@binder).no_tlsv1
end

def test_binder_parses_tlsv1_enabled
skip_on :jruby
@binder.parse(["ssl://0.0.0.0?key=#{@key}&cert=#{@cert}&no_tlsv1=false"], @events)

key = File.expand_path "../../examples/puma/puma_keypair.pem", __FILE__
cert = File.expand_path "../../examples/puma/cert_puma.pem", __FILE__

@binder.parse(["ssl://0.0.0.0?key=#{key}&cert=#{cert}&no_tlsv1=false"], @events)

ssl = @binder.instance_variable_get(:@ios).first
ctx = ssl.instance_variable_get(:@ctx)
refute(ctx.no_tlsv1)
refute ssl_context_for_binder(@binder).no_tlsv1
end

def test_binder_parses_tlsv1_unspecified_defaults_to_enabled
skip_on :jruby

key = File.expand_path "../../examples/puma/puma_keypair.pem", __FILE__
cert = File.expand_path "../../examples/puma/cert_puma.pem", __FILE__

@binder.parse(["ssl://0.0.0.0?key=#{key}&cert=#{cert}"], @events)
@binder.parse(["ssl://0.0.0.0?key=#{@key}&cert=#{@cert}"], @events)

ssl = @binder.instance_variable_get(:@ios).first
ctx = ssl.instance_variable_get(:@ctx)
refute(ctx.no_tlsv1)
refute ssl_context_for_binder(@binder).no_tlsv1
end
end
34 changes: 20 additions & 14 deletions test/test_integration.rb
Expand Up @@ -6,6 +6,9 @@

# These don't run on travis because they're too fragile

# TODO: Remove over-utilization of @instance variables
# TODO: remove stdout logging, get everything out of my rainbow dots

class TestIntegration < Minitest::Test

def setup
Expand Down Expand Up @@ -41,22 +44,25 @@ def teardown
end
end

def server(argv)
def server_cmd(argv)
@tcp_port = next_port
base = "#{Gem.ruby} -Ilib bin/puma"
base.prepend("bundle exec ") if defined?(Bundler)
cmd = "#{base} -b tcp://127.0.0.1:#{@tcp_port} #{argv}"
@server = IO.popen(cmd, "r")
base = "bundle exec #{base}" if defined?(Bundler)
"#{base} -b tcp://127.0.0.1:#{@tcp_port} #{argv}"
end

wait_for_server_to_boot
def server(argv)
@server = IO.popen(server_cmd(argv), "r")

wait_for_server_to_boot(@server)

@server
end

def start_forked_server(argv)
@tcp_port = next_port
servercmd = server_cmd(argv)
pid = fork do
exec "#{Gem.ruby} -I lib/ bin/puma -b tcp://127.0.0.1:#{@tcp_port} #{argv}"
exec servercmd
end

sleep 5
Expand All @@ -71,9 +77,9 @@ def stop_forked_server(pid)

def restart_server_and_listen(argv)
server(argv)
s = connect
initial_reply = read_body(s)
restart_server(s)
connection = connect
initial_reply = read_body(connection)
restart_server(@server, connection)
[initial_reply, read_body(connect)]
end

Expand All @@ -86,12 +92,12 @@ def wait_booted
end

# reuses an existing connection to make sure that works
def restart_server(connection)
def restart_server(server, connection)
signal :USR2

connection.write "GET / HTTP/1.1\r\n\r\n" # trigger it to start by sending a new request

wait_for_server_to_boot
wait_for_server_to_boot(server)
end

def connect
Expand All @@ -101,8 +107,8 @@ def connect
s
end

def wait_for_server_to_boot
true while @server.gets !~ /Ctrl-C/ # wait for server to say it booted
def wait_for_server_to_boot(server)
true while server.gets !~ /Ctrl-C/ # wait for server to say it booted
end

def read_body(connection)
Expand Down