1

我想使用 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 来为 realz 做事吗?

(注意:我的实际食谱有一个构建配置文件的自定义 LWRP。它从厨师服务器获取信息,这就是我使用 ServerRunner 的原因)

4

3 回答 3

1

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更新资源。它还为您提供了一个很好的资源列表,这些资源在第二次运行时已更新。

于 2017-09-29T08:39:09.310 回答
0

警告这是未经测试的。

我假设你可以模拟::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 旨在测试一次性运行以确保食谱正确,不会处理同一测试中的多次主厨运行,您最终必须决定要用于多次运行的内容测试。

在主厨邮件列表上有一个关于基础设施测试的讨论,请参阅标签 wiki 以获取 ML 的链接(该讨论不是最终答案,也不适合 SO)。

于 2015-05-04T08:20:39.660 回答
0

看起来不同的起始条件只能通过实际收敛来实际测试。如果是这样,我的问题的正确答案是使用像 test-kitchen 和 Vagrant 这样的东西,而不是 ChefSpec。

于 2015-05-05T10:27:06.217 回答