Skip to content

Commit f458a03

Browse files
author
starbelly
committed
Add Unicorn, Puma, nad Exec plugins and tests for Excon::Test::Server
- Added Unicorn plugin for Excon::Test::Server - Added Puma plugin fo Excon::Test::Server - Added Exec plugin for Excon::Test::Server (i.e., for sinatra, etc.) - Added initial tests for Unicorn, Puma, Exec plugins - Renamed Rackup|rackup to Webrick|webrick - Load Unicorn, Puma, and Exec plugins from Excon::Test::Server by default - Added support for URIs in order to better support ipv6 - Added conditional ops to delete a unix socket if one still exists post-shutdown - move check_implementation under private to make ruby < 2.0.0 happy - Add nested_const_get to stay compat with ruby < 1.9 - Specify webrick in with_rackup since puma is in the mix now - Changed default rspec format to doc instead of progress - used shared examples in excon test server spec - define get_abs_path to dry up path helpers - let rackup_path helper call get_abs_path - define unicorn_path and puma_path to support the web server shared example, it calls rackup_path - rename server_path to exec_path and call get_abs_path - Skip any tests when unicorn is the server and platform is jruby - Add "bundle exec rake spec" to travis.yml - Modify task for rspec to take a format argument, defaults to doc - use progress format for rspec on travis for less log - Added puma to Gemfile - Moved unicorn to groups test and devel
1 parent a1a4108 commit f458a03

14 files changed

+208
-49
lines changed

.rspec

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
--color
22
--require spec_helper
3+
--format d

.travis.yml

+4-1
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,8 @@ rvm:
1717
- jruby
1818
- rbx-3.2
1919
- ree
20-
script: "bundle exec shindont"
20+
script:
21+
- "bundle exec shindont"
22+
- "bundle exec rake spec[progress]"
23+
2124
sudo: false

Gemfile

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ source "http://rubygems.org"
33
gemspec
44

55
gem 'jruby-openssl', :platform => :jruby
6-
gem 'unicorn', :platforms => [:mri, :rbx]
6+
gem 'puma', :groups => [:development, :test]
7+
gem 'unicorn', :platforms => [:mri, :rbx], :groups => [:development, :test]
78
gem 'rubysl', '~> 2.0', :platform => :rbx
89
gem 'rack', '~> 1.6'
910

Gemfile.lock

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ GEM
2828
minitest (4.7.5)
2929
multi_json (1.3.6)
3030
open4 (1.3.0)
31+
puma (3.6.0)
3132
rack (1.6.0)
3233
rack-protection (1.2.0)
3334
rack
@@ -286,6 +287,7 @@ DEPENDENCIES
286287
jruby-openssl
287288
json (>= 1.8.2)
288289
open4
290+
puma
289291
rack (~> 1.6)
290292
rake
291293
rdoc

Rakefile

+3-2
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,9 @@ end
4646
require 'shindo/rake'
4747
require "rspec/core/rake_task"
4848

49-
RSpec::Core::RakeTask.new do |t|
50-
t.rspec_opts = ["-c", "-f progress", "-r ./spec/spec_helper.rb"]
49+
RSpec::Core::RakeTask.new(:spec, :format) do |t, args|
50+
format = args[:format] || 'doc'
51+
t.rspec_opts = ["-c", "-f #{format}", "-r ./spec/spec_helper.rb"]
5152
t.pattern = 'spec/**/*_spec.rb'
5253
end
5354

lib/excon/test/plugin/server/exec.rb

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
module Excon
2+
module Test
3+
module Plugin
4+
module Server
5+
module Exec
6+
def start(app_str = app)
7+
line = ''
8+
open_process(app)
9+
until line =~ /\Aready\Z/
10+
line = error.gets
11+
fatal_time = elapsed_time > timeout
12+
if fatal_time
13+
msg = "executable #{app} has taken too long to start"
14+
raise msg
15+
end
16+
end
17+
true
18+
end
19+
end
20+
end
21+
end
22+
end
23+
end

lib/excon/test/plugin/server/puma.rb

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
module Excon
2+
module Test
3+
module Plugin
4+
module Server
5+
module Puma
6+
def start(app_str = app, bind_uri = bind)
7+
bind.host = bind_uri.host.gsub(/[\[\]]/, '')
8+
open_process('puma', '-b', bind_uri.to_s, app_str)
9+
line = ''
10+
until line =~ /Use Ctrl-C to stop/
11+
line = read.gets
12+
fatal_time = elapsed_time > timeout
13+
raise 'puma server has taken too long to start' if fatal_time
14+
end
15+
true
16+
end
17+
end
18+
end
19+
end
20+
end
21+
end

lib/excon/test/plugin/server/rackup.rb

-20
This file was deleted.
+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
module Excon
2+
module Test
3+
module Plugin
4+
module Server
5+
module Unicorn
6+
def start(app_str = app, bind_uri = bind)
7+
bind_uri = URI.parse(bind_uri) unless bind_uri.is_a? URI::Generic
8+
is_unix_socket = (bind_uri.scheme == "unix")
9+
if is_unix_socket
10+
bind_str = bind_uri.to_s
11+
else
12+
host = bind_uri.host.gsub(/[\[\]]/, '')
13+
bind_str = "#{host}:#{bind_uri.port}"
14+
end
15+
args = [
16+
'unicorn',
17+
'--no-default-middleware',
18+
'-l',
19+
bind_str,
20+
app_str
21+
]
22+
open_process(*args)
23+
line = ''
24+
until line =~ /worker\=0 ready/
25+
line = error.gets
26+
fatal_time = elapsed_time > timeout
27+
raise 'unicorn server has taken too long to start' if fatal_time
28+
end
29+
true
30+
end
31+
end
32+
end
33+
end
34+
end
35+
end
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
module Excon
2+
module Test
3+
module Plugin
4+
module Server
5+
module Webrick
6+
def start(app_str = app, bind_uri = bind)
7+
bind_uri = URI.parse(bind_uri) unless bind_uri.is_a? URI::Generic
8+
host = bind_uri.host.gsub(/[\[\]]/, '')
9+
port = bind_uri.port.to_s
10+
open_process('rackup', '-s', 'webrick', '--host', host, '--port', port, app_str)
11+
line = ''
12+
until line =~ /HTTPServer#start/
13+
line = error.gets
14+
fatal_time = elapsed_time > timeout
15+
raise 'webrick server has taken too long to start' if fatal_time
16+
end
17+
true
18+
end
19+
end
20+
end
21+
end
22+
end
23+
end

lib/excon/test/server.rb

+33-12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
require 'open4'
22
require 'excon'
3-
require 'excon/test/plugin/server/rackup'
3+
require 'excon/test/plugin/server/webrick'
4+
require 'excon/test/plugin/server/unicorn'
5+
require 'excon/test/plugin/server/puma'
6+
require 'excon/test/plugin/server/exec'
7+
48

59
module Excon
610
module Test
@@ -19,27 +23,22 @@ def initialize(args)
1923
# TODO: Validate these args
2024
@server = args.keys.first
2125
@app = args[server]
22-
@bind = args[:bind]
26+
args[:bind] ||= 'tcp://127.0.0.1:9292'
27+
@bind = URI.parse(args[:bind])
28+
@is_unix_socket = (@bind.scheme == 'unix')
29+
@bind.host = @bind.host.gsub(/[\[\]]/, '') unless @is_unix_socket
2330
if args[:timeout]
2431
@timeout = args[:timeout]
2532
else
2633
# Double the default timeout if jruby because of the startup cost
2734
@timeout = RUBY_PLATFORM == "java" ? 20 : 10
2835
end
2936
name = @server.to_s.split('_').collect(&:capitalize).join
30-
plug = "Excon::Test::Plugin::Server::#{name}"
31-
self.extend Kernel.const_get plug
37+
plug = nested_const_get("Excon::Test::Plugin::Server::#{name}")
38+
self.extend plug
3239
check_implementation(plug)
3340
end
3441

35-
private def check_implementation(plug)
36-
INSTANCE_REQUIRES.each do |m|
37-
unless self.respond_to? m
38-
raise "FATAL: #{plug} does not implement ##{m}"
39-
end
40-
end
41-
end
42-
4342
def open_process(*args)
4443
if RUBY_PLATFORM == 'java'
4544
@pid, @write, @read, @error = IO.popen4(*args)
@@ -62,6 +61,12 @@ def stop
6261
GC.enable if RUBY_VERSION < '1.9'
6362
Process.wait(pid)
6463
end
64+
65+
if @is_unix_socket
66+
socket = @bind.path
67+
File.delete(socket) if File.exist?(socket)
68+
end
69+
6570
# TODO: Ensure process is really dead
6671
dump_errors
6772
true
@@ -81,6 +86,22 @@ def dump_errors
8186
puts line if in_err
8287
end
8388
end
89+
90+
private
91+
92+
def nested_const_get(namespace)
93+
namespace.split('::').inject(Object) do |mod, klass|
94+
mod.const_get(klass)
95+
end
96+
end
97+
98+
def check_implementation(plug)
99+
INSTANCE_REQUIRES.each do |m|
100+
unless self.respond_to? m
101+
raise "FATAL: #{plug} does not implement ##{m}"
102+
end
103+
end
104+
end
84105
end
85106
end
86107
end

spec/excon_test_server_spec.rb

+44-5
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,51 @@
11
require 'spec_helper'
22

3-
describe Excon::Test::Server do
4-
context 'when rackup' do
5-
it 'starts a new a app' do
6-
instance = Excon::Test::Server.new(rackup: rackup_path('basic.ru'), bind: '127.0.0.1')
7-
expect(instance).to be_a(Excon::Test::Server)
3+
# The variable file should be renamed to something better - starbelly
4+
shared_examples_for "a web server" do |plugin, file, bind_str = nil|
5+
plugin = plugin.to_sym unless plugin.is_a? Symbol
6+
7+
if plugin == :unicorn && RUBY_PLATFORM == "java"
8+
before { skip("until unicorn supports jruby") }
9+
end
10+
11+
abs_file = Object.send("#{plugin}_path", file)
12+
instance = nil
13+
args = { plugin => abs_file}
14+
args[:bind] = bind_str unless bind_str.nil?
15+
16+
it "returns an instance" do
17+
instance = Excon::Test::Server.new(args)
18+
expect(instance).to be_instance_of Excon::Test::Server
19+
end
20+
21+
it 'starts the server' do
822
expect(instance.start).to be true
23+
end
24+
25+
it 'stops the server' do
926
expect(instance.stop).to be true
1027
end
28+
end
29+
30+
describe Excon::Test::Server do
31+
context 'when webrick' do
32+
it_should_behave_like "a web server", :webrick, 'basic.ru'
33+
end
34+
35+
context 'when unicorn' do
36+
it_should_behave_like "a web server", :unicorn, 'streaming.ru'
37+
end
38+
39+
context "when unicorn is given a unix socket uri" do
40+
socket_uri = 'unix:///tmp/unicorn.socket'
41+
it_should_behave_like "a web server", :unicorn, 'streaming.ru', socket_uri
42+
end
43+
44+
context 'when puma' do
45+
it_should_behave_like "a web server", :puma, 'streaming.ru'
46+
end
47+
48+
context 'when executable' do
49+
it_should_behave_like "a web server", :exec, 'good.rb'
1150
end
1251
end

spec/spec_helper.rb

+15-6
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,21 @@
106106

107107
end
108108

109+
# Todo: s/tests/specs when migration is complete
110+
def get_abs_path(*parts)
111+
File.join(File.expand_path('../..', __FILE__), 'tests', *parts)
112+
end
113+
109114
def rackup_path(*parts)
110-
File.join(File.expand_path('../..', __FILE__), 'tests', 'rackups', *parts)
115+
get_abs_path('rackups', *parts)
111116
end
112117

113-
# TODO: Delete above method and uncommend this one when rackup tests are
114-
# ported
115-
#def rackup_path(*parts)
116-
# File.expand_path(File.join(File.dirname(__FILE__), 'rackups', *parts))
117-
#end
118+
def webrick_path(*parts) rackup_path(*parts); end
119+
120+
def unicorn_path(*parts) rackup_path(*parts); end
121+
122+
def puma_path(*parts) rackup_path(*parts); end
123+
124+
def exec_path(*parts)
125+
get_abs_path('servers', *parts)
126+
end

tests/test_helper.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -234,9 +234,9 @@ def rackup_path(*parts)
234234
def with_rackup(name, host="127.0.0.1")
235235
unless RUBY_PLATFORM == 'java'
236236
GC.disable if RUBY_VERSION < '1.9'
237-
pid, w, r, e = Open4.popen4("rackup", "--host", host, rackup_path(name))
237+
pid, w, r, e = Open4.popen4("rackup", "-s", "webrick", "--host", host, rackup_path(name))
238238
else
239-
pid, w, r, e = IO.popen4("rackup", "--host", host, rackup_path(name))
239+
pid, w, r, e = IO.popen4("rackup", "-s", "webrick", "--host", host, rackup_path(name))
240240
end
241241
until e.gets =~ /HTTPServer#start:/; end
242242
yield

0 commit comments

Comments
 (0)