beaker 4.18.0 → 4.19.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: 9a6ffdf30249cf3d13af3ce8bb88668c0c50a06861a43a2c6cf34f026dd937dd
4
- data.tar.gz: 9bbedea15bd4815259b9df3ac75e410106d8a052c91bb5aabf6f595d4b327863
3
+ metadata.gz: 8a1ffd36126ef1c3aa4bc3fc1ad93dab786f7c8a67bc01749020e063c0d6642b
4
+ data.tar.gz: b4c320f7acf05904d85b899b1d7ea6e51a6097b5dae317eec0f3c4a6df533ac3
5
5
  SHA512:
6
- metadata.gz: 32ffc2eff47d6233e8176ef570e9fa063620d122b43ff383ad4169de4956ee5e0103fec99d9d1d029b3beae47ba82e5678e34f99cff3a555fd0a033bf7b42bb9
7
- data.tar.gz: 27206ea065b9382a9b5e2b85fdb469d7116ec8ee310e881118047886206faecd6987621d3781e827bfddfe7ab5ea7292184bc2608779c21e47ccfe79af9534aa
6
+ metadata.gz: d9ba01bffcfe9cfe356ff06bc294d32d248283b01e943139582d346fe7566a5ed8b4fe5ae5715ff1de57253f20a44eba3c50649c9876f4399aaf000ef53d64ad
7
+ data.tar.gz: b48a94b96ed04579fcb27842a69de75a70adf0c9fe93a5210b93a476321ce9139e4d3cb4bf9376f8708e6fd9f170bc83f863c0381a13a393b97d34c35ac37d89
@@ -11,7 +11,35 @@ Tracking in this Changelog began for this project in version 3.25.0.
11
11
  If you're looking for changes from before this, refer to the project's
12
12
  git logs & PR history.
13
13
 
14
- # [Unreleased](https://github.com/puppetlabs/beaker/compare/4.18.0...master)
14
+ The headers used in [Keep a Changelog](http://keepachangelog.com) are:
15
+
16
+ - Added - for new features.
17
+ - Changed - for changes in existing functionality.
18
+ - Deprecated - for soon-to-be removed features.
19
+ - Removed - for now removed features.
20
+ - Fixed - for any bug fixes.
21
+ - Security - in case of vulnerabilities.
22
+
23
+ # [Unreleased](https://github.com/puppetlabs/beaker/compare/4.19.0...master)
24
+
25
+ # [4.19.0](https://github.com/puppetlabs/beaker/compare/4.18.0...4.19.0)
26
+
27
+ ### Added
28
+
29
+ - `apt-transport-https` package will now be installed on Debian-based systems as part of the prebuilt process. ([#1631](https://github.com/puppetlabs/beaker/pull/1631))
30
+ - Ubuntu 19.10 and 20.04 code name handling. ([#1632](https://github.com/puppetlabs/beaker/pull/1632))
31
+
32
+ ### Changed
33
+
34
+ - The `wait_time`, `max_connection_tries`, and `uptime_retries` parameters have been added to `Host::Unix::Exec.reboot`. This allows for more fine-grained control over how the reboot is handled. ([#1625](https://github.com/puppetlabs/beaker/pull/1625))
35
+
36
+ ### Fixed
37
+
38
+ - In `hosts.yml`, `packaging_platform` will now default to `platform` if unspecified. This fixed a bug where beaker would fail unless you specified both values in your config, even if both values were identical. ([#1628](https://github.com/puppetlabs/beaker/pull/1628))
39
+ - `version_is_less` will now correctly handle builds and RCs when used in version numbers. ([#1630](https://github.com/puppetlabs/beaker/pull/1630))
40
+
41
+ ### Security
42
+ - Update `rake` to `~> 12.0`, which currently resolves to `12.3.3` to remediate [CVE-2020-8130](https://nvd.nist.gov/vuln/detail/CVE-2020-8130)
15
43
 
16
44
  # [4.18.0](https://github.com/puppetlabs/beaker/compare/4.17.0...4.18.0) - 2020-02-26
17
45
  ### Changed
@@ -1,5 +1,6 @@
1
1
  # -*- encoding: utf-8 -*-
2
- $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
2
+ lib = File.expand_path("lib", __dir__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
4
  require 'beaker/version'
4
5
 
5
6
  Gem::Specification.new do |s|
@@ -24,7 +25,7 @@ Gem::Specification.new do |s|
24
25
  s.add_development_dependency 'rspec-its'
25
26
  s.add_development_dependency 'fakefs', '~> 0.6', '< 0.14.0'
26
27
  s.add_development_dependency 'simplecov'
27
- s.add_development_dependency 'rake', '~> 10.0'
28
+ s.add_development_dependency 'rake', '~> 12.0'
28
29
 
29
30
  # Provisioner dependencies - needed for acceptance tests
30
31
  # TODO: figure out how to remove these
@@ -70,6 +70,7 @@ module Beaker
70
70
  def initialize name, host_hash, options
71
71
  @logger = host_hash[:logger] || options[:logger]
72
72
  @name, @host_hash, @options = name.to_s, host_hash.dup, options.dup
73
+ @host_hash['packaging_platform'] ||= @host_hash['platform']
73
74
 
74
75
  @host_hash = self.platform_defaults.merge(@host_hash)
75
76
  pkg_initialize
@@ -2,9 +2,16 @@ module Unix::Exec
2
2
  include Beaker::CommandFactory
3
3
 
4
4
  # Reboots the host, comparing uptime values to verify success
5
+ # @param [Integer] wait_time How long to wait after sending the reboot
6
+ # command before attempting to check in on the host
7
+ # @param [Integer] max_connection_tries How many times to retry connecting to
8
+ # host after reboot. Note that there is an fibbonacci
9
+ # backoff when attempting retries so the time spent
10
+ # waiting on this can grow quickly.
11
+ # @param [Integer] uptime_retries How many times to check to see if the value of the uptime has reset.
5
12
  #
6
13
  # Will throw an exception RebootFailure if it fails
7
- def reboot
14
+ def reboot(wait_time=10, max_connection_tries=9, uptime_retries=18)
8
15
  begin
9
16
  original_uptime = exec(Beaker::Command.new("uptime"))
10
17
  original_uptime_str = parse_uptime original_uptime.stdout
@@ -15,20 +22,36 @@ module Unix::Exec
15
22
  else
16
23
  exec(Beaker::Command.new("/sbin/shutdown -r now"), :expect_connection_failure => true)
17
24
  end
25
+ rescue Beaker::Host::CommandFailure => e
26
+ raise Beaker::Host::RebootFailure, "Command failed when attempting to reboot: #{e.message}"
27
+ rescue RuntimeError => e
28
+ raise Beaker::Host::RebootFailure, "Unexpected exception in reboot: #{e.message}"
29
+ end
18
30
 
31
+ attempts = 0
32
+ begin
19
33
  # give the host a little time to shutdown
20
- sleep 5
34
+ @logger.debug("Waiting #{wait_time} for host to shut down.")
35
+ sleep wait_time
21
36
 
22
37
  #use uptime to check if the host has rebooted
23
- current_uptime_exec = exec(Beaker::Command.new("uptime"), {:max_connection_tries => 9, :silent => true})
38
+ current_uptime_exec = exec(Beaker::Command.new("uptime"), {:max_connection_tries => max_connection_tries, :silent => true})
24
39
  current_uptime = current_uptime_exec.stdout
25
40
  current_uptime_str = parse_uptime current_uptime
26
41
  current_uptime_int = uptime_int current_uptime_str
27
42
  unless original_uptime_int > current_uptime_int
28
- raise Beaker::Host::RebootFailure, "Uptime did not reset. Reboot appears to have failed."
43
+ raise Beaker::Host::RebootFailure, "Uptime did not reset. Reboot appears to have failed."
44
+ end
45
+ rescue Beaker::Host::RebootFailure => e
46
+ attempts += 1
47
+ if attempts < uptime_retries
48
+ @logger.debug("Uptime did not reset. Will retry #{uptime_retries - attempts} more times.")
49
+ retry
50
+ else
51
+ raise
29
52
  end
30
53
  rescue Beaker::Host::CommandFailure => e
31
- raise Beaker::Host::RebootFailure, "Command failed in reboot: #{e.message}"
54
+ raise Beaker::Host::RebootFailure, "Command failed when attempting to reboot: #{e.message}"
32
55
  rescue RuntimeError => e
33
56
  raise Beaker::Host::RebootFailure, "Unexpected exception in reboot: #{e.message}"
34
57
  end
@@ -21,7 +21,7 @@ module Beaker
21
21
  PSWINDOWS_PACKAGES = []
22
22
  SLES10_PACKAGES = ['curl']
23
23
  SLES_PACKAGES = ['curl', 'ntp']
24
- DEBIAN_PACKAGES = ['curl', 'ntpdate', 'lsb-release']
24
+ DEBIAN_PACKAGES = ['curl', 'ntpdate', 'lsb-release', 'apt-transport-https']
25
25
  CUMULUS_PACKAGES = ['curl', 'ntpdate']
26
26
  SOLARIS10_PACKAGES = ['CSWcurl', 'CSWntp', 'wget']
27
27
  SOLARIS11_PACKAGES = ['curl', 'ntp']
@@ -12,7 +12,8 @@ module Beaker
12
12
  "wheezy" => "7",
13
13
  "squeeze" => "6",
14
14
  },
15
- :ubuntu => { "eoan" => "1910",
15
+ :ubuntu => { "focal" => "2004",
16
+ "eoan" => "1910",
16
17
  "disco" => "1904",
17
18
  "cosmic" => "1810",
18
19
  "bionic" => "1804",
@@ -7,8 +7,11 @@ module Beaker
7
7
  #@param [String] b A version of the form '\d.\d.\d.*'
8
8
  #@return [Boolean] true if a is less than b, otherwise return false
9
9
  #
10
- #@note 3.0.0-160-gac44cfb is greater than 3.0.0, and 2.8.2
11
- #@note -rc being less than final builds is not yet implemented.
10
+ #@note This has been updated for our current versioning scheme.
11
+ #@note 2019.5.0 is greater than 2019.5.0-rc0
12
+ #@note 2019.5.0-rc0-1-gabc1234 is greater than 2019.5.0-rc0
13
+ #@note 2019.5.0-rc1 is greater than 2019.5.0-rc0-1-gabc1234
14
+ #@note 2019.5.0-1-gabc1234 is greater than 2019.5.0
12
15
  def version_is_less a, b
13
16
  a_nums = a.split('-')[0].split('.')
14
17
  b_nums = b.split('-')[0].split('.')
@@ -24,16 +27,45 @@ module Beaker
24
27
  end
25
28
  end
26
29
  #checks all dots, they are equal so examine the rest
27
- a_rest = a.split('-', 2)[1]
28
- b_rest = b.split('-', 2)[1]
29
- if a_rest and b_rest and a_rest < b_rest
30
- return false
31
- elsif a_rest and not b_rest
30
+ a_rest = a.split('-').drop(1)
31
+ a_is_release = a_rest.empty?
32
+ a_is_rc = !a_is_release && !!(a_rest[0] =~ /rc\d+/)
33
+ b_rest = b.split('-').drop(1)
34
+ b_is_release = b_rest.empty?
35
+ b_is_rc = !b_is_release && !!(b_rest[0] =~ /rc\d+/)
36
+
37
+ if a_is_release && b_is_release
38
+ # They are equal
32
39
  return false
33
- elsif not a_rest and b_rest
34
- return true
40
+ elsif !a_is_release && !b_is_release
41
+ a_next = a_rest.shift
42
+ b_next = b_rest.shift
43
+ if a_is_rc && b_is_rc
44
+ a_rc = a_next.gsub('rc','').to_i
45
+ b_rc = b_next.gsub('rc','').to_i
46
+ if a_rc < b_rc
47
+ return true
48
+ elsif a_rc > b_rc
49
+ return false
50
+ else
51
+ a_next = a_rest.shift
52
+ b_next = b_rest.shift
53
+ if a_next && b_next
54
+ return a_next.to_i < b_next.to_i
55
+ else
56
+ # If a has nothing after -rc#, it is a tagged RC and
57
+ # b must be a later build after this tag.
58
+ return a_next.nil?
59
+ end
60
+ end
61
+ else
62
+ # If one of them is not an rc (and also not a release),
63
+ # that one is a post-release build. So if a is the RC, it is less.
64
+ return a_is_rc
65
+ end
66
+ else
67
+ return (b_is_release && a_is_rc) || (a_is_release && !b_is_rc)
35
68
  end
36
- return false
37
69
  end
38
70
 
39
71
  # Gets the max semver version from a list of them
@@ -1,5 +1,5 @@
1
1
  module Beaker
2
2
  module Version
3
- STRING = '4.18.0'
3
+ STRING = '4.19.0'
4
4
  end
5
5
  end
@@ -159,36 +159,96 @@ module Beaker
159
159
  end
160
160
 
161
161
  describe '#reboot' do
162
+ # no-op response
162
163
  let (:response) { double( 'response' ) }
164
+ let (:uptime_initial_response) { double( 'response' ) }
165
+ let (:uptime_initial_stdout) { '19:52 up 14 mins, 2 users, load averages: 2.95 4.19 4.31' }
166
+
167
+ let (:uptime_success_response) { double( 'response' ) }
168
+ let (:uptime_success_stdout) { '19:52 up 0 mins, 2 users, load averages: 2.95 4.19 4.31' }
169
+ let (:sleep_time) { 10 }
163
170
 
164
171
  before :each do
165
172
  # stubs enough to survive the first uptime call & output parsing
166
173
  # note: just stubs input-chain between calls, parsing methods still run
167
- allow( Beaker::Command ).to receive(:new).with("uptime").and_return(:uptime_command_stub)
168
- allow( instance ).to receive( :exec ).with(:uptime_command_stub).and_return(response)
169
- allow( response ).to receive(:stdout).and_return('19:52 up 14 mins, 2 users, load averages: 2.95 4.19 4.31')
174
+ allow(Beaker::Command).to receive(:new).with("uptime").and_return(:uptime_command_stub)
175
+
176
+ # mock initial uptime call
177
+ allow(instance).to receive( :exec ).with(:uptime_command_stub).and_return(uptime_initial_response).once
178
+ allow(uptime_initial_response).to receive(:stdout).and_return(uptime_initial_stdout)
179
+
180
+ allow(uptime_success_response).to receive(:stdout).and_return(uptime_success_stdout)
170
181
 
171
- allow( Beaker::Command ).to receive(:new).with("/sbin/shutdown -r now").and_return(:shutdown_command_stub)
182
+ allow(instance).to receive(:sleep)
183
+
184
+ allow(Beaker::Command).to receive(:new).with("/sbin/shutdown -r now").and_return(:shutdown_command_stub)
172
185
  end
173
186
 
174
187
  it 'raises a reboot failure when command fails' do
175
- expect(instance).to receive(:exec).with(:shutdown_command_stub, anything).and_raise(Host::CommandFailure)
176
- expect{ instance.reboot }.to raise_error(Beaker::Host::RebootFailure, /Command failed in reboot: .*/)
188
+ expect(instance).not_to receive(:sleep)
189
+ expect(instance).to receive(:exec).with(:shutdown_command_stub, anything).and_raise(Host::CommandFailure).once
190
+ expect{ instance.reboot }.to raise_error(Beaker::Host::RebootFailure, /Command failed when attempting to reboot: .*/)
177
191
  end
178
192
 
179
193
  it 'raises a reboot failure when we receive an unexpected error' do
180
- expect(instance).to receive(:exec).with(:shutdown_command_stub, anything).and_raise(Net::SSH::HostKeyError)
181
- expect{ instance.reboot }.to raise_error(Beaker::Host::RebootFailure, /Unexpected exception in reboot: .*/)
194
+ expect(instance).not_to receive(:sleep)
195
+ expect(instance).to receive(:exec).with(:shutdown_command_stub, anything).and_raise(Net::SSH::HostKeyError).once
196
+ expect { instance.reboot }.to raise_error(Beaker::Host::RebootFailure, /Unexpected exception in reboot: .*/)
182
197
  end
183
198
 
184
199
  it 'raises RebootFailure if new uptime is never less than old uptime' do
200
+ expect(instance).to receive(:sleep).with(sleep_time)
185
201
  # bypass shutdown command itself
186
- allow( instance ).to receive( :exec ).with(:shutdown_command_stub, anything).and_return(response)
187
- # allow the second uptime and the hash arguments in exec
188
- allow( instance ).to receive( :exec ).with(:uptime_command_stub, anything).and_return(response)
202
+ expect(instance).to receive( :exec ).with(:shutdown_command_stub, anything).and_return(response).once
203
+ # allow the second uptime and the hash arguments in exec, repeated 18 times by default in order to replicate the previous behavior of the ping based Host.down?
204
+ expect(instance).to receive( :exec ).with(:uptime_command_stub, anything).and_return(uptime_initial_response).exactly(18).times
189
205
 
190
206
  expect { instance.reboot }.to raise_error(Beaker::Host::RebootFailure, /Uptime did not reset/)
191
207
  end
208
+
209
+ it 'raises RebootFailure if new uptime is never less than old uptime when the number of retries is changed' do
210
+ expect(instance).to receive(:sleep).with(sleep_time)
211
+ # bypass shutdown command itself
212
+ expect(instance).to receive( :exec ).with(:shutdown_command_stub, anything).and_return(response).once
213
+ # allow the second uptime and the hash arguments in exec, repeated 10 times by default
214
+ expect(instance).to receive( :exec ).with(:uptime_command_stub, anything).and_return(uptime_initial_response).exactly(10).times
215
+
216
+ expect { instance.reboot(wait_time=sleep_time, max_connection_tries=9, uptime_retries=10) }.to raise_error(Beaker::Host::RebootFailure, /Uptime did not reset/)
217
+ end
218
+
219
+ it 'passes if new uptime is less than old uptime' do
220
+ expect(instance).to receive(:sleep).with(sleep_time)
221
+ # bypass shutdown command itself
222
+ expect(instance).to receive( :exec ).with(:shutdown_command_stub, anything).and_return(response).once
223
+ # allow the second uptime and the hash arguments in exec
224
+ expect(instance).to receive( :exec ).with(:uptime_command_stub, anything).and_return(uptime_success_response).once
225
+
226
+ expect(instance.reboot).to be(nil)
227
+ end
228
+
229
+ context 'with wait_time_parameter' do
230
+ it 'passes if new uptime is less than old uptime' do
231
+ expect(instance).to receive(:sleep).with(10)
232
+ # bypass shutdown command itself
233
+ expect(instance).to receive( :exec ).with(:shutdown_command_stub, anything).and_return(response).once
234
+ # allow the second uptime and the hash arguments in exec
235
+ expect(instance).to receive( :exec ).with(:uptime_command_stub, anything).and_return(uptime_success_response).once
236
+
237
+ expect(instance.reboot(10)).to be(nil)
238
+ end
239
+ end
240
+
241
+ context 'with max_connection_tries parameter' do
242
+ it 'passes if new uptime is less than old uptime' do
243
+ expect(instance).to receive(:sleep).with(sleep_time)
244
+ # bypass shutdown command itself
245
+ expect(instance).to receive( :exec ).with(:shutdown_command_stub, anything).and_return(response).once
246
+ # allow the second uptime and the hash arguments in exec
247
+ expect(instance).to receive( :exec ).with(:uptime_command_stub, hash_including(:max_connection_tries => 20)).and_return(uptime_success_response).once
248
+
249
+ expect(instance.reboot(sleep_time, 20)).to be(nil)
250
+ end
251
+ end
192
252
  end
193
253
 
194
254
  describe '#enable_remote_rsyslog' do
@@ -77,6 +77,11 @@ module Beaker
77
77
  expect( platform.with_version_codename ).to be === 'debian-squeeze-xxx'
78
78
  end
79
79
 
80
+ it "can convert unbuntu-2004-xxx to ubuntu-focal-xxx" do
81
+ @name = 'ubuntu-2004-xxx'
82
+ expect( platform.with_version_codename ).to be === 'ubuntu-focal-xxx'
83
+ end
84
+
80
85
  it "can convert unbuntu-1604-xxx to ubuntu-xenial-xxx" do
81
86
  @name = 'ubuntu-1604-xxx'
82
87
  expect( platform.with_version_codename ).to be === 'ubuntu-xenial-xxx'
@@ -10,8 +10,24 @@ module Beaker
10
10
  expect( subject.version_is_less( '2015.3.0-rc0-8-gf80879a', '2016' ) ).to be === true
11
11
  end
12
12
 
13
- it 'reports 2015.3.0-rc0-8-gf80879a is not less than 2015.3.0' do
14
- expect( subject.version_is_less( '2015.3.0-rc0-8-gf80879a', '2015.3.0' ) ).to be === false
13
+ it 'reports 2015.3.0-rc0-8-gf80879a is less than 2015.3.0' do
14
+ expect( subject.version_is_less( '2015.3.0-rc0-8-gf80879a', '2015.3.0' ) ).to be === true
15
+ end
16
+
17
+ it 'reports that 2015.3.0-rc0 is less than 2015.3.0-rc0-8-gf80879a' do
18
+ expect( subject.version_is_less( '2015.3.0-rc0', '2015.3.0-rc0-8-gf80879a' ) ).to be === true
19
+ end
20
+
21
+ it 'reports that 2015.3.0-rc2 is less than 2015.3.0-rc10 (not using string comparison)' do
22
+ expect( subject.version_is_less( '2015.3.0-rc2', '2015.3.0-rc10' ) ).to be === true
23
+ end
24
+
25
+ it 'reports that 2015.3.0 is less than 2015.3.0-1-gabc1234' do
26
+ expect( subject.version_is_less( '2015.3.0', '2015.3.0-1-gabc1234' ) ).to be === true
27
+ end
28
+
29
+ it 'reports that 2015.3.0-rc2 is less than 2015.3.0-1-gabc1234' do
30
+ expect( subject.version_is_less( '2015.3.0-rc2', '2015.3.0-1-gabc1234' ) ).to be === true
15
31
  end
16
32
 
17
33
  it 'reports 2015.3.0-rc0-8-gf80879a is not less than 3.0.0' do
@@ -41,6 +57,10 @@ module Beaker
41
57
  it 'reports 2.8 is less than 2.9' do
42
58
  expect( subject.version_is_less( '2.8', '2.9' ) ).to be === true
43
59
  end
60
+
61
+ it 'reports that 2015.3.0 is not less than 2015.3.0' do
62
+ expect( subject.version_is_less( '2015.3.0', '2015.3.0' ) ).to be == false
63
+ end
44
64
  end
45
65
 
46
66
  describe 'max_version' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: beaker
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.18.0
4
+ version: 4.19.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppet
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-26 00:00:00.000000000 Z
11
+ date: 2020-03-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -78,14 +78,14 @@ dependencies:
78
78
  requirements:
79
79
  - - "~>"
80
80
  - !ruby/object:Gem::Version
81
- version: '10.0'
81
+ version: '12.0'
82
82
  type: :development
83
83
  prerelease: false
84
84
  version_requirements: !ruby/object:Gem::Requirement
85
85
  requirements:
86
86
  - - "~>"
87
87
  - !ruby/object:Gem::Version
88
- version: '10.0'
88
+ version: '12.0'
89
89
  - !ruby/object:Gem::Dependency
90
90
  name: beaker-aws
91
91
  requirement: !ruby/object:Gem::Requirement