1
0
Fork 0
mirror of https://github.com/capistrano/capistrano synced 2023-03-27 23:21:18 -04:00
capistrano/test/actor_test.rb

383 lines
9.1 KiB
Ruby

$:.unshift File.dirname(__FILE__) + "/../lib"
require 'stringio'
require 'test/unit'
require 'capistrano/actor'
require 'capistrano/logger'
require 'capistrano/configuration'
class ActorTest < Test::Unit::TestCase
class TestingConnectionFactory
def initialize(config)
end
def connect_to(server)
server
end
end
class GatewayConnectionFactory
def connect_to(server)
server
end
end
class TestingCommand
def self.invoked!
@invoked = true
end
def self.invoked?
@invoked
end
def self.reset!
@invoked = nil
end
def initialize(*args)
end
def process!
self.class.invoked!
end
end
class TestActor < Capistrano::Actor
attr_reader :factory
self.connection_factory = TestingConnectionFactory
self.command_factory = TestingCommand
def establish_gateway
GatewayConnectionFactory.new
end
end
class MockConfiguration
Role = Struct.new(:host, :options)
attr_accessor :gateway, :pretend
def delegated_method
"result of method"
end
ROLES = { :db => [ Role.new("01.example.com", :primary => true),
Role.new("02.example.com", {}),
Role.new("all.example.com", {})],
:web => [ Role.new("03.example.com", {}),
Role.new("04.example.com", {}),
Role.new("all.example.com", {})],
:app => [ Role.new("05.example.com", {}),
Role.new("06.example.com", {}),
Role.new("07.example.com", {}),
Role.new("all.example.com", {})] }
def roles
ROLES
end
def logger
@logger ||= Capistrano::Logger.new(:output => StringIO.new)
end
end
module CustomExtension
def do_something_extra(a, b, c)
run "echo '#{a} :: #{b} :: #{c}'"
end
end
def setup
TestingCommand.reset!
@actor = TestActor.new(MockConfiguration.new)
ENV["ROLES"] = nil
ENV["HOSTS"] = nil
end
def test_define_task_creates_method
@actor.define_task :hello do
"result"
end
assert @actor.respond_to?(:hello)
assert_equal "result", @actor.hello
end
def test_define_task_with_successful_transaction
class << @actor
attr_reader :rolled_back
attr_reader :history
end
@actor.define_task :hello do
(@history ||= []) << :hello
on_rollback { @rolled_back = true }
"hello"
end
@actor.define_task :goodbye do
(@history ||= []) << :goodbye
transaction do
hello
end
"goodbye"
end
assert_nothing_raised { @actor.goodbye }
assert !@actor.rolled_back
assert_equal [:goodbye, :hello], @actor.history
end
def test_define_task_with_failed_transaction
class << @actor
attr_reader :rolled_back
attr_reader :history
end
@actor.define_task :hello do
(@history ||= []) << :hello
on_rollback { @rolled_back = true }
"hello"
end
@actor.define_task :goodbye do
(@history ||= []) << :goodbye
transaction do
hello
raise "ouch"
end
"goodbye"
end
assert_raise(RuntimeError) do
@actor.goodbye
end
assert @actor.rolled_back
assert_equal [:goodbye, :hello], @actor.history
end
def test_rollback_uses_roles_for_associated_task
@actor.define_task :inner, :roles => :db do
on_rollback { run "error" }
run "go"
raise "fail"
end
@actor.define_task :outer do
transaction do
inner
end
run "done"
end
assert_raise(RuntimeError) { @actor.outer }
assert TestingCommand.invoked?
assert_equal %w(01.example.com 02.example.com all.example.com), @actor.sessions.keys.sort
end
def test_delegates_to_configuration
@actor.define_task :hello do
delegated_method
end
assert_equal "result of method", @actor.hello
end
def test_task_servers_with_duplicates
@actor.define_task :foo do
run "do this"
end
assert_equal %w(01.example.com 02.example.com 03.example.com 04.example.com 05.example.com 06.example.com 07.example.com all.example.com), @actor.tasks[:foo].servers.sort
end
def test_run_in_task_without_explicit_roles_selects_all_roles
@actor.define_task :foo do
run "do this"
end
@actor.foo
assert_equal %w(01.example.com 02.example.com 03.example.com 04.example.com 05.example.com 06.example.com 07.example.com all.example.com), @actor.sessions.keys.sort
end
def test_run_in_task_with_single_role_selects_that_role
@actor.define_task :foo, :roles => :db do
run "do this"
end
@actor.foo
assert_equal %w(01.example.com 02.example.com all.example.com), @actor.sessions.keys.sort
end
def test_run_in_task_with_single_role_selects_that_role_from_environment
ENV["ROLES"] = "app"
@actor.define_task :foo, :roles => :db do
run "do this"
end
@actor.foo
assert_equal %w(05.example.com 06.example.com 07.example.com all.example.com), @actor.sessions.keys.sort
end
def test_run_in_task_with_multiple_roles_selects_those_roles
@actor.define_task :foo, :roles => [:db, :web] do
run "do this"
end
@actor.foo
assert_equal %w(01.example.com 02.example.com 03.example.com 04.example.com all.example.com), @actor.sessions.keys.sort
end
def test_run_in_task_with_multiple_roles_selects_those_roles_from_environment
ENV["ROLES"] = "app,db"
@actor.define_task :foo, :roles => [:db, :web] do
run "do this"
end
@actor.foo
assert_equal %w(01.example.com 02.example.com 05.example.com 06.example.com 07.example.com all.example.com), @actor.sessions.keys.sort
end
def test_run_in_task_with_only_restricts_selected_roles
@actor.define_task :foo, :roles => :db, :only => { :primary => true } do
run "do this"
end
@actor.foo
assert_equal %w(01.example.com), @actor.sessions.keys.sort
end
def test_run_in_task_with_except_restricts_selected_roles
@actor.define_task :foo, :roles => :db, :except => { :primary => true } do
run "do this"
end
@actor.foo
assert_equal %w(02.example.com all.example.com), @actor.sessions.keys.sort
end
def test_run_in_task_with_single_host_selected
@actor.define_task :foo, :hosts => "01.example.com" do
run "do this"
end
@actor.foo
assert_equal %w(01.example.com), @actor.sessions.keys.sort
end
def test_run_in_task_with_single_host_selected_from_environment
ENV["HOSTS"] = "02.example.com"
@actor.define_task :foo, :hosts => "01.example.com" do
run "do this"
end
@actor.foo
assert_equal %w(02.example.com), @actor.sessions.keys.sort
end
def test_run_in_task_with_multiple_hosts_selected
@actor.define_task :foo, :hosts => [ "01.example.com", "07.example.com" ] do
run "do this"
end
@actor.foo
assert_equal %w(01.example.com 07.example.com), @actor.sessions.keys.sort
end
def test_run_in_task_with_multiple_hosts_selected_from_environment
ENV["HOSTS"] = "02.example.com,06.example.com"
@actor.define_task :foo, :hosts => [ "01.example.com", "07.example.com" ] do
run "do this"
end
@actor.foo
assert_equal %w(02.example.com 06.example.com), @actor.sessions.keys.sort
end
def test_establish_connection_uses_gateway_if_specified
@actor.configuration.gateway = "10.example.com"
@actor.define_task :foo, :roles => :db do
run "do this"
end
@actor.foo
assert_instance_of GatewayConnectionFactory, @actor.factory
end
def test_run_when_not_pretend
@actor.define_task :foo do
run "do this"
end
@actor.configuration.pretend = false
@actor.foo
assert TestingCommand.invoked?
end
def test_run_when_pretend
@actor.define_task :foo do
run "do this"
end
@actor.configuration.pretend = true
@actor.foo
assert !TestingCommand.invoked?
end
def test_task_before_hook
history = []
@actor.define_task :foo do
history << "foo"
end
@actor.define_task :before_foo do
history << "before_foo"
end
@actor.foo
assert_equal %w(before_foo foo), history
end
def test_task_after_hook
history = []
@actor.define_task :foo do
history << "foo"
end
@actor.define_task :after_foo do
history << "after_foo"
end
@actor.foo
assert_equal %w(foo after_foo), history
end
def test_uppercase_variables
config = Capistrano::Configuration.new(TestActor)
config.set :HELLO, "world"
assert_equal "world", config.actor.instance_eval("HELLO")
config.set :HELLO, "test"
assert_equal "test", config.actor.instance_eval("HELLO")
end
def test_connect_when_no_matching_servers
@actor.define_task :foo, :roles => :db, :only => { :fnoofy => true } do
run "do this"
end
assert_raises(RuntimeError) { @actor.foo }
end
def test_custom_extension
assert Capistrano.plugin(:custom, CustomExtension)
@actor.define_task :foo, :roles => :db do
custom.do_something_extra(1, 2, 3)
end
assert_nothing_raised { @actor.foo }
assert TestingCommand.invoked?
assert Capistrano.remove_plugin(:custom)
end
end