Permalink
Browse files

Fix up tests and runner

All ruby tests should pass now.
  • Loading branch information...
1 parent 7dcfc53 commit d2ee83848661e9374c8736cb7411711ba3862c2d Ryan Dahl committed Mar 17, 2008
View
@@ -1,38 +1,4 @@
#!/usr/bin/env ruby
require File.dirname(__FILE__) + '/../ruby_lib/ebb'
-require 'optparse'
-require 'rubygems'
-require 'rack'
-module Rack
- module Adapter
- autoload :Rails, Ebb::LIBDIR + '/rack/adapter/rails'
- end
-end
-
-class EbbRails < Ebb::Runner
- def extra_options
- # defaults for ebb_rails
- @options.update(
- :environment => 'development',
- :port => 3000,
- # rails has a mutex lock around each request - threaded processing
- # will only slow things down
- :threaded_processing => false
- )
-
- @parser.on("-e", "--env ENV",
- "Rails environment (default: development)") do |env|
- @options[:environment] = env
- end
- @parser.on("-c", "--chdir DIR", "RAILS_ROOT directory") do |c|
- @options[:root] = c
- end
- end
-
- def app(options)
- Rack::Adapter::Rails.new(options)
- end
-end
-
-EbbRails.new(ARGV).run
+Ebb::Runner::Rails.new.run(ARGV)
View
@@ -21,7 +21,7 @@ def self.start_server(app, options={})
@running = true
trap('INT') { stop_server }
- puts "Ebb listening at http://0.0.0.0:#{port}/ (#{threaded_processing ? 'threaded' : 'sequential'} processing, PID #{Process.pid})"
+ log.puts "Ebb listening at http://0.0.0.0:#{port}/ (#{threaded_processing ? 'threaded' : 'sequential'} processing, PID #{Process.pid})"
while @running
FFI::server_process_connections()
@@ -74,12 +74,20 @@ def self.process(app, client)
client.body_written()
end
rescue => e
- puts "Ebb Error! #{e.class} #{e.message}"
- puts e.backtrace.join("\n")
+ log.puts "Ebb Error! #{e.class} #{e.message}"
+ log.puts e.backtrace.join("\n")
ensure
client.release
end
+ @@log = STDOUT
+ def self.log=(output)
+ @@log = output
+ end
+ def self.log
+ @@log
+ end
+
# This array is created and manipulated in the C extension.
def FFI.waiting_clients
@waiting_clients
View
@@ -20,6 +20,10 @@ def daemonize
module Ebb
class Runner
+ # Classes are modules and I hate this 'Base' class pattern. I'm putting
+ # other classes inside this one.
+ autoload :Rails, LIBDIR + '/ebb/runner/rails'
+
# Kill the process which PID is stored in +pid_file+.
def self.kill(pid_file, timeout=60)
raise ArgumentError, 'You must specify a pid_file to stop deamonized server' unless pid_file
@@ -28,12 +32,12 @@ def self.kill(pid_file, timeout=60)
pid = pid.to_i
Process.kill('KILL', pid)
- puts "stopped!"
+ Ebb.log.puts "stopped!"
else
- puts "Can't stop process, no PID found in #{@pid_file}"
+ Ebb.log.puts "Can't stop process, no PID found in #{@pid_file}"
end
rescue Errno::ESRCH # No such process
- puts "process not found!"
+ Ebb.log.puts "process not found!"
ensure
File.delete(pid_file) rescue nil
end
@@ -43,13 +47,14 @@ def self.remove_pid_file(file)
end
def self.write_pid_file(file)
- puts ">> Writing PID to #{file}"
+ Ebb.log.puts ">> Writing PID to #{file}"
open(file,"w+") { |f| f.write(Process.pid) }
File.chmod(0644, file)
end
- def initialize(argv)
- @argv = argv
+ attr_reader :options
+
+ def initialize
@parser = OptionParser.new
@options = {
:port => 4001,
@@ -58,8 +63,7 @@ def initialize(argv)
}
end
-
- def run
+ def parse_options(argv)
@parser.banner = "Usage: #{self.class} [options] start | stop"
@parser.separator ""
extra_options if respond_to?(:extra_options)
@@ -74,22 +78,26 @@ def run
@parser.separator ""
@parser.on_tail("-h", "--help", "Show this message") do
- puts @parser
+ Ebb.log.puts @parser
exit
end
@parser.on_tail('-v', '--version', "Show version") do
- puts "Ebb #{Ebb::VERSION}"
+ Ebb.log.puts "Ebb #{Ebb::VERSION}"
exit
end
- @parser.parse!(@argv)
+ @parser.parse!(argv)
+ end
+
+ def run(argv)
+ parse_options(argv)
- case @argv[0]
+ case argv[0]
when 'start'
- STDOUT.print("Ebb is loading the application...")
- STDOUT.flush()
+ Ebb.log.print("Ebb is loading the application...")
+ Ebb.log.flush()
@app = app(@options)
- STDOUT.puts("loaded")
+ Ebb.log.puts("loaded")
if @options[:daemonize]
pwd = Dir.pwd # Current directory is changed during daemonization, so store it
@@ -105,7 +113,7 @@ def run
if @options[:pid_file]
Runner.write_pid_file(@options[:pid_file])
at_exit do
- puts ">> Exiting!"
+ Ebb.log.puts ">> Exiting!"
Runner.remove_pid_file(@options[:pid_file])
end
end
@@ -114,8 +122,8 @@ def run
when 'stop'
Ebb::Runner.kill @options[:pid_file], @options[:timeout]
when nil
- puts "Command required"
- puts @parser
+ Ebb.log.puts "Command required"
+ Ebb.log.puts @parser
exit 1
else
abort "Invalid command : #{argv[0]}"
@@ -124,3 +132,4 @@ def run
end
end
end
+
@@ -0,0 +1,34 @@
+module Rack
+ module Adapter
+ autoload :Rails, Ebb::LIBDIR + '/rack/adapter/rails'
+ end
+end
+
+module Ebb
+ class Runner
+ class Rails < Runner
+ def extra_options
+ # defaults for ebb_rails
+ @options.update(
+ :environment => 'development',
+ :port => 3000,
+ # rails has a mutex lock around each request - threaded processing
+ # will only slow things down
+ :threaded_processing => false
+ )
+
+ @parser.on("-e", "--env ENV",
+ "Rails environment (default: development)") do |env|
+ @options[:environment] = env
+ end
+ @parser.on("-c", "--chdir DIR", "RAILS_ROOT directory") do |c|
+ @options[:root] = c
+ end
+ end
+
+ def app(options)
+ Rack::Adapter::Rails.new(options)
+ end
+ end
+ end
+end
@@ -1,4 +1,6 @@
require 'cgi'
+require 'rubygems'
+require 'rack'
# Adapter to run a Rails app with any supported Rack handler.
# By default it will try to load the Rails application in the
View
@@ -1,29 +1,29 @@
-require File.dirname(__FILE__) + '/helper'
+require File.dirname(__FILE__) + '/helper'
class BasicTest < ServerTest
def test_get_bytes
[1,10,1000].each do |i|
response = get("/bytes/#{i}")
- assert_equal "#{'C'*i.to_i}", response.body
+ assert_equal "#{'C'*i.to_i}", response['output']
end
end
def test_get_unknown
response = get('/blah')
- assert_equal "Undefined url", response.body
+ assert_equal "Undefined url", response['output']
end
def test_small_posts
[1,10,321,123,1000].each do |i|
response = post("/test_post_length", 'C'*i)
- assert_equal 200, response.code.to_i, response.body
+ assert_equal 200, response['status']
end
end
def test_large_post
[50,60,100].each do |i|
response = post("/test_post_length", 'C'*1024*i)
- assert_equal 200, response.code.to_i, response.body
+ assert_equal 200, response['status']
end
end
end
View
@@ -0,0 +1,34 @@
+require File.dirname(__FILE__) + '/helper'
+
+APP_DIR = File.dirname(__FILE__) + "/rails_app"
+EBB_RAILS = "#{Ebb::LIBDIR}/../bin/ebb_rails"
+class EbbRailsTest < Test::Unit::TestCase
+ # just to make sure there isn't some load error
+ def test_version
+ out = %x{ruby #{EBB_RAILS} -v}
+ assert_match %r{Ebb #{Ebb::VERSION}}, out
+ end
+
+ def test_parser
+ runner = Ebb::Runner::Rails.new
+ runner.parse_options("start -c #{APP_DIR} -p #{TEST_PORT}".split)
+ assert_equal TEST_PORT, runner.options[:port].to_i
+ assert_equal APP_DIR, runner.options[:root]
+ end
+
+
+ def test_start_app
+ Thread.new do
+ runner = Ebb::Runner::Rails.new
+ runner.run("start -c #{APP_DIR} -p #{TEST_PORT}".split)
+ end
+ sleep 0.1 until Ebb.running?
+
+ response = get '/'
+ assert_equal 200, response.code.to_i
+
+ ensure
+ Ebb.stop_server
+ sleep 0.1 while Ebb.running?
+ end
+end
View
@@ -1,15 +0,0 @@
-require 'rubygems'
-require 'json'
-require File.dirname(__FILE__) + '/../ruby_lib/ebb'
-
-
-class EchoApp
- def call(env)
- env['rack.input'] = env['rack.input'].read(1000000)
- env.delete('rack.errors')
- [200, {'Content-Type' => 'text/json'}, env.to_json]
- end
-end
-
-
-server = Ebb::start_server(EchoApp.new, :port => 4037, :workers => 10)
View
@@ -1,16 +1,11 @@
+require File.dirname(__FILE__) + '/helper'
require 'socket'
require 'rubygems'
require 'json'
require 'test/unit'
-PORT = 4037
-
-# This test depends on echo_server running at port 4037. I do this so that
-# I can run a Python server at that port with a similar application and reuse
-# these tests.
-
def send_request(request_string)
- socket = TCPSocket.new("0.0.0.0", PORT)
+ socket = TCPSocket.new("0.0.0.0", TEST_PORT)
socket.write(request_string)
lines = []
out = socket.read(5000000)
@@ -36,7 +31,7 @@ def drops_request?(request_string)
:fail == send_request(request_string)
end
-class HttpParserTest < Test::Unit::TestCase
+class HttpParserTest < ServerTest
def test_parse_simple
env = send_request("GET / HTTP/1.1\r\n\r\n")
@@ -48,14 +43,14 @@ def test_parse_simple
assert_equal 'GET', env['REQUEST_METHOD']
assert_nil env['FRAGMENT']
assert_nil env['QUERY_STRING']
- assert_nil env['rack.input']
+ assert_equal "", env['rack.input']
end
def test_parse_dumbfuck_headers
should_be_good = "GET / HTTP/1.1\r\naaaaaaaaaaaaa:++++++++++\r\n\r\n"
env = send_request(should_be_good)
assert_equal "++++++++++", env["HTTP_AAAAAAAAAAAAA"]
- assert_nil env['rack.input']
+ assert_equal "", env['rack.input']
nasty_pound_header = "GET / HTTP/1.1\r\nX-SSL-Bullshit: -----BEGIN CERTIFICATE-----\r\n\tMIIFbTCCBFWgAwIBAgICH4cwDQYJKoZIhvcNAQEFBQAwcDELMAkGA1UEBhMCVUsx\r\n\tETAPBgNVBAoTCGVTY2llbmNlMRIwEAYDVQQLEwlBdXRob3JpdHkxCzAJBgNVBAMT\r\n\tAkNBMS0wKwYJKoZIhvcNAQkBFh5jYS1vcGVyYXRvckBncmlkLXN1cHBvcnQuYWMu\r\n\tdWswHhcNMDYwNzI3MTQxMzI4WhcNMDcwNzI3MTQxMzI4WjBbMQswCQYDVQQGEwJV\r\n\tSzERMA8GA1UEChMIZVNjaWVuY2UxEzARBgNVBAsTCk1hbmNoZXN0ZXIxCzAJBgNV\r\n\tBAcTmrsogriqMWLAk1DMRcwFQYDVQQDEw5taWNoYWVsIHBhcmQYJKoZIhvcNAQEB\r\n\tBQADggEPADCCAQoCggEBANPEQBgl1IaKdSS1TbhF3hEXSl72G9J+WC/1R64fAcEF\r\n\tW51rEyFYiIeZGx/BVzwXbeBoNUK41OK65sxGuflMo5gLflbwJtHBRIEKAfVVp3YR\r\n\tgW7cMA/s/XKgL1GEC7rQw8lIZT8RApukCGqOVHSi/F1SiFlPDxuDfmdiNzL31+sL\r\n\t0iwHDdNkGjy5pyBSB8Y79dsSJtCW/iaLB0/n8Sj7HgvvZJ7x0fr+RQjYOUUfrePP\r\n\tu2MSpFyf+9BbC/aXgaZuiCvSR+8Snv3xApQY+fULK/xY8h8Ua51iXoQ5jrgu2SqR\r\n\twgA7BUi3G8LFzMBl8FRCDYGUDy7M6QaHXx1ZWIPWNKsCAwEAAaOCAiQwggIgMAwG\r\n\tA1UdEwEB/wQCMAAwEQYJYIZIAYb4QgEBBAQDAgWgMA4GA1UdDwEB/wQEAwID6DAs\r\n\tBglghkgBhvhCAQ0EHxYdVUsgZS1TY2llbmNlIFVzZXIgQ2VydGlmaWNhdGUwHQYD\r\n\tVR0OBBYEFDTt/sf9PeMaZDHkUIldrDYMNTBZMIGaBgNVHSMEgZIwgY+AFAI4qxGj\r\n\tloCLDdMVKwiljjDastqooXSkcjBwMQswCQYDVQQGEwJVSzERMA8GA1UEChMIZVNj\r\n\taWVuY2UxEjAQBgNVBAsTCUF1dGhvcml0eTELMAkGA1UEAxMCQ0ExLTArBgkqhkiG\r\n\t9w0BCQEWHmNhLW9wZXJhdG9yQGdyaWQtc3VwcG9ydC5hYy51a4IBADApBgNVHRIE\r\n\tIjAggR5jYS1vcGVyYXRvckBncmlkLXN1cHBvcnQuYWMudWswGQYDVR0gBBIwEDAO\r\n\tBgwrBgEEAdkvAQEBAQYwPQYJYIZIAYb4QgEEBDAWLmh0dHA6Ly9jYS5ncmlkLXN1\r\n\tcHBvcnQuYWMudmT4sopwqlBWsvcHViL2NybC9jYWNybC5jcmwwPQYJYIZIAYb4QgEDBDAWLmh0\r\n\tdHA6Ly9jYS5ncmlkLXN1cHBvcnQuYWMudWsvcHViL2NybC9jYWNybC5jcmwwPwYD\r\n\tVR0fBDgwNjA0oDKgMIYuaHR0cDovL2NhLmdyaWQt5hYy51ay9wdWIv\r\n\tY3JsL2NhY3JsLmNybDANBgkqhkiG9w0BAQUFAAOCAQEAS/U4iiooBENGW/Hwmmd3\r\n\tXCy6Zrt08YjKCzGNjorT98g8uGsqYjSxv/hmi0qlnlHs+k/3Iobc3LjS5AMYr5L8\r\n\tUO7OSkgFFlLHQyC9JzPfmLCAugvzEbyv4Olnsr8hbxF1MbKZoQxUZtMVu29wjfXk\r\n\thTeApBv7eaKCWpSp7MCbvgzm74izKhu3vlDk9w6qVrxePfGgpKPqfHiOoGhFnbTK\r\n\twTC6o2xq5y0qZ03JonF7OJspEd3I5zKY3E+ov7/ZhW6DqT8UFvsAdjvQbXyhV8Eu\r\n\tYhixw1aKEPzNjNowuIseVogKOLXxWI5vAi5HgXdS0/ES5gDGsABo4fqovUKlgop3\r\n\tRA==\r\n\t-----END CERTIFICATE-----\r\n\r\n"
assert drops_request?(nasty_pound_header) # Correct?
@@ -69,7 +64,7 @@ def test_fragment_in_uri
env = send_request("GET /forums/1/topics/2375?page=1#posts-17408 HTTP/1.1\r\n\r\n")
assert_equal '/forums/1/topics/2375?page=1', env['REQUEST_URI']
assert_equal 'posts-17408', env['FRAGMENT']
- assert_nil env['rack.input']
+ assert_equal "", env['rack.input']
end
# lame random garbage maker
Oops, something went wrong.

0 comments on commit d2ee838

Please sign in to comment.