Chef のレシピから serverspec のテストを自動生成する chef-serverspec-handler という gem を作ってみた
『Chef のレシピは「こうあるべき」を記述するものだから、レシピからテストが自動生成できるべきだよな』とずっと思っていたんだけど、最近触りはじめた serverspec がシンプルで簡単に自動生成できそうなのでやってみた。
使い方は上記リンクに書いてある通りなのですが、たとえば Chef のレシピにこう書いてあるやつを、
template '/var/tmp/template.txt' do source 'template.txt.erb' mode 0777 owner 'root' group 'root' variables(:val1 => 'val1', :val2 => 'val2', :val3 => 'val3') action :create end
このような serverspec のテストに自動変換してくれます。
context file('/var/tmp/template.txt') do it { should be_file should be_mode 777 should be_owned_by 'root' should contain 'val1' should contain 'val2' should contain 'val3' } end
この形がよいのかどうかはよく分からないけど Chef の Handler として実装してあり、--why-run オプションと組み合わせて使うことを想定しています。
コンセプトコードみたいなものなので、ちゃんと動かないところがたくさんあるかも。というか試しに Opscode コミュニティの wordpress クックブック + ニフティクラウドの CentOS 6.3 64bit Plain サーバーで試したら、自動生成された 77 テスト中 4 つのテストが失敗した。
Failures: [18/829] 1) apache2::default Package "apache2" Failure/Error: it { should be_installed } rpm -q apache2 パッケージ apache2 はインストールされていません。 expected Package "apache2" to be installed # ./spec/localhost/apache2/default_spec.rb:5:in `block (3 levels) in <top (required)>' 2) apache2::mod_php5 Package "php package" Failure/Error: it { should be_installed } rpm -q php\ package パッケージ php package はインストールされていません。 expected Package "php package" to be installed # ./spec/localhost/apache2/mod_php5_spec.rb:9:in `block (3 levels) in <top (required)>' 3) mysql::server File "/etc/my.cnf" Failure/Error: should contain 'false' grep -q -- false /etc/my.cnf expected File "/etc/my.cnf" to contain "false" # ./spec/localhost/mysql/server_spec.rb:73:in `block (3 levels) in <top (required)>' 4) wordpress::default File "/etc/httpd/sites-available/wordpress.conf" Failure/Error: should contain '{:template=>"wordpress.conf.erb", :enable=>true, :docroot=>"/var/www/wordpress", :server_name=>"localhost", :server_aliases=>["localhost"], :na me=>"wordpress"}' grep -q -- \{:template\=\>\"wordpress.conf.erb\",\ :enable\=\>true,\ :docroot\=\>\"/var/www/wordpress\",\ :server_name\=\>\"localhost\",\ :server_aliases\=\>\[\"localhost\" \],\ :name\=\>\"wordpress\"\} /etc/httpd/sites-available/wordpress.conf expected File "/etc/httpd/sites-available/wordpress.conf" to contain "{:template=>\"wordpress.conf.erb\", :enable=>true, :docroot=>\"/var/www/wordpress\", :server_name=>\"l ocalhost\", :server_aliases=>[\"localhost\"], :name=>\"wordpress\"}" # ./spec/localhost/wordpress/default_spec.rb:44:in `block (3 levels) in <top (required)>'
1,2 は CentOS なのに Debian/Ubuntu のパッケージをインストールしようとしているのでレシピが悪いように思うのですが、
3,4 は chef-serverspec-handler が template リソースの variables で指定されたハッシュの値を単純に should contain しているのがダメで、そもそも variables は単純な値の埋め込み以外にも true/false を渡してテンプレートの内容を切り分けるような用途にも使うので、テンプレートの内容を論理的に解析する必要があり、対応するのがむずかしそうに思った。
というようにマダマダな感じなのですが、既存のレシピ資産にテストを書く足がかりにはなると思うので、よかったらお試しください。