fbpx

Cookbookテストフレームワーク「test-kitchen」前編 #opschef_ja

この記事は1年以上前に投稿されました。情報が古い可能性がありますので、ご注意ください。

test-kitchenはCookbookテストフレームワークです。VagrantVirtualBoxを使って仮想OSを作成し、クリーンな環境の中でCookbookのテストが行えます。テストの仕組みにはMiniTest::SpecCucumberが用いられます。どちらもビヘイビア駆動開発や振舞駆動開発(BDD, Behavior Driven Development)と呼ばれる開発手法のためのテストフレームワークです。なお、OpenStack上に仮想OSを作成してのテストも可能です。

本稿では前編として、test-kitchen環境の準備とテストケースを作成しない簡易テストまでを行います。

VirtualBox, Vagrantのインストール

VirtualBoxのインストールについては各OS、VirtualBox公式サイトの情報を参照してください。

ここではVagrantは1.0系をインストールします。gemでインストールすると1.0系がインストールされます。

ubuntu@kitchen:~$ sudo /opt/chef/embedded/bin/gem install vagrant --no-rdoc --no-ri --verbose
	:
/opt/chef/embedded/bin/vagrant
Successfully installed vagrant-1.0.7
1 gem installed
ubuntu@kitchen:~$ 

Vagrant 1.0系は今後レガシー化していき、Vagrant 1.1系が安定版として主流になっていくでしょう。1.1系はgemではなく、単体のパッケージとして提供されます。

Boxの準備

テストに利用するためのVMイメージ(Box)を準備します。提供サイトとしてVagrantbox.esがよく知られていますが、ここではOpscodeが提供しているBoxを利用します。他に、VeeWeeBentoを用いてBoxを自作する方法もあります。

ここではUbuntu 12.04 LTS, Ubuntu 10.04 LTS, CenOS 6.3, CentOS 5.8 (すべて x86_64, Chef 11.2.0)のBoxを利用します。

ubuntu@kitchen:~$ for i in \
  opscode_ubuntu-12.04_chef-11.2.0.box \
  opscode_ubuntu-10.04_chef-11.2.0.box \
  opscode_centos-6.3_chef-11.2.0.box \
  opscode_centos-5.8_chef-11.2.0.box; do \
    /opt/chef/embedded/bin/vagrant box add `echo $i | sed -e 's/opscode_/opscode-/' -e 's/_.*//' https://opscode-vm.s3.amazonaws.com/vagrant/$i; \
done
[vagrant] Downloading with Vagrant::Downloaders::HTTP...
[vagrant] Downloading box: https://opscode-vm.s3.amazonaws.com/vagrant/opscode_ubuntu-12.04_chef-11.2.0.box
[vagrant] Extracting box...
[vagrant] Verifying box...
[vagrant] Cleaning up downloaded box...
	:
ubuntu@kitchen:~$

ubuntu@kitchen:~$ ls -F .vagrant.d/boxes
opscode-centos-5.8/  opscode-ubuntu-10.04/
opscode-centos-6.3/  opscode-ubuntu-12.04/
ubuntu@kitchen:~$

test-kitchenのインストール

まず、bundlerをgemでインストールします。

ubuntu@kitchen:~$ sudo /opt/chef/embedded/bin/gem install bundler --no-rdoc --no-ri --verbose
	:
/opt/chef/embedded/bin/bundle
Successfully installed bundler-1.3.5
1 gem installed
ubuntu@kitchen:~$ 

テストケースを作成するCookbookのディレクトリに移動し、
test-kitchenをインストールするためのGemfileファイルを作成します。

ubuntu@kitchen:~/chef-repo/cookbooks/apache2-take$ cat < Gemfile
source 'https://rubygems.org'
gem "test-kitchen", "> 1.0"
ubuntu@kitchen:~/chef-repo/cookbooks/apache2-take$ 

システムにそのままtest-kitchenをインストールする場合は、そのままbundle installを行います。ただし、システムに既に多数のgemがインストールされている場合、干渉が起きて動作不良が発生する可能性があります。

ubuntu@kitchen:~/chef-repo/cookbooks/apache2-take$ sudo /opt/chef/embedded/bin/bundle install --verbose
	:
Your bundle is complete!
Use `bundle show [gemname]` to see where a bundled gem is installed.
Post-install message from bunny:
[Version 0.7.8] test suite cleanup (eliminated some race conditions related to queue.message_count)
ubuntu@kitchen:~/chef-repo/cookbooks/apache2-take$ 

システム外のディレクトリにインストールする場合、インストールパスを指定してbundle installを行います。この場合、.bundle/configファイルが生成され、そちらにパスが格納されます。

ubuntu@kitchen:~/chef-repo/cookbooks/apache2-take$ /opt/chef/embedded/bin/bundle install --path /home/ubuntu/chef-repo/cookbooks/vendor/bundle --verbose
	:
Your bundle is complete!
It was installed into /home/ubuntu/chef-repo/cookbooks/vendor/bundle
Post-install message from bunny:
[Version 0.7.8] test suite cleanup (eliminated some race conditions related to queue.message_count)
ubuntu@kitchen:~/chef-repo/cookbooks/apache2-take$ 

ubuntu@kitchen:~/chef-repo/cookbooks/apache2-take$ cat .bundle/config
---
BUNDLE_PATH: /home/ubuntu/chef-repo/cookbooks/vendor/bundle
BUNDLE_DISABLE_SHARED_GEMS: '1'
ubuntu@kitchen:~/chef-repo/cookbooks/apache2-take$ 

簡易テスト

bundle exec kitchen initを実行すると、testディレクトリとその中に雛形が作成されます。

ubuntu@kitchen:~/chef-repo/cookbooks/apache2-take$ /opt/chef/embedded/bin/bundle exec kitchen init
ubuntu@kitchen:~/chef-repo/cookbooks/apache2-take$ 

ubuntu@kitchen:~/chef-repo/cookbooks/apache2-take$ ls -aR test/
test/:
.  ..  kitchen

test/kitchen:
.  ..  Kitchenfile
ubuntu@kitchen:~/chef-repo/cookbooks/apache2-take$ 

ubuntu@kitchen:~/chef-repo/cookbooks/apache2-take$ cat test/kitchen/Kitchenfile cookbook "apache2-take" do

end
ubuntu@kitchen:~/chef-repo/cookbooks/apache2-take$ 

テストケースを何も作っていない状態でも簡易テストが行えます。
bundle exec kitchen testを実行してみましょう。
何が行われているか順に見ていきます。

ubuntu@kitchen:~/chef-repo/cookbooks/apache2-take$ /opt/chef/embedded/bin/bundle exec kitchen test
checking apache2-take

まず、knife cookbook testによって、Cookbook中の.rbと.erbで終わるすべてのファイルに対してRubyの構文チェックを行います。

Running syntax check on apache2-take
Validating ruby files
Validating templates

次に、foodcriticによってCookbookのよくある間違いや推奨されない記述などのチェックが行われます。
ここではapache2-take Cookbookのmaintainerとmaintainer_emailが生成されたままの状態で変更されていないことを指摘しています。

なお、foodcriticはgem単体でインストールが可能です。

FC008: Generated cookbook metadata needs updating: /home/ubuntu/chef-repo/cookbooks/apache2-take/metadata.rb:2
FC008: Generated cookbook metadata needs updating: /home/ubuntu/chef-repo/cookbooks/apache2-take/metadata.rb:3

knife cookbook testとfoodcriticによる静的テストが完了したら、インスタンスを用いてCookbookを実際に適用するテストを行います。

centos-5.8, centos-6.3, ubuntu-10.04, ubuntu-12.04の順番でインスタンスが起動されますが、このCookbookはsupportsがUbuntuのみのため、CentOSは飛ばされています。

Assembling required cookbooks at [/home/ubuntu/chef-repo/cookbooks/apache2-take/test/kitchen/.kitchen/cookbooks].
[ubuntu-10.04] Importing base box 'opscode-ubuntu-10.04'...
[ubuntu-10.04] Progress: 90%
[ubuntu-10.04] Matching MAC address for NAT networking...
[ubuntu-10.04] Clearing any previously set forwarded ports...
[ubuntu-10.04] Forwarding ports...
[ubuntu-10.04] -- 22 =< 2222 (adapter 1)
[ubuntu-10.04] Creating shared folders metadata...
[ubuntu-10.04] Clearing any previously set network interfaces...
[ubuntu-10.04] Running any VM customizations...
[ubuntu-10.04] Booting VM...
[ubuntu-10.04] Waiting for VM to boot. This can take a few minutes.
[ubuntu-10.04] VM booted and ready for use!
	:
[ubuntu-10.04] Setting host name...
[ubuntu-10.04] Mounting shared folders...
[ubuntu-10.04] -- v-root: /vagrant
[ubuntu-10.04] -- project: /test-kitchen/source
[ubuntu-10.04] -- v-csc-1: /tmp/vagrant-chef-1/chef-solo-1/cookbooks
[ubuntu-10.04] Running provisioner: Vagrant::Provisioners::ChefSolo...
[ubuntu-10.04] Generating chef JSON and uploading...
[ubuntu-10.04] Running chef-solo...
stdin: is not a tty
[2013-04-10T07:35:53+00:00] INFO: *** Chef 11.2.0 ***
[2013-04-10T07:35:53+00:00] INFO: Setting the run_list to ["test-kitchen::default", "recipe[minitest-handler]", "apache2-take::default"] from JSON
[2013-04-10T07:35:53+00:00] INFO: Starting Chef Run for ubuntu-10-04
[2013-04-10T07:35:53+00:00] INFO: Running start handlers
[2013-04-10T07:35:53+00:00] INFO: Start handlers complete.
[2013-04-10T07:35:54+00:00] INFO: Processing execute[apt-get update] action run (apt::default line 29)
[2013-04-10T07:36:00+00:00] INFO: execute[apt-get update] ran successfully
[2013-04-10T07:36:00+00:00] INFO: Processing chef_gem[minitest] action nothing (minitest-handler::default line 4)
[2013-04-10T07:36:00+00:00] INFO: Processing chef_gem[minitest] action install (minitest-handler::default line 4)
[2013-04-10T07:36:06+00:00] INFO: Processing chef_gem[minitest-chef-handler] action nothing (minitest-handler::default line 9)
[2013-04-10T07:36:06+00:00] INFO: Processing chef_gem[minitest-chef-handler] action install (minitest-handler::default line 9)
	:

まず最初に環境設定が行われ、実際にCookbookを適用してのテストが開始されます。

[2013-04-10T07:36:39+00:00] INFO: Processing execute[apt-get update] action run (apache2-take::default line 11)
[2013-04-10T07:36:41+00:00] INFO: execute[apt-get update] ran successfully
[2013-04-10T07:36:41+00:00] INFO: Processing package[apache2] action install (apache2-take::default line 17)
	:
	:
	:
[2013-04-10T07:37:15+00:00] INFO: service[apache2] restarted
[2013-04-10T07:37:15+00:00] INFO: Chef Run complete in 81.87310443 seconds
[2013-04-10T07:37:15+00:00] INFO: Running report handlers
Run options: -v --seed 7363


# Running tests:


minitesthandler::default#test_0001_runs_no_tests = 
0.00 s = 
.



Finished tests in 0.002253s, 443.7565 tests/s, 0.0000 assertions/s.


1 tests, 0 assertions, 0 failures, 0 errors, 0 skips

[2013-04-10T07:37:15+00:00] INFO: Report handlers complete
[ubuntu-10.04] Forcing shutdown of VM...
[ubuntu-10.04] Destroying VM and associated drives...

今回は正常にRecipeが実行されたようです。
テストケースを作成していないため十分とは言えませんが、クリーンな環境でRecipeの実行が行えるだけでも有用だと思われます。

インスタンスの状態を確認するにはbundle exec kitchen statusとします。

ubuntu@kitchen:~/chef-repo/cookbooks/apache2-take$ /opt/chef/embedded/bin/bundle exec kitchen status
Current VM states:

centos-5.8               not created
centos-6.3               not created
ubuntu-10.04             not created
ubuntu-12.04             not created

This environment represents multiple VMs. The VMs are all listed
above with their current state. For more information about a specific
VM, run `vagrant status NAME`.
ubuntu@kitchen:~/chef-repo/cookbooks/apache2-take$

テストの実行後にインスタンスの停止・削除を自動的に行うには--teardownオプションをつけてください。

$ /opt/chef/embedded/bin/bundle exec kitchen test --teardown

手動で停止・削除を行うにはbundle exec kitchen destroyとします。

$ /opt/chef/embedded/bin/bundle exec kitchen destroy

テストを行いたいVMイメージ、停止したいインスタンスを指定したい場合は--platformオプションをつけてください。

$ /opt/chef/embedded/bin/bundle exec kitchen test --platform ubuntu-10.04
$ /opt/chef/embedded/bin/bundle exec kitchen destroy --platform ubuntu-10.04

kitchenには他にもいくつか利用方法があるのでbundle exec kitchenを実行してサブコマンドを確認してみてください。

以上でtest-kitchen環境の準備と簡易テストは終わりです。
後編では実際にテストケースを作成してみます。

Author

Chef・Docker・Mirantis製品などの技術要素に加えて、会議の進め方・文章の書き方などの業務改善にも取り組んでいます。「Chef活用ガイド」共著のほか、Debian Official Developerもやっています。

Daisuke Higuchiの記事一覧

新規CTA