#! /usr/bin/env ruby require 'spec_helper' require_relative '../pops/parser/parser_rspec_helper' require 'puppet/resource/capability_finder' describe Puppet::Resource::CapabilityFinder do context 'when PuppetDB is not configured' do it 'should error' do Puppet::Util.expects(:const_defined?).with('Puppetdb').returns false expect { Puppet::Resource::CapabilityFinder.find('production', nil, nil) }.to raise_error(/PuppetDB is not available/) end end context 'when PuppetDB is configured' do around(:each) do |example| mock_pdb = !Puppet::Util.const_defined?('Puppetdb') if mock_pdb module Puppet::Util::Puppetdb class Http; end end end begin Puppet::Parser::Compiler.any_instance.stubs(:loaders).returns(loaders) Puppet.override(:loaders => loaders, :current_environment => env) do make_cap_type example.run end ensure Puppet::Util.send(:remove_const, 'Puppetdb') if mock_pdb Puppet::Type.rmtype(:cap) Puppet::Pops::Loaders.clear end end let(:env) { Puppet::Node::Environment.create(:testing, []) } let(:loaders) { Puppet::Pops::Loaders.new(env) } let(:response_body) { [{"type"=>"Cap", "title"=>"cap", "parameters"=>{"host"=>"ahost"}}] } let(:response) { stub('response', :body => response_body.to_json) } def make_cap_type Puppet::Type.newtype :cap, :is_capability => true do newparam :name newparam :host end end describe "when query_puppetdb method is available" do it 'should call use the query_puppetdb method if available' do Puppet::Util::Puppetdb.expects(:query_puppetdb).returns(response_body) Puppet::Util::Puppetdb::Http.expects(:action).never result = Puppet::Resource::CapabilityFinder.find('production', nil, Puppet::Resource.new('Cap', 'cap')) expect(result['host']).to eq('ahost') end end describe "when query_puppetdb method is unavailable" do before :each do Puppet::Util::Puppetdb.stubs(:respond_to?).with(:query_puppetdb).returns false end it 'should call Puppet::Util::PuppetDB::Http.action' do Puppet::Util::Puppetdb::Http.expects(:action).returns(response) result = Puppet::Resource::CapabilityFinder.find('production', nil, Puppet::Resource.new('Cap', 'cap')) expect(result['host']).to eq('ahost') end end describe '#find' do let(:capability) { Puppet::Resource.new('Cap', 'cap') } let(:code_id) { 'b59e5df0578ef411f773ee6c33d8073c50e7b8fe' } it 'should search for the resource without including code_id or environment' do resources = [{"type"=>"Cap", "title"=>"cap", "parameters"=>{"host"=>"ahost"}}] Puppet::Resource::CapabilityFinder.stubs(:search).with(nil, nil, capability).returns resources result = Puppet::Resource::CapabilityFinder.find('production', code_id, Puppet::Resource.new('Cap', 'cap')) expect(result['host']).to eq('ahost') end it 'should return nil if no resource is found' do Puppet::Resource::CapabilityFinder.stubs(:search).with(nil, nil, capability).returns [] result = Puppet::Resource::CapabilityFinder.find('production', code_id, capability) expect(result).to be_nil end describe 'when multiple results are returned for different environments' do let(:resources) do [{"type"=>"Cap", "title"=>"cap", "parameters"=>{"host"=>"ahost"}, "tags"=>["producer:production"]}, {"type"=>"Cap", "title"=>"cap", "parameters"=>{"host"=>"bhost"}, "tags"=>["producer:other_env"]}] end before :each do Puppet::Resource::CapabilityFinder.stubs(:search).with(nil, nil, capability).returns resources end it 'should return the resource matching environment' do result = Puppet::Resource::CapabilityFinder.find('production', code_id, capability) expect(result['host']).to eq('ahost') end it 'should return nil if no resource matches environment' do result = Puppet::Resource::CapabilityFinder.find('bad_env', code_id, capability) expect(result).to be_nil end end describe 'when multiple results are returned for the same environment' do let(:resources) do [{"type"=>"Cap", "title"=>"cap", "parameters"=>{"host"=>"ahost"}, "tags"=>["producer:production"]}, {"type"=>"Cap", "title"=>"cap", "parameters"=>{"host"=>"bhost"}, "tags"=>["producer:production"]}] end before :each do Puppet::Resource::CapabilityFinder.stubs(:search).with(nil, nil, capability).returns resources end it 'should return the resource matching code_id' do Puppet::Resource::CapabilityFinder.stubs(:search).with('production', code_id, capability).returns [{"type"=>"Cap", "title"=>"cap", "parameters"=>{"host"=>"chost"}}] result = Puppet::Resource::CapabilityFinder.find('production', code_id, capability) expect(result['host']).to eq('chost') end it 'should return nil if no resource matches code_id' do Puppet::Resource::CapabilityFinder.stubs(:search).with('production', code_id, capability).returns [] result = Puppet::Resource::CapabilityFinder.find('production', code_id, capability) expect(result).to be_nil end it 'should fail if multiple resources match code_id' do Puppet::Resource::CapabilityFinder.stubs(:search).with('production', code_id, capability).returns resources expect { Puppet::Resource::CapabilityFinder.find('production', code_id, capability) }.to raise_error(Puppet::DevError, /expected exactly one resource/) end it 'should fail if no code_id was specified' do Puppet::Resource::CapabilityFinder.stubs(:search).with('production', nil, capability).returns resources expect { Puppet::Resource::CapabilityFinder.find('production', nil, capability) }.to raise_error(Puppet::DevError, /expected exactly one resource/) end end end end end