beaker 2.52.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +8 -8
  2. data/HISTORY.md +27034 -2
  3. data/acceptance/tests/base/external_resources_test.rb +7 -25
  4. data/acceptance/tests/base/host/host_test.rb +106 -0
  5. data/beaker.gemspec +13 -12
  6. data/docs/concepts/shared_options_for_executing_beaker_commands.md +1 -1
  7. data/docs/how_to/hypervisors/openstack.md +9 -0
  8. data/docs/how_to/test_arbitrary_beaker_versions.md +46 -0
  9. data/docs/how_to/upgrade_from_2_to_3.md +76 -0
  10. data/docs/tutorials/README.md +82 -0
  11. data/lib/beaker/dsl.rb +0 -2
  12. data/lib/beaker/dsl/helpers/puppet_helpers.rb +2 -1
  13. data/lib/beaker/dsl/install_utils/windows_utils.rb +27 -1
  14. data/lib/beaker/host.rb +16 -1
  15. data/lib/beaker/host/unix/exec.rb +4 -4
  16. data/lib/beaker/host/unix/pkg.rb +3 -2
  17. data/lib/beaker/host_prebuilt_steps.rb +2 -46
  18. data/lib/beaker/hypervisor.rb +1 -1
  19. data/lib/beaker/hypervisor/openstack.rb +19 -34
  20. data/lib/beaker/options/presets.rb +1 -5
  21. data/lib/beaker/version.rb +1 -1
  22. data/spec/beaker/dsl/helpers/puppet_helpers_spec.rb +18 -4
  23. data/spec/beaker/dsl/helpers/web_helpers_spec.rb +26 -4
  24. data/spec/beaker/dsl/install_utils/windows_utils_spec.rb +47 -1
  25. data/spec/beaker/host/unix/pkg_spec.rb +1 -0
  26. data/spec/beaker/host_prebuilt_steps_spec.rb +2 -33
  27. data/spec/beaker/host_spec.rb +14 -2
  28. data/spec/beaker/hypervisor/hypervisor_spec.rb +0 -15
  29. data/spec/beaker/hypervisor/openstack_spec.rb +5 -0
  30. data/spec/helpers.rb +1 -0
  31. metadata +15 -105
  32. data/lib/beaker/hypervisor/aixer.rb +0 -48
  33. data/lib/beaker/hypervisor/solaris.rb +0 -59
  34. data/spec/beaker/hypervisor/aixer_spec.rb +0 -34
  35. data/spec/beaker/hypervisor/solaris_spec.rb +0 -40
@@ -323,7 +323,8 @@ module Beaker
323
323
  curl_retries = 120 if curl_retries.nil?
324
324
  port = options[:puppetserver_port] if port.nil?
325
325
  if host.graceful_restarts?
326
- apachectl_path = host.is_pe? ? "#{host['puppetsbindir']}/apache2ctl" : 'apache2ctl'
326
+ service = host.check_for_command('apache2ctl') ? 'apache2ctl' : 'apachectl'
327
+ apachectl_path = host.is_pe? ? "#{host['puppetsbindir']}/#{service}" : service
327
328
  host.exec(Command.new("#{apachectl_path} graceful"))
328
329
  else
329
330
  host.exec puppet_resource('service', service, 'ensure=stopped')
@@ -139,7 +139,33 @@ exit /B %errorlevel%
139
139
  # if puppet service exists, then pe-puppet is not queried
140
140
  # if puppet service does not exist, pe-puppet is queried and that exit code is used
141
141
  # therefore, this command will always exit 0 if either service is installed
142
- on host, Command.new("sc query puppet || sc query pe-puppet", [], { :cmdexe => true })
142
+ #
143
+ # We also take advantage of this output to verify the startup
144
+ # settings are honored as supplied to the MSI
145
+ on host, Command.new("sc qc puppet || sc qc pe-puppet", [], { :cmdexe => true }) do |result|
146
+ output = result.stdout
147
+ startup_mode = msi_opts['PUPPET_AGENT_STARTUP_MODE'].upcase
148
+
149
+ search = case startup_mode
150
+ when 'AUTOMATIC'
151
+ { :code => 2, :name => 'AUTO_START' }
152
+ when 'MANUAL'
153
+ { :code => 3, :name => 'DEMAND_START' }
154
+ when 'DISABLED'
155
+ { :code => 4, :name => 'DISABLED' }
156
+ end
157
+
158
+ if output !~ /^\s+START_TYPE\s+:\s+#{search[:code]}\s+#{search[:name]}/
159
+ raise "puppet service startup mode did not match supplied MSI option '#{startup_mode}'"
160
+ end
161
+ end
162
+
163
+ # (PA-514) value for PUPPET_AGENT_STARTUP_MODE should be present in
164
+ # registry and honored after install/upgrade.
165
+ reg_key = host.is_x86_64? ? "HKLM\\SOFTWARE\\Wow6432Node\\Puppet Labs\\PuppetInstaller" :
166
+ "HKLM\\SOFTWARE\\Puppet Labs\\PuppetInstaller"
167
+ reg_query_command = %Q(reg query "#{reg_key}" /v "RememberedPuppetAgentStartupMode" | findstr #{msi_opts['PUPPET_AGENT_STARTUP_MODE']})
168
+ on host, Command.new(reg_query_command, [], { :cmdexe => true })
143
169
 
144
170
  # emit the misc/versions.txt file which contains component versions for
145
171
  # puppet, facter, hiera, pxp-agent, packaging and vendored Ruby
data/lib/beaker/host.rb CHANGED
@@ -92,11 +92,26 @@ module Beaker
92
92
  TCPSocket.new(reachable_name, port).close
93
93
  return true
94
94
  end
95
- rescue Errno::ECONNREFUSED, Timeout::Error, Errno::ETIMEDOUT
95
+ rescue Errno::ECONNREFUSED, Timeout::Error, Errno::ETIMEDOUT, Errno::EHOSTUNREACH
96
96
  return false
97
97
  end
98
98
  end
99
99
 
100
+ # Wait for a port on the host. Useful for those occasions when you've called
101
+ # host.reboot and want to avoid spam from subsequent SSH connections retrying
102
+ # to connect from say retry_on()
103
+ def wait_for_port(port, attempts=15)
104
+ @logger.debug(" Waiting for port #{port} ... ", false)
105
+ start = Time.now
106
+ done = repeat_fibonacci_style_for(attempts) { port_open?(port) }
107
+ if done
108
+ @logger.debug('connected in %0.2f seconds' % (Time.now - start))
109
+ else
110
+ @logger.debug('timeout')
111
+ end
112
+ done
113
+ end
114
+
100
115
  def up?
101
116
  begin
102
117
  Socket.getaddrinfo( reachable_name, nil )
@@ -106,7 +106,7 @@ module Unix::Exec
106
106
  if exec(Beaker::Command.new("grep ^#{key}=.*#{escaped_val} #{env_file}"), :accept_all_exit_codes => true ).exit_code == 0
107
107
  return #nothing to do here, key value pair already exists
108
108
  #see if the key already exists
109
- elsif exec(Beaker::Command.new("grep ^#{key} #{env_file}"), :accept_all_exit_codes => true ).exit_code == 0
109
+ elsif exec(Beaker::Command.new("grep ^#{key}= #{env_file}"), :accept_all_exit_codes => true ).exit_code == 0
110
110
  exec(Beaker::SedCommand.new(self['platform'], "s/^#{key}=/#{key}=#{escaped_val}:/", env_file))
111
111
  else
112
112
  exec(Beaker::Command.new("echo \"#{key}=#{val}\" >> #{env_file}"))
@@ -142,7 +142,7 @@ module Unix::Exec
142
142
  # host.get_env_var('path')
143
143
  def get_env_var key
144
144
  key = key.to_s
145
- exec(Beaker::Command.new("env | grep #{key}"), :accept_all_exit_codes => true).stdout.chomp
145
+ exec(Beaker::Command.new("env | grep ^#{key}="), :accept_all_exit_codes => true).stdout.chomp
146
146
  end
147
147
 
148
148
  #Delete the environment variable from the current ssh environment
@@ -153,7 +153,7 @@ module Unix::Exec
153
153
  key = key.to_s
154
154
  env_file = self[:ssh_env_file]
155
155
  #remove entire line
156
- exec(Beaker::SedCommand.new(self['platform'], "/#{key}=.*$/d", env_file))
156
+ exec(Beaker::SedCommand.new(self['platform'], "/^#{key}=.*$/d", env_file))
157
157
  #update the profile.d to current state
158
158
  #match it to the contents of ssh_env_file
159
159
  mirror_env_to_profile_d(env_file)
@@ -296,7 +296,7 @@ module Unix::Exec
296
296
 
297
297
  # Checks if selinux is enabled
298
298
  #
299
- # @return [Boolean] true if selinux is enabled, false otherwise
299
+ # @return [Boolean] true if selinux is enabled, false otherwise
300
300
  def selinux_enabled?()
301
301
  exec(Beaker::Command.new("sudo selinuxenabled"), :accept_all_exit_codes => true).exit_code == 0
302
302
  end
@@ -95,8 +95,9 @@ module Unix::Pkg
95
95
  if ! check_for_command('pkgutil')
96
96
  # https://www.opencsw.org/package/pkgutil/
97
97
  noask_text = self.noask_file_text
98
- create_remote_file self, File.join(noask_directory, 'noask'), noask_text
99
- execute('pkgadd -d http://get.opencsw.org/now -a noask -n all', opts)
98
+ noask_file = File.join(external_copy_base, 'noask')
99
+ create_remote_file(self, noask_file, noask_text)
100
+ execute("pkgadd -d http://get.opencsw.org/now -a #{noask_file} -n all", opts)
100
101
  execute('/opt/csw/bin/pkgutil -U', opts)
101
102
  execute('/opt/csw/bin/pkgutil -y -i pkgutil', opts)
102
103
  end
@@ -161,41 +161,6 @@ module Beaker
161
161
  report_and_raise(logger, e, "sync_root_keys")
162
162
  end
163
163
 
164
- #Determine the Extra Packages for Enterprise Linux URL for the provided Enterprise Linux host.
165
- # @param [Host, Array<Host>] host One host to act on. Will use host epel_url, epel_arch and epel_pkg
166
- # before using defaults provided in opts.
167
- # @return [String, String, String] The URL, arch and package name for EPL for the provided host
168
- # @param [Hash{Symbol=>String}] opts Options to alter execution.
169
- # @option opts [String] :epel_url Link to download
170
- # @option opts [String] :epel_arch Architecture to download (i386, x86_64, etc), defaults to i386 for 5 and 6, x86_64 for 7
171
- # @option opts [String] :epel_6_pkg Package to download from provided link for el-6
172
- # @option opts [String] :epel_5_pkg Package to download from provided link for el-5
173
- # @raise [Exception] Raises an error if the host provided's platform != /el-(5|6)/
174
- def epel_info_for host, opts
175
- if !el_based?(host)
176
- raise "epel_info_for! not available for #{host.name} on platform #{host['platform']}"
177
- end
178
-
179
- version = host['platform'].version
180
- url = "#{host[:epel_url] || opts[:epel_url]}/#{version}"
181
- if version == '7'
182
- if opts[:epel_7_arch] == 'i386'
183
- raise ArgumentError.new("epel-7 does not provide packages for i386")
184
- end
185
- pkg = host[:epel_pkg] || opts[:epel_7_pkg]
186
- arch = opts[:epel_7_arch] || 'x86_64'
187
- elsif version == '6'
188
- pkg = host[:epel_pkg] || opts[:epel_6_pkg]
189
- arch = host[:epel_arch] || opts[:epel_6_arch] || 'i386'
190
- elsif version == '5'
191
- pkg = host[:epel_pkg] || opts[:epel_5_pkg]
192
- arch = host[:epel_arch] || opts[:epel_5_arch] || 'i386'
193
- else
194
- raise ArgumentError.new("epel_info_for does not support el version #{version}, on #{host.name}")
195
- end
196
- return url, arch, pkg
197
- end
198
-
199
164
  # Run 'apt-get update' on the provided host or hosts.
200
165
  # If the platform of the provided host is not ubuntu, debian or cumulus: do nothing.
201
166
  #
@@ -258,10 +223,6 @@ module Beaker
258
223
  # @option opts [Boolean] :debug If true, print verbose rpm information when installing EPEL
259
224
  # @option opts [Beaker::Logger] :logger A {Beaker::Logger} object
260
225
  # @option opts [String] :epel_url Link to download from
261
- # @option opts [String] :epel_arch Architecture of epel to download (i386, x86_64, etc)
262
- # @option opts [String] :epel_7_pkg Package to download from provided link for el-7
263
- # @option opts [String] :epel_6_pkg Package to download from provided link for el-6
264
- # @option opts [String] :epel_5_pkg Package to download from provided link for el-5
265
226
  def add_el_extras( host, opts )
266
227
  #add_el_extras
267
228
  #only supports el-* platforms
@@ -272,14 +233,9 @@ module Beaker
272
233
  when el_based?(host) && ['5','6','7'].include?(host['platform'].version)
273
234
  result = host.exec(Command.new('rpm -qa | grep epel-release'), :acceptable_exit_codes => [0,1])
274
235
  if result.exit_code == 1
275
- url, arch, pkg = epel_info_for host, opts
276
- if host['platform'].version == '7'
277
- host.exec(Command.new("rpm -i#{debug_opt} #{url}/#{arch}/e/#{pkg}"))
278
- else
279
- host.exec(Command.new("rpm -i#{debug_opt} #{url}/#{arch}/#{pkg}"))
280
- end
236
+ host.exec(Command.new("rpm -i#{debug_opt} #{opts[:epel_url]}/epel-release-latest-#{host['platform'].version}.noarch.rpm"))
281
237
  #update /etc/yum.repos.d/epel.repo for new baseurl
282
- host.exec(Command.new("sed -i -e 's;#baseurl.*$;baseurl=#{Regexp.escape(url)}/\$basearch;' /etc/yum.repos.d/epel.repo"))
238
+ host.exec(Command.new("sed -i -e 's;#baseurl.*$;baseurl=#{Regexp.escape("#{opts[:epel_url]}/#{host['platform'].version}")}/\$basearch;' /etc/yum.repos.d/epel.repo"))
283
239
  #remove mirrorlist
284
240
  host.exec(Command.new("sed -i -e '/mirrorlist/d' /etc/yum.repos.d/epel.repo"))
285
241
  host.exec(Command.new('yum clean all && yum makecache'))
@@ -149,6 +149,6 @@ module Beaker
149
149
  end
150
150
  end
151
151
 
152
- [ 'vsphere_helper', 'vagrant', 'vagrant_custom', 'vagrant_virtualbox', 'vagrant_parallels', 'vagrant_libvirt', 'vagrant_fusion', 'vagrant_workstation', 'fusion', 'aws_sdk', 'vsphere', 'vmpooler', 'vcloud', 'aixer', 'solaris', 'docker', 'google_compute', 'openstack', 'noop' ].each do |lib|
152
+ [ 'vsphere_helper', 'vagrant', 'vagrant_custom', 'vagrant_virtualbox', 'vagrant_parallels', 'vagrant_libvirt', 'vagrant_fusion', 'vagrant_workstation', 'fusion', 'aws_sdk', 'vsphere', 'vmpooler', 'vcloud', 'docker', 'google_compute', 'openstack', 'noop' ].each do |lib|
153
153
  require "beaker/hypervisor/#{lib}"
154
154
  end
@@ -171,23 +171,33 @@ module Beaker
171
171
  end
172
172
  end
173
173
 
174
+ # Get a floating IP address to associate with the instance, and
175
+ # allocate a new one if none are available
174
176
  def get_ip
177
+ @logger.debug "Finding IP"
175
178
  ip = @compute_client.addresses.find { |ip| ip.instance_id.nil? }
176
179
  if ip.nil?
177
- @logger.debug "Creating IP"
178
- ip = @compute_client.addresses.create
180
+ begin
181
+ @logger.debug "Creating IP"
182
+ ip = @compute_client.addresses.create
183
+ rescue Fog::Compute::OpenStack::NotFound
184
+ # If there are no more floating IP addresses, allocate a
185
+ # new one and try again.
186
+ @compute_client.allocate_address(@options[:floating_ip_pool])
187
+ ip = @compute_client.addresses.find { |ip| ip.instance_id.nil? }
188
+ end
179
189
  end
190
+ raise 'Could not find or allocate an address' if not ip
180
191
  ip
181
192
  end
182
193
 
183
-
184
194
  #Create new instances in OpenStack
185
195
  def provision
186
196
  @logger.notify "Provisioning OpenStack"
187
197
 
188
198
  @hosts.each do |host|
189
199
  ip = get_ip
190
- hostname = ip.ip.gsub! '.','-'
200
+ hostname = ip.ip.gsub '.','-'
191
201
  host[:vmhostname] = hostname+'.rfc1918.puppetlabs.net'
192
202
  @logger.debug "Provisioning #{host.name} (#{host[:vmhostname]})"
193
203
  options = {
@@ -223,36 +233,8 @@ module Beaker
223
233
  end
224
234
 
225
235
  # Associate a public IP to the server
226
- # Create if there are no floating ips available
227
- #
228
- # Do we already have an address?
229
- @logger.debug vm.addresses
230
- address=nil
231
- begin
232
- # Here we try and assign an address from a floating IP pool
233
- # This seems to fail on some implementations (FloatingIpPoolNotFound)
234
- ip.ip.gsub! '-','.'
235
- ip.server = vm
236
- address = ip.ip
237
-
238
- rescue Fog::Compute::OpenStack::NotFound
239
- # Here, we fail to just trying to use an address that's already assigned if there is one
240
- # There may be better logic, but this worked in the original implementation
241
- # There might be an argument for checking whether an address is reachable a la
242
- # port_open? logic in host.rb but maybe race conditions
243
-
244
- begin
245
- if vm.addresses[@options[:openstack_network]]
246
- address = vm.addresses[@options[:openstack_network]].map{ |network| network['addr'] }.first
247
- end
248
- rescue NoMethodError
249
- @logger.debug "No current address retrievable from OpenStack data"
250
- end
251
-
252
- end
253
-
254
- raise 'Could not find or assign an address to the instance' unless address
255
- host[:ip] = address
236
+ ip.server = vm
237
+ host[:ip] = ip.ip
256
238
 
257
239
  @logger.debug "OpenStack host #{host.name} (#{host[:vmhostname]}) assigned ip: #{host[:ip]}"
258
240
 
@@ -262,6 +244,9 @@ module Beaker
262
244
  :project => @options[:project].to_s })
263
245
  @vms << vm
264
246
 
247
+ # Wait for the host to accept ssh logins
248
+ host.wait_for_port(22)
249
+
265
250
  #enable root if user is not root
266
251
  enable_root(host)
267
252
 
@@ -170,10 +170,6 @@ module Beaker
170
170
  :package_proxy => false,
171
171
  :add_el_extras => false,
172
172
  :epel_url => "http://dl.fedoraproject.org/pub/epel",
173
- :epel_arch => "i386",
174
- :epel_7_pkg => "epel-release-7-8.noarch.rpm",
175
- :epel_6_pkg => "epel-release-6-8.noarch.rpm",
176
- :epel_5_pkg => "epel-release-5-4.noarch.rpm",
177
173
  :consoleport => 443,
178
174
  :pe_dir => '/opt/enterprise/dists',
179
175
  :pe_version_file => 'LATEST',
@@ -190,7 +186,7 @@ module Beaker
190
186
  :puppetdb_port_nonssl => 8080,
191
187
  :puppetserver_port => 8140,
192
188
  :nodeclassifier_port => 4433,
193
- :cache_files_locally => true, # TODO change to false in next major version
189
+ :cache_files_locally => false,
194
190
  :aws_keyname_modifier => rand(10 ** 10).to_s.rjust(10,'0'), # 10 digit random number string
195
191
  :run_in_parallel => [],
196
192
  :ssh => {
@@ -1,5 +1,5 @@
1
1
  module Beaker
2
2
  module Version
3
- STRING = '2.52.0'
3
+ STRING = '3.0.0'
4
4
  end
5
5
  end
@@ -775,28 +775,42 @@ describe ClassMixedWithDSLHelpers do
775
775
  host.uses_passenger!
776
776
  end
777
777
  it 'bounces puppet twice' do
778
+ allow( subject ).to receive(:curl_with_retries)
779
+ subject.with_puppet_running_on(host, {})
780
+ expect(host).to execute_commands_matching(/apachectl graceful/).exactly(2).times
781
+ end
782
+
783
+ it 'gracefully restarts using apache2ctl' do
784
+ allow(host).to receive( :check_for_command ).and_return( true )
778
785
  allow( subject ).to receive(:curl_with_retries)
779
786
  subject.with_puppet_running_on(host, {})
780
787
  expect(host).to execute_commands_matching(/apache2ctl graceful/).exactly(2).times
781
788
  end
782
789
 
790
+ it 'gracefully restarts using apachectl' do
791
+ allow(host).to receive( :check_for_command ).and_return( false )
792
+ allow( subject ).to receive(:curl_with_retries)
793
+ subject.with_puppet_running_on(host, {})
794
+ expect(host).to execute_commands_matching(/apachectl graceful/).exactly(2).times
795
+ end
796
+
783
797
  it 'yields to a block after bouncing service' do
784
798
  execution = 0
785
799
  allow( subject ).to receive(:curl_with_retries)
786
800
  expect do
787
801
  subject.with_puppet_running_on(host, {}) do
788
- expect(host).to execute_commands_matching(/apache2ctl graceful/).once
802
+ expect(host).to execute_commands_matching(/apachectl graceful/).once
789
803
  execution += 1
790
804
  end
791
805
  end.to change { execution }.by(1)
792
- expect(host).to execute_commands_matching(/apache2ctl graceful/).exactly(2).times
806
+ expect(host).to execute_commands_matching(/apachectl graceful/).exactly(2).times
793
807
  end
794
808
 
795
809
  context ':restart_when_done flag set false' do
796
810
  it 'bounces puppet once' do
797
811
  allow( subject ).to receive(:curl_with_retries)
798
812
  subject.with_puppet_running_on(host, { :restart_when_done => false })
799
- expect(host).to execute_commands_matching(/apache2ctl graceful/).once
813
+ expect(host).to execute_commands_matching(/apachectl graceful/).once
800
814
  end
801
815
 
802
816
  it 'yields to a block after bouncing service' do
@@ -804,7 +818,7 @@ describe ClassMixedWithDSLHelpers do
804
818
  allow( subject ).to receive(:curl_with_retries)
805
819
  expect do
806
820
  subject.with_puppet_running_on(host, { :restart_when_done => false }) do
807
- expect(host).to execute_commands_matching(/apache2ctl graceful/).once
821
+ expect(host).to execute_commands_matching(/apachectl graceful/).once
808
822
  execution += 1
809
823
  end
810
824
  end.to change { execution }.by(1)
@@ -36,14 +36,13 @@ describe ClassMixedWithDSLHelpers do
36
36
  it "returns its second and third arguments concatenated." do
37
37
  concat_path = "#{destdir}/#{name}"
38
38
  create_files([concat_path])
39
- expect( logger ).to receive( :notify ).with( /^Already\ fetched\ / )
39
+ allow(logger).to receive(:notify)
40
+ allow(subject).to receive(:open)
40
41
  result = subject.fetch_http_file url, name, destdir
41
42
  expect(result).to eq(concat_path)
42
43
  end
43
44
 
44
- it 'doesn\'t cache if :cache_files_locally set false' do
45
- options[:cache_files_locally] = false
46
-
45
+ it 'doesn\'t cache by default' do
47
46
  expect( logger ).to receive( :notify ).with( /^Fetching/ ).ordered
48
47
  expect( logger ).to receive( :notify ).with( /^\ \ and\ saving\ to\ / ).ordered
49
48
  expect( subject ).to receive( :open )
@@ -51,6 +50,29 @@ describe ClassMixedWithDSLHelpers do
51
50
  subject.fetch_http_file( url, name, destdir )
52
51
  end
53
52
 
53
+ context ':cache_files_locally option is set' do
54
+ it 'caches if the file exists locally' do
55
+ options[:cache_files_locally] = true
56
+ allow(File).to receive(:exists?).and_return(true)
57
+
58
+ expect( logger ).to receive( :notify ).with( /^Already\ fetched\ / )
59
+ expect( subject ).not_to receive( :open )
60
+
61
+ subject.fetch_http_file( url, name, destdir )
62
+ end
63
+
64
+ it 'doesn\'t cache if the file doesn\'t exist locally' do
65
+ options[:cache_files_locally] = true
66
+ allow(File).to receive(:exists?).and_return(false)
67
+
68
+ expect( logger ).to receive( :notify ).with( /^Fetching/ ).ordered
69
+ expect( logger ).to receive( :notify ).with( /^\ \ and\ saving\ to\ / ).ordered
70
+ expect( subject ).to receive( :open )
71
+
72
+ subject.fetch_http_file( url, name, destdir )
73
+ end
74
+ end
75
+
54
76
  end
55
77
 
56
78
  describe 'given invalid arguments' do
@@ -36,7 +36,7 @@ describe ClassMixedWithDSLInstallUtils do
36
36
 
37
37
  def expect_status_called(times = hosts.length)
38
38
  expect( Beaker::Command ).to receive( :new )
39
- .with( "sc query puppet || sc query pe-puppet", [], {:cmdexe => true} )
39
+ .with( "sc qc puppet || sc qc pe-puppet", [], {:cmdexe => true} )
40
40
  .exactly( times ).times
41
41
  end
42
42
 
@@ -61,6 +61,16 @@ describe ClassMixedWithDSLInstallUtils do
61
61
  end
62
62
  end
63
63
 
64
+ def expect_reg_query_called(times = hosts.length)
65
+ hosts.each do |host|
66
+ expect(host).to receive(:is_x86_64?).and_return(:true)
67
+ end
68
+
69
+ expect( Beaker::Command ).to receive( :new )
70
+ .with(%r{reg query "HKLM\\SOFTWARE\\Wow6432Node\\Puppet Labs\\PuppetInstaller}, [], {:cmdexe => true})
71
+ .exactly(times).times
72
+ end
73
+
64
74
  describe "#install_msi_on" do
65
75
  let( :log_file ) { '/fake/log/file.log' }
66
76
  before :each do
@@ -71,6 +81,7 @@ describe ClassMixedWithDSLInstallUtils do
71
81
  it "will specify a PUPPET_AGENT_STARTUP_MODE of Manual (disabling the service) by default" do
72
82
  expect_install_called
73
83
  expect_status_called
84
+ expect_reg_query_called
74
85
  expect_version_log_called
75
86
  expect( subject ).to receive( :create_install_msi_batch_on ).with(
76
87
  anything, anything,
@@ -81,6 +92,7 @@ describe ClassMixedWithDSLInstallUtils do
81
92
  it "allows configuration of PUPPET_AGENT_STARTUP_MODE" do
82
93
  expect_install_called
83
94
  expect_status_called
95
+ expect_reg_query_called
84
96
  expect_version_log_called
85
97
  value = 'Automatic'
86
98
  expect( subject ).to receive( :create_install_msi_batch_on ).with(
@@ -109,6 +121,7 @@ describe ClassMixedWithDSLInstallUtils do
109
121
 
110
122
  it "will generate a command to emit a log file with the :debug option set" do
111
123
  expect_install_called
124
+ expect_reg_query_called
112
125
  expect_status_called
113
126
  expect_version_log_called
114
127
 
@@ -118,6 +131,7 @@ describe ClassMixedWithDSLInstallUtils do
118
131
 
119
132
  it 'will pass msi_path to #create_install_msi_batch_on as-is' do
120
133
  expect_install_called
134
+ expect_reg_query_called
121
135
  expect_status_called
122
136
  expect_version_log_called
123
137
  test_path = 'test/path'
@@ -125,6 +139,38 @@ describe ClassMixedWithDSLInstallUtils do
125
139
  anything, test_path, anything)
126
140
  subject.install_msi_on(hosts, test_path)
127
141
  end
142
+
143
+ it 'will search in Wow6432Node for the remembered startup setting on 64-bit hosts' do
144
+ expect_install_called
145
+ expect_status_called
146
+ expect_version_log_called
147
+
148
+ hosts.each do |host|
149
+ expect(host).to receive(:is_x86_64?).and_return(true)
150
+ end
151
+
152
+ expect( Beaker::Command ).to receive( :new )
153
+ .with('reg query "HKLM\\SOFTWARE\\Wow6432Node\\Puppet Labs\\PuppetInstaller" /v "RememberedPuppetAgentStartupMode" | findstr Foo', [], {:cmdexe => true})
154
+ .exactly(hosts.length).times
155
+
156
+ subject.install_msi_on(hosts, msi_path, {'PUPPET_AGENT_STARTUP_MODE' => "Foo"})
157
+ end
158
+
159
+ it 'will omit Wow6432Node in the registry search for remembered startup setting on 32-bit hosts' do
160
+ expect_install_called
161
+ expect_status_called
162
+ expect_version_log_called
163
+
164
+ hosts.each do |host|
165
+ expect(host).to receive(:is_x86_64?).and_return(false)
166
+ end
167
+
168
+ expect( Beaker::Command ).to receive( :new )
169
+ .with('reg query "HKLM\\SOFTWARE\\Puppet Labs\\PuppetInstaller" /v "RememberedPuppetAgentStartupMode" | findstr Foo', [], {:cmdexe => true})
170
+ .exactly(hosts.length).times
171
+
172
+ subject.install_msi_on(hosts, msi_path, {'PUPPET_AGENT_STARTUP_MODE' => "Foo"})
173
+ end
128
174
  end
129
175
 
130
176
  describe '#create_install_msi_batch_on' do