Infrastruktur – News

Puppet Test Driven Development: part II – Create a more complex class and refactor it

19 März 2015

Now that we have all our setup done and a functional class to manage the OpenLDAP client part, let’s deal with a more complex part: the server class.

Write the acceptance tests

Let’s write the acceptance tests to code the behavior we want in spec/acceptance/openldap__server_spec.rb:

openldap::server, the server is listening on port 389 and that slapd service is running and enabled at boot time. No need to run it for now because it will obviously fail as the openldap::serverdoes not exist yet.

Write the unit tests

Let’s write the unit tests skeleton for our openldap::serverclass in spec/classes/openldap__server_spec.rb:When we declare the openldap::serverclass, we want the catalog to contain a service resource named ‘slapd’ that requires a package named ‘slapd’ on Debian and ‘openldap-servers’ on RedHat.

Write the puppet code

Now, let’s write the actual Puppet code:

Launch the unit tests

Now, if you launch the unit tests, it should work:

Launch the acceptance tests


On RedHat 7

Let’s test on RedHat:

On Debian 7


Now that everything is working as expected, we can refactor without risking any regression. For the moment, our class is quite simple, but it might become wildly unmaintainable as it grows. To prevent that, we’ll use the more standard package -> config ~> service pattern explained in R.I.Pienaar’s excellent blog post „Simple Puppet Module Structure Redux“:

The openldap::serverclass becomes (we don’t manage configuration for now):The openldap::server::install class:

The openldap::server::config class (empty for now):And finally, the openldap::server::service class:

Launch the unit tests

And now we can launch the unit tests to see if we didn’t break anything:Unfortunately, as of version 2.0.1, rspec-puppet does not look up in the full graph for resource dependencies, so we can not yet validate that we don’t break resource application order when refactoring (corresponding thread in puppet-dev mailing list). We will mark this test as pending for now. That way, our test suite will pass even though this specific test fails, but it will fail again when rspec-puppet is fixed, so that we’re warned. In the meantime, we’ll add some tests that check the dependency between subclasses. This roughly checks the same thing but is less than ideal as the module’s structure should not appear in the tests.

Then, we launch it again:Now it works with 2 tests marked as pending that we will fix as soon as rspec-puppet is fixed.

Launch the acceptance tests

Finally, we can launch our acceptance tests again and check that everything is still OK:

On RedHat 7

On Debian 7

We have now seen how to use unit and acceptance tests to help limit the risks when refactoring our code. Next time, we’ll go a little bit further by developing a custom type and provider to manage OpenLDAP databases in a behavior/test driven manner.


Hinterlassen Sie einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Un commentaire

  1. personalized tshirts sagt:

    Good post. I learn something totally new and challenging on websites I stumbleupon everyday.
    It’s always interesting to read through content
    from other writers and practice something from their sites.