Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

render_file will select delete_file resources out of the resource collection and ignore template_create resources that would otherwise match #858

Open
aogail opened this issue Jul 3, 2017 · 7 comments · May be fixed by #1029
Labels

Comments

@aogail
Copy link

aogail commented Jul 3, 2017

In one of my cookbooks, I'm using a node attribute to control whether a config file is laid down or deleted during the chef run. The node attribute's default value is nil, in which case the config file is deleted. If the node attribute is set to another value, the config file is created based on a template from the cookbook.

I discovered that in this scenario, the render_file matcher does not correctly match the latter case. create_template does correctly match, though. I distilled a minimal cookbook to exhibit the issue and posted it on Github: https://github.com/aogail/chefspec-template-or-delete

Recipe:

template '/etc/config.conf' do
  variables(
      :setting => node['chefspec-render-file']['setting']
  )
  source 'config.conf.erb'
  not_if {node['chefspec-render-file']['setting'].nil?}
end

file '/etc/config.conf' do
  action :delete
  only_if {node['chefspec-render-file']['setting'].nil?}
end

Chefspec tests:

require 'chefspec'

describe 'chefspec-render-file::default' do
  let(:config_path) {'/etc/config.conf'}

  context 'with default node attributes' do
    let(:chef_run) do
      ChefSpec::SoloRunner.new(platform: 'oracle', version: '7.2').converge(described_recipe)
    end

    it 'deletes the config file' do
      expect(chef_run).to delete_file(config_path)
    end

    it 'does not create the config file, verified by create_template' do
      expect(chef_run).to_not create_template(config_path)
    end

    it 'does not create the config file, verified by render_file' do
      expect(chef_run).to_not render_file(config_path)
    end
  end

  context 'with the optional attribute set' do
    let(:setting) {'some_value'}

    let(:chef_run) do
      ChefSpec::SoloRunner.new(platform: 'oracle', version: '7.2') do |node|
        node.override['chefspec-render-file']['setting'] = setting
      end.converge(described_recipe)
    end

    it 'does not delete the config file' do
      expect(chef_run).to_not delete_file(config_path)
    end

    it 'creates the config file, verified by create_template' do
      expect(chef_run).to create_template(config_path)
    end

    it 'creates the config file, verified by render_file' do
      expect(chef_run).to render_file(config_path)
    end

    it 'creates the config file, verified by render_file with content' do
      expect(chef_run).to render_file(config_path).with_content(/#{setting}/)
    end
  end
end

Chefspec failure output:

  1) chefspec-render-file::default with the optional attribute set creates the config file, verified by render_file
     Failure/Error: expect(chef_run).to render_file(config_path)
       expected Chef run to render "/etc/config.conf"
     # ./spec/unit/recipes/default_spec.rb:42:in `block (3 levels) in <top (required)>'

  2) chefspec-render-file::default with the optional attribute set creates the config file, verified by render_file with content
     Failure/Error: expect(chef_run).to render_file(config_path).with_content(/#{setting}/)
     
       expected Chef run to render "/etc/config.conf" matching:
     
       (?-mix:some_value)
     
       but got:
     
     
        
     # ./spec/unit/recipes/default_spec.rb:46:in `block (3 levels) in <top (required)>'
@aogail aogail changed the title render_file not matching template resource when a node attribute controls whether to create or delete the template render_file not matching template resource when a node attribute controls whether to create or delete the file Jul 3, 2017
@coderanger
Copy link
Contributor

Please include your recipe and spec code as well.

@aogail
Copy link
Author

aogail commented Jul 3, 2017

@coderanger It's at https://github.com/aogail/chefspec-template-or-delete. Do you mean I should include it somewhere else?

@coderanger
Copy link
Contributor

@aogail In general it's best to include it in the issue itself since external repos 1) have a ton of extra files in them and 2) can change under the hood.

@coderanger
Copy link
Contributor

coderanger commented Jul 3, 2017

Does it work if you use a single resource instead?

template '/etc/config.conf' do
  variables(
      :setting => node['chefspec-render-file']['setting']
  )
  source 'config.conf.erb'
  action node['chefspec-render-file']['setting'] ? :create : :delete
end

Guessing something might be getting overwritten in the internal tracking?

@aogail
Copy link
Author

aogail commented Jul 3, 2017

Good idea, I'll give that a try.

@lamont-granquist
Copy link
Contributor

the render_file matcher finds the file[<filename>] resource first and then stops and does not find the template[<filename>] resource:

@resource ||= @runner.find_resource(:cookbook_file, @path) ||
@runner.find_resource(:file, @path) ||
@runner.find_resource(:template, @path)

@lamont-granquist lamont-granquist changed the title render_file not matching template resource when a node attribute controls whether to create or delete the file render_file will select delete_file resources out of the resource collection and ignore template_create resources that would otherwise match May 8, 2018
@lamont-granquist
Copy link
Contributor

as far as i can see the node attribute control has nothing to do with this bug...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants