m-namikiの日記

おもしろき こともなき世を おもしろく

serverspecのテストケースを育ててみた

前回の記事で作成したserverspecのテストケースを育ててみました。Ruby on Railsチュートリアルの写経を始めました - m-namikiの日記のときに作成したレシピを対象にします。レシピはこんなことをやっていました。

  • iptablesの停止、無効化
  • epel、remiをyumリポジトリに追加
  • sqlite-develのインストール
  • rbenvでruby1.9.3-p545のインストール
  • gemでrbenv-rehash、rails3.2.14のインストール

で、追加したテストケースはこちら。

# package for rails3-tutorial
describe package('sqlite-devel') do
  it { should be_installed }
end

# ruby versions
describe command('ruby -v') do
  it { should return_stdout /ruby 1\.9\.3p545.+/ }
end

# for gem packages
describe package('rbenv-rehash') do
  it { should be_installed.by('gem') }
end

describe package('rails') do
  it { should be_installed.by('gem').with_version('3.2.14') }
end

epel、remiに関しては最初に書いたときに入れていたので割愛します。で、さっそく実行してみると

C:\Users\m-namiki\Documents\20_vagrant\rails3_tutorial>rake spec
C:/Ruby193/bin/ruby.exe -S rspec spec/default/base_spec.rb
..........FFF

Failures:

  1) Command "ruby -v" should return stdout /ruby 1\.9\.3p545.+/
     Failure/Error: it { should return_stdout /ruby 1\.9\.3p545.+/ }
       sudo ruby -v
       ruby 1.8.7 (2011-06-30 patchlevel 352) [x86_64-linux]
       expected Command "ruby -v" to return stdout /ruby 1\.9\.3p545.+/
     # ./spec/default/base_spec.rb:36:in `block (2 levels) in <top (required)>'

  2) Package "rbenv-rehash" should be installed
     Failure/Error: it { should be_installed.by('gem') }
       sudo gem list --local | grep -w -- \^rbenv-rehash
       expected Package "rbenv-rehash" to be installed
     # ./spec/default/base_spec.rb:41:in `block (2 levels) in <top (required)>'

  3) Package "rails" should be installed
     Failure/Error: it { should be_installed.by('gem').with_version('3.2.14') }
       sudo gem list --local | grep -w -- \^rails | grep -w -- 3.2.14
       expected Package "rails" to be installed
     # ./spec/default/base_spec.rb:45:in `block (2 levels) in <top (required)>'

Finished in 27.6 seconds
13 examples, 3 failures

Failed examples:

rspec ./spec/default/base_spec.rb:36 # Command "ruby -v" should return stdout /r
uby 1\.9\.3p545.+/
rspec ./spec/default/base_spec.rb:41 # Package "rbenv-rehash" should be installe
d
rspec ./spec/default/base_spec.rb:45 # Package "rails" should be installed
C:/Ruby193/bin/ruby.exe -S rspec spec/default/base_spec.rb failed

残念、失敗!エラーメッセージを見るとsudoしているので、rbenvでインストールしたrubyのバージョンが違ったり、gemで認識されていなかったりするようです。なのでまずはvagrantユーザで実行しているrubygemはどこを見ているのか確認してみます。

[vagrant@localhost ~]$ which ruby
/opt/rbenv/shims/ruby
[vagrant@localhost shims]$ which gem
/opt/rbenv/shims/gem

なるほど、ならばリソースタイプがcommandの場合はこのパスを追加してあげれば良さそうですが、packageの場合はどうしよう。答えは公式ドキュメントに書いてありました。ページ下段の方にあるBlock scoped PATH environment variableを読んでみるとブロック内でPATHを指定することができるようです。なので以下のように書き換えてみました。

# ruby versions
describe command('ruby -v') do
  let(:path) { '/opt/rbenv/shims' }
  it { should return_stdout /ruby 1\.9\.3p545.+/ }
end

# for gem packages
describe package('rbenv-rehash') do
  let(:path) { '/opt/rbenv/shims' }
  it { should be_installed.by('gem') }
end

describe package('rails') do
  let(:path) { '/opt/rbenv/shims' }
  it { should be_installed.by('gem').with_version('3.2.14') }
end

同じ設定を3回書いてるのがちょっとアレですが、これで実行してみます。

C:\Users\m2-namiki\Documents\20_vagrant\rails3_tutorial>rake spec
C:/Ruby193/bin/ruby.exe -S rspec spec/default/base_spec.rb
...............

Finished in 29.69 seconds
15 examples, 0 failures

今度は無事に成功しました。公式ドキュメントは隅々まで読まなきゃダメですね。。。あとはChefでrbenvを使ってRubyをインストールするCookbookを書いた | ひげろぐを参考にさせていただき、最終的なテストケースはこんな感じになりました。
serverspecをvagrantと連携させるためのプラグインvagrant-serverspec)もあるそうなので、今度はこちらも試してみようと思います。