Test Kitchen の Shell Verifier で Serverspec による Cookbook テストを行う #getchef #serverspec
この記事は1年以上前に投稿されました。情報が古い可能性がありますので、ご注意ください。
2015年12月現在、Test Kitchen で Chef Cookbook のテストを行うのは busser-serverspec を媒介とした Serverspec がデファクトスタンダードとなっています(RubyGems.org 調べ: busser-serverspec:132万DL, busser-bats:28万DL, busser-rspec:7万DL)。
本稿では、Cookbook テストを行うための媒介として従来の busser 機構の代わりに、2015年7月に公開された Shell Verifier (2015年12月に Test Kitchen 本体にマージ)を用いる方法を見てみます。
busser のおさらい
Test Kitchen + busser + busser-serverspec + Serverspec による Cookbook テストの挙動を確認しておきましょう。
この例では Kitchen Driver に Vagrant (VirtualBox)、Kitchen Provisioner に chef-solo を使うとします。他の Driver や Provisioner でも変わらないでしょう。テストケースは Serverspec で作っているとします。
まず、Test Kitchen を実行すると、Vagrant (VirtualBox) を用いて、Cookbook を適用するための Chef Node を作成します。そちらに Cookbook を転送し、Chef-Solo で Node に適用・収束を行います。
収束が完了したら、Test Kitchen は RubyGems.org から busser gem などを Chef Node にインストールします。インストールされた busser は、テストケースが Serverspec で作られていることをディレクトリから判別し、RubyGems.org から busser-serverspec gem を Chef Node にインストールします。Test Kitchen は Chef Node にテストケースをアップロードし、busser-serverspec は localhost すなわち Chef Node に対して Serverspec を実行します。
これで、Serverspec による Chef Cookbook のテストを実現しています。
busser 機構によるテストの問題点として、次が挙げられるでしょう。
- busser や busser-serverspec を毎回 Chef Node に RubyGems.org から取得してインストールするため時間がかかる、あるいはネットワークの疎通を気にする必要がある。
- テストを busser 下という特殊な状況で実行するため、バグか仕様かわからない現象に悩まされる(issues)。または操作に自由が効かない(Pull Requests)。
busser は、もともとネットワーク機能を持たないようなテストスイートでも Cookbook のテストが行えるように、Chef Node 内に隔離環境を作ってテストを行う仕組みなので、ある意味仕方のない面があるかもしれません。
一方、Serverspec は SSH をはじめとしてさまざまなネットワーク機能を備えているため、ホスト側で Serverspec を実行してやれば、busser を仲介役に置く必要がありません。これを実現するのが Shell Verifier です。
Shell Verifier とは
Test Kitchen + Shell Verifier + Serverspec による Cookbook テストの挙動を確認しておきましょう。
Verifier とは Test Kitchen 1.4.0 で導入された仕組みで、Cookbook の Verify ステップを行う部位をプラガブルにしたものです。実は busser もこの Verifier から呼び出されています。
この例でも同様に、Kitchen Driver に Vagrant (VirtualBox)、Kitchen Provisioner に chef-solo を使うとします。他の Driver や Provisioner でも変わらないでしょう。テストケースは Serverspec で作っているとします。
ここでもやはり Test Kitchen を実行すると、Vagrant (VirtualBox) を用いて、Cookbook を適用するための Chef Node を作成します。そちらに Cookbook を転送し、Chef-Solo で Node に適用・収束を行います。
収束が完了したら、Test Kitchen は .kitchen.yml にて Shell Verifier として指定したコマンドを実行します。ここでは Serverspec (rspec) を実行したとしましょう。Serverspec は Chef Node に対して SSH 接続、すなわちリモートホストに対してテストケースを実行します。
この方法だと、収束した Chef Node は(Cookbook テストが終われば破棄するとはいえ)クリーンな状態に置かれ、ローカルマシン側は既にインストールされているであろう Serverspec を Cookbook テストのたびに再インストールする必要もありません。
Serverspec による Cookbook テストを行うならば、busser + busser-serverspec に比べて、Shell Verifier がいかに単純に行えるかがわかると思います。
Shell Verifier で実際に Cookbook テストを行う
では実際に Shell Verifier を使ったテストを行います。Cookbook は こちら です。テストの前に、Shell Verifier に具体的な部位を見ていきましょう。
.kitchen.yml:
verifier:
name: shell
command: rspec -c -f d -I serverspec serverspec/apache2-take_spec.rb
Verify ステップで Shell Verifier を使い、どのようなコマンドを実行するか指定しています。
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
:
(中略)
:
何の変哲もない Serverspec のテストケースです。busser で使っているものと違いはありません。言い換えると、流用できるということです。
require 'serverspec'
set :backend, :ssh
options = Net::SSH::Config.for(host)
options