class Sinatra::Runner

NOTE: This feature is experimental, and missing tests!

Helps you spinning up and shutting down your own sinatra app. This is especially helpful for running real network tests against a sinatra backend.

The backend server could look like the following (in test/server.rb).

require "sinatra"

get "/" do
  "Cheers from test server"
end

get "/ping" do
  "1"
end

Note that you need to implement a ping action for internal use.

Next, you need to write your runner.

require 'sinatra/runner'

class Runner < Sinatra::Runner
  def app_file
    File.expand_path("../server.rb", __FILE__)
  end
end

Override Runner#app_file, command, port, protocol and ping_path for customization.

**Don't forget to override app_file specific to your application!**

Wherever you need this test backend, here's how you manage it. The following example assumes you have a test in your app that needs to be run against your test backend.

runner = ServerRunner.new
runner.run

# ..tests against localhost:4567 here..

runner.kill

For an example, check github.com/apotonick/roar/blob/master/test/integration/runner.rb

Attributes

pipe[RW]

Public Instance Methods

app_file() click to toggle source
# File lib/sinatra/runner.rb, line 51
def app_file
  File.expand_path("../server.rb", __FILE__)
end
get(url) click to toggle source
# File lib/sinatra/runner.rb, line 69
def get(url)
  Timeout.timeout(1) { get_url("#{protocol}://127.0.0.1:#{port}#{url}") }
end
get_response(url) click to toggle source
# File lib/sinatra/runner.rb, line 82
def get_response(url)
  Net::HTTP.start '127.0.0.1', port do |http|
    request = Net::HTTP::Get.new url
    http.request request do |response|
      response
    end
  end
end
get_stream(url = "/stream", &block) click to toggle source
# File lib/sinatra/runner.rb, line 73
def get_stream(url = "/stream", &block)
  Net::HTTP.start '127.0.0.1', port do |http|
    request = Net::HTTP::Get.new url
    http.request request do |response|
      response.read_body(&block)
    end
  end
end
kill() click to toggle source
# File lib/sinatra/runner.rb, line 61
def kill
  return unless pipe
  Process.kill("KILL", pipe.pid)
rescue NotImplementedError
  system "kill -9 #{pipe.pid}"
rescue Errno::ESRCH
end
log() click to toggle source
# File lib/sinatra/runner.rb, line 91
def log
  @log ||= ""
  loop { @log <<  pipe.read_nonblock(1) }
rescue Exception
  @log
end
run() click to toggle source
# File lib/sinatra/runner.rb, line 55
def run
  @pipe     = start
  @started  = Time.now
  warn "#{server} up and running on port #{port}" if ping
end

Private Instance Methods

alive?() click to toggle source
# File lib/sinatra/runner.rb, line 121
def alive?
  3.times { get(ping_path) }
  true
rescue Errno::ECONNREFUSED, Errno::ECONNRESET, EOFError, SystemCallError, OpenURI::HTTPError, Timeout::Error
  false
end
command() click to toggle source
# File lib/sinatra/runner.rb, line 105
def command # to be overwritten
  "bundle exec ruby #{app_file} -p #{port} -e production"
end
get_https_url(uri) click to toggle source
# File lib/sinatra/runner.rb, line 147
def get_https_url(uri)
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl      = true
  http.verify_mode  = OpenSSL::SSL::VERIFY_NONE
  request = Net::HTTP::Get.new(uri.request_uri)
  http.request(request).body
end
get_url(url) click to toggle source
# File lib/sinatra/runner.rb, line 140
def get_url(url)
  uri = URI.parse(url)

  return uri.read unless protocol == "https"
  get_https_url(uri)
end
ping(timeout=30) click to toggle source
# File lib/sinatra/runner.rb, line 109
def ping(timeout=30)
  loop do
    return if alive?
    if Time.now - @started > timeout
      $stderr.puts command, log
      fail "timeout"
    else
      sleep 0.1
    end
  end
end
ping_path() click to toggle source
# File lib/sinatra/runner.rb, line 128
def ping_path # to be overwritten
  '/ping'
end
port() click to toggle source
# File lib/sinatra/runner.rb, line 132
def port # to be overwritten
  4567
end
protocol() click to toggle source
# File lib/sinatra/runner.rb, line 136
def protocol
  "http"
end
start() click to toggle source
# File lib/sinatra/runner.rb, line 101
def start
  IO.popen(command)
end