test-kitchen + serverspec を使ってみた。

# 経緯
前回、[初めての Vagrant + Chef Zero + Berkshelf](http://qiita.com/tsuyopooon/items/d90679d9f8b5ccfcfde5) をやってみて、
ゲスト OS に ssh して、適用した cookbook の確認を目視で確認していたのですが、
今後 cookbook を自作していく際に、簡単に recipe が反映されているか確認したいなということで、出会ったのが tet-kitchen + serverspec　達。

## さっそく使ってみる

### test-kitchen の設定ファイルを作成

.kitchen.yml を作成します。デフォルトのドライバは Vagrant の模様。

```
$ cd test_centos64/chef-repo
$ kitchen init
```

```vim:.kitchen.yml
---
driver:
  name: vagrant

provisioner:
  name: chef_solo

platforms:
  - name: ubuntu-12.04
  - name: centos-6.4

suites:
  - name: default
    run_list:
    attributes:
```

- driver
テストする仮想環境を指定します。
- provisioner
利用する provisioner を指定します。
- platforms
テストする環境を指定します。複数可。
- suites
実行するテストスイート。


.kitchen.yml を下記のように変更します。
今回作成するテストスイートは、前回使用した recipe の timezone-ii が正しく反映されているか確認するものにします。

```vim:.kitchen.yml
---
driver:
  name: vagrant

provisioner:
  name: chef_zero
  require_chef_omnibus: latest

platforms:
  - name: ubuntu-12.04
  - name: centos-6.4
    driver:
      box: centos-6.4
      box_url: http://developer.nrel.gov/downloads/vagrant-boxes/CentOS-6.4-x86_64-v20131103.box

suites:
  - name: timezone
    run_list:
      - recipe[timezone-ii::rhel]
    attributes:
      tz: "Asia/Tokyo"
    excludes:
      - ubuntu-12.04
```
- platforms の driver の box_url を指定してあげないと、`kitchen create`時にエラー発生。
- provisioner の require_chef_omnibus を指定してあげないと、`kitchen setup`時にエラー発生。
 
### テストケースを作成

test を置くディレクトリは、下記の場所
```
test/integration/SUITES_NAME/TESTING_FRAMEWORK/
```

今回テストフレームワークには Serverspec を用いることにします。
特に選定理由はありません、触ってみたかったからということでw。

そのため、パスは

```
test/integration/timezone/serverspec/
```
となり、この配下の、*_spec.rbが読み込まれます。

では、さっそく timezone が"Asia/Tokyo"に設定されているか確認するテストケースを作成します

```bash
$ mkdir -p test/integration/timezone/serverspec/
$ vi test/integration/timezone/serverspec/change-jp_timezone_spec.rb
```

```vim:change-jp_timezone_spec.rb
require 'serverspec'
# これないと verify 時に"No backend type is specified. Fall back to :exec type."がいっぱい出力される
set :backend, :exec

describe command('date') do
  its(:stdout) { should match /JST/ }
end

describe command('strings /etc/localtime') do
  its(:stdout) { should match /JST-9/ }
end

describe file('/etc/sysconfig/clock') do
  its(:content) { should match(/ZONE=\"Asia\/Tokyo\"/) }
end
```

### テストの実行

テストケースが作成できたので、Instance リストとライフサイクル上の状態を確認します

```bash
$ kitchen list
Instance            Driver   Provisioner  Last Action
timezone-centos-64  Vagrant  ChefZero     <Not Created>
```

テスト対象のゲスト OSを create します。

```bash
$ kitchen create timezone-centos-64
$ kitchen list
Instance            Driver   Provisioner  Last Action
timezone-centos-64  Vagrant  ChefZero     Created
```

create 後の初回なので、setup しておきます。

```bash
$ kitchen setup timezone-centos-64
$ kitchen list
Instance            Driver   Provisioner  Last Action
timezone-centos-64  Vagrant  ChefZero     Set Up
```

２回目以降で recipe をインスタンスに適用したい場合は converge します。

```bash
$ kitchen converge timezone-centos-64
$ kitchen list
Instance            Driver   Provisioner  Last Action
timezone-centos-64  Vagrant  ChefZero     Converged
```

準備ができたので、おまちかねのテストを実行してみます。

```bash
$ kitchen verify timezone-centos-64
・・・
       Finished in 0.04841 seconds (files took 0.28425 seconds to load)
       3 examples, 0 failures

       Finished verifying <timezone-centos-64> (4m23.56s).
-----> Kitchen is finished. (4m24.02s)
$ kitchen list
Instance            Driver   Provisioner  Last Action
timezone-centos-64  Vagrant  ChefZero     Verified
```

これで、recipe が正しく反映されていることが、チェックできました！

----

とりあえず、当面の目標が初心者のローカルテスト環境の構築のため、確認の手間を省けるメリットは大きそう。
これで、いろいろ確認済みの cookbook に影響が出てないかを簡単に確認できるので、冒険ができそうです！