tests: disable Rails 2.x tests under Ruby 1.9.2
[unicorn.git] / test / rails / test_rails.rb
blob4b3857f5f400b24e10ce65f25025f2d7c0aaee96
1 # -*- encoding: binary -*-
3 # Copyright (c) 2009 Eric Wong
4 require 'test/test_helper'
6 # don't call exit(0) since it may be run under rake (but gmake is recommended)
7 do_test = true
9 $unicorn_rails_bin = ENV['UNICORN_RAILS_TEST_BIN'] || "unicorn_rails"
10 redirect_test_io { do_test = system($unicorn_rails_bin, '-v') }
12 unless do_test
13   warn "#$unicorn_rails_bin not found in PATH=#{ENV['PATH']}, " \
14        "skipping this test"
15 end
17 unless which('git')
18   warn "git not found in PATH=#{ENV['PATH']}, skipping this test"
19   do_test = false
20 end
22 if RAILS_GIT_REPO = ENV['RAILS_GIT_REPO']
23   unless File.directory?(RAILS_GIT_REPO)
24     warn "#{RAILS_GIT_REPO} not found, create it with:\n" \
25          "\tgit clone --mirror git://github.com/rails/rails #{RAILS_GIT_REPO}" \
26          "skipping this test for now"
27     do_test = false
28   end
29 else
30   warn "RAILS_GIT_REPO not defined, don't know where to git clone from"
31   do_test = false
32 end
34 unless UNICORN_RAILS_TEST_VERSION = ENV['UNICORN_RAILS_TEST_VERSION']
35   warn 'UNICORN_RAILS_TEST_VERSION not defined in environment, ' \
36        'skipping this test'
37   do_test = false
38 end
40 RAILS_ROOT = "#{File.dirname(__FILE__)}/app-#{UNICORN_RAILS_TEST_VERSION}"
41 unless File.directory?(RAILS_ROOT)
42   warn "unsupported UNICORN_RAILS_TEST_VERSION=#{UNICORN_RAILS_TEST_VERSION}"
43   do_test = false
44 end
46 ROR_V = UNICORN_RAILS_TEST_VERSION.split(/\./).map { |x| x.to_i }
47 RB_V = RUBY_VERSION.split(/\./).map { |x| x.to_i }
48 if RB_V[0] >= 1 && RB_V[1] >= 9
49   if RB_V[2] >= 2
50     warn "Ruby 1.9.2+ is not compatible with Rails 2.x"
51     do_test = false
52   end
53   unless ROR_V[0] >= 2 && ROR_V[1] >= 3
54     warn "skipping Ruby >=1.9 test with Rails <2.3"
55     do_test = false
56   end
57 end
59 class RailsTest < Test::Unit::TestCase
60   trap(:QUIT, 'IGNORE')
62   COMMON_TMP = Tempfile.new('unicorn_tmp') unless defined?(COMMON_TMP)
64   HEAVY_CFG = <<-EOS
65 worker_processes 2
66 timeout 30
67 logger Logger.new('#{COMMON_TMP.path}')
68   EOS
70   def setup
71     @pwd = Dir.pwd
72     @tmpfile = Tempfile.new('unicorn_rails_test')
73     @tmpdir = @tmpfile.path
74     @tmpfile.close!
75     assert_nothing_raised do
76       FileUtils.cp_r(RAILS_ROOT, @tmpdir, :preserve => true)
77     end
78     Dir.chdir(@tmpdir)
79     system('git', 'clone', '-nsq', RAILS_GIT_REPO, 'vendor/rails')
80     Dir.chdir("#@tmpdir/vendor/rails") do
81       system('git', 'reset', '-q', '--hard', "v#{UNICORN_RAILS_TEST_VERSION}")
82     end
84     assert(system('rake', 'db:sessions:create'))
85     assert(system('rake', 'db:migrate'))
87     @addr = ENV['UNICORN_TEST_ADDR'] || '127.0.0.1'
88     @port = unused_port(@addr)
89     @start_pid = $$
90     @pid = nil
91   end
93   def test_launcher
94     tmp_dirs = %w(cache pids sessions sockets)
95     tmp_dirs.each { |dir| assert(! File.exist?("tmp/#{dir}")) }
96     redirect_test_io { @pid = fork { exec 'unicorn_rails', "-l#@addr:#@port" } }
97     wait_master_ready("test_stderr.#$$.log")
99     # basic GET
100     res = Net::HTTP.get_response(URI.parse("http://#@addr:#@port/foo"))
101     assert_equal "FOO\n", res.body
102     assert_match %r{^text/html\b}, res['Content-Type']
103     assert_equal "4", res['Content-Length']
104     assert_equal "200 OK", res['Status']
106     # temp dirs exist
107     tmp_dirs.each { |dir| assert(File.directory?("tmp/#{dir}")) }
109     # can we set cookies?
110     res = Net::HTTP.get_response(URI.parse("http://#@addr:#@port/foo/xcookie"))
111     assert_equal "200", res.code
112     assert_equal "200 OK", res['Status']
113     cookies = res.get_fields('Set-Cookie')
114     assert_equal 2, cookies.size
115     assert_equal 1, cookies.grep(/\A_unicorn_rails_test\./).size
116     assert_equal 1, cookies.grep(/\Afoo=cookie/).size
118     # how about just a session?
119     res = Net::HTTP.get_response(URI.parse("http://#@addr:#@port/foo/xnotice"))
120     assert_equal "200", res.code
121     assert_equal "200 OK", res['Status']
122     cookies = res.get_fields('Set-Cookie')
123     assert_equal 1, cookies.size
124     assert_equal 1, cookies.grep(/\A_unicorn_rails_test\./).size
126     # posting forms?
127     uri = URI.parse("http://#@addr:#@port/foo/xpost")
128     wait_master_ready("test_stderr.#$$.log")
129     res = Net::HTTP.post_form(uri, {"a" => "b", "c"=>"d"})
130     assert_equal "200", res.code
131     params = res.body.split(/\n/).grep(/^params:/)
132     assert_equal 1, params.size
133     params = eval(params[0].gsub!(/\Aparams:/, ''))
134     assert_equal Hash, params.class
135     assert_equal 'b', params['a']
136     assert_equal 'd', params['c']
137     assert_equal "200 OK", res['Status']
139     # try uploading a big file
140     tmp = Tempfile.new('random')
141     sha1 = Digest::SHA1.new
142     assert_nothing_raised do
143       File.open("/dev/urandom", "rb") do |fp|
144         256.times do
145           buf = fp.sysread(4096)
146           sha1.update(buf)
147           tmp.syswrite(buf)
148         end
149       end
150     end
152     # fixed in Rack commit 44ed4640f077504a49b7f1cabf8d6ad7a13f6441,
153     # no released version of Rails or Rack has this fix
154     if RB_V[0] >= 1 && RB_V[1] >= 9
155       warn "multipart broken with Rack 1.0.0 and Rails 2.3.2.1 under 1.9"
156     else
157       resp = `curl -isSfN -Ffile=@#{tmp.path} http://#@addr:#@port/foo/xpost`
158       assert $?.success?
159       resp = resp.split(/\r?\n/)
160       grepped = resp.grep(/^sha1: (.{40})/)
161       assert_equal 1, grepped.size
162       assert_equal(sha1.hexdigest, /^sha1: (.{40})/.match(grepped.first)[1])
164       grepped = resp.grep(/^Content-Type:\s+(.+)/i)
165       assert_equal 1, grepped.size
166       assert_match %r{^text/plain}, grepped.first.split(/\s*:\s*/)[1]
167       assert_equal 1, resp.grep(/^Status:/i).size
168     end
170     # make sure we can get 403 responses, too
171     uri = URI.parse("http://#@addr:#@port/foo/xpost")
172     wait_master_ready("test_stderr.#$$.log")
173     res = Net::HTTP.get_response(uri)
174     assert_equal "403", res.code
175     assert_equal "403 Forbidden", res['Status']
177     # non existent controller
178     uri = URI.parse("http://#@addr:#@port/asdf")
179     res = Net::HTTP.get_response(uri)
180     assert_equal "404", res.code
181     assert_equal "404 Not Found", res['Status']
183     # static files
185     # ensure file we're about to serve is not there yet
186     res = Net::HTTP.get_response(URI.parse("http://#@addr:#@port/pid.txt"))
187     assert_equal "404 Not Found", res['Status']
188     assert_equal '404', res.code
190     # can we serve text files based on suffix?
191     File.open("public/pid.txt", "wb") { |fp| fp.syswrite("#$$\n") }
192     res = Net::HTTP.get_response(URI.parse("http://#@addr:#@port/pid.txt"))
193     assert_equal '200', res.code
194     assert_equal "200 OK", res['Status']
195     assert_match %r{^text/plain}, res['Content-Type']
196     assert_equal "#$$\n", res.body
198     # can we serve HTML files based on suffix?
199     assert File.exist?("public/500.html")
200     res = Net::HTTP.get_response(URI.parse("http://#@addr:#@port/500.html"))
201     assert_equal '200', res.code
202     assert_equal '200 OK', res['Status']
203     assert_match %r{^text/html}, res['Content-Type']
204     five_hundred_body = res.body
206     # lets try pretending 500 is a controller that got cached
207     assert ! File.exist?("public/500")
208     assert_equal five_hundred_body, File.read("public/500.html")
209     res = Net::HTTP.get_response(URI.parse("http://#@addr:#@port/500"))
210     assert_equal '200', res.code
211     assert_equal '200 OK', res['Status']
212     assert_match %r{^text/html}, res['Content-Type']
213     assert_equal five_hundred_body, res.body
214   end
216   def test_alt_url_root
217     # cbf to actually work on this since I never use this feature (ewong)
218     return unless ROR_V[0] >= 2 && ROR_V[1] >= 3
219     redirect_test_io do
220       @pid = fork { exec 'unicorn_rails', "-l#@addr:#@port", '-P/poo' }
221     end
222     wait_master_ready("test_stderr.#$$.log")
223     res = Net::HTTP.get_response(URI.parse("http://#@addr:#@port/poo/foo"))
224     # p res
225     # p res.body
226     # system 'cat', 'log/development.log'
227     assert_equal "200", res.code
228     assert_equal '200 OK', res['Status']
229     assert_equal "FOO\n", res.body
230     assert_match %r{^text/html\b}, res['Content-Type']
231     assert_equal "4", res['Content-Length']
233     res = Net::HTTP.get_response(URI.parse("http://#@addr:#@port/foo"))
234     assert_equal "404", res.code
235     assert_equal '404 Not Found', res['Status']
236   end
238   def test_alt_url_root_config_env
239     # cbf to actually work on this since I never use this feature (ewong)
240     return unless ROR_V[0] >= 2 && ROR_V[1] >= 3
241     tmp = Tempfile.new('')
242     tmp.syswrite("ENV['RAILS_RELATIVE_URL_ROOT'] = '/poo'\n")
243     redirect_test_io do
244       @pid = fork { exec 'unicorn_rails', "-l#@addr:#@port", "-c", tmp.path }
245     end
246     wait_master_ready("test_stderr.#$$.log")
247     res = Net::HTTP.get_response(URI.parse("http://#@addr:#@port/poo/foo"))
248     assert_equal "200", res.code
249     assert_equal '200 OK', res['Status']
250     assert_equal "FOO\n", res.body
251     assert_match %r{^text/html\b}, res['Content-Type']
252     assert_equal "4", res['Content-Length']
254     res = Net::HTTP.get_response(URI.parse("http://#@addr:#@port/foo"))
255     assert_equal "404", res.code
256     assert_equal '404 Not Found', res['Status']
258     res = Net::HTTP.get_response(URI.parse("http://#@addr:#@port/poo/x.txt"))
259     assert_equal "200", res.code
260     assert_equal "HELLO\n", res.body
261   end
263   def teardown
264     return if @start_pid != $$
266     if @pid
267       Process.kill(:QUIT, @pid)
268       pid2, status = Process.waitpid2(@pid)
269       assert status.success?
270     end
272     Dir.chdir(@pwd)
273     FileUtils.rmtree(@tmpdir)
274     loop do
275       Process.kill('-QUIT', 0)
276       begin
277         Process.waitpid(-1, Process::WNOHANG) or break
278       rescue Errno::ECHILD
279         break
280       end
281     end
282   end
284 end if do_test