beaker 7.2.2 → 7.3.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/.github/workflows/test.yml +7 -3
- data/.rubocop_todo.yml +19 -10
- data/CHANGELOG.md +14 -0
- data/acceptance/tests/base/dsl/helpers/host_helpers/retry_on_test.rb +8 -6
- data/beaker.gemspec +12 -1
- data/lib/beaker/dsl/helpers/host_helpers.rb +21 -16
- data/lib/beaker/host/unix/pkg.rb +2 -2
- data/lib/beaker/subcommand.rb +20 -9
- data/lib/beaker/version.rb +1 -1
- data/spec/beaker/dsl/helpers/host_helpers_spec.rb +17 -0
- data/spec/beaker/host/unix/pkg_spec.rb +2 -2
- data/spec/beaker/subcommand_spec.rb +97 -104
- metadata +46 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ddee4c17a106c817361dc58a101c0c98d6dba0a1eddab7f865856059eab87bdb
|
|
4
|
+
data.tar.gz: 4248053a457d1c41469bd825d4eef81b1ab2673ac6d30e8fd9ad292f2a4ead3d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f6471b11f4aa7b5dd6e78313d042cdb79bec4d4c15d6c18aff840bbd5e52deab4feb0c9b1a3acce934bf577a12b47688b7e8934a28d6619a7e149c4263ec8638
|
|
7
|
+
data.tar.gz: fb14fbffb4397d853e8cc048b4498af7b7cc96825d208356205caaf067f3e13a7dd9e4d27f97b43217c3948aec69f30233485b33e46ed5bca9ca0fdac600c7e8
|
data/.github/workflows/test.yml
CHANGED
|
@@ -20,12 +20,12 @@ jobs:
|
|
|
20
20
|
- name: Install Ruby ${{ matrix.ruby }}
|
|
21
21
|
uses: ruby/setup-ruby@v1
|
|
22
22
|
with:
|
|
23
|
-
ruby-version:
|
|
23
|
+
ruby-version: '4.0'
|
|
24
24
|
bundler-cache: true
|
|
25
25
|
- name: Run Rubocop
|
|
26
26
|
run: bundle exec rake rubocop
|
|
27
27
|
- id: ruby
|
|
28
|
-
uses: voxpupuli/ruby-version@
|
|
28
|
+
uses: voxpupuli/ruby-version@v2
|
|
29
29
|
|
|
30
30
|
test:
|
|
31
31
|
name: "Ruby ${{ matrix.ruby }}"
|
|
@@ -52,10 +52,14 @@ jobs:
|
|
|
52
52
|
run: bundle exec rake acceptance
|
|
53
53
|
|
|
54
54
|
tests:
|
|
55
|
+
if: always()
|
|
55
56
|
needs:
|
|
56
57
|
- rubocop_and_matrix
|
|
57
58
|
- test
|
|
58
59
|
runs-on: ubuntu-24.04
|
|
59
60
|
name: Test suite
|
|
60
61
|
steps:
|
|
61
|
-
-
|
|
62
|
+
- name: Decide whether the needed jobs succeeded or failed
|
|
63
|
+
uses: re-actors/alls-green@release/v1
|
|
64
|
+
with:
|
|
65
|
+
jobs: ${{ toJSON(needs) }}
|
data/.rubocop_todo.yml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# This configuration was generated by
|
|
2
2
|
# `rubocop --auto-gen-config --no-auto-gen-timestamp`
|
|
3
|
-
# using RuboCop version 1.
|
|
3
|
+
# using RuboCop version 1.81.7.
|
|
4
4
|
# The point is for the user to remove these configuration records
|
|
5
5
|
# one by one as the offenses are removed from the code base.
|
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
|
@@ -127,7 +127,7 @@ Performance/ZipWithoutBlock:
|
|
|
127
127
|
Exclude:
|
|
128
128
|
- 'spec/beaker/dsl/test_tagging_spec.rb'
|
|
129
129
|
|
|
130
|
-
# Offense count:
|
|
130
|
+
# Offense count: 18
|
|
131
131
|
RSpec/AnyInstance:
|
|
132
132
|
Exclude:
|
|
133
133
|
- 'spec/beaker/host/windows/file_spec.rb'
|
|
@@ -158,7 +158,7 @@ RSpec/Eq:
|
|
|
158
158
|
Exclude:
|
|
159
159
|
- 'spec/beaker/logger_spec.rb'
|
|
160
160
|
|
|
161
|
-
# Offense count:
|
|
161
|
+
# Offense count: 230
|
|
162
162
|
# Configuration parameters: CountAsOne.
|
|
163
163
|
RSpec/ExampleLength:
|
|
164
164
|
Max: 44
|
|
@@ -184,6 +184,7 @@ RSpec/InstanceVariable:
|
|
|
184
184
|
- 'spec/beaker/dsl/test_tagging_spec.rb'
|
|
185
185
|
|
|
186
186
|
# Offense count: 3
|
|
187
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
187
188
|
RSpec/IteratedExpectation:
|
|
188
189
|
Exclude:
|
|
189
190
|
- 'spec/beaker/dsl/helpers/host_helpers_spec.rb'
|
|
@@ -204,17 +205,25 @@ RSpec/LeakyConstantDeclaration:
|
|
|
204
205
|
- 'spec/beaker/host/windows/pkg_spec.rb'
|
|
205
206
|
- 'spec/beaker/options/hosts_file_parser_spec.rb'
|
|
206
207
|
|
|
208
|
+
# Offense count: 4
|
|
209
|
+
RSpec/LeakyLocalVariable:
|
|
210
|
+
Exclude:
|
|
211
|
+
- 'spec/beaker/dsl/test_tagging_spec.rb'
|
|
212
|
+
- 'spec/beaker/host/unix/pkg_spec.rb'
|
|
213
|
+
- 'spec/beaker/host_prebuilt_steps_spec.rb'
|
|
214
|
+
- 'spec/beaker/logger_spec.rb'
|
|
215
|
+
|
|
207
216
|
# Offense count: 1
|
|
208
217
|
RSpec/MultipleDescribes:
|
|
209
218
|
Exclude:
|
|
210
219
|
- 'spec/beaker/dsl/test_tagging_spec.rb'
|
|
211
220
|
|
|
212
|
-
# Offense count:
|
|
221
|
+
# Offense count: 141
|
|
213
222
|
# Configuration parameters: AllowSubject.
|
|
214
223
|
RSpec/MultipleMemoizedHelpers:
|
|
215
224
|
Max: 16
|
|
216
225
|
|
|
217
|
-
# Offense count:
|
|
226
|
+
# Offense count: 500
|
|
218
227
|
# Configuration parameters: EnforcedStyle, IgnoreSharedExamples.
|
|
219
228
|
# SupportedStyles: always, named_only
|
|
220
229
|
RSpec/NamedSubject:
|
|
@@ -231,7 +240,7 @@ RSpec/NoExpectationExample:
|
|
|
231
240
|
- 'spec/beaker/logger_spec.rb'
|
|
232
241
|
- 'spec/beaker/options/subcommand_options_parser_spec.rb'
|
|
233
242
|
|
|
234
|
-
# Offense count:
|
|
243
|
+
# Offense count: 60
|
|
235
244
|
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
236
245
|
RSpec/ReceiveMessages:
|
|
237
246
|
Exclude:
|
|
@@ -257,8 +266,8 @@ RSpec/RepeatedExample:
|
|
|
257
266
|
- 'spec/beaker/logger_spec.rb'
|
|
258
267
|
|
|
259
268
|
# Offense count: 14
|
|
260
|
-
# Configuration parameters:
|
|
261
|
-
#
|
|
269
|
+
# Configuration parameters: CustomTransform, IgnoreMethods, IgnoreMetadata, InflectorPath, EnforcedInflector.
|
|
270
|
+
# SupportedInflectors: default, active_support
|
|
262
271
|
RSpec/SpecFilePathFormat:
|
|
263
272
|
Exclude:
|
|
264
273
|
- '**/spec/routing/**/*'
|
|
@@ -277,7 +286,7 @@ RSpec/SpecFilePathFormat:
|
|
|
277
286
|
- 'spec/beaker/host/windows/user_spec.rb'
|
|
278
287
|
- 'spec/beaker/host_prebuilt_steps_spec.rb'
|
|
279
288
|
|
|
280
|
-
# Offense count:
|
|
289
|
+
# Offense count: 178
|
|
281
290
|
RSpec/SubjectStub:
|
|
282
291
|
Exclude:
|
|
283
292
|
- 'spec/beaker/dsl/assertions_spec.rb'
|
|
@@ -302,7 +311,7 @@ RSpec/UnspecifiedException:
|
|
|
302
311
|
- 'spec/beaker/host_spec.rb'
|
|
303
312
|
- 'spec/beaker/test_suite_spec.rb'
|
|
304
313
|
|
|
305
|
-
# Offense count:
|
|
314
|
+
# Offense count: 75
|
|
306
315
|
# Configuration parameters: IgnoreNameless, IgnoreSymbolicNames.
|
|
307
316
|
RSpec/VerifiedDoubles:
|
|
308
317
|
Enabled: false
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [7.3.0](https://github.com/voxpupuli/beaker/tree/7.3.0) (2026-01-06)
|
|
6
|
+
|
|
7
|
+
[Full Changelog](https://github.com/voxpupuli/beaker/compare/7.2.2...7.3.0)
|
|
8
|
+
|
|
9
|
+
**Implemented enhancements:**
|
|
10
|
+
|
|
11
|
+
- Remove `--force-yes` from apt commands [\#1982](https://github.com/voxpupuli/beaker/pull/1982) ([bwitt](https://github.com/bwitt))
|
|
12
|
+
- Lazily create options and state storage [\#1977](https://github.com/voxpupuli/beaker/pull/1977) ([ekohl](https://github.com/ekohl))
|
|
13
|
+
- Add Ruby 4.0 support [\#1976](https://github.com/voxpupuli/beaker/pull/1976) ([bastelfreak](https://github.com/bastelfreak))
|
|
14
|
+
|
|
15
|
+
**Fixed bugs:**
|
|
16
|
+
|
|
17
|
+
- Allow `retry_on` to work for host array [\#1983](https://github.com/voxpupuli/beaker/pull/1983) ([bwitt](https://github.com/bwitt))
|
|
18
|
+
|
|
5
19
|
## [7.2.2](https://github.com/voxpupuli/beaker/tree/7.2.2) (2025-12-19)
|
|
6
20
|
|
|
7
21
|
[Full Changelog](https://github.com/voxpupuli/beaker/compare/7.2.1...7.2.2)
|
|
@@ -24,10 +24,7 @@ test_name "dsl::helpers::host_helpers #retry_on" do
|
|
|
24
24
|
assert_equal "", result.stdout
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
step "#retry_on
|
|
28
|
-
# NOTE: would expect this to work across hosts, or be better documented and
|
|
29
|
-
# to raise Beaker::Host::CommandFailure
|
|
30
|
-
|
|
27
|
+
step "#retry_on works when provided a host array" do
|
|
31
28
|
remote_tmpdir = default.tmpdir
|
|
32
29
|
remote_script_file = File.join(remote_tmpdir, "test.sh")
|
|
33
30
|
|
|
@@ -36,8 +33,13 @@ test_name "dsl::helpers::host_helpers #retry_on" do
|
|
|
36
33
|
create_remote_file_from_fixture("retry_script", host, remote_tmpdir, "test.sh")
|
|
37
34
|
end
|
|
38
35
|
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
results = retry_on hosts, "bash #{remote_script_file} #{remote_tmpdir} 2", { :max_retries => 4, :retry_interval => 0.1 }
|
|
37
|
+
|
|
38
|
+
assert_kind_of Array, results
|
|
39
|
+
assert_equal hosts.length, results.length
|
|
40
|
+
results.each do |result|
|
|
41
|
+
assert_equal 0, result.exit_code
|
|
42
|
+
assert_equal "", result.stdout
|
|
41
43
|
end
|
|
42
44
|
end
|
|
43
45
|
end
|
data/beaker.gemspec
CHANGED
|
@@ -22,7 +22,7 @@ Gem::Specification.new do |s|
|
|
|
22
22
|
s.add_development_dependency 'fakefs', '>= 2.4', '< 4'
|
|
23
23
|
s.add_development_dependency 'rake', '~> 13.0'
|
|
24
24
|
s.add_development_dependency 'rspec', '~> 3.0'
|
|
25
|
-
s.add_development_dependency 'voxpupuli-rubocop', '~> 5.
|
|
25
|
+
s.add_development_dependency 'voxpupuli-rubocop', '~> 5.1.0'
|
|
26
26
|
|
|
27
27
|
# Run time dependencies
|
|
28
28
|
# Required for Ruby 3.3+ support
|
|
@@ -33,6 +33,17 @@ Gem::Specification.new do |s|
|
|
|
33
33
|
s.add_dependency 'minitest', '>= 5.4', '< 7'
|
|
34
34
|
s.add_dependency 'rexml', '~> 3.2', '>= 3.2.5'
|
|
35
35
|
|
|
36
|
+
# readline is a bundled gem since Ruby 4
|
|
37
|
+
s.add_dependency 'readline', '~> 0.0.4'
|
|
38
|
+
|
|
39
|
+
# YAML::PStore depends on pstore, which is a bundled gem since Ruby 4
|
|
40
|
+
# https://github.com/ruby/yaml/issues/69
|
|
41
|
+
s.add_dependency 'pstore', '< 1'
|
|
42
|
+
|
|
43
|
+
# net-ssh needs logger
|
|
44
|
+
# https://github.com/net-ssh/net-ssh/pull/984
|
|
45
|
+
s.add_dependency 'logger', '< 2'
|
|
46
|
+
|
|
36
47
|
# net-ssh compatibility with ed25519 keys
|
|
37
48
|
s.add_dependency 'bcrypt_pbkdf', '>= 1.0', '< 2.0'
|
|
38
49
|
s.add_dependency 'ed25519', '>= 1.2', '<2.0'
|
|
@@ -557,25 +557,30 @@ module Beaker
|
|
|
557
557
|
retry_interval = option_retry_interval == 0 ? 1 : option_retry_interval
|
|
558
558
|
verbose = true.to_s == opts[:verbose]
|
|
559
559
|
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
until desired_exit_codes.include?(result.exit_code)
|
|
568
|
-
sleep retry_interval
|
|
569
|
-
result = on(host, command, { :accept_all_exit_codes => true, :silent => !verbose }, &)
|
|
570
|
-
num_retries += 1
|
|
560
|
+
block_opts = {}
|
|
561
|
+
block_opts[:run_in_parallel] = opts[:run_in_parallel] if opts.key?(:run_in_parallel)
|
|
562
|
+
|
|
563
|
+
block_on host, block_opts do |single_host|
|
|
564
|
+
log_prefix = single_host.log_prefix
|
|
565
|
+
logger.debug "\n#{log_prefix} #{Time.new.strftime('%H:%M:%S')}$ #{command}"
|
|
566
|
+
logger.debug " Trying command #{max_retries} times."
|
|
571
567
|
logger.debug ".", add_newline: false
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
568
|
+
|
|
569
|
+
result = on(single_host, command, { :accept_all_exit_codes => true, :silent => !verbose }, &)
|
|
570
|
+
num_retries = 0
|
|
571
|
+
until desired_exit_codes.include?(result.exit_code)
|
|
572
|
+
sleep retry_interval
|
|
573
|
+
result = on(single_host, command, { :accept_all_exit_codes => true, :silent => !verbose }, &)
|
|
574
|
+
num_retries += 1
|
|
575
|
+
logger.debug ".", add_newline: false
|
|
576
|
+
if (num_retries > max_retries)
|
|
577
|
+
logger.debug " Command \`#{command}\` failed."
|
|
578
|
+
fail("Command \`#{command}\` failed.")
|
|
579
|
+
end
|
|
575
580
|
end
|
|
581
|
+
logger.debug "\n#{log_prefix} #{Time.new.strftime('%H:%M:%S')}$ #{command} ostensibly successful."
|
|
582
|
+
result
|
|
576
583
|
end
|
|
577
|
-
logger.debug "\n#{log_prefix} #{Time.new.strftime('%H:%M:%S')}$ #{command} ostensibly successful."
|
|
578
|
-
result
|
|
579
584
|
end
|
|
580
585
|
|
|
581
586
|
# FIX: this should be moved into host/platform
|
data/lib/beaker/host/unix/pkg.rb
CHANGED
|
@@ -96,7 +96,7 @@ module Unix::Pkg
|
|
|
96
96
|
when /ubuntu|debian/
|
|
97
97
|
name = "#{name}=#{version}" if version
|
|
98
98
|
update_apt_if_needed
|
|
99
|
-
execute("apt-get install
|
|
99
|
+
execute("apt-get install #{cmdline_args} -y #{name}", opts)
|
|
100
100
|
when /solaris-11/
|
|
101
101
|
if opts[:acceptable_exit_codes]
|
|
102
102
|
opts[:acceptable_exit_codes] << 4
|
|
@@ -204,7 +204,7 @@ module Unix::Pkg
|
|
|
204
204
|
execute("yum -y #{cmdline_args} update #{name}", opts)
|
|
205
205
|
when /ubuntu|debian/
|
|
206
206
|
update_apt_if_needed
|
|
207
|
-
execute("apt-get install -o Dpkg::Options::='--force-confold' #{cmdline_args} -y
|
|
207
|
+
execute("apt-get install -o Dpkg::Options::='--force-confold' #{cmdline_args} -y #{name}", opts)
|
|
208
208
|
when /solaris-11/
|
|
209
209
|
if opts[:acceptable_exit_codes]
|
|
210
210
|
opts[:acceptable_exit_codes] << 4
|
data/lib/beaker/subcommand.rb
CHANGED
|
@@ -10,9 +10,6 @@ module Beaker
|
|
|
10
10
|
|
|
11
11
|
def initialize(*args)
|
|
12
12
|
super
|
|
13
|
-
FileUtils.mkdir_p(SubcommandUtil::CONFIG_DIR)
|
|
14
|
-
FileUtils.touch(SubcommandUtil::SUBCOMMAND_OPTIONS) unless SubcommandUtil::SUBCOMMAND_OPTIONS.exist?
|
|
15
|
-
FileUtils.touch(SubcommandUtil::SUBCOMMAND_STATE) unless SubcommandUtil::SUBCOMMAND_STATE.exist?
|
|
16
13
|
@cli = Beaker::CLI.new
|
|
17
14
|
end
|
|
18
15
|
|
|
@@ -83,13 +80,13 @@ module Beaker
|
|
|
83
80
|
|
|
84
81
|
@cli.parse_options
|
|
85
82
|
|
|
83
|
+
# TODO: use options_storage?
|
|
86
84
|
options_to_write = SubcommandUtil.sanitize_options_for_save(@cli.configured_options)
|
|
87
85
|
|
|
88
86
|
@cli.logger.notify 'Writing configured options to disk'
|
|
89
|
-
|
|
87
|
+
SubcommandUtil::SUBCOMMAND_OPTIONS.write(options_to_write.to_yaml)
|
|
90
88
|
@cli.logger.notify "Options written to #{SubcommandUtil::SUBCOMMAND_OPTIONS}"
|
|
91
89
|
|
|
92
|
-
state = YAML::Store.new(SubcommandUtil::SUBCOMMAND_STATE)
|
|
93
90
|
state.transaction do
|
|
94
91
|
state['provisioned'] = false
|
|
95
92
|
end
|
|
@@ -108,7 +105,6 @@ module Beaker
|
|
|
108
105
|
return
|
|
109
106
|
end
|
|
110
107
|
|
|
111
|
-
state = YAML::Store.new(SubcommandUtil::SUBCOMMAND_STATE)
|
|
112
108
|
SubcommandUtil.error_with('Provisioned SUTs detected. Please destroy and reprovision.') if state.transaction { state['provisioned'] }
|
|
113
109
|
|
|
114
110
|
@cli.parse_options
|
|
@@ -125,7 +121,6 @@ module Beaker
|
|
|
125
121
|
|
|
126
122
|
# should we only update the options here with the new host? Or update the settings
|
|
127
123
|
# with whatever new flags may have been provided with provision?
|
|
128
|
-
options_storage = YAML::Store.new(SubcommandUtil::SUBCOMMAND_OPTIONS)
|
|
129
124
|
options_storage.transaction do
|
|
130
125
|
@cli.logger.notify 'updating HOSTS key in subcommand_options'
|
|
131
126
|
options_storage['HOSTS'] = cleaned_hosts
|
|
@@ -197,7 +192,6 @@ module Beaker
|
|
|
197
192
|
|
|
198
193
|
@cli.logger.notify 'updating HOSTS key in subcommand_options'
|
|
199
194
|
hosts = SubcommandUtil.sanitize_options_for_save(@cli.combined_instance_and_options_hosts)
|
|
200
|
-
options_storage = YAML::Store.new(SubcommandUtil::SUBCOMMAND_OPTIONS)
|
|
201
195
|
options_storage.transaction do
|
|
202
196
|
options_storage['HOSTS'] = hosts
|
|
203
197
|
end
|
|
@@ -214,7 +208,6 @@ module Beaker
|
|
|
214
208
|
return
|
|
215
209
|
end
|
|
216
210
|
|
|
217
|
-
state = YAML::Store.new(SubcommandUtil::SUBCOMMAND_STATE)
|
|
218
211
|
SubcommandUtil.error_with('Please provision an environment') unless state.transaction { state['provisioned'] }
|
|
219
212
|
|
|
220
213
|
@cli.parse_options
|
|
@@ -226,5 +219,23 @@ module Beaker
|
|
|
226
219
|
state.delete('provisioned')
|
|
227
220
|
end
|
|
228
221
|
end
|
|
222
|
+
|
|
223
|
+
no_commands do
|
|
224
|
+
private
|
|
225
|
+
|
|
226
|
+
def state
|
|
227
|
+
@state ||= begin
|
|
228
|
+
FileUtils.mkdir_p(SubcommandUtil::CONFIG_DIR)
|
|
229
|
+
YAML::Store.new(SubcommandUtil::SUBCOMMAND_STATE)
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
def options_storage
|
|
234
|
+
@options_storage ||= begin
|
|
235
|
+
FileUtils.mkdir_p(SubcommandUtil::CONFIG_DIR)
|
|
236
|
+
YAML::Store.new(SubcommandUtil::SUBCOMMAND_OPTIONS)
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
end
|
|
229
240
|
end
|
|
230
241
|
end
|
data/lib/beaker/version.rb
CHANGED
|
@@ -241,6 +241,23 @@ describe ClassMixedWithDSLHelpers do
|
|
|
241
241
|
result_given = subject.retry_on(host, command, opts)
|
|
242
242
|
expect(result_given.exit_code).to be === 0
|
|
243
243
|
end
|
|
244
|
+
|
|
245
|
+
it 'operates correctly when host is an array' do
|
|
246
|
+
result.stdout = 'stdout'
|
|
247
|
+
result.stderr = 'stderr'
|
|
248
|
+
result.exit_code = 0
|
|
249
|
+
|
|
250
|
+
opts = {
|
|
251
|
+
:max_retries => 5,
|
|
252
|
+
:retry_interval => 0.0001,
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
allow(subject).to receive(:on).and_return(result)
|
|
256
|
+
expect(subject).to receive(:on).exactly(hosts.length).times
|
|
257
|
+
|
|
258
|
+
results = subject.retry_on(hosts, command, opts)
|
|
259
|
+
expect(results).to eq(Array.new(hosts.length, result))
|
|
260
|
+
end
|
|
244
261
|
end
|
|
245
262
|
|
|
246
263
|
describe "shell" do
|
|
@@ -139,7 +139,7 @@ module Beaker
|
|
|
139
139
|
it "uses apt-get for #{platform}" do
|
|
140
140
|
@opts = { 'platform' => platform }
|
|
141
141
|
pkg = 'pkg'
|
|
142
|
-
expect(Beaker::Command).to receive(:new).with("apt-get install
|
|
142
|
+
expect(Beaker::Command).to receive(:new).with("apt-get install -y #{pkg}", [], { :prepend_cmds => nil, :cmdexe => false }).and_return('')
|
|
143
143
|
expect(instance).to receive(:exec).with('', {}).and_return(generate_result("hello", { :exit_code => 0 }))
|
|
144
144
|
expect(instance.install_package(pkg)).to eq "hello"
|
|
145
145
|
end
|
|
@@ -209,7 +209,7 @@ module Beaker
|
|
|
209
209
|
PlatformHelpers::DEBIANPLATFORMS.each do |platform|
|
|
210
210
|
it "calls the correct apt-get incantation for #{platform}" do
|
|
211
211
|
@opts = { 'platform' => platform }
|
|
212
|
-
expect(Beaker::Command).to receive(:new).with("apt-get install -o Dpkg::Options::='--force-confold' -y
|
|
212
|
+
expect(Beaker::Command).to receive(:new).with("apt-get install -o Dpkg::Options::='--force-confold' -y pkg", [], { :prepend_cmds => nil, :cmdexe => false }).and_return('')
|
|
213
213
|
expect(instance).to receive(:exec).with('', {}).and_return(generate_result("hello", { :exit_code => 0 }))
|
|
214
214
|
expect(instance.upgrade_package('pkg')).to eq "hello"
|
|
215
215
|
end
|
|
@@ -7,101 +7,97 @@ module Beaker
|
|
|
7
7
|
described_class.new
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
+
let(:mock_state) { double(YAML::Store) }
|
|
11
|
+
let(:mock_options_storage) { double(YAML::Store) }
|
|
12
|
+
|
|
10
13
|
describe '#initialize' do
|
|
11
14
|
it 'creates a cli object' do
|
|
12
15
|
expect(subcommand.cli).to be_instance_of(Beaker::CLI)
|
|
13
16
|
end
|
|
17
|
+
end
|
|
14
18
|
|
|
15
|
-
|
|
16
|
-
|
|
19
|
+
describe '#state' do
|
|
20
|
+
it 'ensures the parent directory exists' do
|
|
21
|
+
FakeFS.without do
|
|
17
22
|
expect(FileUtils).to receive(:mkdir_p).with(SubcommandUtil::CONFIG_DIR)
|
|
18
|
-
expect(
|
|
19
|
-
|
|
20
|
-
subcommand
|
|
23
|
+
expect(YAML::Store).to receive(:new).with(SubcommandUtil::SUBCOMMAND_STATE)
|
|
24
|
+
subcommand.send(:state)
|
|
21
25
|
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
22
28
|
|
|
23
|
-
|
|
29
|
+
describe '#options_storage' do
|
|
30
|
+
it 'ensures the parent directory exists' do
|
|
31
|
+
FakeFS.without do
|
|
24
32
|
expect(FileUtils).to receive(:mkdir_p).with(SubcommandUtil::CONFIG_DIR)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
expect(FileUtils).to receive(:touch).with(SubcommandUtil::SUBCOMMAND_OPTIONS)
|
|
28
|
-
expect(FileUtils).to receive(:touch).with(SubcommandUtil::SUBCOMMAND_STATE)
|
|
29
|
-
subcommand
|
|
33
|
+
expect(YAML::Store).to receive(:new).with(SubcommandUtil::SUBCOMMAND_OPTIONS)
|
|
34
|
+
subcommand.send(:options_storage)
|
|
30
35
|
end
|
|
31
36
|
end
|
|
32
37
|
end
|
|
33
38
|
|
|
34
39
|
context 'ensure that beaker options can be passed through' do
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
let(:yaml_store_mock) { double('yaml_store_mock') }
|
|
80
|
-
|
|
81
|
-
it 'does not error with valid beaker options' do
|
|
40
|
+
beaker_options_list = %w[
|
|
41
|
+
options-file
|
|
42
|
+
helper
|
|
43
|
+
load-path
|
|
44
|
+
tests
|
|
45
|
+
pre-suite
|
|
46
|
+
post-suite
|
|
47
|
+
pre-cleanup
|
|
48
|
+
provision
|
|
49
|
+
preserve-hosts
|
|
50
|
+
preserve-state
|
|
51
|
+
root-keys
|
|
52
|
+
keyfile
|
|
53
|
+
timeout
|
|
54
|
+
install
|
|
55
|
+
modules
|
|
56
|
+
quiet
|
|
57
|
+
color
|
|
58
|
+
color-host-output
|
|
59
|
+
log-level
|
|
60
|
+
log-prefix
|
|
61
|
+
dry-run
|
|
62
|
+
fail-mode
|
|
63
|
+
ntp
|
|
64
|
+
repo-proxy
|
|
65
|
+
package-proxy
|
|
66
|
+
validate
|
|
67
|
+
collect-perf-data
|
|
68
|
+
parse-only
|
|
69
|
+
tag
|
|
70
|
+
exclude-tags
|
|
71
|
+
xml-time-order
|
|
72
|
+
debug-errors
|
|
73
|
+
exec_manual_tests
|
|
74
|
+
test-tag-exclude
|
|
75
|
+
test-tag-and
|
|
76
|
+
test-tag-or
|
|
77
|
+
xml
|
|
78
|
+
type
|
|
79
|
+
debug
|
|
80
|
+
]
|
|
81
|
+
|
|
82
|
+
describe 'does not error with valid beaker option' do
|
|
82
83
|
beaker_options_list.each do |option|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
84
|
+
it option do
|
|
85
|
+
allow_any_instance_of(Beaker::CLI).to receive(:parse_options)
|
|
86
|
+
allow_any_instance_of(Beaker::CLI).to receive(:configured_options).and_return({})
|
|
87
|
+
|
|
88
|
+
allow_any_instance_of(described_class).to receive(:state).and_return(mock_state)
|
|
89
|
+
allow(mock_state).to receive(:transaction).and_yield
|
|
90
|
+
allow(mock_state).to receive(:[]=).with('provisioned', false)
|
|
91
|
+
allow(SubcommandUtil::SUBCOMMAND_OPTIONS).to receive(:write)
|
|
92
|
+
allow_any_instance_of(Beaker::Logger).to receive(:notify).twice
|
|
93
|
+
|
|
94
|
+
expect { described_class.start(['init', '--hosts', 'centos', "--#{option}"]) }.not_to output(/ERROR/).to_stderr
|
|
95
|
+
end
|
|
95
96
|
end
|
|
96
97
|
end
|
|
97
98
|
|
|
98
99
|
it "errors with a bad option here" do
|
|
99
|
-
|
|
100
|
-
allow(yaml_store_mock).to receive(:transaction).and_yield
|
|
101
|
-
allow(yaml_store_mock).to receive(:[]=).with('provisioned', false)
|
|
102
|
-
expect(File).not_to receive(:open)
|
|
103
|
-
expect(SubcommandUtil::SUBCOMMAND_OPTIONS).to receive(:exist?).and_return(true)
|
|
104
|
-
expect(SubcommandUtil::SUBCOMMAND_STATE).to receive(:exist?).and_return(true)
|
|
100
|
+
expect(SubcommandUtil::SUBCOMMAND_OPTIONS).not_to receive(:write)
|
|
105
101
|
expect { described_class.start(['init', '--hosts', 'centos', '--bad-option']) }.to output(/ERROR/).to_stderr
|
|
106
102
|
end
|
|
107
103
|
end
|
|
@@ -109,7 +105,6 @@ module Beaker
|
|
|
109
105
|
describe '#init' do
|
|
110
106
|
let(:cli) { subcommand.cli }
|
|
111
107
|
let(:mock_options) { { :timestamp => 'noon', :other_key => 'cordite' } }
|
|
112
|
-
let(:yaml_store_mock) { double('yaml_store_mock') }
|
|
113
108
|
|
|
114
109
|
before do
|
|
115
110
|
allow(cli).to receive(:parse_options)
|
|
@@ -117,34 +112,34 @@ module Beaker
|
|
|
117
112
|
end
|
|
118
113
|
|
|
119
114
|
it 'calculates options and writes them to disk and deletes the' do
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
expect(
|
|
115
|
+
expect(subcommand).to receive(:state).and_return(mock_state).twice
|
|
116
|
+
expect(mock_state).to receive(:transaction).and_yield
|
|
117
|
+
expect(mock_state).to receive(:[]=).with('provisioned', false)
|
|
118
|
+
expect(SubcommandUtil::SUBCOMMAND_OPTIONS).to receive(:write).with({ 'other_key' => 'cordite' }.to_yaml)
|
|
124
119
|
subcommand.init
|
|
125
|
-
expect(mock_options).not_to have_key(:timestamp)
|
|
126
120
|
end
|
|
127
121
|
|
|
128
122
|
it 'requires hosts flag' do
|
|
123
|
+
pending 'this was relying on FakeFS raising an exception'
|
|
129
124
|
expect { subcommand.init }.to raise_error(NotImplementedError)
|
|
130
125
|
end
|
|
131
126
|
end
|
|
132
127
|
|
|
133
128
|
describe '#provision' do
|
|
134
129
|
let(:cli) { subcommand.cli }
|
|
135
|
-
let(:yaml_store_mock) { double('yaml_store_mock') }
|
|
136
130
|
let(:host_hash) { { 'mynode.net' => { :name => 'mynode', :platform => Beaker::Platform.new('centos-6-x86_64') } } }
|
|
137
131
|
let(:cleaned_hosts) { double }
|
|
138
132
|
let(:yielded_host_hash) { double }
|
|
139
133
|
let(:yielded_host_name) { double }
|
|
140
|
-
let(:network_manager) { double(
|
|
134
|
+
let(:network_manager) { double(Beaker::NetworkManager) }
|
|
141
135
|
let(:hosts) { double('hosts') }
|
|
142
136
|
let(:hypervisors) { double('hypervisors') }
|
|
143
137
|
let(:options) { double('options') }
|
|
144
138
|
|
|
145
139
|
it 'provisions the host and saves the host info' do
|
|
146
|
-
|
|
147
|
-
|
|
140
|
+
allow(subcommand).to receive(:state).and_return(mock_state)
|
|
141
|
+
expect(mock_state).to receive(:transaction).and_yield
|
|
142
|
+
expect(mock_state).to receive(:[]).with('provisioned').and_return(false)
|
|
148
143
|
allow(cli).to receive(:preserve_hosts_file).and_return("/path/to/ho")
|
|
149
144
|
allow(cli).to receive(:network_manager).and_return(network_manager)
|
|
150
145
|
allow(cli).to receive(:options).and_return(options)
|
|
@@ -157,13 +152,14 @@ module Beaker
|
|
|
157
152
|
expect(SubcommandUtil).to receive(:sanitize_options_for_save).and_return(cleaned_hosts)
|
|
158
153
|
expect(cleaned_hosts).to receive(:each).and_yield(yielded_host_name, yielded_host_hash)
|
|
159
154
|
expect(yielded_host_hash).to receive(:[]=).with('provision', false)
|
|
160
|
-
|
|
155
|
+
allow(subcommand).to receive(:options_storage).and_return(mock_options_storage)
|
|
161
156
|
|
|
162
|
-
expect(
|
|
163
|
-
expect(
|
|
164
|
-
expect(
|
|
157
|
+
expect(mock_options_storage).to receive(:transaction).and_yield
|
|
158
|
+
expect(mock_options_storage).to receive(:[]=).with('HOSTS', cleaned_hosts)
|
|
159
|
+
expect(mock_options_storage).to receive(:[]=).with('hosts_preserved_yaml_file', "/path/to/hosts")
|
|
165
160
|
|
|
166
|
-
expect(
|
|
161
|
+
expect(mock_state).to receive(:transaction).and_yield
|
|
162
|
+
expect(mock_state).to receive(:[]=).with('provisioned', true)
|
|
167
163
|
subcommand.provision
|
|
168
164
|
end
|
|
169
165
|
|
|
@@ -182,11 +178,10 @@ module Beaker
|
|
|
182
178
|
|
|
183
179
|
let(:cleaned_hosts) { double }
|
|
184
180
|
let(:host_hash) { { 'mynode.net' => { :name => 'mynode', :platform => Beaker::Platform.new('centos-6-x86_64') } } }
|
|
185
|
-
let(:yaml_store_mock) { double('yaml_store_mock') }
|
|
186
181
|
|
|
187
182
|
it 'calls execute! when no resource is given' do
|
|
188
|
-
|
|
189
|
-
|
|
183
|
+
allow_any_instance_of(Pathname).to receive(:exist?).and_return(false)
|
|
184
|
+
allow_any_instance_of(Pathname).to receive(:directory?).and_return(false)
|
|
190
185
|
expect(subcommand.cli).to receive(:execute!).once
|
|
191
186
|
expect { subcommand.exec }.not_to raise_error
|
|
192
187
|
end
|
|
@@ -255,15 +250,14 @@ module Beaker
|
|
|
255
250
|
end
|
|
256
251
|
|
|
257
252
|
it 'updates the subcommand_options file with new host info if `preserve-state` is set' do
|
|
258
|
-
allow(yaml_store_mock).to receive(:[]).and_return(false)
|
|
259
253
|
allow(subcommand).to receive(:options).and_return('preserve-state' => true)
|
|
260
254
|
|
|
261
255
|
expect(subcommand.cli).to receive(:parse_options).and_return(subcommand.cli)
|
|
262
256
|
expect(subcommand.cli).to receive(:combined_instance_and_options_hosts).and_return(host_hash)
|
|
263
257
|
expect(SubcommandUtil).to receive(:sanitize_options_for_save).and_return(cleaned_hosts)
|
|
264
|
-
expect(
|
|
265
|
-
expect(
|
|
266
|
-
expect(
|
|
258
|
+
expect(subcommand).to receive(:options_storage).and_return(mock_options_storage).twice
|
|
259
|
+
expect(mock_options_storage).to receive(:transaction).and_yield.once
|
|
260
|
+
expect(mock_options_storage).to receive(:[]=).with('HOSTS', cleaned_hosts)
|
|
267
261
|
expect(subcommand.cli.logger).to receive(:notify)
|
|
268
262
|
|
|
269
263
|
subcommand.exec('tests')
|
|
@@ -280,8 +274,7 @@ module Beaker
|
|
|
280
274
|
context 'destroy' do
|
|
281
275
|
let(:cli) { subcommand.cli }
|
|
282
276
|
let(:mock_options) { { :timestamp => 'noon', :other_key => 'cordite' } }
|
|
283
|
-
let(:
|
|
284
|
-
let(:network_manager) { double('network_manager') }
|
|
277
|
+
let(:network_manager) { double(Beaker::NetworkManager) }
|
|
285
278
|
|
|
286
279
|
it 'calls destroy and updates the yaml store' do
|
|
287
280
|
allow(cli).to receive(:parse_options)
|
|
@@ -289,10 +282,10 @@ module Beaker
|
|
|
289
282
|
allow(cli).to receive(:network_manager).and_return(network_manager)
|
|
290
283
|
expect(network_manager).to receive(:cleanup)
|
|
291
284
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
285
|
+
allow(subcommand).to receive(:state).and_return(mock_state)
|
|
286
|
+
expect(mock_state).to receive(:transaction).and_yield.twice
|
|
287
|
+
expect(mock_state).to receive(:[]).with('provisioned').and_return(true)
|
|
288
|
+
expect(mock_state).to receive(:delete).with('provisioned').and_return(true)
|
|
296
289
|
expect(SubcommandUtil).to receive(:error_with).with("Please provision an environment").exactly(0).times
|
|
297
290
|
subcommand.destroy
|
|
298
291
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: beaker
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 7.
|
|
4
|
+
version: 7.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Puppet
|
|
@@ -64,14 +64,14 @@ dependencies:
|
|
|
64
64
|
requirements:
|
|
65
65
|
- - "~>"
|
|
66
66
|
- !ruby/object:Gem::Version
|
|
67
|
-
version: 5.
|
|
67
|
+
version: 5.1.0
|
|
68
68
|
type: :development
|
|
69
69
|
prerelease: false
|
|
70
70
|
version_requirements: !ruby/object:Gem::Requirement
|
|
71
71
|
requirements:
|
|
72
72
|
- - "~>"
|
|
73
73
|
- !ruby/object:Gem::Version
|
|
74
|
-
version: 5.
|
|
74
|
+
version: 5.1.0
|
|
75
75
|
- !ruby/object:Gem::Dependency
|
|
76
76
|
name: base64
|
|
77
77
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -172,6 +172,48 @@ dependencies:
|
|
|
172
172
|
- - ">="
|
|
173
173
|
- !ruby/object:Gem::Version
|
|
174
174
|
version: 3.2.5
|
|
175
|
+
- !ruby/object:Gem::Dependency
|
|
176
|
+
name: readline
|
|
177
|
+
requirement: !ruby/object:Gem::Requirement
|
|
178
|
+
requirements:
|
|
179
|
+
- - "~>"
|
|
180
|
+
- !ruby/object:Gem::Version
|
|
181
|
+
version: 0.0.4
|
|
182
|
+
type: :runtime
|
|
183
|
+
prerelease: false
|
|
184
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
185
|
+
requirements:
|
|
186
|
+
- - "~>"
|
|
187
|
+
- !ruby/object:Gem::Version
|
|
188
|
+
version: 0.0.4
|
|
189
|
+
- !ruby/object:Gem::Dependency
|
|
190
|
+
name: pstore
|
|
191
|
+
requirement: !ruby/object:Gem::Requirement
|
|
192
|
+
requirements:
|
|
193
|
+
- - "<"
|
|
194
|
+
- !ruby/object:Gem::Version
|
|
195
|
+
version: '1'
|
|
196
|
+
type: :runtime
|
|
197
|
+
prerelease: false
|
|
198
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
199
|
+
requirements:
|
|
200
|
+
- - "<"
|
|
201
|
+
- !ruby/object:Gem::Version
|
|
202
|
+
version: '1'
|
|
203
|
+
- !ruby/object:Gem::Dependency
|
|
204
|
+
name: logger
|
|
205
|
+
requirement: !ruby/object:Gem::Requirement
|
|
206
|
+
requirements:
|
|
207
|
+
- - "<"
|
|
208
|
+
- !ruby/object:Gem::Version
|
|
209
|
+
version: '2'
|
|
210
|
+
type: :runtime
|
|
211
|
+
prerelease: false
|
|
212
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
213
|
+
requirements:
|
|
214
|
+
- - "<"
|
|
215
|
+
- !ruby/object:Gem::Version
|
|
216
|
+
version: '2'
|
|
175
217
|
- !ruby/object:Gem::Dependency
|
|
176
218
|
name: bcrypt_pbkdf
|
|
177
219
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -698,7 +740,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
698
740
|
- !ruby/object:Gem::Version
|
|
699
741
|
version: '0'
|
|
700
742
|
requirements: []
|
|
701
|
-
rubygems_version:
|
|
743
|
+
rubygems_version: 4.0.3
|
|
702
744
|
specification_version: 4
|
|
703
745
|
summary: Let's test Puppet!
|
|
704
746
|
test_files: []
|