Cookbookテストフレームワーク「test-kitchen」前編 #opschef_ja
この記事は1年以上前に投稿されました。情報が古い可能性がありますので、ご注意ください。
test-kitchenはCookbookテストフレームワークです。VagrantとVirtualBoxを使って仮想OSを作成し、クリーンな環境の中でCookbookのテストが行えます。テストの仕組みにはMiniTest::SpecやCucumberが用いられます。どちらもビヘイビア駆動開発や振舞駆動開発(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を利用します。他に、VeeWeeやBentoを用いて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環境の準備と簡易テストは終わりです。
後編では実際にテストケースを作成してみます。