Skip to content

Commit

Permalink
Initial version of Excon::Test::Sever
Browse files Browse the repository at this point in the history
 - Added Excon::Test::Server
 - Added Excon::Test::Plugin::Server::Rackup
 - Added initial spec for Excon::Test::Server and Rackup plugin
 - Added rackup_path to spec_helper
  • Loading branch information
starbelly committed Jul 14, 2016
1 parent c406b15 commit a1a4108
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 0 deletions.
20 changes: 20 additions & 0 deletions lib/excon/test/plugin/server/rackup.rb
@@ -0,0 +1,20 @@
module Excon
module Test
module Plugin
module Server
module Rackup
def start(app_str = app, bind_str = bind)
open_process('rackup', '--host', bind, app)
line = ''
until line =~ /HTTPServer#start:|Use Ctrl-C to stop/
line = RUBY_PLATFORM == 'java' ? read.gets : error.gets
fatal_time = elapsed_time > timeout
raise 'rackup server has taken too long to start' if fatal_time
end
true
end
end
end
end
end
end
86 changes: 86 additions & 0 deletions lib/excon/test/server.rb
@@ -0,0 +1,86 @@
require 'open4'
require 'excon'
require 'excon/test/plugin/server/rackup'

module Excon
module Test
class Server
attr_accessor :app, :server, :bind, :pid, :read, :write, :error, :started_at, :timeout

# Methods that must be implemented by a plugin
INSTANCE_REQUIRES = [:start]
Excon.defaults.merge!(
connect_timeout: 5,
read_timeout: 5,
write_timeout: 5
)

def initialize(args)
# TODO: Validate these args
@server = args.keys.first
@app = args[server]
@bind = args[:bind]
if args[:timeout]
@timeout = args[:timeout]
else
# Double the default timeout if jruby because of the startup cost
@timeout = RUBY_PLATFORM == "java" ? 20 : 10
end
name = @server.to_s.split('_').collect(&:capitalize).join
plug = "Excon::Test::Plugin::Server::#{name}"
self.extend Kernel.const_get plug
check_implementation(plug)
end

private def check_implementation(plug)
INSTANCE_REQUIRES.each do |m|
unless self.respond_to? m
raise "FATAL: #{plug} does not implement ##{m}"
end
end
end

def open_process(*args)
if RUBY_PLATFORM == 'java'
@pid, @write, @read, @error = IO.popen4(*args)
else
GC.disable if RUBY_VERSION < '1.9'
@pid, @write, @read, @error = Open4.popen4(*args)
end
@started_at = Time.now
end

def elapsed_time
Time.now - started_at
end

def stop
if RUBY_PLATFORM == 'java'
Process.kill('USR1', pid)
else
Process.kill(9, pid)
GC.enable if RUBY_VERSION < '1.9'
Process.wait(pid)
end
# TODO: Ensure process is really dead
dump_errors
true
end
def dump_errors
lines = error.read.split($INPUT_RECORD_SEPARATOR)
while line = lines.shift
case line
when /(ERROR|Error)/
unless line =~ /(null cert chain|did not return a certificate|SSL_read:: internal error)/
in_err = true
puts
end
when /^(127|localhost)/
in_err = false
end
puts line if in_err
end
end
end
end
end
12 changes: 12 additions & 0 deletions spec/excon_test_server_spec.rb
@@ -0,0 +1,12 @@
require 'spec_helper'

describe Excon::Test::Server do
context 'when rackup' do
it 'starts a new a app' do
instance = Excon::Test::Server.new(rackup: rackup_path('basic.ru'), bind: '127.0.0.1')
expect(instance).to be_a(Excon::Test::Server)
expect(instance.start).to be true
expect(instance.stop).to be true
end
end
end
12 changes: 12 additions & 0 deletions spec/spec_helper.rb
@@ -1,4 +1,5 @@
require 'excon'
require 'excon/test/server'

# This file was generated by the `rspec --init` command. Conventionally, all
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
Expand Down Expand Up @@ -102,4 +103,15 @@
# as the one that triggered the failure.
Kernel.srand config.seed
=end

end

def rackup_path(*parts)
File.join(File.expand_path('../..', __FILE__), 'tests', 'rackups', *parts)
end

# TODO: Delete above method and uncommend this one when rackup tests are
# ported
#def rackup_path(*parts)
# File.expand_path(File.join(File.dirname(__FILE__), 'rackups', *parts))
#end

0 comments on commit a1a4108

Please sign in to comment.