diff --git a/.fixtures.yml b/.fixtures.yml index 2296adb..4db6cdb 100644 --- a/.fixtures.yml +++ b/.fixtures.yml @@ -3,4 +3,8 @@ --- fixtures: forge_modules: -# stdlib: "puppetlabs/stdlib" + facts: 'puppetlabs/facts' + puppet_agent: 'puppetlabs/puppet_agent' + stdlib: 'puppetlabs/stdlib' + symlinks: + patching: "#{source_dir}" diff --git a/.sync.yml b/.sync.yml index 8da36be..2f7290a 100644 --- a/.sync.yml +++ b/.sync.yml @@ -12,12 +12,21 @@ .gitlab-ci.yml: # we don't use GitLab unmanaged: true +.travis.yml: + # removed Puppet 5 checks here + remove_includes: + - env: PUPPET_GEM_VERSION="~> 5.0" CHECK=parallel_spec + rvm: 2.4.5 + stage: spec appveyor.yml: # we don't use Appveyor unmanaged: true Gemfile: required: ':development': + - gem: 'rake' + - gem: 'bolt' + version: '>= 1.48.0' - gem: 'puppet-lint-absolute_template_path' version: '>= 1.0.1' - gem: 'puppet-lint-alias-check' @@ -40,15 +49,29 @@ Gemfile: version: '>= 0.3.0' - gem: 'puppet-lint-version_comparison-check' version: '>= 0.2.1' + - gem: 'puppetlabs_spec_helper' - gem: 'r10k' version: '>= 3.0.0' + - gem: 'rspec-puppet-facts' # cri is needed by r10k, but due to a bug in the cri gem v2.15.7 it breaks r10k # see: https://github.com/puppetlabs/r10k/issues/930 - gem: 'cri' version: '2.15.6' - gem: 'yaml-lint' version: '>= 0.0.10' -# Rakefile: -# extras: -# - "# exclude plans because puppet-syntax doesn't support them yet: https://github.com/voxpupuli/puppet-syntax/issues/95" -# - 'PuppetSyntax.exclude_paths = ["plans/**/*", "vendor/**/*"]' +spec/spec_helper.rb: + mock_with: ':rspec' + spec_overrides: + - '# setup for Bolt spec tests' + - "require 'bolt_spec/plans'" + - 'BoltSpec::Plans.init' + - 'include BoltSpec::Plans' + - '' + - '# setup the proper modulepath for Bolt' + - 'base_dir = File.dirname(File.expand_path(__FILE__))' + - 'RSpec.configure do |c|' + - ' # should we just use rspec_puppet' + - ' c.add_setting :module_path' + - " c.module_path = File.join(base_dir, 'fixtures', 'modules')" + - 'end' + diff --git a/.travis.yml b/.travis.yml index cc78f7d..3274504 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,10 +29,6 @@ matrix: - env: CHECK="check:symlinks check:git_ignore check:dot_underscore check:test_file rubocop syntax lint metadata_lint" stage: static - - - env: PUPPET_GEM_VERSION="~> 5.0" CHECK=parallel_spec - rvm: 2.4.5 - stage: spec - env: PUPPET_GEM_VERSION="~> 6.0" CHECK=parallel_spec rvm: 2.5.3 diff --git a/Gemfile b/Gemfile index a661681..79b9968 100644 --- a/Gemfile +++ b/Gemfile @@ -28,6 +28,8 @@ group :development do gem "puppet-module-posix-dev-r#{minor_version}", '~> 0.4', require: false, platforms: [:ruby] gem "puppet-module-win-default-r#{minor_version}", '~> 0.4', require: false, platforms: [:mswin, :mingw, :x64_mingw] gem "puppet-module-win-dev-r#{minor_version}", '~> 0.4', require: false, platforms: [:mswin, :mingw, :x64_mingw] + gem "rake", require: false + gem "bolt", '>= 1.48.0', require: false gem "puppet-lint-absolute_template_path", '>= 1.0.1', require: false gem "puppet-lint-alias-check", '>= 0.1.1', require: false gem "puppet-lint-classes_and_types_beginning_with_digits-check", '>= 0.1.2', require: false @@ -39,7 +41,9 @@ group :development do gem "puppet-lint-trailing_comma-check", '>= 0.3.2', require: false gem "puppet-lint-unquoted_string-check", '>= 0.3.0', require: false gem "puppet-lint-version_comparison-check", '>= 0.2.1', require: false + gem "puppetlabs_spec_helper", require: false gem "r10k", '>= 3.0.0', require: false + gem "rspec-puppet-facts", require: false gem "cri", '2.15.6', require: false gem "yaml-lint", '>= 0.0.10', require: false end diff --git a/plans/check_puppet.pp b/plans/check_puppet.pp index 73401cf..79331bf 100644 --- a/plans/check_puppet.pp +++ b/plans/check_puppet.pp @@ -80,7 +80,7 @@ if !$targets_no_puppet.empty() { # run `facter` if it's available otherwise get basic facts run_plan('facts', - nodes => $targets_no_puppet) + targets => $targets_no_puppet) } return({ diff --git a/spec/plans/available_updates_spec.rb b/spec/plans/available_updates_spec.rb new file mode 100644 index 0000000..3ff7c1c --- /dev/null +++ b/spec/plans/available_updates_spec.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'patching::available_updates' do + let(:targets_names) { ['foo', 'bar'] } + let(:targets) { bolt_targets_arr(targets_names) } + let(:targets_obj) { bolt_targets_obj(targets_names) } + let(:plan_name) { 'patching::available_updates' } + + context 'with nodes passed' do + it 'returns a default value' do + expect_task('patching::available_updates') + .with_targets(targets) + .with_params('_noop' => false) + .return_for_targets( + 'foo' => { 'values' => { 'updates' => ['a'] } }, + 'bar' => { 'values' => { 'updates' => ['b'] } }, + ) + + result = run_plan(plan_name, + 'nodes' => targets_names, + 'format' => 'none') + expect(result).to be_ok + expect(result.value.class).to eq(Bolt::ResultSet) + expect(result.value).to eq(bolt_results('foo' => { 'values' => { 'updates' => ['a'] } }, + 'bar' => { 'values' => { 'updates' => ['b'] } })) + end + end +end diff --git a/spec/plans/check_online_spec.rb b/spec/plans/check_online_spec.rb new file mode 100644 index 0000000..9fc9192 --- /dev/null +++ b/spec/plans/check_online_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'patching::check_online' do + let(:targets_names) { ['foo', 'bar'] } + let(:targets) { bolt_targets_arr(targets_names) } + let(:targets_obj) { bolt_targets_obj(targets_names) } + let(:plan_name) { 'patching::check_online' } + + context 'with nodes passed' do + it 'returns a default value' do + expect_task('puppet_agent::version') + .with_targets(targets) + .with_params('_catch_errors' => true) + expect_out_message.with_params('All nodes succeeded!') + + result = run_plan(plan_name, 'nodes' => targets_names) + expect(result).to be_ok + expect(result.value).to be_nil + end + end +end diff --git a/spec/plans/check_puppet_spec.rb b/spec/plans/check_puppet_spec.rb new file mode 100644 index 0000000..89b8c3b --- /dev/null +++ b/spec/plans/check_puppet_spec.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'patching::check_puppet' do + let(:targets_names) { ['foo', 'bar'] } + let(:targets) { bolt_targets_arr(targets_names) } + let(:targets_obj) { bolt_targets_obj(targets_names) } + let(:plan_name) { 'patching::check_puppet' } + + context 'with nodes passed' do + it 'returns a default value' do + expect_task('puppet_agent::version') + .with_targets(targets) + .with_params('_catch_errors' => false) + .return_for_targets( + 'foo' => { 'values' => { 'version' => '6.5.4' } }, + 'bar' => { 'values' => { 'version' => :undef } }, + ) + + # expect_plan('patching::puppet_facts') + # .with_params('nodes' => [targets_obj['foo']]) + expect_plan('facts') + .with_params('targets' => [targets_obj['foo'], targets_obj['bar']]) + + result = run_plan(plan_name, 'nodes' => targets_names) + puts "result = #{result}" + expect(result).to be_ok + end + end +end diff --git a/spec/plans/puppet_facts_spec.rb b/spec/plans/puppet_facts_spec.rb new file mode 100644 index 0000000..65cc540 --- /dev/null +++ b/spec/plans/puppet_facts_spec.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'patching::puppet_facts' do + let(:targets_names) { ['foo', 'bar'] } + let(:targets) { bolt_targets_arr(targets_names) } + let(:targets_obj) { bolt_targets_obj(targets_names) } + let(:plan_name) { 'patching::puppet_facts' } + + context 'with nodes passed' do + it 'returns a default value' do + expect_task('patching::puppet_facts').with_targets(targets).return_for_targets( + 'foo' => { 'values' => { 'fact1' => 1 } }, + 'bar' => { 'values' => { 'fact2' => 2 } }, + ) + expect(inventory).to receive(:add_facts) + .with(targets_obj['foo'], 'fact1' => 1) + .and_return('fact1' => 1) + expect(inventory).to receive(:add_facts) + .with(targets_obj['bar'], 'fact2' => 2) + .and_return('fact2' => 2) + + result = run_plan(plan_name, 'nodes' => targets_names) + expect(result).to be_ok + expect(result.value.class).to eq(Bolt::ResultSet) + expect(result.value).to eq(bolt_results('foo' => { 'values' => { 'fact1' => 1 } }, + 'bar' => { 'values' => { 'fact2' => 2 } })) + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 35a1408..9d5ab09 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,5 +1,9 @@ # frozen_string_literal: true +RSpec.configure do |c| + c.mock_with :rspec +end + require 'puppetlabs_spec_helper/module_spec_helper' require 'rspec-puppet-facts' @@ -54,3 +58,15 @@ def ensure_module_defined(module_name) end # 'spec_overrides' from sync.yml will appear below this line +# setup for Bolt spec tests +require 'bolt_spec/plans' +BoltSpec::Plans.init +include BoltSpec::Plans + +# setup the proper modulepath for Bolt +base_dir = File.dirname(File.expand_path(__FILE__)) +RSpec.configure do |c| + # should we just use rspec_puppet + c.add_setting :module_path + c.module_path = File.join(base_dir, 'fixtures', 'modules') +end diff --git a/spec/spec_helper_local.rb b/spec/spec_helper_local.rb new file mode 100644 index 0000000..345d36b --- /dev/null +++ b/spec/spec_helper_local.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +require 'spec_helper' + +# bolt_results({ +# 'foo' => { 'values' => { 'fact1' => 1 } }, +# 'bar' => { 'values' => { 'fact2' => 2 } })) +# +# - This accepts a Hash +# - Each key is the name of a target +# - Each value is a hash with a key 'values'. The 'values' key then contains +# a hash of the result data for that target. +def bolt_results(targets_values) + Bolt::ResultSet.new( + targets_values.map { |t, v| Bolt::Result.new(targets_obj[t], value: v) }, + ) +end + +# Converts an array of names into an array of Bolt::Target objects +def bolt_targets_arr(target_names_a) + target_names_a.map { |t| Bolt::Target.new(t) } +end + +# Converts an array of names into a hash where the keys are target names +# and the values are Bolt::Target objects +def bolt_targets_obj(target_names_a) + h = {} + target_names_a.each { |t| h[t] = Bolt::Target.new(t) } + h +end