summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Keiser <john@johnkeiser.com>2014-06-12 12:37:20 -0700
committerJohn Keiser <john@johnkeiser.com>2014-06-12 12:37:20 -0700
commite675050eb2f3dffe2fa646fdbbb8e2f80e93a974 (patch)
treeb7f12bbea878b127403fa28734394fcbaa0985b7
parent9a15065435c16113c018fc0d6cea521bbf981df2 (diff)
parentd60221a7e5539874516bbfe75a5701d7e3b90971 (diff)
downloadchef-zero-e675050eb2f3dffe2fa646fdbbb8e2f80e93a974.tar.gz
Merge pull request #67 from opscode/ports
Allow server to try multiple ports
-rw-r--r--.travis.yml4
-rw-r--r--Rakefile6
-rwxr-xr-xbin/chef-zero18
-rw-r--r--lib/chef_zero/server.rb50
-rw-r--r--spec/server_spec.rb28
5 files changed, 97 insertions, 9 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/bin/chef-zero b/bin/chef-zero
index 6d6884f..c2b3120 100755
--- a/bin/chef-zero
+++ b/bin/chef-zero
@@ -10,6 +10,19 @@ require 'chef_zero/version'
require 'chef_zero/server'
require 'optparse'
+def parse_port(port)
+ array = []
+ port.split(',').each do |part|
+ a,b = part.split('-',2)
+ if b
+ array = array.concat(a.to_i.upto(b.to_i).to_a)
+ else
+ array = array.concat([a.to_i])
+ end
+ end
+ array
+end
+
options = {}
OptionParser.new do |opts|
@@ -19,8 +32,9 @@ OptionParser.new do |opts|
options[:host] = value
end
- opts.on("-p", "--port PORT", Integer, "Port to listen on") do |value|
- options[:port] = value
+ opts.on("-p", "--port PORT", "Port to listen on (e.g. 8889, or 8500-8600 or 8885,8888)") do |value|
+ options[:port] ||= []
+ options[:port] += parse_port(value)
end
opts.on("--[no-]generate-keys", "Whether to generate actual keys or fake it (faster). Default: false.") do |value|
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