-
Notifications
You must be signed in to change notification settings - Fork 547
/
nginx_tests.rb
320 lines (279 loc) · 8.26 KB
/
nginx_tests.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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
require File.expand_path(File.dirname(__FILE__) + "/spec_helper")
require 'support/nginx_controller'
require 'integration_tests/shared/example_webapp_tests'
describe "Phusion Passenger for Nginx" do
before :all do
if !CONFIG['nginx']
STDERR.puts "*** ERROR: You must set the 'nginx' config option in test/config.json."
exit!(1)
end
check_hosts_configuration
FileUtils.mkdir_p("tmp.nginx")
end
after :all do
begin
@nginx.stop if @nginx
ensure
FileUtils.rm_rf("tmp.nginx")
end
end
before :each do
File.open("test.log", "a") do |f|
# Make sure that all Nginx log output is prepended by the test description
# so that we know which messages are associated with which tests.
f.puts "\n#### #{Time.now}: #{example.full_description}"
end
end
def create_nginx_controller(options = {})
@nginx = NginxController.new("tmp.nginx")
if Process.uid == 0
@nginx.set({
:www_user => CONFIG['normal_user_1'],
:www_group => Etc.getgrgid(Etc.getpwnam(CONFIG['normal_user_1']).gid).name
}.merge(options))
end
end
describe "a Ruby app running on the root URI" do
before :all do
create_nginx_controller
@server = "http://1.passenger.test:#{@nginx.port}"
@stub = RackStub.new('rack')
@nginx.add_server do |server|
server[:server_name] = "1.passenger.test"
server[:root] = "#{@stub.full_app_root}/public"
end
@nginx.start
end
after :all do
@stub.destroy
@nginx.stop if @nginx
end
before :each do
@stub.reset
end
it_should_behave_like "an example web app"
end
describe "a Ruby app running in a sub-URI" do
before :all do
create_nginx_controller
@server = "http://1.passenger.test:#{@nginx.port}/subapp"
@stub = RackStub.new('rack')
@nginx.add_server do |server|
server[:server_name] = "1.passenger.test"
server[:root] = "#{PhusionPassenger.source_root}/test/stub"
server << %Q{
location ~ ^/subapp(/.*|$) {
alias #{@stub.full_app_root}/public$1;
passenger_base_uri /subapp;
passenger_document_root #{@stub.full_app_root}/public;
passenger_app_root #{@stub.full_app_root};
passenger_enabled on;
}
}
end
@nginx.start
end
after :all do
@stub.destroy
@nginx.stop if @nginx
end
before :each do
@stub.reset
end
it_should_behave_like "an example web app"
it "does not interfere with the root website" do
@server = "http://1.passenger.test:#{@nginx.port}"
get('/').should == "This is the stub directory."
end
end
describe "a Python app running on the root URI" do
before :all do
create_nginx_controller
@server = "http://1.passenger.test:#{@nginx.port}"
@stub = PythonStub.new('wsgi')
@nginx.add_server do |server|
server[:server_name] = "1.passenger.test"
server[:root] = "#{@stub.full_app_root}/public"
end
@nginx.start
end
after :all do
@stub.destroy
@nginx.stop if @nginx
end
before :each do
@stub.reset
end
it_should_behave_like "an example web app"
end
describe "a Python app running in a sub-URI" do
before :all do
create_nginx_controller
@server = "http://1.passenger.test:#{@nginx.port}/subapp"
@stub = PythonStub.new('wsgi')
@nginx.add_server do |server|
server[:server_name] = "1.passenger.test"
server[:root] = "#{PhusionPassenger.source_root}/test/stub"
server << %Q{
location ~ ^/subapp(/.*|$) {
alias #{@stub.full_app_root}/public$1;
passenger_base_uri /subapp;
passenger_app_root #{@stub.full_app_root};
passenger_document_root #{@stub.full_app_root}/public;
passenger_enabled on;
}
}
end
@nginx.start
end
after :all do
@stub.destroy
@nginx.stop if @nginx
end
before :each do
@stub.reset
end
it_should_behave_like "an example web app"
it "does not interfere with the root website" do
@server = "http://1.passenger.test:#{@nginx.port}"
get('/').should == "This is the stub directory."
end
end
describe "various features" do
before :all do
create_nginx_controller
@server = "http://1.passenger.test:#{@nginx.port}"
@stub = RackStub.new('rack')
@nginx.set(:passenger_load_shell_envvars => 'off')
@nginx.add_server do |server|
server[:server_name] = "1.passenger.test"
server[:root] = "#{@stub.full_app_root}/public"
server << %q{
location /crash_without_friendly_error_page {
passenger_enabled on;
passenger_friendly_error_pages off;
}
}
end
@nginx.add_server do |server|
server[:server_name] = "2.passenger.test"
server[:root] = "#{@stub.full_app_root}/public"
server[:passenger_app_group_name] = "secondary"
server[:passenger_show_version_in_header] = "off"
end
@nginx.add_server do |server|
server[:server_name] = "3.passenger.test"
server[:passenger_app_group_name] = "tertiary"
server[:root] = "#{@stub.full_app_root}/public"
server[:passenger_max_requests] = 3
end
@nginx.start
end
after :all do
@stub.destroy
@nginx.stop if @nginx
end
before :each do
@stub.reset
@error_page_signature = /<meta name="generator" content="Phusion Passenger">/
File.touch("#{@stub.app_root}/tmp/restart.txt", 1 + rand(100000))
end
it "sets ENV['SERVER_SOFTWARE']" do
File.write("#{@stub.app_root}/config.ru", %q{
server_software = ENV['SERVER_SOFTWARE']
app = lambda do |env|
[200, { "Content-Type" => "text/plain" }, [server_software]]
end
run app
})
get('/').should =~ /nginx/i
end
it "displays a friendly error page if the application fails to spawn" do
File.write("#{@stub.app_root}/config.ru", %q{
raise "my error"
})
data = get('/')
data.should =~ /#{@error_page_signature}/
data.should =~ /my error/
end
it "doesn't display a friendly error page if the application fails to spawn but passenger_friendly_error_pages is off" do
File.write("#{@stub.app_root}/config.ru", %q{
raise "my error"
})
data = get('/crash_without_friendly_error_page')
data.should_not =~ /#{@error_page_signature}/
data.should_not =~ /my error/
end
it "appends an X-Powered-By header containing the Phusion Passenger version number" do
response = get_response('/')
response["X-Powered-By"].should include("Phusion Passenger")
response["X-Powered-By"].should include(PhusionPassenger::VERSION_STRING)
end
it "omits the version number in X-Powered-By when passenger_show_version_in_header is off" do
@server = "http://2.passenger.test:#{@nginx.port}/"
response = get_response('/')
response["X-Powered-By"].should include("Phusion Passenger")
response["X-Powered-By"].should_not include(PhusionPassenger::VERSION_STRING)
end
it "respawns the app after handling max_requests requests" do
@server = "http://3.passenger.test:#{@nginx.port}/"
pid = get("/pid")
get("/pid").should == pid
get("/pid").should == pid
get("/pid").should_not == pid
end
end
describe "oob work" do
before :all do
create_nginx_controller
@server = "http://passenger.test:#{@nginx.port}"
@stub = RackStub.new('rack')
@nginx.set(:max_pool_size => 2)
@nginx.add_server do |server|
server[:server_name] = "passenger.test"
server[:root] = "#{@stub.full_app_root}/public"
end
end
after :all do
@stub.destroy
@nginx.stop if @nginx
end
before :each do
@stub.reset
File.write("#{@stub.app_root}/config.ru", <<-RUBY)
PhusionPassenger.on_event(:oob_work) do
f = File.open("#{@stub.full_app_root}/oob_work.\#{$$}", 'w')
f.close
sleep 1
end
app = lambda do |env|
if env['PATH_INFO'] == '/oobw'
[200, { "Content-Type" => "text/html", "X-Passenger-Request-OOB-Work" => 'true' }, [$$]]
else
[200, { "Content-Type" => "text/html" }, [$$]]
end
end
run app
RUBY
@nginx.start
end
it "invokes oobw when requested by the app process" do
pid = get("/oobw")
sleep 0.5 # wait for oobw callback to be invoked
File.exists?("#{@stub.app_root}/oob_work.#{pid}").should == true
end
it "does not block client while invoking oob work" do
get("/") # ensure there are spawned app processes
t0 = Time.now
get("/oobw")
secs = Time.now - t0
secs.should <= 0.1
end
end
##### Helper methods #####
def start_web_server_if_necessary
if !@nginx.running?
@nginx.start
end
end
end