1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
|
require 'open4'
require 'excon'
require 'excon/test/plugin/server/webrick'
require 'excon/test/plugin/server/unicorn'
require 'excon/test/plugin/server/puma'
require 'excon/test/plugin/server/exec'
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]
args[:bind] ||= 'tcp://127.0.0.1:9292'
@bind = URI.parse(args[:bind])
@is_unix_socket = (@bind.scheme == 'unix')
@bind.host = @bind.host.gsub(/[\[\]]/, '') unless @is_unix_socket
if args[:timeout]
@timeout = args[:timeout]
else
@timeout = 20
end
name = @server.to_s.split('_').collect(&:capitalize).join
plug = nested_const_get("Excon::Test::Plugin::Server::#{name}")
self.extend plug
check_implementation(plug)
end
def open_process(*args)
if RUBY_PLATFORM == 'java'
@pid, @write, @read, @error = IO.popen4(*args)
else
@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)
Process.wait(pid)
end
if @is_unix_socket
socket = @bind.path
File.delete(socket) if File.exist?(socket)
end
# TODO: Ensure process is really dead
dump_errors
true
end
def dump_errors
lines = error.read.split($/)
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
private
def nested_const_get(namespace)
namespace.split('::').inject(Object) do |mod, klass|
mod.const_get(klass)
end
end
def check_implementation(plug)
INSTANCE_REQUIRES.each do |m|
unless self.respond_to? m
raise "FATAL: #{plug} does not implement ##{m}"
end
end
end
end
end
end
|