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.
- checksums.yaml +4 -4
- data/.travis.yml +2 -2
- data/BREAKING_API_WISHLIST.md +14 -0
- data/CHANGELOG.md +74 -0
- data/CONTRIBUTING.md +43 -0
- data/EXAMPLES.md +265 -169
- data/Gemfile +7 -0
- data/README.md +274 -9
- data/RELEASING.md +16 -8
- data/Rakefile +8 -0
- data/lib/sshkit.rb +0 -9
- data/lib/sshkit/all.rb +6 -4
- data/lib/sshkit/backends/abstract.rb +42 -42
- data/lib/sshkit/backends/connection_pool.rb +57 -8
- data/lib/sshkit/backends/local.rb +21 -50
- data/lib/sshkit/backends/netssh.rb +45 -98
- data/lib/sshkit/backends/printer.rb +3 -23
- data/lib/sshkit/backends/skipper.rb +4 -8
- data/lib/sshkit/color.rb +51 -20
- data/lib/sshkit/command.rb +68 -47
- data/lib/sshkit/configuration.rb +38 -5
- data/lib/sshkit/deprecation_logger.rb +17 -0
- data/lib/sshkit/formatters/abstract.rb +28 -4
- data/lib/sshkit/formatters/black_hole.rb +1 -2
- data/lib/sshkit/formatters/dot.rb +3 -10
- data/lib/sshkit/formatters/pretty.rb +31 -56
- data/lib/sshkit/formatters/simple_text.rb +6 -44
- data/lib/sshkit/host.rb +5 -6
- data/lib/sshkit/logger.rb +0 -1
- data/lib/sshkit/mapping_interaction_handler.rb +47 -0
- data/lib/sshkit/runners/parallel.rb +1 -1
- data/lib/sshkit/runners/sequential.rb +1 -1
- data/lib/sshkit/version.rb +1 -1
- data/sshkit.gemspec +0 -1
- data/test/functional/backends/test_local.rb +14 -1
- data/test/functional/backends/test_netssh.rb +58 -50
- data/test/helper.rb +2 -2
- data/test/unit/backends/test_abstract.rb +145 -0
- data/test/unit/backends/test_connection_pool.rb +27 -2
- data/test/unit/backends/test_printer.rb +47 -47
- data/test/unit/formatters/test_custom.rb +65 -0
- data/test/unit/formatters/test_dot.rb +25 -32
- data/test/unit/formatters/test_pretty.rb +114 -22
- data/test/unit/formatters/test_simple_text.rb +83 -0
- data/test/unit/test_color.rb +69 -5
- data/test/unit/test_command.rb +53 -18
- data/test/unit/test_command_map.rb +0 -4
- data/test/unit/test_configuration.rb +47 -7
- data/test/unit/test_coordinator.rb +45 -52
- data/test/unit/test_deprecation_logger.rb +38 -0
- data/test/unit/test_host.rb +3 -4
- data/test/unit/test_logger.rb +0 -1
- data/test/unit/test_mapping_interaction_handler.rb +101 -0
- metadata +37 -41
- data/lib/sshkit/utils/capture_output_methods.rb +0 -13
- 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
|
data/test/unit/test_color.rb
CHANGED
@@ -4,13 +4,77 @@ require 'sshkit'
|
|
4
4
|
module SSHKit
|
5
5
|
class TestColor < UnitTest
|
6
6
|
|
7
|
-
def
|
8
|
-
|
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
|
12
|
-
Color.
|
13
|
-
assert_equal
|
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
|
data/test/unit/test_command.rb
CHANGED
@@ -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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
168
|
+
def test_on_stdout
|
167
169
|
c = Command.new(:whoami)
|
168
|
-
|
169
|
-
|
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
|
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
|
-
|
175
|
-
assert_equal
|
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
|
@@ -5,11 +5,27 @@ module SSHKit
|
|
5
5
|
class TestConfiguration < UnitTest
|
6
6
|
|
7
7
|
def setup
|
8
|
-
|
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
|
55
|
-
|
56
|
-
|
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
|
60
|
-
|
61
|
-
|
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
|
-
@
|
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
|
17
|
-
|
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
|
-
|
41
|
+
Coordinator.new(%w{1.example.com}).each do |host|
|
46
42
|
execute "echo #{host.hostname}"
|
47
43
|
end
|
48
|
-
|
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
|
-
|
58
|
-
|
59
|
-
|
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
|
-
|
66
|
-
|
67
|
-
|
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
|
-
|
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
|
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
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
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
|
105
|
-
|
106
|
-
|
107
|
-
|
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
|