diff options
Diffstat (limited to 'test/rails/test_rails.rb')
-rw-r--r-- | test/rails/test_rails.rb | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/test/rails/test_rails.rb b/test/rails/test_rails.rb new file mode 100644 index 0000000..c7add20 --- /dev/null +++ b/test/rails/test_rails.rb @@ -0,0 +1,247 @@ +# Copyright (c) 2009 Eric Wong +require 'test/test_helper' + +# don't call exit(0) since it may be run under rake (but gmake is recommended) +do_test = true + +$unicorn_rails_bin = ENV['UNICORN_RAILS_TEST_BIN'] || "unicorn_rails" +redirect_test_io { do_test = system($unicorn_rails_bin, '-v') } + +unless do_test + warn "#$unicorn_rails_bin not found in PATH=#{ENV['PATH']}, " \ + "skipping this test" +end + +unless which('git') + warn "git not found in PATH=#{ENV['PATH']}, skipping this test" + do_test = false +end + +if RAILS_GIT_REPO = ENV['RAILS_GIT_REPO'] + unless File.directory?(RAILS_GIT_REPO) + warn "#{RAILS_GIT_REPO} not found, create it with:\n" \ + "\tgit clone --mirror git://github.com/rails/rails #{RAILS_GIT_REPO}" \ + "skipping this test for now" + do_test = false + end +else + warn "RAILS_GIT_REPO not defined, don't know where to git clone from" + do_test = false +end + +unless UNICORN_RAILS_TEST_VERSION = ENV['UNICORN_RAILS_TEST_VERSION'] + warn 'UNICORN_RAILS_TEST_VERSION not defined in environment, ' \ + 'skipping this test' + do_test = false +end + +RAILS_ROOT = "#{File.dirname(__FILE__)}/app-#{UNICORN_RAILS_TEST_VERSION}" +unless File.directory?(RAILS_ROOT) + warn "unsupported UNICORN_RAILS_TEST_VERSION=#{UNICORN_RAILS_TEST_VERSION}" + do_test = false +end + +ROR_V = UNICORN_RAILS_TEST_VERSION.split(/\./).map { |x| x.to_i } +RB_V = RUBY_VERSION.split(/\./).map { |x| x.to_i } +if RB_V[0] >= 1 && RB_V[1] >= 9 + unless ROR_V[0] >= 2 && ROR_V[1] >= 3 + warn "skipping Ruby >=1.9 test with Rails <2.3" + do_test = false + end +end + +class RailsTest < Test::Unit::TestCase + trap(:QUIT, 'IGNORE') + + COMMON_TMP = Tempfile.new('unicorn_tmp') unless defined?(COMMON_TMP) + + HEAVY_CFG = <<-EOS +worker_processes 2 +timeout 30 +logger Logger.new('#{COMMON_TMP.path}') + EOS + + def setup + @pwd = Dir.pwd + @tmpfile = Tempfile.new('unicorn_rails_test') + @tmpdir = @tmpfile.path + @tmpfile.close! + assert_nothing_raised do + FileUtils.cp_r(RAILS_ROOT, @tmpdir, :preserve => true) + end + Dir.chdir(@tmpdir) + system('git', 'clone', '-nsq', RAILS_GIT_REPO, 'vendor/rails') + Dir.chdir("#@tmpdir/vendor/rails") do + system('git', 'reset', '-q', '--hard', "v#{UNICORN_RAILS_TEST_VERSION}") + end + + assert(system('rake', 'db:sessions:create')) + assert(system('rake', 'db:migrate')) + + @addr = ENV['UNICORN_TEST_ADDR'] || '127.0.0.1' + @port = unused_port(@addr) + @start_pid = $$ + @pid = nil + end + + def test_launcher + tmp_dirs = %w(cache pids sessions sockets) + tmp_dirs.each { |dir| assert(! File.exist?("tmp/#{dir}")) } + redirect_test_io { @pid = fork { exec 'unicorn_rails', "-l#@addr:#@port" } } + wait_master_ready("test_stderr.#$$.log") + + # temp dirs exist + tmp_dirs.each { |dir| assert(File.directory?("tmp/#{dir}")) } + + # basic GET + res = Net::HTTP.get_response(URI.parse("http://#@addr:#@port/foo")) + assert_equal "FOO\n", res.body + assert_match %r{^text/html\b}, res['Content-Type'] + assert_equal "4", res['Content-Length'] + assert_equal "200 OK", res['Status'] + + # can we set cookies? + res = Net::HTTP.get_response(URI.parse("http://#@addr:#@port/foo/xcookie")) + assert_equal "200", res.code + assert_equal "200 OK", res['Status'] + cookies = res.get_fields('Set-Cookie') + assert_equal 2, cookies.size + assert_equal 1, cookies.grep(/\A_unicorn_rails_test\./).size + assert_equal 1, cookies.grep(/\Afoo=cookie/).size + + # how about just a session? + res = Net::HTTP.get_response(URI.parse("http://#@addr:#@port/foo/xnotice")) + assert_equal "200", res.code + assert_equal "200 OK", res['Status'] + cookies = res.get_fields('Set-Cookie') + assert_equal 1, cookies.size + assert_equal 1, cookies.grep(/\A_unicorn_rails_test\./).size + + # posting forms? + uri = URI.parse("http://#@addr:#@port/foo/xpost") + wait_master_ready("test_stderr.#$$.log") + res = Net::HTTP.post_form(uri, {"a" => "b", "c"=>"d"}) + assert_equal "200", res.code + params = res.body.split(/\n/).grep(/^params:/) + assert_equal 1, params.size + params = eval(params[0].gsub!(/\Aparams:/, '')) + assert_equal Hash, params.class + assert_equal 'b', params['a'] + assert_equal 'd', params['c'] + assert_equal "200 OK", res['Status'] + + # try uploading a big file + tmp = Tempfile.new('random') + sha1 = Digest::SHA1.new + assert_nothing_raised do + File.open("/dev/urandom", "rb") do |fp| + 256.times do + buf = fp.sysread(4096) + sha1.update(buf) + tmp.syswrite(buf) + end + end + end + resp = `curl -isSfN -Ffile=@#{tmp.path} http://#@addr:#@port/foo/xpost` + assert $?.success? + resp = resp.split(/\r?\n/) + grepped = resp.grep(/^sha1: (.{40})/) + assert_equal 1, grepped.size + assert_equal(sha1.hexdigest, /^sha1: (.{40})/.match(grepped.first)[1]) + + grepped = resp.grep(/^Content-Type:\s+(.+)/i) + assert_equal 1, grepped.size + assert_match %r{^text/plain}, grepped.first.split(/\s*:\s*/)[1] + + assert_equal 1, resp.grep(/^Status:/i).size + + # make sure we can get 403 responses, too + uri = URI.parse("http://#@addr:#@port/foo/xpost") + wait_master_ready("test_stderr.#$$.log") + res = Net::HTTP.get_response(uri) + assert_equal "403", res.code + assert_equal "403 Forbidden", res['Status'] + + # non existent controller + uri = URI.parse("http://#@addr:#@port/asdf") + res = Net::HTTP.get_response(uri) + assert_equal "404", res.code + assert_equal "404 Not Found", res['Status'] + + # static files + + # ensure file we're about to serve is not there yet + res = Net::HTTP.get_response(URI.parse("http://#@addr:#@port/pid.txt")) + assert_equal "404 Not Found", res['Status'] + assert_equal '404', res.code + + # can we serve text files based on suffix? + File.open("public/pid.txt", "wb") { |fp| fp.syswrite("#$$\n") } + res = Net::HTTP.get_response(URI.parse("http://#@addr:#@port/pid.txt")) + assert_equal '200', res.code + assert_equal "200 OK", res['Status'] + assert_match %r{^text/plain}, res['Content-Type'] + assert_equal "#$$\n", res.body + + # can we serve HTML files based on suffix? + assert File.exist?("public/500.html") + res = Net::HTTP.get_response(URI.parse("http://#@addr:#@port/500.html")) + assert_equal '200', res.code + assert_equal '200 OK', res['Status'] + assert_match %r{^text/html}, res['Content-Type'] + five_hundred_body = res.body + + # lets try pretending 500 is a controller that got cached + assert ! File.exist?("public/500") + assert_equal five_hundred_body, File.read("public/500.html") + res = Net::HTTP.get_response(URI.parse("http://#@addr:#@port/500")) + assert_equal '200', res.code + assert_equal '200 OK', res['Status'] + assert_match %r{^text/html}, res['Content-Type'] + assert_equal five_hundred_body, res.body + end + + def test_alt_url_root + # cbf to actually work on this since I never use this feature (ewong) + return unless ROR_V[0] >= 2 && ROR_V[1] >= 3 + redirect_test_io do + @pid = fork { exec 'unicorn_rails', "-l#@addr:#@port", '-P/poo' } + end + wait_master_ready("test_stderr.#$$.log") + res = Net::HTTP.get_response(URI.parse("http://#@addr:#@port/poo/foo")) + # p res + # p res.body + # system 'cat', 'log/development.log' + assert_equal "200", res.code + assert_equal '200 OK', res['Status'] + assert_equal "FOO\n", res.body + assert_match %r{^text/html\b}, res['Content-Type'] + assert_equal "4", res['Content-Length'] + + res = Net::HTTP.get_response(URI.parse("http://#@addr:#@port/foo")) + assert_equal "404", res.code + assert_equal '404 Not Found', res['Status'] + end + + def teardown + return if @start_pid != $$ + + if @pid + Process.kill(:QUIT, @pid) + pid2, status = Process.waitpid2(@pid) + assert status.success? + end + + Dir.chdir(@pwd) + FileUtils.rmtree(@tmpdir) + loop do + Process.kill('-QUIT', 0) + begin + Process.waitpid(-1, Process::WNOHANG) or break + rescue Errno::ECHILD + break + end + end + end + +end if do_test |