Как проверить идемпотентность с помощью chefspec

Я хотел бы использовать chefspec для проверки идемпотентности моего рецепта.

Допустим, у меня есть рецепт, который включает эти два оператора ресурсов:

file '/etc/app.config' do
  action :create
  notifies :restart, "service[app]"
end

service 'app' do
  action :enable
end

Как я могу написать пример chefspec, который доказывает, что если файл /etc/app.config уже существует, то служба app не будет уведомлена о перезапуске?

Есть ли какое-то издевательство, которое я могу сделать, чтобы ресурс «файл» думал, что файл уже существует? Могу ли я запустить ChefSpec::ServerRunner дважды, сохранив состояние первого запуска (полагаю, что нет, так как файл на самом деле не будет создан)? Или мне придется использовать test-kitchen и Vagrant, чтобы добиться реальных результатов?

(Примечание: в моей реальной поваренной книге есть собственный LWRP, который создает файл конфигурации. Он получает информацию от сервера шеф-повара, поэтому я использую ServerRunner)


person Kief    schedule 01.05.2015    source источник
comment
Учитывая, что ChefSpec никогда не пытается объединить ваши ресурсы, я совершенно уверен, что вы не сможете проверить идемпотентность с помощью ChefSpec. В основном это делается для того, чтобы убедиться, что вы объявляете правильные ресурсы с правильными действиями и атрибутами, но на самом деле не проверяет, правильно ли эти ресурсы работают. Но я надеюсь, что кто-то сможет доказать, что я ошибаюсь в этом.   -  person Tejay Cardon    schedule 01.05.2015
comment
@TejayCardon, вы правы, мы не сможем протестировать идемпотентность на уровне полной конвергенции (с помощью chefspec). Я, по крайней мере, надеялся, что смогу протестировать разные начальные условия для одного ресурса. К сожалению, это не выглядит осуществимым с полки. Думаю, надо протестировать на тест-кухне.   -  person Kief    schedule 05.05.2015


Ответы (3)


test-kitchen, начиная с версии 1.18.0, есть работающая поддержка проверки идемпотентности для chef_* провайдеров (она была введена ранее, но не работает и исправлена ​​только в последней версии). Это не задокументировано, но вы можете найти некоторые подробности здесь .

По сути, вы можете добавить эти две строки в определение provisioner:

  provisioner:
    name: chef_zero
    ...
    enforce_idempotency: true # force idempotence check
    multiple_converge: 2 # how many times to run your provisioners
    ...

Это запустит вашу поваренную книгу несколько раз и проверит, что последний запуск содержит 0 обновленные ресурсы. Это также дает вам хороший список ресурсов, которые были обновлены при втором запуске.

person Artem Yarmoluk    schedule 29.09.2017

Предупреждение Это не проверено.

Я предполагаю, что вы можете смоделировать ::File.exist?, чтобы вернуть true в своей спецификации для этого файла.

allow_any_instance_of(File).to receive('exists?').with('/etc/app.config').and_return(true)

Согласно поставщику файлов, это метод, вызываемый в провайдере для получения текущего состояния.

Это будет работать чисто для файлового ресурса, подобного тому, который вы описали в своем вопросе.

Однако, если действие равно :create, а ресурс определен с атрибутом checksum или атрибутом content, вам придется издеваться над содержимым файла или контрольной суммой, подобной этой

allow_any_instance_of(Chef::Digester).to receive('generate_checksum').with('/etc/app.config').and_return('The checksum of the file, do a sha256sum on your file to get this')

После этого вам нужно будет следовать документации ChefSpec по уведомлениям здесь

resource = chef_run.file('/etc/app.config')
expect(resource).to_not notify('service[app]').to(:restart)

Насколько я знаю, Test-Kitchen стремился протестировать одноразовый запуск, чтобы убедиться, что поваренные книги верны, несколько запусков шеф-повара в одном и том же тесте не обрабатываются, и в конечном итоге вам нужно решить, что вы хотите использовать для многократного запуска. тестовое задание.

Об этом говорится в списке рассылки шеф-повара о тестировании инфраструктуры, см. вики по тегу для ссылок на ML (разговор не является окончательным ответом и не подходит для SO).

person Tensibai    schedule 04.05.2015
comment
Poke @Tejaycardon. Вы правы, конвергенции нет, это вопрос имитации состояния для проверки поведения, но со временем это, вероятно, будет подвержено ошибкам. - person Tensibai; 04.05.2015
comment
издеваетесь над File.exist? проверка не работает. Поставщик файлов на самом деле не вызывает это при запуске с Chefspec, что имеет смысл, учитывая, что без конвергенции файл не будет создан, поэтому произойдет сбой. - person Kief; 05.05.2015
comment
@Kief Идея состоит в том, чтобы предоставить поддельное состояние, в котором файл присутствует и содержит правильное содержимое (поэтому запуск не должен обновлять ресурс). Вы правы, поставщик полностью запутан, вам придется писать вокруг этот сопоставитель - person Tensibai; 05.05.2015

Похоже, что различные начальные условия могут быть проверены на практике только путем фактического схождения. Если да, то правильный ответ на мой вопрос — использовать что-то вроде test-kitchen и Vagrant, а не ChefSpec.

person Kief    schedule 05.05.2015