Getting to Know the Puppet Development Kit (PDK) Part 3

Back to Listing

Hanover, MD, 21 September 2020


This post is the last post in a three-part series on Puppet module development using the Puppet Development Kit (PDK), adapted from a presentation for the St. Louis Puppet Users Group.

In part 1, we covered getting started with PDK. In part 2, we talked about customizing PDK for your own use. It’s been a while since those parts were released. Originally part 3 was going to talk about annoyances, gotchas, and various other random oddities in PDK. Fortunately, there has been a ton of development work going on in PDK so most of that is in the distant past.

Now, for part 3, my final post on PDK (for now), we’re going to explore adding additional test coverage to converted modules.

Follow-up on Smoke Tests

As mentioned in the last installment, smoke tests (lint, rubocop, and parser checks) can be run with the following command:

$ pdk validate

I also went through using the various component tools to auto-correct issues. Now that is even easier! Just use:

$ pdk validate -a

Unit Tests

Unit tests (Ruby scripts that use rspec-puppet to test the contents of a compiled catalog) can be executed with the following command:

$ pdk test unit

The default tests use rspec-puppet-facts to test catalog compilation on each supported OS.

This all works great if you created your classes and defined types with pdk new, but if they were created by hand, you’ll need to add the associated rspec tests. Fortunately, pdk new test was added in PDK 1.14.0.

$ pdk new test --unit mymodule
pdk (INFO): Using Ruby 2.5.8
pdk (INFO): Using Puppet 6.18.0
[✔] Examining module contents

---------------Files added--------------
/home/steve/mymodule/spec/classes/mymodule_spec.rb

----------------------------------------

Unfortunately, this does require you to run pdk new test once per class and defined type in your module. If you want to add tests for all of your classes and defined types at once, I wrote a script for that. It’s available at https://github.com/silug/pdk_add_tests.

pdk bundle

If you’re familiar with the underlying Ruby tools, PDK allows you to run arbitrary bundle commands with pdk bundle. For example, to see what rake tasks are available, you can run the following command:

$ pdk bundle exec rake -- -T

To see all output of the rake tasks run by pdk test unit, you can run the following command:

$ pdk bundle exec rake spec

Acceptance Tests

Acceptance tests spin up VMs or Docker containers to test the behavior of a module on a live system. PDK currently has no direct support for acceptance tests, but it is relatively easy to add acceptance tests to your PDK-compatible module. In fact, if you have an existing module with working tests, you should be able to make some minor additions to Gemfile and run the following:

$ pdk bundle exec rake beaker

Assuming you haven’t built acceptance tests before, you have a choice to make as there are at least 3 different test frameworks available for Puppet. To make your choice slightly easier, if you don’t need multi-node tests (tests where, for example, you build a client and a server and test the interaction between them), you probably want to use Litmus, a relatively new tool from Puppet. They have instructions for adding tests here: https://puppetlabs.github.io/litmus/

If you need multi-node tests, you’ll want to use Beaker (an older tool, also from Puppet), at least for now. In my case, I already work on a lot of other modules that use Beaker, so I’m sticking with it until Litmus is a little more mature (and adds multi-node tests).

Since the link above tells you how to set up Litmus, I won’t waste space here on that. Let’s talk instead about adding Beaker tests.

First, add the required gems to your Gemfile by adding the following to .sync.yml:

Gemfile:
  optional:
    ':acceptance':
      - gem: beaker
      - gem: beaker-rspec
      - gem: beaker-puppet_install_helper
      - gem: beaker-module_install_helper
      - gem: beaker-vagrant
      - gem: vagrant-wrapper
      - gem: net-ssh
        version: '~> 5.2'

(At the time of this writing, there is a bug that’s causing a negative interaction between beaker and net-ssh 6, which is why net-ssh is pinned to 5.2 in the snippet above.)

After making that change, run pdk update to update your Gemfile.

Next, add spec/spec_helper_acceptance.rb. It can look as simple as this:

require 'beaker-rspec/spec_helper'
require 'beaker-rspec/helpers/serverspec'
require 'beaker/puppet_install_helper'
require 'beaker/module_install_helper'

run_puppet_install_helper
install_module_on(hosts)
install_module_dependencies_on(hosts)

Next, you’ll need to specify the types of systems you want to test your code against. Let’s start by adding a default that launches CentOS 7 in Vagrant by creating spec/acceptance/nodesets/default.yml with the following contents:

---
HOSTS:
  centos-7-x64:
    platform: el-7-x86_64
    roles:
      - agent
      - default
    hypervisor: vagrant
    box: centos/7
    ip: '172.31.255.7'
    netmask: '255.255.255.128'
CONFIG:
  type: aio
  puppet_collection: puppet6

Now you have everything you need to run Beaker tests other than the tests themselves!

A good first test is to make sure that your main class applies and is idempotent (meaning it makes no changes on a subsequent application). You can do that with something like this in spec/acceptance/init_spec.rb:

  require 'spec_helper_acceptance'

  describe 'mymodule' do
    context 'default parameters' do
      it 'is expected to apply with no errors' do
        # Run twice to test idempotency
        apply_manifest('include mymodule', 'catch_failures' => true)
        apply_manifest('include mymodule', 'catch_changes' => true)
      end
    end
  end

For more information on acceptance tests, see the following:

Documentation

pdk bundle exec rake strings:generate:reference will generate REFERENCE.md from Puppet Strings documentation in your classes, etc.

Building Your Module

pdk build will package up your module in a format ready to be distributed on the Puppet Forge. It ignores files and directories listed in the top-level .pdkignore file (which is managed by PDK, so updates need to be added to .sync.yml).

PDK now also has an experimental pdk release command which can prep a module for release and upload it to the Puppet Forge in one step!

Click here to learn more about how Onyx Point, Inc's professional services and development teams can help you.

Steven is a consultant and trainer for Onyx Point, focusing on Puppet, compliance automation, and all things DevOps.

At Onyx Point, our engineers focus on Security, System Administration, Automation, Dataflow, and DevOps consulting for government and commercial clients. We offer professional services for Puppet, RedHat, SIMP, NiFi, GitLab, and the other solutions in place that keep your systems running securely and efficiently. We offer Open Source Software support and Engineering and Consulting services through GSA IT Schedule 70. As Open Source contributors and advocates, we encourage the use of FOSS products in Government as part of an overarching IT Efficiencies plan to reduce ongoing IT expenditures attributed to software licensing. Our support and contributions to Open Source, are just one of our many guiding principles

  • Customer First.
  • Security in All We Do.
  • Pursue Innovation with Integrity.
  • Communicate Openly and Respectfully.
  • Offer Your Talents, and Appreciate the Talents of Others

puppet, pdk, rspec, testing, programming, technical

Share this story

We work with these Technologies + Partners

puppet
gitlab
simp
beaker
redhat
AFCEA
GitHub
FOSSFeb