Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing a Chef provider

How can I write a unit test for a Chef provider?

So far, our unit testing strategy uses ChefSpec for recipes, and we stuff most of the interesting logic for our providers in libraries to make the logic more testable. However, we still run into issues where our providers are calling other resources (among other simple logic issues). For example:

action :run do

   helper = Helper.new
   template '/etc/hosts' do
     source 'hosts.erb'
     variables ({
              "host" => @new_resource.host,
              "ip_address" => node['ipaddress']
          })
     only_if { helper.update_hosts }
   end

   service 'httpd' do
      action :restart
   end
end

(this is not real code, just a trivial example)

What we'd like to do is test this provider in isolation to check for logic errors. ChefSpec has the capability of stepping into an LWRP, but it looks like that would force us to put the LWRP into a recipe, and many of our cookbooks are basically LWRP libraries with no recipes. We'd also just like to keep a clean separation in our tests, so it's obvious what component failed by looking at the file name.

Additionally, it would be nice if the test would automatically fail if there are any syntax errors in the LWRP definition. For example:

action :run do
   template '/etc/hosts/' do
     source_whoops 'hosts.erb'
     action :whoops
   end
end

It would be really nice if the above statement would cause the test to fail due to the attribute name being defined incorrectly, and the action name not existing (just like ChefSpec).

The only solution I've come up with is to basically create a "test cookbook" - a separate cookbook that defines each LWRP 1:1 with a single recipe, so ChefSpec can step into it that way. It seems like a reasonable, but less than ideal solution.

like image 754
user949286 Avatar asked Jan 16 '14 18:01

user949286


People also ask

Is unit testing worth the money?

Unit testing ensures that all code meets quality standards before it's deployed. This ensures a reliable engineering environment where quality is paramount. Over the course of the product development life cycle, unit testing saves time and money, and helps developers write better code, more efficiently.

What is test kitchen in Chef?

Test Kitchen is Chef's integrated testing framework. It enables writing test recipes, which will run on the VMs once they are instantiated and converged using the cookbook. The test recipes run on that VM and can verify if everything works as expected. ChefSpec is something which only simulates a Chef run.

What is ChefSpec?

ChefSpec is a unit testing framework for testing Chef cookbooks. ChefSpec makes it easy to write examples and get fast feedback on cookbook changes without the need for virtual machines or cloud servers. ChefSpec runs your cookbooks locally while skipping making actual changes.


1 Answers

Looks like there is a (very recent) solution to this.

First, this pull request would basically do what I'm asking, although it has been rejected by the ChefSpec maintainer for understandable reasons.

The maintainer suggests to use a mycookbook_test pattern - a separate cookbook keeps all the unit tests. This would allow a simple 1 recipe-per-lwrp approach.

Additionally, this approach keeps the cookbook clear of any unit tests, which is nice for consumers of the cookbook. Consumers may want to run their own unit tests, and there's no need (or desire) to run tests on third party cookbooks.

like image 88
user949286 Avatar answered Oct 07 '22 13:10

user949286