Как я могу имитировать факты, чтобы проверить шаблон Puppet, который выполняет десятичное умножение на факт?

Контекст:

У меня есть шаблон марионетки, который обращается к подкомпоненту count факта processors при его отображении. Этот факт есть у всех моих клиентов.

Вариант использования этого факта находится в строке шаблона, которая выполняет над ним десятичную математику, например: MyConfigVar=<%= 0.9 * @processors['count'] %> в каком-то .erb файле.

Я бы хотел:

  1. Получите мой шаблонный код, развернутый на производственных узлах.
  2. Напишите надежные модульные тесты для моих шаблонов, чтобы я мог быть уверен, что они будут отображаться правильно, учитывая различные разумные значения факта.

Что я пробовал:

Сначала я попробовал сигилы: <%= 0.9 * @processors[:count] %>. Если я с помощью rspec-puppet издевался над чем-то вроде facts = { :processors => { :count => 10 } }, все мои тесты проходили. Приложение манифеста не работало; у него была ошибка "невозможно умножить nil". Сигилы, видимо, закончились.

Затем я попробовал с тягучими клавишами: <%= 0.9 * @processors['count'] %>. Мои тесты с сигилом (facts = { :processors => { :count => 10 } }) не были приняты, но мое значение было правильно найдено и умножено на facts = { :processors => { 'count' => 10 } }. Все тесты потом прошли. Однако приложение манифеста завершилось с ошибкой Can't coerce String into Int.

Затем я попытался использовать строковые значения. Шаблон все еще читал <%= 0.9 * @processors['count'].to_i %>, и я тестировал как строковые, так и целые значения, например.

let(:facts) { :processors => { 'count' => '10' } }
# tests with string value
let(:facts) { :processors => { 'count' => 10 } }
# tests with integer value

Тесты все прошли, но приложение манифеста выдало 0.0 за значение факта.

Вопросы:

Два основных вопроса:

  1. Как я могу надежно заставить встроенную десятичную математику работать с этим (или любым) фактом?
  2. Как я могу надежно выполнить модульное тестирование, используя rspec-puppet или подобное, фактически имитируя значения с репрезентативными для производства типами?

person Zac B    schedule 25.04.2016    source источник


Ответы (2)


Здесь есть несколько вещей.

Как говорит Джош Соуза, старые версии Facter не поддерживали хэши или массивы. Поэтому в зависимости от версии Puppet и Facter, которую вы используете, я бы проверил значение stringify_facts config.

Если для этого установлено значение true (которое будет в более старых версиях Puppet), то факты не будут отображаться в виде хэшей, они преобразуются в строку в вашем манифесте, что приводит к смешанной строке без разделения (например, modelsIntel(R) Core(TM) i7-2760QM CPU @ 2.40GHzcount1physicalcount1). Обратите внимание на count1, это было бы :count => 1 в исходном хэше.

Вы можете проверить это с помощью настройки stringify_facts в вашем spec_helper в rspec-puppet >= 2.2.

Таким образом, есть ряд устаревших фактов, которые не являются хэшами, которые вы можете увидеть, если запустите facter -p:

$ facter -p | grep processor
processorcount => 8
processors => {"count"=>8, "speed"=>"2.5 GHz"}
sp_current_processor_speed => 2.5 GHz
sp_number_processors => 4

Поэтому я бы рекомендовал использовать факт $::processorcount, который должен быть целым числом, потому что это возвращаемое значение, но вы можете использовать to_i, чтобы быть уверенным в своем шаблоне .erb. Я почти уверен, что он всегда должен возвращать целое число.

Если вы чувствуете себя действительно смелым, вы можете создать функцию для приведения значения к числовому и использовать его в своем манифесте (например, https://github.com/kwilczynski/puppet-functions/blob/master/lib/puppet/parser/functions/str2num.rb< /а>)

Таким образом, у вас будет код, который выглядит так:

if (is_integer($::processorcount)) {
  $processor_as_int = $::processorcount
} else {
  $processor_as_int = str2num($::processorcount)
}

В общем, это немного запутанно, вы можете понять, почему в Puppet 4 у нас есть гораздо более жесткая система набора текста!

person Peter Souter    schedule 28.04.2016

Что бы это ни стоило, я провел некоторое расследование вашей проблемы, и на моем тестовом стенде факт «процессоров», в то время как хэш при запуске facter processors, на самом деле является строкой, когда он попадает в Puppet/templates, и в нем отсутствует какой-либо разделитель ( IE «modelsIntel(R) Core(TM) i7-2760QM CPU @ 2,40 ГГцcount1physicalcount1» — это необработанное значение). Я проверил это, используя '@processors.class' в моем шаблоне ruby, а также несколько других тестов, чтобы быть уверенным. На моем тестовом стенде работают Puppet 3.8.3 и Facter 2.4.6, на случай, если это что-то затронет.

Итак, решения, которые я могу предложить, следующие:

  1. Используйте факт @processorcount, который всегда будет целым числом и должен прекрасно работать с сигилами в ваших модульных тестах.
  2. Используйте Facter прямо в своем шаблоне (что не совсем кукольно, но работает)

    • <%= Facter.value(:processors)['count'] %>
  3. Используйте синтаксический анализ строки регулярных выражений (я не рекомендую это, так как он хрупкий и хакерский, но он ДЕЙСТВУЕТ)

Вполне возможно, что в разных версиях Puppet/Facter это не проблема, но, надеюсь, этого достаточно, чтобы двигаться в правильном направлении.

person Josh Souza    schedule 27.04.2016