I'm integrating rspec-puppet tests in our puppet project and I'm trying to auto generate "should compile" specs for all hosts (and eventually probably other resource). This is to ensure everything at least compiles successfully.
Given a list of nodes I can do this with:
hosts.each do |host|
describe host, type: :host do
it { should compile }
end
end
The issue is how to actually get the hosts list. I can use regex to parse the node files but that obviously leads to insanity... Since the puppet gem is already present and used for loading the catalogues by the rspec-puppet gem, can I use it to get a list of the hosts?
EDIT:
I eventually managed to do this using the puppet pops system but I'm not sure if this the best way to do this or if there's some higher level abstraction that would be easier to use:
require 'spec_helper'
require 'puppet/pops'
code_dirs = [RSpec.configuration.module_path, RSpec.configuration.manifest_dir]
definitions =
Dir["{#{code_dirs.join(',')}}/**/*.pp"].
map {|file| Puppet::Pops::Parser::Parser.new.parse_file file}.
flat_map {|parsed_manifest| parsed_manifest.definitions}
hosts = definitions.
select {|definition| definition.is_a? Puppet::Pops::Model::NodeDefinition}.
flat_map {|node_definition| node_definition.host_matches}.
select {|host_match| host_match.is_a? Puppet::Pops::Model::LiteralString}.
map {|string_host_match| string_host_match.value}
classes = definitions.
select {|definition| definition.is_a? Puppet::Pops::Model::HostClassDefinition}.
map {|host_class_definition| host_class_definition.name}
hosts.each do |host|
describe host, type: :host do
it {should compile}
end
end
classes.each do |klass|
describe klass, type: :class do
it {should compile}
end
end