Edited at

Serverspecにカスタムリソースタイプを追加して使う


はじめに

serverspecを使っていて、mysql_configがあるならhoge_configがあってもいいじゃない、と思ったのでカスタムリソースタイプを書きました。

具体的には、PowerDNSの設定をテストしたくて、mysql_configに習ってpdns_configを追加しました。それと、MySQLユーザの存在確認と接続を許可するホストもテストしたかったので、mysql_userを追加しました。


カスタムリソースタイプ

ファイル構成はこう。

spec/

├── dns/
│   ├── mysql_spec.rb
│   ├── pdns_spec.rb
│   └── type/
│   ├── mysql_user.rb
│   ├── pdns_config.rb
│   └── pdns_config.rb
└── spec_helper.rb

spec/dns/type以下に、追加したいカスタムリソースタイプの実装を入れる。


pdns_config


pdns_config.rb

module Serverspec::Type

class PdnsConfig < Base
def value
# `pdns_control current-config` show the currently running configuration.
ret = @runner.run_command("pdns_control current-config | grep '^#{@name}'")
val = ret.stdout.match(/^#{@name}=.+$/)[0].split('=')[1]
val = val.to_i if val.match(/^\d+$/)
val
end
end

def pdns_config(name)
PdnsConfig.new(name)
end
end


こう書いて、


pdns_spec.rb

{ :setuid => 'pdns',

:setgid => 'pdns',
:'local-address' => '127.0.0.1',
:'local-port' => 53 }.each do |key, val|
describe pdns_config(key) do
its(:value) { should eq val }
end
end

こう使う。


mysql_user


mysql_user.rb

module Serverspec::Type

class MysqlUser < Base
def exists?
ret = @runner.run_command("mysql -u root -p#{ENV['MYSQL_ROOT_PASSWORD']} -e 'select user from mysql.user;'")
ret.stdout.match(/^#{@name}\s/) != nil ? true : false
end

def host
ret = @runner.run_command("mysql -u root -p#{ENV['MYSQL_ROOT_PASSWORD']} -e 'select user, host from mysql.user;'")
ret.stdout.match(/#{@name}.+$/).to_s.split()[1]
end
end

def mysql_user(name)
MysqlUser.new(name)
end
end


こう書いて、


mysql_spec.rb

describe mysql_user('root') do

it { should exist }
its(:host) { should eq 'localhost' }
end

こう使う。


おわりに

pdns_configは公式に実装されているmysql_configやphp_configに寄せて書きました。

今回やったことを実現するためにマッチャーを書くやり方もあるみたいで、どちらが一般的なのか困るところです。普通こうするよ、みたいなのあったら教えてください。