-
Notifications
You must be signed in to change notification settings - Fork 2.1k
/
integration_helper.rb
137 lines (117 loc) · 2.96 KB
/
integration_helper.rb
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
require 'sinatra/base'
require 'rbconfig'
require 'open-uri'
module IntegrationHelper
class Server
extend Enumerable
attr_accessor :server, :port, :pipe
alias name server
def self.all
@all ||= []
end
def self.each(&block)
all.each(&block)
end
def self.run(server, port)
new(server, port).run
end
def app_file
File.expand_path('../integration/app.rb', __FILE__)
end
def environment
"development"
end
def initialize(server, port)
@installed, @pipe, @server, @port = nil, nil, server, port
Server.all << self
end
def run
return unless installed?
@log = ""
@pipe = IO.popen(command)
@started = Time.now
warn "#{server} up and running on port #{port}" if ping
at_exit { kill }
end
def expect(str)
return if log.size < str.size or log[0, str.size] == str
raise "Server did not start properly:\n\n#{log}"
end
def ping(timeout = 10)
loop do
return if alive?
if Time.now - @started > timeout
$stderr.puts command, log
get('/ping')
else
expect "loading"
sleep 0.1
end
end
end
def alive?
3.times { get('/ping') }
true
rescue Errno::ECONNREFUSED => error
false
end
def open(url)
super("http://127.0.0.1:#{port}#{url}")
end
def get(url)
open(url).read
end
def log
@log ||= ""
loop { @log << @pipe.read_nonblock(1) }
rescue Exception
@log
end
def installed?
return @installed unless @installed.nil?
require server
@installed = true
rescue LoadError
warn "#{server} is not installed, skipping integration tests"
@installed = false
end
def command
@command ||= begin
cmd = ["RACK_ENV=#{environment}", "exec"]
if RbConfig.respond_to? :ruby
cmd << RbConfig.ruby.inspect
else
file, dir = RbConfig::CONFIG.values_at('ruby_install_name', 'bindir')
cmd << File.expand_path(file, dir).inspect
end
cmd << "-I" << File.expand_path('../../lib', __FILE__).inspect
cmd << app_file.inspect << '-s' << server << '-o' << '127.0.0.1' << '-p' << port
cmd << "-e" << environment.to_s << '2>&1'
cmd.join " "
end
end
def kill
return unless pipe
Process.kill("KILL", pipe.pid)
rescue NotImplementedError
system "kill -9 #{pipe.pid}"
end
end
def it(message, &block)
Server.each do |server|
next unless server.installed?
super "with #{server.name}: #{message}" do
self.server = server
server.run unless server.alive?
instance_eval(&block)
end
end
end
def self.extend_object(obj)
super
base_port = 5000 + Process.pid % 100
Sinatra::Base.server.each_with_index do |server, index|
Server.run(server, 5000+index)
end
end
end