0

Is there a way I can use a custom fact while using rspec? My module works fine and the custom fact exists and works as intended when I do a puppet run on my agent, but when I try to use the same fact in rspec I get the following error:

Failure/Error: it { should contain_class('zabbixconfig') }

     Puppet::PreformattedError:
       Evaluation Error: Unknown variable: 'pskkey_generate'. at /etc/puppetlabs/code/environments/production/modules/zabbixconfig/spec/fixtures/modules/zabbixconfig/manifests/init.pp:46:13 on node puppet-master-poc

The pskkey_generate in the error above is my custom fact, and here's a snippet of my class including it:

$pskkey = $pskkey_generate

Does anyone know how to get rspec to recognize my custom fact? Any help would be appreciated.

2 Answers 2

1

In your spec/spec_helper.rb file you can add the following:

RSpec.configure do |c|
  c.default_facts = { :pskkey_generate => '...' }
end

See https://github.com/rodjek/rspec-puppet#default_facts

2
  • Thanks! I understand that the '...' needs to be replaced with the value of the pskkey_generate, but the pskkey_generate is a dynamically generated key. The command used to generate the key is openssl rand -hex 32. Since it's random, is there a way I can assign the value of the output to the pskkey_generate variable in the default_facts as well? If not I may just not unit test it for now and come back to it later. Feb 27, 2019 at 13:49
  • Not really, as facts can behave differently on the host/OS that you're developing on versus the intended host/OS your code will run on. But by setting the fact to a known value, you can test that it affects your module in a known way. If the value just gets written out to a file, then you can add a test to check that with something like it { is_expected.to contain_file('/some/file').with_content('abc123') }, assuming you set the pskkey_generate fact to abc123 in your tests.
    – bodgit
    Feb 27, 2019 at 14:06
0

In your case, it probably is best to hard code a known value of your fact in default_facts as bodgit suggests. In other cases, when the fact comes from a third party module, it is annoying to have to add mocking to make realistic tests of your use of their code.

I have added at the top of my spec/spec_helper.rb:

if ENV.include? 'MODULEPATH'
  top_path = File.dirname(File.dirname(__FILE__))
  ENV['FACTERLIB'] = ENV['MODULEPATH'].split(/:/).map do |p|
    p.start_with?('/') ? p : File.join(top_path, p)
  end.map do |p|
    Dir.glob(File.join(p, '*/lib/facter'))
  end.flatten.join(':')
end

When the Facter library loads, it will honour the FACTERLIB environment variable and evaluate all the custom facts supplied by the modules in your Puppet environment.

A typical value for MODULEPATH is "design:modules" when testing environments.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .