[Pkg-puppet-devel] [facter] 243/352: (FACT-239) Expose resolution type controls

Stig Sandbeck Mathisen ssm at debian.org
Sun Apr 6 22:21:49 UTC 2014


This is an automated email from the git hooks/post-receive script.

ssm pushed a commit to branch master
in repository facter.

commit b93d261f7d9e8c1c3b9a4da9d0fcf4f0392e95fc
Author: Adrien Thebo <git at somethingsinistral.net>
Date:   Fri Jan 31 14:23:53 2014 -0800

    (FACT-239) Expose resolution type controls
    
    This commit exposes the ability to create different types of
    resolutions. When a resolution is being created the `:type` option can
    be specified, creating either a simple resolution (using `:type =>
    :simple`) or aggregate (using `:type => :aggregate`). If no type is
    given the type defaults to simple.
    
    If a resolution is redefined the requested type is compared against the
    currently existing resolution. If the types are mismatched an error will
    be raised since there's no particularly good way to resolve this
    discrepancy.
---
 lib/facter/core/aggregate.rb |  4 +++
 lib/facter/util/fact.rb      | 47 +++++++++++++++++++--------
 spec/unit/util/fact_spec.rb  | 77 +++++++++++++++++++++++++-------------------
 3 files changed, 81 insertions(+), 47 deletions(-)

diff --git a/lib/facter/core/aggregate.rb b/lib/facter/core/aggregate.rb
index 5637f94..948fad8 100644
--- a/lib/facter/core/aggregate.rb
+++ b/lib/facter/core/aggregate.rb
@@ -144,6 +144,10 @@ class Facter::Core::Aggregate
     end
   end
 
+  def resolution_type
+    :aggregate
+  end
+
   private
 
   # Evaluate the results of this aggregate.
diff --git a/lib/facter/util/fact.rb b/lib/facter/util/fact.rb
index 38d0418..587bd33 100644
--- a/lib/facter/util/fact.rb
+++ b/lib/facter/util/fact.rb
@@ -1,5 +1,6 @@
 require 'facter'
 require 'facter/util/resolution'
+require 'facter/core/aggregate'
 
 # This class represents a fact. Each fact has a name and multiple
 # {Facter::Util::Resolution resolutions}.
@@ -52,27 +53,23 @@ class Facter::Util::Fact
   # Define a new named resolution or return an existing resolution with
   # the given name.
   #
-  # @param resolve_name [String] The name of the resolve to define or look up
+  # @param resolution_name [String] The name of the resolve to define or look up
   # @param options [Hash] A hash of options to set on the resolution
   # @return [Facter::Util::Resolution]
   #
   # @api public
-  def define_resolution(resolve_name, options = {}, &block)
-    resolve = self.resolution(resolve_name)
+  def define_resolution(resolution_name, options = {}, &block)
 
-    if resolve.nil?
-      resolve = Facter::Util::Resolution.new(resolve_name, self)
-      resolve.set_options(options) unless options.empty?
+    resolution_type = options.delete(:type) || :simple
 
-      resolve.evaluate(&block) if block
-      @resolves << resolve
-    else
-      resolve.set_options(options) unless options.empty?
-      resolve.evaluate(&block) if block
-    end
+    resolve = create_or_return_resolution(resolution_name, resolution_type)
+
+    resolve.set_options(options) unless options.empty?
+    resolve.evaluate(&block) if block
 
+    resolve
   rescue => e
-    Facter.warn "Unable to add resolve #{resolve_name.inspect} for fact #{@name}: #{e}"
+    Facter.warn "Unable to add resolve #{resolution_name.inspect} for fact #{@name}: #{e}"
   end
 
   # Retrieve an existing resolution by name
@@ -184,4 +181,28 @@ class Facter::Util::Fact
   def normalize_value(value)
     value == "" ? nil : value
   end
+
+  def create_or_return_resolution(resolution_name, resolution_type)
+    resolve = self.resolution(resolution_name)
+
+    if resolve
+      if resolution_type != resolve.resolution_type
+        raise ArgumentError, "Cannot return resolution #{resolution_name} with type" +
+          " #{resolution_type}; already defined as #{resolve.resolution_type}"
+      end
+    else
+      case resolution_type
+      when :simple
+        resolve = Facter::Util::Resolution.new(resolution_name, self)
+      when :aggregate
+        resolve = Facter::Core::Aggregate.new(resolution_name, self)
+      else
+        raise ArgumentError, "Expected resolution type to be one of (:simple, :aggregate) but was #{resolution_type}"
+      end
+
+      @resolves << resolve
+    end
+
+    resolve
+  end
 end
diff --git a/spec/unit/util/fact_spec.rb b/spec/unit/util/fact_spec.rb
index 8c50e5b..f3aebef 100755
--- a/spec/unit/util/fact_spec.rb
+++ b/spec/unit/util/fact_spec.rb
@@ -13,8 +13,8 @@ describe Facter::Util::Fact do
     expect { Facter::Util::Fact.new }.to raise_error(ArgumentError)
   end
 
-  it "downcases the name and converts it to a symbol" do
-    Facter::Util::Fact.new("YayNess").name.should == :yayness
+  it "downcases and converts the name to a symbol" do
+    expect(Facter::Util::Fact.new("YayNess").name).to eq :yayness
   end
 
   it "issues a deprecation warning for use of ldapname" do
@@ -22,12 +22,10 @@ describe Facter::Util::Fact do
     Facter::Util::Fact.new("YayNess", :ldapname => "fooness")
   end
 
-  describe "when adding resolution mechanisms" do
-    it "instance_evals the passed block on the new resolution" do
-      fact.add {
-        setcode { "foo" }
-      }
-      expect(fact.value).to eq "foo"
+  describe "when adding resolution mechanisms using #add" do
+    it "delegates to #define_resolution with an anonymous resolution" do
+      subject.expects(:define_resolution).with(nil, {})
+      subject.add
     end
   end
 
@@ -47,7 +45,12 @@ describe Facter::Util::Fact do
 
   describe "adding resolution mechanisms by name" do
 
-    let(:res) { stub 'resolution', :name => 'named', :set_options => nil }
+    let(:res) do
+      stub 'resolution',
+        :name => 'named',
+        :set_options => nil,
+        :resolution_type => :simple
+    end
 
     it "creates a new resolution if no such resolution exists" do
       Facter::Util::Resolution.expects(:new).once.with('named', fact).returns(res)
@@ -57,6 +60,29 @@ describe Facter::Util::Fact do
       expect(fact.resolution('named')).to eq res
     end
 
+    it "creates a simple resolution when the type is nil" do
+      fact.define_resolution('named')
+      expect(fact.resolution('named')).to be_a_kind_of Facter::Util::Resolution
+    end
+
+    it "creates a simple resolution when the type is :simple" do
+      fact.define_resolution('named', :type => :simple)
+      expect(fact.resolution('named')).to be_a_kind_of Facter::Util::Resolution
+    end
+
+    it "creates an aggregate resolution when the type is :aggregate" do
+      fact.define_resolution('named', :type => :aggregate)
+      expect(fact.resolution('named')).to be_a_kind_of Facter::Core::Aggregate
+    end
+
+    it "raises an error if there is an existing resolution with a different type" do
+      pending "We need to stop rescuing all errors when instantiating resolutions"
+      fact.define_resolution('named')
+      expect {
+        fact.define_resolution('named', :type => :aggregate)
+      }.to raise_error(ArgumentError, /Cannot return resolution.*already defined as simple/)
+    end
+
     it "returns existing resolutions by name" do
       Facter::Util::Resolution.expects(:new).once.with('named', fact).returns(res)
 
@@ -68,10 +94,6 @@ describe Facter::Util::Fact do
   end
 
   describe "when returning a value" do
-    before do
-      fact = Facter::Util::Fact.new("yay")
-    end
-
     it "returns nil if there are no resolutions" do
       Facter::Util::Fact.new("yay").value.should be_nil
     end
@@ -112,28 +134,15 @@ describe Facter::Util::Fact do
     subject do
       Facter::Util::Fact.new(:foo)
     end
-    context 'basic facts using setcode' do
-      it "flushes the cached value when invoked" do
-        system = mock('some_system_call')
-        system.expects(:data).twice.returns(100,200)
 
-        subject.add { setcode { system.data } }
-        5.times { subject.value.should == 100 }
-        subject.flush
-        subject.value.should == 200
-      end
-    end
-    context 'facts using setcode and on_flush' do
-      it 'invokes the block passed to on_flush' do
-        model = { :data => "Hello World" }
-        subject.add do
-          on_flush { model[:data] = "FLUSHED!" }
-          setcode { model[:data] }
-        end
-        subject.value.should == "Hello World"
-        subject.flush
-        subject.value.should == "FLUSHED!"
-      end
+    it "invokes #flush on all resolutions" do
+      simple = subject.add(:type => :simple)
+      simple.expects(:flush)
+
+      aggregate = subject.add(:type => :aggregate)
+      aggregate.expects(:flush)
+
+      subject.flush
     end
   end
 end

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-puppet/facter.git



More information about the Pkg-puppet-devel mailing list