1

レシピでテンプレート リソースを使用する場合

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
...

ソーステンプレート「バー」がクックブックにない場合でも、すべてのテストに合格します。

これにより、考えられるすべてのテストに合格するクックブックが作成されますが、実行しようとすると失敗します。cookbook_file リソースについても同じです。

リソースがソース ファイルを検索できるすべての場所をテストするのはワームの缶詰になることはわかりますが (リソース ドキュメントの「ファイル固有性」セクションに従って)、それでもテスト ツールに大きな穴があるように見えます。 .

ソースファイルの存在をテストする方法を見落としていますか、それともより基本的なレベルで何か間違っていますか? それとも、これが現状であり、誰もがそれと一緒に暮らしているのでしょうか?

4

1 に答える 1

1

OK、これは少し複雑ですが、うまくいきます。このレシピ フラグメントの場合:

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 は、.with_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(/.*/)ArgumentError をキャッチするようなハック的なことをしない限り、このトリックはバイナリ クックブック ファイルでは機能しません。

于 2015-02-17T02:11:24.440 に答える