[Pkg-puppet-devel] [facter] 169/352: (FACT-65) Extract Resolvable and Suitable mixins

Stig Sandbeck Mathisen ssm at debian.org
Sun Apr 6 22:21:42 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 8f45e7193ba4231f54e112c8bc9ae111e700c2be
Author: Adrien Thebo <git at somethingsinistral.net>
Date:   Tue Jan 7 13:59:20 2014 -0800

    (FACT-65) Extract Resolvable and Suitable mixins
    
    The Facter::Util::Resolution class contained behavior for determining if
    a resolution was suitable, the precedence of the resolution, code for
    safely resolving values, and code for actually resolving information.
    This commit breaks up the Resolution class into a Suitable mixin for
    determining if a resolution can run and the precedence of that
    resolution, and a Resolvable mixin for handling behavior around the
    resolution of a given fact.
---
 lib/facter/core/resolvable.rb     |  96 ++++++++++++++++++
 lib/facter/core/suitable.rb       |  80 +++++++++++++++
 lib/facter/util/resolution.rb     | 178 ++++-----------------------------
 spec/unit/core/resolvable_spec.rb | 116 ++++++++++++++++++++++
 spec/unit/core/suitable_spec.rb   |  70 +++++++++++++
 spec/unit/util/resolution_spec.rb | 202 +-------------------------------------
 6 files changed, 384 insertions(+), 358 deletions(-)

diff --git a/lib/facter/core/resolvable.rb b/lib/facter/core/resolvable.rb
new file mode 100644
index 0000000..420e0ab
--- /dev/null
+++ b/lib/facter/core/resolvable.rb
@@ -0,0 +1,96 @@
+require 'timeout'
+
+# The resolvable mixin defines behavior for evaluating and returning fact
+# resolutions.
+#
+# Classes including this mixin should implement at #name method describing
+# the value being resolved and a #resolve_value that actually executes the code
+# to resolve the value.
+module Facter::Core::Resolvable
+
+  # The timeout, in seconds, for evaluating this resolution.
+  # @return [Integer]
+  # @api public
+  attr_accessor :timeout
+
+  # Return the timeout period for resolving a value.
+  # (see #timeout)
+  # @return [Numeric]
+  # @comment requiring 'timeout' stdlib class causes Object#timeout to be
+  #   defined which delegates to Timeout.timeout. This method may potentially
+  #   overwrite the #timeout attr_reader on this class, so we define #limit to
+  #   avoid conflicts.
+  def limit
+    @timeout || 0
+  end
+
+  ##
+  # on_flush accepts a block and executes the block when the resolution's value
+  # is flushed.  This makes it possible to model a single, expensive system
+  # call inside of a Ruby object and then define multiple dynamic facts which
+  # resolve by sending messages to the model instance.  If one of the dynamic
+  # facts is flushed then it can, in turn, flush the data stored in the model
+  # instance to keep all of the dynamic facts in sync without making multiple,
+  # expensive, system calls.
+  #
+  # Please see the Solaris zones fact for an example of how this feature may be
+  # used.
+  #
+  # @see Facter::Util::Fact#flush
+  # @see Facter::Util::Resolution#flush
+  #
+  # @api public
+  def on_flush(&block)
+    @on_flush_block = block
+  end
+
+  ##
+  # flush executes the block, if any, stored by the {on_flush} method
+  #
+  # @see Facter::Util::Fact#flush
+  # @see Facter::Util::Resolution#on_flush
+  #
+  # @api private
+  def flush
+    @on_flush_block.call if @on_flush_block
+  end
+
+  def value
+    result = nil
+
+    with_timing do
+      Timeout.timeout(limit) do
+        result = resolve_value
+      end
+    end
+
+    Facter::Util::Normalization.normalize(result)
+
+  rescue Timeout::Error => detail
+    Facter.warn "Timed out seeking value for #{self.name}"
+
+    # This call avoids zombies -- basically, create a thread that will
+    # dezombify all of the child processes that we're ignoring because
+    # of the timeout.
+    Thread.new { Process.waitall }
+    return nil
+  rescue Facter::Util::Normalization::NormalizationError => e
+    Facter.warn "Fact resolution #{self.name} resolved to an invalid value: #{e.message}"
+    return nil
+  rescue => details
+    Facter.warn "Could not retrieve #{self.name}: #{details.message}"
+    return nil
+  end
+
+  private
+
+  def with_timing
+    starttime = Time.now.to_f
+
+    yield
+
+    finishtime = Time.now.to_f
+    ms = (finishtime - starttime) * 1000
+    Facter.show_time "#{self.name}: #{"%.2f" % ms}ms"
+  end
+end
diff --git a/lib/facter/core/suitable.rb b/lib/facter/core/suitable.rb
new file mode 100644
index 0000000..3f4a7bc
--- /dev/null
+++ b/lib/facter/core/suitable.rb
@@ -0,0 +1,80 @@
+require 'facter'
+
+# The Suitable mixin provides mechanisms for confining objects to run on
+# certain platforms and determining the run precedence of these objects.
+#
+# Classes that include the Suitable mixin should define a `#confines` method
+# that returns an Array of zero or more Facter::Util::Confine objects.
+module Facter::Core::Suitable
+
+  attr_writer :weight
+
+  # Sets the weight of this resolution. If multiple suitable resolutions
+  # are found, the one with the highest weight will be used.  If weight
+  # is not given, the number of confines set on a resolution will be
+  # used as its weight (so that the most specific resolution is used).
+  #
+  # @param weight [Integer] the weight of this resolution
+  #
+  # @return [void]
+  #
+  # @api public
+  def has_weight(weight)
+    @weight = weight
+  end
+
+  # Sets the conditions for this resolution to be used. This takes a
+  # hash of fact names and values. Every fact must match the values
+  # given for that fact, otherwise this resolution will not be
+  # considered suitable. The values given for a fact can be an array, in
+  # which case the value of the fact must be in the array for it to
+  # match.
+  #
+  # @param confines [Hash{String => Object}] a hash of facts and the
+  #   values they should have in order for this resolution to be
+  #   used
+  #
+  # @example Confining to Linux
+  #     Facter.add(:powerstates) do
+  #       # This resolution only makes sense on linux systems
+  #       confine :kernel => "Linux"
+  #       setcode do
+  #         Facter::Util::Resolution.exec('cat /sys/power/states')
+  #       end
+  #     end
+  #
+  # @return [void]
+  #
+  # @api public
+  def confine(confines)
+    confines.each do |fact, values|
+      @confines.push Facter::Util::Confine.new(fact, *values)
+    end
+  end
+
+  # Returns the importance of this resolution. If the weight was not
+  # given, the number of confines is used instead (so that a more
+  # specific resolution wins over a less specific one).
+  #
+  # @return [Integer] the weight of this resolution
+  #
+  # @api private
+  def weight
+    if @weight
+      @weight
+    else
+      @confines.length
+    end
+  end
+
+  # Is this resolution mechanism suitable on the system in question?
+  #
+  # @api private
+  def suitable?
+    unless defined? @suitable
+      @suitable = ! @confines.detect { |confine| ! confine.true? }
+    end
+
+    return @suitable
+  end
+end
diff --git a/lib/facter/util/resolution.rb b/lib/facter/util/resolution.rb
index 4129309..6bb4842 100644
--- a/lib/facter/util/resolution.rb
+++ b/lib/facter/util/resolution.rb
@@ -2,8 +2,8 @@ require 'facter/util/confine'
 require 'facter/util/config'
 require 'facter/util/normalization'
 require 'facter/core/execution'
-
-require 'timeout'
+require 'facter/core/resolvable'
+require 'facter/core/suitable'
 
 # This represents a fact resolution. A resolution is a concrete
 # implementation of a fact. A single fact can have many resolutions and
@@ -17,23 +17,9 @@ require 'timeout'
 #
 # @api public
 class Facter::Util::Resolution
-  # The timeout, in seconds, for evaluating this resolution. The default
-  # is 0 which is equivalent to no timeout. This can be set using the
-  # options hash argument to {Facter.add}.
-  # @return [Integer]
-  # @api public
-  attr_accessor :timeout
-
-  # @!attribute [rw] name
-  # The name of this resolution. The resolution name should be unique with
-  # respect to the given fact.
-  # @return [String]
-  # @api public
-  attr_accessor :name
-
   # @api private
   attr_accessor :code
-  attr_writer :value, :weight
+  attr_writer :value
 
   INTERPRETER = Facter::Util::Config.is_windows? ? "cmd.exe" : "/bin/sh"
 
@@ -48,48 +34,15 @@ class Facter::Util::Resolution
     public :search_paths, :which, :absolute_path?, :expand_command, :with_env, :exec
   end
 
-  # Sets the conditions for this resolution to be used. This takes a
-  # hash of fact names and values. Every fact must match the values
-  # given for that fact, otherwise this resolution will not be
-  # considered suitable. The values given for a fact can be an array, in
-  # which case the value of the fact must be in the array for it to
-  # match.
-  #
-  # @param confines [Hash{String => Object}] a hash of facts and the
-  #   values they should have in order for this resolution to be
-  #   used
-  #
-  # @example Confining to Linux
-  #     Facter.add(:powerstates) do
-  #       # This resolution only makes sense on linux systems
-  #       confine :kernel => "Linux"
-  #       setcode do
-  #         Facter::Util::Resolution.exec('cat /sys/power/states')
-  #       end
-  #     end
-  #
-  # @return [void]
-  #
-  # @api public
-  def confine(confines)
-    confines.each do |fact, values|
-      @confines.push Facter::Util::Confine.new(fact, *values)
-    end
-  end
+  include Facter::Core::Resolvable
+  include Facter::Core::Suitable
 
-  # Sets the weight of this resolution. If multiple suitable resolutions
-  # are found, the one with the highest weight will be used.  If weight
-  # is not given, the number of confines set on a resolution will be
-  # used as its weight (so that the most specific resolution is used).
-  #
-  # @param weight [Integer] the weight of this resolution
-  #
-  # @return [void]
-  #
+  # @!attribute [rw] name
+  # The name of this resolution. The resolution name should be unique with
+  # respect to the given fact.
+  # @return [String]
   # @api public
-  def has_weight(weight)
-    @weight = weight
-  end
+  attr_accessor :name
 
   # Create a new resolution mechanism.
   #
@@ -127,30 +80,6 @@ class Facter::Util::Resolution
     end
   end
 
-  # Returns the importance of this resolution. If the weight was not
-  # given, the number of confines is used instead (so that a more
-  # specific resolution wins over a less specific one).
-  #
-  # @return [Integer] the weight of this resolution
-  #
-  # @api private
-  def weight
-    if @weight
-      @weight
-    else
-      @confines.length
-    end
-  end
-
-  # (see #timeout)
-  # This is another name for {#timeout}.
-  # @comment We need this as a getter for 'timeout', because some versions
-  #   of ruby seem to already have a 'timeout' method and we can't
-  #   seem to override the instance methods, somehow.
-  def limit
-    @timeout
-  end
-
   # Sets the code block or external program that will be evaluated to
   # get the value of the fact.
   #
@@ -181,37 +110,6 @@ class Facter::Util::Resolution
     end
   end
 
-  ##
-  # on_flush accepts a block and executes the block when the resolution's value
-  # is flushed.  This makes it possible to model a single, expensive system
-  # call inside of a Ruby object and then define multiple dynamic facts which
-  # resolve by sending messages to the model instance.  If one of the dynamic
-  # facts is flushed then it can, in turn, flush the data stored in the model
-  # instance to keep all of the dynamic facts in sync without making multiple,
-  # expensive, system calls.
-  #
-  # Please see the Solaris zones fact for an example of how this feature may be
-  # used.
-  #
-  # @see Facter::Util::Fact#flush
-  # @see Facter::Util::Resolution#flush
-  #
-  # @api public
-  def on_flush(&block)
-    @on_flush_block = block
-  end
-
-  ##
-  # flush executes the block, if any, stored by the {on_flush} method
-  #
-  # @see Facter::Util::Fact#flush
-  # @see Facter::Util::Resolution#on_flush
-  #
-  # @api private
-  def flush
-    @on_flush_block.call if @on_flush_block
-  end
-
   # @deprecated
   def interpreter
     Facter.warnonce "The 'Facter::Util::Resolution.interpreter' method is deprecated and will be removed in a future version."
@@ -224,62 +122,22 @@ class Facter::Util::Resolution
     @interpreter = interp
   end
 
-  # Is this resolution mechanism suitable on the system in question?
-  #
-  # @api private
-  def suitable?
-    if @suitable.nil?
-      @suitable = @confines.all? { |confine| confine.true? }
-    end
-
-    return @suitable
-  end
-
   # (see value)
   # @deprecated
   def to_s
     return self.value()
   end
 
-  # Evaluates the code block or external program to get the value of the
-  # fact.
-  #
-  # @api private
-  def value
-    return @value if @value
-    result = nil
-    return result if @code == nil
-
-    starttime = Time.now.to_f
+  private
 
-    begin
-      Timeout.timeout(limit) do
-        if @code.is_a?(Proc)
-          result = @code.call()
-        else
-          result = Facter::Util::Resolution.exec(@code)
-        end
-      end
-    rescue Timeout::Error => detail
-      Facter.warn "Timed out seeking value for %s" % self.name
+  def resolve_value
+    return @value if @value
+    return nil if @code.nil?
 
-      # This call avoids zombies -- basically, create a thread that will
-      # dezombify all of the child processes that we're ignoring because
-      # of the timeout.
-      Thread.new { Process.waitall }
-      return nil
-    rescue => details
-      Facter.warn "Could not retrieve %s: %s" % [self.name, details]
-      return nil
+    if @code.is_a? Proc
+      @code.call()
+    else
+      Facter::Util::Resolution.exec(@code)
     end
-
-    finishtime = Time.now.to_f
-    ms = (finishtime - starttime) * 1000
-    Facter.show_time "#{self.name}: #{"%.2f" % ms}ms"
-
-    Facter::Util::Normalization.normalize(result)
-  rescue Facter::Util::Normalization::NormalizationError => e
-    Facter.warn "Fact resolution #{self.name} resolved to an invalid value: #{e.message}"
-    nil
   end
 end
diff --git a/spec/unit/core/resolvable_spec.rb b/spec/unit/core/resolvable_spec.rb
new file mode 100644
index 0000000..69d9c33
--- /dev/null
+++ b/spec/unit/core/resolvable_spec.rb
@@ -0,0 +1,116 @@
+require 'spec_helper'
+require 'facter/core/resolvable'
+
+describe Facter::Core::Resolvable do
+
+  class ResolvableClass
+    def initialize(name)
+      @name = name
+    end
+    attr_accessor :name, :resolve_value
+    include Facter::Core::Resolvable
+  end
+
+  subject { ResolvableClass.new('resolvable') }
+
+  it "has a default timeout of 0 seconds" do
+    expect(subject.limit).to eq 0
+  end
+
+  it "can specify a custom timeout" do
+    subject.timeout = 10
+    expect(subject.limit).to eq 10
+  end
+
+  describe "generating a value" do
+    let(:fact_value) { "" }
+
+    let(:utf16_string) do
+      if String.method_defined?(:encode) && defined?(::Encoding)
+        fact_value.encode(Encoding::UTF_16LE).freeze
+      else
+        [0x00, 0x00].pack('C*').freeze
+      end
+    end
+
+    let(:expected_value) do
+      if String.method_defined?(:encode) && defined?(::Encoding)
+        fact_value.encode(Encoding::UTF_8).freeze
+      else
+        [0x00, 0x00].pack('C*').freeze
+      end
+    end
+
+    it "returns the results of #resolve_value" do
+      subject.resolve_value = 'stuff'
+      expect(subject.value).to eq 'stuff'
+    end
+
+    it "normalizes the resolved value" do
+      subject.resolve_value = fact_value
+      expect(subject.value).to eq(expected_value)
+    end
+
+    it "returns nil if an exception was raised" do
+      subject.expects(:resolve_value).raises RuntimeError, "kaboom!"
+      expect(subject.value).to eq nil
+    end
+
+    it "logs a warning if an exception was raised" do
+      subject.expects(:resolve_value).raises RuntimeError, "kaboom!"
+      Facter.expects(:warn).with('Could not retrieve resolvable: kaboom!')
+      expect(subject.value).to eq nil
+    end
+  end
+
+  describe "timing out" do
+    it "uses #limit instead of #timeout to determine the timeout period" do
+      subject.expects(:timeout).never
+      subject.expects(:limit).returns 25
+
+      Timeout.expects(:timeout).with(25)
+      subject.value
+    end
+
+    it "times out after the provided timeout" do
+      def subject.resolve_value
+        sleep 2
+      end
+      subject.timeout = 0.1
+      subject.value
+    end
+
+    it "returns nil if the timeout was reached" do
+      Timeout.expects(:timeout).raises Timeout::Error
+
+      expect(subject.value).to be_nil
+    end
+
+
+    it "starts a thread to wait on all child processes if the timeout was reached" do
+      Thread.expects(:new).yields
+      Process.expects(:waitall)
+
+      Timeout.expects(:timeout).raises Timeout::Error
+
+      subject.value
+    end
+  end
+
+  describe 'callbacks when flushing facts' do
+    class FlushFakeError < StandardError; end
+
+    context '#on_flush' do
+      it 'accepts a block with on_flush' do
+        subject.on_flush() { raise NotImplementedError }
+      end
+    end
+
+    context '#flush' do
+      it 'calls the block passed to on_flush' do
+        subject.on_flush() { raise FlushFakeError }
+        expect { subject.flush }.to raise_error FlushFakeError
+      end
+    end
+  end
+end
diff --git a/spec/unit/core/suitable_spec.rb b/spec/unit/core/suitable_spec.rb
new file mode 100644
index 0000000..feadb41
--- /dev/null
+++ b/spec/unit/core/suitable_spec.rb
@@ -0,0 +1,70 @@
+require 'spec_helper'
+require 'facter/core/suitable'
+
+describe Facter::Core::Suitable do
+
+  class SuitableClass
+    def initialize
+      @confines = []
+    end
+    attr_reader :confines
+    include Facter::Core::Suitable
+  end
+
+  subject { SuitableClass.new }
+
+  it "can add confines" do
+    subject.confine :kernel => 'Linux'
+  end
+
+  it "creates a Facter::Util::Confine object for the confine call" do
+    subject.confine :kernel => 'Linux'
+    conf = subject.confines.first
+    expect(conf).to be_a_kind_of Facter::Util::Confine
+    expect(conf.fact).to eq :kernel
+    expect(conf.values).to eq ['Linux']
+  end
+
+  describe "determining weight" do
+    it "is zero if no confines are set" do
+      expect(subject.weight).to eq 0
+    end
+
+    it "defaults to the number of confines" do
+      subject.confine :kernel => 'Linux'
+      expect(subject.weight).to eq 1
+    end
+
+    it "can be explicitly set" do
+      subject.has_weight 10
+      expect(subject.weight).to eq 10
+    end
+
+    it "prefers an explicit weight over the number of confines" do
+      subject.confine :kernel => 'Linux'
+      subject.has_weight 11
+      expect(subject.weight).to eq 11
+    end
+  end
+
+  describe "determining suitability" do
+    it "is true if all confines for the object evaluate to true" do
+      subject.confine :kernel => 'Linux'
+      subject.confine :operatingsystem => 'Redhat'
+
+      subject.confines.each { |confine| confine.stubs(:true?).returns true }
+
+      expect(subject).to be_suitable
+    end
+
+    it "is false if any confines for the object evaluate to false" do
+      subject.confine :kernel => 'Linux'
+      subject.confine :operatingsystem => 'Redhat'
+
+      subject.confines.first.stubs(:true?).returns true
+      subject.confines.first.stubs(:true?).returns false
+
+      expect(subject).to_not be_suitable
+    end
+  end
+end
diff --git a/spec/unit/util/resolution_spec.rb b/spec/unit/util/resolution_spec.rb
index a6b954e..4e4b3f9 100755
--- a/spec/unit/util/resolution_spec.rb
+++ b/spec/unit/util/resolution_spec.rb
@@ -6,11 +6,11 @@ require 'facter/util/resolution'
 describe Facter::Util::Resolution do
   include FacterSpec::ConfigHelper
 
-  it "should require a name" do
-    lambda { Facter::Util::Resolution.new }.should raise_error(ArgumentError)
+  it "requires a name" do
+    expect { Facter::Util::Resolution.new }.to raise_error(ArgumentError)
   end
 
-  it "should have a name" do
+  it "can return its name" do
     Facter::Util::Resolution.new("yay").name.should == "yay"
   end
 
@@ -20,22 +20,6 @@ describe Facter::Util::Resolution do
     resolve.value.should == "foo"
   end
 
-  it "should have a method for setting the weight" do
-    Facter::Util::Resolution.new("yay").should respond_to(:has_weight)
-  end
-
-  it "should have a method for setting the code" do
-    Facter::Util::Resolution.new("yay").should respond_to(:setcode)
-  end
-
-  it "should support a timeout value" do
-    Facter::Util::Resolution.new("yay").should respond_to(:timeout=)
-  end
-
-  it "should default to a timeout of 0 seconds" do
-    Facter::Util::Resolution.new("yay").limit.should == 0
-  end
-
   it "should default to nil for code" do
     Facter::Util::Resolution.new("yay").code.should be_nil
   end
@@ -45,12 +29,6 @@ describe Facter::Util::Resolution do
     Facter::Util::Resolution.new("yay").interpreter.should be_nil
   end
 
-  it "should provide a 'limit' method that returns the timeout" do
-    res = Facter::Util::Resolution.new("yay")
-    res.timeout = "testing"
-    res.limit.should == "testing"
-  end
-
   describe "when setting the code" do
     before do
       Facter.stubs(:warnonce)
@@ -91,54 +69,11 @@ describe Facter::Util::Resolution do
     end
 
     it "should fail if neither a string nor block has been provided" do
-      lambda { @resolve.setcode }.should raise_error(ArgumentError)
-    end
-  end
-
-  describe 'callbacks when flushing facts' do
-    class FlushFakeError < StandardError; end
-
-    subject do
-      Facter::Util::Resolution.new("jeff")
-    end
-
-    context '#on_flush' do
-      it 'accepts a block with on_flush' do
-        subject.on_flush() { raise NotImplementedError }
-      end
-    end
-
-    context '#flush' do
-      it 'calls the block passed to on_flush' do
-        subject.on_flush() { raise FlushFakeError }
-        expect { subject.flush }.to raise_error FlushFakeError
-      end
+      expect { @resolve.setcode }.to raise_error(ArgumentError)
     end
   end
 
-  it "should be able to return a value" do
-    Facter::Util::Resolution.new("yay").should respond_to(:value)
-  end
-
   describe "when returning the value" do
-    let(:fact_value) { "" }
-
-    let(:utf16_string) do
-      if String.method_defined?(:encode) && defined?(::Encoding)
-        fact_value.encode(Encoding::UTF_16LE).freeze
-      else
-        [0x00, 0x00].pack('C*').freeze
-      end
-    end
-
-    let(:expected_value) do
-      if String.method_defined?(:encode) && defined?(::Encoding)
-        fact_value.encode(Encoding::UTF_8).freeze
-      else
-        [0x00, 0x00].pack('C*').freeze
-      end
-    end
-
     before do
       @resolve = Facter::Util::Resolution.new("yay")
     end
@@ -167,14 +102,6 @@ describe Facter::Util::Resolution do
 
           @resolve.value.should == "yup"
         end
-
-        it "it normalizes the resolved value" do
-          @resolve.setcode "/bin/foo"
-
-          Facter::Util::Resolution.expects(:exec).once.returns(utf16_string)
-
-          expect(@resolve.value).to eq(expected_value)
-        end
       end
 
       describe "on non-windows systems" do
@@ -188,14 +115,6 @@ describe Facter::Util::Resolution do
 
           @resolve.value.should == "yup"
         end
-
-        it "it normalizes the resolved value" do
-          @resolve.setcode "/bin/foo"
-
-          Facter::Util::Resolution.expects(:exec).once.returns(utf16_string)
-
-          expect(@resolve.value).to eq(expected_value)
-        end
       end
     end
 
@@ -210,41 +129,6 @@ describe Facter::Util::Resolution do
         @resolve.setcode { "yayness" }
         @resolve.value.should == "yayness"
       end
-
-      it "it normalizes the resolved value" do
-        @resolve.setcode { utf16_string }
-
-        expect(@resolve.value).to eq(expected_value)
-      end
-
-      it "should use its limit method to determine the timeout, to avoid conflict when a 'timeout' method exists for some other reason" do
-        @resolve.expects(:timeout).never
-        @resolve.expects(:limit).returns "foo"
-        Timeout.expects(:timeout).with("foo")
-
-        @resolve.setcode { sleep 2; "raise This is a test"}
-        @resolve.value
-      end
-
-      it "should timeout after the provided timeout" do
-        Facter.expects(:warn)
-        @resolve.timeout = 0.1
-        @resolve.setcode { sleep 2; raise "This is a test" }
-        Thread.expects(:new).yields
-
-        @resolve.value.should be_nil
-      end
-
-      it "should waitall to avoid zombies if the timeout is exceeded" do
-        Facter.stubs(:warn)
-        @resolve.timeout = 0.1
-        @resolve.setcode { sleep 2; raise "This is a test" }
-
-        Thread.expects(:new).yields
-        Process.expects(:waitall)
-
-        @resolve.value
-      end
     end
   end
 
@@ -254,84 +138,6 @@ describe Facter::Util::Resolution do
     @resolve.to_s.should == "myval"
   end
 
-  it "should allow the adding of confines" do
-    Facter::Util::Resolution.new("yay").should respond_to(:confine)
-  end
-
-  it "should provide a method for returning the number of confines" do
-    @resolve = Facter::Util::Resolution.new("yay")
-    @resolve.confine "one" => "foo", "two" => "fee"
-    @resolve.weight.should == 2
-  end
-
-  it "should return 0 confines when no confines have been added" do
-    Facter::Util::Resolution.new("yay").weight.should == 0
-  end
-
-  it "should provide a way to set the weight" do
-    @resolve = Facter::Util::Resolution.new("yay")
-    @resolve.has_weight(45)
-    @resolve.weight.should == 45
-  end
-
-  it "should allow the weight to override the number of confines" do
-    @resolve = Facter::Util::Resolution.new("yay")
-    @resolve.confine "one" => "foo", "two" => "fee"
-    @resolve.weight.should == 2
-    @resolve.has_weight(45)
-    @resolve.weight.should == 45
-  end
-
-  it "should have a method for determining if it is suitable" do
-    Facter::Util::Resolution.new("yay").should respond_to(:suitable?)
-  end
-
-  describe "when adding confines" do
-    before do
-      @resolve = Facter::Util::Resolution.new("yay")
-    end
-
-    it "should accept a hash of fact names and values" do
-      lambda { @resolve.confine :one => "two" }.should_not raise_error
-    end
-
-    it "should create a Util::Confine instance for every argument in the provided hash" do
-      Facter::Util::Confine.expects(:new).with("one", "foo")
-      Facter::Util::Confine.expects(:new).with("two", "fee")
-
-      @resolve.confine "one" => "foo", "two" => "fee"
-    end
-
-  end
-
-  describe "when determining suitability" do
-    before do
-      @resolve = Facter::Util::Resolution.new("yay")
-    end
-
-    it "should always be suitable if no confines have been added" do
-      @resolve.should be_suitable
-    end
-
-    it "should be unsuitable if any provided confines return false" do
-      confine1 = mock 'confine1', :true? => true
-      confine2 = mock 'confine2', :true? => false
-      Facter::Util::Confine.expects(:new).times(2).returns(confine1).then.returns(confine2)
-      @resolve.confine :one => :two, :three => :four
-
-      @resolve.should_not be_suitable
-    end
-
-    it "should be suitable if all provided confines return true" do
-      confine1 = mock 'confine1', :true? => true
-      confine2 = mock 'confine2', :true? => true
-      Facter::Util::Confine.expects(:new).times(2).returns(confine1).then.returns(confine2)
-      @resolve.confine :one => :two, :three => :four
-
-      @resolve.should be_suitable
-    end
-  end
-
   describe "setting options" do
     subject(:resolution) { described_class.new(:foo) }
 

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