Sometimes, when you are writing an rspec-puppet test, you’re not sure exactly how the test should be written. You know that you want to test a resource with some extra attribute, but you may be describing the resource wrong, or using a bad regex to test the contents. Rspec-puppet will helpfully tell you when the code and the test do not match, but it does not always tell you where the mismatch is. In those cases, you want to see the whole catalog to see more detail on the resource attributes.
Let’s look at a very simple profile and its corresponding tests and test output:
[rnelson0@build03 profile:production]$ cat manifests/apache.pp class profile::apache { include ::apache firewall { '100 HTTP/S inbound': dport => [80, 443], proto => tcp, action => accept, } } [rnelson0@build03 profile:production]$ cat spec/classes/apache_spec.rb require 'spec_helper' describe 'profile::apache', :type => :class do let :facts do { :id => 'root', :kernel => 'Linux', :osfamily => 'RedHat', :operatingsystem => 'RedHat', :operatingsystemrelease => '6', :concat_basedir => '/dne', :path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', } end context 'with defaults for all parameters' do it { is_expected.to create_class('profile::apache') } it { is_expected.to contain_package('httpd') } it { is_expected.to contain_user("apache") } end end [rnelson0@build03 profile:production]$ be rspec spec/classes/apache_spec.rb profile::apache with defaults for all parameters should contain Class[profile::apache] should contain Package[httpd] should contain User[apache] Finished in 4.74 seconds (files took 2.62 seconds to load) 3 examples, 0 failures Coverage report generated for RSpec to /home/rnelson0/puppet/controlrepo/dist/profile/coverage. 0.0 / 0.0 LOC (100.0%) covered. COVERAGE: 100.00% -- 0.0/0.0 lines in 0 files
These tests work, but we can still examine the catalog to see the details of it. To do so, we add a single line to the context block of the test:
it { pp catalogue.resources }
This will use ruby’s pretty print method to display the contents of the catalog as semi-human-readable output. Here’s what the updated test looks like, as well as a snippet of the 199 lines of output (the apache module includes a LOT of resources by default):
[rnelson0@build03 profile:production±]$ cat spec/classes/apache_spec.rb require 'spec_helper' describe 'profile::apache', :type => :class do let :facts do { :id => 'root', :kernel => 'Linux', :osfamily => 'RedHat', :operatingsystem => 'RedHat', :operatingsystemrelease => '6', :concat_basedir => '/dne', :path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', } end context 'with defaults for all parameters' do it { is_expected.to create_class('profile::apache') } it { is_expected.to contain_package('httpd') } it { is_expected.to contain_user("apache") } it { pp catalogue.resources } end end [rnelson0@build03 profile:production±]$ be rspec spec/classes/apache_spec.rb /home/rnelson0/puppet/controlrepo/dist/profile/spec/spec_helper.rb:12:in `block in <top (required)>': [DEPRECATION] ::[] is deprecated. Use ::new instead. profile::apache with defaults for all parameters should contain Class[profile::apache] should contain Package[httpd] should contain User[apache] [Stage[main]{:name=>"main"}, Class[Settings]{:name=>"Settings"}, Class[main]{:name=>"main"}, Class[Profile::Apache]{:name=>"Profile::Apache"}, Class[Apache::Version]{:name=>"Apache::Version"}, Class[Apache::Params]{:name=>"Apache::Params"}, Class[Apache]{:name=>"Apache", :apache_name=>"httpd", :service_name=>"httpd", :default_mods=>true, :default_vhost=>true, :default_confd_files=>true, :default_ssl_vhost=>false, :default_ssl_cert=>"/etc/pki/tls/certs/localhost.crt", :default_ssl_key=>"/etc/pki/tls/private/localhost.key", :default_type=>"none", :dev_packages=>"httpd-devel", :service_enable=>true, :service_manage=>true, :service_ensure=>"running", :purge_configs=>true, :purge_vdir=>false, :serveradmin=>"root@localhost", :sendfile=>"On", :error_documents=>false, :timeout=>"120", :httpd_dir=>"/etc/httpd", :server_root=>"/etc/httpd", :conf_dir=>"/etc/httpd/conf", :confd_dir=>"/etc/httpd/conf.d", :vhost_dir=>"/etc/httpd/conf.d", :vhost_include_pattern=>"*", :mod_dir=>"/etc/httpd/conf.d", :mpm_module=>"prefork", :lib_path=>"modules", :conf_template=>"apache/httpd.conf.erb", :servername=>"build03.nelson.va", :pidfile=>"run/httpd.pid", :manage_user=>true, :manage_group=>true, :user=>"apache", :group=>"apache", :keepalive=>"Off", :keepalive_timeout=>15, :max_keepalive_requests=>100, :limitreqfieldsize=>"8190", :logroot=>"/var/log/httpd", :log_level=>"warn", :log_formats=>{}, :ports_file=>"/etc/httpd/conf/ports.conf", :docroot=>"/var/www/html", :apache_version=>"2.2", :server_tokens=>"OS", :server_signature=>"On", :trace_enable=>"On", :package_ensure=>"installed", :use_optional_includes=>false, :use_systemd=>true, :mime_types_additional=>{"AddHandler"=>{"type-map"=>"var"}, "AddType"=>{"text/html"=>".shtml"}, "AddOutputFilter"=>{"INCLUDES"=>".shtml"}}, :file_mode=>"0644", :root_directory_options=>["FollowSymLinks"], :root_directory_secured=>false}, Package[httpd]{:name=>"httpd", :ensure=>"installed", :notify=>Class[Apache::Service]{:name=>"Apache::Service"}}, User[apache]{:name=>"apache", :ensure=>"present", :gid=>"apache", :require=>Package[httpd]{:name=>"httpd"}}, Group[apache]{:name=>"apache", :ensure=>"present", :require=>Package[httpd]{:name=>"httpd"}}, Class[Apache::Service]{:name=>"Apache::Service", :service_name=>"httpd", :service_enable=>true, :service_manage=>true, :service_ensure=>"running"},
When you have a complex test or you’re using a resource type that’s new to you, inspecting the catalog can help you find what you need with a little less trial and error. Thanks to Kristof Willaert (@willaerk) for sharing this!
Edit: Alex Harvey (alexharv074) has previously described a similar method to do this.
4 thoughts on “Print the rspec-puppet catalog, courtesy of @willaerk”