Question

I have a Chef repo that needs some cleanup. Configuration data is scattered around into files in nodes, environments and roles folders.

My idea is to use ChefSpec to test against regressions during restructuring the data. As only roles appear to be supported directly by ChefSpec, how could I use existing nodes/environments in my ChefSpec tests?

Was it helpful?

Solution 2

Answering myself, just in case someone else might find it useful:

I ended up with an example like this:

it 'renders config file with proper data on node ABC in environment XYZ' do
  runner = ChefSpec::Runner.new

  node_attr = JSON.parse(File.open('nodes/ABC.json'))
  runner.node.consume_attributes(node_attr)

  env_attr = JSON.parse(File.open('environments/XYZ.json'))
  env = Chef::Environment.json_create(env_attr)

  runner.node.stub(:chef_environment).and_return('XYZ')
  Chef::Environment.stub(:load).and_return(env)

  runner.converge('cookbook::recipe')

  expect(runner).to render_file('/etc/cookbook.cfg').with_content('some data from ABC.json')
end

This works with the "monolithic chef repo" pattern, which I am using in this early phase of our chef adoption - in fact we are using chef-solo, but on a folder structure that tries to be compatible to a chef repo.

Moreover, I do not want to test for regressions during all the necessary restructuring without the speed of ChefSpec!

OTHER TIPS

Most of the Chef tooling is designed to work with a single cookbook. You can use ChefSpec in the "monolithic Chef repo" pattern. ChefSpec does have support for mocking Environments and roles.

When you write ChefSpec tests (usually called "examples"), they are against a single cookbook, not a role or environment. If you wrote ChefSpec examples for all your cookbooks, then you could safely do this refactor, running the tests on each run. But there's no way to write tests against your entire Chef repository.

Sources:

  • I maintain it and wrote the current version
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top