When working on your puppet code, you’re going to want to run rspec against your tests on a regular basis. There are a few quirks to this process that we should cover quickly.
“Normal” Usage
Let’s start with a simple test of everything. You can do this with bundle exec rake spec (or the test target, which includes spec plus some other targets). That would look something like this (note: be is an alias for bundle exec):
$ be rake spec Cloning into 'spec/fixtures/modules/stdlib'... remote: Counting objects: 449, done. remote: Compressing objects: 100% (302/302), done. remote: Total 449 (delta 143), reused 378 (delta 131), pack-reused 0 Receiving objects: 100% (449/449), 198.99 KiB | 0 bytes/s, done. Resolving deltas: 100% (143/143), done. /usr/bin/ruby -I/home/rnelson0/modules/local_user/vendor/ruby/gems/rspec-core-3.1.7/lib:/home/rnelson0/modules/local_user/vendor/ruby/gems/rspec-support-3.1.2/lib /home/rnelson0/modules/local_user/vendor/ruby/gems/rspec-core-3.1.7/exe/rspec --pattern spec/\{classes,defines,unit,functions,hosts,integration,types\}/\*\*/\*_spec.rb --color /home/rnelson0/modules/local_user/spec/spec_helper.rb:12:in `block in <top (required)>': [DEPRECATION] ::[] is deprecated. Use ::new instead. local_user using minimum params should contain User[rnelson0] with comment => "rnelson0", shell => "/bin/bash", home => "/home/rnelson0", groups => ["group1", "group2"] and password_max_age => 90 should not contain Group[rnelson0] should contain Exec[set rnelson0's password] managing all groups should contain User[rnelson0] with comment => "Rob Nelson" and groups => ["group1", "group2"] should contain Group[rnelson0] should contain Group[group1] should contain Group[group2] managing gid only should contain User[rnelson0] with comment => "Rob Nelson" and groups => ["group1", "group2"] should contain Group[rnelson0] should not contain Group[group1] should not contain Group[group2] set manage_groups to false should contain User[rnelson0] with comment => "rnelson0", groups => ["group1", "group2"] and password_max_age => 90 should not contain Group[rnelson0] should not contain Group[group1] should not contain Group[group2] manage_groups with invalid input should raise Puppet::Error using full params should contain User[rnelson0] with comment => "Rob Nelson", shell => "/bin/zsh", home => "/nfshome/rnelson0", groups => ["group1", "group2"], password_max_age => 120 and uid => 101 should contain Local_user::Ssh_authorized_keys[ssh-rsa AAAA...zwE1 rsa-key-20141029] should not contain Group[rnelson0] with a valid date for last_change should contain User[rnelson0] should not contain Group[rnelson0] with an invalid date for last_change should raise Puppet::Error local_user::ssh_authorized_keys default should contain Ssh_authorized_key[rnelson0_ssh-rsa_rsa-key-20141029] with user => "rnelson0", type => "ssh-rsa", key => "AAAA...zwE1" and name => "rsa-key-20141029" local_user::windows with defaults should contain User[rnelson0] with comment => "rnelson0", groups => ["Remote Desktop Users"] and password => "Microsoft1" with allow_rdp => false, admin => false, no groups should contain User[rnelson0] with comment => "rnelson0", groups => [] and password => "Microsoft1" with allow_rdp => true, admin => true, no groups should contain User[rnelson0] with comment => "rnelson0", groups => ["Administrators", "Remote Desktop Users"] and password => "Microsoft1" with allow_rdp => false, admin > true, no groups should contain User[rnelson0] with comment => "rnelson0", groups => ["Administrators"] and password => "Microsoft1" with allow_rdp => false, admin => true, rnelson0 group should contain User[rnelson0] with comment => "rnelson0", groups => ["rnelson0", "Administrators"] and password => "Microsoft1" with allow_rdp => true, admin => true, rnelson0 group should contain User[rnelson0] with comment => "rnelson0", groups => ["rnelson0", "Administrators", "Remote Desktop Users"] and password => "Microsoft1" with allow_rdp => false, admin => true, rnelson0 group should contain User[rnelson0] with comment => "rnelson0", groups => ["rnelson0"] and password => "Microsoft1" fail on non-windows systems should fail to compile and raise an error matching /Windows support only!/ Finished in 1.69 seconds (files took 1.03 seconds to load) 31 examples, 0 failures Coverage report generated for RSpec to /home/rnelson0/modules/local_user/coverage. 0.0 / 0.0 LOC (100.0%) covered. COVERAGE: 100.00% -- 0.0/0.0 lines in 0 files Total resources: 7 Touched resources: 7 Resource coverage: 100.00%
Awesome, everything passed.
How It Works
Take a look at the top of the output and you’ll see a git clone happening. If you run rake against the same target, you’ll see that happen every time. Take a look at the rake targets to see why:
$ be rake -T | grep spec rake check:git_ignore # Fails if directories contain the files specified in .gitignore rake module:dependency[module_name,version] # Set specific module dependency version rake spec # Run spec tests in a clean fixtures directory rake spec_clean # Clean up the fixtures directory rake spec_prep # Create the fixtures directory rake spec_standalone # Run spec tests on an existing fixtures directory rake test # Run syntax, lint, and spec tests
The spec target says it runs in a clean fixtures directory. It achieves this by running the next three targets in series: spec_clean to wipe out the fixtures directory, It has been pointed out to me that this description is misleading. The target assumes that the fixtures directory is clean. It runs the targets spec_prep to create the fixtures (where git repos are cloned and forge modules are downloaded per .fixtures.yml). If any fixtures exist, the spec_prep target will skip those fixtures. Next, it runs the target spec_standalone, which actually runs the tests. If spec_standalone is successful (exit code 0), it then runs spec_clean again. This means that when your tests fail, the fixtures are left alone. We can do test out these steps ourselves pretty easily:
$ be rake spec_clean $ be rake spec_prep Cloning into 'spec/fixtures/modules/stdlib'... remote: Counting objects: 449, done. remote: Compressing objects: 100% (302/302), done. remote: Total 449 (delta 143), reused 378 (delta 131), pack-reused 0 Receiving objects: 100% (449/449), 198.99 KiB | 0 bytes/s, done. Resolving deltas: 100% (143/143), done. $ be rake spec_standalone /usr/bin/ruby -I/home/rnelson0/modules/local_user/vendor/ruby/gems/rspec-core-3.1.7/lib:/home/rnelson0/modules/local_user/vendor/ruby/gems/rspec-support-3.1.2/lib /home/rnelson0/modules/local_user/vendor/ruby/gems/rspec-core-3.1.7/exe/rspec --pattern spec/\{classes,defines,unit,functions,hosts,integration,types\}/\*\*/\*_spec.rb --color /home/rnelson0/modules/local_user/spec/spec_helper.rb:12:in `block in <top (required)>': [DEPRECATION] ::[] is deprecated. Use ::new instead. local_user using minimum params <snip> Finished in 1.49 seconds (files took 1.04 seconds to load) 31 examples, 0 failures Coverage report generated for RSpec to /home/rnelson0/modules/local_user/coverage. 0.0 / 0.0 LOC (100.0%) covered. COVERAGE: 100.00% -- 0.0/0.0 lines in 0 files Total resources: 7 Touched resources: 7 Resource coverage: 100.00% $ echo $? 0 $ ls spec/fixtures/modules/ local_user stdlib
Because we ran the steps individually, even though spec_standalone succeeded, the files are left behind unless we manually call spec_clean. If your module has a lot of dependencies, or you are working with your controlrepo’s profiles module, you may find that the spec_prep step takes a long time. If you are doing repeated tests, you may want to run bundle exec rake spec_prep once and then bundle exec rake spec_standalone as many times as you want. If you change a fixture or the fixture has been modified upstream, then run bundle exec rake spec_clean followed by spec_prep so that you have the latest version of the correct fixtures.
Individual Tests
You may also desire to run rspec against an individual test file, or a group of files smaller than the entire set. You can do this by skipping rake targets and using rspec <filename|glob>. You will still need to run rake spec_prep first, however, so that the fixtures are present. For example:
$ be rake spec_prep Cloning into 'spec/fixtures/modules/stdlib'... remote: Counting objects: 449, done. remote: Compressing objects: 100% (302/302), done. remote: Total 449 (delta 143), reused 378 (delta 131), pack-reused 0 Receiving objects: 100% (449/449), 198.99 KiB | 0 bytes/s, done. Resolving deltas: 100% (143/143), done. $ be rspec spec/defines/windows_spec.rb local_user::windows with defaults should contain User[rnelson0] with comment => "rnelson0", groups => ["Remote Desktop Users"] and password => "Microsoft1" with allow_rdp => false, admin => false, no groups should contain User[rnelson0] with comment => "rnelson0", groups => [] and password => "Microsoft1" with allow_rdp => true, admin => true, no groups should contain User[rnelson0] with comment => "rnelson0", groups => ["Administrators", "Remote Desktop Users"] and password => "Microsoft1" with allow_rdp => false, admin > true, no groups should contain User[rnelson0] with comment => "rnelson0", groups => ["Administrators"] and password => "Microsoft1" with allow_rdp => false, admin => true, rnelson0 group should contain User[rnelson0] with comment => "rnelson0", groups => ["rnelson0", "Administrators"] and password => "Microsoft1" with allow_rdp => true, admin => true, rnelson0 group should contain User[rnelson0] with comment => "rnelson0", groups => ["rnelson0", "Administrators", "Remote Desktop Users"] and password => "Microsoft1" with allow_rdp => false, admin => true, rnelson0 group should contain User[rnelson0] with comment => "rnelson0", groups => ["rnelson0"] and password => "Microsoft1" fail on non-windows systems should fail to compile and raise an error matching /Windows support only!/ Finished in 0.8302 seconds (files took 1.02 seconds to load) 8 examples, 0 failures Coverage report generated for RSpec to /home/rnelson0/modules/local_user/coverage. 0.0 / 0.0 LOC (100.0%) covered. COVERAGE: 100.00% -- 0.0/0.0 lines in 0 files
Cleanup
As mentioned above, the fixtures file or the fixtures themselves change over time. When you’re using a CI pipeline that starts with a fresh environment, you won’t have to worry about cleaning anything up, but if you’re running tests on a local node in your home directory, it’s possible for the fixtures to get stale. You may also change between two branches where the fixtures are different. Be sure to clean up after such work, or when you haven’t used the local repo in a while, so that you get new fixtures, with bundle exec rake spec_clean. You can also remove individual modules from the fixtures directory, if you do not want to disturb other modules, by simply removing the module directory:
$ rm -fR spec/fixtures/modules/stdlib/ $ be rake spec_prep Cloning into 'spec/fixtures/modules/stdlib'... remote: Counting objects: 449, done. remote: Compressing objects: 100% (302/302), done. remote: Total 449 (delta 143), reused 378 (delta 131), pack-reused 0 Receiving objects: 100% (449/449), 198.99 KiB | 0 bytes/s, done. Resolving deltas: 100% (143/143), done.
Troubleshooting
During this process, you’ll inevitably forget to spec_prep before you spec_standalone. That will look like this:
$ be rake spec_clean $ be rake spec_standalone /usr/bin/ruby -I/home/rnelson0/modules/local_user/vendor/ruby/gems/rspec-core-3.1.7/lib:/home/rnelson0/modules/local_user/vendor/ruby/gems/rspec-support-3.1.2/lib /home/rnelson0/modules/local_user/vendor/ruby/gems/rspec-core-3.1.7/exe/rspec --pattern spec/\{classes,defines,unit,functions,hosts,integration,types\}/\*\*/\*_spec.rb --color local_user using minimum params should contain User[rnelson0] with comment => "rnelson0", shell => "/bin/bash", home => "/home/rnelson0", groups => ["group1", "group2"] and password_max_age => 90 (FAILED - 1) should not contain Group[rnelson0] (FAILED - 2) should contain Exec[set rnelson0's password] (FAILED - 3) managing all groups should contain User[rnelson0] with comment => "Rob Nelson" and groups => ["group1", "group2"] (FAILED - 4) should contain Group[rnelson0] (FAILED - 5) should contain Group[group1] (FAILED - 6) should contain Group[group2] (FAILED - 7) managing gid only should contain User[rnelson0] with comment => "Rob Nelson" and groups => ["group1", "group2"] (FAILED - 8) should contain Group[rnelson0] (FAILED - 9) should not contain Group[group1] (FAILED - 10) should not contain Group[group2] (FAILED - 11) set manage_groups to false should contain User[rnelson0] with comment => "rnelson0", groups => ["group1", "group2"] and password_max_age => 90 (FAILED - 12) should not contain Group[rnelson0] (FAILED - 13) should not contain Group[group1] (FAILED - 14) should not contain Group[group2] (FAILED - 15) manage_groups with invalid input should raise Puppet::Error using full params should contain User[rnelson0] with comment => "Rob Nelson", shell => "/bin/zsh", home => "/nfshome/rnelson0", groups => ["group1", "group2"], password_max_age => 120 and uid => 101 (FAILED - 16) should contain Local_user::Ssh_authorized_keys[ssh-rsa AAAA...zwE1 rsa-key-20141029] (FAILED - 17) should not contain Group[rnelson0] (FAILED - 18) with a valid date for last_change should contain User[rnelson0] (FAILED - 19) should not contain Group[rnelson0] (FAILED - 20) with an invalid date for last_change should raise Puppet::Error local_user::ssh_authorized_keys default should contain Ssh_authorized_key[rnelson0_ssh-rsa_rsa-key-20141029] with user => "rnelson0", type => "ssh-rsa", key => "AAAA...zwE1" and name => "rsa-key-20141029" (FAILED - 21) local_user::windows with defaults should contain User[rnelson0] with comment => "rnelson0", groups => ["Remote Desktop Users"] and password => "Microsoft1" (FAILED - 22) with allow_rdp => false, admin => false, no groups should contain User[rnelson0] with comment => "rnelson0", groups => [] and password => "Microsoft1" (FAILED - 23) with allow_rdp => true, admin => true, no groups should contain User[rnelson0] with comment => "rnelson0", groups => ["Administrators", "Remote Desktop Users"] and password => "Microsoft1" (FAILED - 24) with allow_rdp => false, admin > true, no groups should contain User[rnelson0] with comment => "rnelson0", groups => ["Administrators"] and password => "Microsoft1" (FAILED - 25) with allow_rdp => false, admin => true, rnelson0 group should contain User[rnelson0] with comment => "rnelson0", groups => ["rnelson0", "Administrators"] and password => "Microsoft1" (FAILED - 26) with allow_rdp => true, admin => true, rnelson0 group should contain User[rnelson0] with comment => "rnelson0", groups => ["rnelson0", "Administrators", "Remote Desktop Users"] and password => "Microsoft1" (FAILED - 27) with allow_rdp => false, admin => true, rnelson0 group should contain User[rnelson0] with comment => "rnelson0", groups => ["rnelson0"] and password => "Microsoft1" (FAILED - 28) fail on non-windows systems should fail to compile and raise an error matching /Windows support only!/ (FAILED - 29) Failures: 1) local_user using minimum params should contain User[rnelson0] with comment => "rnelson0", shell => "/bin/bash", home => "/home/rnelson0", groups => ["group1", "group2"] and password_max_age => 90 Failure/Error: it { is_expected.to create_user('rnelson0').with({ Puppet::PreformattedError: Evaluation Error: Error while evaluating a Resource Statement, Invalid resource type local_user at line 1:1 on node build03.nelson.va # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/resource.rb:266:in `initialize' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/parser/resource.rb:123:in `initialize' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/evaluator/runtime3_support.rb:329:in `new' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/evaluator/runtime3_support.rb:329:in `block in create_resources' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/evaluator/runtime3_support.rb:328:in `map' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/evaluator/runtime3_support.rb:328:in `create_resources' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/evaluator/evaluator_impl.rb:763:in `block in eval_ResourceExpression' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/evaluator/evaluator_impl.rb:760:in `map' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/evaluator/evaluator_impl.rb:760:in `eval_ResourceExpression' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/visitor.rb:46:in `block in visit_this' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/visitor.rb:42:in `each' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/visitor.rb:42:in `visit_this' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/visitor.rb:69:in `visit_this_1' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/evaluator/evaluator_impl.rb:73:in `evaluate' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/evaluator/evaluator_impl.rb:644:in `eval_Program' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/visitor.rb:46:in `block in visit_this' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/visitor.rb:42:in `each' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/visitor.rb:42:in `visit_this' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/visitor.rb:69:in `visit_this_1' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/evaluator/evaluator_impl.rb:73:in `evaluate' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/pops/parser/evaluating_parser.rb:57:in `evaluate' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/parser/ast/pops_bridge.rb:111:in `evaluate' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/parser/ast.rb:31:in `safeevaluate' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/resource/type.rb:185:in `evaluate_code' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/parser/resource.rb:84:in `block in evaluate' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/util/profiler/around_profiler.rb:58:in `profile' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/util/profiler.rb:51:in `profile' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/parser/resource.rb:76:in `evaluate' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/parser/compiler.rb:638:in `evaluate_main' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/parser/compiler.rb:180:in `block (2 levels) in compile' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/util/profiler/around_profiler.rb:58:in `profile' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/util/profiler.rb:51:in `profile' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/parser/compiler.rb:180:in `block in compile' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/context.rb:65:in `override' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet.rb:240:in `override' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/parser/compiler.rb:168:in `compile' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/parser/compiler.rb:36:in `compile' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/indirector/catalog/compiler.rb:93:in `block (2 levels) in compile' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/util/profiler/around_profiler.rb:58:in `profile' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/util/profiler.rb:51:in `profile' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/indirector/catalog/compiler.rb:91:in `block in compile' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/util.rb:129:in `block in benchmark' # /usr/share/ruby/benchmark.rb:296:in `realtime' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/util.rb:128:in `benchmark' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/indirector/catalog/compiler.rb:90:in `compile' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/indirector/catalog/compiler.rb:50:in `find' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/indirector/indirection.rb:194:in `find' # ./vendor/ruby/gems/rspec-puppet-2.3.2/lib/rspec-puppet/support.rb:218:in `block in build_catalog_without_cache' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet/context.rb:65:in `override' # ./vendor/ruby/gems/puppet-4.3.2/lib/puppet.rb:240:in `override' # ./vendor/ruby/gems/rspec-puppet-2.3.2/lib/rspec-puppet/support.rb:216:in `build_catalog_without_cache' # ./vendor/ruby/gems/rspec-puppet-2.3.2/lib/rspec-puppet/support.rb:231:in `block in build_catalog' # ./vendor/ruby/gems/rspec-puppet-2.3.2/lib/rspec-puppet/cache.rb:17:in `call' # ./vendor/ruby/gems/rspec-puppet-2.3.2/lib/rspec-puppet/cache.rb:17:in `get' # ./vendor/ruby/gems/rspec-puppet-2.3.2/lib/rspec-puppet/support.rb:230:in `build_catalog' # ./vendor/ruby/gems/rspec-puppet-2.3.2/lib/rspec-puppet/support.rb:28:in `load_catalogue' # ./vendor/ruby/gems/rspec-puppet-2.3.2/lib/rspec-puppet/example/define_example_group.rb:7:in `catalogue' # ./vendor/ruby/gems/rspec-puppet-2.3.2/lib/rspec-puppet/support.rb:8:in `block in subject' # ./vendor/ruby/gems/rspec-puppet-2.3.2/lib/rspec-puppet/matchers/create_generic.rb:82:in `call' # ./vendor/ruby/gems/rspec-puppet-2.3.2/lib/rspec-puppet/matchers/create_generic.rb:82:in `matches?' # ./spec/defines/init_spec.rb:19:in `block (3 levels) in <top (required)>' <Repeat for every other test> Finished in 0.69899 seconds (files took 1.03 seconds to load) 31 examples, 29 failures Failed examples: rspec ./spec/defines/init_spec.rb:19 # local_user using minimum params should contain User[rnelson0] with comment => ... <Repeat for every other test> COVERAGE: 100.00% -- 0.0/0.0 lines in 0 files Total resources: 0 Touched resources: 0 Resource coverage: NaN% Untouched resources: /usr/bin/ruby -I/home/rnelson0/modules/local_user/vendor/ruby/gems/rspec-core-3.1.7/lib:/home/rnelson0/modules/local_user/vendor/ruby/gems/rspec-support-3.1.2/lib /home/rnelson0/modules/local_user/vendor/ruby/gems/rspec-core-3.1.7/exe/rspec --pattern spec/\{classes,defines,unit,functions,hosts,integration,types\}/\*\*/\*_spec.rb --color failed
All the errors will be the same, and the error will vary based on the first resource referenced in a test file. If the first resource was include mymodule, the error would look something like:
Both merely indicate that you need to run bundle exec spec_prep and you’ll be fine.
“The spec target says it runs in a clean fixtures directory. It achieves this by running the next three targets in series: spec_clean to wipe out the fixtures directory…”
I’m not sure that this is accurate. Does spec really run spec_clean first? If I have failing tests and rerun spec, fixtures aren’t re-downloaded, (which they would have to be if spec_clean got run by spec as its first task).
https://github.com/puppetlabs/puppetlabs_spec_helper/blob/master/lib/puppetlabs_spec_helper/rake_tasks.rb#L276
I’ve been a fan of adding to my `spec_helper.rb`
“`
RSpec.configure do |config|
config.filter_run focus: true
config.run_all_when_everything_filtered = true
end
“`
which allows me to add `:focus => true` to any context/define. `bundle exec rake spec` then just tests the blocks that are “focused”.
“`
context “ipa http ssl cert”, :focus => true do
let(:params) { { :http_cert_provider => ‘ipa’ } }
it do
is_expected.to contain_apache__vhost(‘site-https’).with(
:ssl => true,
…
)
end
end
“`