Skip to content

Instantly share code, notes, and snippets.

@xaviershay
Created December 13, 2011 02:19
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save xaviershay/1470160 to your computer and use it in GitHub Desktop.
Save xaviershay/1470160 to your computer and use it in GitHub Desktop.
Running a rack app in a thread for integration tests.
require 'integration_helper'
require 'rack'
require 'rack/handler/webrick'
describe HttpClient do
before :all do
@server = WEBrick::HTTPServer.new(
:Port => 9293,
:Logger => Rails.logger,
:AccessLog => Rails.logger
)
@server.mount '/', Rack::Handler::WEBrick, lambda {|env|
requested_response_code = env['REQUEST_PATH'][1..-1].to_i
[requested_response_code, {}, ['{}']]
}
Thread.new do
@server.start
end
start_time = Time.now
while !listen_on_port?(9293) && Time.now < start_time + 1.second
end
raise "Could not start server" if !listen_on_port?(9293)
end
after :all do
@server.shutdown
end
let(:http) { HttpClient.new("http://localhost:9293/") }
shared_examples_for 'an http method' do
it 'raises FailedRequest for non-successful requests' do
lambda { perform("/404") }.should raise_error(HttpClient::FailedRequest)
lambda { perform("/500") }.should raise_error(HttpClient::FailedRequest)
end
it 'does not raise for successful requests' do
lambda { perform("/200") }.should_not raise_error(HttpClient::FailedRequest)
end
end
describe '#get' do
def perform(path)
http.get(path, {})
end
it_should_behave_like 'an http method'
it 'should return response with body' do
perform('/200').body.should == '{}'
end
end
def listen_on_port?(port)
`lsof -i :#{port}`
$? == 0
end
end
@tcrayford
Copy link

As I understand it, I could use a similar thing to measure the boot time of raptor, correct?

(measuring boot time as: fork off a shell running rackup, send an http request at it, check it returns some value, then shutdown)

@xaviershay
Copy link
Author

If there's no dynamic loading, you can just start it up with a flag to auto-quit, no need to actually hit it (I use rails runner for Rails apps).

@janko
Copy link

janko commented Mar 14, 2015

Thank you, this really helped me out. After I made it work, I assembled a bit simpler way how to write it:

require "timeout"
# ...
    @server = WEBrick::HTTPServer.new(
      :Port          => 9293,
      :StartCallback => -> { @started = true }, # <--------------------
      :Logger        => Rails.logger,
      :AccessLog     => Rails.logger
    )
    @server.mount '/', Rack::Handler::WEBrick, lambda {|env|
      requested_response_code = env['REQUEST_PATH'][1..-1].to_i
      [requested_response_code, {}, ['{}']]
    }

    Thread.new { @server.start }
    Timeout.timeout(1) { :wait until @started } # <--------------
# ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment