我正在使用serverspec对服务器进行远程测试。
我做了很多不同的测试,一切正常:
`-- spec
|-- builder.example.org.uk
\ host_spec.rb
|-- chat.example.org.uk
\ host_spec.rb
|-- docker.example.org.uk
\ host_spec.rb
\-- git.example.org.uk
\ host_spec.rb
但是,每个主机测试都有很多重复,因为我想确保每个主机都运行sshd
,例如。
我尝试了几种创建spec/common_tests.rb
的方法,但每次都失败了。例如,添加spec/common.rb
:
describe command("lsb_release -d") do
its(:stdout) { should match /wheezy/ }
end
然后在spec/chat.example.org.uk/host_spec.rb
:
require 'common'
然而,这似乎突然想要连接到不同的主机,并且失败了:
shelob ~ $ bundle exec rake spec:ssh.example.org.uk
/usr/bin/ruby1.9.1 -S rspec spec/ssh.example.org.uk/host_spec.rb
F.....................
Failures:
1) Command "lsb_release -d" stdout
On host `ssh.example.org.uk`
Failure/Error: Unable to find matching line from backtrace
SocketError: getaddrinfo: Name or service not known
所以我的问题有两个:
答案 0 :(得分:2)
我不确定您的示例是否有拼写错误,因为它似乎完全符合您的要求。您正在运行bundle exec rake spec:ssh.example.org.uk
并且它正在ssh.example.org.uk
上运行。
serverspec documentation提出了另一种运行共享规范的方法。您应该通过 role 组织它们,而不是通过主机组织文件。例如:
`-- spec
|-- app
| `-- ruby_spec.rb
|-- base
| `-- users_and_groups_spec.rb
|-- db
| `-- mysql_spec.rb
|-- proxy
| `-- nginx_spec.rb
`-- spec_helper.rb
然后,在Rakefile
中,您将主机映射到角色:
hosts = [{name: 'www.example.org.uk', roles: %w(base app)},
{name: 'db.example.org.uk', roles: %w(base db)}]
然后,您可以通过覆盖RSpec's spec_command
method来提供运行命令的ServerSpecTask
,方法是将主机地址设置为环境变量:
class ServerspecTask < RSpec::Core::RakeTask
attr_accessor :target
def spec_command
cmd = super
"env TARGET_HOST=#{target} #{cmd}"
end
end
namespace :serverspec do
hosts.each do |host|
desc "Run serverspec to #{host[:name]}"
ServerspecTask.new(host[:name].to_sym) do |t|
t.target = host[:name]
t.pattern = 'spec/{' + host[:roles].join(',') + '}/*_spec.rb'
end
end
end
最后,更新您的spec_helper.rb
以阅读该环境变量并将其用作主机:
RSpec.configure do |c|
c.host = ENV['TARGET_HOST']
options = Net::SSH::Config.for(c.host)
user = options[:user] || Etc.getlogin
c.ssh = Net::SSH.start(c.host, user, options)
c.os = backend.check_os
end