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
-~----------~----~----~----~------~----~------~--~---

Reply via email to