bats-chef-handler

Run BATS tests at the end of a chef run, similar to minitest-chef-handler


License
MIT
Install
gem install bats-chef-handler -v 0.0.5

Documentation

Description

Chef report handler that will find and execute BATS tests, similiar to and inspired by minitest-chef-handler

Requirements

  • Tested on Chef 10.14.x and 11.14.x.
  • Only tested with chef-solo thus far. I do not run chef-server or hosted chef.
  • Install bats. It should be in $PATH for the Chef run.

Installation

There are two ways to use Chef Handlers.

Method 1 (recommended)

Use the chef_handler cookbook by Opscode. Create a recipe with the following:

include_recipe "chef_handler"

# Install `bats-chef-handler` gem during the compile phase
chef_gem "bats-chef-handler"

# load the gem here so it gets added to the $LOAD_PATH, otherwise chef_handler
# will fail.
require 'chef/handler/bats_handler'

# Activate the handler immediately during compile phase
chef_handler "Chef::Handler::BatsHandler" do
  source "chef/handler/bats_handler"
  action :nothing
end.run_action(:enable)

Method 2

Install the gem ahead of time, and configure Chef to use them:

gem install bats-chef-handler

Then add to the configuration (/etc/chef/solo.rb for chef-solo or /etc/chef/client.rb for chef-client):

require "chef/handler/bats_handler"
report_handlers << Chef::Handler::BatsHandler.new

Usage

Test cases

Write your BATS tests and place them together with the cookbooks they are designed to test. The handler will automatically load and execute tests based on the list of recipes that were executed during the test run.

Examples:

If the executed recipes include the recipe foo::default, we try to load tests from:

<cookbook_path>/foo/tests/default_test.bats
<cookbook_path>/foo/tests/default/*.bats

node variables

Since BATS tests are bash scripts that execute outside of the Ruby VM, you do not have access to node variables like you would with tests written in minitest. This may or may not be an issue depending on what you're testing and there are strategies to work around this. In practice we don't expect this will be an issue for the majority of testing.

Additionally, BATS seems to be catching on as the preferred integration test approach for Chef (as seen by it's prevalance in cookbooks covered by test-kitchen testing) so we decided BATS was potentially a better test framework for Chef.

It's also easier to run BATS tests outside of the Chef context, for example as a Sensu test or post-deploy smoketest.

Chef run failure

If any of the tests fail, the handler raises an error to abort the Chef execution.

Example

While developing a simple cookbook for clamav we decide to write a few integration tests. Our clamav cookbook is composed of 2 recipes

  • clamav::default
  • clamav::freshclam

We have created simple tests for each of them in the paths: cookbooks/clamav/tests/default_test.bats and cookbooks/clamav/tests/freshclam_test.bats:

$ chef-solo

[2013-10-01T21:38:23+00:00] INFO: *** Chef 10.14.2 ***
...
[2013-10-01T21:38:39+00:00] INFO: Chef Run complete in 12.715307935 seconds
[2013-10-01T21:38:39+00:00] INFO: Running report handlers
[2013-10-01T21:38:39+00:00] INFO: Resources updated this run:
[2013-10-01T21:38:39+00:00] INFO:   chef_handler[Chef::Handler::BatsHandler] (0s)

[2013-10-01T21:38:39+00:00] INFO: Running test: /opt/titan/chef/cookbooks/clamav/tests/base_test.bats
1..1
ok 1 clamav package installed
[2013-10-01T21:38:40+00:00] INFO: Running test: /opt/titan/chef/cookbooks/clamav/tests/freshclam_test.bats
1..4
ok 1 clamav-update package installed
ok 2 /etc/sysconfig/freshclam exists and is enabled
ok 3 /etc/cron.d/clamav-update cron job exists
ok 4 virus database should exist (if not, see /etc/cron.d/clamav-update)
[2013-10-01T21:38:41+00:00] INFO: Report handlers complete

Credit

The idea and much of the code to make this happen was borrowed straight out of (minitest-chef-handler)[https://github.com/calavera/minitest-chef-handler] by David Calavera. We simply wanted the same thing but with BATS tests.

TODO

  • It would be nice to support a similar path structure to what test-kitchen's BATS busser expects so that tests were easily and automatically executed in the bats-handler context and test-kitchen context.
  • Only call the bats binary once with all .bats files as arguments so that there is a single TAPS output. Not currently supported by BATS but would be an easy patch.

License

Licensed under the MIT license. See LICENSE file for details.

Joe Miller https://github.com/joemiller, https://twitter.com/miller_joe