微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Puppet 单元测试在测试之间更改参数

如何解决Puppet 单元测试在测试之间更改参数

我有一个关于如何为同一资源设置多个测试以及如何为不同测试更改参数的问题。该示例被最小化以仅反映问题。

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。