Как проверить, содержит ли параметр массива для ресурса Puppet значение

Я пишу настраиваемый модуль марионетки, который включает ресурс :: apache :: vhost, и хотел бы проверить в моих тестах rspec, что параметр каталогов содержит определенное значение, без воспроизведения всей конфигурации каталогов, которая в основном жестко запрограммирована в тесте спецификации .

class foo::apache {

  # prepend 'from ' to each element in array of subnets
  # Change this ugliness to use map once we've upgraded to puppet v4
  # open to suggetions on better way to do this too...
  $subnets = $::foo::subnets
  $subnets_yaml = inline_template('<%= subnets.map {|s| "from " +s}.to_yaml %>')
  $allowed_subnets_directives = parseyaml($subnets_yaml)

  ::apache::vhost { 'foo_vhost':
    directories => [
       -- snip --
        ##### How can I check just the path & allow keys of this element?
      { 'path' => '~^.*$',
        'Order' => 'deny,allow',
        'allow' => concat(['from localhost'],
                   $allowed_subnets_directives),
        'provider' => 'location',
      },
    ]
  } # foo_vhost
} # foo::apache

Я удалил большую часть манифеста для краткости.

Я могу протестировать весь параметр директив с чем-то вроде

describe 'foo::apache' do
  it { is_expected.to contain_apache__vhost('foo_vhost').with(
    'directories' => [{'path' => '~^.*$',
                       'allow' => ['from localhost',
                                   'from 10.20.30/24',
                                  ],},
                     ]

но параметр каталогов длинный и статический, и я стараюсь этого избежать.

Сопоставитель rspec include выглядит как то, что мне нужно, но я не могу понять, как его использовать для проверки параметра или переменной $allowed_subnets_directives


person TaninDirect    schedule 13.07.2015    source источник
comment
FWIW, добавление чего-либо ко всему в массиве может быть выполнено в более старых версиях с помощью regsubst функция.   -  person Felix Frank    schedule 14.07.2015


Ответы (2)


Недавно я столкнулся с этой же проблемой. Нет чистого способа прямого доступа к внутренней части параметра.

Я разговаривал с dev_el_ops в канале voxpupuli на freenode, и он сказал, что «одна из проблем дизайна rspec-pupet заключается в том, что он не предоставляет значения свойств обычным сопоставителям rspec»

Я не уверен, как лучше всего «найти хеш с ключом в массиве» в рубине, поэтому я ссылаюсь на этот ответ Я бы проверил вышесказанное примерно так

it do
  vhost_directories = catalogue.resource('apache__vhost', 'foo_vhost').send(:parameters)[:directories]
  expect(vhost_directories.find {|x| x[:path] == '~^.*$'}).to be_truthy
end

Если вы сделаете предположение, что это первая запись в массиве, вы можете использовать более читаемый 'include' matcher в хеше.

it do
  vhost_directories = catalogue.resource('apache__vhost', 'foo_vhost').send(:parameters)[:directories]
  expect(vhost_directories.first).to include(:path => '~^.*$')
end
person Cinderhaze    schedule 11.01.2017

Этот запрос несколько устарел, однако он все еще актуален для rspec-puppet и puppet 5+. По крайней мере, для простых массивов (верхнего уровня) можно использовать значения регулярных выражений, чтобы проверить, содержится ли значение в параметрах.

Например, для простого класса марионеток:

# simple test with array parameter
class array_test(
  Array[String] $values = [],
) {
  notify{"And the values are: ${values}": }
}

Следующий тест включает проверку регулярных выражений на предмет ожидаемых значений:

# frozen_string_literal: true

require 'spec_helper'
describe 'array_test' do

  context 'with default values for all parameters' do
    it { is_expected.to compile.with_all_deps }
    it { is_expected.to contain_class('array_test') }
  end
  context 'with there parameters' do
    let(:params) {{
      'values' => ['a','b','c','abcd']
    }}

    it { is_expected.to contain_class('array_test').with('values' => %r{"a"}) }
    it { is_expected.to contain_class('array_test').with('values' => %r{"b"}) }
    it { is_expected.to contain_class('array_test').with('values' => %r{"c"}) }
    it { is_expected.to contain_class('array_test').with('values' => %r{"abcd"}) }
    it { is_expected.not_to contain_class('array_test').with('values' => %r{"d"}) }
  end
end

Что при запуске дает следующий результат:

$ bundle exec rake spec
(in /home/vagrant/git/array_test)
I, [2019-08-01T15:35:28.987120 #6373]  INFO -- : Creating symlink from spec/fixtures/modules/array_test to /home/vagrant/git/array_test
/home/vagrant/.rvm/rubies/ruby-2.4.4/bin/ruby -I/home/vagrant/.rvm/gems/ruby-2.4.4/gems/rspec-core-3.8.2/lib:/home/vagrant/.rvm/gems/ruby-2.4.4/gems/rspec-support-3.8.2/lib /home/vagrant/.rvm/gems/ruby-2.4.4/gems/rspec-core-3.8.2/exe/rspec --pattern spec/\{aliases,classes,defines,functions,hosts,integration,plans,tasks,type_aliases,types,unit\}/\*\*/\*_spec.rb

array_test
  with default values for all parameters
    should compile into a catalogue without dependency cycles
    should contain Class[array_test]
  with there parameters
    should contain Class[array_test] with values =~ /"a"/
    should contain Class[array_test] with values =~ /"b"/
    should contain Class[array_test] with values =~ /"c"/
    should contain Class[array_test] with values =~ /"abcd"/
    should not contain Class[array_test] with values =~ /"d"/

Finished in 1.03 seconds (files took 4.26 seconds to load)
7 examples, 0 failures


Code coverage
  must cover at least 0% of resources
Total resources:   2
Touched resources: 0
Resource coverage:  0.00%

Untouched resources:
  Notify[And the values are: []]
  Notify[And the values are: [a, b, c, abcd]]
person MarkBarry    schedule 01.08.2019