beaker 4.26.0 → 4.29.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,6 +5,7 @@ module Unix::Pkg
5
5
  # unix-specific package management setup
6
6
  def pkg_initialize
7
7
  @apt_needs_update = true
8
+ @pacman_needs_update = true
8
9
  end
9
10
 
10
11
  def check_for_command(name)
@@ -71,6 +72,17 @@ module Unix::Pkg
71
72
  end
72
73
  end
73
74
 
75
+ # Arch Linux is a rolling release distribution. We need to ensure that it is up2date
76
+ # Except for the kernel. An upgrade will purge the modules for the currently running kernel
77
+ def update_pacman_if_needed
78
+ if self['platform'] =~ /archlinux/
79
+ if @pacman_needs_update
80
+ execute("pacman --sync --noconfirm --noprogressbar --refresh --sysupgrade --ignore linux --ignore linux-docs --ignore linux-headers")
81
+ @pacman_needs_update = false
82
+ end
83
+ end
84
+ end
85
+
74
86
  def install_package(name, cmdline_args = '', version = nil, opts = {})
75
87
  case self['platform']
76
88
  when /sles-/
@@ -138,6 +150,7 @@ module Unix::Pkg
138
150
  retry
139
151
  end
140
152
  when /archlinux/
153
+ update_pacman_if_needed
141
154
  execute("pacman -S --noconfirm #{cmdline_args} #{name}", opts)
142
155
  else
143
156
  raise "Package #{name} cannot be installed on #{self}"
@@ -6,11 +6,12 @@ module Beaker
6
6
  PLATFORMS = /^(alpine|huaweios|cisco_nexus|cisco_ios_xr|(free|open)bsd|osx|centos|fedora|debian|oracle|redhat|redhatfips|scientific|sles|ubuntu|windows|solaris|aix|archlinux|el|eos|cumulus|f5|netscaler)\-.+\-.+$/
7
7
  # Platform version numbers vs. codenames conversion hash
8
8
  PLATFORM_VERSION_CODES =
9
- { :debian => { "buster" => "10",
10
- "stretch" => "9",
11
- "jessie" => "8",
12
- "wheezy" => "7",
13
- "squeeze" => "6",
9
+ { :debian => { "bullseye" => "11",
10
+ "buster" => "10",
11
+ "stretch" => "9",
12
+ "jessie" => "8",
13
+ "wheezy" => "7",
14
+ "squeeze" => "6",
14
15
  },
15
16
  :ubuntu => { "focal" => "2004",
16
17
  "eoan" => "1910",
@@ -1,5 +1,5 @@
1
1
  module Beaker
2
2
  module Version
3
- STRING = '4.26.0'
3
+ STRING = '4.29.0'
4
4
  end
5
5
  end
@@ -89,6 +89,7 @@ describe ClassMixedWithDSLHelpers do
89
89
  describe "#fetch_http_dir" do
90
90
  let( :logger) { double("Beaker::Logger", :notify => nil , :debug => nil ) }
91
91
  let( :result) { double(:each_line => []) }
92
+ let( :status) { double('Process::Status', success?: true) }
92
93
 
93
94
  before do
94
95
  fetch_allows
@@ -97,8 +98,7 @@ describe ClassMixedWithDSLHelpers do
97
98
  describe "given valid arguments" do
98
99
 
99
100
  it "returns basename of first argument concatenated to second." do
100
- expect(subject).to receive(:`).with(/^wget.*/).ordered { result }
101
- expect($?).to receive(:to_i).and_return(0)
101
+ expect(Open3).to receive(:capture2e).with(/^wget.*/).ordered { result }.and_return(['', status])
102
102
  result = subject.fetch_http_dir "#{url}/beep", destdir
103
103
  expect(result).to eq("#{destdir}/beep")
104
104
  end
@@ -29,8 +29,8 @@ module Beaker
29
29
  it "deletes" do
30
30
  path = '/path/to/delete'
31
31
  corrected_path = '\\path\\to\\delete'
32
- expect( instance ).to receive(:execute).with("del /s /q #{corrected_path}").and_return(0)
33
- expect( instance.rm_rf(path) ).to be === 0
32
+ expect(instance).to receive(:execute).with(%(del /s /q "#{corrected_path}")).and_return(0)
33
+ expect(instance.rm_rf(path)).to eq(0)
34
34
  end
35
35
  end
36
36
 
@@ -39,10 +39,9 @@ module Beaker
39
39
  let(:destination) { '/destination/path/of/content' }
40
40
 
41
41
  it 'rm first' do
42
- expect( instance ).to receive(:execute).with("del /s /q #{destination.gsub(/\//, '\\')}").and_return(0)
43
- expect( instance ).to receive(:execute).with("move /y #{origin.gsub(/\//, '\\')} #{destination.gsub(/\//, '\\')}").and_return(0)
44
- expect( instance.mv(origin, destination) ).to be === 0
45
-
42
+ expect(instance).to receive(:execute).with("del /s /q \"\\destination\\path\\of\\content\"").and_return(0)
43
+ expect(instance).to receive(:execute).with("move /y #{origin.gsub(/\//, '\\')} #{destination.gsub(/\//, '\\')}").and_return(0)
44
+ expect(instance.mv(origin, destination)).to eq(0)
46
45
  end
47
46
 
48
47
  it 'does not rm' do
@@ -169,6 +169,66 @@ module Beaker
169
169
  end
170
170
 
171
171
  describe '#reboot' do
172
+ year = Time.now.strftime('%Y')
173
+
174
+ check_cmd_output = {
175
+ :centos6 => {
176
+ :who => {
177
+ :initial => " system boot #{year}-05-13 03:51",
178
+ :success => " system boot #{year}-05-13 03:52",
179
+ },
180
+ :last => {
181
+ :initial => <<~LAST_F,
182
+ reboot system boot 2.6.32-754.29.1. Tue May 5 17:34:52 #{year} - Tue May 5 17:52:48 #{year} (00:17)
183
+ reboot system boot 2.6.32-754.29.1. Mon May 4 18:45:43 #{year} - Mon May 5 05:35:44 #{year} (4+01:50)
184
+ LAST_F
185
+ :success => <<~LAST_F,
186
+ reboot system boot 2.6.32-754.29.1. Tue May 5 17:52:48 #{year} - Tue May 5 17:52:49 #{year} (00:17)
187
+ reboot system boot 2.6.32-754.29.1. Mon May 4 18:45:43 #{year} - Mon May 5 05:35:44 #{year} (4+01:50)
188
+ LAST_F
189
+ },
190
+ },
191
+ :centos7 => {
192
+ :who => {
193
+ :initial => " system boot #{year}-05-13 03:51",
194
+ :success => " system boot #{year}-05-13 03:52",
195
+ },
196
+ :last => {
197
+ :initial => <<~LAST_F,
198
+ reboot system boot 3.10.0-1127.el7. Tue May 5 17:34:52 #{year} - Tue May 5 17:52:48 #{year} (00:17)
199
+ reboot system boot 3.10.0-1127.el7. Mon May 4 18:45:43 #{year} - Mon May 5 05:35:44 #{year} (4+01:50)
200
+ LAST_F
201
+ :success => <<~LAST_F,
202
+ reboot system boot 3.10.0-1127.el7. Tue May 5 17:52:48 #{year} - Tue May 5 17:52:49 #{year} (00:17)
203
+ reboot system boot 3.10.0-1127.el7. Mon May 4 18:45:43 #{year} - Mon May 5 05:35:44 #{year} (4+01:50)
204
+ LAST_F
205
+ },
206
+ },
207
+ :centos8 => {
208
+ :who => {
209
+ :initial => " system boot #{year}-05-13 03:51",
210
+ :success => " system boot #{year}-05-13 03:52",
211
+ },
212
+ :last => {
213
+ :initial => <<~LAST_F,
214
+ reboot system boot 4.18.0-147.8.1.e Tue May 5 17:34:52 #{year} still running
215
+ reboot system boot 4.18.0-147.8.1.e Mon May 4 17:41:27 #{year} - Tue May 5 17:00:00 #{year} (5+00:11)
216
+ LAST_F
217
+ :success => <<~LAST_F,
218
+ reboot system boot 4.18.0-147.8.1.e Tue May 5 17:34:53 #{year} still running
219
+ reboot system boot 4.18.0-147.8.1.e Mon May 4 17:41:27 #{year} - Tue May 5 17:00:00 #{year} (5+00:11)
220
+ LAST_F
221
+ },
222
+ },
223
+ :freebsd => {
224
+ # last -F doesn't work on freebsd so no output will be returned
225
+ :who => {
226
+ :initial => ' system boot May 13 03:51',
227
+ :success => ' system boot May 13 03:52',
228
+ }
229
+ },
230
+ }
231
+
172
232
  # no-op response
173
233
  let (:response) { double( 'response' ) }
174
234
  let (:boot_time_initial_response) { double( 'response' ) }
@@ -179,7 +239,7 @@ module Beaker
179
239
  before :each do
180
240
  # stubs enough to survive the first boot_time call & output parsing
181
241
  # note: just stubs input-chain between calls, parsing methods still run
182
- allow(Beaker::Command).to receive(:new).with('who -b').and_return(:boot_time_command_stub)
242
+ allow(Beaker::Command).to receive(:new).with('last -F reboot || who -b').and_return(:boot_time_command_stub)
183
243
 
184
244
  allow(boot_time_initial_response).to receive(:stdout).and_return(boot_time_initial_stdout)
185
245
  allow(boot_time_success_response).to receive(:stdout).and_return(boot_time_success_stdout)
@@ -190,116 +250,128 @@ module Beaker
190
250
  end
191
251
 
192
252
  context 'new boot time greater than old boot time' do
193
- let (:boot_time_initial_stdout) { ' system boot 2020-05-13 03:51' }
194
- let (:boot_time_success_stdout) { ' system boot 2020-05-13 03:52' }
195
-
196
- it 'passes with defaults' do
197
- expect(instance).to receive(:sleep).with(sleep_time)
198
- # bypass shutdown command itself
199
- expect(instance).to receive( :exec ).with(:shutdown_command_stub, anything).and_return(response)
200
- # allow the second boot_time and the hash arguments in exec
201
- expect(instance).to receive( :exec ).with(:boot_time_command_stub, anything).and_return(boot_time_initial_response).once
202
- expect(instance).to receive( :exec ).with(:boot_time_command_stub, anything).and_return(boot_time_success_response).once
203
-
204
- expect(instance.reboot).to be(nil)
205
- end
253
+ check_cmd_output.each do |check_os, cmd_opts|
254
+ cmd_opts.each do |cmd_name, cmd_outputs|
255
+ context "on '#{check_os}' with the '#{cmd_name}' command" do
256
+ let (:boot_time_initial_stdout) { cmd_outputs[:initial] }
257
+ let (:boot_time_success_stdout) { cmd_outputs[:success] }
258
+
259
+ it 'passes with defaults' do
260
+ expect(instance).to receive(:sleep).with(sleep_time)
261
+ # bypass shutdown command itself
262
+ expect(instance).to receive( :exec ).with(:shutdown_command_stub, anything).and_return(response)
263
+ expect(instance).to receive( :exec ).with(:boot_time_command_stub, anything).and_return(boot_time_initial_response).once
264
+ # allow the second boot_time and the hash arguments in exec
265
+ expect(instance).to receive( :exec ).with(:boot_time_command_stub, anything).and_return(boot_time_success_response).once
206
266
 
207
- it 'passes with wait_time_parameter' do
208
- expect(instance).to receive(:sleep).with(10)
209
- # bypass shutdown command itself
210
- expect(instance).to receive( :exec ).with(:shutdown_command_stub, anything).and_return(response).once
211
- expect(instance).to receive( :exec ).with(:boot_time_command_stub, anything).and_return(boot_time_initial_response).once
212
- # allow the second boot_time and the hash arguments in exec
213
- expect(instance).to receive( :exec ).with(:boot_time_command_stub, anything).and_return(boot_time_success_response).once
267
+ expect(instance.reboot).to be(nil)
268
+ end
214
269
 
215
- expect(instance.reboot(10)).to be(nil)
216
- end
270
+ it 'passes with wait_time_parameter' do
271
+ expect(instance).to receive(:sleep).with(10)
272
+ # bypass shutdown command itself
273
+ expect(instance).to receive( :exec ).with(:shutdown_command_stub, anything).and_return(response).once
274
+ expect(instance).to receive( :exec ).with(:boot_time_command_stub, anything).and_return(boot_time_initial_response).once
275
+ # allow the second boot_time and the hash arguments in exec
276
+ expect(instance).to receive( :exec ).with(:boot_time_command_stub, anything).and_return(boot_time_success_response).once
217
277
 
218
- it 'passes with max_connection_tries parameter' do
219
- expect(instance).to receive(:sleep).with(sleep_time)
220
- # bypass shutdown command itself
221
- expect(instance).to receive( :exec ).with(:shutdown_command_stub, anything).and_return(response).once
222
- expect(instance).to receive( :exec ).with(:boot_time_command_stub, anything).and_return(boot_time_initial_response).once
223
- # allow the second boot_time and the hash arguments in exec
224
- expect(instance).to receive( :exec ).with(:boot_time_command_stub, hash_including(:max_connection_tries => 20)).and_return(boot_time_success_response).once
278
+ expect(instance.reboot(10)).to be(nil)
279
+ end
225
280
 
226
- expect(instance.reboot(sleep_time, 20)).to be(nil)
227
- end
281
+ it 'passes with max_connection_tries parameter' do
282
+ expect(instance).to receive(:sleep).with(sleep_time)
283
+ # bypass shutdown command itself
284
+ expect(instance).to receive( :exec ).with(:shutdown_command_stub, anything).and_return(response).once
285
+ expect(instance).to receive( :exec ).with(:boot_time_command_stub, anything).and_return(boot_time_initial_response).once
286
+ # allow the second boot_time and the hash arguments in exec
287
+ expect(instance).to receive( :exec ).with(:boot_time_command_stub, hash_including(:max_connection_tries => 20)).and_return(boot_time_success_response).once
228
288
 
229
- context 'command errors' do
230
- before :each do
231
- allow(instance).to receive( :exec ).with(:boot_time_command_stub, anything).and_return(boot_time_initial_response).once
232
- end
289
+ expect(instance.reboot(sleep_time, 20)).to be(nil)
290
+ end
233
291
 
234
- it 'raises a reboot failure when command fails' do
235
- expect(instance).not_to receive(:sleep)
236
- expect(instance).to receive(:exec).with(:shutdown_command_stub, anything).and_raise(Host::CommandFailure).once
292
+ context 'command errors' do
293
+ before :each do
294
+ allow(instance).to receive( :exec ).with(:boot_time_command_stub, anything).and_return(boot_time_initial_response).at_least(:once)
295
+ end
237
296
 
238
- expect{ instance.reboot }.to raise_error(Beaker::Host::RebootFailure, /Command failed when attempting to reboot: .*/)
239
- end
297
+ it 'raises a reboot failure when command fails' do
298
+ expect(instance).to receive(:sleep).at_least(:once)
299
+ expect(instance).to receive(:exec).with(:shutdown_command_stub, anything).and_raise(Host::CommandFailure).at_least(:once)
240
300
 
241
- it 'raises a reboot failure when we receive an unexpected error' do
242
- expect(instance).not_to receive(:sleep)
243
- expect(instance).to receive(:exec).with(:shutdown_command_stub, anything).and_raise(Net::SSH::HostKeyError).once
301
+ expect{ instance.reboot }.to raise_error(Beaker::Host::CommandFailure)
302
+ end
244
303
 
245
- expect { instance.reboot }.to raise_error(Beaker::Host::RebootFailure, /Unexpected exception in reboot: .*/)
246
- end
304
+ it 'raises a reboot failure when we receive an unexpected error' do
305
+ expect(instance).to receive(:sleep).at_least(:once)
306
+ expect(instance).to receive(:exec).with(:shutdown_command_stub, anything).and_raise(Net::SSH::HostKeyError).at_least(:once)
247
307
 
248
- context 'incorrect time string' do
249
- context 'original time' do
250
- let (:boot_time_initial_stdout) { 'boot bad' }
308
+ expect { instance.reboot }.to raise_error(Net::SSH::HostKeyError)
309
+ end
251
310
 
252
- it 'raises a reboot failure' do
253
- expect(instance).not_to receive(:sleep)
311
+ context 'incorrect time string' do
312
+ context 'original time' do
313
+ let (:boot_time_initial_stdout) { 'boot bad' }
254
314
 
255
- expect { instance.reboot }.to raise_error(Beaker::Host::RebootFailure, /Unable to parse time: .*/)
256
- end
257
- end
315
+ it 'raises a reboot failure' do
316
+ # Handle the 'retry'
317
+ allow(instance).to receive( :exec ).with(:boot_time_command_stub, anything).and_return(boot_time_initial_response).at_least(:once)
258
318
 
259
- context 'current time' do
260
- let (:boot_time_success_stdout) { 'boot bad' }
319
+ expect(instance).not_to receive(:sleep)
261
320
 
262
- it 'raises a reboot failure' do
263
- expect(instance).to receive(:exec).with(:shutdown_command_stub, anything).and_return(response).once
264
- expect(instance).to receive( :exec ).with(:boot_time_command_stub, anything).and_return(boot_time_initial_response).once
265
- # allow the second boot_time and the hash arguments in exec, repeated 10 times by default
266
- expect(instance).to receive( :exec ).with(:boot_time_command_stub, anything).and_return(boot_time_success_response).once
321
+ expect { instance.reboot }.to raise_error(Beaker::Host::RebootWarning, /Found no valid times in .*/)
322
+ end
323
+ end
324
+
325
+ context 'current time' do
326
+ let (:boot_time_success_stdout) { 'boot bad' }
327
+
328
+ it 'raises a reboot failure' do
329
+ expect(instance).to receive(:exec).with(:shutdown_command_stub, anything).and_return(response).once
330
+ expect(instance).to receive( :exec ).with(:boot_time_command_stub, anything).and_return(boot_time_initial_response).once
331
+ # allow the second boot_time and the hash arguments in exec, repeated 10 times by default
332
+ expect(instance).to receive( :exec ).with(:boot_time_command_stub, anything).and_return(boot_time_success_response).at_least(:once)
267
333
 
268
- expect { instance.reboot }.to raise_error(Beaker::Host::RebootFailure, /Unable to parse time: .*/)
334
+ expect { instance.reboot(10,9,1) }.to raise_error(Beaker::Host::RebootWarning, /Found no valid times in .*/)
335
+ end
336
+ end
337
+ end
269
338
  end
270
339
  end
271
340
  end
272
341
  end
273
342
  end
274
343
 
275
- context 'new boot time less than old boot time' do
276
- let (:boot_time_initial_stdout) { ' system boot 2020-05-13 03:51' }
277
- let (:boot_time_success_stdout) { ' system boot 2020-05-13 03:50' }
344
+ context 'system did not reboot' do
345
+ check_cmd_output.each do |check_os, cmd_opts|
346
+ cmd_opts.each do |cmd_name, cmd_outputs|
347
+ context "on '#{check_os}' with the '#{cmd_name}' command" do
348
+ let (:boot_time_initial_stdout) { cmd_outputs[:initial] }
349
+ let (:boot_time_success_stdout) { cmd_outputs[:initial] }
278
350
 
279
- it 'raises RebootFailure' do
280
- expect(instance).to receive(:sleep).with(sleep_time)
281
- # bypass shutdown command itself
282
- expect(instance).to receive( :exec ).with(:shutdown_command_stub, anything).and_return(response).once
351
+ it 'raises RebootFailure' do
352
+ expect(instance).to receive(:sleep).with(sleep_time)
353
+ # bypass shutdown command itself
354
+ expect(instance).to receive( :exec ).with(:shutdown_command_stub, anything).and_return(response).once
283
355
 
284
- expect(instance).to receive( :exec ).with(:boot_time_command_stub, anything).and_return(boot_time_initial_response).once
285
- # allow the second boot_time and the hash arguments in exec, repeated 18 times by default in order to replicate the previous behavior of the ping based Host.down?
286
- expect(instance).to receive( :exec ).with(:boot_time_command_stub, anything).and_return(boot_time_success_response).exactly(18).times
356
+ expect(instance).to receive( :exec ).with(:boot_time_command_stub, anything).and_return(boot_time_initial_response).once
357
+ expect(instance).to receive( :exec ).with(:boot_time_command_stub, anything).and_return(boot_time_success_response).once
287
358
 
288
- expect { instance.reboot }.to raise_error(Beaker::Host::RebootFailure, /Boot time did not reset/)
289
- end
359
+ expect { instance.reboot }.to raise_error(Beaker::Host::RebootFailure, /Boot time did not reset/)
360
+ end
290
361
 
291
- it 'raises RebootFailure if the number of retries is changed' do
292
- expect(instance).to receive(:sleep).with(sleep_time)
293
- # bypass shutdown command itself
294
- expect(instance).to receive( :exec ).with(:shutdown_command_stub, anything).and_return(response).once
295
- expect(instance).to receive( :exec ).with(:boot_time_command_stub, anything).and_return(boot_time_initial_response).once
296
- # allow the second boot_time and the hash arguments in exec, repeated 10 times by default
297
- expect(instance).to receive( :exec ).with(:boot_time_command_stub, anything).and_return(boot_time_success_response).exactly(10).times
362
+ it 'raises RebootFailure if the number of retries is changed' do
363
+ expect(instance).to receive(:sleep).with(sleep_time)
364
+ # bypass shutdown command itself
365
+ expect(instance).to receive( :exec ).with(:shutdown_command_stub, anything).and_return(response).once
366
+ expect(instance).to receive( :exec ).with(:boot_time_command_stub, anything).and_return(boot_time_initial_response).once
367
+ expect(instance).to receive( :exec ).with(:boot_time_command_stub, anything).and_return(boot_time_success_response).once
298
368
 
299
- expect { instance.reboot(wait_time=sleep_time, max_connection_tries=9, boot_time_retries=10) }.to raise_error(Beaker::Host::RebootFailure, /Boot time did not reset/)
369
+ expect { instance.reboot(wait_time=sleep_time, max_connection_tries=9, boot_time_retries=10) }.to raise_error(Beaker::Host::RebootFailure, /Boot time did not reset/)
370
+ end
371
+ end
372
+ end
300
373
  end
301
374
  end
302
-
303
375
  end
304
376
 
305
377
  describe '#enable_remote_rsyslog' do
@@ -314,30 +386,86 @@ module Beaker
314
386
  end
315
387
 
316
388
  describe '#which' do
317
- before do
318
- allow(instance).to receive(:execute)
319
- .with(where_command, :accept_all_exit_codes => true).and_return(result)
389
+ context 'when type -P works' do
390
+ before do
391
+ expect(instance).to receive(:execute)
392
+ .with('type -P true', :accept_all_exit_codes => true).and_return('/bin/true').once
393
+
394
+ allow(instance).to receive(:execute)
395
+ .with(where_command, :accept_all_exit_codes => true).and_return(result)
396
+ end
397
+
398
+ context 'when only the environment variable PATH is used' do
399
+ let(:where_command) { "type -P ruby" }
400
+ let(:result) { "/usr/bin/ruby.exe" }
401
+
402
+ it 'returns the correct path' do
403
+ response = instance.which('ruby')
404
+
405
+ expect(response).to eq(result)
406
+ end
407
+ end
408
+
409
+ context 'when command is not found' do
410
+ let(:where_command) { "type -P unknown" }
411
+ let(:result) { '' }
412
+
413
+ it 'return empty string if command is not found' do
414
+ response = instance.which('unknown')
415
+
416
+ expect(response).to eq(result)
417
+ end
418
+ end
320
419
  end
321
420
 
322
- context 'when only the environment variable PATH is used' do
323
- let(:where_command) { "which ruby" }
324
- let(:result) { "/usr/bin/ruby.exe" }
421
+ context 'when which works' do
422
+ before do
423
+ expect(instance).to receive(:execute)
424
+ .with('type -P true', :accept_all_exit_codes => true).and_return('').once
325
425
 
326
- it 'returns the correct path' do
327
- response = instance.which('ruby')
426
+ expect(instance).to receive(:execute)
427
+ .with('which true', :accept_all_exit_codes => true).and_return('/bin/true').once
328
428
 
329
- expect(response).to eq(result)
429
+ allow(instance).to receive(:execute)
430
+ .with(where_command, :accept_all_exit_codes => true).and_return(result)
431
+ end
432
+
433
+ context 'when only the environment variable PATH is used' do
434
+ let(:where_command) { "which ruby" }
435
+ let(:result) { "/usr/bin/ruby.exe" }
436
+
437
+ it 'returns the correct path' do
438
+ response = instance.which('ruby')
439
+
440
+ expect(response).to eq(result)
441
+ end
442
+ end
443
+
444
+ context 'when command is not found' do
445
+ let(:where_command) { "which unknown" }
446
+ let(:result) { '' }
447
+
448
+ it 'return empty string if command is not found' do
449
+ response = instance.which('unknown')
450
+
451
+ expect(response).to eq(result)
452
+ end
330
453
  end
331
454
  end
332
455
 
333
- context 'when command is not found' do
334
- let(:where_command) { "which unknown" }
335
- let(:result) { '' }
456
+ context 'when neither works' do
457
+ before do
458
+ expect(instance).to receive(:execute)
459
+ .with('type -P true', :accept_all_exit_codes => true).and_return('').once
336
460
 
337
- it 'return empty string if command is not found' do
338
- response = instance.which('unknown')
461
+ expect(instance).to receive(:execute)
462
+ .with('which true', :accept_all_exit_codes => true).and_return('').once
463
+ end
339
464
 
340
- expect(response).to eq(result)
465
+ context 'when only the environment variable PATH is used' do
466
+ it 'fails correctly' do
467
+ expect{instance.which('ruby')}.to raise_error(/suitable/)
468
+ end
341
469
  end
342
470
  end
343
471
  end