Wednesday, March 30, 2016

Testing Puppet Code, Part 1

This is the first in a series of posts about how you, as a Puppet practitioner, can test your Puppet code.

Why do we test our code?  First, testing code saves time.  It’s counterintuitive but true.  When writing tests you may find new solutions to the problem or write something more efficient.  Second, running tests discovers bugs.  Problems arise from untested code and you’ll spend time fixing those problems later on.  Lastly adding tests enhances documentation.  Tests describe how the code should behave and are a self-documenting feature.  There are many other reasons and specific types of tests but we'll save that for later.

We start with basic Puppet syntax checks.  The command `puppet parser validate` will "validate(s) Puppet DSL syntax without compiling a catalog or syncing any resources".  Simply put it examines a Puppet manifest, ensures those curly braces `{ }` are correct and that we followed the Puppet DSL.

Run `puppet parser validate` without any arguments and it looks for the default manifest at `/etc/puppetlabs/puppet/manifests/site.pp`.  I ran the command but the file doesn’t exist and I get an error.

Note: I run `echo $?` to show the previous command's exit status.  Knowing the exit status is helpful when scripting.

To test our Puppet manifest we need to pass the filename as an argument to the command.  In this example we pass the manifest `init.pp`.  The old adage “No news is good news “ is true.  The command found no errors and there’s no output aside from some warnings.

Let's break the manifest and rerun the test.  I remove a single curly brace and now we have an error.

That output tells us the file and line number of the error: file init.pp, line number 105.  When I look at line 105 I can’t find the error.  But if we look a few lines up, at line 103, we see the `case` statement is missing a curly brace `{`.  We have to play detective to find errors as they are not always at the reported line number.

Usually we want to test more than one file at a time.  We could pass multiple files to `puppet parser` but it will stop at the first error.  Send one manifest at a time to the command and we get a complete list of all errors in all the manifests.  We can use the `find` command to run `puppet parser` on every manifest, like this example.

We test our code to avoid bugs and make our code more efficient.  Tests can be done quickly and easily with the simple syntax test, `puppet parser validate`.  We can save some time and perform multiple tests with simple shell scripting.  In the next article we will improve code readability with the command `puppet-lint`.