Chef

Table Of Contents

Kitchen

Kitchen is an integration framework that is used to automatically test cookbook data across across any combination of platforms and test suites, as defined by a kitchen.yml file. Kitchen uses a driver plugin architecture that allows it to support cookbook testing across many cloud providers and virtualization technologies. Kitchen supports all of the common testing frameworks used by the Ruby community.

The key concepts in Kitchen are:

  • A platform is the operating system or target environment on which a cookbook is to be tested
  • A suite is the chef-client configuration, a run-list, and (optionally) node attributes
  • An instance is the combination of a specific platform and a specific suite, with each instance being assigned an auto-generated name
  • A driver is the lifecycle that implements the actions associated with a specific instance—create the instance, do what is needed to converge on that instance (such as installing the chef-client, uploading cookbooks, starting the chef-client run, and so on), setup anything else needed for testing, verify one (or more) suites post-converge, and then destroy that instance
  • A provisioner is the component on which the chef-client code will be run, either using chef-zero or chef-solo via the chef_zero and chef_solo provisioners, respectively

Note

This topic details functionality that is packaged with Chef development kit. See http://kitchen.ci/docs/getting-started/ for more information about Kitchen.

Test Frameworks

An integration test is an executable test that fails when the assumptions defined by the test are proven to be false. Each test is written in Ruby and must be located in the /tests directory within the cookbook to be tested.

The following frameworks are good options for building integration tests with Kitchen:

Test Framework Description
Bats Bats (or Bash Automated Testing System) is an testing framework for Bash. Bats is also the default framework for Kitchen.
Minitest A small, fast, testing framework.
Rspec The primary testing framework for Ruby, using the words describe and it to express tests as conversation. Bats, Minitest, Serverspec are all based on RSpec.
Serverspec RSpec-based tests for servers.

The syntax used for the tests depends on the testing framework. RSpec-based testing is similar to the following:

it 'what_the_test_does' do
  # Ruby code that defines the test
end

For example:

it 'contains the default configuration settings' do
  file(File.join(node['chef_client']['conf_dir'], 'client.rb')).must_match('^chef_server_url')
  file(File.join(node['chef_client']['conf_dir'], 'client.rb')).must_match('^validation_client_name')
end

or:

it 'converts ssl_verify_mode to a symbol' do
  file(File.join(node['chef_client']['conf_dir'], 'client.rb')).must_match('^ssl_verify_mode :verify_peer')
end

or:

it 'disables ohai plugins' do
  regexp = 'Ohai::Config\[:disabled_plugins\] =\s+\["passwd"\]'
  file(File.join(node['chef_client']['conf_dir'], 'client.rb')).must_match(/#{regexp}/)
end

Handlers can also be run as part of cookbook testing. At the top of the test file, use:

require File.expand_path('../support/helpers', __FILE__)

to specify the handler, and then include the handler within the test:

it 'enables exception_handlers' do
  file(File.join(node['chef_client']['conf_dir'], 'client.rb')).must_match(
    '^exception_handlers << Report::UpdateResource.new'
  )
end

Drivers

Kitchen uses a driver plugin architecture to enable Kitchen to simulate testing on cloud providers, such as Amazon EC2, OpenStack, and Rackspace. Each driver is responsible for managing a virtual instance of that platform so that it may be used by Kitchen during cookbook testing.

Note

The Chef development kit includes the kitchen-vagrant driver.

Most drivers have driver-specific configuration settings that must be added to the kitchen.yml file before Kitchen will be able to use that platform during cookbook testing. Some popular drivers:

Driver Plugin Description
kitchen-all A driver for everything, or “all the drivers in a single Rubygem”.
kitchen-bluebox A driver for Blue Box.
kitchen-cloudstack A driver for CloudStack.
kitchen-digitalocean A driver for DigitalOcean.
kitchen-docker A driver for Docker.
kitchen-ec2 A driver for Amazon EC2.
kitchen-fog A driver for FOG.
kitchen-gce A driver for Google Compute Engine.
kitchen-openstack A driver for OpenStack.
kitchen-rackspace A driver for Rackspace.
kitchen-vagrant A driver for Vagrant. The default driver packaged with the Chef development kit.

kitchen (executable)

kitchen is the command-line tool for Kitchen, an integration testing tool used by the chef-client. Kitchen runs tests against any combination of platforms using any combination of test suites. Each test, however, is done against a specific instance, which is comprised of a single platform and a single set of testing criteria. This allows each test to be run in isolation, ensuring that different behaviors within the same codebase can be tested thoroughly before those changes are committed to production.

Note

Any Kitchen subcommand that does not specify an instance will be applied to all instances.

For more information about the kitchen command line tool, see kitchen.

kitchen.yml

A kitchen.yml file is used to define what is required to run Kitchen, including the driver, the provisioner, and that platforms that are used to create instances on which one (or more) test suites will run.

For more information about the kitchen.yml file, see kitchen.yml.

Syntax

The basic structure of a kitchen.yml file is as follows:

driver:
  name: driver_name

provisioner:
  name: provisioner_name

platforms:
  - name: platform-version
  - name: platform-version

suites:
  - name: suite_name
    run_list:
      - recipe[cookbook_name::recipe_name]
    attributes: { foo: "bar" }
    excludes:
      - platform-version
  - name: suite_name
    run_list:
      - recipe[cookbook_name::recipe_name]
    attributes: { foo: "bar" }
    excludes:
      - platform-version

where:

  • driver_name is the name of a driver that will be used to create platform instances used during cookbook testing. For example, vagrant is the name to use for the kitchen-vagrant driver; some drivers support custom settings

  • provisioner_name specifies how the chef-client will be simulated during testing. chef_zero and chef_solo are the most common provisioners used for testing cookbooks

  • platform-version is a the name of a platform on which Kitchen will perform cookbook testing, for example, ubuntu-12.04 or centos-6.4; depending on the platform, additional driver details—for example, instance names and URLs used with cloud platforms like OpenStack or Amazon EC2—may be required

  • platforms may define Chef server attributes that are common to the collection of test suites

  • suites is a collection of test suites, with each suite_name grouping defining an aspect of a cookbook to be tested. Each suite_name must specify a run-list, for example:

    run_list:
      - recipe[cookbook_name::default]
      - recipe[cookbook_name::recipe_name]
    
  • Each suite_name grouping may specify attributes as a Hash: { foo: "bar" }

  • Each suite_name grouping may use excludes to exclude certain platforms

For example, a very simple kitchen.yml file:

 driver:
   name: vagrant

 provisioner:
   name: chef_zero

 platforms:
   - name: ubuntu-12.04
   - name: centos-6.4
   - name: debian-7.1.0

suites:
  - name: default
    run_list:
      - recipe[apache::httpd]
    excludes:
      - debian-7.1.0

This file uses Vagrant as the driver, which requires no additional configuration because it’s the default driver used by Kitchen, chef-zero as the provisioner, and a single (default) test suite that runs on Ubuntu 12.04, and CentOS 6.4.

For more information ...

For more information about test-driven development and Kitchen: