Search code examples
chef-infrachefspec

How can I use ChefSpec during refactoring of environments/roles/nodes


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?


Solution

  • 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!