[Vagrant & VirtualBox] Serverspec 入門

以前に作った vagrant ファイルにテストを追加します。

[markdown]
> * [VMs/Zend at master · DriftwoodJP/VMs](https://github.com/DriftwoodJP/VMs/tree/master/Zend)
> * [Chef: インストールから Cookbook を作って動かすまで | deadwood](https://www.d-wood.com/blog/2014/09/26_6926.html)
> * [Chef: Vagrant から Chef でプロビジョニングする | deadwood](https://www.d-wood.com/blog/2014/09/29_6938.html)
> * [Chef: 用意したテンプレートを設定ファイルとして利用する | deadwood](https://www.d-wood.com/blog/2014/09/30_6949.html)
> * [Chef: Resources を少し確認する | deadwood](https://www.d-wood.com/blog/2014/10/01_6952.html)

## インストール

`gem install` もしくは Gemfile に下記のように記載する。

> * [Serverspec – Home](http://serverspec.org/)

rake もインストールする必要があります。

“`ruby:Gemfile
gem “chef”, “11.16.0”
gem “knife-solo”
gem “serverspec”, “~>2.8.2”
gem “rspec”, “~>3.2.0”
gem “rake”, “~>10.4.2”
“`

bundle install を実行する。

“`prettyprinted
% bundle install –path vendor/bundle
“`

## プロジェクトを初期化する

“`prettyprinted
% bundle exec serverspec-init
Select OS type:
1) UN*X
2) Windows
Select number: 1
Select a backend type:
1) SSH
2) Exec (local)
Select number: 1
Vagrant instance y/n: y
Auto-configure Vagrant from Vagrantfile? y/n: y
+ spec/
+ spec/default/
+ spec/default/sample_spec.rb
+ spec/spec_helper.rb
+ Rakefile
+ .rspec
“`

サンプルファイルも生成されるので、早速実行します。

## テストを実行する

`bundle exec rake spec` を実行するとうまく動きません。

“`prettyprinted
% bundle exec rake spec
rake aborted!
Circular dependency detected: TOP => spec => spec:all => spec:default => spec:all
Tasks: TOP => spec => spec:all => spec:default
(See full trace by running task with –trace)
“`

### Circular dependency detected に対応

こちらを参考に `task :default => :all` をコメントアウトします。

> * [Ops研修(11月13日).md](https://gist.github.com/yutokyokutyo/cbaa463ee9f1b8cd1fd6)
> * [[serverspec]Circular dependency detectedエラーが出てしまう – Qiita](http://qiita.com/a_ishidaaa/items/1f802fa7bb571bdb00ea)

“`ruby:Rakefile
# task :default => :all
“`

再度実行するとうまく動いたようです。

“`prettyprinted
% bundle exec rake spec
:
Package “httpd”
should be installed
Service “httpd”
should be enabled
should be running
Port “80”
should be listening
Finished in 1.01 seconds (files took 20.28 seconds to load)
4 examples, 0 failures
“`

現行バージョンで動かない理由など、このあたり解決できず。

### vagrant-serverspec

vagrant provision 時に serverspec が実行されるように、plugin をインストールしましたが、エラーを解決できないのでペンディング。

> * [jvoorhis/vagrant-serverspec](https://github.com/jvoorhis/vagrant-serverspec)

“`prettyprinted
% vagrant plugin install vagrant-serverspec
“`

Vagrantfile に serverspec の設定を追加します。

“`ruby:Vagrantfile
Vagrant.configure(‘2’) do |config|
:
# serverspec
config.vm.provision :serverspec do |spec|
spec.pattern = ‘spec/**/*_spec.rb’
end
end
“`

実行すると NoMethodError

“`prettyprinted
% vagrant provision
:
==> default: Running provisioner: serverspec…
/Users/****/projects/VMs/Zend/spec/spec_helper.rb:5:in `‘: undefined method `set’ for main:Object (NoMethodError)
:
“`

> * [vagrant-serverspecを使ってプロビジョニング結果をテストする | Ryuzee.com](http://www.ryuzee.com/contents/blog/6822)

## *_spec.rb にテストを追加する

こちらを参考にテストを追加してみます。

> * [Serverspec – Resource Types](http://serverspec.org/resource_types.html)
> * [Ruby – serverspecのリソースタイプ・マッチャー – Qiita](http://qiita.com/ando-masaki/items/e02960789c7a4e0c4d20)

Resource Types を利用していきます。

### yumrepo

[yumrepo](http://serverspec.org/resource_types.html#yumrepo) の存在と設定を確認。

“`ruby
describe yumrepo(‘remi’) do
it { should exist }
it { should_not be_enabled }
end
“`

### package

[package](http://serverspec.org/resource_types.html#package) がインストールされているか。

“`ruby
describe package(‘php’) do
it { should be_installed }
# it { should be_installed.with_version “5.5” }
end
“`

[php_config](http://serverspec.org/resource_types.html#php_config) という Resource Types もあります。

### command

[command](http://serverspec.org/resource_types.html#command) の実行結果を正規表現で。

“`ruby
describe command(‘php -v’) do
its(:stdout) { should match /^PHP 5\.5\./ }
end
“`

### host

[host](http://serverspec.org/resource_types.html#host) を確認。

“`ruby
describe host(‘php.local’) do
it { should be_resolvable.by(‘hosts’) }
end
“`

### file

[file](http://serverspec.org/resource_types.html#file) を確認し、指定した内容が含まれているか。
配列も利用できる。

“`ruby
describe file(‘/etc/httpd/conf/httpd.conf’) do
it { should be_file }
%w(php zf1 zf2).each do |h|
its(:content) { should match /ServerName #{h}.local/ }
its(:content) { should match /DocumentRoot \/vagrant\/www\/#{h}\/public/ }
end
end
“`

などなど。

## 補遺

参考にさせて頂きました。

> * [Serverspecの使い方入門、Chefで構成管理するサーバー環境をテスト | EasyRamble](http://easyramble.com/serverspec-for-chef-server.html)
> * [watashideath — serverspecでテストを書いた](http://watashideath.tumblr.com/post/70890071015/serverspec)
[/markdown]