sshkit 1.7.1 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -2
  3. data/BREAKING_API_WISHLIST.md +14 -0
  4. data/CHANGELOG.md +74 -0
  5. data/CONTRIBUTING.md +43 -0
  6. data/EXAMPLES.md +265 -169
  7. data/Gemfile +7 -0
  8. data/README.md +274 -9
  9. data/RELEASING.md +16 -8
  10. data/Rakefile +8 -0
  11. data/lib/sshkit.rb +0 -9
  12. data/lib/sshkit/all.rb +6 -4
  13. data/lib/sshkit/backends/abstract.rb +42 -42
  14. data/lib/sshkit/backends/connection_pool.rb +57 -8
  15. data/lib/sshkit/backends/local.rb +21 -50
  16. data/lib/sshkit/backends/netssh.rb +45 -98
  17. data/lib/sshkit/backends/printer.rb +3 -23
  18. data/lib/sshkit/backends/skipper.rb +4 -8
  19. data/lib/sshkit/color.rb +51 -20
  20. data/lib/sshkit/command.rb +68 -47
  21. data/lib/sshkit/configuration.rb +38 -5
  22. data/lib/sshkit/deprecation_logger.rb +17 -0
  23. data/lib/sshkit/formatters/abstract.rb +28 -4
  24. data/lib/sshkit/formatters/black_hole.rb +1 -2
  25. data/lib/sshkit/formatters/dot.rb +3 -10
  26. data/lib/sshkit/formatters/pretty.rb +31 -56
  27. data/lib/sshkit/formatters/simple_text.rb +6 -44
  28. data/lib/sshkit/host.rb +5 -6
  29. data/lib/sshkit/logger.rb +0 -1
  30. data/lib/sshkit/mapping_interaction_handler.rb +47 -0
  31. data/lib/sshkit/runners/parallel.rb +1 -1
  32. data/lib/sshkit/runners/sequential.rb +1 -1
  33. data/lib/sshkit/version.rb +1 -1
  34. data/sshkit.gemspec +0 -1
  35. data/test/functional/backends/test_local.rb +14 -1
  36. data/test/functional/backends/test_netssh.rb +58 -50
  37. data/test/helper.rb +2 -2
  38. data/test/unit/backends/test_abstract.rb +145 -0
  39. data/test/unit/backends/test_connection_pool.rb +27 -2
  40. data/test/unit/backends/test_printer.rb +47 -47
  41. data/test/unit/formatters/test_custom.rb +65 -0
  42. data/test/unit/formatters/test_dot.rb +25 -32
  43. data/test/unit/formatters/test_pretty.rb +114 -22
  44. data/test/unit/formatters/test_simple_text.rb +83 -0
  45. data/test/unit/test_color.rb +69 -5
  46. data/test/unit/test_command.rb +53 -18
  47. data/test/unit/test_command_map.rb +0 -4
  48. data/test/unit/test_configuration.rb +47 -7
  49. data/test/unit/test_coordinator.rb +45 -52
  50. data/test/unit/test_deprecation_logger.rb +38 -0
  51. data/test/unit/test_host.rb +3 -4
  52. data/test/unit/test_logger.rb +0 -1
  53. data/test/unit/test_mapping_interaction_handler.rb +101 -0
  54. metadata +37 -41
  55. data/lib/sshkit/utils/capture_output_methods.rb +0 -13
  56. data/test/functional/test_coordinator.rb +0 -17
@@ -0,0 +1,83 @@
1
+ require 'helper'
2
+
3
+ module SSHKit
4
+ class TestSimpleText < UnitTest
5
+
6
+ def setup
7
+ super
8
+ SSHKit.config.output_verbosity = Logger::DEBUG
9
+ end
10
+
11
+ def output
12
+ @output ||= String.new
13
+ end
14
+
15
+ def simple
16
+ @simple ||= SSHKit::Formatter::SimpleText.new(output)
17
+ end
18
+
19
+ %w(fatal error warn info debug).each do |level|
20
+ define_method("test_#{level}_output") do
21
+ simple.send(level, 'Test')
22
+ assert_log_output "Test\n"
23
+ end
24
+ end
25
+
26
+ def test_logging_message_with_leading_and_trailing_space
27
+ simple.log(" some spaces\n\n \t")
28
+ assert_log_output "some spaces\n"
29
+ end
30
+
31
+ def test_can_log_non_strings
32
+ simple.log(Pathname.new('/var/log/my.log'))
33
+ assert_log_output "/var/log/my.log\n"
34
+ end
35
+
36
+ def test_command_lifecycle_logging
37
+ command = SSHKit::Command.new(:a_cmd, 'some args', host: Host.new('user@localhost'))
38
+ command.stubs(:uuid).returns('aaaaaa')
39
+ command.stubs(:runtime).returns(1)
40
+
41
+ simple.log_command_start(command)
42
+ command.started = true
43
+ command.on_stdout(nil, 'stdout message')
44
+ simple.log_command_data(command, :stdout, 'stdout message')
45
+ command.on_stderr(nil, 'stderr message')
46
+ simple.log_command_data(command, :stderr, 'stderr message')
47
+ command.exit_status = 0
48
+ simple.log_command_exit(command)
49
+
50
+ expected_log_lines = [
51
+ 'Running /usr/bin/env a_cmd some args as user@localhost',
52
+ 'Command: /usr/bin/env a_cmd some args',
53
+ "\tstdout message",
54
+ "\tstderr message",
55
+ 'Finished in 1.000 seconds with exit status 0 (successful).'
56
+ ]
57
+ assert_equal expected_log_lines, output.split("\n")
58
+ end
59
+
60
+ def test_unsupported_class
61
+ raised_error = assert_raises RuntimeError do
62
+ simple << Pathname.new('/tmp')
63
+ end
64
+ assert_equal('write only supports formatting SSHKit::LogMessage, called with Pathname: #<Pathname:/tmp>', raised_error.message)
65
+ end
66
+
67
+ def test_does_not_log_when_verbosity_is_too_low
68
+ SSHKit.config.output_verbosity = Logger::WARN
69
+ simple.info('Some info')
70
+ assert_log_output('')
71
+
72
+ SSHKit.config.output_verbosity = Logger::INFO
73
+ simple.info('Some other info')
74
+ assert_log_output("Some other info\n")
75
+ end
76
+
77
+ private
78
+
79
+ def assert_log_output(expected_output)
80
+ assert_equal expected_output, output
81
+ end
82
+ end
83
+ end
@@ -4,13 +4,77 @@ require 'sshkit'
4
4
  module SSHKit
5
5
  class TestColor < UnitTest
6
6
 
7
- def test_responds_to_colorize?
8
- assert Color.respond_to?(:colorize?)
7
+ def test_colorize_when_tty_available
8
+ color = SSHKit::Color.new(stub(tty?: true), {})
9
+ assert_equal "\e[1;32;49mhi\e[0m", color.colorize('hi', :green, :bold)
9
10
  end
10
11
 
11
- def test_not_fails_on_bold_mode
12
- Color.stubs(:colorize?).returns true
13
- assert_equal Color.bold("test"), 'test'.bold
12
+ def test_colorize_when_SSHKIT_COLOR_present
13
+ color = SSHKit::Color.new(stub(tty?: false), {'SSHKIT_COLOR' => 'a'})
14
+ assert_equal "\e[0;31;49mhi\e[0m", color.colorize('hi', :red)
15
+ end
16
+
17
+ def test_does_not_colorize_when_no_tty_and_SSHKIT_COLOR_not_present
18
+ color = SSHKit::Color.new(stub(tty?: false), {})
19
+ assert_equal 'hi', color.colorize('hi', :red)
20
+ end
21
+
22
+ # The output parameter may not define the tty method eg if it is a Logger.
23
+ # In this case we assume showing colors would not be supported
24
+ # https://github.com/capistrano/sshkit/pull/246#issuecomment-100358122
25
+ def test_does_not_colorize_when_tty_method_not_defined_and_SSHKIT_COLOR_not_present
26
+ color = SSHKit::Color.new(stub(), {})
27
+ assert_equal 'hi', color.colorize('hi', :red)
28
+ end
29
+
30
+ def test_colorize_colors
31
+ color = SSHKit::Color.new(stub(tty?: true), {})
32
+ assert_equal "\e[0;30;49mhi\e[0m", color.colorize('hi', :black)
33
+ assert_equal "\e[0;31;49mhi\e[0m", color.colorize('hi', :red)
34
+ assert_equal "\e[0;32;49mhi\e[0m", color.colorize('hi', :green)
35
+ assert_equal "\e[0;33;49mhi\e[0m", color.colorize('hi', :yellow)
36
+ assert_equal "\e[0;34;49mhi\e[0m", color.colorize('hi', :blue)
37
+ assert_equal "\e[0;35;49mhi\e[0m", color.colorize('hi', :magenta)
38
+ assert_equal "\e[0;36;49mhi\e[0m", color.colorize('hi', :cyan)
39
+ assert_equal "\e[0;37;49mhi\e[0m", color.colorize('hi', :white)
40
+ assert_equal "\e[0;90;49mhi\e[0m", color.colorize('hi', :light_black)
41
+ assert_equal "\e[0;91;49mhi\e[0m", color.colorize('hi', :light_red)
42
+ assert_equal "\e[0;92;49mhi\e[0m", color.colorize('hi', :light_green)
43
+ assert_equal "\e[0;93;49mhi\e[0m", color.colorize('hi', :light_yellow)
44
+ assert_equal "\e[0;94;49mhi\e[0m", color.colorize('hi', :light_blue)
45
+ assert_equal "\e[0;95;49mhi\e[0m", color.colorize('hi', :light_magenta)
46
+ assert_equal "\e[0;96;49mhi\e[0m", color.colorize('hi', :light_cyan)
47
+ assert_equal "\e[0;97;49mhi\e[0m", color.colorize('hi', :light_white)
48
+ end
49
+
50
+ def test_colorize_bold_colors
51
+ color = SSHKit::Color.new(stub(tty?: true), {})
52
+ assert_equal "\e[1;30;49mhi\e[0m", color.colorize('hi', :black, :bold)
53
+ assert_equal "\e[1;31;49mhi\e[0m", color.colorize('hi', :red, :bold)
54
+ assert_equal "\e[1;32;49mhi\e[0m", color.colorize('hi', :green, :bold)
55
+ assert_equal "\e[1;33;49mhi\e[0m", color.colorize('hi', :yellow, :bold)
56
+ assert_equal "\e[1;34;49mhi\e[0m", color.colorize('hi', :blue, :bold)
57
+ assert_equal "\e[1;35;49mhi\e[0m", color.colorize('hi', :magenta, :bold)
58
+ assert_equal "\e[1;36;49mhi\e[0m", color.colorize('hi', :cyan, :bold)
59
+ assert_equal "\e[1;37;49mhi\e[0m", color.colorize('hi', :white, :bold)
60
+ assert_equal "\e[1;90;49mhi\e[0m", color.colorize('hi', :light_black, :bold)
61
+ assert_equal "\e[1;91;49mhi\e[0m", color.colorize('hi', :light_red, :bold)
62
+ assert_equal "\e[1;92;49mhi\e[0m", color.colorize('hi', :light_green, :bold)
63
+ assert_equal "\e[1;93;49mhi\e[0m", color.colorize('hi', :light_yellow, :bold)
64
+ assert_equal "\e[1;94;49mhi\e[0m", color.colorize('hi', :light_blue, :bold)
65
+ assert_equal "\e[1;95;49mhi\e[0m", color.colorize('hi', :light_magenta, :bold)
66
+ assert_equal "\e[1;96;49mhi\e[0m", color.colorize('hi', :light_cyan, :bold)
67
+ assert_equal "\e[1;97;49mhi\e[0m", color.colorize('hi', :light_white, :bold)
68
+ end
69
+
70
+ def test_ignores_unrecognized_color
71
+ color = SSHKit::Color.new(stub(tty?: true), {})
72
+ assert_equal 'hi', color.colorize('hi', :tangerine)
73
+ end
74
+
75
+ def test_ignores_unrecognized_mode
76
+ color = SSHKit::Color.new(stub(tty?: true), {})
77
+ assert_equal "\e[0;31;49mhi\e[0m", color.colorize('hi', :red, :underline)
14
78
  end
15
79
  end
16
80
  end
@@ -4,10 +4,6 @@ require 'sshkit'
4
4
  module SSHKit
5
5
  class TestCommand < UnitTest
6
6
 
7
- def setup
8
- SSHKit.reset_configuration!
9
- end
10
-
11
7
  def test_maps_a_command
12
8
  c = Command.new('example')
13
9
  assert_equal '/usr/bin/env example', c.to_command
@@ -32,38 +28,44 @@ module SSHKit
32
28
  def test_including_the_env
33
29
  SSHKit.config = nil
34
30
  c = Command.new(:rails, 'server', env: {rails_env: :production})
35
- assert_equal "( RAILS_ENV=production /usr/bin/env rails server )", c.to_command
31
+ assert_equal %{( export RAILS_ENV="production" ; /usr/bin/env rails server )}, c.to_command
36
32
  end
37
33
 
38
34
  def test_including_the_env_with_multiple_keys
39
35
  SSHKit.config = nil
40
36
  c = Command.new(:rails, 'server', env: {rails_env: :production, foo: 'bar'})
41
- assert_equal "( RAILS_ENV=production FOO=bar /usr/bin/env rails server )", c.to_command
37
+ assert_equal %{( export RAILS_ENV="production" FOO="bar" ; /usr/bin/env rails server )}, c.to_command
42
38
  end
43
39
 
44
40
  def test_including_the_env_with_string_keys
45
41
  SSHKit.config = nil
46
42
  c = Command.new(:rails, 'server', env: {'FACTER_env' => :production, foo: 'bar'})
47
- assert_equal "( FACTER_env=production FOO=bar /usr/bin/env rails server )", c.to_command
43
+ assert_equal %{( export FACTER_env="production" FOO="bar" ; /usr/bin/env rails server )}, c.to_command
44
+ end
45
+
46
+ def test_double_quotes_are_escaped_in_env
47
+ SSHKit.config = nil
48
+ c = Command.new(:rails, 'server', env: {foo: 'asdf"hjkl'})
49
+ assert_equal %{( export FOO="asdf\\\"hjkl" ; /usr/bin/env rails server )}, c.to_command
48
50
  end
49
51
 
50
52
  def test_including_the_env_doesnt_addressively_escape
51
53
  SSHKit.config = nil
52
54
  c = Command.new(:rails, 'server', env: {path: '/example:$PATH'})
53
- assert_equal "( PATH=/example:$PATH /usr/bin/env rails server )", c.to_command
55
+ assert_equal %{( export PATH="/example:$PATH" ; /usr/bin/env rails server )}, c.to_command
54
56
  end
55
57
 
56
58
  def test_global_env
57
59
  SSHKit.config = nil
58
60
  SSHKit.config.default_env = { default: 'env' }
59
61
  c = Command.new(:rails, 'server', env: {})
60
- assert_equal "( DEFAULT=env /usr/bin/env rails server )", c.to_command
62
+ assert_equal %{( export DEFAULT="env" ; /usr/bin/env rails server )}, c.to_command
61
63
  end
62
64
 
63
65
  def test_default_env_is_overwritten_with_locally_defined
64
66
  SSHKit.config.default_env = { foo: 'bar', over: 'under' }
65
67
  c = Command.new(:rails, 'server', env: { over: 'write'})
66
- assert_equal "( FOO=bar OVER=write /usr/bin/env rails server )", c.to_command
68
+ assert_equal %{( export FOO="bar" OVER="write" ; /usr/bin/env rails server )}, c.to_command
67
69
  end
68
70
 
69
71
  def test_working_in_a_given_directory
@@ -73,7 +75,7 @@ module SSHKit
73
75
 
74
76
  def test_working_in_a_given_directory_with_env
75
77
  c = Command.new(:ls, '-l', in: "/opt/sites", env: {a: :b})
76
- assert_equal "cd /opt/sites && ( A=b /usr/bin/env ls -l )", c.to_command
78
+ assert_equal %{cd /opt/sites && ( export A="b" ; /usr/bin/env ls -l )}, c.to_command
77
79
  end
78
80
 
79
81
  def test_having_a_host_passed
@@ -118,7 +120,7 @@ module SSHKit
118
120
  def test_umask_with_env_and_working_directory_and_user
119
121
  SSHKit.config.umask = '007'
120
122
  c = Command.new(:touch, 'somefile', user: 'bob', env: {a: 'b'}, in: '/var')
121
- assert_equal "cd /var && umask 007 && ( A=b sudo -u bob A=b -- sh -c '/usr/bin/env touch somefile' )", c.to_command
123
+ assert_equal %{cd /var && umask 007 && ( export A="b" ; sudo -u bob A="b" -- sh -c '/usr/bin/env touch somefile' )}, c.to_command
122
124
  end
123
125
 
124
126
  def test_verbosity_defaults_to_logger_info
@@ -163,16 +165,49 @@ module SSHKit
163
165
  assert c.failed?
164
166
  end
165
167
 
166
- def test_appending_stdout
168
+ def test_on_stdout
167
169
  c = Command.new(:whoami)
168
- assert c.stdout += "test\n"
169
- assert_equal "test\n", c.stdout
170
+ c.on_stdout(nil, "test\n")
171
+ c.on_stdout(nil, 'test2')
172
+ c.on_stdout(nil, 'test3')
173
+ assert_equal "test\ntest2test3", c.full_stdout
170
174
  end
171
175
 
172
- def test_appending_stderr
176
+ def test_on_stderr
177
+ c = Command.new(:whoami)
178
+ c.on_stderr(nil, 'test')
179
+ assert_equal 'test', c.full_stderr
180
+ end
181
+
182
+ def test_deprecated_stdtream_accessors
183
+ deprecation_out = ''
184
+ SSHKit.config.deprecation_output = deprecation_out
185
+
173
186
  c = Command.new(:whoami)
174
- assert c.stderr += "test\n"
175
- assert_equal "test\n", c.stderr
187
+ c.stdout='a test'
188
+ assert_equal('a test', c.stdout)
189
+ c.stderr='another test'
190
+ assert_equal('another test', c.stderr)
191
+ deprecation_lines = deprecation_out.lines.to_a
192
+
193
+ assert_equal 8, deprecation_lines.size
194
+ assert_equal(
195
+ '[Deprecated] The stdout= method on Command is deprecated. ' +
196
+ "The @stdout attribute will be removed in a future release.\n",
197
+ deprecation_lines[0])
198
+ assert_equal(
199
+ '[Deprecated] The stdout method on Command is deprecated. ' +
200
+ "The @stdout attribute will be removed in a future release. Use full_stdout() instead.\n",
201
+ deprecation_lines[2])
202
+
203
+ assert_equal(
204
+ '[Deprecated] The stderr= method on Command is deprecated. ' +
205
+ "The @stderr attribute will be removed in a future release.\n",
206
+ deprecation_lines[4])
207
+ assert_equal(
208
+ '[Deprecated] The stderr method on Command is deprecated. ' +
209
+ "The @stderr attribute will be removed in a future release. Use full_stderr() instead.\n",
210
+ deprecation_lines[6])
176
211
  end
177
212
 
178
213
  def test_setting_exit_status
@@ -4,10 +4,6 @@ require 'sshkit'
4
4
  module SSHKit
5
5
  class TestCommandMap < UnitTest
6
6
 
7
- def setup
8
- SSHKit.reset_configuration!
9
- end
10
-
11
7
  def test_defaults
12
8
  map = CommandMap.new
13
9
  assert_equal map[:rake], "/usr/bin/env rake"
@@ -5,11 +5,27 @@ module SSHKit
5
5
  class TestConfiguration < UnitTest
6
6
 
7
7
  def setup
8
- SSHKit.config = nil
8
+ super
9
9
  SSHKit.config.command_map.clear
10
10
  SSHKit.config.output = SSHKit::Formatter::Pretty.new($stdout)
11
11
  end
12
12
 
13
+ def test_deprecation_output
14
+ output = ''
15
+ SSHKit.config.deprecation_output = output
16
+ SSHKit.config.deprecation_logger.log('Test')
17
+ assert_equal "[Deprecated] Test\n", output.lines.first
18
+ end
19
+
20
+ def test_default_deprecation_output
21
+ SSHKit.config.deprecation_logger.log('Test')
22
+ end
23
+
24
+ def test_nil_deprecation_output
25
+ SSHKit.config.deprecation_output = nil
26
+ SSHKit.config.deprecation_logger.log('Test')
27
+ end
28
+
13
29
  def test_output
14
30
  assert SSHKit.config.output.is_a? SSHKit::Formatter::Pretty
15
31
  assert SSHKit.config.output = $stderr
@@ -51,14 +67,38 @@ module SSHKit
51
67
  assert_equal "/opt/sites/example/current/bin ruby", SSHKit.config.command_map[:ruby]
52
68
  end
53
69
 
54
- def test_setting_formatter_to_dot
55
- assert SSHKit.config.format = :dot
56
- assert SSHKit.config.output.is_a? SSHKit::Formatter::Dot
70
+ def test_setting_formatter_types
71
+ {
72
+ dot: SSHKit::Formatter::Dot,
73
+ blackhole: SSHKit::Formatter::BlackHole,
74
+ simpletext: SSHKit::Formatter::SimpleText,
75
+ }.each do |format, expected_class|
76
+ SSHKit.config.format = format
77
+ assert SSHKit.config.output.is_a? expected_class
78
+ end
57
79
  end
58
80
 
59
- def test_setting_formatter_to_blackhole
60
- assert SSHKit.config.format = :BlackHole
61
- assert SSHKit.config.output.is_a? SSHKit::Formatter::BlackHole
81
+ def test_prohibits_unknown_formatter_type_with_exception
82
+ assert_raises(NameError) do
83
+ SSHKit.config.format = :doesnotexist
84
+ end
85
+ end
86
+
87
+ def test_options_can_be_provided_to_formatter
88
+ SSHKit.config.use_format(TestFormatter, :color => false)
89
+ formatter = SSHKit.config.output
90
+ assert_instance_of(TestFormatter, formatter)
91
+ assert_equal($stdout, formatter.output)
92
+ assert_equal({ :color => false }, formatter.options)
93
+ end
94
+
95
+ class TestFormatter
96
+ attr_accessor :output, :options
97
+
98
+ def initialize(output, options={})
99
+ @output = output
100
+ @options = options
101
+ end
62
102
  end
63
103
  end
64
104
 
@@ -5,20 +5,16 @@ module SSHKit
5
5
 
6
6
  class TestCoordinator < UnitTest
7
7
 
8
- CloseEnough = 0.01; # 10 msec
9
-
10
8
  def setup
11
9
  super
12
- @s = String.new
10
+ @output = String.new
11
+ SSHKit.config.output_verbosity = :debug
12
+ SSHKit.config.output = SSHKit::Formatter::SimpleText.new(@output)
13
13
  SSHKit.config.backend = SSHKit::Backend::Printer
14
14
  end
15
15
 
16
- def tearddown
17
- @s = nil
18
- end
19
-
20
- def block_to_run
21
- lambda do |host|
16
+ def echo_time
17
+ lambda do |_host|
22
18
  execute "echo #{Time.now.to_f}"
23
19
  end
24
20
  end
@@ -42,69 +38,66 @@ module SSHKit
42
38
  end
43
39
 
44
40
  def test_the_connection_manager_yields_the_host_to_each_connection_instance
45
- spy = lambda do |host|
41
+ Coordinator.new(%w{1.example.com}).each do |host|
46
42
  execute "echo #{host.hostname}"
47
43
  end
48
- String.new.tap do |str|
49
- SSHKit.capture_output str do
50
- Coordinator.new(%w{1.example.com}).each &spy
51
- end
52
- assert_equal "/usr/bin/env echo 1.example.com", str.strip
53
- end
44
+ assert_equal "Command: echo 1.example.com\n", actual_output_commands.last
54
45
  end
55
46
 
56
47
  def test_the_connection_manaager_runs_things_in_parallel_by_default
57
- SSHKit.capture_output @s do
58
- Coordinator.new(%w{1.example.com 2.example.com}).each &block_to_run
59
- end
60
- assert_equal 2, results.length
61
- assert_in_delta *results, CloseEnough
48
+ Coordinator.new(%w{1.example.com 2.example.com}).each(&echo_time)
49
+ assert_equal 2, actual_execution_times.length
50
+ assert_within_10_ms(actual_execution_times)
62
51
  end
63
52
 
64
53
  def test_the_connection_manager_can_run_things_in_sequence
65
- SSHKit.capture_output @s do
66
- Coordinator.new(%w{1.example.com 2.example.com}).each in: :sequence, &block_to_run
67
- end
68
- assert_equal 2, results.length
69
- assert_operator (results.last - results.first), :>, 1.0
54
+ Coordinator.new(%w{1.example.com 2.example.com}).each in: :sequence, &echo_time
55
+ assert_equal 2, actual_execution_times.length
56
+ assert_at_least_1_sec_apart(actual_execution_times.first, actual_execution_times.last)
70
57
  end
71
58
 
72
59
  def test_the_connection_manager_can_run_things_in_sequence_with_wait
73
60
  start = Time.now
74
- SSHKit.capture_output @s do
75
- Coordinator.new(%w{1.example.com 2.example.com}).each in: :sequence, wait: 10, &block_to_run
76
- end
61
+ Coordinator.new(%w{1.example.com 2.example.com}).each in: :sequence, wait: 10, &echo_time
77
62
  stop = Time.now
78
- assert_operator (stop - start), :>=, 10.0
63
+ assert_operator(stop - start, :>=, 10.0)
79
64
  end
80
65
 
81
66
  def test_the_connection_manager_can_run_things_in_groups
82
- SSHKit.capture_output @s do
83
- Coordinator.new(
84
- %w{
85
- 1.example.com
86
- 2.example.com
87
- 3.example.com
88
- 4.example.com
89
- 5.example.com
90
- 6.example.com
91
- }
92
- ).each in: :groups, &block_to_run
93
- end
94
- assert_equal 6, results.length
95
- assert_in_delta *results[0..1], CloseEnough
96
- assert_in_delta *results[2..3], CloseEnough
97
- assert_in_delta *results[4..5], CloseEnough
98
- assert_operator (results[2] - results[1]), :>, 1.0
99
- assert_operator (results[4] - results[3]), :>, 1.0
67
+ Coordinator.new(
68
+ %w{
69
+ 1.example.com
70
+ 2.example.com
71
+ 3.example.com
72
+ 4.example.com
73
+ 5.example.com
74
+ 6.example.com
75
+ }
76
+ ).each in: :groups, &echo_time
77
+ assert_equal 6, actual_execution_times.length
78
+ assert_within_10_ms(actual_execution_times[0..1])
79
+ assert_within_10_ms(actual_execution_times[2..3])
80
+ assert_within_10_ms(actual_execution_times[4..5])
81
+ assert_at_least_1_sec_apart(actual_execution_times[1], actual_execution_times[2])
82
+ assert_at_least_1_sec_apart(actual_execution_times[3], actual_execution_times[4])
100
83
  end
101
84
 
102
85
  private
103
86
 
104
- def results
105
- @s.lines.collect do |line|
106
- line.split(' ').last.to_f
107
- end
87
+ def assert_at_least_1_sec_apart(first_time, last_time)
88
+ assert_operator(last_time - first_time, :>, 1.0)
89
+ end
90
+
91
+ def assert_within_10_ms(array)
92
+ assert_in_delta(*array, 0.01) # 10 msec
93
+ end
94
+
95
+ def actual_execution_times
96
+ actual_output_commands.map { |line| line.split(' ').last.to_f }
97
+ end
98
+
99
+ def actual_output_commands
100
+ @output.lines.select { |line| line.start_with?('Command:') }
108
101
  end
109
102
 
110
103
  end