Reputation: 45
I have a question concerning how to set up multiple tests for the same resource and changing parameters for different tests. The example is minimized to reflect just the problem.
TheGood: I got the first unit test running, where the parameter is a direct parameter of the resource: mymod/manifests/as/myressource3.pp:
define mymod::as::myressource3 (
Optional[String] $maxheap = undef,
) {
$effective_maxheap = ($maxheap =~ NotUndef) ? {
true => $maxheap,
false => "${::facts['memory']['system']['total_bytes'] * 3 / 4 / 1024 / 1024}M",
}
notice("effective_maxheap = ${effective_maxheap}")
mymod::as::myressource2 {"myres3_myres2-${title}":
maxheap => $effective_maxheap,
}
}
mymod/spec/defines/as/myressource3_spec.rb:
require 'spec_helper'
describe 'mymod::as::myressource3' do
let(:title) { 'as_myressource3_test' }
on_supported_os.each do |os, os_facts|
context "no maxheap on #{os}" do
let(:facts) { os_facts }
let(:params) { {
} }
it { is_expected.to compile }
it { is_expected.to contain_mymod__as__myressource2("myres3_myres2-as_myressource3_test").with({
:maxheap => /^[0-9]+M$/,
})}
context "with maxheap on #{os}" do
let(:params) do
super().merge('maxheap' => '3G')
end
it { is_expected.to compile }
it { is_expected.to contain_mymod__as__myressource2("myres3_myres2-as_myressource3_test").with({
:maxheap => '3G',
})}
end
end
end
end
As said, this works fine and I can change the value of the parameter maxheap for the second test.
TheBad: But in a different situation another resource is using a „global“ variable from an outer class. Using the same approach as in „TheGood“, I am not able the change the parameter in the second context.
mymod/manifests/as/myressource.pp:
define mymod::as::myressource (
) {
$effective_maxheap = ($::mymod::maxheap =~ NotUndef) ? {
true => $::mymod::maxheap,
false => "${::facts['memory']['system']['total_bytes'] * 3 / 4 / 1024 / 1024}M",
}
notice("effective_maxheap = ${effective_maxheap}")
mymod::as::myressource2 {"myres_myres2-${title}":
maxheap => $effective_maxheap,
}
}
notice the use of $::mymod::maxheap!
mymod/manifests/init.pp:
class mymod(
Optional[String] $maxheap = undef,
) {
notice("${title} start maxheap=${maxheap} ...")
mymod::as::myressource {'whatever': }
notice("${title} end ...")
}
mymod/spec/defines/as/myressource_spec.rb:
require 'spec_helper'
describe 'mymod::as::myressource' do
let(:title) { 'as_myressource_test' }
on_supported_os.each do |os, os_facts|
context "no maxheap on #{os}" do
let(:facts) { os_facts }
let(:pre_condition) do
"
class { 'mymod':
}
"
end
it { is_expected.to compile }
it { is_expected.to contain_mymod__as__myressource2("myres_myres2-as_myressource_test").with({
:maxheap => /^[0-9]+M$/,
})}
context "with maxheap on #{os}" do
let(:params) do
super().merge('::mymod::maxheap' => '3G')
end
it { is_expected.to compile }
it { is_expected.to contain_mymod__as__myressource2("myres_myres2-as_myressource_test").with({
:maxheap => '3G'
})}
end
end
end
end
This is giving the following exeption:
1) mymod::as::myressource no maxheap on sles-12-x86_64 with maxheap on sles-12-x86_64 is expected to compile into a catalogue without dependency cycles
Failure/Error: super().merge('::mymod::maxheap' => '3G')
NoMethodError:
super: no superclass method `params' for #<RSpec::ExampleGroups::MymodAsMyressource::NoMaxheapOnSles12X8664::WithMaxheapOnSles12X8664:0x000000000781c5c0>
Did you mean? param_str
# /opt/puppetlabs/pdk/share/cache/ruby/2.5.0/gems/rspec-puppet-2.7.8/lib/rspec-puppet/matchers/dynamic_matchers.rb:7:in `method_missing'
# ./spec/defines/as/myressource_spec.rb:23:in `block (5 levels) in <top (required)>'
# /opt/puppetlabs/pdk/share/cache/ruby/2.5.0/gems/rspec-puppet-2.7.8/lib/rspec-puppet/support.rb:149:in `test_manifest'
# /opt/puppetlabs/pdk/share/cache/ruby/2.5.0/gems/rspec-puppet-2.7.8/lib/rspec-puppet/support.rb:21:in `build_code'
# /opt/puppetlabs/pdk/share/cache/ruby/2.5.0/gems/rspec-puppet-2.7.8/lib/rspec-puppet/support.rb:91:in `block in load_catalogue'
# /opt/puppetlabs/pdk/share/cache/ruby/2.5.0/gems/rspec-puppet-2.7.8/lib/rspec-puppet/support.rb:376:in `with_vardir'
# /opt/puppetlabs/pdk/share/cache/ruby/2.5.0/gems/rspec-puppet-2.7.8/lib/rspec-puppet/support.rb:83:in `load_catalogue'
# /opt/puppetlabs/pdk/share/cache/ruby/2.5.0/gems/rspec-puppet-2.7.8/lib/rspec-puppet/example/define_example_group.rb:7:in `catalogue'
# /opt/puppetlabs/pdk/share/cache/ruby/2.5.0/gems/rspec-puppet-2.7.8/lib/rspec-puppet/support.rb:12:in `block in subject'
# /opt/puppetlabs/pdk/share/cache/ruby/2.5.0/gems/rspec-puppet-2.7.8/lib/rspec-puppet/matchers/compile.rb:23:in `matches?'
# ./spec/defines/as/myressource_spec.rb:25:in `block (5 levels) in <top (required)>'
How can I change ::mymod::maxheap for the second test? Or maybe this example is no good puppet style?
Upvotes: 0
Views: 424
Reputation: 799
I think there are two ways to fix this. first in you have the following
define mymod::as::myressource (
) {
$effective_maxheap = ($::mymod::maxheap =~ NotUndef) ? {}
}
As you make use of the mymod class i would explicitly include it e.g.
define mymod::as::myressource (
) {
include mymod
$effective_maxheap = ($::mymod::maxheap =~ NotUndef) ? {}
}
This means that when your rspec tests run mymod will automaticity be included, all code in it compiled, and you wont need to mock anything in rspec.
If this is not possible or desirable then you can use pre_condition
to initiate the class for you. Again this will cause everything inside mymod to also get compiled when running the spec test
describe 'mymod::as::myressource' do
let(:title) { 'as_myressource_test' }
on_supported_os.each do |os, os_facts|
context "no maxheap on #{os}" do
let(:facts) { os_facts }
let(:pre_condition) { "class {'mymod': $maxheap = undef" }
end
end
end
if compiling the code in mymod is undesirable and you really just want to mock the maxheap variable you can do the following
describe 'mymod::as::myressource' do
let(:title) { 'as_myressource_test' }
on_supported_os.each do |os, os_facts|
context "no maxheap on #{os}" do
let(:facts) { os_facts }
let(:pre_condition) { "class mymod { $maxheap = undef }" }
end
end
end
Upvotes: 1