rspec-puppet how to test for a define as a member of a class

543 Views Asked by At

I have a class which looks like

class addon {
    case $::operatingsystem {
    'windows': {
        Dsc_xfirewall {
            dsc_ensure    => 'Present',
        }
     }
     'RedHat': {
     }
     default: { warning "OS : ${::operatingsystem} is not (yet) supported" }
  }
}

and I would like my test to look like

describe 'addon', :type => :class do
    os = 'windows'
    let(:facts) {{:operatingsystem => os}}
    describe os do
        it {
            is_expected.to contain_class('addon').with(
              {
                :Dsc_xfirewall => {
                  :dsc_ensure => 'Present',
                }
              }
            )
        }
    end
end

The catalog compiles correctly, the is_expected.to compile is removed for clarity. However I can't seem to get this to work: dsc_xfirewall is nil, if I try Dsc_xfirewall same story and if try

contains_dsc_xfirewall

I get an error that dsc_firewall is not a valid define. Does anyone have any ideas how I can better structure my test? Before anyone points out that if the catalog compiles correctly I don't need this test, I know that; this is just a cooked down version of something more complex.

My question is therefore: what does the test have to look like to check that the class contains dsc_xfirewall and that all the parameters are set correctly?

1

There are 1 best solutions below

3
On

The obvious problem is that your manifest does not declare any actual resources, whereas your Rspec seems to expect that the manifest in fact did.

This code here:

    Dsc_xfirewall {
        dsc_ensure => 'Present',
    }

declares resource defaults (ref) for a custom type dsc_xfirewall. My guess is that the upper case P in Present is a typo too.

I also note that you have the let(:facts) statement misplaced, and you open another describe block where I think you ought to use context.

I wrote some code along the lines of what I think you are trying to do, to illustrate both what the manifest and Rspec code should look like:

(I changed a few things so I can easily get it to compile on my Mac.)

class foo {
  case $::operatingsystem {
    'Darwin': {
      file { '/tmp/foo':
        ensure => file,
      }
    }
    'RedHat': {
    }
    default: { fail("OS : ${::operatingsystem} is not (yet) supported") }
  }
}

Rspec:

describe 'foo', :type => :class do
  context 'Darwin' do
    let(:facts) {{:operatingsystem => 'Darwin'}}
    it {
      is_expected.to contain_class('foo')
    }
    it {
      is_expected.to contain_file('/tmp/foo').with(
        {
          :ensure => 'file',
        }
      )
    }

    # Write out the catalog for debugging purposes.
    it { File.write('myclass.json', PSON.pretty_generate(catalogue)) }
  end
end

Obviously, instead of contain_file you would use contain_dsc_xfirewall.