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

568 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
Alex Harvey 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.