beaker 2.10.0 → 2.11.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.
Files changed (43) hide show
  1. checksums.yaml +8 -8
  2. data/HISTORY.md +292 -4
  3. data/acceptance/tests/base/host.rb +1 -0
  4. data/lib/beaker/answers/version30.rb +10 -10
  5. data/lib/beaker/cli.rb +10 -8
  6. data/lib/beaker/command.rb +1 -1
  7. data/lib/beaker/dsl/helpers/facter_helpers.rb +10 -1
  8. data/lib/beaker/dsl/helpers/hiera_helpers.rb +0 -11
  9. data/lib/beaker/dsl/helpers/host_helpers.rb +12 -3
  10. data/lib/beaker/dsl/helpers/puppet_helpers.rb +11 -3
  11. data/lib/beaker/dsl/helpers/tk_helpers.rb +0 -12
  12. data/lib/beaker/dsl/helpers/web_helpers.rb +0 -12
  13. data/lib/beaker/dsl/install_utils/module_utils.rb +9 -6
  14. data/lib/beaker/dsl/install_utils/pe_utils.rb +60 -8
  15. data/lib/beaker/dsl/install_utils/puppet_utils.rb +15 -2
  16. data/lib/beaker/host.rb +11 -145
  17. data/lib/beaker/host/mac.rb +3 -7
  18. data/lib/beaker/host/mac/pkg.rb +43 -0
  19. data/lib/beaker/host/pswindows.rb +1 -1
  20. data/lib/beaker/host/pswindows/exec.rb +83 -2
  21. data/lib/beaker/host/pswindows/pkg.rb +9 -6
  22. data/lib/beaker/host/unix/exec.rb +105 -0
  23. data/lib/beaker/host/unix/pkg.rb +22 -9
  24. data/lib/beaker/host/windows.rb +2 -1
  25. data/lib/beaker/host/windows/exec.rb +1 -1
  26. data/lib/beaker/host/windows/pkg.rb +4 -7
  27. data/lib/beaker/host_prebuilt_steps.rb +14 -14
  28. data/lib/beaker/hypervisor/aws_sdk.rb +198 -114
  29. data/lib/beaker/hypervisor/openstack.rb +48 -25
  30. data/lib/beaker/shared/host_manager.rb +11 -2
  31. data/lib/beaker/ssh_connection.rb +26 -0
  32. data/lib/beaker/version.rb +1 -1
  33. data/spec/beaker/answers_spec.rb +56 -0
  34. data/spec/beaker/cli_spec.rb +16 -12
  35. data/spec/beaker/command_spec.rb +3 -0
  36. data/spec/beaker/dsl/install_utils/module_utils_spec.rb +2 -2
  37. data/spec/beaker/dsl/install_utils/pe_utils_spec.rb +71 -3
  38. data/spec/beaker/dsl/install_utils/puppet_utils_spec.rb +4 -1
  39. data/spec/beaker/host/unix/pkg_spec.rb +10 -10
  40. data/spec/beaker/host_prebuilt_steps_spec.rb +3 -1
  41. data/spec/beaker/host_spec.rb +8 -2
  42. data/spec/beaker/hypervisor/vagrant_spec.rb +1 -0
  43. metadata +3 -2
@@ -148,7 +148,7 @@ module Beaker
148
148
  env_array << "#{key.to_s.upcase}=\"#{val}\""
149
149
  end
150
150
 
151
- if host['is_cygwin'].nil? or host['is_cygwin'] == true
151
+ if not host.is_powershell?
152
152
  environment_string = env_array.join(' ')
153
153
  "env #{environment_string}"
154
154
  else
@@ -6,13 +6,22 @@ module Beaker
6
6
  #
7
7
  module FacterHelpers
8
8
 
9
- # @!macro common_opts
9
+ # @!macro [new] common_opts
10
10
  # @param [Hash{Symbol=>String}] opts Options to alter execution.
11
11
  # @option opts [Boolean] :silent (false) Do not produce log output
12
12
  # @option opts [Array<Fixnum>] :acceptable_exit_codes ([0]) An array
13
13
  # (or range) of integer exit codes that should be considered
14
14
  # acceptable. An error will be thrown if the exit code does not
15
15
  # match one of the values in this list.
16
+ # @option opts [Boolean] :accept_all_exit_codes (false) Consider all
17
+ # exit codes as passing.
18
+ # @option opts [Boolean] :dry_run (false) Do not actually execute any
19
+ # commands on the SUT
20
+ # @option opts [String] :stdin (nil) Input to be provided during command
21
+ # execution on the SUT.
22
+ # @option opts [Boolean] :pty (false) Execute this command in a pseudoterminal.
23
+ # @option opts [Boolean] :expect_connection_failure (false) Expect this command
24
+ # to result in a connection failure, reconnect and continue execution.
16
25
  # @option opts [Hash{String=>String}] :environment ({}) These will be
17
26
  # treated as extra environment variables that should be set before
18
27
  # running the command.
@@ -5,17 +5,6 @@ module Beaker
5
5
  # for these methods to execute correctly
6
6
  module HieraHelpers
7
7
 
8
- # @!macro common_opts
9
- # @param [Hash{Symbol=>String}] opts Options to alter execution.
10
- # @option opts [Boolean] :silent (false) Do not produce log output
11
- # @option opts [Array<Fixnum>] :acceptable_exit_codes ([0]) An array
12
- # (or range) of integer exit codes that should be considered
13
- # acceptable. An error will be thrown if the exit code does not
14
- # match one of the values in this list.
15
- # @option opts [Hash{String=>String}] :environment ({}) These will be
16
- # treated as extra environment variables that should be set before
17
- # running the command.
18
-
19
8
  # Write hiera config file on one or more provided hosts
20
9
  #
21
10
  # @param[Host, Array<Host>, String, Symbol] host One or more hosts to act upon,
@@ -5,13 +5,22 @@ module Beaker
5
5
  # methods do not require puppet to be installed to execute correctly
6
6
  module HostHelpers
7
7
 
8
- # @!macro common_opts
8
+ # @!macro [new] common_opts
9
9
  # @param [Hash{Symbol=>String}] opts Options to alter execution.
10
10
  # @option opts [Boolean] :silent (false) Do not produce log output
11
11
  # @option opts [Array<Fixnum>] :acceptable_exit_codes ([0]) An array
12
12
  # (or range) of integer exit codes that should be considered
13
13
  # acceptable. An error will be thrown if the exit code does not
14
14
  # match one of the values in this list.
15
+ # @option opts [Boolean] :accept_all_exit_codes (false) Consider all
16
+ # exit codes as passing.
17
+ # @option opts [Boolean] :dry_run (false) Do not actually execute any
18
+ # commands on the SUT
19
+ # @option opts [String] :stdin (nil) Input to be provided during command
20
+ # execution on the SUT.
21
+ # @option opts [Boolean] :pty (false) Execute this command in a pseudoterminal.
22
+ # @option opts [Boolean] :expect_connection_failure (false) Expect this command
23
+ # to result in a connection failure, reconnect and continue execution.
15
24
  # @option opts [Hash{String=>String}] :environment ({}) These will be
16
25
  # treated as extra environment variables that should be set before
17
26
  # running the command.
@@ -414,11 +423,11 @@ module Beaker
414
423
  logger.debug " Trying command #{max_retries} times."
415
424
  logger.debug ".", add_newline=false
416
425
 
417
- result = on host, command, {:acceptable_exit_codes => (0...127), :silent => !verbose}, &block
426
+ result = on host, command, {:accept_all_exit_codes => true, :silent => !verbose}, &block
418
427
  num_retries = 0
419
428
  until desired_exit_codes.include?(result.exit_code)
420
429
  sleep retry_interval
421
- result = on host, command, {:acceptable_exit_codes => (0...127), :silent => !verbose}, &block
430
+ result = on host, command, {:accept_all_exit_codes => true, :silent => !verbose}, &block
422
431
  num_retries += 1
423
432
  logger.debug ".", add_newline=false
424
433
  if (num_retries > max_retries)
@@ -9,19 +9,27 @@ module Beaker
9
9
  # for these methods to execute correctly
10
10
  module PuppetHelpers
11
11
 
12
- # @!macro common_opts
12
+ # @!macro [new] common_opts
13
13
  # @param [Hash{Symbol=>String}] opts Options to alter execution.
14
14
  # @option opts [Boolean] :silent (false) Do not produce log output
15
15
  # @option opts [Array<Fixnum>] :acceptable_exit_codes ([0]) An array
16
16
  # (or range) of integer exit codes that should be considered
17
17
  # acceptable. An error will be thrown if the exit code does not
18
18
  # match one of the values in this list.
19
+ # @option opts [Boolean] :accept_all_exit_codes (false) Consider all
20
+ # exit codes as passing.
21
+ # @option opts [Boolean] :dry_run (false) Do not actually execute any
22
+ # commands on the SUT
23
+ # @option opts [String] :stdin (nil) Input to be provided during command
24
+ # execution on the SUT.
25
+ # @option opts [Boolean] :pty (false) Execute this command in a pseudoterminal.
26
+ # @option opts [Boolean] :expect_connection_failure (false) Expect this command
27
+ # to result in a connection failure, reconnect and continue execution.
19
28
  # @option opts [Hash{String=>String}] :environment ({}) These will be
20
29
  # treated as extra environment variables that should be set before
21
30
  # running the command.
22
31
  #
23
32
 
24
-
25
33
  # Return the name of the puppet user.
26
34
  #
27
35
  # @param [Host] host One object that acts like a Beaker::Host
@@ -322,7 +330,7 @@ module Beaker
322
330
  #
323
331
  # @option opts [Boolean] :expect_changes (false) This option enables
324
332
  # detailed exit codes and causes a test failure
325
- # if `puppet --apply` indicates that there were
333
+ # if `puppet --apply` indicates that there were
326
334
  # no resource changes during its execution.
327
335
  #
328
336
  # @option opts [Boolean] :expect_failures (false) This option enables
@@ -9,18 +9,6 @@ module Beaker
9
9
  # Convenience methods for modifying and reading TrapperKeeper configs
10
10
  module TKHelpers
11
11
 
12
- # @!macro common_opts
13
- # @param [Hash{Symbol=>String}] opts Options to alter execution.
14
- # @option opts [Boolean] :silent (false) Do not produce log output
15
- # @option opts [Array<Fixnum>] :acceptable_exit_codes ([0]) An array
16
- # (or range) of integer exit codes that should be considered
17
- # acceptable. An error will be thrown if the exit code does not
18
- # match one of the values in this list.
19
- # @option opts [Hash{String=>String}] :environment ({}) These will be
20
- # treated as extra environment variables that should be set before
21
- # running the command.
22
- #
23
-
24
12
  # Modify the given TrapperKeeper config file.
25
13
  #
26
14
  # @param [Host] host A host object
@@ -4,18 +4,6 @@ module Beaker
4
4
  # Convenience methods for checking links and moving web content to hosts
5
5
  module WebHelpers
6
6
 
7
- # @!macro common_opts
8
- # @param [Hash{Symbol=>String}] opts Options to alter execution.
9
- # @option opts [Boolean] :silent (false) Do not produce log output
10
- # @option opts [Array<Fixnum>] :acceptable_exit_codes ([0]) An array
11
- # (or range) of integer exit codes that should be considered
12
- # acceptable. An error will be thrown if the exit code does not
13
- # match one of the values in this list.
14
- # @option opts [Hash{String=>String}] :environment ({}) These will be
15
- # treated as extra environment variables that should be set before
16
- # running the command.
17
- #
18
-
19
7
  # Blocks until the port is open on the host specified, returns false
20
8
  # on failure
21
9
  def port_open_within?( host, port = 8140, seconds = 120 )
@@ -121,23 +121,26 @@ module Beaker
121
121
  _, module_name = parse_for_modulename( source_path )
122
122
  end
123
123
 
124
+ target_path = File.join(target_module_dir, module_name)
125
+
124
126
  opts[:protocol] ||= 'scp'
125
127
  case opts[:protocol]
126
128
  when 'scp'
127
129
  #move to the host
130
+ logger.debug "Using scp to transfer #{source_path} to #{target_path}"
128
131
  scp_to host, source_path, target_module_dir, {:ignore => ignore_list}
129
132
  #rename to the selected module name, if not correct
130
133
  cur_path = File.join(target_module_dir, source_name)
131
- new_path = File.join(target_module_dir, module_name)
132
- if (cur_path != new_path)
133
- if host.is_cygwin?
134
- on host, "mv #{cur_path} #{new_path}"
134
+ if (cur_path != target_path)
135
+ if host.is_powershell?
136
+ on host, "move /y #{cur_path} #{target_path}"
135
137
  else
136
- on host, "move /y #{cur_path} #{new_path}"
138
+ on host, "mv #{cur_path} #{target_path}"
137
139
  end
138
140
  end
139
141
  when 'rsync'
140
- rsync_to host, source, File.join(target_module_dir, module_name), {:ignore => ignore_list}
142
+ logger.debug "Using rsync to transfer #{source_path} to #{target_path}"
143
+ rsync_to host, source_path, target_path, {:ignore => ignore_list}
141
144
  else
142
145
  logger.debug "Unsupported transfer protocol, returning nil"
143
146
  nil
@@ -92,6 +92,9 @@ module Beaker
92
92
  # @param [Hash{Symbol=>Symbol, String}] opts The options
93
93
  # @option opts [String] :pe_dir Default directory or URL to pull PE package from
94
94
  # (Otherwise uses individual hosts pe_dir)
95
+ # @option opts [Boolean] :fetch_local_then_push_to_host determines whether
96
+ # you use Beaker as the middleman for this (true), or curl the
97
+ # file from the host (false; default behavior)
95
98
  # @api private
96
99
  def fetch_pe_on_mac(host, opts)
97
100
  path = host['pe_dir'] || opts[:pe_dir]
@@ -107,7 +110,11 @@ module Beaker
107
110
  if not link_exists?("#{path}/#{filename}#{extension}")
108
111
  raise "attempting installation on #{host}, #{path}/#{filename}#{extension} does not exist"
109
112
  end
110
- on host, "cd #{host['working_dir']}; curl -O #{path}/#{filename}#{extension}"
113
+ if opts[:fetch_local_then_push_to_host]
114
+ fetch_and_push_pe(host, path, filename, extension)
115
+ else
116
+ on host, "cd #{host['working_dir']}; curl -O #{path}/#{filename}#{extension}"
117
+ end
111
118
  end
112
119
  end
113
120
 
@@ -119,6 +126,9 @@ module Beaker
119
126
  # (Otherwise uses individual hosts pe_dir)
120
127
  # @option opts [String] :pe_ver_win Default PE version to install or upgrade to
121
128
  # (Otherwise uses individual hosts pe_ver)
129
+ # @option opts [Boolean] :fetch_local_then_push_to_host determines whether
130
+ # you use Beaker as the middleman for this (true), or curl the
131
+ # file from the host (false; default behavior)
122
132
  # @api private
123
133
  def fetch_pe_on_windows(host, opts)
124
134
  path = host['pe_dir'] || opts[:pe_dir]
@@ -135,11 +145,13 @@ module Beaker
135
145
  if not link_exists?("#{path}/#{filename}#{extension}")
136
146
  raise "attempting installation on #{host}, #{path}/#{filename}#{extension} does not exist"
137
147
  end
138
- if host.is_cygwin?
148
+ if opts[:fetch_local_then_push_to_host]
149
+ fetch_and_push_pe(host, path, filename, extension)
150
+ on host, "cd #{host['working_dir']}; chmod 644 #{filename}#{extension}"
151
+ elsif host.is_cygwin?
139
152
  on host, "cd #{host['working_dir']}; curl -O #{path}/#{filename}#{extension}"
140
153
  else
141
- on host, powershell("$webclient = New-Object System.Net.WebClient; $webclient.DownloadFile('#{path}/#{filename}#{extension}','#{host['wor
142
- king_dir']}\\#{filename}#{extension}')")
154
+ on host, powershell("$webclient = New-Object System.Net.WebClient; $webclient.DownloadFile('#{path}/#{filename}#{extension}','#{host['working_dir']}\\#{filename}#{extension}')")
143
155
  end
144
156
  end
145
157
  end
@@ -150,6 +162,9 @@ module Beaker
150
162
  # @param [Hash{Symbol=>Symbol, String}] opts The options
151
163
  # @option opts [String] :pe_dir Default directory or URL to pull PE package from
152
164
  # (Otherwise uses individual hosts pe_dir)
165
+ # @option opts [Boolean] :fetch_local_then_push_to_host determines whether
166
+ # you use Beaker as the middleman for this (true), or curl the
167
+ # file from the host (false; default behavior)
153
168
  # @api private
154
169
  def fetch_pe_on_unix(host, opts)
155
170
  path = host['pe_dir'] || opts[:pe_dir]
@@ -184,7 +199,14 @@ module Beaker
184
199
  else
185
200
  unpack = 'tar -xvf -'
186
201
  unpack = extension =~ /gz/ ? 'gunzip | ' + unpack : unpack
187
- on host, "cd #{host['working_dir']}; curl #{path}/#{filename}#{extension} | #{unpack}"
202
+ if opts[:fetch_local_then_push_to_host]
203
+ fetch_and_push_pe(host, path, filename, extension)
204
+ command_file_push = 'cat '
205
+ else
206
+ command_file_push = "curl #{path}/"
207
+ end
208
+ on host, "cd #{host['working_dir']}; #{command_file_push}#{filename}#{extension} | #{unpack}"
209
+
188
210
  end
189
211
  end
190
212
  end
@@ -199,6 +221,9 @@ module Beaker
199
221
  # (Otherwise uses individual hosts pe_ver)
200
222
  # @option opts [String] :pe_ver_win Default PE version to install or upgrade to on Windows hosts
201
223
  # (Otherwise uses individual Windows hosts pe_ver)
224
+ # @option opts [Boolean] :fetch_local_then_push_to_host determines whether
225
+ # you use Beaker as the middleman for this (true), or curl the
226
+ # file from the host (false; default behavior)
202
227
  # @api private
203
228
  def fetch_pe(hosts, opts)
204
229
  hosts.each do |host|
@@ -240,10 +265,16 @@ module Beaker
240
265
  # @option opts [Boolean] :set_console_password Should we set the PE console password in the answers file? Used during upgrade only.
241
266
  # @option opts [Hash<String>] :answers Pre-set answers based upon ENV vars and defaults
242
267
  # (See {Beaker::Options::Presets.env_vars})
268
+ # @option opts [Boolean] :fetch_local_then_push_to_host determines whether
269
+ # you use Beaker as the middleman for this (true), or curl the
270
+ # file from the host (false; default behavior)
243
271
  #
244
272
  # @example
245
273
  # do_install(hosts, {:type => :upgrade, :pe_dir => path, :pe_ver => version, :pe_ver_win => version_win})
246
274
  #
275
+ # @note on windows, the +:ruby_arch+ host parameter can determine in addition
276
+ # to other settings whether the 32 or 64bit install is used
277
+ #
247
278
  # @api private
248
279
  #
249
280
  def do_install hosts, opts = {}
@@ -272,12 +303,13 @@ module Beaker
272
303
  host['dist'] = "puppet-enterprise-#{version}-#{host['platform']}"
273
304
  elsif host['platform'] =~ /windows/
274
305
  version = host[:pe_ver] || opts['pe_ver_win']
275
- should_install_64bit = !(version_is_less(version, '3.4')) && host.is_x86_64? && !host['install_32'] && !opts['install_32']
306
+ is_config_32 = true == (host['ruby_arch'] == 'x86') || host['install_32'] || opts['install_32']
307
+ should_install_64bit = !(version_is_less(version, '3.4')) && host.is_x86_64? && !is_config_32
276
308
  #only install 64bit builds if
277
309
  # - we are on pe version 3.4+
278
310
  # - we do not have install_32 set on host
279
311
  # - we do not have install_32 set globally
280
- if !(version_is_less(version, '4.0'))
312
+ if !(version_is_less(version, '3.99'))
281
313
  if should_install_64bit
282
314
  host['dist'] = "puppet-agent-#{version}-x64"
283
315
  else
@@ -448,6 +480,9 @@ module Beaker
448
480
  # (Otherwise uses individual hosts pe_dir)
449
481
  # @option opts [String] :pe_ver Default PE version to install
450
482
  # (Otherwise uses individual hosts pe_ver)
483
+ # @option opts [Boolean] :fetch_local_then_push_to_host determines whether
484
+ # you use Beaker as the middleman for this (true), or curl the
485
+ # file from the host (false; default behavior)
451
486
  # @raise [StandardError] When installation times out
452
487
  #
453
488
  # @example
@@ -479,7 +514,7 @@ module Beaker
479
514
  prev_sleep = 0
480
515
  cur_sleep = 1
481
516
  while (res.stdout !~ higgs_re) and (attempts < tries)
482
- res = on host, "cd #{host['working_dir']}/#{host['dist']} && cat #{host['higgs_file']}", :acceptable_exit_codes => (0..255)
517
+ res = on host, "cd #{host['working_dir']}/#{host['dist']} && cat #{host['higgs_file']}", :accept_all_exit_codes => true
483
518
  attempts += 1
484
519
  sleep( cur_sleep )
485
520
  prev_sleep = cur_sleep
@@ -512,6 +547,23 @@ module Beaker
512
547
  do_higgs_install higgs_host, options
513
548
  end
514
549
 
550
+ # Grabs the pe file from a remote host to the machine running Beaker, then
551
+ # scp's the file out to the host.
552
+ #
553
+ # @param [Host] host The host to install on
554
+ # @param [String] path path to the install file
555
+ # @param [String] filename the filename of the pe file (without the extension)
556
+ # @param [String] extension the extension of the pe file
557
+ # @param [String] local_dir the directory to store the pe file in on
558
+ # the Beaker-running-machine
559
+ #
560
+ # @api private
561
+ # @return nil
562
+ def fetch_and_push_pe(host, path, filename, extension, local_dir='tmp/pe')
563
+ fetch_http_file("#{path}", "#{filename}#{extension}", local_dir)
564
+ scp_to host, "#{local_dir}/#{filename}#{extension}", host['working_dir']
565
+ end
566
+
515
567
  end
516
568
  end
517
569
  end
@@ -341,13 +341,17 @@ module Beaker
341
341
  # @param [Hash{Symbol=>String}] opts An options hash
342
342
  # @option opts [String] :version The version of Puppet to install, required
343
343
  # @option opts [String] :win_download_url The url to download puppet from
344
+ #
345
+ # @note on windows, the +:ruby_arch+ host parameter can determine in addition
346
+ # to other settings whether the 32 or 64bit install is used
344
347
  def install_puppet_from_msi( host, opts )
345
348
  #only install 64bit builds if
346
349
  # - we are on puppet version 3.7+
347
350
  # - we do not have install_32 set on host
348
351
  # - we do not have install_32 set globally
349
352
  version = opts[:version]
350
- if !(version_is_less(version, '3.7')) and host.is_x86_64? and not host['install_32'] and not opts['install_32']
353
+ is_config_32 = host['ruby_arch'] == 'x86' || host['install_32'] || opts['install_32']
354
+ if !(version_is_less(version, '3.7')) && host.is_x86_64? && !is_config_32
351
355
  host['dist'] = "puppet-#{version}-x64"
352
356
  else
353
357
  host['dist'] = "puppet-#{version}"
@@ -702,6 +706,10 @@ module Beaker
702
706
  # @option opts [String] :copy_dir_external Directory where puppet-agent
703
707
  # artifact will be pushed to on the external machine
704
708
  # (default: '/root')
709
+ #
710
+ # @note on windows, the +:ruby_arch+ host parameter can determine in addition
711
+ # to other settings whether the 32 or 64bit install is used
712
+ #
705
713
  # @return nil
706
714
  def install_puppetagent_dev_repo( host, opts )
707
715
  opts[:copy_base_local] ||= File.join('tmp', 'repo_configs')
@@ -721,7 +729,12 @@ module Beaker
721
729
  when /^windows$/
722
730
  release_path << 'windows'
723
731
  onhost_copy_base = '`cygpath -smF 35`/'
724
- arch_suffix = arch =~ /64/ ? '64' : '86'
732
+ is_config_32 = host['ruby_arch'] == 'x86' || host['install_32'] || opts['install_32']
733
+ should_install_64bit = host.is_x86_64? && !is_config_32
734
+ # only install 64bit builds if
735
+ # - we do not have install_32 set on host
736
+ # - we do not have install_32 set globally
737
+ arch_suffix = should_install_64bit ? '64' : '86'
725
738
  release_file = "puppet-agent-x#{arch_suffix}.msi"
726
739
  else
727
740
  raise "No repository installation step for #{variant} yet..."
@@ -171,7 +171,11 @@ module Beaker
171
171
  end
172
172
 
173
173
  def is_cygwin?
174
- self['is_cygwin'] == nil || self['is_cygwin'] == true
174
+ self.class == Windows::Host
175
+ end
176
+
177
+ def is_powershell?
178
+ self.class == PSWindows::Host
175
179
  end
176
180
 
177
181
  def platform
@@ -233,130 +237,11 @@ module Beaker
233
237
  self[:ip] ||= get_ip
234
238
  end
235
239
 
236
- #Examine the host system to determine the architecture
237
- #@return [Boolean] true if x86_64, false otherwise
238
- def determine_if_x86_64
239
- if is_cygwin?
240
- if self[:platform] =~ /osx|solaris/
241
- result = exec(Beaker::Command.new("uname -a | grep x86_64"), :acceptable_exit_codes => (0...127))
242
- result.exit_code == 0
243
- else
244
- result = exec(Beaker::Command.new("arch | grep x86_64"), :acceptable_exit_codes => (0...127))
245
- result.exit_code == 0
246
- end
247
- else
248
- result = exec(Beaker::Command.new("wmic os get osarchitecture"), :acceptable_exit_codes => (0...127))
249
- result.stdout =~ /64/
250
- end
251
- end
252
-
253
240
  #@return [Boolean] true if x86_64, false otherwise
254
241
  def is_x86_64?
255
242
  @x86_64 ||= determine_if_x86_64
256
243
  end
257
244
 
258
- # Converts the provided environment file to a new shell script in /etc/profile.d, then sources that file.
259
- # This is for sles based hosts.
260
- # @param [String] env_file The ssh environment file to read from
261
- def mirror_env_to_profile_d env_file
262
- if self[:platform] =~ /sles-/
263
- @logger.debug("mirroring environment to /etc/profile.d on sles platform host")
264
- cur_env = exec(Beaker::Command.new("cat #{env_file}")).stdout
265
- shell_env = ''
266
- cur_env.each_line do |env_line|
267
- shell_env << "export #{env_line}"
268
- end
269
- #here doc it over
270
- exec(Beaker::Command.new("cat << EOF > #{self[:profile_d_env_file]}\n#{shell_env}EOF"))
271
- #set permissions
272
- exec(Beaker::Command.new("chmod +x #{self[:profile_d_env_file]}"))
273
- #keep it current
274
- exec(Beaker::Command.new("source #{self[:profile_d_env_file]}"))
275
- else
276
- #noop
277
- @logger.debug("will not mirror environment to /etc/profile.d on non-sles platform host")
278
- end
279
- end
280
-
281
- #Add the provided key/val to the current ssh environment
282
- #@param [String] key The key to add the value to
283
- #@param [String] val The value for the key
284
- #@example
285
- # host.add_env_var('PATH', '/usr/bin:PATH')
286
- def add_env_var key, val
287
- key = key.to_s.upcase
288
- if self.is_cygwin?
289
- env_file = self[:ssh_env_file]
290
- escaped_val = Regexp.escape(val).gsub('/', '\/').gsub(';', '\;')
291
- #see if the key/value pair already exists
292
- if exec(Beaker::Command.new("grep #{key}=.*#{escaped_val} #{env_file}"), :acceptable_exit_codes => (0..255) ).exit_code == 0
293
- return #nothing to do here, key value pair already exists
294
- #see if the key already exists
295
- elsif exec(Beaker::Command.new("grep #{key} #{env_file}"), :acceptable_exit_codes => (0..255) ).exit_code == 0
296
- exec(Beaker::SedCommand.new(self['platform'], "s/#{key}=/#{key}=#{escaped_val}:/", env_file))
297
- else
298
- exec(Beaker::Command.new("echo \"#{key}=#{val}\" >> #{env_file}"))
299
- end
300
- #update the profile.d to current state
301
- #match it to the contents of ssh_env_file
302
- mirror_env_to_profile_d(env_file)
303
- else #powershell windows
304
- #see if the key/value pair already exists
305
- result = exec(Beaker::Command.new("set #{key}"), :acceptable_exit_codes => (0..255))
306
- subbed_result = result.stdout.chomp
307
- if result.exit_code == 0
308
- subbed_result = subbed_result.gsub(/#{Regexp.escape(val.gsub(/'|"/, ''))}/, '')
309
- end
310
- #not present, add it
311
- if subbed_result == result.stdout.chomp
312
- exec(Beaker::Command.new("setx /M #{key} %#{key}%;#{val}"))
313
- exec(Beaker::Command.new("set #{key}=%#{key}%;#{val}"))
314
- end
315
- end
316
- end
317
-
318
- #Return the value of a specific env var
319
- #@param [String] key The key to look for
320
- #@example
321
- # host.get_env_var('path')
322
- def get_env_var key
323
- key = key.to_s.upcase
324
- exec(Beaker::Command.new("env | grep #{key}"), :acceptable_exit_codes => (0..255)).stdout.chomp
325
- end
326
-
327
- #Delete the provided key/val from the current ssh environment
328
- #@param [String] key The key to delete the value from
329
- #@param [String] val The value to delete for the key
330
- #@example
331
- # host.delete_env_var('PATH', '/usr/bin:PATH')
332
- def delete_env_var key, val
333
- key = key.to_s.upcase
334
- if self.is_cygwin?
335
- env_file = self[:ssh_env_file]
336
- val = Regexp.escape(val).gsub('/', '\/').gsub(';', '\;')
337
- #if the key only has that single value remove the entire line
338
- exec(Beaker::SedCommand.new(self['platform'], "/#{key}=#{val}$/d", env_file))
339
- #value in middle of list
340
- exec(Beaker::SedCommand.new(self['platform'], "s/#{key}=\\(.*\\)[;:]#{val}/#{key}=\\1/", env_file))
341
- #value in start of list
342
- exec(Beaker::SedCommand.new(self['platform'], "s/#{key}=#{val}[;:]/#{key}=/", env_file))
343
- #update the profile.d to current state
344
- #match it to the contents of ssh_env_file
345
- mirror_env_to_profile_d(env_file)
346
- else #powershell windows
347
- #get the current value of the key
348
- result = exec(Beaker::Command.new("set #{key}"), :acceptable_exit_codes => (0..255))
349
- subbed_result = result.stdout.chomp
350
- if result.exit_code == 0
351
- subbed_result = subbed_result.gsub(/#{Regexp.escape(val.gsub(/'|"/, ''))}/, '')
352
- end
353
- if subbed_result != result
354
- #set to the truncated value
355
- self.add_env_var(key, subbed_result)
356
- end
357
- end
358
- end
359
-
360
245
  def connection
361
246
  @connection ||= SshConnection.connect( reachable_name,
362
247
  self['user'],
@@ -403,8 +288,10 @@ module Beaker
403
288
  end
404
289
  if options[:expect_connection_failure] && result.exit_code
405
290
  # should have had a connection failure, but didn't
406
- # this can happen because of timing issues, so just raise a warning for now
407
- @logger.warn "Host '#{self}' should have resulted in a connection failure running:\n #{cmdline}\nLast #{@options[:trace_limit]} lines of output were:\n#{result.formatted_output(@options[:trace_limit])}"
291
+ # wait to see if the connection failure will be generation, otherwise raise error
292
+ if not connection.wait_for_connection_failure
293
+ raise CommandFailure, "Host '#{self}' should have resulted in a connection failure running:\n #{cmdline}\nLast #{@options[:trace_limit]} lines of output were:\n#{result.formatted_output(@options[:trace_limit])}"
294
+ end
408
295
  end
409
296
  # No, TestCase has the knowledge about whether its failed, checking acceptable
410
297
  # exit codes at the host level and then raising...
@@ -418,27 +305,6 @@ module Beaker
418
305
  end
419
306
  end
420
307
 
421
- # Recursively remove the path provided
422
- # @param [String] path The path to remove
423
- def rm_rf path
424
- exec(Beaker::Command.new("rm -rf #{path}"))
425
- end
426
-
427
- # Create the provided directory structure on the host
428
- # @param [String] dir The directory structure to create on the host
429
- # @return [Boolean] True, if directory construction succeeded, otherwise False
430
- def mkdir_p dir
431
- if self.is_cygwin?
432
- cmd = "mkdir -p #{dir}"
433
- else
434
- windows_dirstring = dir.gsub('/','\\')
435
- cmd = "if not exist #{windows_dirstring} (md #{windows_dirstring})"
436
- end
437
-
438
- result = exec(Beaker::Command.new(cmd), :acceptable_exit_codes => [0, 1])
439
- result.exit_code == 0
440
- end
441
-
442
308
  # scp files from the localhost to this test host, if a directory is provided it is recursively copied.
443
309
  # If the provided source is a directory both the contents of the directory and the directory
444
310
  # itself will be copied to the host, if you only want to copy directory contents you will either need to specify
@@ -608,12 +474,12 @@ module Beaker
608
474
  end
609
475
 
610
476
  [
611
- 'windows',
612
- 'pswindows',
613
477
  'unix',
614
478
  'aix',
615
479
  'mac',
616
480
  'freebsd',
481
+ 'windows',
482
+ 'pswindows',
617
483
  ].each do |lib|
618
484
  require "beaker/host/#{lib}"
619
485
  end