sshkit 1.7.1 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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