Rspec Chef cookbook_文件和模板资源:如何测试该源是否存在?

Rspec Chef cookbook_文件和模板资源:如何测试该源是否存在?,rspec,chef-infra,chefspec,Rspec,Chef Infra,Chefspec,如果我在配方中使用模板资源 template '/home/user1/foo' do source 'bar' end 我使用chefspec/rspec进行测试 ... expect(chef_run).to render_file('/home/user1/foo') expect(chef_run).to create_template('/home/user1/foo') expect(chef_run).to create_template('/home/user1/foo')

如果我在配方中使用模板资源

template '/home/user1/foo' do
  source 'bar'
end
我使用chefspec/rspec进行测试

...
expect(chef_run).to render_file('/home/user1/foo')
expect(chef_run).to create_template('/home/user1/foo')
expect(chef_run).to create_template('/home/user1/foo').with_source 'bar
...
所有测试都通过…
即使烹饪手册中缺少源模板“bar”。

这给我留下了一本食谱,它通过了我能想到的所有测试,但当我尝试运行它时,它将失败。cookbook_文件资源也是如此

我可以看出,在资源可以查找源文件的所有位置(根据)进行测试将是一堆蠕虫,但它似乎仍然是测试工具中的一个大漏洞


我是否忽略了一种测试源文件存在性的方法,或者在更基本的层面上做错了什么?或者就是这样,每个人都和它一起生活吗?

好吧,这有点复杂,但它是有效的。 对于此配方片段:

template '/home/user1/foo' do
  source 'bar'
end
当不存在模板源文件“bar”时,尽管缺少源文件,但此Chefspec预期将通过

expect(chef_run).to render_file('/home/user1/foo')
但这会失败,因为
Chef::Exceptions::FileNotFound
,提供了一种测试源是否存在的方法:

expect(chef_run).to render_file('/home/user1/foo').with_content(/.*/)
显然,with_content()方法强制解析源引用,以便匹配器可以渲染文件以进行比较。如果您并不真正关心匹配特定内容,
/.*/
匹配任何内容,这样您仍然可以测试源是否存在

更多,回应@user3670408的问题

Chefspec必须将文件内容呈现为一个字符串,以与
进行比较。使用_content()
参数,问题似乎在于您使用的实际烹饪书文件是一个二进制文件。发生的事情可能是这样的:

# Create a bad UTF-8 file
File.open('bad_utf8.bin', mode: 'wb') { |file| file.putc(0xfe) }
# Read contents and try to use the resulting string
File.read('bad_utf8.bin').match(/.*/)
# Result is:  ArgumentError: invalid byte sequence in UTF-8

因此,一般来说,除非你做一些像捕获参数错误这样的黑客操作,否则
.with_content(/.*/)
技巧对二进制食谱文件不起作用。

你正在创建
食谱文件
,但希望厨师创建
模板
s?我不知道这是怎么组合起来的。通过交叉传播模板和cookbook_文件(因为同样的问题也适用)来混淆问题将得到澄清。感谢您指出这一点,因为通常情况下,当一个解决方案出现时,问题似乎有点微不足道。当然,使用_content()进行测试必须使用指定的模板(或cookbook文件等)呈现输出。我想令人困惑的是,使用_render()而不使用-content()实际上并没有测试成功的呈现。