diff --git a/README.md b/README.md index e61e86ec..75c7473c 100644 --- a/README.md +++ b/README.md @@ -60,8 +60,8 @@ require 'spec_helper' describe 'myclass' do - on_supported_os.each do |os, facts| - context "on #{os}" do + on_supported_operatingsystem.each do |facts| + context "on #{facts[:operatingsystem]} #{facts[:operatingsystemmajrelease]}" do let(:facts) do facts end @@ -119,8 +119,8 @@ require 'spec_helper' describe Puppet::Type.type(:mytype) do - on_supported_os.each do |os, facts| - context "on #{os}" do + on_supported_operatingsystem.each do |facts| + context "on #{facts[:operatingsystem]} #{facts[:operatingsystemmajrelease]}" do before :each do Facter.clear facts.each do |k, v| @@ -184,8 +184,8 @@ require 'spec_helper' describe Puppet::Parser::Functions.function(:myfunction) do let(:scope) { PuppetlabsSpec::PuppetInternals.scope } - on_supported_os.each do |os, facts| - context "on #{os}" do + on_supported_operatingsystem.each do |facts| + context "on #{facts[:operatingsystem]} #{facts[:operatingsystemmajrelease]}" do before :each do facts.each do |k, v| scope.stubs(:lookupvar).with("::#{k}").returns(v) @@ -207,7 +207,7 @@ require 'spec_helper' describe 'myclass' do - on_supported_os({ + on_supported_operatingsystem({ :hardwaremodels => ['i386', 'x86_64'], :supported_os => [ { @@ -225,8 +225,8 @@ describe 'myclass' do ] } ], - }).each do |os, facts| - context "on #{os}" do + }).each do |facts| + context "on #{facts[:operatingsystem]} #{facts[:operatingsystemmajrelease]}" do let(:facts) do facts end @@ -246,8 +246,8 @@ require 'spec_helper' describe 'myclass' do - on_supported_os.each do |os, facts| - context "on #{os}" do + on_supported_operatingsystem.each do |facts| + context "on #{facts[:operatingsystem]} #{facts[:operatingsystemmajrelease]}" do let(:facts) do facts.merge({ :foo => 'bar', diff --git a/lib/rspec-puppet-facts.rb b/lib/rspec-puppet-facts.rb index effc8d06..d202dbba 100644 --- a/lib/rspec-puppet-facts.rb +++ b/lib/rspec-puppet-facts.rb @@ -8,30 +8,10 @@ # module's RSpec tests by looping through all supported # OS'es and their facts data which is received from the FacterDB. module RspecPuppetFacts - # Use the provided options or the data from the metadata.json file - # to find a set of matching facts in the FacterDB. - # OS names and facts can be used in the Puppet RSpec tests - # to run the examples against all supported facts combinations. - # - # The list of received OS facts can also be filtered by the SPEC_FACTS_OS - # environment variable. For example, if the variable is set to "debian" - # only the OS names which start with "debian" will be returned. It allows a - # user to quickly run the tests only on a single facts set without any - # file modifications. - # - # @return [Hash Hash>] - # @param [Hash] opts - # @option opts [String,Array] :hardwaremodels The OS architecture names, i.e. x86_64 - # @option opts [Array] :supported_os If this options is provided the data - # will be used instead of the "operatingsystem_support" section if the metadata file - # even if the file is missing. - def on_supported_os(opts = {}) - opts[:hardwaremodels] ||= ['x86_64'] - opts[:hardwaremodels] = [opts[:hardwaremodels]] unless opts[:hardwaremodels].is_a? Array - opts[:supported_os] ||= RspecPuppetFacts.meta_supported_os + def jgrep_filter(supported_os, opts) filter = [] - opts[:supported_os].map do |os_sup| + supported_os.map do |os_sup| if os_sup['operatingsystemrelease'] os_sup['operatingsystemrelease'].map do |operatingsystemmajrelease| opts[:hardwaremodels].each do |hardwaremodel| @@ -62,15 +42,63 @@ def on_supported_os(opts = {}) end end end + filter + end - received_facts = FacterDB::get_facts(filter) - unless received_facts.any? - RspecPuppetFacts.warning "No facts were found in the FacterDB for: #{filter.inspect}" - return {} + # Use the provided options or the data from the metadata.json file + # to find a set of matching facts in the FacterDB. + # OS names and facts can be used in the Puppet RSpec tests + # to run the examples against all supported facts combinations. + # + # The list of received OS facts can also be filtered by the SPEC_FACTS_OS + # environment variable. For example, if the variable is set to "debian" + # only the OS names which start with "debian" will be returned. It allows a + # user to quickly run the tests only on a single facts set without any + # file modifications. + # + # @return [Array] + # @param [Hash] opts + # @option opts [String,Array] :hardwaremodels The OS architecture names, i.e. x86_64 + # @option opts [Array] :supported_os If this options is provided the data + # will be used instead of the "operatingsystem_support" section if the metadata file + # even if the file is missing. + def on_supported_operatingsystem(opts = {}) + opts[:hardwaremodels] ||= ['x86_64'] + opts[:hardwaremodels] = [opts[:hardwaremodels]] unless opts[:hardwaremodels].is_a? Array + opts[:supported_os] ||= RspecPuppetFacts.meta_supported_os + + os_facts_array = [] + RspecPuppetFacts.facterdb_facts(jgrep_filter(opts[:supported_os], opts)).map do |facts| + next unless facts[:operatingsystem].downcase.start_with? RspecPuppetFacts.spec_facts_os_filter if RspecPuppetFacts.spec_facts_os_filter + os_facts_array << facts.merge(RspecPuppetFacts.common_facts) end + os_facts_array + end + + # Use the provided options or the data from the metadata.json file + # to find a set of matching facts in the FacterDB. + # OS names and facts can be used in the Puppet RSpec tests + # to run the examples against all supported facts combinations. + # + # The list of received OS facts can also be filtered by the SPEC_FACTS_OS + # environment variable. For example, if the variable is set to "debian" + # only the OS names which start with "debian" will be returned. It allows a + # user to quickly run the tests only on a single facts set without any + # file modifications. + # + # @return [Hash Hash>] + # @param [Hash] opts + # @option opts [String,Array] :hardwaremodels The OS architecture names, i.e. x86_64 + # @option opts [Array] :supported_os If this options is provided the data + # will be used instead of the "operatingsystem_support" section if the metadata file + # even if the file is missing. + def on_supported_os(opts = {}) + opts[:hardwaremodels] ||= ['x86_64'] + opts[:hardwaremodels] = [opts[:hardwaremodels]] unless opts[:hardwaremodels].is_a? Array + opts[:supported_os] ||= RspecPuppetFacts.meta_supported_os os_facts_hash = {} - received_facts.map do |facts| + RspecPuppetFacts.facterdb_facts(jgrep_filter(opts[:supported_os], opts)).map do |facts| os = "#{facts[:operatingsystem].downcase}-#{facts[:operatingsystemrelease].split('.')[0]}-#{facts[:hardwaremodel]}" next unless os.start_with? RspecPuppetFacts.spec_facts_os_filter if RspecPuppetFacts.spec_facts_os_filter facts.merge! RspecPuppetFacts.common_facts @@ -89,6 +117,15 @@ def self.spec_facts_os_filter ENV['SPEC_FACTS_OS'] end + def self.facterdb_facts(filter) + received_facts = FacterDB::get_facts(filter) + unless received_facts.any? + RspecPuppetFacts.warning "No facts were found in the FacterDB for: #{filter.inspect}" + return {} + end + received_facts + end + # These facts are common for all OS'es and will be # added to the facts retrieved from the FacterDB # @api private diff --git a/spec/rspec_puppet_facts_spec.rb b/spec/rspec_puppet_facts_spec.rb index e98067db..8f9f4297 100644 --- a/spec/rspec_puppet_facts_spec.rb +++ b/spec/rspec_puppet_facts_spec.rb @@ -6,10 +6,10 @@ 'spec/fixtures/metadata.json' end - describe '#on_supported_os' do + describe '#on_supported_operatingsystem' do context 'Without specifying supported_os' do - subject { on_supported_os } + subject { on_supported_operatingsystem } context 'Without metadata.json' do before(:each) do @@ -19,6 +19,338 @@ it { expect { subject }.to raise_error(StandardError, /Can't find metadata.json/) } end + context 'With a metadata.json' do + it 'can load the metadata file' do + allow(RspecPuppetFacts).to receive(:metadata_file).and_return(metadata_file) + RspecPuppetFacts.reset + expect(RspecPuppetFacts.metadata).to be_a Hash + expect(RspecPuppetFacts.metadata['name']).to eq 'mcanevet-mymodule' + end + + context 'With a valid metadata.json' do + let(:metadata) do + fixture = File.read(metadata_file) + JSON.parse fixture + end + + before :each do + allow(RspecPuppetFacts).to receive(:metadata).and_return(metadata) + end + + it 'should return a hash' do + is_expected.to be_a Array + end + + it 'should have 5 elements' do + expect(subject.size).to eq 5 + end + + it 'should return supported OS' do + expect(subject.map{|h| "#{h[:operatingsystem]}-#{h[:operatingsystemmajrelease]}"}).to eq %w( + Debian-6 + Debian-7 + RedHat-5 + RedHat-6 + RedHat-7 + ) + end + + it 'should be able to filter the received OS facts' do + allow(RspecPuppetFacts).to receive(:spec_facts_os_filter).and_return('redhat') + expect(subject.map{|h| "#{h[:operatingsystem]}-#{h[:operatingsystemmajrelease]}"}).to eq %w( + RedHat-5 + RedHat-6 + RedHat-7 + ) + end + end + + context 'With a broken metadata.json' do + before :each do + allow(RspecPuppetFacts).to receive(:metadata).and_return(metadata) + end + + context 'With a missing operatingsystem_support section' do + let(:metadata) do + {} + end + + it { expect { subject }.to raise_error(StandardError, /Unknown operatingsystem support/) } + end + + context 'With a wrong operatingsystem_support section' do + let(:metadata) do + { + 'operatingsystem_support' => 'Ubuntu', + } + end + + it { expect { subject }.to raise_error(StandardError, /Unknown operatingsystem support/) } + end + end + + end + end + + context 'When specifying supported_os' do + subject { + on_supported_operatingsystem( + { + :supported_os => [ + { + "operatingsystem" => "Debian", + "operatingsystemrelease" => [ + "6", + "7" + ] + }, + { + "operatingsystem" => "RedHat", + "operatingsystemrelease" => [ + "5", + "6" + ] + } + ] + } + ) + } + + it 'should return a hash' do + is_expected.to be_a Array + end + + it 'should have 4 elements' do + expect(subject.size).to eq 4 + end + + it 'should return supported OS' do + expect(subject.map{|h| "#{h[:operatingsystem]}-#{h[:operatingsystemmajrelease]}"}).to eq %w( + Debian-6 + Debian-7 + RedHat-5 + RedHat-6 + ) + end + + it 'should be able to filter the received OS facts' do + allow(RspecPuppetFacts).to receive(:spec_facts_os_filter).and_return('redhat') + expect(subject.map{|h| "#{h[:operatingsystem]}-#{h[:operatingsystemmajrelease]}"}).to eq %w( + RedHat-5 + RedHat-6 + ) + end + end + + context 'When testing Ubuntu' do + subject { + on_supported_operatingsystem( + { + :supported_os => [ + { + "operatingsystem" => "Ubuntu", + "operatingsystemrelease" => [ + "14.04", + "14.10", + "15.04", + "15.10", + "16.04", + ], + }, + ], + } + ) + } + it 'should return a hash' do + expect(subject.class).to eq Array + end + it 'should have 5 elements' do + expect(subject.size).to eq 5 + end + it 'should return supported OS' do + expect(subject.map{|h| "#{h[:operatingsystem]}-#{h[:operatingsystemmajrelease]}"}).to eq %w( + Ubuntu-14.04 + Ubuntu-14.10 + Ubuntu-15.04 + Ubuntu-15.10 + Ubuntu-16.04 + ) + end + end + + context 'When testing FreeBSD 10' do + subject { + on_supported_operatingsystem( + { + :supported_os => [ + { + "operatingsystem" => "FreeBSD", + "operatingsystemrelease" => [ + "10", + ], + }, + ], + } + ) + } + it 'should return a hash' do + expect(subject.class).to eq Array + end + it 'should have 1 elements' do + expect(subject.size).to eq 1 + end + it 'should return supported OS' do + expect(subject.map{|h| "#{h[:operatingsystem]}-#{h[:operatingsystemmajrelease]}"}).to eq %w( + FreeBSD-10 + ) + end + end + + context 'When testing OpenBSD 5.7' do + subject { + on_supported_operatingsystem( + { + :supported_os => [ + { + "operatingsystem" => "OpenBSD", + "operatingsystemrelease" => [ + "5.7", + ], + }, + ], + } + ) + } + it 'should return a hash' do + expect(subject.class).to eq Array + end + it 'should have 1 elements' do + expect(subject.size).to eq 1 + end + it 'should return supported OS' do + expect(subject.map{|h| "#{h[:operatingsystem]}-#{h[:operatingsystemmajrelease]}"}).to eq %w( + OpenBSD-5 + ) + end + end + + context 'When testing Windows 7', :if => Facter.version.to_f >= 2.4 do + subject { + on_supported_operatingsystem( + { + :supported_os => [ + { + "operatingsystem" => "windows", + "operatingsystemrelease" => [ + "7", + ], + }, + ], + } + ) + } + it 'should return a hash' do + expect(subject.class).to eq Array + end + it 'should have 1 elements' do + expect(subject.size).to eq 1 + end + it 'should return supported OS' do + expect(subject.map{|h| "#{h[:operatingsystem]}-#{h[:operatingsystemmajrelease]}"}).to eq %w( + windows-7 + ) + end + end + + context 'When operatingsystemrelease has space' do + subject { + on_supported_operatingsystem( + { + :supported_os => [ + { + "operatingsystem" => "SLES", + "operatingsystemrelease" => [ + "11 SP1" + ] + } + ] + } + ) + } + it 'should return a hash' do + expect(subject.class).to eq Array + end + it 'should have 1 elements' do + expect(subject.size).to eq 1 + end + it 'should return supported OS' do + expect(subject.map{|h| "#{h[:operatingsystem]}-#{h[:operatingsystemmajrelease]}"}).to eq %w( + SLES-11 + ) + end + end + + context 'When specifying wrong supported_os' do + subject { + on_supported_operatingsystem( + { + :supported_os => [ + { + "operatingsystem" => "Debian", + "operatingsystemrelease" => [ + "4", + ], + }, + ] + } + ) + } + + it 'should output warning message' do + expect(RspecPuppetFacts).to receive(:warning).with(/No facts were found in the FacterDB/) + subject + end + end + + context 'When specifying rolling release operating system' do + subject { + on_supported_operatingsystem( + { + :supported_os => [ + { + "operatingsystem" => "Debian", + "operatingsystemrelease" => [ + "8", + ], + }, + { + "operatingsystem" => "Archlinux", + }, + ] + } + ) + } + + it 'should return a hash' do + expect(subject.class).to eq Array + end + it 'should have 2 elements' do + expect(subject.size).to eq 2 + end + it 'should return supported OS' do + expect(subject.map{|h| "#{h[:operatingsystem]}-#{h[:operatingsystemmajrelease]}"}).to eq %w( + Archlinux-3 + Debian-8 + ) + end + end + end + + describe '#on_supported_os' do + + context 'Without specifying supported_os' do + subject { on_supported_os } + context 'With a metadata.json' do it 'can load the metadata file' do allow(RspecPuppetFacts).to receive(:metadata_file).and_return(metadata_file)