時と場合によりけり

日々のアップデートとイノベーションに翻弄され彷徨える IT エンジニアの覚書

Severspec のテストをロールごとに実行できるようにしてみる

概要

serverspec-init で生成される Rakefile に手を加えて、テスト実行を細かく制御してみたいと思います。今回のテスト対象は、Vagrant仮想マシンCentOS 6.8 )です。Serverspec のインストールについては、以下のエントリーをご参照ください。

stangler.hatenablog.com

参考 URL

serverspec のテストをホスト間で共有する方法 - Gosuke Miyashita

ハードウェア

  • マシン: Macbook Pro Early 2011
  • メモリ: 16 GB
  • ストレージ: SSD 512 GB

ホスト

ゲスト

Vagrant VM

web と db 2台の仮想マシンを立ち上げます。それぞれにプライベート ip を付与します。

% vim Vagrantfile
Vagrant.configure(2) do |config|

  config.vm.box = "centos68"
  config.ssh.insert_key = false
  config.vm.provider "virtualbox" do |vb|
    vb.memory = "2048"
  end

  config.vm.define "web" do |node|
    node.vm.hostname = "web.com"
    node.vm.network :private_network, ip: "192.168.33.10"
  end

  config.vm.define "db" do |node|
    node.vm.hostname = "db.com"
    node.vm.network :private_network, ip: "192.168.33.11"
  end

end

ロール作成

任意でロールとなるディレクトリを作成します。ここでは例として、5つのロールを作成します。

  • base: どのサーバーでも必要となる基本設定
  • app: アプリケーション
  • proxy: プロキシ
  • dbserver: DBサーバー・モジュール
  • dbclient: DBクライアント・モジュール
% mkdir spec
% cd spec
% mkdir base app proxy dbserver dbclient

spec ディレクトリの構造

spec ディレクトリの全体像は以下となります。わかりやすように、例として、いくつかの spec ファイルを後で作成します。

% tree
.
├── app
│   └── sample_anyenv_spec.rb
├── base
│   └── sample_wget_spec.rb
├── dbclient
│   └── sample_mysql-client_spec.rb
├── dbserver
│   └── sample_mysql-server_spec.rb
├── proxy
│   └── sample_nginx_spec.rb
└── spec_helper.rb

5 directories, 6 files

spec_helper.rb 作成

spec_helper.rb は、serverspec-init で作成されるもの( Vagrant 用)を流用しつつ、不要な部分は削ぎ落としました。

% vim spec_helper.rb
require 'serverspec'
require 'net/ssh'
require 'tempfile'

set :backend, :ssh

host = ENV['TARGET_HOST']

`vagrant up #{host}`

config = Tempfile.new('', Dir.tmpdir)
config.write(`vagrant ssh-config #{host}`)
config.close

options = Net::SSH::Config.for(host, [config.path])

options[:user] ||= Etc.getlogin

set :host,        options[:host_name] || host
set :ssh_options, options

Rakefile 作成

今回の肝となる Rakefileです。

% cd ..
% vim Rakefile

4〜13 行目でホストを設定しています。見たらわかると思いますが、サーバーを追加するには、json 形式で 13 行目以降に記述するだけです。また、7行目と 11 行目でロールを設定しています。ロールを追加するときは、ここに入れるだけです。spec ディレクトリに追加するロールのディレクトリを作成するのも忘れずに。

.rspec 作成

テスト実行時に見やすくするために色をつけたりしましょう。

% vim .rspec
--color
--format documentation

サンプル spec

動作確認用に、それぞれのロールごとの簡単なテスト(例)をあげておきます。それぞれのパッケージがインストールされていなければ、当然ですが、テストは失敗します。

base

% vim spec/base/sample_wget_spec.rb
require 'spec_helper'

describe package('wget') do
  it { should be_installed }
end

app

% vim spec/app/sample_anyenv_spec.rb
require 'spec_helper'

describe command('which anyenv') do
  let(:disable_sudo) { true }
  its(:exit_status) { should eq 0 }
end

proxy

% vim spec/proxy/sample_nginx_spec.rb
require 'spec_helper'

describe package('nginx') do
  it { should be_installed }
end

dbserver

% vim spec/dbserver/sample_mysql-server_spec.rb
require 'spec_helper'

describe package('mysql-community-server') do
  it { should be_installed }
end

dbclient

% vim spec/dbclient/sample_mysql-client_spec.rb
require 'spec_helper'

describe package('mysql-community-client') do
  it { should be_installed }
end

テスト実行(例)

以下の例で、時と場合に応じて実行する、テストのイメージを掴かめると思います。

テスト実行(全サーバーの全ロール)

% rbenv exec bundle exec rake spec -t

テスト実行(webサーバーの全ロール)

% rbenv exec bundle exec rake spec:web -t

テスト実行(dbサーバーの全ロール)

% rbenv exec bundle exec rake spec:db -t

テスト実行(各サーバーの個別スペック: base/sample_wget の場合)

% rbenv exec bundle exec rake spec:web SPEC=spec/base/sample_wget_spec.rb -t
% rbenv exec bundle exec rake spec:db SPEC=spec/base/sample_wget_spec.rb -t

テスト実行(webサーバーの個別スペック: app/sample_anyenv の場合)

% rbenv exec bundle exec rake spec:web SPEC=spec/app/sample_anyenv_spec.rb -t

テスト実行(webサーバーの個別スペック: proxy/sample_nginx の場合)

% rbenv exec bundle exec rake spec:web SPEC=spec/proxy/sample_nginx_spec.rb -t

テスト実行(dbサーバーの個別スペック: dbserver/sample_mysql-server の場合)

% rbenv exec bundle exec rake spec:db SPEC=spec/dbserver/sample_mysql-server_spec.rb -t

テスト実行(webサーバーの個別スペック: dbclient/sample_mysql-client の場合)

% rbenv exec bundle exec rake spec:web SPEC=spec/dbclient/sample_mysql-client_spec.rb -t

以上です。