From 5e558bcbf09058d1532db05350c3949333839f16 Mon Sep 17 00:00:00 2001 From: Jamis Buck Date: Sat, 6 Aug 2005 19:35:25 +0000 Subject: [PATCH] When executing multiline commands, escape newlines with a backslash git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1975 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- switchtower/CHANGELOG | 3 ++ switchtower/lib/switchtower/actor.rb | 38 +++++++++++++-------- switchtower/lib/switchtower/command.rb | 2 +- switchtower/test/actor_test.rb | 47 ++++++++++++++------------ switchtower/test/command_test.rb | 43 +++++++++++++++++++++++ 5 files changed, 96 insertions(+), 37 deletions(-) create mode 100644 switchtower/CHANGELOG create mode 100644 switchtower/test/command_test.rb diff --git a/switchtower/CHANGELOG b/switchtower/CHANGELOG new file mode 100644 index 0000000000000..e8681cfaebb63 --- /dev/null +++ b/switchtower/CHANGELOG @@ -0,0 +1,3 @@ +*SVN* + +* When executing multiline commands, use a backslash to escape the newline diff --git a/switchtower/lib/switchtower/actor.rb b/switchtower/lib/switchtower/actor.rb index cbaf8463e1b94..db25ca99c21e1 100644 --- a/switchtower/lib/switchtower/actor.rb +++ b/switchtower/lib/switchtower/actor.rb @@ -12,6 +12,27 @@ module SwitchTower # new actor via Configuration#actor. class Actor + # An adaptor for making the Net::SSH interface look and act like that of the + # Gateway class. + class DefaultConnectionFactory #:nodoc: + def initialize(config) + @config= config + end + + def connect_to(server) + Net::SSH.start(server, :username => @config.user, + :password => @config.password) + end + end + + class < @config.user, - :password => @config.password) - end - end - # Represents the definition of a single task. class Task #:nodoc: attr_reader :name, :options @@ -88,7 +96,7 @@ def initialize(config) #:nodoc: @tasks = {} @task_call_frames = [] @sessions = {} - @factory = DefaultConnectionFactory.new(configuration) + @factory = self.class.connection_factory.new(configuration) end # Define a new task for this actor. The block will be invoked when this @@ -134,7 +142,7 @@ def run(cmd, options={}, &block) establish_connections(servers) # execute the command on each server in parallel - command = Command.new(servers, cmd, block, options, self) + command = self.class.command_factory.new(servers, cmd, block, options, self) command.process! # raises an exception if command fails on any server end end diff --git a/switchtower/lib/switchtower/command.rb b/switchtower/lib/switchtower/command.rb index 910c97cb455ba..807958fd7679d 100644 --- a/switchtower/lib/switchtower/command.rb +++ b/switchtower/lib/switchtower/command.rb @@ -7,7 +7,7 @@ class Command def initialize(servers, command, callback, options, actor) #:nodoc: @servers = servers - @command = command + @command = command.gsub(/\r?\n/, "\\\n") @callback = callback @options = options @actor = actor diff --git a/switchtower/test/actor_test.rb b/switchtower/test/actor_test.rb index bc33750b836f9..ed657ee26e5b3 100644 --- a/switchtower/test/actor_test.rb +++ b/switchtower/test/actor_test.rb @@ -5,28 +5,24 @@ require 'switchtower/actor' require 'switchtower/logger' -module SwitchTower - class Actor - attr_reader :factory +class ActorTest < Test::Unit::TestCase - class DefaultConnectionFactory - def connect_to(server) - server - end + class TestingConnectionFactory + def initialize(config) end - class GatewayConnectionFactory - def connect_to(server) - server - end + def connect_to(server) + server end + end - def establish_gateway - GatewayConnectionFactory.new + class GatewayConnectionFactory + def connect_to(server) + server end end - class Command + class TestingCommand def self.invoked! @invoked = true end @@ -46,9 +42,18 @@ def process! self.class.invoked! end end -end -class ActorTest < Test::Unit::TestCase + class TestActor < SwitchTower::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) @@ -79,8 +84,8 @@ def logger end def setup - SwitchTower::Command.reset! - @actor = SwitchTower::Actor.new(MockConfiguration.new) + TestingCommand.reset! + @actor = TestActor.new(MockConfiguration.new) end def test_define_task_creates_method @@ -203,7 +208,7 @@ def test_establish_connection_uses_gateway_if_specified end @actor.foo - assert_instance_of SwitchTower::Actor::GatewayConnectionFactory, @actor.factory + assert_instance_of GatewayConnectionFactory, @actor.factory end def test_run_when_not_pretend @@ -213,7 +218,7 @@ def test_run_when_not_pretend @actor.configuration.pretend = false @actor.foo - assert SwitchTower::Command.invoked? + assert TestingCommand.invoked? end def test_run_when_pretend @@ -223,7 +228,7 @@ def test_run_when_pretend @actor.configuration.pretend = true @actor.foo - assert !SwitchTower::Command.invoked? + assert !TestingCommand.invoked? end def test_task_before_hook diff --git a/switchtower/test/command_test.rb b/switchtower/test/command_test.rb new file mode 100644 index 0000000000000..7005ba0f2d622 --- /dev/null +++ b/switchtower/test/command_test.rb @@ -0,0 +1,43 @@ +$:.unshift File.dirname(__FILE__) + "/../lib" + +require 'stringio' +require 'test/unit' +require 'switchtower/command' + +class CommandTest < Test::Unit::TestCase + class MockSession + def open_channel + { :closed => true, :status => 0 } + end + end + + class MockActor + attr_reader :sessions + + def initialize + @sessions = Hash.new { |h,k| h[k] = MockSession.new } + end + end + + def setup + @actor = MockActor.new + end + + def test_command_executes_on_all_servers + command = SwitchTower::Command.new(%w(server1 server2 server3), + "hello", nil, {}, @actor) + assert_equal %w(server1 server2 server3), @actor.sessions.keys.sort + end + + def test_command_with_newlines + command = SwitchTower::Command.new(%w(server1), "hello\nworld", nil, {}, + @actor) + assert_equal "hello\\\nworld", command.command + end + + def test_command_with_windows_newlines + command = SwitchTower::Command.new(%w(server1), "hello\r\nworld", nil, {}, + @actor) + assert_equal "hello\\\nworld", command.command + end +end