summaryrefslogtreecommitdiffstats
path: root/script/spec_server
blob: 17b56f8783817c1f4c9f98d4cc146561d53c2e75 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/usr/bin/env ruby
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../vendor/plugins/rspec/lib' # For rspec installed as plugin
require 'rubygems'
require 'drb/drb'
require 'rbconfig'
require 'spec'
require 'optparse'

# This is based on Florian Weber's TDDMate
module Spec
  module Runner
    class RailsSpecServer
      def run(argv, stderr, stdout)
        $stdout = stdout
        $stderr = stderr

        base = ActiveRecord::Base
        def base.clear_reloadable_connections!
          active_connections.each do |name, conn|
            if conn.requires_reloading?
              conn.disconnect!
              active_connections.delete(name)
            end
          end
        end

        if ActionController.const_defined?(:Dispatcher)
          dispatcher = ::ActionController::Dispatcher.new($stdout)
          dispatcher.cleanup_application
        elsif ::Dispatcher.respond_to?(:reset_application!)
          ::Dispatcher.reset_application!
        else
          raise "Application reloading failed"
        end
        if Object.const_defined?(:Fixtures) && Fixtures.respond_to?(:reset_cache)
          Fixtures.reset_cache
        end

        ::Dependencies.mechanism = :load
        require_dependency('application.rb') unless Object.const_defined?(:ApplicationController)
        load File.dirname(__FILE__) + '/../spec/spec_helper.rb'

        if in_memory_database?
          load "#{RAILS_ROOT}/db/schema.rb" # use db agnostic schema by default
          ActiveRecord::Migrator.up('db/migrate') # use migrations
        end

        ::Spec::Runner::CommandLine.run(
          ::Spec::Runner::OptionParser.parse(
            argv,
            $stderr,
            $stdout
          )
        )
      end

      def in_memory_database?
        ENV["RAILS_ENV"] == "test" and
        ::ActiveRecord::Base.connection.class.to_s == "ActiveRecord::ConnectionAdapters::SQLite3Adapter" and
        ::Rails::Configuration.new.database_configuration['test']['database'] == ':memory:'
      end
    end
  end
end
puts "Loading Rails environment"

ENV["RAILS_ENV"] = "test"
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
require 'dispatcher'

def restart_test_server
  puts "restarting"
  config       = ::Config::CONFIG
  ruby         = File::join(config['bindir'], config['ruby_install_name']) + config['EXEEXT']
  command_line = [ruby, $0, ARGV].flatten.join(' ')
  exec(command_line)
end

def daemonize(pid_file = nil)
  return yield if $DEBUG
  pid = Process.fork{
    Process.setsid
    Dir.chdir(RAILS_ROOT)
    trap("SIGINT"){ exit! 0 }
    trap("SIGTERM"){ exit! 0 }
    trap("SIGHUP"){ restart_test_server }
    File.open("/dev/null"){|f|
      STDERR.reopen f
      STDIN.reopen  f
      STDOUT.reopen f
    }
    yield
  }
  puts "spec_server launched. (PID: %d)" % pid
  File.open(pid_file,"w"){|f| f.puts pid } if pid_file
  exit! 0
end

options = Hash.new
opts = OptionParser.new
opts.on("-d", "--daemon"){|v| options[:daemon] = true }
opts.on("-p", "--pid PIDFILE"){|v| options[:pid] = v }
opts.parse!(ARGV)

puts "Ready"
exec_server = lambda {
  trap("USR2") { restart_test_server } if Signal.list.has_key?("USR2")
  DRb.start_service("druby://127.0.0.1:8989", Spec::Runner::RailsSpecServer.new)
  DRb.thread.join
}

if options[:daemon]
  daemonize(options[:pid], &exec_server)
else
  exec_server.call
end