在参数化的puppet模块中rspec测试子类的最佳方法是什么?

时间:2014-11-26 01:03:27

标签: rspec puppet theforeman

我们正在使用具有Foreman enc的Puppet(v3.6.2)并且具有许多自定义模块,其模式在以下插图模块中展示;

#mkdir/manifests/init.pp
class mkdir ($path, $mode) {
  class {'mkdir::file': }
}

#mkdir/manifests/file.pp
class mkdir::file {
  file {$mkdir::path:
    ensure => 'directory',
    mode   => $mkdir::mode,
  }
}

#mkdir/spec/classes/mkdir_spec.rb
require 'spec_helper'
describe 'mkdir' do
  let(:params) {{ :path=>'/foo', :mode=>'777' }}
  it { should contain_class( 'mkdir::file' ) }
end

# All good so far, but here's the rub
# mkdir/spec/classes/file_spec.rb
require 'spec_helper'
describe 'mkdir::file' do
  # how can I set $mkdir::path and $mkdir::mode???
  let(:params) {{ :path=>'/bar', :mode=>'555' }}

  it { should contain_file('/bar').with({
    mode=>'555' })
  }
end

正如代码注释所说,如何在file_spec测试中设置模块参数$ mkdir :: path和$ mkdir :: mode?

显然,可以对模块进行重构,以便将所有需要的参数传递给每个子类,如果这是唯一的方法,我会做的就是这样,但似乎不太可能没有&#39 ; ta方式来测试这种模式。

我也看过很多使用模块:: params模式的例子,对于使用hiera的安装来说这肯定是一个干净的模式,但是我还没有能够使这个模式适用于Foreman,并且最多它需要包括每个参数化模块的两个木偶类,这是丑陋的。

2 个答案:

答案 0 :(得分:3)

你的结论是正确的。但params类模式与节点级配置方案无关。有可能将Hiera更紧密地绑在它上面,但这是你通常想做的事情:

  1. params课程中定义默认值。默认值可能取决于事实值,例如$osfamily
  2. 使模块的主类inherit成为params类,并使用params中声明的变量作为模块类参数的默认值。
  3. 使用ENC时,请确保将节点变量数据作为参数值传递给模块,以便在适当的时候覆盖params类的默认值。
  4. 使模块类将所有必需的配置数据转发给模块中的每个类。
  5. 例如:

    class mkdir::params {
        case $osfamily {
            'Debian': { $path = '/usr/share/foo' }
            'RedHat': { $path = '/var/lib/foo' }
            default:  { fail "The $osfamily platform is not supported by the mkdir module." }
        }
        $mode = 644
    }
    
    class mkdir($mode = $mkdir::params::mode,
                $path = $mkdir::params::path) inherits mkdir::params
    {
        class { 'mkdir::file': mode => $mode, path => $path }
    }
    
    class mkdir::file($path, $mode) {
        # ...
    }
    

    编写测试应该非常直接。

答案 1 :(得分:0)

重构和使用Felix的解决方案可能是更好的解决方案,但对后人来说,另一种选择是:

#spec_helper.rb
def setup_mkdir(p_mode, p_path)
  return "class { 'mkdir':
                    mode => p_mode
                    path => p_path}"
end

# mkdir/spec/classes/file_spec.rb
require 'spec_helper'
describe 'mkdir::file' do
  let(:pre_condition) do
    [ setup_mkdir('555', '/bar') ]
  end

  it { should contain_file('/bar').with({
    mode=>'555' })
  }
end

关键是在pre_condition块中模拟基类。 不要重复自己,并将类模拟放在参数化方法中。