aboutsummaryrefslogtreecommitdiffstats
path: root/switchtower/test
diff options
context:
space:
mode:
Diffstat (limited to 'switchtower/test')
-rw-r--r--switchtower/test/actor_test.rb256
-rw-r--r--switchtower/test/configuration_test.rb212
-rw-r--r--switchtower/test/fixtures/config.rb5
3 files changed, 473 insertions, 0 deletions
diff --git a/switchtower/test/actor_test.rb b/switchtower/test/actor_test.rb
new file mode 100644
index 0000000000..bc33750b83
--- /dev/null
+++ b/switchtower/test/actor_test.rb
@@ -0,0 +1,256 @@
+$:.unshift File.dirname(__FILE__) + "/../lib"
+
+require 'stringio'
+require 'test/unit'
+require 'switchtower/actor'
+require 'switchtower/logger'
+
+module SwitchTower
+ class Actor
+ attr_reader :factory
+
+ class DefaultConnectionFactory
+ def connect_to(server)
+ server
+ end
+ end
+
+ class GatewayConnectionFactory
+ def connect_to(server)
+ server
+ end
+ end
+
+ def establish_gateway
+ GatewayConnectionFactory.new
+ end
+ end
+
+ class Command
+ 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
+end
+
+class ActorTest < Test::Unit::TestCase
+ 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 ||= SwitchTower::Logger.new(:output => StringIO.new)
+ end
+ end
+
+ def setup
+ SwitchTower::Command.reset!
+ @actor = SwitchTower::Actor.new(MockConfiguration.new)
+ 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_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(@actor.configuration).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_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_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_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 SwitchTower::Actor::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 SwitchTower::Command.invoked?
+ end
+
+ def test_run_when_pretend
+ @actor.define_task :foo do
+ run "do this"
+ end
+
+ @actor.configuration.pretend = true
+ @actor.foo
+ assert !SwitchTower::Command.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
+end
diff --git a/switchtower/test/configuration_test.rb b/switchtower/test/configuration_test.rb
new file mode 100644
index 0000000000..2ec299ab6d
--- /dev/null
+++ b/switchtower/test/configuration_test.rb
@@ -0,0 +1,212 @@
+$:.unshift File.dirname(__FILE__) + "/../lib"
+
+require 'test/unit'
+require 'switchtower/configuration'
+require 'flexmock'
+
+class ConfigurationTest < Test::Unit::TestCase
+ class MockActor
+ attr_reader :tasks
+
+ def initialize(config)
+ end
+
+ def define_task(*args, &block)
+ (@tasks ||= []).push [args, block].flatten
+ end
+ end
+
+ class MockSCM
+ attr_reader :configuration
+ attr_accessor :latest_revision
+
+ def initialize(config)
+ @configuration = config
+ end
+ end
+
+ def setup
+ @config = SwitchTower::Configuration.new(MockActor)
+ @config.set :scm, MockSCM
+ end
+
+ def test_version_dir_default
+ assert "releases", @config.version_dir
+ end
+
+ def test_current_dir_default
+ assert "current", @config.current_dir
+ end
+
+ def test_shared_dir_default
+ assert "shared", @config.shared_dir
+ end
+
+ def test_set_repository
+ @config.set :repository, "/foo/bar/baz"
+ assert_equal "/foo/bar/baz", @config.repository
+ end
+
+ def test_set_user
+ @config.set :user, "flippy"
+ assert_equal "flippy", @config.user
+ end
+
+ def test_define_single_role
+ @config.role :app, "somewhere.example.com"
+ assert_equal 1, @config.roles[:app].length
+ assert_equal "somewhere.example.com", @config.roles[:app].first.host
+ assert_equal Hash.new, @config.roles[:app].first.options
+ end
+
+ def test_define_single_role_with_options
+ @config.role :app, "somewhere.example.com", :primary => true
+ assert_equal 1, @config.roles[:app].length
+ assert_equal "somewhere.example.com", @config.roles[:app].first.host
+ assert_equal({:primary => true}, @config.roles[:app].first.options)
+ end
+
+ def test_define_multi_role
+ @config.role :app, "somewhere.example.com", "else.example.com"
+ assert_equal 2, @config.roles[:app].length
+ assert_equal "somewhere.example.com", @config.roles[:app].first.host
+ assert_equal "else.example.com", @config.roles[:app].last.host
+ assert_equal({}, @config.roles[:app].first.options)
+ assert_equal({}, @config.roles[:app].last.options)
+ end
+
+ def test_define_multi_role_with_options
+ @config.role :app, "somewhere.example.com", "else.example.com", :primary => true
+ assert_equal 2, @config.roles[:app].length
+ assert_equal "somewhere.example.com", @config.roles[:app].first.host
+ assert_equal "else.example.com", @config.roles[:app].last.host
+ assert_equal({:primary => true}, @config.roles[:app].first.options)
+ assert_equal({:primary => true}, @config.roles[:app].last.options)
+ end
+
+ def test_load_string_unnamed
+ @config.load :string => "set :repository, __FILE__"
+ assert_equal "<eval>", @config.repository
+ end
+
+ def test_load_string_named
+ @config.load :string => "set :repository, __FILE__", :name => "test.rb"
+ assert_equal "test.rb", @config.repository
+ end
+
+ def test_load
+ file = File.dirname(__FILE__) + "/fixtures/config.rb"
+ @config.load file
+ assert_equal "1/2/foo", @config.repository
+ assert_equal "./#{file}.example.com", @config.gateway
+ assert_equal 1, @config.roles[:web].length
+ end
+
+ def test_load_explicit_name
+ file = File.dirname(__FILE__) + "/fixtures/config.rb"
+ @config.load file, :name => "config"
+ assert_equal "1/2/foo", @config.repository
+ assert_equal "config.example.com", @config.gateway
+ assert_equal 1, @config.roles[:web].length
+ end
+
+ def test_load_file_implied_name
+ file = File.dirname(__FILE__) + "/fixtures/config.rb"
+ @config.load :file => file
+ assert_equal "1/2/foo", @config.repository
+ assert_equal "./#{file}.example.com", @config.gateway
+ assert_equal 1, @config.roles[:web].length
+ end
+
+ def test_load_file_explicit_name
+ file = File.dirname(__FILE__) + "/fixtures/config.rb"
+ @config.load :file => file, :name => "config"
+ assert_equal "1/2/foo", @config.repository
+ assert_equal "config.example.com", @config.gateway
+ assert_equal 1, @config.roles[:web].length
+ end
+
+ def test_task_without_options
+ block = Proc.new { }
+ @config.task :hello, &block
+ assert_equal 1, @config.actor.tasks.length
+ assert_equal :hello, @config.actor.tasks[0][0]
+ assert_equal({}, @config.actor.tasks[0][1])
+ assert_equal block, @config.actor.tasks[0][2]
+ end
+
+ def test_task_with_options
+ block = Proc.new { }
+ @config.task :hello, :roles => :app, &block
+ assert_equal 1, @config.actor.tasks.length
+ assert_equal :hello, @config.actor.tasks[0][0]
+ assert_equal({:roles => :app}, @config.actor.tasks[0][1])
+ assert_equal block, @config.actor.tasks[0][2]
+ end
+
+ def test_source
+ @config.set :repository, "/foo/bar/baz"
+ assert_equal "/foo/bar/baz", @config.source.configuration.repository
+ end
+
+ def test_releases_path_default
+ @config.set :deploy_to, "/start/of/path"
+ assert_equal "/start/of/path/releases", @config.releases_path
+ end
+
+ def test_releases_path_custom
+ @config.set :deploy_to, "/start/of/path"
+ @config.set :version_dir, "right/here"
+ assert_equal "/start/of/path/right/here", @config.releases_path
+ end
+
+ def test_current_path_default
+ @config.set :deploy_to, "/start/of/path"
+ assert_equal "/start/of/path/current", @config.current_path
+ end
+
+ def test_current_path_custom
+ @config.set :deploy_to, "/start/of/path"
+ @config.set :current_dir, "right/here"
+ assert_equal "/start/of/path/right/here", @config.current_path
+ end
+
+ def test_shared_path_default
+ @config.set :deploy_to, "/start/of/path"
+ assert_equal "/start/of/path/shared", @config.shared_path
+ end
+
+ def test_shared_path_custom
+ @config.set :deploy_to, "/start/of/path"
+ @config.set :shared_dir, "right/here"
+ assert_equal "/start/of/path/right/here", @config.shared_path
+ end
+
+ def test_release_path_implicit
+ @config.set :deploy_to, "/start/of/path"
+ @config.source.latest_revision = 2257
+ assert_equal "/start/of/path/releases/2257", @config.release_path
+ end
+
+ def test_release_path_explicit
+ @config.set :deploy_to, "/start/of/path"
+ assert_equal "/start/of/path/releases/silly", @config.release_path("silly")
+ end
+
+ def test_task_description
+ block = Proc.new { }
+ @config.desc "A sample task"
+ @config.task :hello, &block
+ assert_equal "A sample task", @config.actor.tasks[0][1][:desc]
+ end
+
+ def test_set_scm_to_darcs
+ @config.set :scm, :darcs
+ assert_equal "SwitchTower::SCM::Darcs", @config.source.class.name
+ end
+
+ def test_set_scm_to_subversion
+ @config.set :scm, :subversion
+ assert_equal "SwitchTower::SCM::Subversion", @config.source.class.name
+ end
+end
diff --git a/switchtower/test/fixtures/config.rb b/switchtower/test/fixtures/config.rb
new file mode 100644
index 0000000000..0570980bd8
--- /dev/null
+++ b/switchtower/test/fixtures/config.rb
@@ -0,0 +1,5 @@
+set :application, "foo"
+set :repository, "1/2/#{application}"
+set :gateway, "#{__FILE__}.example.com"
+
+role :web, "www.example.com", :primary => true