summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Keiser <jkeiser@opscode.com>2014-06-10 20:43:16 -0700
committerJohn Keiser <jkeiser@opscode.com>2014-06-10 20:43:16 -0700
commit25fe70279ea8eb89b360131e95ce65f6a8696992 (patch)
treed78f5bef2c2c84fe18828c1db6cb861a67c2a2fd
parent9a15065435c16113c018fc0d6cea521bbf981df2 (diff)
downloadchef-zero-25fe70279ea8eb89b360131e95ce65f6a8696992.tar.gz
Support port range in :port
-rw-r--r--.travis.yml4
-rw-r--r--Rakefile6
-rw-r--r--lib/chef_zero/server.rb50
-rw-r--r--spec/server_spec.rb28
4 files changed, 81 insertions, 7 deletions
diff --git a/.travis.yml b/.travis.yml
index 0837536..f3fedc3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,7 +2,7 @@ rvm: 1.9.3
gemfile: Gemfile
-script: bundle exec rake spec
+script: bundle exec rake pedant
matrix:
include:
@@ -24,6 +24,8 @@ matrix:
env: CHEF_FS=true
- rvm: 2.1.1
script: bundle exec rake chef_spec
+ - rvm: 2.1.1
+ script: bundle exec rake spec
allow_failures:
- rvm: 1.8.7
diff --git a/Rakefile b/Rakefile
index 099a270..4599e68 100644
--- a/Rakefile
+++ b/Rakefile
@@ -3,7 +3,13 @@ require 'bundler/gem_tasks'
require 'chef_zero/version'
+task :default => :pedant
+
task :spec do
+ system('rspec spec/*_spec.rb')
+end
+
+task :pedant do
require File.expand_path('spec/run')
end
diff --git a/lib/chef_zero/server.rb b/lib/chef_zero/server.rb
index 4955282..dbbe473 100644
--- a/lib/chef_zero/server.rb
+++ b/lib/chef_zero/server.rb
@@ -80,6 +80,17 @@ module ChefZero
# @return [Hash]
attr_reader :options
+ # @return [Integer]
+ def port
+ if @port
+ @port
+ elsif !options[:port].respond_to?(:each)
+ options[:port]
+ else
+ raise "port cannot be determined until server is started"
+ end
+ end
+
# @return [WEBrick::HTTPServer]
attr_reader :server
@@ -95,9 +106,9 @@ module ChefZero
#
def url
@url ||= if @options[:host].include?(':')
- URI("http://[#{@options[:host]}]:#{@options[:port]}").to_s
+ URI("http://[#{@options[:host]}]:#{port}").to_s
else
- URI("http://#{@options[:host]}:#{@options[:port]}").to_s
+ URI("http://#{@options[:host]}:#{port}").to_s
end
end
@@ -153,14 +164,20 @@ module ChefZero
output = publish.respond_to?(:puts) ? publish : STDOUT
output.puts <<-EOH.gsub(/^ {10}/, '')
>> Starting Chef Zero (v#{ChefZero::VERSION})...
+ EOH
+ end
+
+ thread = start_background
+
+ if publish
+ output = publish.respond_to?(:puts) ? publish : STDOUT
+ output.puts <<-EOH.gsub(/^ {10}/, '')
>> WEBrick (v#{WEBrick::VERSION}) on Rack (v#{Rack.release}) is listening at #{url}
>> Press CTRL+C to stop
EOH
end
- thread = start_background
-
%w[INT TERM].each do |signal|
Signal.trap(signal) do
puts "\n>> Stopping Chef Zero..."
@@ -185,8 +202,7 @@ module ChefZero
#
def start_background(wait = 5)
@server = WEBrick::HTTPServer.new(
- :BindAddress => @options[:host],
- :Port => @options[:port],
+ :DoNotListen => true,
:AccessLog => [],
:Logger => WEBrick::Log.new(StringIO.new, 7),
:StartCallback => proc {
@@ -195,18 +211,40 @@ module ChefZero
)
@server.mount('/', Rack::Handler::WEBrick, app)
+ # Pick a port
+ if options[:port].respond_to?(:each)
+ options[:port].each do |port|
+ begin
+ @server.listen(options[:host], port)
+ @port = port
+ break
+ rescue Errno::EADDRINUSE
+ end
+ end
+ if !@port
+ raise Errno::EADDRINUSE, "No port in :port range is available"
+ end
+ else
+ @server.listen(options[:host], options[:port])
+ @port = options[:port]
+ end
+
+ # Start the server in the background
@thread = Thread.new do
begin
Thread.current.abort_on_exception = true
@server.start
ensure
+ @port = nil
@running = false
end
end
+
# Do not return until the web server is genuinely started.
while !@running && @thread.alive?
sleep(0.01)
end
+
@thread
end
diff --git a/spec/server_spec.rb b/spec/server_spec.rb
new file mode 100644
index 0000000..575c2e2
--- /dev/null
+++ b/spec/server_spec.rb
@@ -0,0 +1,28 @@
+require 'chef_zero/server'
+
+describe ChefZero::Server do
+ context 'with a server bound to port 8889' do
+ before :each do
+ @server = ChefZero::Server.new(:port => 8889)
+ @server.start_background
+ end
+ after :each do
+ @server.stop
+ end
+
+ it 'a second server bound to port 8889 throws EADDRINUSE' do
+ expect { ChefZero::Server.new(:port => 8889).start }.to raise_error Errno::EADDRINUSE
+ end
+
+ it 'a server bound to range 8889-9999 binds to a port > 8889' do
+ server = ChefZero::Server.new(:port => 8889.upto(9999))
+ server.start_background
+ expect(server.port).to be > 8889
+ expect(URI(server.url).port).to be > 8889
+ end
+
+ it 'a server bound to range 8889-8889 throws an exception' do
+ expect { ChefZero::Server.new(:port => 8889.upto(8889)).start_background }.to raise_error Errno::EADDRINUSE
+ end
+ end
+end