beaker 4.23.1 → 4.27.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: 442731199e19c2bfbd64dbc64851c80155659e8e7deee3e6512fe05006056efb
4
- data.tar.gz: 51c93bf9df5a4ef96c3739dbbae19d41ca70e91f03a250a4e6c5418294d7cfc9
3
+ metadata.gz: b7bc325aade2e41145790de7c1c5d8c3f07b054dc22999762cbbe812f81deeca
4
+ data.tar.gz: 403bc79d97df6b8b30d59a5caa8ef26434e1adfc6420025cc15d3267c149aaef
5
5
  SHA512:
6
- metadata.gz: 838c910a425573e64ae111686c1a3b1da59c2cfc4d485b177af8374d103a1879aab0a41fd0f9074a438c0adda41d4acbd3adc55017d7e49a52df79ffc1c91403
7
- data.tar.gz: 6869be1711abcdeaf5166213ec3ba082e5e1210576c0fab3d777cb0a902793465acd44bd4e36a8ae6e7aa2ebb2be5cf6f4d0f096c65c12c0ac765163e891741c
6
+ metadata.gz: fe7a3e52bc3db292ae174f97f2c93b2455e032693956931b60e6bc5cc1c0caf84be93f92d877d9bcdb7698f77e3367c08e0781e2e858b5c9a5d335d99d6b059f
7
+ data.tar.gz: 6616a6a1bb3399a30defc9536b64b67d7f742d67dddf09f8dad70604a0df9b9c4460c414080e70f42001495bdb47e1dcab8a9354210fb67348453ea065933707
@@ -0,0 +1,8 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: bundler
4
+ directory: "/"
5
+ schedule:
6
+ interval: daily
7
+ time: "13:00"
8
+ open-pull-requests-limit: 10
@@ -1,5 +1,5 @@
1
1
  before_install:
2
- - gem update --system 2.2.1
2
+ - gem update
3
3
  - gem --version
4
4
  language: ruby
5
5
  script: "bundle exec rake travis"
@@ -7,6 +7,4 @@ notifications:
7
7
  email: false
8
8
  rvm:
9
9
  - 2.6
10
- - 2.0.0
11
- - 1.9.3
12
- - 1.8.7-p374
10
+ - 2.4
@@ -20,7 +20,55 @@ The headers used in [Keep a Changelog](http://keepachangelog.com) are:
20
20
  - Fixed - for any bug fixes.
21
21
  - Security - in case of vulnerabilities.
22
22
 
23
- # [Unreleased](https://github.com/puppetlabs/beaker/compare/4.23.1...master)
23
+ # [Unreleased](https://github.com/puppetlabs/beaker/compare/4.27.0...master)
24
+
25
+ # [4.27.0](https://github.com/puppetlabs/beaker/compare/4.26.0...4.27.0) - 07-24-2020
26
+
27
+ ### Changed
28
+
29
+ - Updated dependency versions and minimum Ruby version in gemspec to Ruby 2.4, which is the minimum
30
+ version Beaker will run with.
31
+ - Added Travis unit testing and disabled Jenkins integrations in preparation for transferring the
32
+ repo to Vox Pupuli
33
+
34
+
35
+ # [4.26.0](https://github.com/puppetlabs/beaker/compare/4.25.0...4.26.0)
36
+
37
+ ### Changed
38
+
39
+ - Fixed deprecated SSH option handling for `verify_ssh_key` being passed into Net::SSH. #1655
40
+
41
+ ### Removed
42
+
43
+ - Removed deprecated use of `paranoid` flag with Net::SSH. #1655
44
+
45
+ # [4.25.0](https://github.com/puppetlabs/beaker/compare/4.24.0...4.25.0)
46
+
47
+ ### Added
48
+
49
+ - Execution of Beaker directly through ruby on localhost #1637 ([#1637](https://github.com/puppetlabs/beaker/pull/1637))
50
+
51
+ ### Fixed
52
+
53
+ - Reliability improvements to the `Host#reboot` method ([#1656](https://github.com/puppetlabs/beaker/pull/1656)) ([#1659](https://github.com/puppetlabs/beaker/pull/1659))
54
+
55
+ # [4.24.0](https://github.com/puppetlabs/beaker/compare/4.23.0...4.24.0) - 2020-06-05
56
+
57
+ ### Added
58
+
59
+ - Host method which ([#1651](https://github.com/puppetlabs/beaker/pull/1651))
60
+
61
+ ### Fixed
62
+
63
+ - Fixed implementation for cat and file_exists? host methods for PSWindows ([#1654](https://github.com/puppetlabs/beaker/pull/1654))
64
+ - Fixed implementation for mkdir_p host method for PSWindows ([#1657](https://github.com/puppetlabs/beaker/pull/1657))
65
+
66
+ # [4.23.2](https://github.com/puppetlabs/beaker/compare/4.23.1...4.23.2)
67
+
68
+ ### Fixed
69
+
70
+ - Fixed Beaker's behavior when the `strict_host_key_checking` option is
71
+ provided in the SSH config and Net-SSH > 5 is specified. (#1652)
24
72
 
25
73
  # [4.23.1](https://github.com/puppetlabs/beaker/compare/4.23.0...4.23.1)
26
74
 
data/CODEOWNERS CHANGED
@@ -1,2 +0,0 @@
1
- * @puppetlabs/beaker
2
- * @puppetlabs/dio
data/Rakefile CHANGED
@@ -26,10 +26,7 @@ task :history do
26
26
  Rake::Task['history:gen'].invoke
27
27
  end
28
28
 
29
- task :travis do
30
- Rake::Task['yard'].invoke if !Beaker::Shared::Semvar.version_is_less(RUBY_VERSION, '2.0.0')
31
- Rake::Task['spec'].invoke
32
- end
29
+ task travis: [:yard, :test]
33
30
 
34
31
  module HarnessOptions
35
32
  defaults = {
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
18
18
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
19
  s.require_paths = ["lib"]
20
20
 
21
- s.required_ruby_version = Gem::Requirement.new('>= 2.1.8')
21
+ s.required_ruby_version = Gem::Requirement.new('>= 2.4')
22
22
 
23
23
  # Testing dependencies
24
24
  s.add_development_dependency 'rspec', '~> 3.0'
@@ -39,7 +39,7 @@ Gem::Specification.new do |s|
39
39
  # Run time dependencies
40
40
  s.add_runtime_dependency 'minitest', '~> 5.4'
41
41
  s.add_runtime_dependency 'minitar', '~> 0.6'
42
- s.add_runtime_dependency 'pry-byebug', '~> 3.6'
42
+ s.add_runtime_dependency 'pry-byebug', '~> 3.9'
43
43
  # pry-byebug can have issues with native readline libs so add rb-readline
44
44
  s.add_runtime_dependency 'rb-readline', '~> 0.5.3'
45
45
 
@@ -6,7 +6,7 @@ require 'rsync'
6
6
  require 'beaker/dsl/helpers'
7
7
  require 'beaker/dsl/patterns'
8
8
 
9
- [ 'command', 'ssh_connection'].each do |lib|
9
+ [ 'command', 'ssh_connection', 'local_connection' ].each do |lib|
10
10
  require "beaker/#{lib}"
11
11
  end
12
12
 
@@ -294,6 +294,11 @@ module Beaker
294
294
 
295
295
  def connection
296
296
  # create new connection object if necessary
297
+ if self['hypervisor'] == 'none' && @name == 'localhost'
298
+ @connection ||= LocalConnection.connect( { :ssh_env_file => self['ssh_env_file'], :logger => @logger })
299
+ return @connection
300
+ end
301
+
297
302
  @connection ||= SshConnection.connect( { :ip => self['ip'], :vmhostname => self['vmhostname'], :hostname => @name },
298
303
  self['user'],
299
304
  self['ssh'], { :logger => @logger, :ssh_connection_preference => self[:ssh_connection_preference]} )
@@ -104,9 +104,9 @@ module PSWindows::Exec
104
104
  # @param [String] dir The directory structure to create on the host
105
105
  # @return [Boolean] True, if directory construction succeeded, otherwise False
106
106
  def mkdir_p dir
107
- windows_dirstring = dir.gsub('/','\\')
108
- cmd = "if not exist #{windows_dirstring} (md #{windows_dirstring})"
109
- result = exec(Beaker::Command.new(cmd), :acceptable_exit_codes => [0, 1])
107
+ normalized_path = dir.gsub('/','\\')
108
+ result = exec(powershell("New-Item -Path '#{normalized_path}' -ItemType 'directory'"),
109
+ :acceptable_exit_codes => [0, 1])
110
110
  result.exit_code == 0
111
111
  end
112
112
 
@@ -237,4 +237,19 @@ module PSWindows::Exec
237
237
  end
238
238
  end
239
239
 
240
+ #First path it finds for the command executable
241
+ #@param [String] command The command executable to search for
242
+ #
243
+ # @return [String] Path to the searched executable or empty string if not found
244
+ #
245
+ #@example
246
+ # host.which('ruby')
247
+ def which(command)
248
+ where_command = "cmd /C \"where #{command}\""
249
+
250
+ result = execute(where_command, :accept_all_exit_codes => true)
251
+ return '' if result.empty?
252
+
253
+ result
254
+ end
240
255
  end
@@ -21,11 +21,11 @@ module PSWindows::File
21
21
  end
22
22
 
23
23
  def cat(path)
24
- exec(powershell("type #{path}"))
24
+ exec(powershell("type #{path}")).stdout
25
25
  end
26
26
 
27
27
  def file_exist?(path)
28
- result = exec(Beaker::Command.new("if exist #{path} echo true"), :acceptable_exit_codes => [0, 1])
29
- result.stdout =~ /true/
28
+ result = exec(Beaker::Command.new("if exist #{path} echo true"), accept_all_exit_codes: true)
29
+ result.stdout.strip == 'true'
30
30
  end
31
31
  end
@@ -14,15 +14,27 @@ module Unix::Exec
14
14
  def reboot(wait_time=10, max_connection_tries=9, uptime_retries=18)
15
15
  require 'time'
16
16
 
17
+ attempts = 0
18
+
19
+ original_boot_time_str = nil
20
+ original_boot_time_line = nil
17
21
  begin
18
22
  original_boot_time_str = exec(Beaker::Command.new('who -b'), {:max_connection_tries => max_connection_tries, :silent => true}).stdout
19
23
  original_boot_time_line = original_boot_time_str.lines.grep(/boot/).first
20
24
 
21
- raise Beaker::Host::RebootFailure, "Could not find system boot time using 'who -b': #{original_boot_time_str}" unless original_boot_time_line
25
+ raise Beaker::Host::RebootFailure, "Could not find system boot time using 'who -b': '#{original_boot_time_str}'" unless original_boot_time_line
22
26
 
23
27
  original_boot_time = Time.parse(original_boot_time_line)
24
28
 
25
29
  exec(Beaker::Command.new('/bin/systemctl reboot -i || reboot || /sbin/shutdown -r now'), :expect_connection_failure => true)
30
+ rescue Beaker::Host::RebootFailure => e
31
+ attempts += 1
32
+ if attempts < uptime_retries
33
+ @logger.debug("Could not get initial boot time. Will retry #{uptime_retries - attempts} more times.")
34
+ retry
35
+ else
36
+ raise
37
+ end
26
38
  rescue Beaker::Host::CommandFailure => e
27
39
  raise Beaker::Host::RebootFailure, "Command failed when attempting to reboot: #{e.message}"
28
40
  rescue RuntimeError => e
@@ -38,7 +50,11 @@ module Unix::Exec
38
50
  sleep wait_time
39
51
 
40
52
  current_boot_time_str = exec(Beaker::Command.new('who -b'), {:max_connection_tries => max_connection_tries, :silent => true}).stdout
41
- current_boot_time = Time.parse(current_boot_time_str.lines.grep(/boot/).first)
53
+ current_boot_time_line = current_boot_time_str.lines.grep(/boot/).first
54
+
55
+ raise Beaker::Host::RebootFailure, "Could not find system boot time using 'who -b': '#{current_boot_time_str}'" unless current_boot_time_line
56
+
57
+ current_boot_time = Time.parse(current_boot_time_line)
42
58
 
43
59
  @logger.debug("Original Boot Time: #{original_boot_time}")
44
60
  @logger.debug("Current Boot Time: #{current_boot_time}")
@@ -63,42 +79,6 @@ module Unix::Exec
63
79
  end
64
80
  end
65
81
 
66
- def uptime_int(uptime_str)
67
- time_array = uptime_str.split(", ")
68
- accumulated_mins = 0
69
- time_array.each do |time_segment|
70
- value, unit = time_segment.split
71
- if unit.nil?
72
- # 20:47 case: hours & mins
73
- hours, mins = value.split(":")
74
- accumulated_mins += (hours.to_i * 60 + mins.to_i)
75
- elsif unit =~ /day(s)?/
76
- accumulated_mins += (value.to_i * 1440) # 60 * 24 = 1440
77
- elsif unit =~ /min(s)?/
78
- accumulated_mins += value.to_i
79
- else
80
- raise ArgumentError, "can't parse uptime segment: #{time_segment}"
81
- end
82
- end
83
-
84
- accumulated_mins
85
- end
86
-
87
- def parse_uptime(uptime)
88
- # get String from up to users
89
- # eg 19:52 up 14 mins, 2 users, load averages: 2.95 4.19 4.31
90
- # 8:03 up 52 days, 20:47, 3 users, load averages: 1.36 1.42 1.40
91
- # 22:19 up 54 days, 1 min, 4 users, load averages: 2.08 2.06 2.27
92
- regexp = /.*up (.*)[[:space:]]+[[:digit:]]+ user.*/
93
- result = uptime.match regexp
94
- if self['platform'] =~ /solaris-/ && result[1].empty?
95
- return "0 min"
96
- end
97
- raise "Couldn't parse uptime: #{uptime}" if result.nil?
98
-
99
- result[1].strip.chomp(",")
100
- end
101
-
102
82
  def echo(msg, abs=true)
103
83
  (abs ? '/bin/echo' : 'echo') + " #{msg}"
104
84
  end
@@ -435,4 +415,19 @@ module Unix::Exec
435
415
  true
436
416
  end
437
417
 
418
+ #First path it finds for the command executable
419
+ #@param [String] command The command executable to search for
420
+ #
421
+ # @return [String] Path to the searched executable or empty string if not found
422
+ #
423
+ #@example
424
+ # host.which('ruby')
425
+ def which(command)
426
+ which_command = "which #{command}"
427
+
428
+ result = execute(which_command, :accept_all_exit_codes => true)
429
+ return '' if result.empty?
430
+
431
+ result
432
+ end
438
433
  end
@@ -0,0 +1,86 @@
1
+ require 'open3'
2
+
3
+ module Beaker
4
+ class LocalConnection
5
+
6
+ attr_accessor :logger, :hostname, :ip
7
+
8
+ def initialize options = {}
9
+ @logger = options[:logger]
10
+ @ssh_env_file = File.expand_path(options[:ssh_env_file])
11
+ @hostname = 'localhost'
12
+ @ip = '127.0.0.1'
13
+ @options = options
14
+ end
15
+
16
+ def self.connect options = {}
17
+ connection = new options
18
+ connection.connect
19
+ connection
20
+ end
21
+
22
+ def connect options = {}
23
+ @logger.debug "Local connection, no connection to start"
24
+ end
25
+
26
+ def close
27
+ @logger.debug "Local connection, no connection to close"
28
+ end
29
+
30
+ def with_env(env)
31
+ backup = ENV.to_hash
32
+ ENV.replace(env)
33
+ yield
34
+ ensure
35
+ ENV.replace(backup)
36
+ end
37
+
38
+ def execute command, options = {}, stdout_callback = nil, stderr_callback = stdout_callback
39
+ result = Result.new(@hostname, command)
40
+ envs = {}
41
+ if File.readable?(@ssh_env_file)
42
+ File.foreach(@ssh_env_file) do |line|
43
+ key, value = line.split('=')
44
+ envs[key] = value
45
+ end
46
+ end
47
+
48
+ begin
49
+ clean_env = ENV.reject{ |k| k =~ /^BUNDLE|^RUBY|^GEM/ }
50
+
51
+ with_env(clean_env) do
52
+ std_out, std_err, status = Open3.capture3(envs, command)
53
+ result.stdout << std_out
54
+ result.stderr << std_err
55
+ result.exit_code = status.exitstatus
56
+ end
57
+ rescue => e
58
+ result.stderr << e.inspect
59
+ result.exit_code = 1
60
+ end
61
+
62
+ result.finalize!
63
+ @logger.last_result = result
64
+ result
65
+ end
66
+
67
+ def scp_to(source, target, _options = {})
68
+
69
+ result = Result.new(@hostname, [source, target])
70
+ begin
71
+ FileUtils.cp_r source, target
72
+ rescue Errno::ENOENT => e
73
+ @logger.warn "#{e.class} error in cp'ing. Forcing the connection to close, which should " \
74
+ "raise an error."
75
+ end
76
+
77
+ result.stdout << " CP'ed file #{source} to #{target}"
78
+ result.exit_code = 0
79
+ result
80
+ end
81
+
82
+ def scp_from(source, target, options = {})
83
+ scp_to(target, source, options)
84
+ end
85
+ end
86
+ end
@@ -68,6 +68,16 @@ module Beaker
68
68
  max_connection_tries = options[:max_connection_tries] || 11
69
69
  begin
70
70
  @logger.debug "Attempting ssh connection to #{host}, user: #{user}, opts: #{ssh_opts}"
71
+
72
+ # Work around net-ssh 6+ incompatibilities
73
+ if ssh_opts.include?(:strict_host_key_checking) && (Net::SSH::Version::CURRENT.major > 5)
74
+ strict_host_key_checking = ssh_opts.delete(:strict_host_key_checking)
75
+
76
+ unless ssh_opts[:verify_host_key].is_a?(Symbol)
77
+ ssh_opts[:verify_host_key] ||= strict_host_key_checking ? :always : :never
78
+ end
79
+ end
80
+
71
81
  Net::SSH.start(host, user, ssh_opts)
72
82
  rescue *RETRYABLE_EXCEPTIONS => e
73
83
  if try <= max_connection_tries
@@ -1,5 +1,5 @@
1
1
  module Beaker
2
2
  module Version
3
- STRING = '4.23.1'
3
+ STRING = '4.27.0'
4
4
  end
5
5
  end
@@ -99,5 +99,59 @@ module Beaker
99
99
  to be == "set \"LD_PATH=/:/tmp\" && "
100
100
  end
101
101
  end
102
+
103
+ describe '#which' do
104
+ before do
105
+ allow(instance).to receive(:execute)
106
+ .with(where_command, :accept_all_exit_codes => true).and_return(result)
107
+ end
108
+ let(:where_command) { "cmd /C \"where ruby\"" }
109
+
110
+ context 'when only the environment variable PATH is used' do
111
+ let(:result) { "C:\\Ruby26-x64\\bin\\ruby.exe" }
112
+
113
+ it 'returns the correct path' do
114
+ response = instance.which('ruby')
115
+
116
+ expect(response).to eq(result)
117
+ end
118
+ end
119
+
120
+ context 'when command is not found' do
121
+ let(:where_command) { "cmd /C \"where unknown\"" }
122
+ let(:result) { '' }
123
+
124
+ it 'return empty string if command is not found' do
125
+ response = instance.which('unknown')
126
+
127
+ expect(response).to eq(result)
128
+ end
129
+ end
130
+ end
131
+
132
+ describe '#mkdir_p' do
133
+ let(:dir_path) { "C:\\tmpdir\\my_dir" }
134
+ let(:beaker_command) { instance_spy(Beaker::Command) }
135
+ let(:command) {"-Command New-Item -Path '#{dir_path}' -ItemType 'directory'"}
136
+ let(:result) { instance_spy(Beaker::Result) }
137
+
138
+ before do
139
+ allow(Beaker::Command).to receive(:new).
140
+ with('powershell.exe', array_including(command)).and_return(beaker_command)
141
+ allow(instance).to receive(:exec).with(beaker_command, :acceptable_exit_codes => [0, 1]).and_return(result)
142
+ end
143
+
144
+ it 'returns true and creates folder structure' do
145
+ allow(result).to receive(:exit_code).and_return(0)
146
+
147
+ expect(instance.mkdir_p(dir_path)).to be(true)
148
+ end
149
+
150
+ it 'returns false if failed to create directory structure' do
151
+ allow(result).to receive(:exit_code).and_return(1)
152
+
153
+ expect(instance.mkdir_p(dir_path)).to be(false)
154
+ end
155
+ end
102
156
  end
103
157
  end
@@ -25,11 +25,31 @@ module Beaker
25
25
  let (:instance) { PSWindowsFileTest.new(opts, logger) }
26
26
 
27
27
  describe '#cat' do
28
+ let(:path) { '/path/to/cat' }
29
+ let(:content) { 'file content' }
28
30
  it 'reads output for file' do
29
- path = '/path/to/delete'
30
- expect(instance).to receive(:exec)
31
+ expect(instance).to receive(:exec).and_return(double(stdout: content))
31
32
  expect(Beaker::Command).to receive(:new).with('powershell.exe', array_including("-Command type #{path}"))
32
- instance.cat(path)
33
+ expect(instance.cat(path)).to eq(content)
34
+ end
35
+ end
36
+
37
+ describe '#file_exist?' do
38
+ let(:path) { '/path/to/test/file.txt' }
39
+ context 'file exists' do
40
+ it 'returns true' do
41
+ expect(instance).to receive(:exec).and_return(double(stdout: "true\n"))
42
+ expect(Beaker::Command).to receive(:new).with("if exist #{path} echo true")
43
+ expect(instance.file_exist?(path)).to eq(true)
44
+ end
45
+ end
46
+
47
+ context 'file does not exist' do
48
+ it 'returns false' do
49
+ expect(instance).to receive(:exec).and_return(double(stdout: ""))
50
+ expect(Beaker::Command).to receive(:new).with("if exist #{path} echo true")
51
+ expect(instance.file_exist?(path)).to eq(false)
52
+ end
33
53
  end
34
54
  end
35
55
 
@@ -39,7 +59,6 @@ module Beaker
39
59
 
40
60
  before do
41
61
  allow(instance).to receive(:execute).with(anything)
42
-
43
62
  end
44
63
 
45
64
  context 'with dirname sent' do
@@ -313,40 +313,32 @@ module Beaker
313
313
 
314
314
  end
315
315
 
316
- describe '#parse_uptime' do
317
- it 'parses variation of uptime string' do
318
- expect(instance.parse_uptime("19:52 up 14 mins, 2 users, load averages: 2.95 4.19 4.31")).to be == "14 mins"
316
+ describe '#which' do
317
+ before do
318
+ allow(instance).to receive(:execute)
319
+ .with(where_command, :accept_all_exit_codes => true).and_return(result)
319
320
  end
320
- it 'parses variation 2 of uptime string' do
321
- expect(instance.parse_uptime("8:03 up 52 days, 20:47, 3 users, load averages: 1.36 1.42 1.40")).to be == "52 days, 20:47"
322
- end
323
- it 'parses variation 3 of uptime string' do
324
- expect(instance.parse_uptime("22:19 up 54 days, 1 min, 4 users, load averages: 2.08 2.06 2.27")).to be == "54 days, 1 min"
325
- end
326
- it 'parses variation 4 of uptime string' do
327
- expect(instance.parse_uptime("18:44:45 up 5 min, 0 users, load average: 0.14, 0.11, 0.05")).to be == "5 min"
328
- end
329
- it 'parses solaris\'s "just up" without time message' do
330
- opts['platform'] = 'solaris-11-x86_64'
331
- expect(instance.parse_uptime("10:05am up 0 users, load average: 0.66, 0.14, 0.05")).to be == "0 min"
332
- end
333
- end
334
321
 
335
- describe '#uptime_int' do
336
- it 'parses time segment variation into a minute value' do
337
- expect(instance.uptime_int("14 mins")).to be == 14
338
- end
339
- it 'parses time segment variation 2 into a minute value' do
340
- expect(instance.uptime_int("52 days, 20:47")).to be == 76127
341
- end
342
- it 'parses time segment variation 3 into a minute value' do
343
- expect(instance.uptime_int("54 days, 1 min")).to be == 77761
322
+ context 'when only the environment variable PATH is used' do
323
+ let(:where_command) { "which ruby" }
324
+ let(:result) { "/usr/bin/ruby.exe" }
325
+
326
+ it 'returns the correct path' do
327
+ response = instance.which('ruby')
328
+
329
+ expect(response).to eq(result)
344
330
  end
345
- it 'parses time segment variation 4 into a minute value' do
346
- expect(instance.uptime_int("54 days")).to be == 77760
347
331
  end
348
- it 'raises if we pass garbage to it' do
349
- expect { instance.uptime_int("solaris roxx my soxx") }.to raise_error
332
+
333
+ context 'when command is not found' do
334
+ let(:where_command) { "which unknown" }
335
+ let(:result) { '' }
336
+
337
+ it 'return empty string if command is not found' do
338
+ response = instance.which('unknown')
339
+
340
+ expect(response).to eq(result)
341
+ end
350
342
  end
351
343
  end
352
344
  end
@@ -349,7 +349,13 @@ module Beaker
349
349
  allow( result ).to receive( :exit_code ).and_return( 0 )
350
350
  allow( host ).to receive( :exec ).and_return( result )
351
351
 
352
- expect( Beaker::Command ).to receive(:new).with("if not exist test\\test\\test (md test\\test\\test)")
352
+ expect( Beaker::Command ).to receive(:new).
353
+ with("powershell.exe", ["-ExecutionPolicy Bypass",
354
+ "-InputFormat None",
355
+ "-NoLogo",
356
+ "-NoProfile",
357
+ "-NonInteractive",
358
+ "-Command New-Item -Path 'test\\test\\test' -ItemType 'directory'"])
353
359
  expect( host.mkdir_p('test/test/test') ).to be == true
354
360
 
355
361
  end
@@ -0,0 +1,106 @@
1
+ require 'spec_helper'
2
+ require 'net/ssh'
3
+
4
+ module Beaker
5
+ describe LocalConnection do
6
+ let( :options ) { { :logger => double('logger').as_null_object, :ssh_env_file => '/path/to/ssh/file'} }
7
+ subject(:connection) { LocalConnection.new(options) }
8
+
9
+ before :each do
10
+ allow( subject ).to receive(:sleep)
11
+ end
12
+
13
+ describe '#self.connect' do
14
+ it 'loggs message' do
15
+ expect(options[:logger]).to receive(:debug).with('Local connection, no connection to start')
16
+ connection_constructor = LocalConnection.connect(options)
17
+ expect( connection_constructor ).to be_a_kind_of LocalConnection
18
+ end
19
+ end
20
+
21
+ describe '#close' do
22
+ it 'logs message' do
23
+ expect(options[:logger]).to receive(:debug).with('Local connection, no connection to close')
24
+ connection.close
25
+ end
26
+ end
27
+
28
+ describe '#with_env' do
29
+ it 'sets envs temporarily' do
30
+ connection.connect
31
+ connection.with_env({'my_env' => 'my_env_value'}) do
32
+ expect(ENV.to_hash).to include({'my_env' => 'my_env_value'})
33
+ end
34
+ expect(ENV.to_hash).not_to include({'my_env' => 'my_env_value'})
35
+ end
36
+ end
37
+
38
+ describe '#execute' do
39
+ it 'calls open3' do
40
+ expect( Open3 ).to receive( :capture3 ).with({}, 'my_command')
41
+ connection.connect
42
+ expect(connection.execute('my_command')).to be_a_kind_of Result
43
+ end
44
+
45
+ it 'sets stdout, stderr and exitcode' do
46
+ allow(Open3).to receive(:capture3).and_return(['stdout', 'stderr', double({exitstatus: 0})])
47
+ connection.connect
48
+ result = connection.execute('my_command')
49
+ expect(result.exit_code).to eq(0)
50
+ expect(result.stdout).to eq('stdout')
51
+ expect(result.stderr).to eq('stderr')
52
+ end
53
+
54
+ it 'sets logger last_result' do
55
+ allow(Open3).to receive(:capture3).and_return(['stdout', 'stderr', double({exitstatus: 0})])
56
+ expect(options[:logger]).to receive(:last_result=).with(an_instance_of(Result))
57
+ connection.connect
58
+ connection.execute('my_command')
59
+ end
60
+
61
+ it 'sets exitcode to 1, when Open3 raises exeception' do
62
+ allow(Open3).to receive(:capture3).and_raise Errno::ENOENT
63
+ connection.connect
64
+ result = connection.execute('my_failing_command')
65
+ expect(result.exit_code).to eq(1)
66
+ end
67
+ end
68
+
69
+ describe '#scp_to' do
70
+ let(:source) { '/source/path' }
71
+ let(:dest) { '/dest/path' }
72
+
73
+ it 'calls FileUtils.cp_r' do
74
+ connection.connect
75
+ expect(FileUtils).to receive(:cp_r).with(source, dest)
76
+ connection.scp_to(source, dest)
77
+ end
78
+
79
+ it 'returns and Result object' do
80
+ expect(FileUtils).to receive(:cp_r).and_return(true)
81
+ connection.connect
82
+ result = connection.scp_to(source, dest)
83
+ expect(result.exit_code).to eq(0)
84
+ expect(result.stdout).to eq(" CP'ed file #{source} to #{dest}")
85
+ end
86
+
87
+ it 'catches exception and logs warning message' do
88
+ allow(FileUtils).to receive(:cp_r).and_raise Errno::ENOENT
89
+ expect(options[:logger]).to receive(:warn).with("Errno::ENOENT error in cp'ing. Forcing the connection to close, which should raise an error.")
90
+ connection.connect
91
+ connection.scp_to(source, dest)
92
+ end
93
+ end
94
+
95
+ describe '#scp_from' do
96
+ let(:source) { '/source/path' }
97
+ let(:dest) { '/dest/path' }
98
+
99
+ it 'callse scp_to with reversed params' do
100
+ expect(connection).to receive(:scp_to).with(dest, source, {})
101
+ connection.connect
102
+ connection.scp_from(source, dest)
103
+ end
104
+ end
105
+ end
106
+ end
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.23.1
4
+ version: 4.27.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-05-20 00:00:00.000000000 Z
11
+ date: 2020-07-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -176,14 +176,14 @@ dependencies:
176
176
  requirements:
177
177
  - - "~>"
178
178
  - !ruby/object:Gem::Version
179
- version: '3.6'
179
+ version: '3.9'
180
180
  type: :runtime
181
181
  prerelease: false
182
182
  version_requirements: !ruby/object:Gem::Requirement
183
183
  requirements:
184
184
  - - "~>"
185
185
  - !ruby/object:Gem::Version
186
- version: '3.6'
186
+ version: '3.9'
187
187
  - !ruby/object:Gem::Dependency
188
188
  name: rb-readline
189
189
  requirement: !ruby/object:Gem::Requirement
@@ -352,6 +352,7 @@ executables:
352
352
  extensions: []
353
353
  extra_rdoc_files: []
354
354
  files:
355
+ - ".github/dependabot.yml"
355
356
  - ".gitignore"
356
357
  - ".rspec"
357
358
  - ".simplecov"
@@ -576,6 +577,7 @@ files:
576
577
  - lib/beaker/hypervisor.rb
577
578
  - lib/beaker/hypervisor/noop.rb
578
579
  - lib/beaker/junit.xsl
580
+ - lib/beaker/local_connection.rb
579
581
  - lib/beaker/logger.rb
580
582
  - lib/beaker/logger_junit.rb
581
583
  - lib/beaker/network_manager.rb
@@ -646,6 +648,7 @@ files:
646
648
  - spec/beaker/host_prebuilt_steps_spec.rb
647
649
  - spec/beaker/host_spec.rb
648
650
  - spec/beaker/hypervisor/hypervisor_spec.rb
651
+ - spec/beaker/localhost_connection_spec.rb
649
652
  - spec/beaker/logger_junit_spec.rb
650
653
  - spec/beaker/logger_spec.rb
651
654
  - spec/beaker/network_manager_spec.rb
@@ -692,14 +695,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
692
695
  requirements:
693
696
  - - ">="
694
697
  - !ruby/object:Gem::Version
695
- version: 2.1.8
698
+ version: '2.4'
696
699
  required_rubygems_version: !ruby/object:Gem::Requirement
697
700
  requirements:
698
701
  - - ">="
699
702
  - !ruby/object:Gem::Version
700
703
  version: '0'
701
704
  requirements: []
702
- rubygems_version: 3.0.6
705
+ rubygems_version: 3.0.8
703
706
  signing_key:
704
707
  specification_version: 4
705
708
  summary: Let's test Puppet!