From 3fc8639b78417cffc112916537bb8249f8880394 Mon Sep 17 00:00:00 2001 From: Jamis Buck Date: Wed, 3 Aug 2005 12:59:03 +0000 Subject: Initial commit of the new switchtower utility git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1967 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- switchtower/test/actor_test.rb | 256 +++++++++++++++++++++++++++++++++ switchtower/test/configuration_test.rb | 212 +++++++++++++++++++++++++++ switchtower/test/fixtures/config.rb | 5 + 3 files changed, 473 insertions(+) create mode 100644 switchtower/test/actor_test.rb create mode 100644 switchtower/test/configuration_test.rb create mode 100644 switchtower/test/fixtures/config.rb (limited to 'switchtower/test') 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 "", @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 -- cgit v1.2.3