123456789_123456789_123456789_123456789_123456789_

Class: Sinatra::Runner

Relationships & Source Files
Inherits: Object
Defined in: sinatra-contrib/lib/sinatra/runner.rb

Overview

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", dir) 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 https://github.com/apotonick/roar/blob/master/test/integration/runner.rb

Instance Attribute Summary

Instance Method Summary

Instance Attribute Details

#alive?Boolean (readonly, private)

[ GitHub ]

  
# File 'sinatra-contrib/lib/sinatra/runner.rb', line 127

def alive?
  3.times { get(ping_path) }
  true
rescue EOFError, SystemCallError, OpenURI::HTTPError, Timeout::Error
  false
end

#pipe (rw, private)

[ GitHub ]

  
# File 'sinatra-contrib/lib/sinatra/runner.rb', line 103

attr_accessor :pipe

Instance Method Details

#app_file

[ GitHub ]

  
# File 'sinatra-contrib/lib/sinatra/runner.rb', line 53

def app_file
  File.expand_path('server.rb', __dir__)
end

#command (private)

to be overwritten

[ GitHub ]

  
# File 'sinatra-contrib/lib/sinatra/runner.rb', line 110

def command
  "bundle exec ruby #{app_file} -p #{port} -e production"
end

#get(url)

[ GitHub ]

  
# File 'sinatra-contrib/lib/sinatra/runner.rb', line 72

def get(url)
  Timeout.timeout(1) { get_url("#{protocol}://127.0.0.1:#{port}#{url}") }
end

#get_https_url(uri) (private)

[ GitHub ]

  
# File 'sinatra-contrib/lib/sinatra/runner.rb', line 156

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_response(url)

[ GitHub ]

  
# File 'sinatra-contrib/lib/sinatra/runner.rb', line 85

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)

[ GitHub ]

  
# File 'sinatra-contrib/lib/sinatra/runner.rb', line 76

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

#get_url(url) (private)

[ GitHub ]

  
# File 'sinatra-contrib/lib/sinatra/runner.rb', line 148

def get_url(url)
  uri = URI.parse(url)

  return uri.read unless protocol == 'https'

  get_https_url(uri)
end

#kill

[ GitHub ]

  
# File 'sinatra-contrib/lib/sinatra/runner.rb', line 63

def kill
  return unless pipe

  Process.kill('KILL', pipe.pid)
rescue NotImplementedError
  system "kill -9 #{pipe.pid}"
rescue Errno::ESRCH
end

#log

[ GitHub ]

  
# File 'sinatra-contrib/lib/sinatra/runner.rb', line 94

def log
  @log ||= ''
  loop { @log << pipe.read_nonblock(1) }
rescue Exception
  @log
end

#ping(timeout = 30) (private)

[ GitHub ]

  
# File 'sinatra-contrib/lib/sinatra/runner.rb', line 114

def ping(timeout = 30)
  loop do
    return if alive?

    if Time.now - @started > timeout
      warn command, log
      raise "timeout starting server with command '#{command}'"
    else
      sleep 0.1
    end
  end
end

#ping_path (private)

to be overwritten

[ GitHub ]

  
# File 'sinatra-contrib/lib/sinatra/runner.rb', line 135

def ping_path
  '/ping'
end

#port (private)

to be overwritten

[ GitHub ]

  
# File 'sinatra-contrib/lib/sinatra/runner.rb', line 140

def port
  4567
end

#protocol (private)

[ GitHub ]

  
# File 'sinatra-contrib/lib/sinatra/runner.rb', line 144

def protocol
  'http'
end

#run

[ GitHub ]

  
# File 'sinatra-contrib/lib/sinatra/runner.rb', line 57

def run
  @pipe     = start
  @started  = Time.now
  warn "#{server} up and running on port #{port}" if ping
end

#start (private)

[ GitHub ]

  
# File 'sinatra-contrib/lib/sinatra/runner.rb', line 105

def start
  IO.popen(command)
end