Test Kitchen is a framework for isolated integration testing of chef recipes.
For testing a recipe it spawn a vm, execute tests and then destroys it. For local cookbook development and manual testing of changes vagarnt is definitely the first choice, but for developing cookbook with automated tests suits this VM based approach is very slow and as test kitchen destroys box with each run, testing feedback time become really important factor in development speed and is worthy candidate for optimisation.
Optimisation
Containers like openvz and lxc are faster to launch and are very lightweight as compared to virtual box and other VM based backends.
As compared to open vz, lxc is available on the mainstream linux kernel but managing lxc container with scripts is not an easy task, there are two lxc baced framework available, vagrant lxc(vagrant lxc provider) and docker (package and run application as container) which provides good abstraction layer over lxc.
Test Kitchen has a architecture for pluggable virualization backend and it support vagrant, ec2 and recently with kitchen-docker plugin, docker can also used as driver.
I am using following setup to use test kitchen with docker.
Setup
Install docker
Install it for supported platform or Install it with community cookbook with chef and berkself
#Berksfile to install docker
site :opscode
metadata
group :integration do
cookbook 'docker'
end
Install test-kitchen and docker driver
Can be installed with bundler by using following Gemfile file
source 'https://rubygems.org'
gem 'berkshelf', '~> 2.0'
group :integration do
gem 'test-kitchen', '~> 1.0.0.beta'
gem 'kitchen-docker'
end
Test Cookbook
Download ntp cookbook for testing, beacuse it also serve as a testing documentation reference
Execute Tests
Change .kitchen.yml file of ntp cookbook to use kitchen docker plugin
---
driver_plugin: docker
driver_config:
require_chef_omnibus: true
platforms:
- name: centos
driver_config:
image: "centos"
platform: "rhel"
run_list:
- recipe[yum]
suites:
- name: default
run_list:
- recipe[ntp::default]
attributes:
ntp:
sync_clock: true
sync_hw_clock: true
- name: undo
run_list:
- recipe[ntp::undo]
And run kitchen to execute tests in docker container
bundle exec kitchen test
More optimisations
Test Kitchen downloads chef omnibus package every time while spawning a container, this step takes both time and bandwidth, this behaviour can be override by setting require_chef_omnibus flag, there are also few tricks to speed up this step.
- use local repository for chef omnibus and override chef_omnibus_url flag
- use lightweight gem like chef zero
- utilize docker cache with provision_command command
- package omnibus with container and build image for testing
New image can be easily created by using following docker file
cat << 'EOF' > Dockerfile
FROM centos
RUN curl -L https://www.opscode.com/chef/install.sh | sudo bash
EOF
docker build -t image_name .
Set and image: image_name in .kitchen.yml file and execute tests more faster.