是否可以在serverspec中包含常见测试?

时间:2014-09-03 11:19:41

标签: ruby rspec serverspec

我正在使用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

所以我的问题有两个:

  • 是否可以在外部文件中包含常用测试?
  • 如果是这样,我该如何做到这一点?

1 个答案:

答案 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