问题描述
我有一个关于如何为同一资源设置多个测试以及如何为不同测试更改参数的问题。该示例被最小化以仅反映问题。
TheGood:我运行了第一个单元测试,其中参数是资源的直接参数: 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
如上所述,这很好用,我可以为第二个测试更改参数 maxheap 的值。
TheBad:但在另一种情况下,另一种资源使用来自外部类的“全局”变量。使用与“TheGood”相同的方法,我无法在第二个上下文中更改参数。
mymod/manifests/as/myressource.pp:
define mymod::as::myressource (
) {
$effective_maxheap = ($::mymod::maxheap =~ NotUndef) ? {
true => $::mymod::maxheap,}
notice("effective_maxheap = ${effective_maxheap}")
mymod::as::myressource2 {"myres_myres2-${title}":
maxheap => $effective_maxheap,}
}
注意$::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
这是给出以下例外:
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)>'
如何更改 ::mymod::maxheap 以进行第二次测试?或者这个例子可能不是很好的木偶风格?
解决方法
我认为有两种方法可以解决这个问题。首先在你有以下
define mymod::as::myressource (
) {
$effective_maxheap = ($::mymod::maxheap =~ NotUndef) ? {}
}
当你使用 mymod 类时,我会明确地包含它,例如
define mymod::as::myressource (
) {
include mymod
$effective_maxheap = ($::mymod::maxheap =~ NotUndef) ? {}
}
这意味着当你的 rspec 测试运行 mymod 时将自动包含其中的所有代码,并且你不需要在 rspec 中模拟任何东西。
如果这是不可能的或不可取的,那么您可以使用 pre_condition
为您启动课程。同样,这将导致 mymod 中的所有内容在运行规范测试时也被编译
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
如果在 mymod 中编译代码是不可取的,而您真的只想模拟 maxheap 变量,您可以执行以下操作
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