Ruby
Mac
RSpec
chef
inspec

InSpecでshared_contextを使いたい時


背景

InSpecを使っていて、下記のように同じような内容をチェックしようとしている時に、

# profile

describe file('/Users/hoge/.bash_profile') do
it { should exist }
its('type') { should eq :file }
its('mode') { should cmp '0755' }
its('owner') { should eq 'hoge' }
its('group') { should eq 'staff' }
its('size') { should > 0 }

its('content') { should match '# Bash completion' }
its('content') { should match 'if \[ -f `brew --prefix`/etc/bash_completion \]; then' }
its('content') { should match ' . `brew --prefix`/etc/bash_completion' }
its('content') { should match 'fi' }
its('content') { should match 'source ~/.bashrc' }
end

# alias
describe file('/Users/hoge/.bashrc') do
it { should exist }
its('type') { should eq :file }
its('mode') { should cmp '0755' }
its('owner') { should eq 'hoge' }
its('group') { should eq 'staff' }
its('size') { should > 0 }

its('content') { should match '^alias rm="trash"$' }
end

冗長的なので下記のようにRSpecのshared_contextを使ってみると

shared_context 'check_file' do

it { should exist }
its('type') { should eq :file }
its('mode') { should cmp '0755' }
its('owner') { should eq 'hoge' }
its('group') { should eq 'staff' }
its('size') { should > 0 }
end

describe file('/Users/hoge/.bash_profile') do
include_context 'check_file'
...
end

# alias
describe file('/Users/hoge/.bashrc') do
include_context 'check_file'
...
end

下記のようにエラーが出て、RSpecわけわかめ!となった

$ inspec exec cookbooks/provision_mac/test/integration/default/default_test.rb 

Traceback (most recent call last):
18: from /usr/local/bin/inspec:292:in `<main>'
17: from /usr/local/bin/inspec:292:in `load'
16: from /opt/chefdk/embedded/lib/ruby/gems/2.5.0/gems/inspec-2.2.70/bin/inspec:12:in `<top (required)>'
15: from /opt/chefdk/embedded/lib/ruby/gems/2.5.0/gems/thor-0.20.0/lib/thor/base.rb:466:in `start'
14: from /opt/chefdk/embedded/lib/ruby/gems/2.5.0/gems/thor-0.20.0/lib/thor.rb:387:in `dispatch'
13: from /opt/chefdk/embedded/lib/ruby/gems/2.5.0/gems/thor-0.20.0/lib/thor/invocation.rb:126:in `invoke_command'
12: from /opt/chefdk/embedded/lib/ruby/gems/2.5.0/gems/thor-0.20.0/lib/thor/command.rb:27:in `run'
11: from /opt/chefdk/embedded/lib/ruby/gems/2.5.0/gems/inspec-2.2.70/lib/inspec/cli.rb:173:in `exec'
10: from /opt/chefdk/embedded/lib/ruby/gems/2.5.0/gems/inspec-2.2.70/lib/inspec/runner.rb:102:in `run'
9: from /opt/chefdk/embedded/lib/ruby/gems/2.5.0/gems/inspec-2.2.70/lib/inspec/runner.rb:81:in `load'
8: from /opt/chefdk/embedded/lib/ruby/gems/2.5.0/gems/inspec-2.2.70/lib/inspec/runner.rb:81:in `each'
7: from /opt/chefdk/embedded/lib/ruby/gems/2.5.0/gems/inspec-2.2.70/lib/inspec/runner.rb:92:in `block in load'
6: from /opt/chefdk/embedded/lib/ruby/gems/2.5.0/gems/inspec-2.2.70/lib/inspec/profile.rb:168:in `collect_tests'
5: from /opt/chefdk/embedded/lib/ruby/gems/2.5.0/gems/inspec-2.2.70/lib/inspec/profile.rb:168:in `each'
4: from /opt/chefdk/embedded/lib/ruby/gems/2.5.0/gems/inspec-2.2.70/lib/inspec/profile.rb:171:in `block in collect_tests'
3: from /opt/chefdk/embedded/lib/ruby/gems/2.5.0/gems/inspec-2.2.70/lib/inspec/profile_context.rb:142:in `load_control_file'
2: from /opt/chefdk/embedded/lib/ruby/gems/2.5.0/gems/inspec-2.2.70/lib/inspec/profile_context.rb:158:in `load_with_context'
1: from /opt/chefdk/embedded/lib/ruby/gems/2.5.0/gems/inspec-2.2.70/lib/inspec/profile_context.rb:158:in `instance_eval'
cookbooks/provision_mac/test/integration/default/default_test.rb:43:in `load_with_context': undefined method `shared_context' for #<#<Class:0x00007f9aa6820d28>:0x00007f9aa681b148> (NoMethodError)


対象環境

$ sw_vers

ProductName: Mac OS X
ProductVersion: 10.13.6
BuildVersion: 17G65
$ inspec version
2.2.70


対象読者


  • インフラエンジニア

  • Chef, InSpec始めたばっかり

  • Rubyちょろっと書ける

  • RSpecもちょろっと書ける

  • けど、コーディングがっつりじゃない勢


対処法

- shared_context 'check_file' do

+ RSpec.shared_context 'check_file' do
it { should exist }
its('type') { should eq :file }
its('mode') { should cmp '0755' }
its('owner') { should eq 'hoge' }
its('group') { should eq 'staff' }
its('size') { should > 0 }
end

と、RSpec.を頭に入れたらいいだけだった

公式ドキュメントをしっかり見ると、RSpec.を入れてました

ruby-rspecの時は入れてないので、どこかでうまいことやられてたのかな。。。

ruby, rspecもしっかり勉強しないといけないなぁと痛感しました


参考