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