Now that all the setup work is done (see Puppet Test Driven Development: Part 0 – Setup your environment), you can start writing some code. You are going to develop this module in a behavior/test driven manner, meaning you will write tests to describe how the module should behave before writing the actual code.
We will create an
openldap::client class that, when declared, will install the OpenLDAP clients tools, including the
ldapsearch command, so that we can connect to an LDAP server.
Write your first acceptance test
Now for the first tests, we will create a test to validate the
openldap::client class' behavior in spec/acceptance/openldap__client_spec.rb. By convention, you should use a double underscore to replace the double colon in the class name.
The first thing to do in any test file is require our spec_helper_acceptance.rb file.
The first acceptance test: testing that the Puppet catalog converges at first run
Line 6 – 8
Store the Puppet manifest to run with apply_manifest() in the
Run the manifest and catch any failure.
Run the manifest a second time and catch any change. Your manifest should converge at first run.
If you run your tests right now, you should see a nasty block of errors because the openldap::client class doesn’t actually exist yet. Let’s test with the centos7 nodeset:
The command to launch includes the nodeset to use in the environment variable
BEAKER_set and specify the acceptance test to run.
Line 3 – 4
The label of the
describe blocks in the acceptance test (line 3 and 4 of spec/acceptance/openldap__client_spec.rb)
Scp Puppet manifests to the virtual machine
Result of the test (failure)
Line 13 – 22
Detail of the failure
Acceptance test run timer summary
Acceptance test result summary
Line 27 – 29
Failure summary It basically says that the Puppet catalog does not even compile because it can’t find the
openldap::client class. So let’s write a unit test that verifies that, at least, the catalog compiles.
Write your first unit test
We’ll now write a unit test for our
openldap::client class that validates that the Puppet catalog compiles. Unit tests for classes lives in spec/classes, so let’s create the directory first.
Then, we’ll create a unit test file for the class
openldap::client in spec/classes/openldap__client_spec.rb.
The first thing to do in any test file is to require our spec_helper.rb file.
The first unit test : testing that the catalog compiles
As first test, you should always be sure that your catalog compiles.
Test that verifies that the catalog actually compiles.
If you run your test right now, you should also see a big block of errors because the class does not exist yet.
The command to run to launch unit tests. It tells bundler to exec the rake task
spec (defined in puppetlabs_spec_helper) with the environment variable SPEC_OPTS set to
-d which sets the output format to
documentation for a cleaner output.
The label of the
describe block (line 3 of spec/classes/openldap__client_spec.rb)
Result of the unit test
Line 6 – 11
Details of the failures
Unit test timer summary
Unit test summary
Line 16 – 18
Write the class
Now that everything is set up, let’s write the actual Puppet code! First, create the directory where our manifests will live.
Next, create our openldap::client class
If you save and run the unit tests again now, you’ll see that now that the class exists, our unit test passes.
and our acceptance test also passes.
but it doesn’t yet do what we want… Let’s add the acceptance test that describe what we really want, i.e. be able to connect to an ldap server.
The next check: testing that we can actually connect to an ldap server
You’ll test that you can really connect to a public ldap test server with ldapsearch. First, you need to create a method that will launch the ldapsearch command. Put it in your spec_helper_acceptance.rb so that you can use it in all your acceptance test files
shell beaker DSL function to actually launch command
Now you can use it in your acceptance test:
Line 15 – 19
Declare a new test that actually runs the ldapsearch command. If you save and run beaker you’ll have an error because it doesn’t find the ldapsearch command:
ldapsearch command is available in the
openldap-client package on RedHat, so let’s be sure that a
package resource with named
openldap-clients exists in the catalog.
If you save and run the unit tests, you should have an error because you don’t actually have a file resource named openldap-clients in your catalog
So, let’s fix this adding the installation of ldap client tools in openldap::client class:
And launch the unit tests again:
Then, the acceptance tests:
Now we have the behavior we wanted. We can connect to an ldap server. At least on Centos/RedHat7… But what happens if you run the tests on Debian 7? Let’s see…
It fails because the package
openldap-clients does not exist on Debian and thus, the
ldapsearch command is not installed.
On Debian, the ldapsearch command lives in the
ldap-utils package and not in openldap-clients.
We have to be sure that, on Debian family OS, Puppet installs the
ldap-utils package and not the
openldap-clients package. For that, we can test the content of the catalog with a unit tests.
rspec-puppet sends the
:facts hash to the Puppet compiler to populate the facts or top scope variables you use in your manifests.
We have to add some logic in our unit test because our catalog will be different.
You can either populate the :facts hash yourself:
Or, probably better, let
rspec-puppet-facts (https://github.com/mcanevet/rspec-puppet-facts) populate the
:facts hash for you and avoid duplicate code:
Loop over every supported operating system declared in your metadata.json.
rspec-puppet-facts gem to your Gemfile:
And update your gemset:
Load rspec-puppet-facts in your spec/spec_helper.rb
Then, run the unit tests again
Now we can fix the
And run the tests again
Let’s try the acceptance test with the Debian7 nodeset to test the actual behavior:
It works too!
Now that you know how to develop a simple Puppet class in a behavior/test driver manner, we will see in Part 2 how to code a more complex class.