beaker 4.38.1 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +9 -0
- data/.github/workflows/release.yml +2 -2
- data/.github/workflows/test.yml +36 -11
- data/.rubocop.yml +75 -0
- data/.rubocop_todo.yml +239 -0
- data/CHANGELOG.md +88 -33
- data/Gemfile +16 -4
- data/HISTORY.md +103 -0
- data/Rakefile +101 -112
- data/acceptance/config/acceptance-options.rb +1 -1
- data/acceptance/config/base/acceptance-options.rb +2 -2
- data/acceptance/config/hypervisor/acceptance-options.rb +2 -2
- data/acceptance/config/subcommands/acceptance-options.rb +2 -2
- data/acceptance/fixtures/module/Gemfile +1 -1
- data/acceptance/fixtures/module/Rakefile +3 -3
- data/acceptance/fixtures/module/spec/acceptance/demo_spec.rb +16 -23
- data/acceptance/fixtures/module/spec/classes/init_spec.rb +1 -2
- data/acceptance/fixtures/module/spec/spec_helper_acceptance.rb +3 -5
- data/acceptance/lib/helpers/test_helper.rb +7 -6
- data/acceptance/pre_suite/subcommands/05_install_ruby.rb +2 -3
- data/acceptance/pre_suite/subcommands/08_install_beaker.rb +1 -2
- data/acceptance/tests/base/dsl/helpers/configuration_test.rb +4 -4
- data/acceptance/tests/base/dsl/helpers/hocon_helpers_test.rb +7 -8
- data/acceptance/tests/base/dsl/helpers/host_helpers/add_system32_hosts_entry_test.rb +0 -3
- data/acceptance/tests/base/dsl/helpers/host_helpers/archive_file_from_test.rb +9 -7
- data/acceptance/tests/base/dsl/helpers/host_helpers/backup_the_file_test.rb +15 -21
- data/acceptance/tests/base/dsl/helpers/host_helpers/check_for_package_test.rb +0 -4
- data/acceptance/tests/base/dsl/helpers/host_helpers/create_remote_file_test.rb +23 -30
- data/acceptance/tests/base/dsl/helpers/host_helpers/curl_on_test.rb +3 -3
- data/acceptance/tests/base/dsl/helpers/host_helpers/curl_with_retries_test.rb +0 -1
- data/acceptance/tests/base/dsl/helpers/host_helpers/on_test.rb +21 -16
- data/acceptance/tests/base/dsl/helpers/host_helpers/retry_on_test.rb +7 -7
- data/acceptance/tests/base/dsl/helpers/host_helpers/rsync_to_test.rb +30 -38
- data/acceptance/tests/base/dsl/helpers/host_helpers/run_cron_on_test.rb +14 -18
- data/acceptance/tests/base/dsl/helpers/host_helpers/run_script_on_test.rb +8 -14
- data/acceptance/tests/base/dsl/helpers/host_helpers/run_script_test.rb +7 -11
- data/acceptance/tests/base/dsl/helpers/host_helpers/scp_from_test.rb +5 -5
- data/acceptance/tests/base/dsl/helpers/host_helpers/scp_to_test.rb +4 -5
- data/acceptance/tests/base/dsl/helpers/host_helpers/shell_test.rb +8 -8
- data/acceptance/tests/base/dsl/helpers/host_helpers/upgrade_package_test.rb +4 -6
- data/acceptance/tests/base/dsl/platform_tag_confiner_test.rb +14 -17
- data/acceptance/tests/base/dsl/structure_test.rb +9 -21
- data/acceptance/tests/base/host/file_test.rb +8 -8
- data/acceptance/tests/base/host/group_test.rb +2 -3
- data/acceptance/tests/base/host/host_test.rb +69 -66
- data/acceptance/tests/base/host/packages.rb +27 -30
- data/acceptance/tests/base/host/packages_unix.rb +0 -55
- data/acceptance/tests/base/host/user_test.rb +2 -3
- data/acceptance/tests/base/host_prebuilt_steps/ssh_environment_test.rb +1 -2
- data/acceptance/tests/base/test_suite/export.rb +6 -9
- data/acceptance/tests/install/from_file.rb +3 -5
- data/acceptance/tests/load_path_bootstrap.rb +1 -1
- data/acceptance/tests/subcommands/destroy.rb +19 -21
- data/acceptance/tests/subcommands/exec.rb +0 -1
- data/acceptance/tests/subcommands/init.rb +2 -3
- data/acceptance/tests/subcommands/provision.rb +0 -1
- data/beaker.gemspec +10 -14
- data/docs/concepts/argument_processing_and_precedence.md +1 -10
- data/docs/concepts/style_guide.md +1 -1
- data/docs/how_to/debug_beaker_tests.md +13 -13
- data/docs/how_to/hosts/eos.md +2 -12
- data/docs/how_to/install_puppet.md +0 -18
- data/docs/how_to/test_arbitrary_beaker_versions.md +2 -2
- data/docs/how_to/the_beaker_dsl.md +0 -2
- data/lib/beaker/cli.rb +63 -74
- data/lib/beaker/command.rb +22 -30
- data/lib/beaker/command_factory.rb +4 -3
- data/lib/beaker/dsl/assertions.rb +7 -19
- data/lib/beaker/dsl/helpers/hocon_helpers.rb +5 -9
- data/lib/beaker/dsl/helpers/host_helpers.rb +72 -133
- data/lib/beaker/dsl/helpers/test_helpers.rb +3 -5
- data/lib/beaker/dsl/helpers/web_helpers.rb +20 -28
- data/lib/beaker/dsl/helpers.rb +2 -4
- data/lib/beaker/dsl/outcomes.rb +17 -19
- data/lib/beaker/dsl/patterns.rb +1 -3
- data/lib/beaker/dsl/roles.rb +18 -21
- data/lib/beaker/dsl/structure.rb +55 -67
- data/lib/beaker/dsl/test_tagging.rb +7 -10
- data/lib/beaker/dsl/wrappers.rb +15 -16
- data/lib/beaker/dsl.rb +2 -3
- data/lib/beaker/host/aix/exec.rb +1 -1
- data/lib/beaker/host/aix/file.rb +0 -1
- data/lib/beaker/host/aix/group.rb +3 -3
- data/lib/beaker/host/aix/user.rb +3 -3
- data/lib/beaker/host/aix.rb +3 -4
- data/lib/beaker/host/cisco.rb +36 -48
- data/lib/beaker/host/eos.rb +4 -30
- data/lib/beaker/host/freebsd/exec.rb +1 -1
- data/lib/beaker/host/freebsd/pkg.rb +3 -3
- data/lib/beaker/host/freebsd.rb +9 -12
- data/lib/beaker/host/mac/exec.rb +5 -5
- data/lib/beaker/host/mac/group.rb +13 -13
- data/lib/beaker/host/mac/pkg.rb +6 -109
- data/lib/beaker/host/mac/user.rb +7 -7
- data/lib/beaker/host/mac.rb +8 -9
- data/lib/beaker/host/pswindows/exec.rb +70 -74
- data/lib/beaker/host/pswindows/file.rb +4 -6
- data/lib/beaker/host/pswindows/group.rb +5 -5
- data/lib/beaker/host/pswindows/pkg.rb +17 -17
- data/lib/beaker/host/pswindows/user.rb +4 -4
- data/lib/beaker/host/pswindows.rb +4 -3
- data/lib/beaker/host/unix/exec.rb +86 -88
- data/lib/beaker/host/unix/file.rb +41 -47
- data/lib/beaker/host/unix/group.rb +3 -3
- data/lib/beaker/host/unix/pkg.rb +158 -421
- data/lib/beaker/host/unix/user.rb +4 -4
- data/lib/beaker/host/unix.rb +18 -20
- data/lib/beaker/host/windows/exec.rb +20 -20
- data/lib/beaker/host/windows/file.rb +5 -5
- data/lib/beaker/host/windows/group.rb +5 -5
- data/lib/beaker/host/windows/pkg.rb +6 -57
- data/lib/beaker/host/windows/user.rb +4 -4
- data/lib/beaker/host/windows.rb +13 -13
- data/lib/beaker/host.rb +82 -139
- data/lib/beaker/host_prebuilt_steps.rb +121 -233
- data/lib/beaker/hypervisor/noop.rb +2 -4
- data/lib/beaker/hypervisor.rb +46 -63
- data/lib/beaker/local_connection.rb +4 -6
- data/lib/beaker/logger.rb +71 -85
- data/lib/beaker/logger_junit.rb +22 -26
- data/lib/beaker/network_manager.rb +40 -43
- data/lib/beaker/options/command_line_parser.rb +12 -23
- data/lib/beaker/options/hosts_file_parser.rb +34 -25
- data/lib/beaker/options/options_file_parser.rb +3 -6
- data/lib/beaker/options/options_hash.rb +3 -10
- data/lib/beaker/options/parser.rb +89 -105
- data/lib/beaker/options/presets.rb +114 -123
- data/lib/beaker/options/subcommand_options_file_parser.rb +3 -6
- data/lib/beaker/options/validator.rb +26 -31
- data/lib/beaker/perf.rb +29 -34
- data/lib/beaker/platform.rb +38 -46
- data/lib/beaker/result.rb +7 -6
- data/lib/beaker/shared/error_handler.rb +8 -10
- data/lib/beaker/shared/fog_credentials.rb +5 -9
- data/lib/beaker/shared/host_manager.rb +40 -46
- data/lib/beaker/shared/options_resolver.rb +3 -7
- data/lib/beaker/shared/repetition.rb +6 -8
- data/lib/beaker/shared/semvar.rb +39 -43
- data/lib/beaker/shared/timed.rb +2 -5
- data/lib/beaker/shared.rb +1 -1
- data/lib/beaker/ssh_connection.rb +46 -55
- data/lib/beaker/subcommand.rb +23 -30
- data/lib/beaker/subcommands/subcommand_util.rb +4 -4
- data/lib/beaker/tasks/quick_start.rb +5 -10
- data/lib/beaker/tasks/rake_task.rb +26 -28
- data/lib/beaker/tasks/test.rb +4 -4
- data/lib/beaker/test_case.rb +15 -27
- data/lib/beaker/test_suite.rb +35 -39
- data/lib/beaker/test_suite_result.rb +52 -57
- data/lib/beaker/version.rb +1 -1
- data/lib/beaker.rb +5 -6
- data/spec/beaker/cli_spec.rb +135 -153
- data/spec/beaker/command_spec.rb +64 -58
- data/spec/beaker/dsl/assertions_spec.rb +38 -47
- data/spec/beaker/dsl/helpers/host_helpers_spec.rb +114 -135
- data/spec/beaker/dsl/helpers/test_helpers_spec.rb +9 -10
- data/spec/beaker/dsl/helpers/web_helpers_spec.rb +30 -36
- data/spec/beaker/dsl/outcomes_spec.rb +15 -14
- data/spec/beaker/dsl/roles_spec.rb +170 -132
- data/spec/beaker/dsl/structure_spec.rb +181 -163
- data/spec/beaker/dsl/test_tagging_spec.rb +94 -95
- data/spec/beaker/dsl/wrappers_spec.rb +39 -40
- data/spec/beaker/host/aix_spec.rb +14 -14
- data/spec/beaker/host/cisco_spec.rb +92 -102
- data/spec/beaker/host/eos_spec.rb +15 -36
- data/spec/beaker/host/freebsd/exec_spec.rb +5 -8
- data/spec/beaker/host/freebsd/pkg_spec.rb +29 -29
- data/spec/beaker/host/mac/exec_spec.rb +4 -5
- data/spec/beaker/host/mac/group_spec.rb +47 -56
- data/spec/beaker/host/mac/user_spec.rb +53 -62
- data/spec/beaker/host/pswindows/exec_spec.rb +36 -35
- data/spec/beaker/host/pswindows/file_spec.rb +21 -18
- data/spec/beaker/host/pswindows/user_spec.rb +17 -23
- data/spec/beaker/host/pswindows_spec.rb +14 -14
- data/spec/beaker/host/unix/exec_spec.rb +87 -92
- data/spec/beaker/host/unix/file_spec.rb +76 -82
- data/spec/beaker/host/unix/pkg_spec.rb +165 -407
- data/spec/beaker/host/unix_spec.rb +11 -207
- data/spec/beaker/host/windows/exec_spec.rb +32 -34
- data/spec/beaker/host/windows/file_spec.rb +22 -23
- data/spec/beaker/host/windows/group_spec.rb +17 -19
- data/spec/beaker/host/windows/pkg_spec.rb +10 -13
- data/spec/beaker/host/windows/user_spec.rb +17 -23
- data/spec/beaker/host/windows_spec.rb +39 -39
- data/spec/beaker/host_prebuilt_steps_spec.rb +193 -341
- data/spec/beaker/host_spec.rb +241 -312
- data/spec/beaker/hypervisor/hypervisor_spec.rb +38 -63
- data/spec/beaker/localhost_connection_spec.rb +14 -13
- data/spec/beaker/logger_junit_spec.rb +22 -34
- data/spec/beaker/logger_spec.rb +174 -155
- data/spec/beaker/network_manager_spec.rb +27 -27
- data/spec/beaker/options/command_line_parser_spec.rb +20 -23
- data/spec/beaker/options/data/hosts_preserved.yml +395 -0
- data/spec/beaker/options/hosts_file_parser_spec.rb +36 -31
- data/spec/beaker/options/options_file_parser_spec.rb +4 -7
- data/spec/beaker/options/options_hash_spec.rb +7 -9
- data/spec/beaker/options/parser_spec.rb +187 -187
- data/spec/beaker/options/presets_spec.rb +8 -10
- data/spec/beaker/options/subcommand_options_parser_spec.rb +15 -15
- data/spec/beaker/options/validator_spec.rb +27 -28
- data/spec/beaker/perf_spec.rb +32 -34
- data/spec/beaker/platform_spec.rb +27 -37
- data/spec/beaker/shared/error_handler_spec.rb +8 -17
- data/spec/beaker/shared/fog_credentials_spec.rb +30 -30
- data/spec/beaker/shared/host_manager_spec.rb +55 -89
- data/spec/beaker/shared/options_resolver_spec.rb +9 -12
- data/spec/beaker/shared/repetition_spec.rb +24 -31
- data/spec/beaker/shared/semvar_spec.rb +21 -26
- data/spec/beaker/ssh_connection_spec.rb +85 -90
- data/spec/beaker/subcommand/subcommand_util_spec.rb +40 -37
- data/spec/beaker/subcommand_spec.rb +89 -89
- data/spec/beaker/test_case_spec.rb +33 -62
- data/spec/beaker/test_suite_spec.rb +153 -160
- data/spec/helpers.rb +48 -53
- data/spec/matchers.rb +9 -8
- data/spec/mocks.rb +6 -11
- data/spec/spec_helper.rb +0 -4
- metadata +60 -85
- data/acceptance/tests/base/dsl/helpers/host_helpers/deploy_package_repo_test.rb +0 -142
- data/acceptance/tests/base/external_resources_test.rb +0 -31
- data/spec/beaker/host/mac_spec.rb +0 -113
- data/spec/mock_fission.rb +0 -60
- data/spec/mock_vsphere.rb +0 -314
- data/spec/mock_vsphere_helper.rb +0 -183
@@ -4,11 +4,9 @@ require 'net/scp'
|
|
4
4
|
|
5
5
|
module Beaker
|
6
6
|
class SshConnection
|
7
|
+
attr_accessor :logger, :ip, :vmhostname, :hostname, :ssh_connection_preference
|
7
8
|
|
8
|
-
|
9
|
-
attr_accessor :ip, :vmhostname, :hostname, :ssh_connection_preference
|
10
|
-
|
11
|
-
SUPPORTED_CONNECTION_METHODS = [:ip, :vmhostname, :hostname]
|
9
|
+
SUPPORTED_CONNECTION_METHODS = %i[ip vmhostname hostname]
|
12
10
|
|
13
11
|
RETRYABLE_EXCEPTIONS = [
|
14
12
|
SocketError,
|
@@ -67,18 +65,18 @@ module Beaker
|
|
67
65
|
wait = 3
|
68
66
|
max_connection_tries = options[:max_connection_tries] || 11
|
69
67
|
begin
|
70
|
-
|
68
|
+
@logger.debug "Attempting ssh connection to #{host}, user: #{user}, opts: #{ssh_opts}"
|
71
69
|
|
72
|
-
|
73
|
-
|
74
|
-
|
70
|
+
# Work around net-ssh 6+ incompatibilities
|
71
|
+
if ssh_opts.include?(:strict_host_key_checking) && (Net::SSH::Version::CURRENT.major > 5)
|
72
|
+
strict_host_key_checking = ssh_opts.delete(:strict_host_key_checking)
|
75
73
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
74
|
+
unless ssh_opts[:verify_host_key].is_a?(Symbol)
|
75
|
+
ssh_opts[:verify_host_key] ||= strict_host_key_checking ? :always : :never
|
76
|
+
end
|
77
|
+
end
|
80
78
|
|
81
|
-
|
79
|
+
Net::SSH.start(host, user, ssh_opts)
|
82
80
|
rescue *RETRYABLE_EXCEPTIONS => e
|
83
81
|
if try <= max_connection_tries
|
84
82
|
@logger.warn "Try #{try} -- Host #{host} unreachable: #{e.class.name} - #{e.message}" unless options[:silent]
|
@@ -105,16 +103,14 @@ module Beaker
|
|
105
103
|
# Try three ways to connect to host (vmhostname, ip, hostname)
|
106
104
|
# Try each method in turn until we succeed
|
107
105
|
methods = @ssh_connection_preference.dup
|
108
|
-
while (not @ssh) && (not methods.empty?)
|
109
|
-
|
110
|
-
if SUPPORTED_CONNECTION_METHODS.include?(methods[0])
|
111
|
-
@ssh = connect_block(instance_variable_get("@#{methods[0].to_s}"), @user, @ssh_opts, options)
|
112
|
-
else
|
113
|
-
@logger.warn "Beaker does not support #{methods[0]} to SSH to host, trying next available method."
|
114
|
-
@ssh_connection_preference.delete(methods[0])
|
115
|
-
end
|
116
|
-
else
|
106
|
+
while (not @ssh) && (not methods.empty?)
|
107
|
+
if instance_variable_get("@#{methods[0]}").nil?
|
117
108
|
@logger.warn "Skipping #{methods[0]} method to ssh to host as its value is not set. Refer to https://github.com/puppetlabs/beaker/tree/master/docs/how_to/ssh_connection_preference.md to remove this warning"
|
109
|
+
elsif SUPPORTED_CONNECTION_METHODS.include?(methods[0])
|
110
|
+
@ssh = connect_block(instance_variable_get("@#{methods[0]}"), @user, @ssh_opts, options)
|
111
|
+
else
|
112
|
+
@logger.warn "Beaker does not support #{methods[0]} to SSH to host, trying next available method."
|
113
|
+
@ssh_connection_preference.delete(methods[0])
|
118
114
|
end
|
119
115
|
methods.shift
|
120
116
|
end
|
@@ -157,30 +153,31 @@ module Beaker
|
|
157
153
|
try = 1
|
158
154
|
last_wait = 2
|
159
155
|
wait = 3
|
160
|
-
command = 'echo echo' #can be run on all platforms (I'm looking at you, windows)
|
156
|
+
command = 'echo echo' # can be run on all platforms (I'm looking at you, windows)
|
161
157
|
while try < 11
|
162
158
|
result = Result.new(@hostname, command)
|
163
159
|
begin
|
164
160
|
@logger.notify "Waiting for connection failure on #{@hostname} (attempt #{try}, try again in #{wait} second(s))"
|
165
161
|
@logger.debug("\n#{@hostname} #{Time.new.strftime('%H:%M:%S')}$ #{command}")
|
166
162
|
@ssh.open_channel do |channel|
|
167
|
-
request_terminal_for(
|
163
|
+
request_terminal_for(channel, command) if options[:pty]
|
168
164
|
|
169
165
|
channel.exec(command) do |terminal, success|
|
170
166
|
raise Net::SSH::Exception.new("FAILED: to execute command on a new channel on #{@hostname}") unless success
|
167
|
+
|
171
168
|
register_stdout_for terminal, result, stdout_callback
|
172
169
|
register_stderr_for terminal, result, stderr_callback
|
173
170
|
register_exit_code_for terminal, result
|
174
171
|
|
175
|
-
process_stdin_for(
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
172
|
+
process_stdin_for(terminal, options[:stdin]) if options[:stdin]
|
173
|
+
end
|
174
|
+
end
|
175
|
+
loop_tries = 0
|
176
|
+
# loop is actually loop_forever, so let it try 3 times and then quit instead of endless blocking
|
177
|
+
@ssh.loop { loop_tries += 1; loop_tries < 4 }
|
181
178
|
rescue *RETRYABLE_EXCEPTIONS => e
|
182
179
|
@logger.debug "Connection on #{@hostname} failed as expected (#{e.class.name} - #{e.message})"
|
183
|
-
close #this connection is bad, shut it down
|
180
|
+
close # this connection is bad, shut it down
|
184
181
|
return true
|
185
182
|
end
|
186
183
|
slept = 0
|
@@ -198,20 +195,21 @@ module Beaker
|
|
198
195
|
end
|
199
196
|
|
200
197
|
def try_to_execute command, options = {}, stdout_callback = nil,
|
201
|
-
|
198
|
+
stderr_callback = stdout_callback
|
202
199
|
|
203
200
|
result = Result.new(@hostname, command)
|
204
201
|
|
205
202
|
@ssh.open_channel do |channel|
|
206
|
-
request_terminal_for(
|
203
|
+
request_terminal_for(channel, command) if options[:pty]
|
207
204
|
|
208
205
|
channel.exec(command) do |terminal, success|
|
209
206
|
raise Net::SSH::Exception.new("FAILED: to execute command on a new channel on #{@hostname}") unless success
|
207
|
+
|
210
208
|
register_stdout_for terminal, result, stdout_callback
|
211
209
|
register_stderr_for terminal, result, stderr_callback
|
212
210
|
register_exit_code_for terminal, result
|
213
211
|
|
214
|
-
process_stdin_for(
|
212
|
+
process_stdin_for(terminal, options[:stdin]) if options[:stdin]
|
215
213
|
end
|
216
214
|
end
|
217
215
|
|
@@ -243,7 +241,7 @@ module Beaker
|
|
243
241
|
end
|
244
242
|
|
245
243
|
def request_terminal_for channel, command
|
246
|
-
channel.request_pty do |
|
244
|
+
channel.request_pty do |_ch, success|
|
247
245
|
if success
|
248
246
|
@logger.debug "Allocated a PTY on #{@hostname} for #{command.inspect}"
|
249
247
|
else
|
@@ -254,7 +252,7 @@ module Beaker
|
|
254
252
|
end
|
255
253
|
|
256
254
|
def register_stdout_for channel, output, callback = nil
|
257
|
-
channel.on_data do |
|
255
|
+
channel.on_data do |_ch, data|
|
258
256
|
callback[data] if callback
|
259
257
|
output.stdout << data
|
260
258
|
output.output << data
|
@@ -262,7 +260,7 @@ module Beaker
|
|
262
260
|
end
|
263
261
|
|
264
262
|
def register_stderr_for channel, output, callback = nil
|
265
|
-
channel.on_extended_data do |
|
263
|
+
channel.on_extended_data do |_ch, type, data|
|
266
264
|
if type == 1
|
267
265
|
callback[data] if callback
|
268
266
|
output.stderr << data
|
@@ -272,7 +270,7 @@ module Beaker
|
|
272
270
|
end
|
273
271
|
|
274
272
|
def register_exit_code_for channel, output
|
275
|
-
channel.on_request("exit-status") do |
|
273
|
+
channel.on_request("exit-status") do |_ch, data|
|
276
274
|
output.exit_code = data.read_long
|
277
275
|
end
|
278
276
|
end
|
@@ -288,11 +286,8 @@ module Beaker
|
|
288
286
|
end
|
289
287
|
|
290
288
|
def scp_to source, target, options = {}
|
291
|
-
|
292
289
|
local_opts = options.dup
|
293
|
-
if local_opts[:recursive].nil?
|
294
|
-
local_opts[:recursive] = File.directory?(source)
|
295
|
-
end
|
290
|
+
local_opts[:recursive] = File.directory?(source) if local_opts[:recursive].nil?
|
296
291
|
local_opts[:chunk_size] ||= 16384
|
297
292
|
|
298
293
|
result = Result.new(@hostname, [source, target])
|
@@ -301,18 +296,17 @@ module Beaker
|
|
301
296
|
begin
|
302
297
|
# This is probably windows with an environment variable so we need to
|
303
298
|
# expand it.
|
304
|
-
target = self.execute(%{echo "#{target}"}).output.strip.
|
299
|
+
target = self.execute(%{echo "#{target}"}).output.strip.delete('"') if target.include?('%')
|
305
300
|
|
306
|
-
@ssh.scp.upload! source, target, local_opts do |
|
307
|
-
result.stdout << "\tcopying %s: %10d/%d\n"
|
301
|
+
@ssh.scp.upload! source, target, local_opts do |_ch, name, sent, total|
|
302
|
+
result.stdout << (format("\tcopying %s: %10d/%d\n", name, sent, total))
|
308
303
|
end
|
309
304
|
rescue => e
|
310
305
|
logger.warn "#{e.class} error in scp'ing. Forcing the connection to close, which should " <<
|
311
|
-
|
306
|
+
"raise an error."
|
312
307
|
close
|
313
308
|
end
|
314
309
|
|
315
|
-
|
316
310
|
# Setting these values allows reporting via result.log(test_name)
|
317
311
|
result.stdout << " SCP'ed file #{source} to #{@hostname}:#{target}"
|
318
312
|
|
@@ -324,11 +318,8 @@ module Beaker
|
|
324
318
|
end
|
325
319
|
|
326
320
|
def scp_from source, target, options = {}
|
327
|
-
|
328
321
|
local_opts = options.dup
|
329
|
-
if local_opts[:recursive].nil?
|
330
|
-
local_opts[:recursive] = true
|
331
|
-
end
|
322
|
+
local_opts[:recursive] = true if local_opts[:recursive].nil?
|
332
323
|
local_opts[:chunk_size] ||= 16384
|
333
324
|
|
334
325
|
result = Result.new(@hostname, [source, target])
|
@@ -337,14 +328,14 @@ module Beaker
|
|
337
328
|
begin
|
338
329
|
# This is probably windows with an environment variable so we need to
|
339
330
|
# expand it.
|
340
|
-
source = self.execute(%{echo "#{source}"}).output.strip.
|
331
|
+
source = self.execute(%{echo "#{source}"}).output.strip.delete('"') if source.include?('%')
|
341
332
|
|
342
|
-
@ssh.scp.download! source, target, local_opts do |
|
343
|
-
result.stdout << "\tcopying %s: %10d/%d\n"
|
333
|
+
@ssh.scp.download! source, target, local_opts do |_ch, name, sent, total|
|
334
|
+
result.stdout << (format("\tcopying %s: %10d/%d\n", name, sent, total))
|
344
335
|
end
|
345
336
|
rescue => e
|
346
337
|
logger.warn "#{e.class} error in scp'ing. Forcing the connection to close, which should " <<
|
347
|
-
|
338
|
+
"raise an error."
|
348
339
|
close
|
349
340
|
end
|
350
341
|
|
data/lib/beaker/subcommand.rb
CHANGED
@@ -28,7 +28,7 @@ module Beaker
|
|
28
28
|
class_option :'pre-suite', :type => :string, :group => 'Beaker run'
|
29
29
|
class_option :'post-suite', :type => :string, :group => 'Beaker run'
|
30
30
|
class_option :'pre-cleanup', :type => :string, :group => 'Beaker run'
|
31
|
-
class_option :
|
31
|
+
class_option :provision, :type => :boolean, :group => 'Beaker run'
|
32
32
|
class_option :'preserve-hosts', :type => :string, :group => 'Beaker run'
|
33
33
|
class_option :'preserve-state', :type => :boolean, :group => 'Beaker run'
|
34
34
|
class_option :'root-keys', :type => :boolean, :group => 'Beaker run'
|
@@ -46,16 +46,15 @@ module Beaker
|
|
46
46
|
class_option :'test-results-file', :type => :string, :group => 'Beaker run'
|
47
47
|
class_option :ntp, :type => :boolean, :group => 'Beaker run'
|
48
48
|
class_option :'repo-proxy', :type => :boolean, :group => 'Beaker run'
|
49
|
-
class_option :'add-el-extras', :type => :boolean, :group => 'Beaker run'
|
50
49
|
class_option :'package-proxy', :type => :string, :group => 'Beaker run'
|
51
|
-
class_option :
|
50
|
+
class_option :validate, :type => :boolean, :group => 'Beaker run'
|
52
51
|
class_option :'collect-perf-data', :type => :boolean, :group => 'Beaker run'
|
53
52
|
class_option :'parse-only', :type => :boolean, :group => 'Beaker run'
|
54
53
|
class_option :tag, :type => :string, :group => 'Beaker run'
|
55
54
|
class_option :'exclude-tags', :type => :string, :group => 'Beaker run'
|
56
55
|
class_option :'xml-time-order', :type => :boolean, :group => 'Beaker run'
|
57
56
|
class_option :'debug-errors', :type => :boolean, :group => 'Beaker run'
|
58
|
-
class_option :
|
57
|
+
class_option :exec_manual_tests, :type => :boolean, :group => 'Beaker run'
|
59
58
|
class_option :'test-tag-exclude', :type => :string, :group => 'Beaker run'
|
60
59
|
class_option :'test-tag-and', :type => :string, :group => 'Beaker run'
|
61
60
|
class_option :'test-tag-or', :type => :string, :group => 'Beaker run'
|
@@ -76,7 +75,7 @@ module Beaker
|
|
76
75
|
LONGDESC
|
77
76
|
option :help, :type => :boolean, :hide => true
|
78
77
|
method_option :hosts, :aliases => '-h', :type => :string, :required => true
|
79
|
-
def init
|
78
|
+
def init
|
80
79
|
if options[:help]
|
81
80
|
invoke :help, [], ["init"]
|
82
81
|
return
|
@@ -87,9 +86,7 @@ module Beaker
|
|
87
86
|
options_to_write = SubcommandUtil.sanitize_options_for_save(@cli.configured_options)
|
88
87
|
|
89
88
|
@cli.logger.notify 'Writing configured options to disk'
|
90
|
-
File.
|
91
|
-
f.write(options_to_write.to_yaml)
|
92
|
-
end
|
89
|
+
File.write(SubcommandUtil::SUBCOMMAND_OPTIONS, options_to_write.to_yaml)
|
93
90
|
@cli.logger.notify "Options written to #{SubcommandUtil::SUBCOMMAND_OPTIONS}"
|
94
91
|
|
95
92
|
state = YAML::Store.new(SubcommandUtil::SUBCOMMAND_STATE)
|
@@ -105,16 +102,14 @@ module Beaker
|
|
105
102
|
flag here to override.
|
106
103
|
LONGDESC
|
107
104
|
option :help, :type => :boolean, :hide => true
|
108
|
-
def provision
|
105
|
+
def provision
|
109
106
|
if options[:help]
|
110
107
|
invoke :help, [], ["provision"]
|
111
108
|
return
|
112
109
|
end
|
113
110
|
|
114
111
|
state = YAML::Store.new(SubcommandUtil::SUBCOMMAND_STATE)
|
115
|
-
if state.transaction { state['provisioned']}
|
116
|
-
SubcommandUtil.error_with('Provisioned SUTs detected. Please destroy and reprovision.')
|
117
|
-
end
|
112
|
+
SubcommandUtil.error_with('Provisioned SUTs detected. Please destroy and reprovision.') if state.transaction { state['provisioned'] }
|
118
113
|
|
119
114
|
@cli.parse_options
|
120
115
|
@cli.provision
|
@@ -124,7 +119,7 @@ module Beaker
|
|
124
119
|
|
125
120
|
# Update each host provisioned with a flag indicating that it no longer needs
|
126
121
|
# provisioning
|
127
|
-
cleaned_hosts.each do |
|
122
|
+
cleaned_hosts.each do |_host, host_hash|
|
128
123
|
host_hash['provision'] = false
|
129
124
|
end
|
130
125
|
|
@@ -154,7 +149,7 @@ module Beaker
|
|
154
149
|
such as: exec pre-suite,tests
|
155
150
|
LONG_DESC
|
156
151
|
option :help, :type => :boolean, :hide => true
|
157
|
-
def exec(resource=nil)
|
152
|
+
def exec(resource = nil)
|
158
153
|
if options[:help]
|
159
154
|
invoke :help, [], ["exec"]
|
160
155
|
return
|
@@ -168,7 +163,7 @@ module Beaker
|
|
168
163
|
return
|
169
164
|
end
|
170
165
|
|
171
|
-
beaker_suites = [
|
166
|
+
beaker_suites = %i[pre_suite tests post_suite pre_cleanup]
|
172
167
|
resources = resource.split(',')
|
173
168
|
paths = resources.map { |r| Pathname(r) }
|
174
169
|
if paths.all?(&:exist?)
|
@@ -186,11 +181,11 @@ module Beaker
|
|
186
181
|
path.to_s
|
187
182
|
end
|
188
183
|
end.flatten
|
189
|
-
elsif resources.all? { |r|
|
184
|
+
elsif resources.all? { |r| /^(pre-suite|tests|post-suite|pre-cleanup)$/.match?(r) }
|
190
185
|
# The regex match here is loose so that users can supply multiple suites,
|
191
186
|
# such as `beaker exec pre-suite,tests`.
|
192
187
|
beaker_suites.each do |suite|
|
193
|
-
@cli.options[suite] = [] unless resource.
|
188
|
+
@cli.options[suite] = [] unless resource.tr('-', '_').match(suite.to_s)
|
194
189
|
end
|
195
190
|
else
|
196
191
|
raise ArgumentError, "Unable to parse #{resource} with beaker exec"
|
@@ -198,13 +193,13 @@ module Beaker
|
|
198
193
|
|
199
194
|
@cli.execute!
|
200
195
|
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
196
|
+
return unless options['preserve-state']
|
197
|
+
|
198
|
+
@cli.logger.notify 'updating HOSTS key in subcommand_options'
|
199
|
+
hosts = SubcommandUtil.sanitize_options_for_save(@cli.combined_instance_and_options_hosts)
|
200
|
+
options_storage = YAML::Store.new(SubcommandUtil::SUBCOMMAND_OPTIONS)
|
201
|
+
options_storage.transaction do
|
202
|
+
options_storage['HOSTS'] = hosts
|
208
203
|
end
|
209
204
|
end
|
210
205
|
|
@@ -213,25 +208,23 @@ module Beaker
|
|
213
208
|
Destroys the currently provisioned VMs
|
214
209
|
LONG_DESC
|
215
210
|
option :help, :type => :boolean, :hide => true
|
216
|
-
def destroy
|
211
|
+
def destroy
|
217
212
|
if options[:help]
|
218
213
|
invoke :help, [], ["destroy"]
|
219
214
|
return
|
220
215
|
end
|
221
216
|
|
222
217
|
state = YAML::Store.new(SubcommandUtil::SUBCOMMAND_STATE)
|
223
|
-
unless state.transaction { state['provisioned']}
|
224
|
-
SubcommandUtil.error_with('Please provision an environment')
|
225
|
-
end
|
218
|
+
SubcommandUtil.error_with('Please provision an environment') unless state.transaction { state['provisioned'] }
|
226
219
|
|
227
220
|
@cli.parse_options
|
228
221
|
@cli.options[:provision] = false
|
229
222
|
@cli.initialize_network_manager
|
230
223
|
@cli.network_manager.cleanup
|
231
224
|
|
232
|
-
state.transaction
|
225
|
+
state.transaction do
|
233
226
|
state.delete('provisioned')
|
234
|
-
|
227
|
+
end
|
235
228
|
end
|
236
229
|
end
|
237
230
|
end
|
@@ -17,10 +17,11 @@ module Beaker
|
|
17
17
|
PERSISTED_HOSTS = Pathname("#{CONFIG_DIR}/.hosts.yaml")
|
18
18
|
PERSISTED_HYPERVISORS = Pathname("#{CONFIG_DIR}/.hypervisors.yaml")
|
19
19
|
# These options should not be part of persisted subcommand state
|
20
|
-
UNPERSISTED_OPTIONS = [
|
20
|
+
UNPERSISTED_OPTIONS = %i[beaker_version command_line hosts_file logger password_prompt timestamp]
|
21
21
|
|
22
22
|
def self.execute_subcommand?(arg0)
|
23
23
|
return false if arg0.nil?
|
24
|
+
|
24
25
|
(Beaker::Subcommand.instance_methods(false) << :help).include? arg0.to_sym
|
25
26
|
end
|
26
27
|
|
@@ -46,9 +47,9 @@ module Beaker
|
|
46
47
|
end
|
47
48
|
|
48
49
|
# Print a message to the console and exit with specified exit code, defaults to 1
|
49
|
-
#
|
50
|
+
# @param [String] msg the message to output
|
50
51
|
# @param [Hash<Object>] options to specify exit code or output stack trace
|
51
|
-
def self.error_with(msg, options={})
|
52
|
+
def self.error_with(msg, options = {})
|
52
53
|
puts msg
|
53
54
|
puts options[:stack_trace] if options[:stack_trace]
|
54
55
|
exit_code = options[:exit_code] ? options[:exit_code] : 1
|
@@ -68,7 +69,6 @@ module Beaker
|
|
68
69
|
$stderr = old_stderr
|
69
70
|
end
|
70
71
|
end
|
71
|
-
|
72
72
|
end
|
73
73
|
end
|
74
74
|
end
|
@@ -3,14 +3,13 @@ require 'beaker-hostgenerator'
|
|
3
3
|
CONFIG_DIR = 'acceptance/config'
|
4
4
|
|
5
5
|
VAGRANT = ['ubuntu1404-64default.mdcal-ubuntu1404-64af', '--hypervisor=vagrant',
|
6
|
-
'--global-config={box_url=https://vagrantcloud.com/puppetlabs/boxes/ubuntu-14.04-64-nocm,box=puppetlabs/ubuntu-14.04-64-nocm}']
|
6
|
+
'--global-config={box_url=https://vagrantcloud.com/puppetlabs/boxes/ubuntu-14.04-64-nocm,box=puppetlabs/ubuntu-14.04-64-nocm}',]
|
7
7
|
|
8
8
|
VMPOOLER = ['redhat7-64default.mdcal-redhat7-64af']
|
9
9
|
|
10
10
|
namespace :beaker_quickstart do
|
11
|
-
|
12
11
|
desc 'Generate Default Beaker Host Config File, valid options are: vmpooler or vagrant.'
|
13
|
-
task :gen_hosts, [:hypervisor] do |
|
12
|
+
task :gen_hosts, [:hypervisor] do |_t, args|
|
14
13
|
hosts_file = "#{CONFIG_DIR}/default_#{args[:hypervisor]}_hosts.yaml"
|
15
14
|
if args[:hypervisor] == 'vagrant'
|
16
15
|
cli = VAGRANT
|
@@ -33,7 +32,6 @@ namespace :beaker_quickstart do
|
|
33
32
|
end
|
34
33
|
end
|
35
34
|
|
36
|
-
|
37
35
|
desc 'Generate Default Pre-Suite'
|
38
36
|
task :gen_pre_suite do
|
39
37
|
pre_suite_file = "acceptance/setup/default_pre_suite.rb"
|
@@ -71,20 +69,17 @@ end")
|
|
71
69
|
|
72
70
|
desc 'Run Default Smoke Test, after generating default host config and test files, valid options are: vmpooler or vagrant.'
|
73
71
|
task :run_test, [:hypervisor] => ["beaker_quickstart:gen_hosts", 'beaker_quickstart:gen_pre_suite',
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
system_args = Hash.new
|
72
|
+
'beaker_quickstart:gen_smoke_test',] do |_t, args|
|
73
|
+
hypervisor = args[:hypervisor] ||= 'vagrant'
|
74
|
+
system_args = {}
|
78
75
|
system_args[:hosts] = "acceptance/config/default_#{hypervisor}_hosts.yaml"
|
79
76
|
system_args[:pre_suite] = 'acceptance/setup/default_pre_suite.rb'
|
80
77
|
system_args[:tests] = 'acceptance/tests/default_smoke_test.rb'
|
81
78
|
puts "About to run - #{beaker_command(system_args)}"
|
82
79
|
system(beaker_command(system_args))
|
83
80
|
end
|
84
|
-
|
85
81
|
end
|
86
82
|
|
87
|
-
|
88
83
|
def beaker_command(system_args)
|
89
84
|
cmd_parts = []
|
90
85
|
cmd_parts << "beaker"
|
@@ -3,7 +3,6 @@ require 'rake/tasklib'
|
|
3
3
|
require 'rake'
|
4
4
|
require 'beaker'
|
5
5
|
|
6
|
-
|
7
6
|
module Beaker
|
8
7
|
module Tasks
|
9
8
|
class RakeTask < ::Rake::TaskLib
|
@@ -11,17 +10,17 @@ module Beaker
|
|
11
10
|
|
12
11
|
DEFAULT_ACCEPTANCE_ROOT = "./acceptance"
|
13
12
|
|
14
|
-
COMMAND_OPTIONS = [
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
13
|
+
COMMAND_OPTIONS = %i[fail_mode
|
14
|
+
hosts
|
15
|
+
helper
|
16
|
+
keyfile
|
17
|
+
log_level
|
18
|
+
options_file
|
19
|
+
preserve_hosts
|
20
|
+
tests
|
21
|
+
type
|
22
|
+
acceptance_root
|
23
|
+
name]
|
25
24
|
# iterates of acceptable params
|
26
25
|
COMMAND_OPTIONS.each do |sym|
|
27
26
|
attr_accessor(sym.to_sym)
|
@@ -31,16 +30,17 @@ module Beaker
|
|
31
30
|
# @param args [Array] First argument is always the name of the task
|
32
31
|
# if no additonal arguments are defined such as parameters it will default to [:hosts,:type]
|
33
32
|
def initialize(*args, &task_block)
|
33
|
+
super
|
34
|
+
|
34
35
|
@name = args.shift || 'beaker:test'
|
35
|
-
if args.empty?
|
36
|
-
args = [:hosts,:type]
|
37
|
-
end
|
36
|
+
args = %i[hosts type] if args.empty?
|
38
37
|
@acceptance_root = DEFAULT_ACCEPTANCE_ROOT
|
39
38
|
@options_file = nil
|
40
39
|
define(args, &task_block)
|
41
40
|
end
|
42
41
|
|
43
42
|
private
|
43
|
+
|
44
44
|
# Run the task provided, implements the rake task interface
|
45
45
|
#
|
46
46
|
# @param verbose [bool] Defines wether to run in verbose mode or not
|
@@ -51,10 +51,10 @@ module Beaker
|
|
51
51
|
command = beaker_command
|
52
52
|
puts command if verbose
|
53
53
|
success = system(command)
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
54
|
+
return unless fail_mode == "fast" && !success
|
55
|
+
|
56
|
+
$stderr.puts "#{command} failed"
|
57
|
+
exit $?.exitstatus
|
58
58
|
end
|
59
59
|
|
60
60
|
# @private
|
@@ -64,7 +64,7 @@ module Beaker
|
|
64
64
|
.application.last_comment)
|
65
65
|
task name, *args do |_, task_args|
|
66
66
|
RakeFileUtils.__send__(:verbose, verbose) do
|
67
|
-
|
67
|
+
yield(*[self, task_args].slice(0, task_block.arity)) if task_block
|
68
68
|
run_task verbose
|
69
69
|
end
|
70
70
|
end
|
@@ -75,19 +75,17 @@ module Beaker
|
|
75
75
|
# if no other options file is provided
|
76
76
|
#
|
77
77
|
def check_for_beaker_type_config
|
78
|
-
|
79
|
-
|
80
|
-
|
78
|
+
return unless !@options_file && File.exist?("#{@acceptance_root}/.beaker-#{@type}.cfg")
|
79
|
+
|
80
|
+
@options_file = File.join(@acceptance_root, ".beaker-#{@type}.cfg")
|
81
81
|
end
|
82
82
|
|
83
83
|
#
|
84
84
|
# Check for existence of ENV variables for test if !@tests is undef
|
85
85
|
#
|
86
86
|
def check_env_variables
|
87
|
-
if File.
|
88
|
-
|
89
|
-
end
|
90
|
-
@tests = ENV['TESTS'] || ENV['TEST'] if !@tests
|
87
|
+
@tests = File.join(DEFAULT_ACCEPTANCE_ROOT, 'tests') if File.exist?(File.join(DEFAULT_ACCEPTANCE_ROOT, 'tests'))
|
88
|
+
@tests = ENV['TESTS'] || ENV.fetch('TEST', nil) if !@tests
|
91
89
|
end
|
92
90
|
|
93
91
|
#
|
@@ -97,7 +95,7 @@ module Beaker
|
|
97
95
|
cmd_parts = []
|
98
96
|
cmd_parts << "beaker"
|
99
97
|
cmd_parts << "--keyfile #{@keyfile}" if @keyfile
|
100
|
-
cmd_parts << "--hosts #{@hosts}" if (@hosts!=nil && !@hosts.empty?)
|
98
|
+
cmd_parts << "--hosts #{@hosts}" if (@hosts != nil && !@hosts.empty?)
|
101
99
|
cmd_parts << "--tests #{tests}" if @tests
|
102
100
|
cmd_parts << "--options-file #{@options_file}" if @options_file
|
103
101
|
cmd_parts << "--type #{@type}" if @type
|
data/lib/beaker/tasks/test.rb
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
require 'beaker/tasks/rake_task'
|
2
2
|
|
3
|
-
Beaker::Tasks::RakeTask.new do |t,args|
|
3
|
+
Beaker::Tasks::RakeTask.new do |t, args|
|
4
4
|
t.type = args[:type]
|
5
5
|
t.hosts = args[:hosts]
|
6
6
|
end
|
7
7
|
|
8
8
|
desc "Run Beaker PE tests"
|
9
|
-
Beaker::Tasks::RakeTask.new("beaker:test:pe"
|
9
|
+
Beaker::Tasks::RakeTask.new("beaker:test:pe", :hosts) do |t, args|
|
10
10
|
t.type = 'pe'
|
11
11
|
t.hosts = args[:hosts]
|
12
12
|
end
|
13
13
|
|
14
14
|
desc "Run Beaker Git tests"
|
15
|
-
Beaker::Tasks::RakeTask.new("beaker:test:git"
|
15
|
+
Beaker::Tasks::RakeTask.new("beaker:test:git", :hosts) do |t, args|
|
16
16
|
t.type = 'git'
|
17
17
|
t.hosts = args[:hosts]
|
18
|
-
end
|
18
|
+
end
|