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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dca3fb90db4e3194bdfa41f3a445f855c392ec3cd132244f871626edd3b2dd87
4
- data.tar.gz: 14ddd5155906b74ee138228b6dc3dfb70ff0118835eaedb90b9bc1f49a09080c
3
+ metadata.gz: ddee4c17a106c817361dc58a101c0c98d6dba0a1eddab7f865856059eab87bdb
4
+ data.tar.gz: 4248053a457d1c41469bd825d4eef81b1ab2673ac6d30e8fd9ad292f2a4ead3d
5
5
  SHA512:
6
- metadata.gz: 28053a4ec06806e583e812aca81e284ec840f366d262fce57f612964a9c5e506ee479c5e75c8e4818994ce9dc9c6fb287c1bf97665b72270437b653b554650a8
7
- data.tar.gz: d70f5e46253a31a7b5228d66c20d539da33b220f5b1c673066f9c6ac382deca36b68fff307192c5f973c1fadf3c56bf1ffa0f434fd454053db9d9069b3ef05be
6
+ metadata.gz: f6471b11f4aa7b5dd6e78313d042cdb79bec4d4c15d6c18aff840bbd5e52deab4feb0c9b1a3acce934bf577a12b47688b7e8934a28d6619a7e149c4263ec8638
7
+ data.tar.gz: fb14fbffb4397d853e8cc048b4498af7b7cc96825d208356205caaf067f3e13a7dd9e4d27f97b43217c3948aec69f30233485b33e46ed5bca9ca0fdac600c7e8
@@ -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: "3.4"
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@v1
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
- - run: echo Test suite completed
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.79.2.
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: 17
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: 232
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: 140
221
+ # Offense count: 141
213
222
  # Configuration parameters: AllowSubject.
214
223
  RSpec/MultipleMemoizedHelpers:
215
224
  Max: 16
216
225
 
217
- # Offense count: 497
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: 58
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: Include, CustomTransform, IgnoreMethods, IgnoreMetadata.
261
- # Include: **/*_spec.rb
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: 176
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: 87
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 CURRENTLY fails when provided a host array" do
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
- assert_raises NoMethodError do
40
- retry_on hosts, "bash #{remote_script_file} #{remote_tmpdir} 2", { :max_retries => 4, :retry_interval => 0.1 }
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.0.0'
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
- log_prefix = host.log_prefix
561
- logger.debug "\n#{log_prefix} #{Time.new.strftime('%H:%M:%S')}$ #{command}"
562
- logger.debug " Trying command #{max_retries} times."
563
- logger.debug ".", add_newline: false
564
-
565
- result = on(host, command, { :accept_all_exit_codes => true, :silent => !verbose }, &)
566
- num_retries = 0
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
- if (num_retries > max_retries)
573
- logger.debug " Command \`#{command}\` failed."
574
- fail("Command \`#{command}\` failed.")
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
@@ -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 --force-yes #{cmdline_args} -y #{name}", opts)
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 --force-yes #{name}", opts)
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
@@ -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
- File.write(SubcommandUtil::SUBCOMMAND_OPTIONS, options_to_write.to_yaml)
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
@@ -1,5 +1,5 @@
1
1
  module Beaker
2
2
  module Version
3
- STRING = '7.2.2'
3
+ STRING = '7.3.0'
4
4
  end
5
5
  end
@@ -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 --force-yes -y #{pkg}", [], { :prepend_cmds => nil, :cmdexe => false }).and_return('')
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 --force-yes pkg", [], { :prepend_cmds => nil, :cmdexe => false }).and_return('')
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
- describe 'File operation initialization for subcommands' do
16
- it 'checks to ensure subcommand file resources exist' do
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(SubcommandUtil::SUBCOMMAND_OPTIONS).to receive(:exist?).and_return(true)
19
- expect(SubcommandUtil::SUBCOMMAND_STATE).to receive(:exist?).and_return(true)
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
- it 'touches the files when they do not exist' do
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
- allow(SubcommandUtil::SUBCOMMAND_OPTIONS).to receive(:exist?).and_return(false)
26
- allow(SubcommandUtil::SUBCOMMAND_STATE).to receive(:exist?).and_return(false)
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
- let(:beaker_options_list) do
36
- %w[
37
- options-file
38
- helper
39
- load-path
40
- tests
41
- pre-suite
42
- post-suite
43
- pre-cleanup
44
- provision
45
- preserve-hosts
46
- preserve-state
47
- root-keys
48
- keyfile
49
- timeout
50
- install
51
- modules
52
- quiet
53
- color
54
- color-host-output
55
- log-level
56
- log-prefix
57
- dry-run
58
- fail-mode
59
- ntp
60
- repo-proxy
61
- package-proxy
62
- validate
63
- collect-perf-data
64
- parse-only
65
- tag
66
- exclude-tags
67
- xml-time-order
68
- debug-errors
69
- exec_manual_tests
70
- test-tag-exclude
71
- test-tag-and
72
- test-tag-or
73
- xml
74
- type
75
- debug
76
- ]
77
- end
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
- allow_any_instance_of(Beaker::CLI).to receive(:parse_options)
84
- allow_any_instance_of(Beaker::CLI).to receive(:configured_options).and_return({})
85
-
86
- allow(YAML::Store).to receive(:new).with(SubcommandUtil::SUBCOMMAND_STATE).and_return(yaml_store_mock)
87
- allow(yaml_store_mock).to receive(:transaction).and_yield
88
- allow(yaml_store_mock).to receive(:[]=).with('provisioned', false)
89
- allow(File).to receive(:open)
90
- allow_any_instance_of(Beaker::Logger).to receive(:notify).twice
91
- expect(SubcommandUtil::SUBCOMMAND_OPTIONS).to receive(:exist?).and_return(true)
92
- expect(SubcommandUtil::SUBCOMMAND_STATE).to receive(:exist?).and_return(true)
93
-
94
- expect { described_class.start(['init', '--hosts', 'centos', "--#{option}"]) }.not_to output(/ERROR/).to_stderr
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
- allow(YAML::Store).to receive(:new).with(SubcommandUtil::SUBCOMMAND_STATE).and_return(yaml_store_mock)
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
- allow(File).to receive(:open)
121
- allow(YAML::Store).to receive(:new).with(SubcommandUtil::SUBCOMMAND_STATE).and_return(yaml_store_mock)
122
- allow(yaml_store_mock).to receive(:transaction).and_yield
123
- expect(yaml_store_mock).to receive(:[]=).with('provisioned', false)
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('network_manager') }
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
- expect(YAML::Store).to receive(:new).with(SubcommandUtil::SUBCOMMAND_STATE).and_return(yaml_store_mock)
147
- allow(yaml_store_mock).to receive(:[]).and_return(false)
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
- expect(YAML::Store).to receive(:new).with(SubcommandUtil::SUBCOMMAND_OPTIONS).and_return(yaml_store_mock)
155
+ allow(subcommand).to receive(:options_storage).and_return(mock_options_storage)
161
156
 
162
- expect(yaml_store_mock).to receive(:transaction).and_yield.exactly(3).times
163
- expect(yaml_store_mock).to receive(:[]=).with('HOSTS', cleaned_hosts)
164
- expect(yaml_store_mock).to receive(:[]=).with('hosts_preserved_yaml_file', "/path/to/hosts")
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(yaml_store_mock).to receive(:[]=).with('provisioned', true)
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
- expect_any_instance_of(Pathname).not_to receive(:directory?)
189
- expect_any_instance_of(Pathname).not_to receive(:exist?)
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(YAML::Store).to receive(:new).with(SubcommandUtil::SUBCOMMAND_OPTIONS).and_return(yaml_store_mock)
265
- expect(yaml_store_mock).to receive(:transaction).and_yield.once
266
- expect(yaml_store_mock).to receive(:[]=).with('HOSTS', cleaned_hosts)
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(:yaml_store_mock) { double('yaml_store_mock') }
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
- expect(YAML::Store).to receive(:new).with(SubcommandUtil::SUBCOMMAND_STATE).and_return(yaml_store_mock)
293
- allow(yaml_store_mock).to receive(:transaction).and_yield
294
- allow(yaml_store_mock).to receive(:[]).with('provisioned').and_return(true)
295
- allow(yaml_store_mock).to receive(:delete).with('provisioned').and_return(true)
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.2.2
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.0.0
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.0.0
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: 3.6.9
743
+ rubygems_version: 4.0.3
702
744
  specification_version: 4
703
745
  summary: Let's test Puppet!
704
746
  test_files: []