LoginSignup
39
38

More than 5 years have passed since last update.

chefspecチートシート

Last updated at Posted at 2013-02-17

公私共にchefを使っていて、テストにchefspecを使っていますが、RSpec系になじみがないからか、なかなか覚えられないのでチートシートにまとめます。
詳細や正確な情報は本家で確認してください。

本家:https://github.com/acrmp/chefspec

specを書く上での準備

nodeの設定

cookbook, role, node等でattributesを定義していて、レシピの動作結果がこれに依存している場合は、convergeより先にnodeに値をセットする必要があります。

prepare1
let( :chef_run ) do
  chef_run = ChefSpec::ChefRunner.new do |node|
    node.set['my_attribute'] = 'bar'
    node.set['my_other_attribute'] = {'hoge' => 'bar2'}
  end.converge 'example::default'
end

chef_environmentの設定

chef-soloではサポートしていなかったりで、個人的にはあまり使いたくないところですが。Environmentはインスタンスなのでnodeと比べると面倒です。

prepare2
let( :chef_run ) do
  ChefSpec::ChefRunner.new do |node|
    env = Chef::Environment.new
    env.name 'staging'
    node.stub(:chef_environment).and_return env.name
    Chef::Environment.stub(:load).and_return env
  end.converge 'example::default'
end

cookbook_pathの追加

site-cookbookを使っていたりでcookbookpathが複数ある場合は、パスを追加する必要があります。

prepare3
let (:chef_run) { ChefSpec::ChefRunner.new(:cookbook_path => ['cookbooks', 'site-cookbooks']).converge 'example::default' }

specの書き方

パッケージ、サービス関連

package_and_service
# package
expect(chef_run).to install_package 'foo'
expect(chef_run).to install_package_at_version 'foo', '1.2.3'
expect(chef_run).to upgrade_package 'foo'
expect(chef_run).to install_yum_package 'yum-foo'

# service
expect(chef_run).to set_service_to_start_on_boot 'food'
expect(chef_run).to restart_service 'food'

ファイル、ディレクトリ操作関連

執筆時点(2013/02)の現行バージョンでは、cookbook_fileがcreate_fileで認識されないのでご注意を。(pullreqは承認されているので、じきに反映されると思いますが)

私の勘違いでした。0.9.0でもcookbook_fileはサポートされています。

file_and_directory
# directory
expect(chef_run).to create_directory '/var/lib/foo'
dir = chef_run.directory('/var/lib/foo')
expect(dir.mode).to eq "0700"
expect(dir).to be_owned_by('user', 'group')

# cookbook_file
expect(chef_run).to create_cookbook_file '/var/lib/hoge.txt'
file = chef_run.cookbook_file('/var/lib/hoge.txt')
expect(file.mode).to eq "0700"
expect(file).to be_owned_by('user', 'group')

# file (template)
expect(chef_run).to create_file '/var/log/bar.log'
file = chef_run.template('/var/log/bar.log')
expect(file.mode).to eq "0600"
expect(file).to be_owned_by('user', 'group')

# remote_file
expect(chef_run).to create_remote_file 'http://path/to/file'
file = chef_run.remote_file('/var/lib/hoge.txt')
expect(file.mode).to eq "0700"
expect(file).to be_owned_by('user', 'group')

# symlink
expect(chef_run).to create_link "/path/to/link"
chef_run.link("/path/to/link").to.should == "/path/from/link"

その他

others
# cron
expect(chef_run.cron('daily_job')).to be

# include recipe
expect(chef_run).to include_recipe 'foo::bar'

# if you want check xxx not, use shoud_not
expect(chef_run).not_to create_directory '/no/such/directory'

あとがき

テストの書き方やその度合いは、統一的な見解はないので人それぞれです。私の場合は、仕様として明らかにしたいもの、後続処理などに影響を与える重要なものに絞ってテストを書くようにしています。特に設計がまとまらない時はテストファーストをすることで、設計とテスト準備を同時にやっつけます。

39
38
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
39
38