From ef9a2f05f3e14455dc70a5e0f68b0cf317a8709c Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Wed, 1 Apr 2009 01:43:44 -0700 Subject: Add more tests for Rails Additional tests for Rails have been added * cookies and sessions * POST requests * POST requests with multipart uploads * 404 handling * static file serving * cached static file serving (resources with ";" caching in some old 1.2.x version not yet tested) --- .../app-1.2.3/app/controllers/foo_controller.rb | 29 +++++ .../app-2.0.2/app/controllers/foo_controller.rb | 29 +++++ .../app-2.2.2/app/controllers/foo_controller.rb | 29 +++++ .../app-2.3.2.1/app/controllers/foo_controller.rb | 29 +++++ test/rails/test_rails.rb | 138 +++++++++++++++++++-- 5 files changed, 242 insertions(+), 12 deletions(-) (limited to 'test') diff --git a/test/rails/app-1.2.3/app/controllers/foo_controller.rb b/test/rails/app-1.2.3/app/controllers/foo_controller.rb index 7602947..8d877d1 100644 --- a/test/rails/app-1.2.3/app/controllers/foo_controller.rb +++ b/test/rails/app-1.2.3/app/controllers/foo_controller.rb @@ -1,5 +1,34 @@ +require 'digest/sha1' class FooController < ApplicationController def index render :text => "FOO\n" end + + def xcookie + cookies["foo"] = "cookie #$$" + render :text => "" + end + + def xnotice + flash[:notice] = "session #$$" + render :text => "" + end + + def xpost + if request.post? + digest = Digest::SHA1.new + out = "params: #{params.inspect}\n" + if file = params[:file] + loop do + buf = file.read(4096) or break + digest.update(buf) + end + out << "sha1: #{digest.to_s}\n" + end + headers['content-type'] = 'text/plain' + render :text => out + else + render :status => 403, :text => "need post\n" + end + end end diff --git a/test/rails/app-2.0.2/app/controllers/foo_controller.rb b/test/rails/app-2.0.2/app/controllers/foo_controller.rb index 7602947..8d877d1 100644 --- a/test/rails/app-2.0.2/app/controllers/foo_controller.rb +++ b/test/rails/app-2.0.2/app/controllers/foo_controller.rb @@ -1,5 +1,34 @@ +require 'digest/sha1' class FooController < ApplicationController def index render :text => "FOO\n" end + + def xcookie + cookies["foo"] = "cookie #$$" + render :text => "" + end + + def xnotice + flash[:notice] = "session #$$" + render :text => "" + end + + def xpost + if request.post? + digest = Digest::SHA1.new + out = "params: #{params.inspect}\n" + if file = params[:file] + loop do + buf = file.read(4096) or break + digest.update(buf) + end + out << "sha1: #{digest.to_s}\n" + end + headers['content-type'] = 'text/plain' + render :text => out + else + render :status => 403, :text => "need post\n" + end + end end diff --git a/test/rails/app-2.2.2/app/controllers/foo_controller.rb b/test/rails/app-2.2.2/app/controllers/foo_controller.rb index 7602947..8d877d1 100644 --- a/test/rails/app-2.2.2/app/controllers/foo_controller.rb +++ b/test/rails/app-2.2.2/app/controllers/foo_controller.rb @@ -1,5 +1,34 @@ +require 'digest/sha1' class FooController < ApplicationController def index render :text => "FOO\n" end + + def xcookie + cookies["foo"] = "cookie #$$" + render :text => "" + end + + def xnotice + flash[:notice] = "session #$$" + render :text => "" + end + + def xpost + if request.post? + digest = Digest::SHA1.new + out = "params: #{params.inspect}\n" + if file = params[:file] + loop do + buf = file.read(4096) or break + digest.update(buf) + end + out << "sha1: #{digest.to_s}\n" + end + headers['content-type'] = 'text/plain' + render :text => out + else + render :status => 403, :text => "need post\n" + end + end end diff --git a/test/rails/app-2.3.2.1/app/controllers/foo_controller.rb b/test/rails/app-2.3.2.1/app/controllers/foo_controller.rb index 7602947..261669c 100644 --- a/test/rails/app-2.3.2.1/app/controllers/foo_controller.rb +++ b/test/rails/app-2.3.2.1/app/controllers/foo_controller.rb @@ -1,5 +1,34 @@ +require 'digest/sha1' class FooController < ApplicationController def index render :text => "FOO\n" end + + def xcookie + cookies["foo"] = "cookie-#$$-#{session[:gotta_use_the_session_in_2_3]}" + render :text => "" + end + + def xnotice + flash[:notice] = "session #$$" + render :text => "" + end + + def xpost + if request.post? + digest = Digest::SHA1.new + out = "params: #{params.inspect}\n" + if file = params[:file] + loop do + buf = file.read(4096) or break + digest.update(buf) + end + out << "sha1: #{digest.to_s}\n" + end + headers['content-type'] = 'text/plain' + render :text => out + else + render :status => 403, :text => "need post\n" + end + end end diff --git a/test/rails/test_rails.rb b/test/rails/test_rails.rb index 2815734..a416b24 100644 --- a/test/rails/test_rails.rb +++ b/test/rails/test_rails.rb @@ -77,15 +77,13 @@ logger Logger.new('#{COMMON_TMP.path}') @addr = ENV['UNICORN_TEST_ADDR'] || '127.0.0.1' @port = unused_port(@addr) @start_pid = $$ + @pid = nil end def test_launcher_defaults tmp_dirs = %w(cache pids sessions sockets) tmp_dirs.each { |dir| assert(! File.exist?("tmp/#{dir}")) } - pid = nil - redirect_test_io do - pid = fork { exec 'unicorn_rails', "-l#@addr:#@port" } - end + redirect_test_io { @pid = fork { exec 'unicorn_rails', "-l#@addr:#@port" } } wait_master_ready("test_stderr.#$$.log") tmp_dirs.each { |dir| assert(File.directory?("tmp/#{dir}")) } res = Net::HTTP.get_response(URI.parse("http://#@addr:#@port/foo")) @@ -93,17 +91,100 @@ logger Logger.new('#{COMMON_TMP.path}') assert_match %r{^text/html\b}, res['Content-Type'] assert_equal "4", res['Content-Length'] assert_nil res['Status'] - Process.kill(:QUIT, pid) - pid2, status = Process.waitpid2(pid) - assert status.success? + end + + def test_cookies + redirect_test_io { @pid = fork { exec 'unicorn_rails', "-l#@addr:#@port" } } + wait_master_ready("test_stderr.#$$.log") + res = Net::HTTP.get_response(URI.parse("http://#@addr:#@port/foo/xcookie")) + assert_equal "200", res.code + assert_nil 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 + end + + def test_session + redirect_test_io { @pid = fork { exec 'unicorn_rails', "-l#@addr:#@port" } } + wait_master_ready("test_stderr.#$$.log") + res = Net::HTTP.get_response(URI.parse("http://#@addr:#@port/foo/xnotice")) + assert_equal "200", res.code + assert_nil res['Status'] + cookies = res.get_fields('Set-Cookie') + assert_equal 1, cookies.size + assert_equal 1, cookies.grep(/\A_unicorn_rails_test\./).size + end + + def test_post + redirect_test_io { @pid = fork { exec 'unicorn_rails', "-l#@addr:#@port" } } + 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_nil res['Status'] + end + + def test_post_upload + # I don't trust myself to generate a multipart request by hand + which('curl') or return + + redirect_test_io { @pid = fork { exec 'unicorn_rails', "-l#@addr:#@port" } } + wait_master_ready("test_stderr.#$$.log") + 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 0, resp.grep(/^Status:/i).size + end + + def test_post_forbidden + redirect_test_io { @pid = fork { exec 'unicorn_rails', "-l#@addr:#@port" } } + 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_nil res['Status'] + end + + def test_get_404 + redirect_test_io { @pid = fork { exec 'unicorn_rails', "-l#@addr:#@port" } } + uri = URI.parse("http://#@addr:#@port/asdf") + wait_master_ready("test_stderr.#$$.log") + res = Net::HTTP.get_response(uri) + assert_equal "404", res.code + assert_nil res['Status'] 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 - pid = nil redirect_test_io do - pid = fork { exec 'unicorn_rails', "-l#@addr:#@port", '-P/poo' } + @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")) @@ -119,14 +200,47 @@ logger Logger.new('#{COMMON_TMP.path}') res = Net::HTTP.get_response(URI.parse("http://#@addr:#@port/foo")) assert_equal "404", res.code assert_nil res['Status'] + end - Process.kill(:QUIT, pid) - pid2, status = Process.waitpid2(pid) - assert status.success? + def test_static + redirect_test_io { @pid = fork { exec 'unicorn_rails', "-l#@addr:#@port" } } + wait_master_ready("test_stderr.#$$.log") + res = Net::HTTP.get_response(URI.parse("http://#@addr:#@port/pid.txt")) + assert_nil res['Status'] + assert_equal '404', res.code + 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_match %r{^text/plain}, res['Content-Type'] + assert_equal "#$$\n", res.body + assert_nil res['Status'] + + res = Net::HTTP.get_response(URI.parse("http://#@addr:#@port/500.html")) + assert_equal '200', res.code + assert_match %r{^text/html}, res['Content-Type'] + five_hundred_body = res.body + assert_nil res['Status'] + + assert ! File.exist?("public/500") + assert File.exist?("public/500.html") + 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_match %r{^text/html}, res['Content-Type'] + assert_equal five_hundred_body, res.body + assert_nil 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 -- cgit v1.2.3-24-ge0c7