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
Public Instance Methods
# File lib/sinatra/runner.rb, line 51 def app_file File.expand_path("../server.rb", __FILE__) end
# File lib/sinatra/runner.rb, line 69 def get(url) Timeout.timeout(1) { get_url("#{protocol}://127.0.0.1:#{port}#{url}") } end
# 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
# 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
# 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
# File lib/sinatra/runner.rb, line 91 def log @log ||= "" loop { @log << pipe.read_nonblock(1) } rescue Exception @log end
# 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
# 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
# File lib/sinatra/runner.rb, line 105 def command # to be overwritten "bundle exec ruby #{app_file} -p #{port} -e production" end
# 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
# 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
# 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
# File lib/sinatra/runner.rb, line 128 def ping_path # to be overwritten '/ping' end
# File lib/sinatra/runner.rb, line 132 def port # to be overwritten 4567 end
# File lib/sinatra/runner.rb, line 136 def protocol "http" end
# File lib/sinatra/runner.rb, line 101 def start IO.popen(command) end