chef-infradevopschefspec

Why can't Chefspec find my resource?


I have a Spec recipe that (among other things) tests that one of two commands are run. The first command is to be run if it is installed. If not, then the second should be run.

However that Spec recipe for some reason doesn't "see" the first execute resource despite listing the exact named resource as "other execute resources". But it does see and pass the second command.

The RSpec output looks like this:

gets admin key using getkey (FAILED - 1)
gets admin key using keyremoteclient [passed]

The error message:

Failures:

 1) cookbook-forwarders::install_forwarder_package gets admin key using getkey
 Failure/Error: expect(chef_run).to run_execute('use getkey')

   expected "execute[use getkey]" with action :run to be in Chef run. 
   Other execute resources:

   execute[use getkey]

This part of the error makes no sense because that exact resource is present!

    -->execute[use getkey]<--

The recipe section looks like this

execute 'use getkey' do
  admin_passwd = getkey((node['splunk_forwarder']['key_name']).to_s)
  user 'root'
  only_if '/usr/local/bin/inst ls getkey -noname -noversion'
end

execute 'keyremoteclient' do
  admin_passwd = keyremoteclient((node['splunk_forwarder']['key_kgp']).to_s, (node['splunk_forwarder']['key_name']).to_s)
  user 'root'
  not_if '/usr/local/bin/inst ls getkey -noname -noversion'
end

I've stubbed out the command in the 'only_if' guard at the beginning of the Spec recipe:

  before do
    # stub command to get admin password using getkey
    stub_command('getkey(the_key_name)').and_return('xyz')
    # stub command to get admin password using keyremoteclient
    stub_command('keyremoteclient(the_kgp, the_key_name)').and_return('xyz')
    # stub check if getkey is installed
    stub_command('/usr/local/bin/inst ls getkey -noname -noversion').and_return(true)
    # stub check for already installed getkey package to use keyremoteclient
    stub_command('/usr/local/bin/inst ls getkey -noname -noversion').and_return(false)
end

The Spec recipe section looks like this:

it 'gets admin key using ykeykeygetkey' do
  expect(chef_run).to run_execute('use getkey')
end

it 'gets admin key using ykeykeyremoteclient' do
  expect(chef_run).to run_execute('keyremoteclient')
end

Solution

  • So a few issues; one, you can't use stub_command to stub Ruby code like getkey(). Second, you are using the same command for both guards so the stubs are probably conflicting. I recommend refactoring your code to only use a single command execution. You probably don't need to write unit tests for this, just write integration tests instead.