fbpx

CL LAB

HOME > CL LAB > Chef > Test Kitchen の Shell Verifier で Serverspec による Cookbook テストを行う #getchef #serverspec

Cookbook testing by Serverspec with Shell Verifier of Test Kitchen #getchef #serverspec

 ★ 1

Serverspec intermediated by busser-serverspec is the de facto standard for Chef Cookbook testing with Test Kitchen as of December, 2015.
(From: RubyGems.org, busser-serverspec:1,320K DL, busser-bats:280K DL, busser-rspec:70K DL.)

This document looks at Shell Verifier published in July 2015 instead of conventional busser mechanism that intermediated Cookbook test.
(Shell Verifier has been merged to Test Kitchen in December 2015.)

Review of busser

Let's look at the behavior of Cookbook with Test Kitchen + busser + busser-serverspec + Serverspec here.

busser

This example assumes using Vagrant (VirtualBox) for Kitchen Driver, and chef-solo for Kitchen Provisioner. It will be the same if other Driver and Provisioner are used. Also, testcase is assumed made by Serverspec.

At first when Test Kitchen is executed, Chef Node is created to apply Cookbook with Vagrant (VirtualBox). Transfer Cookbook to the Node, then apply and converge the Node with Chef-Solo.

When the convergence is finished, Test Kitchen will install such as busser gem from RubyGems.org on the Chef Node. The installed busser will check the testcase was made by Serverspec, and install busser-serverspec gem from RubyGems.org. Test Kitchen uploads testcase to Chef Node, and busser-serverspec executes Serverspec against localhost which is Chef Node.

By this, Chef Cookbook test is realized by Serverspec.

Following points are the issues of testing with busser mechanism;

  • It takes every times as it will obtain busser and busser-serverspec from RubyGems.org and install them to Chef Node, or care must be taken for the network communication.
  • It is difficult to determine the phenomenon are bug or specification as test is done under special environment of busser (issues), or limited for operation (Pull Requests).

This could be no choice because busser was designed to test by creating isolated environment within Chef Node, and to test the Cookbook with the test suite where no network functions.

On the other hand, Since Serverspec has SSH and various network functions, busser is not required as a go-between if Serverspec is executed at host side. Shell Verifier realizes this.

What is Shell Verifier?

We have to know the behavior of the Cookbook test with Test Kitchen + Shell Verifier + Serverspec.

Verifier is the mechanism that the part of Verify step is made pluggable and was introduced in Test Kitchen 1.4.0.
The busser is actually called by the Verifier.

verifier

This example as well is assumed using Vagrant (VirtualBox) for Kitchen Driver, and chef-solo for Kitchen Provisioner. It will be the same if other Driver and Provisioner are used. Also, testcase is assumed made by Serverspec.

In this case as well, when Test Kitchen is executed, Chef Node is created to apply Cookbook with Vagrant (VirtualBox). Transfer Cookbook to the Node, then apply and converge the Node with Chef-Solo.

When the convergence is finished, Test Kitchen will execute the designated command as Shell Verifier in .kitchen.yml. Assuming Serverspec (rspec) is executed here, Serverspec will execute SSH connection to Chef Node, in other words, executing testcase for the remote host.

With this method, converged Chef Node is placed under clean environment (destroy it after the Cookbook test, though), Serverspec which is supposed to be already installed at local machine is not necessarily installed every time on Cookbook test.

It is easy for you to imagine how Shell Verifier is simple if conducting Cookbook test with Serverspec, comparing busser + serverspec.

Actual Cookbook test with Shell Verifier

In this section we will conduct an actual test using Shell Verifier. The Cookbook is here. Let's take a look at the actual part of Shell Verifier before starting the test;

.kitchen.yml:


verifier:
name: shell
command: rspec -c -f d -I serverspec serverspec/apache2-take_spec.rb

Use Shell Verifier at Verify step, specify what kind of command to be executed by this.

serverspec/apache2-take_spec.rb:


require 'spec_helper'

%w{ apache2 git-core curl unzip }.each do |i|
describe package( i ) do
it { should be_installed }
end
end
:
(snip)
:

This is a testcase as just what you would expect. There is no difference from using busser. In other words, it can be diverted.

serverspec/spec_helper.rb:


require 'serverspec'

set :backend, :ssh

options = Net::SSH::Config.for(host)
options[:host_name] = ENV['KITCHEN_HOSTNAME']
options[:user] = ENV['KITCHEN_USERNAME']
options[:port] = ENV['KITCHEN_PORT']
options[:keys] = ENV['KITCHEN_SSH_KEY']

set :host, options[:host_name]
set :ssh_options, options
set :env, :LANG => 'C', :LC_ALL => 'C'

Here, Setting is made for Serverspec to SSH log in to Chef Node.

In order to SSH log in to Chef Node, Shell Verifier obtains and sets the environment variables of KITCHEN_HOSTNAME, KITCHEN_USERNAME, KITCHEN_PORT, KITCHEN_SSH_KEY.

Then, the actual log by executing Test Kitchen is as follows;


% kitchen test
-----> Starting Kitchen (v1.4.2)
-----> Cleaning up any prior instances of
-----> Destroying ...
Finished destroying (0m0.00s).
-----> Testing
-----> Creating ...
:
(snip)
:
-----> Converging ...
:
(snip)
:
-----> Installing Chef Omnibus (install only if missing)
:
(snip)
:
Finished converging (1m50.56s).
-----> Setting up ...
Finished setting up (0m0.00s).
-----> Verifying ...
[Shell] Verify on instance=# with state={:hostname=>"127.0.0.1", :port=>"2222", :username=>"vagrant", :ssh_key=>"/home/d-higuchi/github/apache2-take/.kitchen/kitchen-vagrant/kitchen-apache2-take-default-ubuntu-1404/.vagrant/machines/default/virtualbox/private_key", :last_action=>"setup"}

Package "apache2"
should be installed

Package "git-core"
should be installed

Package "curl"
should be installed

Package "unzip"
should be installed

Service "apache2"
should be enabled
should be running

Port "8080"
should be listening

File "/etc/apache2/ports.conf"
should be file
should be owned by "root"
should be grouped into "root"
should be mode 644

File "/etc/apache2/sites-available/default.conf"
should be file
should be owned by "root"
should be grouped into "root"
should be mode 644

File "/etc/apache2/ports.conf"
should contain "NameVirtualHost *:8080"
should contain "Listen 8080"

File "/etc/apache2/sites-available/default.conf"
should contain ""

File "/etc/apache2/sites-enabled/default.conf"
should be linked to "../sites-available/default.conf"

File "/var/www/index.html"
should be file
should contain "Welcome to my top page"

File "/var/www/img"
should be directory

Finished in 1.07 seconds (files took 1.98 seconds to load)
22 examples, 0 failures

Finished verifying (0m3.13s).
Finished testing (2m43.59s).
-----> Kitchen is finished. (2m44.09s)
%

It was very simple to complete Cookbook test by Serverspec.

Summary

We looked at Cookbook testing by Serverspec with Shell Viewer after reviewing testing with busser and busser-serverspec.
You can now understand the former is overwhelmingly simpler and easier. Also, It is beneficial to call the test suites such as Infrataster and Capybara from Shell Verifier.

Frankly speaking, as Cookbook testing can be made without using complex busser, I don't use busser-serverspec recently even I'm the author.
Also, the reason why I positively moved toward merging in the discussion of Add shell verifier Pull Request and the Q&A session of Chef Meetup ( featuring Docker ) was that the merit was very big by not using busser-serverspec.

I would like to thank Yukihiko SAWANOBORI who is author of Shell Verifier and all those who contributed merging.

CL LAB Mail Magazine

CL LABの情報を逃さずチェックしよう!

メールアドレスを登録すると記事が投稿されるとメールで通知します。

メールアドレス: 登録

※登録後メールに記載しているリンクをクリックして認証してください。

Related post