beaker 2.10.0 → 2.11.0

Sign up to get free protection for your applications and to get access to all the features.
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