puppetlabs / rspec-puppet

RSpec tests for your Puppet manifests
https://puppetlabs.github.io/rspec-puppet/
MIT License
11 stars 18 forks source link

Handling merging structured facts #109

Open gerases opened 4 months ago

gerases commented 4 months ago

Use Case

I’m curious if anyone has run into the following problem. If one has their custom puppet modules in one big git repo and then also rspec-puppet tests for each, then at some point, to avoid repetition, one might want to put certain default facts in some spec helper and include it in each test, something like this:

RSpec.configure do |c|
    # ...
    c.default_facts = {
      :architecture   => 'x86_64',
      :concat_basedir => '/tmp',
      :kernel         => 'Linux',
      :os             => {
        :distro  => {
          :description => 'Blah',
        },
        :family  => 'Blah',
        :name    => 'Blah',
        :release => {
          :major => 'x',
        },
      },
    }
    #  ...
  end

This works … until some rspec within the module does this:

 describe 'mymodule' do
    let :facts do
      {
        :os => {
          :family => 'something-custom',
        },
      }
    end
  end

What happens then is that the :os dictionary in default_facts becomes overwritten (no deep merge).

Is there a known, elegant solution to this?

Describe the Solution You Would Like

An elegant way for module level tests to merge their facts with default fact dictionaries.

Describe Alternatives You've Considered

I've written a deep_merge function that deep merges the module-level dictionary with a global dictionary with some defaults. Like so:

\ describe 'mymodule' do
    let :facts do
      DEFAULT_FACTS.deep_merge do
        {
          :os => {
            :family => 'something-custom',
          },
        }
      end
    end
  end
jordanbreen28 commented 4 months ago

Thanks for raising this @gerases! Looks like we should be able to update the merge! to deep_merge! in each of the instances of this method https://github.com/puppetlabs/rspec-puppet/blob/2ab0d16a5cce0c554ac18fd1a1c63857902811e9/lib/rspec-puppet/support.rb#L205. I know rspec-puppet-facts has a change awaiting release in v3.0.0 which will also allow you to merge facts using the add_custom_fact method (see here), so hopefully that should serve as a workaround until we get this implemented.

gerases commented 4 months ago

Thanks @jordanbreen28, for various reasons using rspec-puppet-facts is not an option for me. I will make the change manually on my side for now. Are you going to use a gem for deep_merge just like rspec-puppet-facts does?

jordanbreen28 commented 4 months ago

@gerases No worries! yes i believe that is the approach we will take :) (yet to test it out so could change..)

bastelfreak commented 3 weeks ago

@gerases can you elaborate why you cannot use rspec-puppet-facts?