通常Serverspecは$ rake spec
で実行する
一方、rspec
コマンドで実行するとエラーになる
次の方法でrspec
コマンドで実行できるようにできる
(もし、すでに一般的な対応方法があったら教えてほしい)
通常はrspecコマンドでエラーになる
$ rake spec
で実行した後の出力のFailed examples:
にrspecコマンドが表示される
その通りにrspecコマンドで実行すると以下のようなエラーになる
$ rspec ./spec/www.example.com/some_spec.rb:33
1) Port "80" should be listening
Failure/Error: it { should be_listening }
TypeError:
no implicit conversion of nil into String
または
/Users/user/.rbenv/versions/2.1.4/lib/ruby/gems/2.1.0/gems/net-ssh-2.9.2/lib/net/ssh/transport/session.rb:70:in `initialize': no implicit conversion of nil into String (TypeError)
rspecコマンドで実行できるようにする設定
シングルホストの場合
後述する複数ホストの場合のように、RSpec.configure
でhostを設定しようと最初試したが、そもそもシングルホストの場合はフォルダからhostを取得する必要がない
なので、dotenv
を使う方法が良い
gem 'dotenv'
require 'dotenv'
Dotenv.load
TARGET_HOST=www.example.com
実行結果
$ rspec
...
Failed examples:
rspec ./spec/www.example.com/sample_spec.rb:5 # Service "httpd" should be enabled
複数ホストの場合
想定している構成はspec
以下にホスト名でディレクトリを切って複数管理しているケース(例. spec/www.example.com/some_spec.rb
)
RSpec.configure do |c|
c.add_setting :host_taken_from_path
c.before do |example|
if c.host.nil?
c.host = example.metadata[:file_path].gsub('./spec/', '').split('/').first
c.ssh_options = Net::SSH::Config.for(c.host)
c.host_taken_from_path = true
end
end
c.after do
if c.host_taken_from_path
c.host = c.ssh_options = nil
c.host_taken_from_path = false
end
end
end
rspec実行
$ rspec ./spec/www.example.com/some_spec.rb:33
Port "80"
should be listening
Finished in 4.77 seconds (files took 1.46 seconds to load)
1 example, 0 failures
制約
RSpec.configure
でhostを設定する場合、次のようなos
の条件などが使えない(hostが空の時点でsshが走ってエラーになる)
describe service('httpd'), :if => os[:family] == 'redhat' do
留意点
RSpec.configure
でhostを設定する場合、留意点としては失敗時にOn host 'www.example.com'
のログが出力されない
ソース serverspec.rb
host_taken_from_path
とafter
のブロックを書かなければ出力されるようになるが、ssh_options
をクリアしないことによって、以下のようにssh_options内の:send_env
がおかしなことになる
{:auth_methods=>["none", "publickey", "password", "keyboard-interactive"], :host_name=>"XXX.XXX.XXX.XXX", :user=>"hoge", :keys=>["/Users/hoge/.ssh/id_rsa"], :send_env=>[/^LANG$/, /^LC_.*$/, "LANG", "LANG", "LANG", "LANG", "LANG", "LANG", "LANG", "LANG", "LANG", "LANG", "LANG", "LANG", "LANG", "LANG", "LANG", "LANG", "LANG", "LANG"]}
環境
- rbenv + Ruby 2.1.4
- serverspec (2.14.1), specinfra (2.30.0)
- セットアップは
UN*X
,SSH
- ホストの設定
~/.ssh/config
set :request_pty, true
- 適当なsudoの設定
その他
そもそものFailed examplesの部分の出力を変更することもできるかも
Failed examples:
rspec ./spec/www.example.com/some_spec.rb:33 # Port "80" should be listening
↓
rake spec SPEC=spec/www.example.com/some_spec.rb:33