We have extended the concept of provider specificity so it now includes both specified defaults and class depth, so:
* We are much more likely to choose the correct provider; e.g., 'init' will be chosen over 'base' * We're much less likely to print this warning, because it's only printed when provider specificities are equal which is much rarer lib/puppet/provider.rb | 4 ++-- lib/puppet/type.rb | 4 ++-- spec/unit/type.rb | 17 +++++++++++++++++ test/ral/manager/type.rb | 22 ---------------------- 4 files changed, 21 insertions(+), 26 deletions(-) Signed-off-by: Luke Kanies <[email protected]> --- lib/puppet/provider.rb | 4 ++-- lib/puppet/type.rb | 4 ++-- spec/unit/provider.rb | 31 +++++++++++++++++++++++++++++++ spec/unit/type.rb | 17 +++++++++++++++++ test/ral/manager/type.rb | 22 ---------------------- 5 files changed, 52 insertions(+), 26 deletions(-) create mode 100755 spec/unit/provider.rb diff --git a/lib/puppet/provider.rb b/lib/puppet/provider.rb index 1f13538..3cef0dd 100644 --- a/lib/puppet/provider.rb +++ b/lib/puppet/provider.rb @@ -91,8 +91,8 @@ class Puppet::Provider end end - def self.defaultnum - @defaults.length + def self.specificity + (@defaults.length * 100) + ancestors.select { |a| a.is_a? Class }.length end def self.initvars diff --git a/lib/puppet/type.rb b/lib/puppet/type.rb index d300338..fb3e780 100644 --- a/lib/puppet/type.rb +++ b/lib/puppet/type.rb @@ -1465,8 +1465,8 @@ class Type # If we don't have any default we use suitable providers defaults = suitable if defaults.empty? - max = defaults.collect { |provider| provider.defaultnum }.max - defaults = defaults.find_all { |provider| provider.defaultnum == max } + max = defaults.collect { |provider| provider.specificity }.max + defaults = defaults.find_all { |provider| provider.specificity == max } retval = nil if defaults.length > 1 diff --git a/spec/unit/provider.rb b/spec/unit/provider.rb new file mode 100755 index 0000000..9d78154 --- /dev/null +++ b/spec/unit/provider.rb @@ -0,0 +1,31 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../spec_helper' + +describe Puppet::Provider do + it "should have a specifity class method" do + Puppet::Provider.should respond_to(:specificity) + end + + it "should consider two defaults to be higher specificity than one default" do + one = Class.new(Puppet::Provider) + one.initvars + one.defaultfor :operatingsystem => "solaris" + + two = Class.new(Puppet::Provider) + two.initvars + two.defaultfor :operatingsystem => "solaris", :operatingsystemrelease => "5.10" + + two.specificity.should > one.specificity + end + + it "should consider a subclass more specific than its parent class" do + one = Class.new(Puppet::Provider) + one.initvars + + two = Class.new(one) + two.initvars + + two.specificity.should > one.specificity + end +end diff --git a/spec/unit/type.rb b/spec/unit/type.rb index a9e48a2..a2e9d2c 100755 --- a/spec/unit/type.rb +++ b/spec/unit/type.rb @@ -68,6 +68,23 @@ describe Puppet::Type do resource.tags = [:tag1,:tag2] end + describe "when choosing a default provider" do + it "should choose the provider with the highest specificity" do + # Make a fake type + type = Puppet::Type.newtype(:defaultprovidertest) do + newparam(:name) do end + end + + basic = type.provide(:basic) {} + greater = type.provide(:greater) {} + + basic.stubs(:specificity).returns 1 + greater.stubs(:specificity).returns 2 + + type.defaultprovider.should equal(greater) + end + end + describe "when initializing" do describe "and passed a TransObject" do it "should fail" do diff --git a/test/ral/manager/type.rb b/test/ral/manager/type.rb index 2624e26..30da6d1 100755 --- a/test/ral/manager/type.rb +++ b/test/ral/manager/type.rb @@ -307,28 +307,6 @@ class TestType < Test::Unit::TestCase assert_equal(path, file[:name], "Did not get correct name") end - # Make sure default providers behave correctly - def test_defaultproviders - # Make a fake type - type = Puppet::Type.newtype(:defaultprovidertest) do - newparam(:name) do end - end - - basic = type.provide(:basic) do - defaultfor :operatingsystem => :somethingelse, - :operatingsystemrelease => :yayness - end - - assert_equal(basic, type.defaultprovider) - type.defaultprovider = nil - - greater = type.provide(:greater) do - defaultfor :operatingsystem => Facter.value("operatingsystem") - end - - assert_equal(greater, type.defaultprovider) - end - # Make sure that we can have multiple non-isomorphic objects with the same name, # but not with isomorphic objects. def test_isomorphic_names -- 1.6.1 --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Puppet Developers" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/puppet-dev?hl=en -~----------~----~----~----~------~----~------~--~---
