Можно ли включить общие тесты в serverpec?

Я использую serverpec для проведения удаленного тестирования серверов.

У меня есть несколько различных тестов, которые отлично работают:

`-- 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 ответ

Решение

Я не уверен, что в вашем примере есть опечатка, так как он, кажется, делает именно то, что вы хотите. Ты бежишь bundle exec rake spec:ssh.example.org.uk и он работает против ssh.example.org.uk,

Документация по serverpec предлагает другой способ запуска общих спецификаций. Вместо того, чтобы организовывать свои файлы по хосту, вы должны организовать их по роли. Например:

`-- 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)}]

Затем вы можете предоставить ServerSpecTask который запускает команды, устанавливая адрес хоста как переменную среды, переопределяя RSpec spec_command метод:

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
Другие вопросы по тегам