class Rack::TestServer

An utility class for launching HTTP server with Rack::Server.start and waiting for the server available with checking a healthcheck endpoint with net/http.

The most typical usage is:

“` server = Rack::TestServer.new(app: myapp, Port: 3000) server.start_async server.wait_for_ready “`

Constants

VERSION

Public Class Methods

new(app:, **options) click to toggle source

@param app [Proc] Rack application to run.

Available options can be found here: github.com/rack/rack/blob/2.2.3/lib/rack/server.rb#L173

# File lib/rack/test_server.rb, line 23
def initialize(app:, **options)
  testapp = Rack::Builder.app(app) do
    map '/__ping' do
      run ->(_env) { [200, { 'Content-Type' => 'text/plain' }, ['OK']] }
    end
  end

  @server = Rack::Server.new(app: testapp, **options)
  @host = @server.options[:Host] || @server.default_options[:Host]
  @port = @server.options[:Port] || @server.default_options[:Port]
end

Public Instance Methods

base_url() click to toggle source

@returns [String]

# File lib/rack/test_server.rb, line 36
def base_url
  if @host == '0.0.0.0'
    "http://127.0.0.1:#{@port}"
  else
    "http://#{@host}:#{@port}"
  end
end
ready?() click to toggle source

@returns [true|false]

Check if HTTP server actually responds.

# File lib/rack/test_server.rb, line 77
def ready?
  Net::HTTP.get(URI("#{base_url}/__ping"))
  true
rescue Errno::EADDRNOTAVAIL
  false
rescue Errno::ECONNREFUSED
  false
rescue Errno::EINVAL
  false
end
start() click to toggle source

Start HTTP server. Note that this method will block the thread, and in most cases start_async is suitable.

# File lib/rack/test_server.rb, line 46
def start
  @server.start do |server|
    # server can be a Puma::Launcher, Webrick::Server, Thin::Server
    # They all happen to have 'stop' method for greaceful shutdown.
    # Remember the method as Proc here for stopping server manually.
    @stop_proc = -> { server.stop }
  end
end
start_async() click to toggle source

Start HTTP server. This method is typically used together with `#wait_for_ready` method.

“` server = Rack::TestServer.new(app: myapp) server.start_async server.wait_for_ready “`

# File lib/rack/test_server.rb, line 63
def start_async
  Thread.new { start }
end
stop_async() click to toggle source

Stop HTTP server This method doesn't always wait for the shutdown process, and use wait_for_stopped to ensure the server is actually stopped.

# File lib/rack/test_server.rb, line 70
def stop_async
  Thread.new { @stop_proc.call }
end
wait_for_ready(timeout: 3) click to toggle source

This method blocks until the HTTP server is ensured to respond to HTTP request.

# File lib/rack/test_server.rb, line 89
def wait_for_ready(timeout: 3)
  Timeout.timeout(timeout) do
    sleep 0.1 until ready?
  end
end
wait_for_stopped(timeout: 5) click to toggle source

This method returns after the server is shutdown.

# File lib/rack/test_server.rb, line 96
def wait_for_stopped(timeout: 5)
  Timeout.timeout(timeout) do
    sleep 0.1 if ready?
  end
end